make variables in region/location read-only

to avoid modifying mistakenly
This commit is contained in:
ToruNiina
2018-12-03 00:10:26 +09:00
parent 59588e3a10
commit 679e282e23

View File

@@ -1,9 +1,9 @@
#ifndef TOML11_REGION_H #ifndef TOML11_REGION_H
#define TOML11_REGION_H #define TOML11_REGION_H
#include "exception.hpp"
#include <memory> #include <memory>
#include <algorithm> #include <algorithm>
#include <iterator> #include <iterator>
#include <string>
namespace toml namespace toml
{ {
@@ -18,10 +18,12 @@ struct location
{ {
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>;
location(Container cont) location(Container cont)
: source(std::make_shared<Container>(std::move(cont))), : source_(std::make_shared<Container>(std::move(cont))),
begin(source->cbegin()), iter(source->cbegin()), end(source->cend()) begin_(source_->cbegin()), iter_(source_->cbegin()),
end_(source_->cend())
{} {}
location(const location&) = default; location(const location&) = default;
location(location&&) = default; location(location&&) = default;
@@ -29,8 +31,19 @@ struct location
location& operator=(location&&) = default; location& operator=(location&&) = default;
~location() = default; ~location() = default;
std::shared_ptr<const Container> source; const_iterator& iter() noexcept {return iter_;}
const_iterator begin, iter, end; const_iterator iter() const noexcept {return iter_;}
const_iterator begin() const noexcept {return begin_;}
const_iterator end() const noexcept {return end_;}
source_ptr const& source() const& noexcept {return source_;}
source_ptr&& source() && noexcept {return std::move(source_);}
private:
source_ptr source_;
const_iterator begin_, iter_, end_;
}; };
// region in a container, normally in a file content. // region in a container, normally in a file content.
@@ -42,23 +55,24 @@ struct region
{ {
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>;
region(const location<Container>& loc) region(const location<Container>& loc)
: begin(loc.begin), first(loc.iter), last(loc.iter), end(loc.end), : begin_(loc.begin()), first_(loc.iter()),
source(loc.source) last_(loc.iter()), end_(loc.end()), source_(loc.source())
{} {}
region(location<Container>&& loc) region(location<Container>&& loc)
: begin(loc.begin), first(loc.iter), last(loc.iter), end(loc.end), : begin_(loc.begin()), first_(loc.iter()),
source(std::move(loc.source)) last_(loc.iter()), end_(loc.end()), source_(std::move(loc.source()))
{} {}
region(const location<Container>& loc, const_iterator f, const_iterator l) region(const location<Container>& loc, const_iterator f, const_iterator l)
: begin(loc.begin), first(f), last(l), end(loc.end), : begin_(loc.begin()), first_(f), last_(l), end_(loc.end()),
source(loc.source) source_(loc.source())
{} {}
region(location<Container>&& loc, const_iterator f, const_iterator l) region(location<Container>&& loc, const_iterator f, const_iterator l)
: begin(loc.begin), first(f), last(l), end(loc.end), : begin_(loc.begin()), first_(f), last_(l), end_(loc.end()),
source(std::move(loc.source)) source_(std::move(loc.source()))
{} {}
region(const region&) = default; region(const region&) = default;
@@ -67,11 +81,32 @@ struct region
region& operator=(region&&) = default; region& operator=(region&&) = default;
~region() = default; ~region() = default;
std::string str() const {return std::string(first, last);} region& operator+=(const region& other)
std::size_t size() const {return std::distance(first, last);} {
if(this->begin_ != other.begin_ || this->end_ != other.end_ ||
this->last_ != other.first_)
{
throw internal_error("invalid region concatenation");
}
this->last_ = other.last_;
return *this;
}
const_iterator begin, first, last, end; std::string str() const {return std::string(first_, last_);}
std::shared_ptr<const Container> source; std::size_t size() const {return std::distance(first_, last_);}
const_iterator begin() const noexcept {return begin_;}
const_iterator end() const noexcept {return end_;}
const_iterator first() const noexcept {return first_;}
const_iterator last() const noexcept {return last_;}
source_ptr const& source() const& noexcept {return source_;}
source_ptr&& source() && noexcept {return std::move(source_);}
private:
const_iterator begin_, first_, last_, end_;
source_ptr source_;
}; };
// to show a better error message. // to show a better error message.
@@ -82,13 +117,13 @@ format_underline(const region<Container>& reg, const std::string& msg)
using const_iterator = typename region<Container>::const_iterator; using const_iterator = typename region<Container>::const_iterator;
using reverse_iterator = std::reverse_iterator<const_iterator>; using reverse_iterator = std::reverse_iterator<const_iterator>;
const auto line_begin = std::find( const auto line_begin = std::find(
reverse_iterator(reg.first), reverse_iterator(reg.first()),
reverse_iterator(reg.begin), reverse_iterator(reg.begin()),
'\n').base(); '\n').base();
const auto line_end = std::find(reg.last, reg.end, '\n'); const auto line_end = std::find(reg.last(), reg.end(), '\n');
const auto line_number = std::to_string( const auto line_number = std::to_string(
1 + std::count(reg.begin, reg.first, '\n')); 1 + std::count(reg.begin(), reg.first(), '\n'));
std::string retval; std::string retval;
retval += ' '; retval += ' ';
@@ -98,8 +133,8 @@ format_underline(const region<Container>& reg, const std::string& msg)
retval += '\n'; retval += '\n';
retval += std::string(line_number.size() + 1, ' '); retval += std::string(line_number.size() + 1, ' ');
retval += " | "; retval += " | ";
retval += std::string(std::distance(line_begin, reg.first), ' '); retval += std::string(std::distance(line_begin, reg.first()), ' ');
retval += std::string(std::distance(reg.first, reg.last), '~'); retval += std::string(std::distance(reg.first(), reg.last()), '~');
retval += ' '; retval += ' ';
retval += msg; retval += msg;
return retval; return retval;
@@ -114,13 +149,13 @@ std::string format_underline(const region<Container>& reg,
using const_iterator = typename region<Container>::const_iterator; using const_iterator = typename region<Container>::const_iterator;
using reverse_iterator = std::reverse_iterator<const_iterator>; using reverse_iterator = std::reverse_iterator<const_iterator>;
const auto line_begin = std::find( const auto line_begin = std::find(
reverse_iterator(reg.first), reverse_iterator(reg.first()),
reverse_iterator(reg.begin), reverse_iterator(reg.begin()),
'\n').base(); '\n').base();
const auto line_end = std::find(reg.last, reg.end, '\n'); const auto line_end = std::find(reg.last(), reg.end(), '\n');
const auto line_number = std::to_string( const auto line_number = std::to_string(
1 + std::count(reg.begin, reg.first, '\n')); 1 + std::count(reg.begin(), reg.first(), '\n'));
std::string retval; std::string retval;
retval += ' '; retval += ' ';
@@ -130,16 +165,16 @@ std::string format_underline(const region<Container>& reg,
retval += '\n'; retval += '\n';
retval += std::string(line_number.size() + 1, ' '); retval += std::string(line_number.size() + 1, ' ');
retval += " | "; retval += " | ";
retval += std::string(std::distance(line_begin, reg.first), ' '); retval += std::string(std::distance(line_begin, reg.first()), ' ');
if(std::distance(reg.first, std::prev(pos)) > 0) if(std::distance(reg.first(), std::prev(pos)) > 0)
{ {
retval += std::string(std::distance(reg.first, std::prev(pos)), '-'); retval += std::string(std::distance(reg.first(), std::prev(pos)), '-');
} }
retval += '^'; retval += '^';
if(std::distance(pos, reg.last) > 0) if(std::distance(pos, reg.last()) > 0)
{ {
retval += std::string(std::distance(std::next(pos), reg.last), '-'); retval += std::string(std::distance(std::next(pos), reg.last()), '-');
} }
retval += ' '; retval += ' ';