#ifndef TOML11_SCANNER_IMPL_HPP #define TOML11_SCANNER_IMPL_HPP #include "../fwd/scanner_fwd.hpp" #include "../utility.hpp" #include "../version.hpp" namespace toml { inline namespace TOML11_INLINE_VERSION_NAMESPACE { namespace detail { TOML11_INLINE scanner_storage::scanner_storage(const scanner_storage& other) : scanner_(nullptr) { if(other.is_ok()) { scanner_.reset(other.get().clone()); } } TOML11_INLINE scanner_storage& scanner_storage::operator=(const scanner_storage& other) { if(this == std::addressof(other)) {return *this;} if(other.is_ok()) { scanner_.reset(other.get().clone()); } return *this; } TOML11_INLINE region scanner_storage::scan(location& loc) const { assert(this->is_ok()); return this->scanner_->scan(loc); } TOML11_INLINE std::string scanner_storage::expected_chars(location& loc) const { assert(this->is_ok()); return this->scanner_->expected_chars(loc); } TOML11_INLINE scanner_base& scanner_storage::get() const noexcept { assert(this->is_ok()); return *scanner_; } TOML11_INLINE std::string scanner_storage::name() const { assert(this->is_ok()); return this->scanner_->name(); } // ---------------------------------------------------------------------------- TOML11_INLINE region character::scan(location& loc) const { if(loc.eof()) {return region{};} if(loc.current() == this->value_) { const auto first = loc; loc.advance(1); return region(first, loc); } return region{}; } TOML11_INLINE std::string character::expected_chars(location&) const { return show_char(value_); } TOML11_INLINE scanner_base* character::clone() const { return new character(*this); } TOML11_INLINE std::string character::name() const { return "character{" + show_char(value_) + "}"; } // ---------------------------------------------------------------------------- TOML11_INLINE region character_either::scan(location& loc) const { if(loc.eof()) {return region{};} for(std::size_t i=0; isize_; ++i) { const auto c = char_type(this->value_[i]); if(loc.current() == c) { const auto first = loc; loc.advance(1); return region(first, loc); } } return region{}; } TOML11_INLINE std::string character_either::expected_chars(location&) const { assert( this->value_ ); assert( this->size_ != 0 ); std::string expected; if(this->size_ == 1) { expected += show_char(char_type(value_[0])); } else if(this->size_ == 2) { expected += show_char(char_type(value_[0])) + " or " + show_char(char_type(value_[1])); } else { for(std::size_t i=0; isize_; ++i) { if(i != 0) { expected += ", "; } if(i + 1 == this->size_) { expected += "or "; } expected += show_char(char_type(value_[i])); } } return expected; } TOML11_INLINE scanner_base* character_either::clone() const { return new character_either(*this); } TOML11_INLINE std::string character_either::name() const { std::string n("character_either{"); for(std::size_t i=0; isize_; ++i) { const auto c = char_type(this->value_[i]); n += show_char(c); n += ", "; } if(this->size_ != 0) { n.pop_back(); n.pop_back(); } n += "}"; return n; } // ---------------------------------------------------------------------------- // character_in_range TOML11_INLINE region character_in_range::scan(location& loc) const { if(loc.eof()) {return region{};} const auto curr = loc.current(); if(this->from_ <= curr && curr <= this->to_) { const auto first = loc; loc.advance(1); return region(first, loc); } return region{}; } TOML11_INLINE std::string character_in_range::expected_chars(location&) const { std::string expected("from `"); expected += show_char(from_); expected += "` to `"; expected += show_char(to_); expected += "`"; return expected; } TOML11_INLINE scanner_base* character_in_range::clone() const { return new character_in_range(*this); } TOML11_INLINE std::string character_in_range::name() const { return "character_in_range{" + show_char(from_) + "," + show_char(to_) + "}"; } // ---------------------------------------------------------------------------- // literal TOML11_INLINE region literal::scan(location& loc) const { const auto first = loc; for(std::size_t i=0; iothers_.empty()) { n.pop_back(); n.pop_back(); } n += "}"; return n; } // ---------------------------------------------------------------------------- // either TOML11_INLINE region either::scan(location& loc) const { for(const auto& other : others_) { const auto reg = other.scan(loc); if(reg.is_ok()) { return reg; } } return region{}; } TOML11_INLINE std::string either::expected_chars(location& loc) const { assert( ! others_.empty()); std::string expected = others_.at(0).expected_chars(loc); if(others_.size() == 2) { expected += " or "; expected += others_.at(1).expected_chars(loc); } else { for(std::size_t i=1; iothers_.empty()) { n.pop_back(); n.pop_back(); } n += "}"; return n; } // ---------------------------------------------------------------------------- // repeat_exact TOML11_INLINE region repeat_exact::scan(location& loc) const { const auto first = loc; for(std::size_t i=0; i