mirror of
https://github.com/ToruNiina/toml11.git
synced 2024-11-26 22:30:06 +00:00
add region_base to contain it in toml::value
to make toml::get and toml::value::cast return better error messages
This commit is contained in:
parent
f834e0d142
commit
2b3a4d49a5
@ -65,14 +65,38 @@ struct location
|
|||||||
// region in a container, normally in a file content.
|
// region in a container, normally in a file content.
|
||||||
// shared_ptr points the resource that the iter points.
|
// shared_ptr points the resource that the iter points.
|
||||||
// combinators returns this.
|
// combinators returns this.
|
||||||
// it can be used not only for resource handling, but also error message.
|
// it will be used to generate better error messages.
|
||||||
|
struct region_base
|
||||||
|
{
|
||||||
|
region_base() = default;
|
||||||
|
virtual ~region_base() = default;
|
||||||
|
region_base(const region_base&) = default;
|
||||||
|
region_base(region_base&& ) = default;
|
||||||
|
region_base& operator=(const region_base&) = default;
|
||||||
|
region_base& operator=(region_base&& ) = default;
|
||||||
|
|
||||||
|
virtual bool is_ok() const noexcept {return false;}
|
||||||
|
|
||||||
|
virtual std::string str() const {return std::string("");}
|
||||||
|
virtual std::string name() const {return std::string("");}
|
||||||
|
virtual std::string line() const {return std::string("");}
|
||||||
|
virtual std::string line_num() const {return std::string("?");}
|
||||||
|
|
||||||
|
virtual std::size_t before() const noexcept {return 0;}
|
||||||
|
virtual std::size_t size() const noexcept {return 0;}
|
||||||
|
virtual std::size_t after() const noexcept {return 0;}
|
||||||
|
};
|
||||||
|
|
||||||
template<typename Container>
|
template<typename Container>
|
||||||
struct region
|
struct region final : public region_base
|
||||||
{
|
{
|
||||||
static_assert(std::is_same<char, typename Container::value_type>::value,"");
|
static_assert(std::is_same<char, typename Container::value_type>::value,"");
|
||||||
using const_iterator = typename Container::const_iterator;
|
using const_iterator = typename Container::const_iterator;
|
||||||
using source_ptr = std::shared_ptr<const Container>;
|
using source_ptr = std::shared_ptr<const Container>;
|
||||||
|
|
||||||
|
// delete default constructor. source_ never be null.
|
||||||
|
region() = delete;
|
||||||
|
|
||||||
region(const location<Container>& loc)
|
region(const location<Container>& loc)
|
||||||
: source_(loc.source()), source_name_(loc.name()),
|
: source_(loc.source()), source_name_(loc.name()),
|
||||||
first_(loc.iter()), last_(loc.iter())
|
first_(loc.iter()), last_(loc.iter())
|
||||||
@ -106,18 +130,51 @@ struct region
|
|||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string str() const {return make_string(first_, last_);}
|
bool is_ok() const noexcept override {return static_cast<bool>(source_);}
|
||||||
std::size_t size() const {return std::distance(first_, last_);}
|
|
||||||
|
|
||||||
const_iterator begin() const noexcept {return source_->cbegin();}
|
std::string str() const override {return make_string(first_, last_);}
|
||||||
const_iterator end() const noexcept {return source_->cend();}
|
std::string line() const override
|
||||||
const_iterator first() const noexcept {return first_;}
|
{
|
||||||
const_iterator last() const noexcept {return last_;}
|
return make_string(this->line_begin(), this->line_end());
|
||||||
|
}
|
||||||
|
std::string line_num() const override
|
||||||
|
{
|
||||||
|
return std::to_string(1 + std::count(this->begin(), this->first(), '\n'));
|
||||||
|
}
|
||||||
|
|
||||||
|
std::size_t size() const noexcept override
|
||||||
|
{
|
||||||
|
return std::distance(first_, last_);
|
||||||
|
}
|
||||||
|
std::size_t before() const noexcept override
|
||||||
|
{
|
||||||
|
return std::distance(this->line_begin(), this->first());
|
||||||
|
}
|
||||||
|
std::size_t after() const noexcept override
|
||||||
|
{
|
||||||
|
return std::distance(this->last(), this->line_end());
|
||||||
|
}
|
||||||
|
|
||||||
|
const_iterator line_begin() const noexcept
|
||||||
|
{
|
||||||
|
using reverse_iterator = std::reverse_iterator<const_iterator>;
|
||||||
|
return std::find(reverse_iterator(this->first()),
|
||||||
|
reverse_iterator(this->begin()), '\n').base();
|
||||||
|
}
|
||||||
|
const_iterator line_end() const noexcept
|
||||||
|
{
|
||||||
|
return std::find(this->last(), this->end(), '\n');
|
||||||
|
}
|
||||||
|
|
||||||
|
const_iterator begin() const noexcept {return source_->cbegin();}
|
||||||
|
const_iterator end() const noexcept {return source_->cend();}
|
||||||
|
const_iterator first() const noexcept {return first_;}
|
||||||
|
const_iterator last() const noexcept {return last_;}
|
||||||
|
|
||||||
source_ptr const& source() const& noexcept {return source_;}
|
source_ptr const& source() const& noexcept {return source_;}
|
||||||
source_ptr&& source() && noexcept {return std::move(source_);}
|
source_ptr&& source() && noexcept {return std::move(source_);}
|
||||||
|
|
||||||
std::string const& name() const noexcept {return source_name_;}
|
std::string name() const override {return source_name_;}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
@ -127,20 +184,12 @@ struct region
|
|||||||
};
|
};
|
||||||
|
|
||||||
// to show a better error message.
|
// to show a better error message.
|
||||||
template<typename Container>
|
inline std::string format_underline(const std::string& message,
|
||||||
std::string
|
const region_base& reg, const std::string& comment_for_underline)
|
||||||
format_underline(const std::string& message, const region<Container>& reg,
|
|
||||||
const std::string& comment_for_underline)
|
|
||||||
{
|
{
|
||||||
using const_iterator = typename region<Container>::const_iterator;
|
|
||||||
using reverse_iterator = std::reverse_iterator<const_iterator>;
|
|
||||||
const auto line_begin = std::find(reverse_iterator(reg.first()),
|
|
||||||
reverse_iterator(reg.begin()),
|
|
||||||
'\n').base();
|
|
||||||
const auto line_end = std::find(reg.last(), reg.end(), '\n');
|
|
||||||
|
|
||||||
const auto line_number = std::to_string(
|
const auto line = reg.line();
|
||||||
1 + std::count(reg.begin(), reg.first(), '\n'));
|
const auto line_number = reg.line_num();
|
||||||
|
|
||||||
std::string retval;
|
std::string retval;
|
||||||
retval += message;
|
retval += message;
|
||||||
@ -149,12 +198,12 @@ format_underline(const std::string& message, const region<Container>& reg,
|
|||||||
retval += "\n ";
|
retval += "\n ";
|
||||||
retval += line_number;
|
retval += line_number;
|
||||||
retval += " | ";
|
retval += " | ";
|
||||||
retval += make_string(line_begin, line_end);
|
retval += line;
|
||||||
retval += '\n';
|
retval += '\n';
|
||||||
retval += make_string(line_number.size() + 1, ' ');
|
retval += make_string(line_number.size() + 1, ' ');
|
||||||
retval += " | ";
|
retval += " | ";
|
||||||
retval += make_string(std::distance(line_begin, reg.first()), ' ');
|
retval += make_string(reg.before(), ' ');
|
||||||
retval += make_string(std::distance(reg.first(), reg.last()), '~');
|
retval += make_string(reg.size(), '~');
|
||||||
retval += ' ';
|
retval += ' ';
|
||||||
retval += comment_for_underline;
|
retval += comment_for_underline;
|
||||||
return retval;
|
return retval;
|
||||||
@ -189,7 +238,7 @@ format_underline(const std::string& message, const location<Container>& loc,
|
|||||||
retval += " | ";
|
retval += " | ";
|
||||||
retval += make_string(std::distance(line_begin, loc.iter()),' ');
|
retval += make_string(std::distance(line_begin, loc.iter()),' ');
|
||||||
retval += '^';
|
retval += '^';
|
||||||
retval += make_string(std::distance(loc.iter(), line_end), '-');
|
retval += make_string(std::distance(loc.iter(), line_end), '~');
|
||||||
retval += ' ';
|
retval += ' ';
|
||||||
retval += comment_for_underline;
|
retval += comment_for_underline;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user