mirror of
https://github.com/ToruNiina/toml11.git
synced 2025-09-18 10:28:09 +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:
|
public:
|
||||||
|
|
||||||
explicit character_either(std::initializer_list<char_type> cs) noexcept
|
|
||||||
: chars_(std::move(cs))
|
|
||||||
{
|
|
||||||
assert(! this->chars_.empty());
|
|
||||||
}
|
|
||||||
|
|
||||||
template<std::size_t N>
|
template<std::size_t N>
|
||||||
explicit character_either(const char (&cs)[N]) noexcept
|
explicit character_either(const char (&cs)[N]) noexcept
|
||||||
: chars_(N-1, '\0')
|
: value_(cs), size_(N-1) // remove null character at the end
|
||||||
{
|
{}
|
||||||
static_assert(N >= 1, "");
|
|
||||||
for(std::size_t i=0; i+1<N; ++i)
|
|
||||||
{
|
|
||||||
chars_.at(i) = char_type(cs[i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
~character_either() override = default;
|
~character_either() override = default;
|
||||||
|
|
||||||
region scan(location& loc) const override;
|
region scan(location& loc) const override;
|
||||||
@@ -122,12 +110,11 @@ class character_either final : public scanner_base
|
|||||||
|
|
||||||
scanner_base* clone() const override;
|
scanner_base* clone() const override;
|
||||||
|
|
||||||
void push_back(const char_type c);
|
|
||||||
|
|
||||||
std::string name() const override;
|
std::string name() const override;
|
||||||
|
|
||||||
private:
|
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{};}
|
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)
|
if(loc.current() == c)
|
||||||
{
|
{
|
||||||
const auto first = loc;
|
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
|
TOML11_INLINE std::string character_either::expected_chars(location&) const
|
||||||
{
|
{
|
||||||
assert( ! chars_.empty());
|
assert( this->value_ );
|
||||||
|
assert( this->size_ != 0 );
|
||||||
|
|
||||||
std::string expected;
|
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
|
else
|
||||||
{
|
{
|
||||||
for(std::size_t i=0; i<chars_.size(); ++i)
|
for(std::size_t i=0; i<this->size_; ++i)
|
||||||
{
|
{
|
||||||
if(i != 0)
|
if(i != 0)
|
||||||
{
|
{
|
||||||
expected += ", ";
|
expected += ", ";
|
||||||
}
|
}
|
||||||
if(i + 1 == chars_.size())
|
if(i + 1 == this->size_)
|
||||||
{
|
{
|
||||||
expected += "or ";
|
expected += "or ";
|
||||||
}
|
}
|
||||||
expected += show_char(chars_.at(i));
|
expected += show_char(char_type(value_[i]));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return expected;
|
return expected;
|
||||||
@@ -135,20 +138,16 @@ TOML11_INLINE scanner_base* character_either::clone() const
|
|||||||
return new character_either(*this);
|
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
|
TOML11_INLINE std::string character_either::name() const
|
||||||
{
|
{
|
||||||
std::string n("character_either{");
|
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 += show_char(c);
|
||||||
n += ", ";
|
n += ", ";
|
||||||
}
|
}
|
||||||
if( ! this->chars_.empty())
|
if(this->size_ != 0)
|
||||||
{
|
{
|
||||||
n.pop_back();
|
n.pop_back();
|
||||||
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&)
|
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)
|
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 character_in_range(char_type('1'), char_type('9'));
|
||||||
};
|
};
|
||||||
return sequence(
|
return sequence(
|
||||||
maybe(character_either{char_type('-'), char_type('+')}),
|
maybe(character_either("+-")),
|
||||||
either(
|
either(
|
||||||
sequence(
|
sequence(
|
||||||
digit19(),
|
digit19(),
|
||||||
@@ -222,7 +222,7 @@ TOML11_INLINE sequence oct_int(const spec&)
|
|||||||
TOML11_INLINE sequence bin_int(const spec&)
|
TOML11_INLINE sequence bin_int(const spec&)
|
||||||
{
|
{
|
||||||
const auto digit01 = []() {
|
const auto digit01 = []() {
|
||||||
return character_either{char_type('0'), char_type('1')};
|
return character_either("01");
|
||||||
};
|
};
|
||||||
return sequence(
|
return sequence(
|
||||||
literal("0b"),
|
literal("0b"),
|
||||||
@@ -274,8 +274,8 @@ TOML11_INLINE sequence fractional_part(const spec& s)
|
|||||||
TOML11_INLINE sequence exponent_part(const spec& s)
|
TOML11_INLINE sequence exponent_part(const spec& s)
|
||||||
{
|
{
|
||||||
return sequence(
|
return sequence(
|
||||||
character_either{char_type('e'), char_type('E')},
|
character_either("eE"),
|
||||||
maybe(character_either{char_type('+'), char_type('-')}),
|
maybe(character_either("+-")),
|
||||||
zero_prefixable_int(s)
|
zero_prefixable_int(s)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -291,9 +291,9 @@ TOML11_INLINE sequence hex_floating(const spec& s)
|
|||||||
// - 0x(int)p[+-](int)
|
// - 0x(int)p[+-](int)
|
||||||
|
|
||||||
return sequence(
|
return sequence(
|
||||||
maybe(character_either{char_type('+'), char_type('-')}),
|
maybe(character_either("+-")),
|
||||||
character('0'),
|
character('0'),
|
||||||
character_either{char_type('x'), char_type('X')},
|
character_either("xX"),
|
||||||
either(
|
either(
|
||||||
sequence(
|
sequence(
|
||||||
repeat_at_least(0, hexdig(s)),
|
repeat_at_least(0, hexdig(s)),
|
||||||
@@ -305,8 +305,8 @@ TOML11_INLINE sequence hex_floating(const spec& s)
|
|||||||
maybe(character('.'))
|
maybe(character('.'))
|
||||||
)
|
)
|
||||||
),
|
),
|
||||||
character_either{char_type('p'), char_type('P')},
|
character_either("pP"),
|
||||||
maybe(character_either{char_type('+'), char_type('-')}),
|
maybe(character_either("+-")),
|
||||||
repeat_at_least(1, character_in_range('0', '9'))
|
repeat_at_least(1, character_in_range('0', '9'))
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -322,7 +322,7 @@ TOML11_INLINE either floating(const spec& s)
|
|||||||
)
|
)
|
||||||
),
|
),
|
||||||
sequence(
|
sequence(
|
||||||
maybe(character_either{char_type('-'), char_type('+')}),
|
maybe(character_either("+-")),
|
||||||
either(literal("inf"), literal("nan"))
|
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)
|
TOML11_INLINE either time_offset(const spec& s)
|
||||||
{
|
{
|
||||||
return either(
|
return either(
|
||||||
character_either{'Z', 'z'},
|
character_either("zZ"),
|
||||||
sequence(character_either{'+', '-'},
|
sequence(character_either("+-"),
|
||||||
repeat_exact(2, digit(s)),
|
repeat_exact(2, digit(s)),
|
||||||
character(':'),
|
character(':'),
|
||||||
repeat_exact(2, digit(s))
|
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&)
|
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)
|
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)
|
TOML11_INLINE sequence escaped(const spec& s)
|
||||||
{
|
{
|
||||||
character_either escape_char{
|
const auto escape_char = [&s] {
|
||||||
'\"','\\', 'b', 'f', 'n', 'r', 't'
|
|
||||||
};
|
|
||||||
if(s.v1_1_0_add_escape_sequence_e)
|
if(s.v1_1_0_add_escape_sequence_e)
|
||||||
{
|
{
|
||||||
escape_char.push_back(char_type('e'));
|
return character_either("\"\'bfnrte");
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return character_either("\"\'bfnrt");
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
either escape_seq(
|
either escape_seq(
|
||||||
std::move(escape_char),
|
escape_char(),
|
||||||
sequence(character('u'), repeat_exact(4, hexdig(s))),
|
sequence(character('u'), repeat_exact(4, hexdig(s))),
|
||||||
sequence(character('U'), repeat_exact(8, 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')
|
if('0' <= c && c <= '9')
|
||||||
{
|
{
|
||||||
return err(make_syntax_error("bad datetime: missing T or space",
|
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: 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")));
|
"Hint: invalid: 1979-05-27T7:32:00, 1979-05-27 17:32\n")));
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user