mirror of
https://github.com/ToruNiina/toml11.git
synced 2025-09-17 00:38:08 +08:00
feat: use character literal in character_either
using `std::vector` for this scanner requires many times of memory allocation and free.
This commit is contained in:
@@ -98,22 +98,10 @@ class character_either final : public scanner_base
|
||||
|
||||
public:
|
||||
|
||||
explicit character_either(std::initializer_list<char_type> cs) noexcept
|
||||
: chars_(std::move(cs))
|
||||
{
|
||||
assert(! this->chars_.empty());
|
||||
}
|
||||
|
||||
template<std::size_t N>
|
||||
explicit character_either(const char (&cs)[N]) noexcept
|
||||
: chars_(N-1, '\0')
|
||||
{
|
||||
static_assert(N >= 1, "");
|
||||
for(std::size_t i=0; i+1<N; ++i)
|
||||
{
|
||||
chars_.at(i) = char_type(cs[i]);
|
||||
}
|
||||
}
|
||||
: value_(cs), size_(N-1) // remove null character at the end
|
||||
{}
|
||||
~character_either() override = default;
|
||||
|
||||
region scan(location& loc) const override;
|
||||
@@ -122,12 +110,11 @@ class character_either final : public scanner_base
|
||||
|
||||
scanner_base* clone() const override;
|
||||
|
||||
void push_back(const char_type c);
|
||||
|
||||
std::string name() const override;
|
||||
|
||||
private:
|
||||
std::vector<char_type> chars_;
|
||||
const char* value_;
|
||||
std::size_t size_;
|
||||
};
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
@@ -87,8 +87,9 @@ TOML11_INLINE region character_either::scan(location& loc) const
|
||||
{
|
||||
if(loc.eof()) {return region{};}
|
||||
|
||||
for(const auto c : this->chars_)
|
||||
for(std::size_t i=0; i<this->size_; ++i)
|
||||
{
|
||||
const auto c = char_type(this->value_[i]);
|
||||
if(loc.current() == c)
|
||||
{
|
||||
const auto first = loc;
|
||||
@@ -101,30 +102,32 @@ TOML11_INLINE region character_either::scan(location& loc) const
|
||||
|
||||
TOML11_INLINE std::string character_either::expected_chars(location&) const
|
||||
{
|
||||
assert( ! chars_.empty());
|
||||
assert( this->value_ );
|
||||
assert( this->size_ != 0 );
|
||||
|
||||
std::string expected;
|
||||
if(chars_.size() == 1)
|
||||
if(this->size_ == 1)
|
||||
{
|
||||
expected += show_char(chars_.at(0));
|
||||
expected += show_char(char_type(value_[0]));
|
||||
}
|
||||
else if(chars_.size() == 2)
|
||||
else if(this->size_ == 2)
|
||||
{
|
||||
expected += show_char(chars_.at(0)) + " or " + show_char(chars_.at(1));
|
||||
expected += show_char(char_type(value_[0])) + " or " +
|
||||
show_char(char_type(value_[1]));
|
||||
}
|
||||
else
|
||||
{
|
||||
for(std::size_t i=0; i<chars_.size(); ++i)
|
||||
for(std::size_t i=0; i<this->size_; ++i)
|
||||
{
|
||||
if(i != 0)
|
||||
{
|
||||
expected += ", ";
|
||||
}
|
||||
if(i + 1 == chars_.size())
|
||||
if(i + 1 == this->size_)
|
||||
{
|
||||
expected += "or ";
|
||||
}
|
||||
expected += show_char(chars_.at(i));
|
||||
expected += show_char(char_type(value_[i]));
|
||||
}
|
||||
}
|
||||
return expected;
|
||||
@@ -135,20 +138,16 @@ TOML11_INLINE scanner_base* character_either::clone() const
|
||||
return new character_either(*this);
|
||||
}
|
||||
|
||||
TOML11_INLINE void character_either::push_back(const char_type c)
|
||||
{
|
||||
chars_.push_back(c);
|
||||
}
|
||||
|
||||
TOML11_INLINE std::string character_either::name() const
|
||||
{
|
||||
std::string n("character_either{");
|
||||
for(const auto c : this->chars_)
|
||||
for(std::size_t i=0; i<this->size_; ++i)
|
||||
{
|
||||
const auto c = char_type(this->value_[i]);
|
||||
n += show_char(c);
|
||||
n += ", ";
|
||||
}
|
||||
if( ! this->chars_.empty())
|
||||
if(this->size_ != 0)
|
||||
{
|
||||
n.pop_back();
|
||||
n.pop_back();
|
||||
|
@@ -59,7 +59,7 @@ TOML11_INLINE non_ascii::non_ascii(const spec& s) noexcept
|
||||
|
||||
TOML11_INLINE character_either wschar(const spec&)
|
||||
{
|
||||
return character_either{char_type(' '), char_type('\t')};
|
||||
return character_either(" \t");
|
||||
}
|
||||
|
||||
TOML11_INLINE repeat_at_least ws(const spec& s)
|
||||
@@ -172,7 +172,7 @@ TOML11_INLINE sequence dec_int(const spec& s)
|
||||
return character_in_range(char_type('1'), char_type('9'));
|
||||
};
|
||||
return sequence(
|
||||
maybe(character_either{char_type('-'), char_type('+')}),
|
||||
maybe(character_either("+-")),
|
||||
either(
|
||||
sequence(
|
||||
digit19(),
|
||||
@@ -222,7 +222,7 @@ TOML11_INLINE sequence oct_int(const spec&)
|
||||
TOML11_INLINE sequence bin_int(const spec&)
|
||||
{
|
||||
const auto digit01 = []() {
|
||||
return character_either{char_type('0'), char_type('1')};
|
||||
return character_either("01");
|
||||
};
|
||||
return sequence(
|
||||
literal("0b"),
|
||||
@@ -274,8 +274,8 @@ TOML11_INLINE sequence fractional_part(const spec& s)
|
||||
TOML11_INLINE sequence exponent_part(const spec& s)
|
||||
{
|
||||
return sequence(
|
||||
character_either{char_type('e'), char_type('E')},
|
||||
maybe(character_either{char_type('+'), char_type('-')}),
|
||||
character_either("eE"),
|
||||
maybe(character_either("+-")),
|
||||
zero_prefixable_int(s)
|
||||
);
|
||||
}
|
||||
@@ -291,9 +291,9 @@ TOML11_INLINE sequence hex_floating(const spec& s)
|
||||
// - 0x(int)p[+-](int)
|
||||
|
||||
return sequence(
|
||||
maybe(character_either{char_type('+'), char_type('-')}),
|
||||
maybe(character_either("+-")),
|
||||
character('0'),
|
||||
character_either{char_type('x'), char_type('X')},
|
||||
character_either("xX"),
|
||||
either(
|
||||
sequence(
|
||||
repeat_at_least(0, hexdig(s)),
|
||||
@@ -305,8 +305,8 @@ TOML11_INLINE sequence hex_floating(const spec& s)
|
||||
maybe(character('.'))
|
||||
)
|
||||
),
|
||||
character_either{char_type('p'), char_type('P')},
|
||||
maybe(character_either{char_type('+'), char_type('-')}),
|
||||
character_either("pP"),
|
||||
maybe(character_either("+-")),
|
||||
repeat_at_least(1, character_in_range('0', '9'))
|
||||
);
|
||||
}
|
||||
@@ -322,7 +322,7 @@ TOML11_INLINE either floating(const spec& s)
|
||||
)
|
||||
),
|
||||
sequence(
|
||||
maybe(character_either{char_type('-'), char_type('+')}),
|
||||
maybe(character_either("+-")),
|
||||
either(literal("inf"), literal("nan"))
|
||||
)
|
||||
);
|
||||
@@ -371,8 +371,8 @@ TOML11_INLINE sequence local_time(const spec& s)
|
||||
TOML11_INLINE either time_offset(const spec& s)
|
||||
{
|
||||
return either(
|
||||
character_either{'Z', 'z'},
|
||||
sequence(character_either{'+', '-'},
|
||||
character_either("zZ"),
|
||||
sequence(character_either("+-"),
|
||||
repeat_exact(2, digit(s)),
|
||||
character(':'),
|
||||
repeat_exact(2, digit(s))
|
||||
@@ -385,7 +385,7 @@ TOML11_INLINE sequence full_time(const spec& s)
|
||||
}
|
||||
TOML11_INLINE character_either time_delim(const spec&)
|
||||
{
|
||||
return character_either{'T', 't', ' '};
|
||||
return character_either("Tt ");
|
||||
}
|
||||
TOML11_INLINE sequence local_datetime(const spec& s)
|
||||
{
|
||||
@@ -401,16 +401,19 @@ TOML11_INLINE sequence offset_datetime(const spec& s)
|
||||
|
||||
TOML11_INLINE sequence escaped(const spec& s)
|
||||
{
|
||||
character_either escape_char{
|
||||
'\"','\\', 'b', 'f', 'n', 'r', 't'
|
||||
const auto escape_char = [&s] {
|
||||
if(s.v1_1_0_add_escape_sequence_e)
|
||||
{
|
||||
return character_either("\"\'bfnrte");
|
||||
}
|
||||
else
|
||||
{
|
||||
return character_either("\"\'bfnrt");
|
||||
}
|
||||
};
|
||||
if(s.v1_1_0_add_escape_sequence_e)
|
||||
{
|
||||
escape_char.push_back(char_type('e'));
|
||||
}
|
||||
|
||||
either escape_seq(
|
||||
std::move(escape_char),
|
||||
escape_char(),
|
||||
sequence(character('u'), repeat_exact(4, hexdig(s))),
|
||||
sequence(character('U'), repeat_exact(8, hexdig(s)))
|
||||
);
|
||||
|
@@ -2679,7 +2679,7 @@ guess_number_type(const location& first, const context<TC>& ctx)
|
||||
if('0' <= c && c <= '9')
|
||||
{
|
||||
return err(make_syntax_error("bad datetime: missing T or space",
|
||||
character_either{'T', 't', ' '}, loc, std::string(
|
||||
character_either("Tt "), loc, std::string(
|
||||
"Hint: valid : 1979-05-27T07:32:00, 1979-05-27 07:32:00.999999\n"
|
||||
"Hint: invalid: 1979-05-27T7:32:00, 1979-05-27 17:32\n")));
|
||||
}
|
||||
|
Reference in New Issue
Block a user