feat: save column_number in location

instead of calculating it every time
This commit is contained in:
ToruNiina
2024-10-19 00:04:08 +09:00
parent befe379241
commit 42a2628924
2 changed files with 35 additions and 23 deletions

View File

@@ -31,7 +31,7 @@ class location
location(source_ptr src, std::string src_name) location(source_ptr src, std::string src_name)
: source_(std::move(src)), source_name_(std::move(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; location(const location&) = default;
@@ -59,8 +59,11 @@ class location
{ {
return this->line_number_; return this->line_number_;
} }
std::size_t column_number() const noexcept
{
return this->column_number_;
}
std::string get_line() const; std::string get_line() const;
std::size_t column_number() const noexcept;
source_ptr const& source() const noexcept {return this->source_;} source_ptr const& source() const noexcept {return this->source_;}
std::string const& source_name() const noexcept {return this->source_name_;} 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 advance_impl(const std::size_t n);
void retrace_impl(); void retrace_impl();
std::size_t calc_column_number() const noexcept;
private: private:
@@ -80,6 +84,7 @@ class location
std::string source_name_; std::string source_name_;
std::size_t location_; // std::vector<>::difference_type is signed std::size_t location_; // std::vector<>::difference_type is signed
std::size_t line_number_; std::size_t line_number_;
std::size_t column_number_;
}; };
bool operator==(const location& lhs, const location& rhs) noexcept; bool operator==(const location& lhs, const location& rhs) noexcept;

View File

@@ -16,12 +16,12 @@ TOML11_INLINE void location::advance(std::size_t n) noexcept
if(this->location_ + n < this->source_->size()) if(this->location_ + n < this->source_->size())
{ {
this->advance_impl(n); this->advance_impl(n);
this->location_ += n;
} }
else else
{ {
this->advance_impl(this->source_->size() - this->location_); 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 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->location_ = 0;
this->line_number_ = 1; this->line_number_ = 1;
this->column_number_ = 1;
} }
else else
{ {
this->retrace_impl(); 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); 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()); assert(this->is_ok());
const auto iter = std::next(this->source_->cbegin(), static_cast<difference_type>(this->location_)); const auto iter = std::next(this->source_->cbegin(), static_cast<difference_type>(this->location_));
@@ -88,18 +89,29 @@ TOML11_INLINE std::size_t location::column_number() const noexcept
return static_cast<std::size_t>(std::distance(prev.base(), iter) + 1); // 1-origin return static_cast<std::size_t>(std::distance(prev.base(), iter) + 1); // 1-origin
} }
TOML11_INLINE void location::advance_impl(const std::size_t n) TOML11_INLINE void location::advance_impl(const std::size_t n)
{ {
assert(this->is_ok()); assert(this->is_ok());
assert(this->location_ + n <= this->source_->size()); assert(this->location_ + n <= this->source_->size());
const auto iter = this->source_->cbegin(); auto iter = this->source_->cbegin();
this->line_number_ += static_cast<std::size_t>(std::count( std::advance(iter, static_cast<difference_type>(this->location_));
std::next(iter, static_cast<difference_type>(this->location_)),
std::next(iter, static_cast<difference_type>(this->location_ + n)),
char_type('\n')));
for(std::size_t i=0; i<n; ++i)
{
const auto c = *iter;
if(c == char_type('\n'))
{
this->line_number_ += 1;
this->column_number_ = 1;
}
else
{
this->column_number_ += 1;
}
iter++;
}
this->location_ += n;
return; return;
} }
TOML11_INLINE void location::retrace_impl(/*n == 1*/) 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->is_ok());
assert(this->location_ != 0); assert(this->location_ != 0);
const auto iter = this->source_->cbegin(); this->location_ -= 1;
const auto dline_num = static_cast<std::size_t>(std::count(
std::next(iter, static_cast<difference_type>(this->location_ - 1)),
std::next(iter, static_cast<difference_type>(this->location_)),
char_type('\n')));
if(this->line_number_ <= dline_num) auto iter = this->source_->cbegin();
std::advance(iter, static_cast<difference_type>(this->location_));
if(*iter == '\n')
{ {
this->line_number_ = 1; this->line_number_ -= 1;
} this->column_number_ = this->calc_column_number();
else
{
this->line_number_ -= dline_num;
} }
return; return;
} }