mirror of
https://github.com/ToruNiina/toml11.git
synced 2025-12-16 03:08:52 +08:00
Compare commits
16 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
717f5929c2 | ||
|
|
81abb6c9d7 | ||
|
|
8bba3c8a14 | ||
|
|
b13e727b90 | ||
|
|
d352c9e66f | ||
|
|
c0aaba06d0 | ||
|
|
1633268d57 | ||
|
|
3bf1c2b820 | ||
|
|
4dbd2cb9fe | ||
|
|
65124a8d2e | ||
|
|
1b78f161f5 | ||
|
|
0ce259ada0 | ||
|
|
74da49f87f | ||
|
|
d5d697639c | ||
|
|
0b365ca7d3 | ||
|
|
db6f3d5d11 |
@@ -1068,6 +1068,8 @@ I appreciate the help of the contributors who introduced the great feature to th
|
||||
- Improved error messages for invaild keys to show the location where the parser fails
|
||||
- Petr Beneš (@wbenny)
|
||||
- Fixed warnings on MSVC
|
||||
- Ivan Shynkarenka (@chronoxor)
|
||||
- Fixed Visual Studio 2019 warnings
|
||||
|
||||
## Licensing terms
|
||||
|
||||
|
||||
@@ -18,7 +18,7 @@ do { \
|
||||
BOOST_CHECK_EQUAL(static_cast<std::size_t>(std::distance( \
|
||||
loc.begin(), loc.iter())), region.size()); \
|
||||
} else { \
|
||||
std::cerr << "lexer " << lxr::pattern() << " failed with input `"; \
|
||||
std::cerr << "lexer failed with input `"; \
|
||||
std::cerr << token << "`. expected `" << expected << "`\n"; \
|
||||
std::cerr << "reason: " << result.unwrap_err() << '\n'; \
|
||||
} \
|
||||
|
||||
@@ -56,31 +56,24 @@ struct character
|
||||
static constexpr char target = C;
|
||||
|
||||
template<typename Cont>
|
||||
static result<region<Cont>, std::string>
|
||||
invoke(location<Cont>& loc, const bool msg = false)
|
||||
static result<region<Cont>, none_t>
|
||||
invoke(location<Cont>& loc)
|
||||
{
|
||||
static_assert(std::is_same<char, typename Cont::value_type>::value,
|
||||
"internal error: container::value_type should be `char`.");
|
||||
|
||||
if(loc.iter() == loc.end()) {return err("not sufficient characters");}
|
||||
if(loc.iter() == loc.end()) {return none();}
|
||||
const auto first = loc.iter();
|
||||
|
||||
const char c = *(loc.iter());
|
||||
if(c != target)
|
||||
{
|
||||
if(msg)
|
||||
{
|
||||
return err(concat_to_string("expected '", show_char(target),
|
||||
"' but got '", show_char(c), "'."));
|
||||
}
|
||||
return err("");
|
||||
return none();
|
||||
}
|
||||
loc.advance(); // update location
|
||||
|
||||
return ok(region<Cont>(loc, first, loc.iter()));
|
||||
}
|
||||
|
||||
static std::string pattern() {return show_char(target);}
|
||||
};
|
||||
template<char C>
|
||||
constexpr char character<C>::target;
|
||||
@@ -96,35 +89,24 @@ struct in_range
|
||||
static constexpr char lower = Low;
|
||||
|
||||
template<typename Cont>
|
||||
static result<region<Cont>, std::string>
|
||||
invoke(location<Cont>& loc, const bool msg = false)
|
||||
static result<region<Cont>, none_t>
|
||||
invoke(location<Cont>& loc)
|
||||
{
|
||||
static_assert(std::is_same<char, typename Cont::value_type>::value,
|
||||
"internal error: container::value_type should be `char`.");
|
||||
|
||||
if(loc.iter() == loc.end()) {return err("not sufficient characters");}
|
||||
if(loc.iter() == loc.end()) {return none();}
|
||||
const auto first = loc.iter();
|
||||
|
||||
const char c = *(loc.iter());
|
||||
if(c < lower || upper < c)
|
||||
{
|
||||
if(msg)
|
||||
{
|
||||
return err(concat_to_string("expected character in range "
|
||||
"[", show_char(lower), ", ", show_char(upper), "] but got ",
|
||||
"'", show_char(c), "'."));
|
||||
}
|
||||
return err("");
|
||||
return none();
|
||||
}
|
||||
|
||||
loc.advance();
|
||||
return ok(region<Cont>(loc, first, loc.iter()));
|
||||
}
|
||||
|
||||
static std::string pattern()
|
||||
{
|
||||
return concat_to_string("[",show_char(lower),"-",show_char(upper),"]");
|
||||
}
|
||||
};
|
||||
template<char L, char U> constexpr char in_range<L, U>::upper;
|
||||
template<char L, char U> constexpr char in_range<L, U>::lower;
|
||||
@@ -135,34 +117,24 @@ template<typename Combinator>
|
||||
struct exclude
|
||||
{
|
||||
template<typename Cont>
|
||||
static result<region<Cont>, std::string>
|
||||
invoke(location<Cont>& loc, const bool msg = false)
|
||||
static result<region<Cont>, none_t>
|
||||
invoke(location<Cont>& loc)
|
||||
{
|
||||
static_assert(std::is_same<char, typename Cont::value_type>::value,
|
||||
"internal error: container::value_type should be `char`.");
|
||||
|
||||
if(loc.iter() == loc.end()) {return err("not sufficient characters");}
|
||||
if(loc.iter() == loc.end()) {return none();}
|
||||
auto first = loc.iter();
|
||||
|
||||
auto rslt = Combinator::invoke(loc, msg);
|
||||
auto rslt = Combinator::invoke(loc);
|
||||
if(rslt.is_ok())
|
||||
{
|
||||
loc.reset(first);
|
||||
if(msg)
|
||||
{
|
||||
return err(concat_to_string("invalid pattern (",
|
||||
Combinator::pattern(), ") appeared ", rslt.unwrap().str()));
|
||||
}
|
||||
return err("");
|
||||
return none();
|
||||
}
|
||||
loc.reset(std::next(first)); // XXX maybe loc.advance() is okay but...
|
||||
return ok(region<Cont>(loc, first, loc.iter()));
|
||||
}
|
||||
|
||||
static std::string pattern()
|
||||
{
|
||||
return concat_to_string("^(", Combinator::pattern(), ')');
|
||||
}
|
||||
};
|
||||
|
||||
// increment `iter`, if matches. otherwise, just return empty string.
|
||||
@@ -170,24 +142,19 @@ template<typename Combinator>
|
||||
struct maybe
|
||||
{
|
||||
template<typename Cont>
|
||||
static result<region<Cont>, std::string>
|
||||
invoke(location<Cont>& loc, const bool msg = false)
|
||||
static result<region<Cont>, none_t>
|
||||
invoke(location<Cont>& loc)
|
||||
{
|
||||
static_assert(std::is_same<char, typename Cont::value_type>::value,
|
||||
"internal error: container::value_type should be `char`.");
|
||||
|
||||
const auto rslt = Combinator::invoke(loc, msg);
|
||||
const auto rslt = Combinator::invoke(loc);
|
||||
if(rslt.is_ok())
|
||||
{
|
||||
return rslt;
|
||||
}
|
||||
return ok(region<Cont>(loc));
|
||||
}
|
||||
|
||||
static std::string pattern()
|
||||
{
|
||||
return concat_to_string('(', Combinator::pattern(), ")?");
|
||||
}
|
||||
};
|
||||
|
||||
template<typename ... Ts>
|
||||
@@ -197,41 +164,35 @@ template<typename Head, typename ... Tail>
|
||||
struct sequence<Head, Tail...>
|
||||
{
|
||||
template<typename Cont>
|
||||
static result<region<Cont>, std::string>
|
||||
invoke(location<Cont>& loc, const bool msg = false)
|
||||
static result<region<Cont>, none_t>
|
||||
invoke(location<Cont>& loc)
|
||||
{
|
||||
static_assert(std::is_same<char, typename Cont::value_type>::value,
|
||||
"internal error: container::value_type should be `char`.");
|
||||
|
||||
const auto first = loc.iter();
|
||||
const auto rslt = Head::invoke(loc, msg);
|
||||
const auto rslt = Head::invoke(loc);
|
||||
if(rslt.is_err())
|
||||
{
|
||||
loc.reset(first);
|
||||
return err(rslt.unwrap_err());
|
||||
return none();
|
||||
}
|
||||
return sequence<Tail...>::invoke(loc, std::move(rslt.unwrap()), first, msg);
|
||||
return sequence<Tail...>::invoke(loc, std::move(rslt.unwrap()), first);
|
||||
}
|
||||
|
||||
// called from the above function only, recursively.
|
||||
template<typename Cont, typename Iterator>
|
||||
static result<region<Cont>, std::string>
|
||||
invoke(location<Cont>& loc, region<Cont> reg, Iterator first,
|
||||
const bool msg = false)
|
||||
static result<region<Cont>, none_t>
|
||||
invoke(location<Cont>& loc, region<Cont> reg, Iterator first)
|
||||
{
|
||||
const auto rslt = Head::invoke(loc, msg);
|
||||
const auto rslt = Head::invoke(loc);
|
||||
if(rslt.is_err())
|
||||
{
|
||||
loc.reset(first);
|
||||
return err(rslt.unwrap_err());
|
||||
return none();
|
||||
}
|
||||
reg += rslt.unwrap(); // concat regions
|
||||
return sequence<Tail...>::invoke(loc, std::move(reg), first, msg);
|
||||
}
|
||||
|
||||
static std::string pattern()
|
||||
{
|
||||
return concat_to_string(Head::pattern(), sequence<Tail...>::pattern());
|
||||
return sequence<Tail...>::invoke(loc, std::move(reg), first);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -240,20 +201,18 @@ struct sequence<Head>
|
||||
{
|
||||
// would be called from sequence<T ...>::invoke only.
|
||||
template<typename Cont, typename Iterator>
|
||||
static result<region<Cont>, std::string>
|
||||
invoke(location<Cont>& loc, region<Cont> reg, Iterator first,
|
||||
const bool msg = false)
|
||||
static result<region<Cont>, none_t>
|
||||
invoke(location<Cont>& loc, region<Cont> reg, Iterator first)
|
||||
{
|
||||
const auto rslt = Head::invoke(loc, msg);
|
||||
const auto rslt = Head::invoke(loc);
|
||||
if(rslt.is_err())
|
||||
{
|
||||
loc.reset(first);
|
||||
return err(rslt.unwrap_err());
|
||||
return none();
|
||||
}
|
||||
reg += rslt.unwrap(); // concat regions
|
||||
return ok(reg);
|
||||
}
|
||||
static std::string pattern() {return Head::pattern();}
|
||||
};
|
||||
|
||||
template<typename ... Ts>
|
||||
@@ -263,36 +222,27 @@ template<typename Head, typename ... Tail>
|
||||
struct either<Head, Tail...>
|
||||
{
|
||||
template<typename Cont>
|
||||
static result<region<Cont>, std::string>
|
||||
invoke(location<Cont>& loc, const bool msg = false)
|
||||
static result<region<Cont>, none_t>
|
||||
invoke(location<Cont>& loc)
|
||||
{
|
||||
static_assert(std::is_same<char, typename Cont::value_type>::value,
|
||||
"internal error: container::value_type should be `char`.");
|
||||
|
||||
const auto rslt = Head::invoke(loc, msg);
|
||||
const auto rslt = Head::invoke(loc);
|
||||
if(rslt.is_ok()) {return rslt;}
|
||||
return either<Tail...>::invoke(loc, msg);
|
||||
}
|
||||
|
||||
static std::string pattern()
|
||||
{
|
||||
return concat_to_string('(', Head::pattern(), ")|", either<Tail...>::pattern());
|
||||
return either<Tail...>::invoke(loc);
|
||||
}
|
||||
};
|
||||
template<typename Head>
|
||||
struct either<Head>
|
||||
{
|
||||
template<typename Cont>
|
||||
static result<region<Cont>, std::string>
|
||||
invoke(location<Cont>& loc, const bool msg = false)
|
||||
static result<region<Cont>, none_t>
|
||||
invoke(location<Cont>& loc)
|
||||
{
|
||||
static_assert(std::is_same<char, typename Cont::value_type>::value,
|
||||
"internal error: container::value_type should be `char`.");
|
||||
return Head::invoke(loc, msg);
|
||||
}
|
||||
static std::string pattern()
|
||||
{
|
||||
return concat_to_string('(', Head::pattern(), ')');
|
||||
return Head::invoke(loc);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -307,52 +257,48 @@ template<typename T, std::size_t N>
|
||||
struct repeat<T, exactly<N>>
|
||||
{
|
||||
template<typename Cont>
|
||||
static result<region<Cont>, std::string>
|
||||
invoke(location<Cont>& loc, const bool msg = false)
|
||||
static result<region<Cont>, none_t>
|
||||
invoke(location<Cont>& loc)
|
||||
{
|
||||
region<Cont> retval(loc);
|
||||
const auto first = loc.iter();
|
||||
for(std::size_t i=0; i<N; ++i)
|
||||
{
|
||||
auto rslt = T::invoke(loc, msg);
|
||||
auto rslt = T::invoke(loc);
|
||||
if(rslt.is_err())
|
||||
{
|
||||
loc.reset(first);
|
||||
return err(rslt.unwrap_err());
|
||||
return none();
|
||||
}
|
||||
retval += rslt.unwrap();
|
||||
}
|
||||
return ok(std::move(retval));
|
||||
}
|
||||
static std::string pattern()
|
||||
{
|
||||
return concat_to_string('(', T::pattern(), "){", N, '}');
|
||||
}
|
||||
};
|
||||
|
||||
template<typename T, std::size_t N>
|
||||
struct repeat<T, at_least<N>>
|
||||
{
|
||||
template<typename Cont>
|
||||
static result<region<Cont>, std::string>
|
||||
invoke(location<Cont>& loc, const bool msg = false)
|
||||
static result<region<Cont>, none_t>
|
||||
invoke(location<Cont>& loc)
|
||||
{
|
||||
region<Cont> retval(loc);
|
||||
|
||||
const auto first = loc.iter();
|
||||
for(std::size_t i=0; i<N; ++i)
|
||||
{
|
||||
auto rslt = T::invoke(loc, msg);
|
||||
auto rslt = T::invoke(loc);
|
||||
if(rslt.is_err())
|
||||
{
|
||||
loc.reset(first);
|
||||
return err(rslt.unwrap_err());
|
||||
return none();
|
||||
}
|
||||
retval += rslt.unwrap();
|
||||
}
|
||||
while(true)
|
||||
{
|
||||
auto rslt = T::invoke(loc, msg);
|
||||
auto rslt = T::invoke(loc);
|
||||
if(rslt.is_err())
|
||||
{
|
||||
return ok(std::move(retval));
|
||||
@@ -360,23 +306,19 @@ struct repeat<T, at_least<N>>
|
||||
retval += rslt.unwrap();
|
||||
}
|
||||
}
|
||||
static std::string pattern()
|
||||
{
|
||||
return concat_to_string('(',T::pattern(), "){", N, ",}");
|
||||
}
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
struct repeat<T, unlimited>
|
||||
{
|
||||
template<typename Cont>
|
||||
static result<region<Cont>, std::string>
|
||||
invoke(location<Cont>& loc, const bool msg = false)
|
||||
static result<region<Cont>, none_t>
|
||||
invoke(location<Cont>& loc)
|
||||
{
|
||||
region<Cont> retval(loc);
|
||||
while(true)
|
||||
{
|
||||
auto rslt = T::invoke(loc, msg);
|
||||
auto rslt = T::invoke(loc);
|
||||
if(rslt.is_err())
|
||||
{
|
||||
return ok(std::move(retval));
|
||||
@@ -384,7 +326,6 @@ struct repeat<T, unlimited>
|
||||
retval += rslt.unwrap();
|
||||
}
|
||||
}
|
||||
static std::string pattern() {return concat_to_string('(', T::pattern(), ")*");}
|
||||
};
|
||||
|
||||
} // detail
|
||||
|
||||
@@ -353,15 +353,15 @@ struct local_datetime
|
||||
explicit local_datetime(const std::chrono::system_clock::time_point& tp)
|
||||
{
|
||||
const auto t = std::chrono::system_clock::to_time_t(tp);
|
||||
std::tm time = detail::localtime_s(&t);
|
||||
std::tm ltime = detail::localtime_s(&t);
|
||||
|
||||
this->date = local_date(time);
|
||||
this->time = local_time(time);
|
||||
this->date = local_date(ltime);
|
||||
this->time = local_time(ltime);
|
||||
|
||||
// std::tm lacks subsecond information, so diff between tp and tm
|
||||
// can be used to get millisecond & microsecond information.
|
||||
const auto t_diff = tp -
|
||||
std::chrono::system_clock::from_time_t(std::mktime(&time));
|
||||
std::chrono::system_clock::from_time_t(std::mktime(<ime));
|
||||
this->time.millisecond = static_cast<std::uint16_t>(
|
||||
std::chrono::duration_cast<std::chrono::milliseconds>(t_diff).count());
|
||||
this->time.microsecond = static_cast<std::uint16_t>(
|
||||
|
||||
@@ -276,7 +276,7 @@ namespace detail
|
||||
{
|
||||
|
||||
template<typename T, std::size_t ...I>
|
||||
T get_tuple_impl(const toml::Array& a, index_sequence<I...>)
|
||||
T get_tuple_impl(const toml::array& a, index_sequence<I...>)
|
||||
{
|
||||
return std::make_tuple(
|
||||
::toml::get<typename std::tuple_element<I, T>::type>(a.at(I))...);
|
||||
|
||||
@@ -376,7 +376,7 @@ parse_ml_basic_string(location<Container>& loc)
|
||||
// immediate newline is ignored (if exists)
|
||||
/* discard return value */ lex_newline::invoke(inner_loc);
|
||||
|
||||
delim = err("tmp");
|
||||
delim = none();
|
||||
while(!delim)
|
||||
{
|
||||
using lex_unescaped_seq = repeat<
|
||||
@@ -432,7 +432,7 @@ parse_basic_string(location<Container>& loc)
|
||||
std::string retval;
|
||||
retval.reserve(token.unwrap().size());
|
||||
|
||||
quot = err("tmp");
|
||||
quot = none();
|
||||
while(!quot)
|
||||
{
|
||||
using lex_unescaped_seq = repeat<lex_basic_unescaped, unlimited>;
|
||||
@@ -587,23 +587,17 @@ parse_local_date(location<Container>& loc)
|
||||
const auto y = lex_date_fullyear::invoke(inner_loc);
|
||||
if(!y || inner_loc.iter() == inner_loc.end() || *inner_loc.iter() != '-')
|
||||
{
|
||||
const std::string msg = y.map_err_or_else(
|
||||
[](const std::string& msg) {return msg;}, "should be `-`");
|
||||
|
||||
throw internal_error(format_underline("[error]: "
|
||||
"toml::parse_inner_local_date: invalid year format",
|
||||
{{std::addressof(inner_loc), msg}}));
|
||||
{{std::addressof(inner_loc), "should be `-`"}}));
|
||||
}
|
||||
inner_loc.advance();
|
||||
const auto m = lex_date_month::invoke(inner_loc);
|
||||
if(!m || inner_loc.iter() == inner_loc.end() || *inner_loc.iter() != '-')
|
||||
{
|
||||
const std::string msg = m.map_err_or_else(
|
||||
[](const std::string& msg) {return msg;}, "should be `-`");
|
||||
|
||||
throw internal_error(format_underline("[error]: "
|
||||
"toml::parse_local_date: invalid month format",
|
||||
{{std::addressof(inner_loc), msg}}));
|
||||
{{std::addressof(inner_loc), "should be `-`"}}));
|
||||
}
|
||||
inner_loc.advance();
|
||||
const auto d = lex_date_mday::invoke(inner_loc);
|
||||
@@ -611,7 +605,7 @@ parse_local_date(location<Container>& loc)
|
||||
{
|
||||
throw internal_error(format_underline("[error]: "
|
||||
"toml::parse_local_date: invalid day format",
|
||||
{{std::addressof(inner_loc), d.unwrap_err()}}));
|
||||
{{std::addressof(inner_loc), "here"}}));
|
||||
}
|
||||
return ok(std::make_pair(local_date(
|
||||
static_cast<std::int16_t>(from_string<int>(y.unwrap().str(), 0)),
|
||||
@@ -640,23 +634,17 @@ parse_local_time(location<Container>& loc)
|
||||
const auto h = lex_time_hour::invoke(inner_loc);
|
||||
if(!h || inner_loc.iter() == inner_loc.end() || *inner_loc.iter() != ':')
|
||||
{
|
||||
const std::string msg = h.map_err_or_else(
|
||||
[](const std::string& msg) {return msg;}, "should be `:`");
|
||||
|
||||
throw internal_error(format_underline("[error]: "
|
||||
"toml::parse_local_time: invalid year format",
|
||||
{{std::addressof(inner_loc), msg}}));
|
||||
{{std::addressof(inner_loc), "should be `:`"}}));
|
||||
}
|
||||
inner_loc.advance();
|
||||
const auto m = lex_time_minute::invoke(inner_loc);
|
||||
if(!m || inner_loc.iter() == inner_loc.end() || *inner_loc.iter() != ':')
|
||||
{
|
||||
const std::string msg = m.map_err_or_else(
|
||||
[](const std::string& msg) {return msg;}, "should be `:`");
|
||||
|
||||
throw internal_error(format_underline("[error]: "
|
||||
"toml::parse_local_time: invalid month format",
|
||||
{{std::addressof(inner_loc), msg}}));
|
||||
{{std::addressof(inner_loc), "should be `:`"}}));
|
||||
}
|
||||
inner_loc.advance();
|
||||
const auto s = lex_time_second::invoke(inner_loc);
|
||||
@@ -664,7 +652,7 @@ parse_local_time(location<Container>& loc)
|
||||
{
|
||||
throw internal_error(format_underline("[error]: "
|
||||
"toml::parse_local_time: invalid second format",
|
||||
{{std::addressof(inner_loc), s.unwrap_err()}}));
|
||||
{{std::addressof(inner_loc), "here"}}));
|
||||
}
|
||||
local_time time(
|
||||
static_cast<std::int8_t>(from_string<int>(h.unwrap().str(), 0)),
|
||||
@@ -700,7 +688,7 @@ parse_local_time(location<Container>& loc)
|
||||
{
|
||||
throw internal_error(format_underline("[error]: "
|
||||
"toml::parse_local_time: invalid subsecond format",
|
||||
{{std::addressof(inner_loc), secfrac.unwrap_err()}}));
|
||||
{{std::addressof(inner_loc), "here"}}));
|
||||
}
|
||||
}
|
||||
return ok(std::make_pair(time, token.unwrap()));
|
||||
@@ -724,12 +712,9 @@ parse_local_datetime(location<Container>& loc)
|
||||
const auto date = parse_local_date(inner_loc);
|
||||
if(!date || inner_loc.iter() == inner_loc.end())
|
||||
{
|
||||
const std::string msg = date.map_err_or_else(
|
||||
[](const std::string& msg) {return msg;}, "date, not datetime");
|
||||
|
||||
throw internal_error(format_underline("[error]: "
|
||||
"toml::parse_local_datetime: invalid datetime format",
|
||||
{{std::addressof(inner_loc), msg}}));
|
||||
{{std::addressof(inner_loc), "date, not datetime"}}));
|
||||
}
|
||||
const char delim = *(inner_loc.iter());
|
||||
if(delim != 'T' && delim != 't' && delim != ' ')
|
||||
@@ -769,12 +754,9 @@ parse_offset_datetime(location<Container>& loc)
|
||||
const auto datetime = parse_local_datetime(inner_loc);
|
||||
if(!datetime || inner_loc.iter() == inner_loc.end())
|
||||
{
|
||||
const std::string msg = datetime.map_err_or_else(
|
||||
[](const std::string& msg){return msg;}, "date, not datetime");
|
||||
|
||||
throw internal_error(format_underline("[error]: "
|
||||
"toml::parse_offset_datetime: invalid datetime format",
|
||||
{{std::addressof(inner_loc), msg}}));
|
||||
{{std::addressof(inner_loc), "date, not datetime"}}));
|
||||
}
|
||||
time_offset offset(0, 0);
|
||||
if(const auto ofs = lex_time_numoffset::invoke(inner_loc))
|
||||
@@ -1167,7 +1149,7 @@ insert_nested_key(table& root, const toml::value& v,
|
||||
{
|
||||
if(tab->count(k) == 1) // there is already an array of table
|
||||
{
|
||||
if(tab->at(k).is(value_t::Table))
|
||||
if(tab->at(k).is_table())
|
||||
{
|
||||
// show special err msg for conflicting table
|
||||
throw syntax_error(format_underline(concat_to_string(
|
||||
@@ -1180,7 +1162,7 @@ insert_nested_key(table& root, const toml::value& v,
|
||||
"this conflicts with the previous table"}
|
||||
}));
|
||||
}
|
||||
else if(!(tab->at(k).is(value_t::Array)))
|
||||
else if(!(tab->at(k).is_array()))
|
||||
{
|
||||
throw syntax_error(format_underline(concat_to_string(
|
||||
"[error] toml::insert_value: array of table (\"",
|
||||
@@ -1193,8 +1175,9 @@ insert_nested_key(table& root, const toml::value& v,
|
||||
"while inserting this array-of-tables"}
|
||||
}));
|
||||
}
|
||||
array& a = tab->at(k).template cast<toml::value_t::Array>();
|
||||
if(!(a.front().is(value_t::Table)))
|
||||
// the above if-else-if checks tab->at(k) is an array
|
||||
array& a = tab->at(k).as_array();
|
||||
if(!(a.front().is_table()))
|
||||
{
|
||||
throw syntax_error(format_underline(concat_to_string(
|
||||
"[error] toml::insert_value: array of table (\"",
|
||||
@@ -1248,7 +1231,7 @@ insert_nested_key(table& root, const toml::value& v,
|
||||
|
||||
if(tab->count(k) == 1)
|
||||
{
|
||||
if(tab->at(k).is(value_t::Table) && v.is(value_t::Table))
|
||||
if(tab->at(k).is_table() && v.is_table())
|
||||
{
|
||||
if(!is_valid_forward_table_definition(
|
||||
tab->at(k), first, iter, last))
|
||||
@@ -1268,18 +1251,18 @@ insert_nested_key(table& root, const toml::value& v,
|
||||
// d = 42
|
||||
// [a]
|
||||
// e = 2.71
|
||||
auto& t = tab->at(k).cast<value_t::Table>();
|
||||
for(const auto& kv : v.cast<value_t::Table>())
|
||||
auto& t = tab->at(k).as_table();
|
||||
for(const auto& kv : v.as_table())
|
||||
{
|
||||
t[kv.first] = kv.second;
|
||||
}
|
||||
detail::change_region(tab->at(k), key_reg);
|
||||
return ok(true);
|
||||
}
|
||||
else if(v.is(value_t::Table) &&
|
||||
tab->at(k).is(value_t::Array) &&
|
||||
tab->at(k).cast<value_t::Array>().size() > 0 &&
|
||||
tab->at(k).cast<value_t::Array>().front().is(value_t::Table))
|
||||
else if(v.is_table() &&
|
||||
tab->at(k).is_array() &&
|
||||
tab->at(k).as_array().size() > 0 &&
|
||||
tab->at(k).as_array().front().is_table())
|
||||
{
|
||||
throw syntax_error(format_underline(concat_to_string(
|
||||
"[error] toml::insert_value: array of tables (\"",
|
||||
@@ -1319,14 +1302,14 @@ insert_nested_key(table& root, const toml::value& v,
|
||||
}
|
||||
|
||||
// type checking...
|
||||
if(tab->at(k).is(value_t::Table))
|
||||
if(tab->at(k).is_table())
|
||||
{
|
||||
tab = std::addressof((*tab)[k].template cast<value_t::Table>());
|
||||
tab = std::addressof((*tab)[k].as_table());
|
||||
}
|
||||
else if(tab->at(k).is(value_t::Array)) // inserting to array-of-tables?
|
||||
else if(tab->at(k).is_array()) // inserting to array-of-tables?
|
||||
{
|
||||
array& a = (*tab)[k].template cast<value_t::Array>();
|
||||
if(!a.back().is(value_t::Table))
|
||||
array& a = (*tab)[k].as_array();
|
||||
if(!a.back().is_table())
|
||||
{
|
||||
throw syntax_error(format_underline(concat_to_string(
|
||||
"[error] toml::insert_value: target (",
|
||||
@@ -1337,7 +1320,7 @@ insert_nested_key(table& root, const toml::value& v,
|
||||
{std::addressof(get_region(v)), "inserting this"}
|
||||
}));
|
||||
}
|
||||
tab = std::addressof(a.back().template cast<value_t::Table>());
|
||||
tab = std::addressof(a.back().as_table());
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -1560,7 +1543,7 @@ template<typename Container>
|
||||
result<std::pair<std::vector<key>, region<Container>>, std::string>
|
||||
parse_array_table_key(location<Container>& loc)
|
||||
{
|
||||
if(auto token = lex_array_table::invoke(loc, true))
|
||||
if(auto token = lex_array_table::invoke(loc))
|
||||
{
|
||||
location<std::string> inner_loc(loc.name(), token.unwrap().str());
|
||||
|
||||
@@ -1672,12 +1655,12 @@ result<table, std::string> parse_ml_table(location<Container>& loc)
|
||||
const auto newline = skip_line::invoke(loc);
|
||||
if(!newline && loc.iter() != loc.end())
|
||||
{
|
||||
const auto before = loc.iter();
|
||||
const auto before2 = loc.iter();
|
||||
lex_ws::invoke(loc); // skip whitespace
|
||||
const auto msg = format_underline("[error] toml::parse_table: "
|
||||
"invalid line format", {{std::addressof(loc), concat_to_string(
|
||||
"expected newline, but got '", show_char(*loc.iter()), "'.")}});
|
||||
loc.reset(before);
|
||||
loc.reset(before2);
|
||||
return err(msg);
|
||||
}
|
||||
|
||||
|
||||
@@ -113,21 +113,25 @@ struct result
|
||||
{
|
||||
auto tmp = ::new(std::addressof(this->succ)) success_type(s);
|
||||
assert(tmp == std::addressof(this->succ));
|
||||
(void)tmp;
|
||||
}
|
||||
result(const failure_type& f): is_ok_(false)
|
||||
{
|
||||
auto tmp = ::new(std::addressof(this->fail)) failure_type(f);
|
||||
assert(tmp == std::addressof(this->fail));
|
||||
(void)tmp;
|
||||
}
|
||||
result(success_type&& s): is_ok_(true)
|
||||
{
|
||||
auto tmp = ::new(std::addressof(this->succ)) success_type(std::move(s));
|
||||
assert(tmp == std::addressof(this->succ));
|
||||
(void)tmp;
|
||||
}
|
||||
result(failure_type&& f): is_ok_(false)
|
||||
{
|
||||
auto tmp = ::new(std::addressof(this->fail)) failure_type(std::move(f));
|
||||
assert(tmp == std::addressof(this->fail));
|
||||
(void)tmp;
|
||||
}
|
||||
|
||||
template<typename U>
|
||||
@@ -135,24 +139,28 @@ struct result
|
||||
{
|
||||
auto tmp = ::new(std::addressof(this->succ)) success_type(s.value);
|
||||
assert(tmp == std::addressof(this->succ));
|
||||
(void)tmp;
|
||||
}
|
||||
template<typename U>
|
||||
result(const failure<U>& f): is_ok_(false)
|
||||
{
|
||||
auto tmp = ::new(std::addressof(this->fail)) failure_type(f.value);
|
||||
assert(tmp == std::addressof(this->fail));
|
||||
(void)tmp;
|
||||
}
|
||||
template<typename U>
|
||||
result(success<U>&& s): is_ok_(true)
|
||||
{
|
||||
auto tmp = ::new(std::addressof(this->succ)) success_type(std::move(s.value));
|
||||
assert(tmp == std::addressof(this->succ));
|
||||
(void)tmp;
|
||||
}
|
||||
template<typename U>
|
||||
result(failure<U>&& f): is_ok_(false)
|
||||
{
|
||||
auto tmp = ::new(std::addressof(this->fail)) failure_type(std::move(f.value));
|
||||
assert(tmp == std::addressof(this->fail));
|
||||
(void)tmp;
|
||||
}
|
||||
|
||||
result& operator=(const success_type& s)
|
||||
@@ -161,6 +169,7 @@ struct result
|
||||
this->is_ok_ = true;
|
||||
auto tmp = ::new(std::addressof(this->succ)) success_type(s);
|
||||
assert(tmp == std::addressof(this->succ));
|
||||
(void)tmp;
|
||||
return *this;
|
||||
}
|
||||
result& operator=(const failure_type& f)
|
||||
@@ -169,6 +178,7 @@ struct result
|
||||
this->is_ok_ = false;
|
||||
auto tmp = ::new(std::addressof(this->fail)) failure_type(f);
|
||||
assert(tmp == std::addressof(this->fail));
|
||||
(void)tmp;
|
||||
return *this;
|
||||
}
|
||||
result& operator=(success_type&& s)
|
||||
@@ -177,6 +187,7 @@ struct result
|
||||
this->is_ok_ = true;
|
||||
auto tmp = ::new(std::addressof(this->succ)) success_type(std::move(s));
|
||||
assert(tmp == std::addressof(this->succ));
|
||||
(void)tmp;
|
||||
return *this;
|
||||
}
|
||||
result& operator=(failure_type&& f)
|
||||
@@ -185,6 +196,7 @@ struct result
|
||||
this->is_ok_ = false;
|
||||
auto tmp = ::new(std::addressof(this->fail)) failure_type(std::move(f));
|
||||
assert(tmp == std::addressof(this->fail));
|
||||
(void)tmp;
|
||||
return *this;
|
||||
}
|
||||
|
||||
@@ -195,6 +207,7 @@ struct result
|
||||
this->is_ok_ = true;
|
||||
auto tmp = ::new(std::addressof(this->succ)) success_type(s.value);
|
||||
assert(tmp == std::addressof(this->succ));
|
||||
(void)tmp;
|
||||
return *this;
|
||||
}
|
||||
template<typename U>
|
||||
@@ -204,6 +217,7 @@ struct result
|
||||
this->is_ok_ = false;
|
||||
auto tmp = ::new(std::addressof(this->fail)) failure_type(f.value);
|
||||
assert(tmp == std::addressof(this->fail));
|
||||
(void)tmp;
|
||||
return *this;
|
||||
}
|
||||
template<typename U>
|
||||
@@ -213,6 +227,7 @@ struct result
|
||||
this->is_ok_ = true;
|
||||
auto tmp = ::new(std::addressof(this->succ)) success_type(std::move(s.value));
|
||||
assert(tmp == std::addressof(this->succ));
|
||||
(void)tmp;
|
||||
return *this;
|
||||
}
|
||||
template<typename U>
|
||||
@@ -222,6 +237,7 @@ struct result
|
||||
this->is_ok_ = false;
|
||||
auto tmp = ::new(std::addressof(this->fail)) failure_type(std::move(f.value));
|
||||
assert(tmp == std::addressof(this->fail));
|
||||
(void)tmp;
|
||||
return *this;
|
||||
}
|
||||
|
||||
@@ -233,11 +249,13 @@ struct result
|
||||
{
|
||||
auto tmp = ::new(std::addressof(this->succ)) success_type(other.as_ok());
|
||||
assert(tmp == std::addressof(this->succ));
|
||||
(void)tmp;
|
||||
}
|
||||
else
|
||||
{
|
||||
auto tmp = ::new(std::addressof(this->fail)) failure_type(other.as_err());
|
||||
assert(tmp == std::addressof(this->fail));
|
||||
(void)tmp;
|
||||
}
|
||||
}
|
||||
result(result&& other): is_ok_(other.is_ok())
|
||||
@@ -246,11 +264,13 @@ struct result
|
||||
{
|
||||
auto tmp = ::new(std::addressof(this->succ)) success_type(std::move(other.as_ok()));
|
||||
assert(tmp == std::addressof(this->succ));
|
||||
(void)tmp;
|
||||
}
|
||||
else
|
||||
{
|
||||
auto tmp = ::new(std::addressof(this->fail)) failure_type(std::move(other.as_err()));
|
||||
assert(tmp == std::addressof(this->fail));
|
||||
(void)tmp;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -261,11 +281,13 @@ struct result
|
||||
{
|
||||
auto tmp = ::new(std::addressof(this->succ)) success_type(other.as_ok());
|
||||
assert(tmp == std::addressof(this->succ));
|
||||
(void)tmp;
|
||||
}
|
||||
else
|
||||
{
|
||||
auto tmp = ::new(std::addressof(this->fail)) failure_type(other.as_err());
|
||||
assert(tmp == std::addressof(this->fail));
|
||||
(void)tmp;
|
||||
}
|
||||
}
|
||||
template<typename U, typename F>
|
||||
@@ -275,11 +297,13 @@ struct result
|
||||
{
|
||||
auto tmp = ::new(std::addressof(this->succ)) success_type(std::move(other.as_ok()));
|
||||
assert(tmp == std::addressof(this->succ));
|
||||
(void)tmp;
|
||||
}
|
||||
else
|
||||
{
|
||||
auto tmp = ::new(std::addressof(this->fail)) failure_type(std::move(other.as_err()));
|
||||
assert(tmp == std::addressof(this->fail));
|
||||
(void)tmp;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -290,11 +314,13 @@ struct result
|
||||
{
|
||||
auto tmp = ::new(std::addressof(this->succ)) success_type(other.as_ok());
|
||||
assert(tmp == std::addressof(this->succ));
|
||||
(void)tmp;
|
||||
}
|
||||
else
|
||||
{
|
||||
auto tmp = ::new(std::addressof(this->fail)) failure_type(other.as_err());
|
||||
assert(tmp == std::addressof(this->fail));
|
||||
(void)tmp;
|
||||
}
|
||||
is_ok_ = other.is_ok();
|
||||
return *this;
|
||||
@@ -306,11 +332,13 @@ struct result
|
||||
{
|
||||
auto tmp = ::new(std::addressof(this->succ)) success_type(std::move(other.as_ok()));
|
||||
assert(tmp == std::addressof(this->succ));
|
||||
(void)tmp;
|
||||
}
|
||||
else
|
||||
{
|
||||
auto tmp = ::new(std::addressof(this->fail)) failure_type(std::move(other.as_err()));
|
||||
assert(tmp == std::addressof(this->fail));
|
||||
(void)tmp;
|
||||
}
|
||||
is_ok_ = other.is_ok();
|
||||
return *this;
|
||||
@@ -324,11 +352,13 @@ struct result
|
||||
{
|
||||
auto tmp = ::new(std::addressof(this->succ)) success_type(other.as_ok());
|
||||
assert(tmp == std::addressof(this->succ));
|
||||
(void)tmp;
|
||||
}
|
||||
else
|
||||
{
|
||||
auto tmp = ::new(std::addressof(this->fail)) failure_type(other.as_err());
|
||||
assert(tmp == std::addressof(this->fail));
|
||||
(void)tmp;
|
||||
}
|
||||
is_ok_ = other.is_ok();
|
||||
return *this;
|
||||
@@ -341,11 +371,13 @@ struct result
|
||||
{
|
||||
auto tmp = ::new(std::addressof(this->succ)) success_type(std::move(other.as_ok()));
|
||||
assert(tmp == std::addressof(this->succ));
|
||||
(void)tmp;
|
||||
}
|
||||
else
|
||||
{
|
||||
auto tmp = ::new(std::addressof(this->fail)) failure_type(std::move(other.as_err()));
|
||||
assert(tmp == std::addressof(this->fail));
|
||||
(void)tmp;
|
||||
}
|
||||
is_ok_ = other.is_ok();
|
||||
return *this;
|
||||
@@ -660,5 +692,26 @@ void swap(result<T, E>& lhs, result<T, E>& rhs)
|
||||
// return lhs.is_ok() ? lhs : rhs;
|
||||
// }
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// re-use result<T, E> as a optional<T> with none_t
|
||||
|
||||
namespace detail
|
||||
{
|
||||
struct none_t {};
|
||||
inline bool operator==(const none_t&, const none_t&) noexcept {return true;}
|
||||
inline bool operator!=(const none_t&, const none_t&) noexcept {return false;}
|
||||
inline bool operator< (const none_t&, const none_t&) noexcept {return false;}
|
||||
inline bool operator<=(const none_t&, const none_t&) noexcept {return true;}
|
||||
inline bool operator> (const none_t&, const none_t&) noexcept {return false;}
|
||||
inline bool operator>=(const none_t&, const none_t&) noexcept {return true;}
|
||||
template<typename charT, typename traitsT>
|
||||
std::basic_ostream<charT, traitsT>&
|
||||
operator<<(std::basic_ostream<charT, traitsT>& os, const none_t&)
|
||||
{
|
||||
os << "none";
|
||||
return os;
|
||||
}
|
||||
inline failure<none_t> none() noexcept {return failure<none_t>{none_t{}};}
|
||||
} // detail
|
||||
} // toml11
|
||||
#endif// TOML11_RESULT_H
|
||||
|
||||
@@ -157,7 +157,7 @@ struct serializer
|
||||
|
||||
std::string operator()(const array& v) const
|
||||
{
|
||||
if(!v.empty() && v.front().is(value_t::Table))// v is an array of tables
|
||||
if(!v.empty() && v.front().is_table())// v is an array of tables
|
||||
{
|
||||
// if it's not inlined, we need to add `[[table.key]]`.
|
||||
// but if it can be inlined, we need `table.key = [...]`.
|
||||
@@ -411,7 +411,7 @@ struct serializer
|
||||
// remaining non-table values will be assigned into [foo.bar], not [foo]
|
||||
for(const auto kv : v)
|
||||
{
|
||||
if(kv.second.is(value_t::Table) || is_array_of_tables(kv.second))
|
||||
if(kv.second.is_table() || is_array_of_tables(kv.second))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
@@ -438,7 +438,7 @@ struct serializer
|
||||
bool multiline_table_printed = false;
|
||||
for(const auto& kv : v)
|
||||
{
|
||||
if(!kv.second.is(value_t::Table) && !is_array_of_tables(kv.second))
|
||||
if(!kv.second.is_table() && !is_array_of_tables(kv.second))
|
||||
{
|
||||
continue; // other stuff are already serialized. skip them.
|
||||
}
|
||||
@@ -467,10 +467,9 @@ struct serializer
|
||||
|
||||
bool is_array_of_tables(const value& v) const
|
||||
{
|
||||
if(!v.is(value_t::Array)) {return false;}
|
||||
|
||||
const auto& a = v.cast<value_t::Array>();
|
||||
return !a.empty() && a.front().is(value_t::Table);
|
||||
if(!v.is_array()) {return false;}
|
||||
const auto& a = v.as_array();
|
||||
return !a.empty() && a.front().is_table();
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
@@ -132,29 +132,29 @@ template<> struct toml_default_type<value_t::Empty > {typedef void
|
||||
template<> struct toml_default_type<value_t::Unknown > {typedef void type;};
|
||||
|
||||
template<typename T> struct toml_value_t {static constexpr value_t value = value_t::Unknown ;};
|
||||
template<> struct toml_value_t<Boolean >{static constexpr value_t value = value_t::Boolean ;};
|
||||
template<> struct toml_value_t<Integer >{static constexpr value_t value = value_t::Integer ;};
|
||||
template<> struct toml_value_t<Float >{static constexpr value_t value = value_t::Float ;};
|
||||
template<> struct toml_value_t<String >{static constexpr value_t value = value_t::String ;};
|
||||
template<> struct toml_value_t<OffsetDatetime>{static constexpr value_t value = value_t::OffsetDatetime;};
|
||||
template<> struct toml_value_t<LocalDatetime >{static constexpr value_t value = value_t::LocalDatetime ;};
|
||||
template<> struct toml_value_t<LocalDate >{static constexpr value_t value = value_t::LocalDate ;};
|
||||
template<> struct toml_value_t<LocalTime >{static constexpr value_t value = value_t::LocalTime ;};
|
||||
template<> struct toml_value_t<Array >{static constexpr value_t value = value_t::Array ;};
|
||||
template<> struct toml_value_t<Table >{static constexpr value_t value = value_t::Table ;};
|
||||
template<> struct toml_value_t<boolean >{static constexpr value_t value = value_t::Boolean ;};
|
||||
template<> struct toml_value_t<integer >{static constexpr value_t value = value_t::Integer ;};
|
||||
template<> struct toml_value_t<floating >{static constexpr value_t value = value_t::Float ;};
|
||||
template<> struct toml_value_t<string >{static constexpr value_t value = value_t::String ;};
|
||||
template<> struct toml_value_t<offset_datetime>{static constexpr value_t value = value_t::OffsetDatetime;};
|
||||
template<> struct toml_value_t<local_datetime >{static constexpr value_t value = value_t::LocalDatetime ;};
|
||||
template<> struct toml_value_t<local_date >{static constexpr value_t value = value_t::LocalDate ;};
|
||||
template<> struct toml_value_t<local_time >{static constexpr value_t value = value_t::LocalTime ;};
|
||||
template<> struct toml_value_t<array >{static constexpr value_t value = value_t::Array ;};
|
||||
template<> struct toml_value_t<table >{static constexpr value_t value = value_t::Table ;};
|
||||
|
||||
template<typename T>
|
||||
struct is_exact_toml_type : disjunction<
|
||||
std::is_same<T, Boolean >,
|
||||
std::is_same<T, Integer >,
|
||||
std::is_same<T, Float >,
|
||||
std::is_same<T, String >,
|
||||
std::is_same<T, boolean >,
|
||||
std::is_same<T, integer >,
|
||||
std::is_same<T, floating >,
|
||||
std::is_same<T, string >,
|
||||
std::is_same<T, offset_datetime>,
|
||||
std::is_same<T, local_datetime >,
|
||||
std::is_same<T, local_date >,
|
||||
std::is_same<T, local_time >,
|
||||
std::is_same<T, Array >,
|
||||
std::is_same<T, Table >
|
||||
std::is_same<T, array >,
|
||||
std::is_same<T, table >
|
||||
>{};
|
||||
template<typename T> struct is_exact_toml_type<T&> : is_exact_toml_type<T>{};
|
||||
template<typename T> struct is_exact_toml_type<T const&> : is_exact_toml_type<T>{};
|
||||
|
||||
@@ -79,7 +79,7 @@ std::string concat_to_string(Ts&& ... args)
|
||||
template<typename T, typename U>
|
||||
T from_string(const std::string& str, U&& opt)
|
||||
{
|
||||
T v(std::forward<U>(opt));
|
||||
T v(static_cast<T>(std::forward<U>(opt)));
|
||||
std::istringstream iss(str);
|
||||
iss >> v;
|
||||
return v;
|
||||
|
||||
334
toml/value.hpp
334
toml/value.hpp
@@ -48,6 +48,7 @@ class value
|
||||
{
|
||||
const auto tmp = ::new(std::addressof(dst)) T(std::forward<U>(v));
|
||||
assert(tmp == std::addressof(dst));
|
||||
(void)tmp;
|
||||
}
|
||||
|
||||
using region_base = detail::region_base;
|
||||
@@ -633,27 +634,38 @@ class value
|
||||
template<value_t T>
|
||||
typename detail::toml_default_type<T>::type&& cast() &&;
|
||||
|
||||
boolean const& as_boolean() const {return this->cast<value_t::Boolean >();}
|
||||
integer const& as_integer() const {return this->cast<value_t::Integer >();}
|
||||
floating const& as_float() const {return this->cast<value_t::Float >();}
|
||||
string const& as_string() const {return this->cast<value_t::String >();}
|
||||
offset_datetime const& as_offset_datetime() const {return this->cast<value_t::OffsetDatetime>();}
|
||||
local_datetime const& as_local_datetime() const {return this->cast<value_t::LocalDatetime >();}
|
||||
local_date const& as_local_date() const {return this->cast<value_t::LocalDate >();}
|
||||
local_time const& as_local_time() const {return this->cast<value_t::LocalTime >();}
|
||||
array const& as_array() const {return this->cast<value_t::Array >();}
|
||||
table const& as_table() const {return this->cast<value_t::Table >();}
|
||||
boolean const& as_boolean() const& noexcept {return this->boolean_;}
|
||||
integer const& as_integer() const& noexcept {return this->integer_;}
|
||||
floating const& as_float() const& noexcept {return this->floating_;}
|
||||
string const& as_string() const& noexcept {return this->string_;}
|
||||
offset_datetime const& as_offset_datetime() const& noexcept {return this->offset_datetime_;}
|
||||
local_datetime const& as_local_datetime() const& noexcept {return this->local_datetime_;}
|
||||
local_date const& as_local_date() const& noexcept {return this->local_date_;}
|
||||
local_time const& as_local_time() const& noexcept {return this->local_time_;}
|
||||
array const& as_array() const& noexcept {return this->array_.value();}
|
||||
table const& as_table() const& noexcept {return this->table_.value();}
|
||||
|
||||
boolean& as_boolean() {return this->cast<value_t::Boolean >();}
|
||||
integer& as_integer() {return this->cast<value_t::Integer >();}
|
||||
floating& as_float() {return this->cast<value_t::Float >();}
|
||||
string& as_string() {return this->cast<value_t::String >();}
|
||||
offset_datetime& as_offset_datetime() {return this->cast<value_t::OffsetDatetime>();}
|
||||
local_datetime& as_local_datetime() {return this->cast<value_t::LocalDatetime >();}
|
||||
local_date& as_local_date() {return this->cast<value_t::LocalDate >();}
|
||||
local_time& as_local_time() {return this->cast<value_t::LocalTime >();}
|
||||
array& as_array() {return this->cast<value_t::Array >();}
|
||||
table& as_table() {return this->cast<value_t::Table >();}
|
||||
boolean & as_boolean() & noexcept {return this->boolean_;}
|
||||
integer & as_integer() & noexcept {return this->integer_;}
|
||||
floating & as_float() & noexcept {return this->floating_;}
|
||||
string & as_string() & noexcept {return this->string_;}
|
||||
offset_datetime& as_offset_datetime() & noexcept {return this->offset_datetime_;}
|
||||
local_datetime & as_local_datetime() & noexcept {return this->local_datetime_;}
|
||||
local_date & as_local_date() & noexcept {return this->local_date_;}
|
||||
local_time & as_local_time() & noexcept {return this->local_time_;}
|
||||
array & as_array() & noexcept {return this->array_.value();}
|
||||
table & as_table() & noexcept {return this->table_.value();}
|
||||
|
||||
boolean && as_boolean() && noexcept {return std::move(this->boolean_);}
|
||||
integer && as_integer() && noexcept {return std::move(this->integer_);}
|
||||
floating && as_float() && noexcept {return std::move(this->floating_);}
|
||||
string && as_string() && noexcept {return std::move(this->string_);}
|
||||
offset_datetime&& as_offset_datetime() && noexcept {return std::move(this->offset_datetime_);}
|
||||
local_datetime && as_local_datetime() && noexcept {return std::move(this->local_datetime_);}
|
||||
local_date && as_local_date() && noexcept {return std::move(this->local_date_);}
|
||||
local_time && as_local_time() && noexcept {return std::move(this->local_time_);}
|
||||
array && as_array() && noexcept {return std::move(this->array_.value());}
|
||||
table && as_table() && noexcept {return std::move(this->table_.value());}
|
||||
|
||||
std::string comment() const
|
||||
{
|
||||
@@ -687,9 +699,6 @@ class value
|
||||
template<typename Region>
|
||||
friend void detail::change_region(value&, Region&&);
|
||||
|
||||
template<value_t T>
|
||||
struct switch_cast;
|
||||
|
||||
private:
|
||||
|
||||
using array_storage = detail::storage<array>;
|
||||
@@ -735,107 +744,116 @@ void change_region(value& v, Region&& reg)
|
||||
return;
|
||||
}
|
||||
|
||||
}// detail
|
||||
template<value_t Expected>
|
||||
[[noreturn]] inline void throw_bad_cast(value_t actual, const ::toml::value& v)
|
||||
{
|
||||
throw type_error(detail::format_underline(concat_to_string(
|
||||
"[error] toml::value bad_cast to ", Expected), {
|
||||
{std::addressof(get_region(v)),
|
||||
concat_to_string("the actual type is ", actual)}
|
||||
}));
|
||||
}
|
||||
|
||||
template<> struct value::switch_cast<value_t::Boolean>
|
||||
template<value_t T>
|
||||
struct switch_cast;
|
||||
template<>
|
||||
struct switch_cast<value_t::Boolean>
|
||||
{
|
||||
static Boolean& invoke(value& v) {return v.boolean_;}
|
||||
static Boolean const& invoke(value const& v) {return v.boolean_;}
|
||||
static Boolean&& invoke(value&& v) {return std::move(v.boolean_);}
|
||||
static ::toml::boolean& invoke(value& v) {return v.as_boolean();}
|
||||
static ::toml::boolean const& invoke(value const& v) {return v.as_boolean();}
|
||||
static ::toml::boolean&& invoke(value&& v) {return std::move(v).as_boolean();}
|
||||
};
|
||||
template<> struct value::switch_cast<value_t::Integer>
|
||||
template<>
|
||||
struct switch_cast<value_t::Integer>
|
||||
{
|
||||
static Integer& invoke(value& v) {return v.integer_;}
|
||||
static Integer const& invoke(value const& v) {return v.integer_;}
|
||||
static Integer&& invoke(value&& v) {return std::move(v.integer_);}
|
||||
static ::toml::integer& invoke(value& v) {return v.as_integer();}
|
||||
static ::toml::integer const& invoke(value const& v) {return v.as_integer();}
|
||||
static ::toml::integer&& invoke(value&& v) {return std::move(v).as_integer();}
|
||||
};
|
||||
template<> struct value::switch_cast<value_t::Float>
|
||||
template<>
|
||||
struct switch_cast<value_t::Float>
|
||||
{
|
||||
static Float& invoke(value& v) {return v.floating_;}
|
||||
static Float const& invoke(value const& v) {return v.floating_;}
|
||||
static Float&& invoke(value&& v) {return std::move(v.floating_);}
|
||||
static ::toml::floating& invoke(value& v) {return v.as_float();}
|
||||
static ::toml::floating const& invoke(value const& v) {return v.as_float();}
|
||||
static ::toml::floating&& invoke(value&& v) {return std::move(v).as_float();}
|
||||
};
|
||||
template<> struct value::switch_cast<value_t::String>
|
||||
template<>
|
||||
struct switch_cast<value_t::String>
|
||||
{
|
||||
static String& invoke(value& v) {return v.string_;}
|
||||
static String const& invoke(value const& v) {return v.string_;}
|
||||
static String&& invoke(value&& v) {return std::move(v.string_);}
|
||||
static ::toml::string& invoke(value& v) {return v.as_string();}
|
||||
static ::toml::string const& invoke(value const& v) {return v.as_string();}
|
||||
static ::toml::string&& invoke(value&& v) {return std::move(v).as_string();}
|
||||
};
|
||||
template<> struct value::switch_cast<value_t::OffsetDatetime>
|
||||
template<>
|
||||
struct switch_cast<value_t::OffsetDatetime>
|
||||
{
|
||||
static OffsetDatetime& invoke(value& v) {return v.offset_datetime_;}
|
||||
static OffsetDatetime const& invoke(value const& v) {return v.offset_datetime_;}
|
||||
static OffsetDatetime&& invoke(value&& v) {return std::move(v.offset_datetime_);}
|
||||
static ::toml::offset_datetime& invoke(value& v) {return v.as_offset_datetime();}
|
||||
static ::toml::offset_datetime const& invoke(value const& v) {return v.as_offset_datetime();}
|
||||
static ::toml::offset_datetime&& invoke(value&& v) {return std::move(v).as_offset_datetime();}
|
||||
};
|
||||
template<> struct value::switch_cast<value_t::LocalDatetime>
|
||||
template<>
|
||||
struct switch_cast<value_t::LocalDatetime>
|
||||
{
|
||||
static LocalDatetime& invoke(value& v) {return v.local_datetime_;}
|
||||
static LocalDatetime const& invoke(value const& v) {return v.local_datetime_;}
|
||||
static LocalDatetime&& invoke(value&& v) {return std::move(v.local_datetime_);}
|
||||
static ::toml::local_datetime& invoke(value& v) {return v.as_local_datetime();}
|
||||
static ::toml::local_datetime const& invoke(value const& v) {return v.as_local_datetime();}
|
||||
static ::toml::local_datetime&& invoke(value&& v) {return std::move(v).as_local_datetime();}
|
||||
};
|
||||
template<> struct value::switch_cast<value_t::LocalDate>
|
||||
template<>
|
||||
struct switch_cast<value_t::LocalDate>
|
||||
{
|
||||
static LocalDate& invoke(value& v) {return v.local_date_;}
|
||||
static LocalDate const& invoke(value const& v) {return v.local_date_;}
|
||||
static LocalDate&& invoke(value&& v) {return std::move(v.local_date_);}
|
||||
static ::toml::local_date& invoke(value& v) {return v.as_local_date();}
|
||||
static ::toml::local_date const& invoke(value const& v) {return v.as_local_date();}
|
||||
static ::toml::local_date&& invoke(value&& v) {return std::move(v).as_local_date();}
|
||||
};
|
||||
template<> struct value::switch_cast<value_t::LocalTime>
|
||||
template<>
|
||||
struct switch_cast<value_t::LocalTime>
|
||||
{
|
||||
static LocalTime& invoke(value& v) {return v.local_time_;}
|
||||
static LocalTime const& invoke(value const& v) {return v.local_time_;}
|
||||
static LocalTime&& invoke(value&& v) {return std::move(v.local_time_);}
|
||||
static ::toml::local_time& invoke(value& v) {return v.as_local_time();}
|
||||
static ::toml::local_time const& invoke(value const& v) {return v.as_local_time();}
|
||||
static ::toml::local_time&& invoke(value&& v) {return std::move(v).as_local_time();}
|
||||
};
|
||||
template<> struct value::switch_cast<value_t::Array>
|
||||
template<>
|
||||
struct switch_cast<value_t::Array>
|
||||
{
|
||||
static Array& invoke(value& v) {return v.array_.value();}
|
||||
static Array const& invoke(value const& v) {return v.array_.value();}
|
||||
static Array&& invoke(value&& v) {return std::move(v.array_.value());}
|
||||
static ::toml::array& invoke(value& v) {return v.as_array();}
|
||||
static ::toml::array const& invoke(value const& v) {return v.as_array();}
|
||||
static ::toml::array&& invoke(value&& v) {return std::move(v).as_array();}
|
||||
};
|
||||
template<> struct value::switch_cast<value_t::Table>
|
||||
template<>
|
||||
struct switch_cast<value_t::Table>
|
||||
{
|
||||
static Table& invoke(value& v) {return v.table_.value();}
|
||||
static Table const& invoke(value const& v) {return v.table_.value();}
|
||||
static Table&& invoke(value&& v) {return std::move(v.table_.value());}
|
||||
static ::toml::table& invoke(value& v) {return v.as_table();}
|
||||
static ::toml::table const& invoke(value const& v) {return v.as_table();}
|
||||
static ::toml::table&& invoke(value&& v) {return std::move(v).as_table();}
|
||||
};
|
||||
}// detail
|
||||
|
||||
template<value_t T>
|
||||
typename detail::toml_default_type<T>::type& value::cast() &
|
||||
{
|
||||
if(T != this->type_)
|
||||
{
|
||||
throw type_error(detail::format_underline(concat_to_string(
|
||||
"[error] toml::value bad_cast to ", T), {
|
||||
{this->region_info_.get(),
|
||||
concat_to_string("the actual type is ", this->type_)}
|
||||
}));
|
||||
detail::throw_bad_cast<T>(this->type_, *this);
|
||||
}
|
||||
return switch_cast<T>::invoke(*this);
|
||||
return detail::switch_cast<T>::invoke(*this);
|
||||
}
|
||||
template<value_t T>
|
||||
typename detail::toml_default_type<T>::type const& value::cast() const&
|
||||
{
|
||||
if(T != this->type_)
|
||||
{
|
||||
throw type_error(detail::format_underline(concat_to_string(
|
||||
"[error] toml::value bad_cast to ", T), {
|
||||
{this->region_info_.get(),
|
||||
concat_to_string("the actual type is ", this->type_)}
|
||||
}));
|
||||
detail::throw_bad_cast<T>(this->type_, *this);
|
||||
}
|
||||
return switch_cast<T>::invoke(*this);
|
||||
return detail::switch_cast<T>::invoke(*this);
|
||||
}
|
||||
template<value_t T>
|
||||
typename detail::toml_default_type<T>::type&& value::cast() &&
|
||||
{
|
||||
if(T != this->type_)
|
||||
{
|
||||
throw type_error(detail::format_underline(concat_to_string(
|
||||
"[error] toml::value bad_cast to ", T), {
|
||||
{this->region_info_.get(),
|
||||
concat_to_string("the actual type is ", this->type_)}
|
||||
}));
|
||||
detail::throw_bad_cast<T>(this->type_, *this);
|
||||
}
|
||||
return switch_cast<T>::invoke(std::move(*this));
|
||||
return detail::switch_cast<T>::invoke(std::move(*this));
|
||||
}
|
||||
|
||||
inline bool operator==(const toml::value& lhs, const toml::value& rhs)
|
||||
@@ -844,28 +862,48 @@ inline bool operator==(const toml::value& lhs, const toml::value& rhs)
|
||||
switch(lhs.type())
|
||||
{
|
||||
case value_t::Boolean :
|
||||
return lhs.cast<value_t::Boolean >() == rhs.cast<value_t::Boolean >();
|
||||
{
|
||||
return lhs.as_boolean() == rhs.as_boolean();
|
||||
}
|
||||
case value_t::Integer :
|
||||
return lhs.cast<value_t::Integer >() == rhs.cast<value_t::Integer >();
|
||||
{
|
||||
return lhs.as_integer() == rhs.as_integer();
|
||||
}
|
||||
case value_t::Float :
|
||||
return lhs.cast<value_t::Float >() == rhs.cast<value_t::Float >();
|
||||
{
|
||||
return lhs.as_float() == rhs.as_float();
|
||||
}
|
||||
case value_t::String :
|
||||
return lhs.cast<value_t::String >() == rhs.cast<value_t::String >();
|
||||
{
|
||||
return lhs.as_string() == rhs.as_string();
|
||||
}
|
||||
case value_t::OffsetDatetime:
|
||||
return lhs.cast<value_t::OffsetDatetime>() == rhs.cast<value_t::OffsetDatetime>();
|
||||
{
|
||||
return lhs.as_offset_datetime() == rhs.as_offset_datetime();
|
||||
}
|
||||
case value_t::LocalDatetime:
|
||||
return lhs.cast<value_t::LocalDatetime>() == rhs.cast<value_t::LocalDatetime>();
|
||||
{
|
||||
return lhs.as_local_datetime() == rhs.as_local_datetime();
|
||||
}
|
||||
case value_t::LocalDate:
|
||||
return lhs.cast<value_t::LocalDate>() == rhs.cast<value_t::LocalDate>();
|
||||
{
|
||||
return lhs.as_local_date() == rhs.as_local_date();
|
||||
}
|
||||
case value_t::LocalTime:
|
||||
return lhs.cast<value_t::LocalTime>() == rhs.cast<value_t::LocalTime>();
|
||||
{
|
||||
return lhs.as_local_time() == rhs.as_local_time();
|
||||
}
|
||||
case value_t::Array :
|
||||
return lhs.cast<value_t::Array >() == rhs.cast<value_t::Array >();
|
||||
{
|
||||
return lhs.as_array() == rhs.as_array();
|
||||
}
|
||||
case value_t::Table :
|
||||
return lhs.cast<value_t::Table >() == rhs.cast<value_t::Table >();
|
||||
case value_t::Empty : return true;
|
||||
case value_t::Unknown : return false;
|
||||
default: return false;
|
||||
{
|
||||
return lhs.as_table() == rhs.as_table();
|
||||
}
|
||||
case value_t::Empty : {return true; }
|
||||
case value_t::Unknown : {return false;}
|
||||
default: {return false;}
|
||||
}
|
||||
}
|
||||
inline bool operator<(const toml::value& lhs, const toml::value& rhs)
|
||||
@@ -874,28 +912,48 @@ inline bool operator<(const toml::value& lhs, const toml::value& rhs)
|
||||
switch(lhs.type())
|
||||
{
|
||||
case value_t::Boolean :
|
||||
return lhs.cast<value_t::Boolean >() < rhs.cast<value_t::Boolean >();
|
||||
{
|
||||
return lhs.as_boolean() < rhs.as_boolean();
|
||||
}
|
||||
case value_t::Integer :
|
||||
return lhs.cast<value_t::Integer >() < rhs.cast<value_t::Integer >();
|
||||
{
|
||||
return lhs.as_integer() < rhs.as_integer();
|
||||
}
|
||||
case value_t::Float :
|
||||
return lhs.cast<value_t::Float >() < rhs.cast<value_t::Float >();
|
||||
{
|
||||
return lhs.as_float() < rhs.as_float();
|
||||
}
|
||||
case value_t::String :
|
||||
return lhs.cast<value_t::String >() < rhs.cast<value_t::String >();
|
||||
{
|
||||
return lhs.as_string() < rhs.as_string();
|
||||
}
|
||||
case value_t::OffsetDatetime:
|
||||
return lhs.cast<value_t::OffsetDatetime>() < rhs.cast<value_t::OffsetDatetime>();
|
||||
{
|
||||
return lhs.as_offset_datetime() < rhs.as_offset_datetime();
|
||||
}
|
||||
case value_t::LocalDatetime:
|
||||
return lhs.cast<value_t::LocalDatetime>() < rhs.cast<value_t::LocalDatetime>();
|
||||
{
|
||||
return lhs.as_local_datetime() < rhs.as_local_datetime();
|
||||
}
|
||||
case value_t::LocalDate:
|
||||
return lhs.cast<value_t::LocalDate>() < rhs.cast<value_t::LocalDate>();
|
||||
{
|
||||
return lhs.as_local_date() < rhs.as_local_date();
|
||||
}
|
||||
case value_t::LocalTime:
|
||||
return lhs.cast<value_t::LocalTime>() < rhs.cast<value_t::LocalTime>();
|
||||
{
|
||||
return lhs.as_local_time() < rhs.as_local_time();
|
||||
}
|
||||
case value_t::Array :
|
||||
return lhs.cast<value_t::Array >() < rhs.cast<value_t::Array >();
|
||||
{
|
||||
return lhs.as_array() < rhs.as_array();
|
||||
}
|
||||
case value_t::Table :
|
||||
return lhs.cast<value_t::Table >() < rhs.cast<value_t::Table >();
|
||||
case value_t::Empty : return false;
|
||||
case value_t::Unknown : return false;
|
||||
default: return false;
|
||||
{
|
||||
return lhs.as_table() < rhs.as_table();
|
||||
}
|
||||
case value_t::Empty : {return false;}
|
||||
case value_t::Unknown : {return false;}
|
||||
default: {return false;}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -958,16 +1016,16 @@ visit(Visitor&& visitor, const toml::value& v)
|
||||
{
|
||||
switch(v.type())
|
||||
{
|
||||
case value_t::Boolean : {return visitor(v.cast<value_t::Boolean >());}
|
||||
case value_t::Integer : {return visitor(v.cast<value_t::Integer >());}
|
||||
case value_t::Float : {return visitor(v.cast<value_t::Float >());}
|
||||
case value_t::String : {return visitor(v.cast<value_t::String >());}
|
||||
case value_t::OffsetDatetime: {return visitor(v.cast<value_t::OffsetDatetime>());}
|
||||
case value_t::LocalDatetime : {return visitor(v.cast<value_t::LocalDatetime >());}
|
||||
case value_t::LocalDate : {return visitor(v.cast<value_t::LocalDate >());}
|
||||
case value_t::LocalTime : {return visitor(v.cast<value_t::LocalTime >());}
|
||||
case value_t::Array : {return visitor(v.cast<value_t::Array >());}
|
||||
case value_t::Table : {return visitor(v.cast<value_t::Table >());}
|
||||
case value_t::Boolean : {return visitor(v.as_boolean ());}
|
||||
case value_t::Integer : {return visitor(v.as_integer ());}
|
||||
case value_t::Float : {return visitor(v.as_float ());}
|
||||
case value_t::String : {return visitor(v.as_string ());}
|
||||
case value_t::OffsetDatetime: {return visitor(v.as_offset_datetime());}
|
||||
case value_t::LocalDatetime : {return visitor(v.as_local_datetime ());}
|
||||
case value_t::LocalDate : {return visitor(v.as_local_date ());}
|
||||
case value_t::LocalTime : {return visitor(v.as_local_time ());}
|
||||
case value_t::Array : {return visitor(v.as_array ());}
|
||||
case value_t::Table : {return visitor(v.as_table ());}
|
||||
case value_t::Empty : break;
|
||||
case value_t::Unknown : break;
|
||||
default: break;
|
||||
@@ -982,16 +1040,16 @@ visit(Visitor&& visitor, toml::value& v)
|
||||
{
|
||||
switch(v.type())
|
||||
{
|
||||
case value_t::Boolean : {return visitor(v.cast<value_t::Boolean >());}
|
||||
case value_t::Integer : {return visitor(v.cast<value_t::Integer >());}
|
||||
case value_t::Float : {return visitor(v.cast<value_t::Float >());}
|
||||
case value_t::String : {return visitor(v.cast<value_t::String >());}
|
||||
case value_t::OffsetDatetime: {return visitor(v.cast<value_t::OffsetDatetime>());}
|
||||
case value_t::LocalDatetime : {return visitor(v.cast<value_t::LocalDatetime >());}
|
||||
case value_t::LocalDate : {return visitor(v.cast<value_t::LocalDate >());}
|
||||
case value_t::LocalTime : {return visitor(v.cast<value_t::LocalTime >());}
|
||||
case value_t::Array : {return visitor(v.cast<value_t::Array >());}
|
||||
case value_t::Table : {return visitor(v.cast<value_t::Table >());}
|
||||
case value_t::Boolean : {return visitor(v.as_boolean ());}
|
||||
case value_t::Integer : {return visitor(v.as_integer ());}
|
||||
case value_t::Float : {return visitor(v.as_float ());}
|
||||
case value_t::String : {return visitor(v.as_string ());}
|
||||
case value_t::OffsetDatetime: {return visitor(v.as_offset_datetime());}
|
||||
case value_t::LocalDatetime : {return visitor(v.as_local_datetime ());}
|
||||
case value_t::LocalDate : {return visitor(v.as_local_date ());}
|
||||
case value_t::LocalTime : {return visitor(v.as_local_time ());}
|
||||
case value_t::Array : {return visitor(v.as_array ());}
|
||||
case value_t::Table : {return visitor(v.as_table ());}
|
||||
case value_t::Empty : break;
|
||||
case value_t::Unknown : break;
|
||||
default: break;
|
||||
@@ -1006,16 +1064,16 @@ visit(Visitor&& visitor, toml::value&& v)
|
||||
{
|
||||
switch(v.type())
|
||||
{
|
||||
case value_t::Boolean : {return visitor(std::move(v.cast<value_t::Boolean >()));}
|
||||
case value_t::Integer : {return visitor(std::move(v.cast<value_t::Integer >()));}
|
||||
case value_t::Float : {return visitor(std::move(v.cast<value_t::Float >()));}
|
||||
case value_t::String : {return visitor(std::move(v.cast<value_t::String >()));}
|
||||
case value_t::OffsetDatetime: {return visitor(std::move(v.cast<value_t::OffsetDatetime>()));}
|
||||
case value_t::LocalDatetime : {return visitor(std::move(v.cast<value_t::LocalDatetime >()));}
|
||||
case value_t::LocalDate : {return visitor(std::move(v.cast<value_t::LocalDate >()));}
|
||||
case value_t::LocalTime : {return visitor(std::move(v.cast<value_t::LocalTime >()));}
|
||||
case value_t::Array : {return visitor(std::move(v.cast<value_t::Array >()));}
|
||||
case value_t::Table : {return visitor(std::move(v.cast<value_t::Table >()));}
|
||||
case value_t::Boolean : {return visitor(std::move(v.as_boolean ()));}
|
||||
case value_t::Integer : {return visitor(std::move(v.as_integer ()));}
|
||||
case value_t::Float : {return visitor(std::move(v.as_float ()));}
|
||||
case value_t::String : {return visitor(std::move(v.as_string ()));}
|
||||
case value_t::OffsetDatetime: {return visitor(std::move(v.as_offset_datetime()));}
|
||||
case value_t::LocalDatetime : {return visitor(std::move(v.as_local_datetime ()));}
|
||||
case value_t::LocalDate : {return visitor(std::move(v.as_local_date ()));}
|
||||
case value_t::LocalTime : {return visitor(std::move(v.as_local_time ()));}
|
||||
case value_t::Array : {return visitor(std::move(v.as_array ()));}
|
||||
case value_t::Table : {return visitor(std::move(v.as_table ()));}
|
||||
case value_t::Empty : break;
|
||||
case value_t::Unknown : break;
|
||||
default: break;
|
||||
|
||||
Reference in New Issue
Block a user