mirror of
https://github.com/ToruNiina/toml11.git
synced 2025-12-16 03:08:52 +08:00
refactor: remove template from detail::location
This commit is contained in:
@@ -8,7 +8,7 @@
|
|||||||
do { \
|
do { \
|
||||||
const std::string token (tkn); \
|
const std::string token (tkn); \
|
||||||
const std::string expected(expct); \
|
const std::string expected(expct); \
|
||||||
toml::detail::location<std::string> loc("test", token); \
|
toml::detail::location loc("test", token); \
|
||||||
const auto result = lxr::invoke(loc); \
|
const auto result = lxr::invoke(loc); \
|
||||||
BOOST_TEST(result.is_ok()); \
|
BOOST_TEST(result.is_ok()); \
|
||||||
if(result.is_ok()){ \
|
if(result.is_ok()){ \
|
||||||
@@ -28,7 +28,7 @@ do { \
|
|||||||
#define TOML11_TEST_LEX_REJECT(lxr, tkn) \
|
#define TOML11_TEST_LEX_REJECT(lxr, tkn) \
|
||||||
do { \
|
do { \
|
||||||
const std::string token (tkn); \
|
const std::string token (tkn); \
|
||||||
toml::detail::location<std::string> loc("test", token); \
|
toml::detail::location loc("test", token); \
|
||||||
const auto result = lxr::invoke(loc); \
|
const auto result = lxr::invoke(loc); \
|
||||||
BOOST_TEST(result.is_err()); \
|
BOOST_TEST(result.is_err()); \
|
||||||
const bool loc_same = (loc.begin() == loc.iter()); \
|
const bool loc_same = (loc.begin() == loc.iter()); \
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
#define TOML11_TEST_PARSE_EQUAL(psr, tkn, expct) \
|
#define TOML11_TEST_PARSE_EQUAL(psr, tkn, expct) \
|
||||||
do { \
|
do { \
|
||||||
const std::string token(tkn); \
|
const std::string token(tkn); \
|
||||||
toml::detail::location<std::string> loc("test", token); \
|
toml::detail::location loc("test", token); \
|
||||||
const auto result = psr(loc); \
|
const auto result = psr(loc); \
|
||||||
BOOST_TEST(result.is_ok()); \
|
BOOST_TEST(result.is_ok()); \
|
||||||
if(result.is_ok()){ \
|
if(result.is_ok()){ \
|
||||||
@@ -23,7 +23,7 @@ do { \
|
|||||||
#define TOML11_TEST_PARSE_EQUAL_VALUE(psr, tkn, expct) \
|
#define TOML11_TEST_PARSE_EQUAL_VALUE(psr, tkn, expct) \
|
||||||
do { \
|
do { \
|
||||||
const std::string token(tkn); \
|
const std::string token(tkn); \
|
||||||
toml::detail::location<std::string> loc("test", token); \
|
toml::detail::location loc("test", token); \
|
||||||
const auto result = psr(loc); \
|
const auto result = psr(loc); \
|
||||||
BOOST_TEST(result.is_ok()); \
|
BOOST_TEST(result.is_ok()); \
|
||||||
if(result.is_ok()){ \
|
if(result.is_ok()){ \
|
||||||
|
|||||||
@@ -128,7 +128,7 @@ BOOST_AUTO_TEST_CASE(test_inf)
|
|||||||
{
|
{
|
||||||
{
|
{
|
||||||
const std::string token("inf");
|
const std::string token("inf");
|
||||||
toml::detail::location<std::string> loc("test", token);
|
toml::detail::location loc("test", token);
|
||||||
const auto r = parse_floating(loc);
|
const auto r = parse_floating(loc);
|
||||||
BOOST_CHECK(r.is_ok());
|
BOOST_CHECK(r.is_ok());
|
||||||
BOOST_CHECK(std::isinf(r.unwrap().first));
|
BOOST_CHECK(std::isinf(r.unwrap().first));
|
||||||
@@ -136,7 +136,7 @@ BOOST_AUTO_TEST_CASE(test_inf)
|
|||||||
}
|
}
|
||||||
{
|
{
|
||||||
const std::string token("+inf");
|
const std::string token("+inf");
|
||||||
toml::detail::location<std::string> loc("test", token);
|
toml::detail::location loc("test", token);
|
||||||
const auto r = parse_floating(loc);
|
const auto r = parse_floating(loc);
|
||||||
BOOST_CHECK(r.is_ok());
|
BOOST_CHECK(r.is_ok());
|
||||||
BOOST_CHECK(std::isinf(r.unwrap().first));
|
BOOST_CHECK(std::isinf(r.unwrap().first));
|
||||||
@@ -144,7 +144,7 @@ BOOST_AUTO_TEST_CASE(test_inf)
|
|||||||
}
|
}
|
||||||
{
|
{
|
||||||
const std::string token("-inf");
|
const std::string token("-inf");
|
||||||
toml::detail::location<std::string> loc("test", token);
|
toml::detail::location loc("test", token);
|
||||||
const auto r = parse_floating(loc);
|
const auto r = parse_floating(loc);
|
||||||
BOOST_CHECK(r.is_ok());
|
BOOST_CHECK(r.is_ok());
|
||||||
BOOST_CHECK(std::isinf(r.unwrap().first));
|
BOOST_CHECK(std::isinf(r.unwrap().first));
|
||||||
@@ -156,21 +156,21 @@ BOOST_AUTO_TEST_CASE(test_nan)
|
|||||||
{
|
{
|
||||||
{
|
{
|
||||||
const std::string token("nan");
|
const std::string token("nan");
|
||||||
toml::detail::location<std::string> loc("test", token);
|
toml::detail::location loc("test", token);
|
||||||
const auto r = parse_floating(loc);
|
const auto r = parse_floating(loc);
|
||||||
BOOST_CHECK(r.is_ok());
|
BOOST_CHECK(r.is_ok());
|
||||||
BOOST_CHECK(std::isnan(r.unwrap().first));
|
BOOST_CHECK(std::isnan(r.unwrap().first));
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
const std::string token("+nan");
|
const std::string token("+nan");
|
||||||
toml::detail::location<std::string> loc("test", token);
|
toml::detail::location loc("test", token);
|
||||||
const auto r = parse_floating(loc);
|
const auto r = parse_floating(loc);
|
||||||
BOOST_CHECK(r.is_ok());
|
BOOST_CHECK(r.is_ok());
|
||||||
BOOST_CHECK(std::isnan(r.unwrap().first));
|
BOOST_CHECK(std::isnan(r.unwrap().first));
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
const std::string token("-nan");
|
const std::string token("-nan");
|
||||||
toml::detail::location<std::string> loc("test", token);
|
toml::detail::location loc("test", token);
|
||||||
const auto r = parse_floating(loc);
|
const auto r = parse_floating(loc);
|
||||||
BOOST_CHECK(r.is_ok());
|
BOOST_CHECK(r.is_ok());
|
||||||
BOOST_CHECK(std::isnan(r.unwrap().first));
|
BOOST_CHECK(std::isnan(r.unwrap().first));
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ BOOST_AUTO_TEST_CASE(test_normal_table)
|
|||||||
"key2 = 42\n"
|
"key2 = 42\n"
|
||||||
"key3 = 3.14\n"
|
"key3 = 3.14\n"
|
||||||
);
|
);
|
||||||
location<std::string> loc("test", table);
|
location loc("test", table);
|
||||||
|
|
||||||
const auto result = toml::detail::parse_ml_table<toml::value>(loc);
|
const auto result = toml::detail::parse_ml_table<toml::value>(loc);
|
||||||
BOOST_TEST(result.is_ok());
|
BOOST_TEST(result.is_ok());
|
||||||
@@ -36,7 +36,7 @@ BOOST_AUTO_TEST_CASE(test_nested_table)
|
|||||||
"a.b = \"value\"\n"
|
"a.b = \"value\"\n"
|
||||||
"a.c.d = 42\n"
|
"a.c.d = 42\n"
|
||||||
);
|
);
|
||||||
location<std::string> loc("test", table);
|
location loc("test", table);
|
||||||
|
|
||||||
const auto result = toml::detail::parse_ml_table<toml::value>(loc);
|
const auto result = toml::detail::parse_ml_table<toml::value>(loc);
|
||||||
BOOST_TEST(result.is_ok());
|
BOOST_TEST(result.is_ok());
|
||||||
|
|||||||
@@ -58,13 +58,9 @@ struct character
|
|||||||
{
|
{
|
||||||
static constexpr char target = C;
|
static constexpr char target = C;
|
||||||
|
|
||||||
template<typename Cont>
|
static result<region<std::vector<char>>, none_t>
|
||||||
static result<region<Cont>, none_t>
|
invoke(location& loc)
|
||||||
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 none();}
|
if(loc.iter() == loc.end()) {return none();}
|
||||||
const auto first = loc.iter();
|
const auto first = loc.iter();
|
||||||
|
|
||||||
@@ -75,7 +71,7 @@ struct character
|
|||||||
}
|
}
|
||||||
loc.advance(); // update location
|
loc.advance(); // update location
|
||||||
|
|
||||||
return ok(region<Cont>(loc, first, loc.iter()));
|
return ok(region<std::vector<char>>(loc, first, loc.iter()));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
template<char C>
|
template<char C>
|
||||||
@@ -91,13 +87,9 @@ struct in_range
|
|||||||
static constexpr char upper = Up;
|
static constexpr char upper = Up;
|
||||||
static constexpr char lower = Low;
|
static constexpr char lower = Low;
|
||||||
|
|
||||||
template<typename Cont>
|
static result<region<std::vector<char>>, none_t>
|
||||||
static result<region<Cont>, none_t>
|
invoke(location& loc)
|
||||||
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 none();}
|
if(loc.iter() == loc.end()) {return none();}
|
||||||
const auto first = loc.iter();
|
const auto first = loc.iter();
|
||||||
|
|
||||||
@@ -108,7 +100,7 @@ struct in_range
|
|||||||
}
|
}
|
||||||
|
|
||||||
loc.advance();
|
loc.advance();
|
||||||
return ok(region<Cont>(loc, first, loc.iter()));
|
return ok(region<std::vector<char>>(loc, first, loc.iter()));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
template<char L, char U> constexpr char in_range<L, U>::upper;
|
template<char L, char U> constexpr char in_range<L, U>::upper;
|
||||||
@@ -119,13 +111,9 @@ template<char L, char U> constexpr char in_range<L, U>::lower;
|
|||||||
template<typename Combinator>
|
template<typename Combinator>
|
||||||
struct exclude
|
struct exclude
|
||||||
{
|
{
|
||||||
template<typename Cont>
|
static result<region<std::vector<char>>, none_t>
|
||||||
static result<region<Cont>, none_t>
|
invoke(location& loc)
|
||||||
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 none();}
|
if(loc.iter() == loc.end()) {return none();}
|
||||||
auto first = loc.iter();
|
auto first = loc.iter();
|
||||||
|
|
||||||
@@ -136,7 +124,7 @@ struct exclude
|
|||||||
return none();
|
return none();
|
||||||
}
|
}
|
||||||
loc.reset(std::next(first)); // XXX maybe loc.advance() is okay but...
|
loc.reset(std::next(first)); // XXX maybe loc.advance() is okay but...
|
||||||
return ok(region<Cont>(loc, first, loc.iter()));
|
return ok(region<std::vector<char>>(loc, first, loc.iter()));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -144,19 +132,15 @@ struct exclude
|
|||||||
template<typename Combinator>
|
template<typename Combinator>
|
||||||
struct maybe
|
struct maybe
|
||||||
{
|
{
|
||||||
template<typename Cont>
|
static result<region<std::vector<char>>, none_t>
|
||||||
static result<region<Cont>, none_t>
|
invoke(location& loc)
|
||||||
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);
|
const auto rslt = Combinator::invoke(loc);
|
||||||
if(rslt.is_ok())
|
if(rslt.is_ok())
|
||||||
{
|
{
|
||||||
return rslt;
|
return rslt;
|
||||||
}
|
}
|
||||||
return ok(region<Cont>(loc));
|
return ok(region<std::vector<char>>(loc));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -166,13 +150,9 @@ struct sequence;
|
|||||||
template<typename Head, typename ... Tail>
|
template<typename Head, typename ... Tail>
|
||||||
struct sequence<Head, Tail...>
|
struct sequence<Head, Tail...>
|
||||||
{
|
{
|
||||||
template<typename Cont>
|
static result<region<std::vector<char>>, none_t>
|
||||||
static result<region<Cont>, none_t>
|
invoke(location& loc)
|
||||||
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 first = loc.iter();
|
||||||
const auto rslt = Head::invoke(loc);
|
const auto rslt = Head::invoke(loc);
|
||||||
if(rslt.is_err())
|
if(rslt.is_err())
|
||||||
@@ -184,9 +164,9 @@ struct sequence<Head, Tail...>
|
|||||||
}
|
}
|
||||||
|
|
||||||
// called from the above function only, recursively.
|
// called from the above function only, recursively.
|
||||||
template<typename Cont, typename Iterator>
|
template<typename Iterator>
|
||||||
static result<region<Cont>, none_t>
|
static result<region<std::vector<char>>, none_t>
|
||||||
invoke(location<Cont>& loc, region<Cont> reg, Iterator first)
|
invoke(location& loc, region<std::vector<char>> reg, Iterator first)
|
||||||
{
|
{
|
||||||
const auto rslt = Head::invoke(loc);
|
const auto rslt = Head::invoke(loc);
|
||||||
if(rslt.is_err())
|
if(rslt.is_err())
|
||||||
@@ -203,9 +183,9 @@ template<typename Head>
|
|||||||
struct sequence<Head>
|
struct sequence<Head>
|
||||||
{
|
{
|
||||||
// would be called from sequence<T ...>::invoke only.
|
// would be called from sequence<T ...>::invoke only.
|
||||||
template<typename Cont, typename Iterator>
|
template<typename Iterator>
|
||||||
static result<region<Cont>, none_t>
|
static result<region<std::vector<char>>, none_t>
|
||||||
invoke(location<Cont>& loc, region<Cont> reg, Iterator first)
|
invoke(location& loc, region<std::vector<char>> reg, Iterator first)
|
||||||
{
|
{
|
||||||
const auto rslt = Head::invoke(loc);
|
const auto rslt = Head::invoke(loc);
|
||||||
if(rslt.is_err())
|
if(rslt.is_err())
|
||||||
@@ -224,13 +204,9 @@ struct either;
|
|||||||
template<typename Head, typename ... Tail>
|
template<typename Head, typename ... Tail>
|
||||||
struct either<Head, Tail...>
|
struct either<Head, Tail...>
|
||||||
{
|
{
|
||||||
template<typename Cont>
|
static result<region<std::vector<char>>, none_t>
|
||||||
static result<region<Cont>, none_t>
|
invoke(location& loc)
|
||||||
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);
|
const auto rslt = Head::invoke(loc);
|
||||||
if(rslt.is_ok()) {return rslt;}
|
if(rslt.is_ok()) {return rslt;}
|
||||||
return either<Tail...>::invoke(loc);
|
return either<Tail...>::invoke(loc);
|
||||||
@@ -239,12 +215,9 @@ struct either<Head, Tail...>
|
|||||||
template<typename Head>
|
template<typename Head>
|
||||||
struct either<Head>
|
struct either<Head>
|
||||||
{
|
{
|
||||||
template<typename Cont>
|
static result<region<std::vector<char>>, none_t>
|
||||||
static result<region<Cont>, none_t>
|
invoke(location& loc)
|
||||||
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);
|
return Head::invoke(loc);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -259,11 +232,10 @@ struct unlimited{};
|
|||||||
template<typename T, std::size_t N>
|
template<typename T, std::size_t N>
|
||||||
struct repeat<T, exactly<N>>
|
struct repeat<T, exactly<N>>
|
||||||
{
|
{
|
||||||
template<typename Cont>
|
static result<region<std::vector<char>>, none_t>
|
||||||
static result<region<Cont>, none_t>
|
invoke(location& loc)
|
||||||
invoke(location<Cont>& loc)
|
|
||||||
{
|
{
|
||||||
region<Cont> retval(loc);
|
region<std::vector<char>> retval(loc);
|
||||||
const auto first = loc.iter();
|
const auto first = loc.iter();
|
||||||
for(std::size_t i=0; i<N; ++i)
|
for(std::size_t i=0; i<N; ++i)
|
||||||
{
|
{
|
||||||
@@ -282,11 +254,10 @@ struct repeat<T, exactly<N>>
|
|||||||
template<typename T, std::size_t N>
|
template<typename T, std::size_t N>
|
||||||
struct repeat<T, at_least<N>>
|
struct repeat<T, at_least<N>>
|
||||||
{
|
{
|
||||||
template<typename Cont>
|
static result<region<std::vector<char>>, none_t>
|
||||||
static result<region<Cont>, none_t>
|
invoke(location& loc)
|
||||||
invoke(location<Cont>& loc)
|
|
||||||
{
|
{
|
||||||
region<Cont> retval(loc);
|
region<std::vector<char>> retval(loc);
|
||||||
|
|
||||||
const auto first = loc.iter();
|
const auto first = loc.iter();
|
||||||
for(std::size_t i=0; i<N; ++i)
|
for(std::size_t i=0; i<N; ++i)
|
||||||
@@ -314,11 +285,10 @@ struct repeat<T, at_least<N>>
|
|||||||
template<typename T>
|
template<typename T>
|
||||||
struct repeat<T, unlimited>
|
struct repeat<T, unlimited>
|
||||||
{
|
{
|
||||||
template<typename Cont>
|
static result<region<std::vector<char>>, none_t>
|
||||||
static result<region<Cont>, none_t>
|
invoke(location& loc)
|
||||||
invoke(location<Cont>& loc)
|
|
||||||
{
|
{
|
||||||
region<Cont> retval(loc);
|
region<std::vector<char>> retval(loc);
|
||||||
while(true)
|
while(true)
|
||||||
{
|
{
|
||||||
auto rslt = T::invoke(loc);
|
auto rslt = T::invoke(loc);
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ inline namespace toml_literals
|
|||||||
|
|
||||||
inline ::toml::value operator"" _toml(const char* str, std::size_t len)
|
inline ::toml::value operator"" _toml(const char* str, std::size_t len)
|
||||||
{
|
{
|
||||||
::toml::detail::location<std::vector<char>>
|
::toml::detail::location
|
||||||
loc(/* filename = */ std::string("TOML literal encoded in a C++ code"),
|
loc(/* filename = */ std::string("TOML literal encoded in a C++ code"),
|
||||||
/* contents = */ std::vector<char>(str, str + len));
|
/* contents = */ std::vector<char>(str, str + len));
|
||||||
|
|
||||||
|
|||||||
196
toml/parser.hpp
196
toml/parser.hpp
@@ -25,9 +25,8 @@ namespace toml
|
|||||||
namespace detail
|
namespace detail
|
||||||
{
|
{
|
||||||
|
|
||||||
template<typename Container>
|
inline result<std::pair<boolean, region<std::vector<char>>>, std::string>
|
||||||
result<std::pair<boolean, region<Container>>, std::string>
|
parse_boolean(location& loc)
|
||||||
parse_boolean(location<Container>& loc)
|
|
||||||
{
|
{
|
||||||
const auto first = loc.iter();
|
const auto first = loc.iter();
|
||||||
if(const auto token = lex_boolean::invoke(loc))
|
if(const auto token = lex_boolean::invoke(loc))
|
||||||
@@ -48,9 +47,8 @@ parse_boolean(location<Container>& loc)
|
|||||||
{{std::addressof(loc), "the next token is not a boolean"}}));
|
{{std::addressof(loc), "the next token is not a boolean"}}));
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename Container>
|
inline result<std::pair<integer, region<std::vector<char>>>, std::string>
|
||||||
result<std::pair<integer, region<Container>>, std::string>
|
parse_binary_integer(location& loc)
|
||||||
parse_binary_integer(location<Container>& loc)
|
|
||||||
{
|
{
|
||||||
const auto first = loc.iter();
|
const auto first = loc.iter();
|
||||||
if(const auto token = lex_bin_int::invoke(loc))
|
if(const auto token = lex_bin_int::invoke(loc))
|
||||||
@@ -78,9 +76,8 @@ parse_binary_integer(location<Container>& loc)
|
|||||||
{{std::addressof(loc), "the next token is not an integer"}}));
|
{{std::addressof(loc), "the next token is not an integer"}}));
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename Container>
|
inline result<std::pair<integer, region<std::vector<char>>>, std::string>
|
||||||
result<std::pair<integer, region<Container>>, std::string>
|
parse_octal_integer(location& loc)
|
||||||
parse_octal_integer(location<Container>& loc)
|
|
||||||
{
|
{
|
||||||
const auto first = loc.iter();
|
const auto first = loc.iter();
|
||||||
if(const auto token = lex_oct_int::invoke(loc))
|
if(const auto token = lex_oct_int::invoke(loc))
|
||||||
@@ -99,9 +96,8 @@ parse_octal_integer(location<Container>& loc)
|
|||||||
{{std::addressof(loc), "the next token is not an integer"}}));
|
{{std::addressof(loc), "the next token is not an integer"}}));
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename Container>
|
inline result<std::pair<integer, region<std::vector<char>>>, std::string>
|
||||||
result<std::pair<integer, region<Container>>, std::string>
|
parse_hexadecimal_integer(location& loc)
|
||||||
parse_hexadecimal_integer(location<Container>& loc)
|
|
||||||
{
|
{
|
||||||
const auto first = loc.iter();
|
const auto first = loc.iter();
|
||||||
if(const auto token = lex_hex_int::invoke(loc))
|
if(const auto token = lex_hex_int::invoke(loc))
|
||||||
@@ -120,9 +116,8 @@ parse_hexadecimal_integer(location<Container>& loc)
|
|||||||
{{std::addressof(loc), "the next token is not an integer"}}));
|
{{std::addressof(loc), "the next token is not an integer"}}));
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename Container>
|
inline result<std::pair<integer, region<std::vector<char>>>, std::string>
|
||||||
result<std::pair<integer, region<Container>>, std::string>
|
parse_integer(location& loc)
|
||||||
parse_integer(location<Container>& loc)
|
|
||||||
{
|
{
|
||||||
const auto first = loc.iter();
|
const auto first = loc.iter();
|
||||||
if(first != loc.end() && *first == '0')
|
if(first != loc.end() && *first == '0')
|
||||||
@@ -130,7 +125,7 @@ parse_integer(location<Container>& loc)
|
|||||||
const auto second = std::next(first);
|
const auto second = std::next(first);
|
||||||
if(second == loc.end()) // the token is just zero.
|
if(second == loc.end()) // the token is just zero.
|
||||||
{
|
{
|
||||||
return ok(std::make_pair(0, region<Container>(loc, first, second)));
|
return ok(std::make_pair(0, region<std::vector<char>>(loc, first, second)));
|
||||||
}
|
}
|
||||||
|
|
||||||
if(*second == 'b') {return parse_binary_integer (loc);} // 0b1100
|
if(*second == 'b') {return parse_binary_integer (loc);} // 0b1100
|
||||||
@@ -166,9 +161,8 @@ parse_integer(location<Container>& loc)
|
|||||||
{{std::addressof(loc), "the next token is not an integer"}}));
|
{{std::addressof(loc), "the next token is not an integer"}}));
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename Container>
|
inline result<std::pair<floating, region<std::vector<char>>>, std::string>
|
||||||
result<std::pair<floating, region<Container>>, std::string>
|
parse_floating(location& loc)
|
||||||
parse_floating(location<Container>& loc)
|
|
||||||
{
|
{
|
||||||
const auto first = loc.iter();
|
const auto first = loc.iter();
|
||||||
if(const auto token = lex_float::invoke(loc))
|
if(const auto token = lex_float::invoke(loc))
|
||||||
@@ -255,9 +249,9 @@ parse_floating(location<Container>& loc)
|
|||||||
{{std::addressof(loc), "the next token is not a float"}}));
|
{{std::addressof(loc), "the next token is not a float"}}));
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename Container, typename Container2>
|
template<typename Container>
|
||||||
std::string read_utf8_codepoint(const region<Container>& reg,
|
std::string read_utf8_codepoint(const region<Container>& reg,
|
||||||
/* for err msg */ const location<Container2>& loc)
|
/* for err msg */ const location& loc)
|
||||||
{
|
{
|
||||||
const auto str = reg.str().substr(1);
|
const auto str = reg.str().substr(1);
|
||||||
std::uint_least32_t codepoint;
|
std::uint_least32_t codepoint;
|
||||||
@@ -314,8 +308,7 @@ std::string read_utf8_codepoint(const region<Container>& reg,
|
|||||||
return character;
|
return character;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename Container>
|
inline result<std::string, std::string> parse_escape_sequence(location& loc)
|
||||||
result<std::string, std::string> parse_escape_sequence(location<Container>& loc)
|
|
||||||
{
|
{
|
||||||
const auto first = loc.iter();
|
const auto first = loc.iter();
|
||||||
if(first == loc.end() || *first != '\\')
|
if(first == loc.end() || *first != '\\')
|
||||||
@@ -370,9 +363,8 @@ result<std::string, std::string> parse_escape_sequence(location<Container>& loc)
|
|||||||
return err(msg);
|
return err(msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename Container>
|
inline result<std::pair<toml::string, region<std::vector<char>>>, std::string>
|
||||||
result<std::pair<toml::string, region<Container>>, std::string>
|
parse_ml_basic_string(location& loc)
|
||||||
parse_ml_basic_string(location<Container>& loc)
|
|
||||||
{
|
{
|
||||||
const auto first = loc.iter();
|
const auto first = loc.iter();
|
||||||
if(const auto token = lex_ml_basic_string::invoke(loc))
|
if(const auto token = lex_ml_basic_string::invoke(loc))
|
||||||
@@ -450,9 +442,8 @@ parse_ml_basic_string(location<Container>& loc)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename Container>
|
inline result<std::pair<toml::string, region<std::vector<char>>>, std::string>
|
||||||
result<std::pair<toml::string, region<Container>>, std::string>
|
parse_basic_string(location& loc)
|
||||||
parse_basic_string(location<Container>& loc)
|
|
||||||
{
|
{
|
||||||
const auto first = loc.iter();
|
const auto first = loc.iter();
|
||||||
if(const auto token = lex_basic_string::invoke(loc))
|
if(const auto token = lex_basic_string::invoke(loc))
|
||||||
@@ -503,14 +494,13 @@ parse_basic_string(location<Container>& loc)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename Container>
|
inline result<std::pair<toml::string, region<std::vector<char>>>, std::string>
|
||||||
result<std::pair<toml::string, region<Container>>, std::string>
|
parse_ml_literal_string(location& loc)
|
||||||
parse_ml_literal_string(location<Container>& loc)
|
|
||||||
{
|
{
|
||||||
const auto first = loc.iter();
|
const auto first = loc.iter();
|
||||||
if(const auto token = lex_ml_literal_string::invoke(loc))
|
if(const auto token = lex_ml_literal_string::invoke(loc))
|
||||||
{
|
{
|
||||||
location<std::vector<char>> inner_loc(loc.name(), token.unwrap().str());
|
location inner_loc(loc.name(), token.unwrap().str());
|
||||||
|
|
||||||
const auto open = lex_ml_literal_string_open::invoke(inner_loc);
|
const auto open = lex_ml_literal_string_open::invoke(inner_loc);
|
||||||
if(!open)
|
if(!open)
|
||||||
@@ -566,14 +556,13 @@ parse_ml_literal_string(location<Container>& loc)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename Container>
|
inline result<std::pair<toml::string, region<std::vector<char>>>, std::string>
|
||||||
result<std::pair<toml::string, region<Container>>, std::string>
|
parse_literal_string(location& loc)
|
||||||
parse_literal_string(location<Container>& loc)
|
|
||||||
{
|
{
|
||||||
const auto first = loc.iter();
|
const auto first = loc.iter();
|
||||||
if(const auto token = lex_literal_string::invoke(loc))
|
if(const auto token = lex_literal_string::invoke(loc))
|
||||||
{
|
{
|
||||||
location<std::vector<char>> inner_loc(loc.name(), token.unwrap().str());
|
location inner_loc(loc.name(), token.unwrap().str());
|
||||||
|
|
||||||
const auto open = lex_apostrophe::invoke(inner_loc);
|
const auto open = lex_apostrophe::invoke(inner_loc);
|
||||||
if(!open)
|
if(!open)
|
||||||
@@ -607,9 +596,8 @@ parse_literal_string(location<Container>& loc)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename Container>
|
inline result<std::pair<toml::string, region<std::vector<char>>>, std::string>
|
||||||
result<std::pair<toml::string, region<Container>>, std::string>
|
parse_string(location& loc)
|
||||||
parse_string(location<Container>& loc)
|
|
||||||
{
|
{
|
||||||
if(loc.iter() != loc.end() && *(loc.iter()) == '"')
|
if(loc.iter() != loc.end() && *(loc.iter()) == '"')
|
||||||
{
|
{
|
||||||
@@ -639,14 +627,13 @@ parse_string(location<Container>& loc)
|
|||||||
{{std::addressof(loc), "the next token is not a string"}}));
|
{{std::addressof(loc), "the next token is not a string"}}));
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename Container>
|
inline result<std::pair<local_date, region<std::vector<char>>>, std::string>
|
||||||
result<std::pair<local_date, region<Container>>, std::string>
|
parse_local_date(location& loc)
|
||||||
parse_local_date(location<Container>& loc)
|
|
||||||
{
|
{
|
||||||
const auto first = loc.iter();
|
const auto first = loc.iter();
|
||||||
if(const auto token = lex_local_date::invoke(loc))
|
if(const auto token = lex_local_date::invoke(loc))
|
||||||
{
|
{
|
||||||
location<std::vector<char>> inner_loc(loc.name(), token.unwrap().str());
|
location inner_loc(loc.name(), token.unwrap().str());
|
||||||
|
|
||||||
const auto y = lex_date_fullyear::invoke(inner_loc);
|
const auto y = lex_date_fullyear::invoke(inner_loc);
|
||||||
if(!y || inner_loc.iter() == inner_loc.end() || *inner_loc.iter() != '-')
|
if(!y || inner_loc.iter() == inner_loc.end() || *inner_loc.iter() != '-')
|
||||||
@@ -689,14 +676,13 @@ parse_local_date(location<Container>& loc)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename Container>
|
inline result<std::pair<local_time, region<std::vector<char>>>, std::string>
|
||||||
result<std::pair<local_time, region<Container>>, std::string>
|
parse_local_time(location& loc)
|
||||||
parse_local_time(location<Container>& loc)
|
|
||||||
{
|
{
|
||||||
const auto first = loc.iter();
|
const auto first = loc.iter();
|
||||||
if(const auto token = lex_local_time::invoke(loc))
|
if(const auto token = lex_local_time::invoke(loc))
|
||||||
{
|
{
|
||||||
location<std::vector<char>> inner_loc(loc.name(), token.unwrap().str());
|
location inner_loc(loc.name(), token.unwrap().str());
|
||||||
|
|
||||||
const auto h = lex_time_hour::invoke(inner_loc);
|
const auto h = lex_time_hour::invoke(inner_loc);
|
||||||
if(!h || inner_loc.iter() == inner_loc.end() || *inner_loc.iter() != ':')
|
if(!h || inner_loc.iter() == inner_loc.end() || *inner_loc.iter() != ':')
|
||||||
@@ -778,14 +764,13 @@ parse_local_time(location<Container>& loc)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename Container>
|
inline result<std::pair<local_datetime, region<std::vector<char>>>, std::string>
|
||||||
result<std::pair<local_datetime, region<Container>>, std::string>
|
parse_local_datetime(location& loc)
|
||||||
parse_local_datetime(location<Container>& loc)
|
|
||||||
{
|
{
|
||||||
const auto first = loc.iter();
|
const auto first = loc.iter();
|
||||||
if(const auto token = lex_local_date_time::invoke(loc))
|
if(const auto token = lex_local_date_time::invoke(loc))
|
||||||
{
|
{
|
||||||
location<std::vector<char>> inner_loc(loc.name(), token.unwrap().str());
|
location inner_loc(loc.name(), token.unwrap().str());
|
||||||
const auto date = parse_local_date(inner_loc);
|
const auto date = parse_local_date(inner_loc);
|
||||||
if(!date || inner_loc.iter() == inner_loc.end())
|
if(!date || inner_loc.iter() == inner_loc.end())
|
||||||
{
|
{
|
||||||
@@ -823,14 +808,13 @@ parse_local_datetime(location<Container>& loc)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename Container>
|
inline result<std::pair<offset_datetime, region<std::vector<char>>>, std::string>
|
||||||
result<std::pair<offset_datetime, region<Container>>, std::string>
|
parse_offset_datetime(location& loc)
|
||||||
parse_offset_datetime(location<Container>& loc)
|
|
||||||
{
|
{
|
||||||
const auto first = loc.iter();
|
const auto first = loc.iter();
|
||||||
if(const auto token = lex_offset_date_time::invoke(loc))
|
if(const auto token = lex_offset_date_time::invoke(loc))
|
||||||
{
|
{
|
||||||
location<std::vector<char>> inner_loc(loc.name(), token.unwrap().str());
|
location inner_loc(loc.name(), token.unwrap().str());
|
||||||
const auto datetime = parse_local_datetime(inner_loc);
|
const auto datetime = parse_local_datetime(inner_loc);
|
||||||
if(!datetime || inner_loc.iter() == inner_loc.end())
|
if(!datetime || inner_loc.iter() == inner_loc.end())
|
||||||
{
|
{
|
||||||
@@ -872,9 +856,8 @@ parse_offset_datetime(location<Container>& loc)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename Container>
|
inline result<std::pair<key, region<std::vector<char>>>, std::string>
|
||||||
result<std::pair<key, region<Container>>, std::string>
|
parse_simple_key(location& loc)
|
||||||
parse_simple_key(location<Container>& loc)
|
|
||||||
{
|
{
|
||||||
if(const auto bstr = parse_basic_string(loc))
|
if(const auto bstr = parse_basic_string(loc))
|
||||||
{
|
{
|
||||||
@@ -894,16 +877,15 @@ parse_simple_key(location<Container>& loc)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// dotted key become vector of keys
|
// dotted key become vector of keys
|
||||||
template<typename Container>
|
inline result<std::pair<std::vector<key>, region<std::vector<char>>>, std::string>
|
||||||
result<std::pair<std::vector<key>, region<Container>>, std::string>
|
parse_key(location& loc)
|
||||||
parse_key(location<Container>& loc)
|
|
||||||
{
|
{
|
||||||
const auto first = loc.iter();
|
const auto first = loc.iter();
|
||||||
// dotted key -> foo.bar.baz whitespaces are allowed
|
// dotted key -> foo.bar.baz whitespaces are allowed
|
||||||
if(const auto token = lex_dotted_key::invoke(loc))
|
if(const auto token = lex_dotted_key::invoke(loc))
|
||||||
{
|
{
|
||||||
const auto reg = token.unwrap();
|
const auto reg = token.unwrap();
|
||||||
location<std::vector<char>> inner_loc(loc.name(), reg.str());
|
location inner_loc(loc.name(), reg.str());
|
||||||
std::vector<key> keys;
|
std::vector<key> keys;
|
||||||
|
|
||||||
while(inner_loc.iter() != inner_loc.end())
|
while(inner_loc.iter() != inner_loc.end())
|
||||||
@@ -953,12 +935,12 @@ parse_key(location<Container>& loc)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// forward-decl to implement parse_array and parse_table
|
// forward-decl to implement parse_array and parse_table
|
||||||
template<typename Value, typename Container>
|
template<typename Value>
|
||||||
result<Value, std::string> parse_value(location<Container>&);
|
result<Value, std::string> parse_value(location&);
|
||||||
|
|
||||||
template<typename Value, typename Container>
|
template<typename Value>
|
||||||
result<std::pair<typename Value::array_type, region<Container>>, std::string>
|
result<std::pair<typename Value::array_type, region<std::vector<char>>>, std::string>
|
||||||
parse_array(location<Container>& loc)
|
parse_array(location& loc)
|
||||||
{
|
{
|
||||||
using value_type = Value;
|
using value_type = Value;
|
||||||
using array_type = typename value_type::array_type;
|
using array_type = typename value_type::array_type;
|
||||||
@@ -986,7 +968,7 @@ parse_array(location<Container>& loc)
|
|||||||
{
|
{
|
||||||
loc.advance(); // skip ']'
|
loc.advance(); // skip ']'
|
||||||
return ok(std::make_pair(retval,
|
return ok(std::make_pair(retval,
|
||||||
region<Container>(loc, first, loc.iter())));
|
region<std::vector<char>>(loc, first, loc.iter())));
|
||||||
}
|
}
|
||||||
|
|
||||||
if(auto val = parse_value<value_type>(loc))
|
if(auto val = parse_value<value_type>(loc))
|
||||||
@@ -1039,7 +1021,7 @@ parse_array(location<Container>& loc)
|
|||||||
{
|
{
|
||||||
loc.advance(); // skip ']'
|
loc.advance(); // skip ']'
|
||||||
return ok(std::make_pair(retval,
|
return ok(std::make_pair(retval,
|
||||||
region<Container>(loc, first, loc.iter())));
|
region<std::vector<char>>(loc, first, loc.iter())));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -1061,9 +1043,9 @@ parse_array(location<Container>& loc)
|
|||||||
source_location(std::addressof(loc)));
|
source_location(std::addressof(loc)));
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename Value, typename Container>
|
template<typename Value>
|
||||||
result<std::pair<std::pair<std::vector<key>, region<Container>>, Value>, std::string>
|
result<std::pair<std::pair<std::vector<key>, region<std::vector<char>>>, Value>, std::string>
|
||||||
parse_key_value_pair(location<Container>& loc)
|
parse_key_value_pair(location& loc)
|
||||||
{
|
{
|
||||||
using value_type = Value;
|
using value_type = Value;
|
||||||
|
|
||||||
@@ -1151,9 +1133,8 @@ std::string format_dotted_keys(InputIterator first, const InputIterator last)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// forward decl for is_valid_forward_table_definition
|
// forward decl for is_valid_forward_table_definition
|
||||||
template<typename Container>
|
result<std::pair<std::vector<key>, region<std::vector<char>>>, std::string>
|
||||||
result<std::pair<std::vector<key>, region<Container>>, std::string>
|
parse_table_key(location& loc);
|
||||||
parse_table_key(location<Container>& loc);
|
|
||||||
|
|
||||||
// The following toml file is allowed.
|
// The following toml file is allowed.
|
||||||
// ```toml
|
// ```toml
|
||||||
@@ -1182,7 +1163,7 @@ template<typename Value, typename Iterator>
|
|||||||
bool is_valid_forward_table_definition(const Value& fwd,
|
bool is_valid_forward_table_definition(const Value& fwd,
|
||||||
Iterator key_first, Iterator key_curr, Iterator key_last)
|
Iterator key_first, Iterator key_curr, Iterator key_last)
|
||||||
{
|
{
|
||||||
location<std::vector<char>> def("internal", detail::get_region(fwd).str());
|
location def("internal", detail::get_region(fwd).str());
|
||||||
if(const auto tabkeys = parse_table_key(def))
|
if(const auto tabkeys = parse_table_key(def))
|
||||||
{
|
{
|
||||||
// table keys always contains all the nodes from the root.
|
// table keys always contains all the nodes from the root.
|
||||||
@@ -1220,11 +1201,11 @@ bool is_valid_forward_table_definition(const Value& fwd,
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename Value, typename InputIterator, typename Container>
|
template<typename Value, typename InputIterator>
|
||||||
result<bool, std::string>
|
result<bool, std::string>
|
||||||
insert_nested_key(typename Value::table_type& root, const Value& v,
|
insert_nested_key(typename Value::table_type& root, const Value& v,
|
||||||
InputIterator iter, const InputIterator last,
|
InputIterator iter, const InputIterator last,
|
||||||
region<Container> key_reg,
|
region<std::vector<char>> key_reg,
|
||||||
const bool is_array_of_table = false)
|
const bool is_array_of_table = false)
|
||||||
{
|
{
|
||||||
static_assert(std::is_same<key,
|
static_assert(std::is_same<key,
|
||||||
@@ -1457,9 +1438,9 @@ insert_nested_key(typename Value::table_type& root, const Value& v,
|
|||||||
return err(std::string("toml::detail::insert_nested_key: never reach here"));
|
return err(std::string("toml::detail::insert_nested_key: never reach here"));
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename Value, typename Container>
|
template<typename Value>
|
||||||
result<std::pair<typename Value::table_type, region<Container>>, std::string>
|
result<std::pair<typename Value::table_type, region<std::vector<char>>>, std::string>
|
||||||
parse_inline_table(location<Container>& loc)
|
parse_inline_table(location& loc)
|
||||||
{
|
{
|
||||||
using value_type = Value;
|
using value_type = Value;
|
||||||
using table_type = typename value_type::table_type;
|
using table_type = typename value_type::table_type;
|
||||||
@@ -1479,8 +1460,8 @@ parse_inline_table(location<Container>& loc)
|
|||||||
if(loc.iter() != loc.end() && *loc.iter() == '}')
|
if(loc.iter() != loc.end() && *loc.iter() == '}')
|
||||||
{
|
{
|
||||||
loc.advance(); // skip `}`
|
loc.advance(); // skip `}`
|
||||||
return ok(std::make_pair(
|
return ok(std::make_pair(retval,
|
||||||
retval, region<Container>(loc, first, loc.iter())));
|
region<std::vector<char>>(loc, first, loc.iter())));
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto kv_r = parse_key_value_pair<value_type>(loc);
|
const auto kv_r = parse_key_value_pair<value_type>(loc);
|
||||||
@@ -1490,7 +1471,7 @@ parse_inline_table(location<Container>& loc)
|
|||||||
}
|
}
|
||||||
const auto& kvpair = kv_r.unwrap();
|
const auto& kvpair = kv_r.unwrap();
|
||||||
const std::vector<key>& keys = kvpair.first.first;
|
const std::vector<key>& keys = kvpair.first.first;
|
||||||
const region<Container>& key_reg = kvpair.first.second;
|
const auto& key_reg = kvpair.first.second;
|
||||||
const value_type& val = kvpair.second;
|
const value_type& val = kvpair.second;
|
||||||
|
|
||||||
const auto inserted =
|
const auto inserted =
|
||||||
@@ -1511,7 +1492,7 @@ parse_inline_table(location<Container>& loc)
|
|||||||
{
|
{
|
||||||
loc.advance(); // skip `}`
|
loc.advance(); // skip `}`
|
||||||
return ok(std::make_pair(
|
return ok(std::make_pair(
|
||||||
retval, region<Container>(loc, first, loc.iter())));
|
retval, region<std::vector<char>>(loc, first, loc.iter())));
|
||||||
}
|
}
|
||||||
else if(*loc.iter() == '#' || *loc.iter() == '\r' || *loc.iter() == '\n')
|
else if(*loc.iter() == '#' || *loc.iter() == '\r' || *loc.iter() == '\n')
|
||||||
{
|
{
|
||||||
@@ -1536,8 +1517,7 @@ parse_inline_table(location<Container>& loc)
|
|||||||
source_location(std::addressof(loc)));
|
source_location(std::addressof(loc)));
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename Container>
|
inline result<value_t, std::string> guess_number_type(const location& l)
|
||||||
result<value_t, std::string> guess_number_type(const location<Container>& l)
|
|
||||||
{
|
{
|
||||||
// This function tries to find some (common) mistakes by checking characters
|
// This function tries to find some (common) mistakes by checking characters
|
||||||
// that follows the last character of a value. But it is often difficult
|
// that follows the last character of a value. But it is often difficult
|
||||||
@@ -1545,7 +1525,7 @@ result<value_t, std::string> guess_number_type(const location<Container>& l)
|
|||||||
// spaces, tabs, commas (in an array or inline table), closing brackets
|
// spaces, tabs, commas (in an array or inline table), closing brackets
|
||||||
// (of an array or inline table), comment-sign (#). Since this function
|
// (of an array or inline table), comment-sign (#). Since this function
|
||||||
// does not parse further, those characters are always allowed to be there.
|
// does not parse further, those characters are always allowed to be there.
|
||||||
location<Container> loc = l;
|
location loc = l;
|
||||||
|
|
||||||
if(lex_offset_date_time::invoke(loc)) {return ok(value_t::offset_datetime);}
|
if(lex_offset_date_time::invoke(loc)) {return ok(value_t::offset_datetime);}
|
||||||
loc.reset(l.iter());
|
loc.reset(l.iter());
|
||||||
@@ -1674,8 +1654,7 @@ result<value_t, std::string> guess_number_type(const location<Container>& l)
|
|||||||
{{std::addressof(loc), "here"}}));
|
{{std::addressof(loc), "here"}}));
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename Container>
|
inline result<value_t, std::string> guess_value_type(const location& loc)
|
||||||
result<value_t, std::string> guess_value_type(const location<Container>& loc)
|
|
||||||
{
|
{
|
||||||
switch(*loc.iter())
|
switch(*loc.iter())
|
||||||
{
|
{
|
||||||
@@ -1691,8 +1670,8 @@ result<value_t, std::string> guess_value_type(const location<Container>& loc)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename Value, typename Container>
|
template<typename Value>
|
||||||
result<Value, std::string> parse_value(location<Container>& loc)
|
result<Value, std::string> parse_value(location& loc)
|
||||||
{
|
{
|
||||||
using value_type = Value;
|
using value_type = Value;
|
||||||
|
|
||||||
@@ -1730,13 +1709,12 @@ result<Value, std::string> parse_value(location<Container>& loc)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename Container>
|
inline result<std::pair<std::vector<key>, region<std::vector<char>>>, std::string>
|
||||||
result<std::pair<std::vector<key>, region<Container>>, std::string>
|
parse_table_key(location& loc)
|
||||||
parse_table_key(location<Container>& loc)
|
|
||||||
{
|
{
|
||||||
if(auto token = lex_std_table::invoke(loc))
|
if(auto token = lex_std_table::invoke(loc))
|
||||||
{
|
{
|
||||||
location<std::vector<char>> inner_loc(loc.name(), token.unwrap().str());
|
location inner_loc(loc.name(), token.unwrap().str());
|
||||||
|
|
||||||
const auto open = lex_std_table_open::invoke(inner_loc);
|
const auto open = lex_std_table_open::invoke(inner_loc);
|
||||||
if(!open || inner_loc.iter() == inner_loc.end())
|
if(!open || inner_loc.iter() == inner_loc.end())
|
||||||
@@ -1792,13 +1770,12 @@ parse_table_key(location<Container>& loc)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename Container>
|
inline result<std::pair<std::vector<key>, region<std::vector<char>>>, std::string>
|
||||||
result<std::pair<std::vector<key>, region<Container>>, std::string>
|
parse_array_table_key(location& loc)
|
||||||
parse_array_table_key(location<Container>& loc)
|
|
||||||
{
|
{
|
||||||
if(auto token = lex_array_table::invoke(loc))
|
if(auto token = lex_array_table::invoke(loc))
|
||||||
{
|
{
|
||||||
location<std::vector<char>> inner_loc(loc.name(), token.unwrap().str());
|
location inner_loc(loc.name(), token.unwrap().str());
|
||||||
|
|
||||||
const auto open = lex_array_table_open::invoke(inner_loc);
|
const auto open = lex_array_table_open::invoke(inner_loc);
|
||||||
if(!open || inner_loc.iter() == inner_loc.end())
|
if(!open || inner_loc.iter() == inner_loc.end())
|
||||||
@@ -1851,9 +1828,9 @@ parse_array_table_key(location<Container>& loc)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// parse table body (key-value pairs until the iter hits the next [tablekey])
|
// parse table body (key-value pairs until the iter hits the next [tablekey])
|
||||||
template<typename Value, typename Container>
|
template<typename Value>
|
||||||
result<typename Value::table_type, std::string>
|
result<typename Value::table_type, std::string>
|
||||||
parse_ml_table(location<Container>& loc)
|
parse_ml_table(location& loc)
|
||||||
{
|
{
|
||||||
using value_type = Value;
|
using value_type = Value;
|
||||||
using table_type = typename value_type::table_type;
|
using table_type = typename value_type::table_type;
|
||||||
@@ -1890,7 +1867,7 @@ parse_ml_table(location<Container>& loc)
|
|||||||
{
|
{
|
||||||
const auto& kvpair = kv.unwrap();
|
const auto& kvpair = kv.unwrap();
|
||||||
const std::vector<key>& keys = kvpair.first.first;
|
const std::vector<key>& keys = kvpair.first.first;
|
||||||
const region<Container>& key_reg = kvpair.first.second;
|
const auto& key_reg = kvpair.first.second;
|
||||||
const value_type& val = kvpair.second;
|
const value_type& val = kvpair.second;
|
||||||
const auto inserted =
|
const auto inserted =
|
||||||
insert_nested_key(tab, val, keys.begin(), keys.end(), key_reg);
|
insert_nested_key(tab, val, keys.begin(), keys.end(), key_reg);
|
||||||
@@ -1936,8 +1913,8 @@ parse_ml_table(location<Container>& loc)
|
|||||||
return ok(tab);
|
return ok(tab);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename Value, typename Container>
|
template<typename Value>
|
||||||
result<Value, std::string> parse_toml_file(location<Container>& loc)
|
result<Value, std::string> parse_toml_file(location& loc)
|
||||||
{
|
{
|
||||||
using value_type = Value;
|
using value_type = Value;
|
||||||
using table_type = typename value_type::table_type;
|
using table_type = typename value_type::table_type;
|
||||||
@@ -1950,7 +1927,7 @@ result<Value, std::string> parse_toml_file(location<Container>& loc)
|
|||||||
|
|
||||||
// put the first line as a region of a file
|
// put the first line as a region of a file
|
||||||
// Here first != loc.end(), so taking std::next is okay
|
// Here first != loc.end(), so taking std::next is okay
|
||||||
const region<Container> file(loc, first, std::next(loc.iter()));
|
const region<std::vector<char>> file(loc, first, std::next(loc.iter()));
|
||||||
|
|
||||||
// The first successive comments that are separated from the first value
|
// The first successive comments that are separated from the first value
|
||||||
// by an empty line are for a file itself.
|
// by an empty line are for a file itself.
|
||||||
@@ -1970,7 +1947,7 @@ result<Value, std::string> parse_toml_file(location<Container>& loc)
|
|||||||
>;
|
>;
|
||||||
if(const auto token = lex_first_comments::invoke(loc))
|
if(const auto token = lex_first_comments::invoke(loc))
|
||||||
{
|
{
|
||||||
location<std::vector<char>> inner_loc(loc.name(), token.unwrap().str());
|
location inner_loc(loc.name(), token.unwrap().str());
|
||||||
while(inner_loc.iter() != inner_loc.end())
|
while(inner_loc.iter() != inner_loc.end())
|
||||||
{
|
{
|
||||||
maybe<lex_ws>::invoke(inner_loc); // remove ws if exists
|
maybe<lex_ws>::invoke(inner_loc); // remove ws if exists
|
||||||
@@ -2071,8 +2048,7 @@ parse(std::istream& is, const std::string& fname = "unknown file")
|
|||||||
}
|
}
|
||||||
assert(letters.empty() || letters.back() != '\0');
|
assert(letters.empty() || letters.back() != '\0');
|
||||||
|
|
||||||
detail::location<std::vector<char>>
|
detail::location loc(std::move(fname), std::move(letters));
|
||||||
loc(std::move(fname), std::move(letters));
|
|
||||||
|
|
||||||
// skip BOM if exists.
|
// skip BOM if exists.
|
||||||
// XXX component of BOM (like 0xEF) exceeds the representable range of
|
// XXX component of BOM (like 0xEF) exceeds the representable range of
|
||||||
|
|||||||
@@ -67,25 +67,18 @@ struct region_base
|
|||||||
//
|
//
|
||||||
// it contains pointer to the file content and iterator that points the current
|
// it contains pointer to the file content and iterator that points the current
|
||||||
// location.
|
// location.
|
||||||
template<typename Container>
|
|
||||||
struct location final : public region_base
|
struct location final : public region_base
|
||||||
{
|
{
|
||||||
using const_iterator = typename Container::const_iterator;
|
using const_iterator = typename std::vector<char>::const_iterator;
|
||||||
using difference_type = typename const_iterator::difference_type;
|
using difference_type = typename const_iterator::difference_type;
|
||||||
using source_ptr = std::shared_ptr<const Container>;
|
using source_ptr = std::shared_ptr<const std::vector<char>>;
|
||||||
|
|
||||||
static_assert(std::is_same<char, typename Container::value_type>::value,"");
|
location(std::string name, std::vector<char> cont)
|
||||||
static_assert(std::is_same<std::random_access_iterator_tag,
|
: source_(std::make_shared<std::vector<char>>(std::move(cont))),
|
||||||
typename std::iterator_traits<const_iterator>::iterator_category>::value,
|
line_number_(1), source_name_(std::move(name)), iter_(source_->cbegin())
|
||||||
"container should be randomly accessible");
|
|
||||||
|
|
||||||
location(std::string name, Container cont)
|
|
||||||
: source_(std::make_shared<Container>(std::move(cont))), line_number_(1),
|
|
||||||
source_name_(std::move(name)), iter_(source_->cbegin())
|
|
||||||
{}
|
{}
|
||||||
|
|
||||||
location(std::string name, const std::string& cont)
|
location(std::string name, const std::string& cont)
|
||||||
: source_(std::make_shared<Container>(cont.begin(), cont.end())),
|
: source_(std::make_shared<std::vector<char>>(cont.begin(), cont.end())),
|
||||||
line_number_(1), source_name_(std::move(name)), iter_(source_->cbegin())
|
line_number_(1), source_name_(std::move(name)), iter_(source_->cbegin())
|
||||||
{}
|
{}
|
||||||
|
|
||||||
@@ -215,19 +208,19 @@ struct region final : public region_base
|
|||||||
// delete default constructor. source_ never be null.
|
// delete default constructor. source_ never be null.
|
||||||
region() = delete;
|
region() = delete;
|
||||||
|
|
||||||
region(const location<Container>& loc)
|
region(const location& loc)
|
||||||
: source_(loc.source()), source_name_(loc.name()),
|
: source_(loc.source()), source_name_(loc.name()),
|
||||||
first_(loc.iter()), last_(loc.iter())
|
first_(loc.iter()), last_(loc.iter())
|
||||||
{}
|
{}
|
||||||
region(location<Container>&& loc)
|
region(location&& loc)
|
||||||
: source_(loc.source()), source_name_(loc.name()),
|
: source_(loc.source()), source_name_(loc.name()),
|
||||||
first_(loc.iter()), last_(loc.iter())
|
first_(loc.iter()), last_(loc.iter())
|
||||||
{}
|
{}
|
||||||
|
|
||||||
region(const location<Container>& loc, const_iterator f, const_iterator l)
|
region(const location& loc, const_iterator f, const_iterator l)
|
||||||
: source_(loc.source()), source_name_(loc.name()), first_(f), last_(l)
|
: source_(loc.source()), source_name_(loc.name()), first_(f), last_(l)
|
||||||
{}
|
{}
|
||||||
region(location<Container>&& loc, const_iterator f, const_iterator l)
|
region(location&& loc, const_iterator f, const_iterator l)
|
||||||
: source_(loc.source()), source_name_(loc.name()), first_(f), last_(l)
|
: source_(loc.source()), source_name_(loc.name()), first_(f), last_(l)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ std::basic_string<charT, traits, Alloc>
|
|||||||
format_key(const std::basic_string<charT, traits, Alloc>& key)
|
format_key(const std::basic_string<charT, traits, Alloc>& key)
|
||||||
{
|
{
|
||||||
// check the key can be a bare (unquoted) key
|
// check the key can be a bare (unquoted) key
|
||||||
detail::location<toml::key> loc(key, key);
|
detail::location loc(key, std::vector<char>(key.begin(), key.end()));
|
||||||
detail::lex_unquoted_key::invoke(loc);
|
detail::lex_unquoted_key::invoke(loc);
|
||||||
if(loc.iter() == loc.end())
|
if(loc.iter() == loc.end())
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user