mirror of
https://github.com/ToruNiina/toml11.git
synced 2025-09-18 02:08:09 +08:00
feat: save column_number in location
instead of calculating it every time
This commit is contained in:
@@ -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;
|
||||
|
@@ -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;
|
||||
}
|
||||
|
Reference in New Issue
Block a user