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)
: 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;

View File

@@ -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<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
}
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::size_t>(std::count(
std::next(iter, static_cast<difference_type>(this->location_)),
std::next(iter, static_cast<difference_type>(this->location_ + n)),
char_type('\n')));
auto iter = this->source_->cbegin();
std::advance(iter, static_cast<difference_type>(this->location_));
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;
}
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::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')));
this->location_ -= 1;
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;
}
else
{
this->line_number_ -= dline_num;
this->line_number_ -= 1;
this->column_number_ = this->calc_column_number();
}
return;
}