From 42a2628924eb6538689f75e85d13393e53f29ced Mon Sep 17 00:00:00 2001 From: ToruNiina Date: Sat, 19 Oct 2024 00:04:08 +0900 Subject: [PATCH] feat: save column_number in location instead of calculating it every time --- include/toml11/fwd/location_fwd.hpp | 9 +++-- include/toml11/impl/location_impl.hpp | 49 +++++++++++++++------------ 2 files changed, 35 insertions(+), 23 deletions(-) diff --git a/include/toml11/fwd/location_fwd.hpp b/include/toml11/fwd/location_fwd.hpp index 7fc7eca..395b96c 100644 --- a/include/toml11/fwd/location_fwd.hpp +++ b/include/toml11/fwd/location_fwd.hpp @@ -31,7 +31,7 @@ class location location(source_ptr src, std::string src_name) : source_(std::move(src)), source_name_(std::move(src_name)), - location_(0), line_number_(1) + location_(0), line_number_(1), column_number_(1) {} location(const location&) = default; @@ -59,8 +59,11 @@ class location { return this->line_number_; } + std::size_t column_number() const noexcept + { + return this->column_number_; + } std::string get_line() const; - std::size_t column_number() const noexcept; source_ptr const& source() const noexcept {return this->source_;} std::string const& source_name() const noexcept {return this->source_name_;} @@ -69,6 +72,7 @@ class location void advance_impl(const std::size_t n); void retrace_impl(); + std::size_t calc_column_number() const noexcept; private: @@ -80,6 +84,7 @@ class location std::string source_name_; std::size_t location_; // std::vector<>::difference_type is signed std::size_t line_number_; + std::size_t column_number_; }; bool operator==(const location& lhs, const location& rhs) noexcept; diff --git a/include/toml11/impl/location_impl.hpp b/include/toml11/impl/location_impl.hpp index a909ee4..b996ab6 100644 --- a/include/toml11/impl/location_impl.hpp +++ b/include/toml11/impl/location_impl.hpp @@ -16,12 +16,12 @@ TOML11_INLINE void location::advance(std::size_t n) noexcept if(this->location_ + n < this->source_->size()) { this->advance_impl(n); - this->location_ += n; } else { this->advance_impl(this->source_->size() - this->location_); - this->location_ = this->source_->size(); + + assert(this->location_ == this->source_->size()); } } TOML11_INLINE void location::retrace(/*restricted to n=1*/) noexcept @@ -31,11 +31,11 @@ TOML11_INLINE void location::retrace(/*restricted to n=1*/) noexcept { this->location_ = 0; this->line_number_ = 1; + this->column_number_ = 1; } else { this->retrace_impl(); - this->location_ -= 1; } } @@ -77,7 +77,8 @@ TOML11_INLINE std::string location::get_line() const return make_string(std::next(prev.base()), next); } -TOML11_INLINE std::size_t location::column_number() const noexcept + +TOML11_INLINE std::size_t location::calc_column_number() const noexcept { assert(this->is_ok()); const auto iter = std::next(this->source_->cbegin(), static_cast(this->location_)); @@ -88,18 +89,29 @@ TOML11_INLINE std::size_t location::column_number() const noexcept return static_cast(std::distance(prev.base(), iter) + 1); // 1-origin } - TOML11_INLINE void location::advance_impl(const std::size_t n) { assert(this->is_ok()); assert(this->location_ + n <= this->source_->size()); - const auto iter = this->source_->cbegin(); - this->line_number_ += static_cast(std::count( - std::next(iter, static_cast(this->location_)), - std::next(iter, static_cast(this->location_ + n)), - char_type('\n'))); + auto iter = this->source_->cbegin(); + std::advance(iter, static_cast(this->location_)); + for(std::size_t i=0; iline_number_ += 1; + this->column_number_ = 1; + } + else + { + this->column_number_ += 1; + } + iter++; + } + this->location_ += n; return; } TOML11_INLINE void location::retrace_impl(/*n == 1*/) @@ -107,19 +119,14 @@ TOML11_INLINE void location::retrace_impl(/*n == 1*/) assert(this->is_ok()); assert(this->location_ != 0); - const auto iter = this->source_->cbegin(); - const auto dline_num = static_cast(std::count( - std::next(iter, static_cast(this->location_ - 1)), - std::next(iter, static_cast(this->location_)), - char_type('\n'))); + this->location_ -= 1; - if(this->line_number_ <= dline_num) + auto iter = this->source_->cbegin(); + std::advance(iter, static_cast(this->location_)); + if(*iter == '\n') { - this->line_number_ = 1; - } - else - { - this->line_number_ -= dline_num; + this->line_number_ -= 1; + this->column_number_ = this->calc_column_number(); } return; }