mirror of
https://github.com/marzer/tomlplusplus.git
synced 2026-02-23 16:22:11 +00:00
added iterators for tables and arrays
also: - fixed parsing table headers allowing invalid characters - fixed implicit fallthrough warnings - fixed some issues parsing dates and times - added `table::erase` - added `array::operator[]` - added `value::operator*` - added stream operators for date, time and date_time - added `impl::print_to_stream` - added more parsing diagnostics - added many tests
This commit is contained in:
@@ -8,27 +8,27 @@ TEST_CASE("lifetime - tables")
|
||||
S(R"(test = { val1 = "foo" })"sv),
|
||||
[&](table&& tbl) noexcept
|
||||
{
|
||||
CHECK(tbl.region().begin == source_position{ 1, 1 });
|
||||
CHECK(tbl.region().end == source_position{ 1, 25 });
|
||||
CHECK(tbl.region().path);
|
||||
CHECK(*tbl.region().path == filename);
|
||||
CHECK(tbl.source().begin == source_position{ 1, 1 });
|
||||
CHECK(tbl.source().end == source_position{ 1, 25 });
|
||||
CHECK(tbl.source().path);
|
||||
CHECK(*tbl.source().path == filename);
|
||||
CHECK(tbl.size() == 1_sz);
|
||||
REQUIRE(tbl[S("test")].as<table>());
|
||||
CHECK(tbl[S("test")].as<table>()->size() == 1_sz);
|
||||
CHECK(tbl[S("test")][S("val1")] == S("foo"sv));
|
||||
|
||||
table test_table;
|
||||
CHECK(test_table.region().begin == source_position{});
|
||||
CHECK(test_table.region().end == source_position{});
|
||||
CHECK(!test_table.region().path);
|
||||
CHECK(test_table.source().begin == source_position{});
|
||||
CHECK(test_table.source().end == source_position{});
|
||||
CHECK(!test_table.source().path);
|
||||
CHECK(test_table.size() == 0_sz);
|
||||
CHECK(!test_table[S("test")].as<table>());
|
||||
|
||||
test_table = std::move(tbl);
|
||||
CHECK(test_table.region().begin == source_position{ 1, 1 });
|
||||
CHECK(test_table.region().end == source_position{ 1, 25 });
|
||||
CHECK(test_table.region().path);
|
||||
CHECK(*test_table.region().path == filename);
|
||||
CHECK(test_table.source().begin == source_position{ 1, 1 });
|
||||
CHECK(test_table.source().end == source_position{ 1, 25 });
|
||||
CHECK(test_table.source().path);
|
||||
CHECK(*test_table.source().path == filename);
|
||||
CHECK(test_table.size() == 1_sz);
|
||||
REQUIRE(test_table[S("test")].as<table>());
|
||||
CHECK(test_table[S("test")].as<table>()->size() == 1_sz);
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#include "tests.h"
|
||||
|
||||
TOML_PUSH_WARNINGS
|
||||
TOML_DISABLE_FIELD_INIT_WARNING
|
||||
TOML_DISABLE_INIT_WARNINGS
|
||||
|
||||
TEST_CASE("parsing dates and times")
|
||||
{
|
||||
@@ -20,9 +20,9 @@ lt2 = 00:32:00.999999
|
||||
{
|
||||
static constexpr auto odt1 = date_time{ { 1979, 5, 27 }, { 7, 32 }, time_offset{} };
|
||||
CHECK(tbl[S("odt1")] == odt1);
|
||||
static constexpr auto odt2 = date_time{ { 1979, 5, 27 }, { 0, 32 }, time_offset{ -7 } };
|
||||
static constexpr auto odt2 = date_time{ { 1979, 5, 27 }, { 0, 32 }, time_offset::from_hh_mm(-7, 0) };
|
||||
CHECK(tbl[S("odt2")] == odt2);
|
||||
static constexpr auto odt3 = date_time{ { 1979, 5, 27 }, { 0, 32, 0, 999999000u }, time_offset{ -7 } };
|
||||
static constexpr auto odt3 = date_time{ { 1979, 5, 27 }, { 0, 32, 0, 999999000u }, time_offset::from_hh_mm(-7, 0) };
|
||||
CHECK(tbl[S("odt3")] == odt3);
|
||||
static constexpr auto odt4 = date_time{ { 1979, 5, 27 }, { 7, 32 }, time_offset{} };
|
||||
CHECK(tbl[S("odt4")] == odt4);
|
||||
@@ -38,6 +38,91 @@ lt2 = 00:32:00.999999
|
||||
CHECK(tbl[S("lt2")] == lt2);
|
||||
}
|
||||
);
|
||||
|
||||
//value tests
|
||||
parse_expected_value( "1987-03-16"sv, date{ 1987, 3, 16 } );
|
||||
parse_expected_value( "10:20:30"sv, toml::time{ 10, 20, 30 } );
|
||||
parse_expected_value( "10:20:30.04"sv, toml::time{ 10, 20, 30, 40000000 } );
|
||||
{
|
||||
const auto val = date_time{ { 1987, 3, 16 }, { 10, 20, 30 } };
|
||||
parse_expected_value("1987-03-16T10:20:30"sv, val);
|
||||
parse_expected_value("1987-03-16 10:20:30"sv, val);
|
||||
}
|
||||
{
|
||||
const auto val = date_time{ { 1987, 3, 16 }, { 10, 20, 30 }, time_offset::from_hh_mm( -9, -30 ) };
|
||||
parse_expected_value("1987-03-16T10:20:30-09:30"sv, val);
|
||||
parse_expected_value("1987-03-16 10:20:30-09:30"sv, val);
|
||||
}
|
||||
{
|
||||
const auto val = date_time{ { 1987, 3, 16 }, { 10, 20, 30 }, time_offset::from_hh_mm( 9, 30 ) };
|
||||
parse_expected_value("1987-03-16T10:20:30+09:30"sv, val);
|
||||
parse_expected_value("1987-03-16 10:20:30+09:30"sv, val);
|
||||
}
|
||||
{
|
||||
const auto val = date_time{ { 1987, 3, 16 }, { 10, 20, 30, 40000000 } };
|
||||
parse_expected_value("1987-03-16T10:20:30.04"sv, val);
|
||||
parse_expected_value("1987-03-16 10:20:30.04"sv, val);
|
||||
}
|
||||
{
|
||||
const auto val = date_time{ { 1987, 3, 16 }, { 10, 20, 30, 40000000 }, time_offset::from_hh_mm( -9, -30 ) };
|
||||
parse_expected_value("1987-03-16T10:20:30.04-09:30"sv, val);
|
||||
parse_expected_value("1987-03-16 10:20:30.04-09:30"sv, val);
|
||||
}
|
||||
{
|
||||
const auto val = date_time{ { 1987, 3, 16 }, { 10, 20, 30, 40000000 }, time_offset::from_hh_mm( 9, 30 ) };
|
||||
parse_expected_value("1987-03-16T10:20:30.04+09:30"sv, val);
|
||||
parse_expected_value("1987-03-16 10:20:30.04+09:30"sv, val);
|
||||
}
|
||||
{
|
||||
const auto val = date_time{ { 1987, 3, 16 }, { 10, 20, 30 }, time_offset{} };
|
||||
parse_expected_value("1987-03-16T10:20:30Z"sv, val);
|
||||
parse_expected_value("1987-03-16 10:20:30Z"sv, val);
|
||||
}
|
||||
{
|
||||
const auto val = date_time{ { 1987, 3, 16 }, { 10, 20, 30, 40000000 }, time_offset{} };
|
||||
parse_expected_value("1987-03-16T10:20:30.04Z"sv, val);
|
||||
parse_expected_value("1987-03-16 10:20:30.04Z"sv, val);
|
||||
}
|
||||
|
||||
// toml/issues/671 - omitting seconds
|
||||
#if TOML_LANG_HIGHER_THAN(0, 5, 0)
|
||||
|
||||
parse_expected_value( "10:20"sv, toml::time{ 10, 20 } );
|
||||
{
|
||||
const auto val = date_time{ { 1987, 3, 16 }, { 10, 20 } };
|
||||
parse_expected_value("1987-03-16T10:20"sv, val );
|
||||
parse_expected_value("1987-03-16 10:20"sv, val );
|
||||
}
|
||||
{
|
||||
const auto val = date_time{ { 1987, 3, 16 }, { 10, 20 }, time_offset::from_hh_mm( -9, -30 ) };
|
||||
parse_expected_value("1987-03-16T10:20-09:30"sv, val);
|
||||
parse_expected_value("1987-03-16 10:20-09:30"sv, val);
|
||||
}
|
||||
{
|
||||
const auto val = date_time{ { 1987, 3, 16 }, { 10, 20 }, time_offset::from_hh_mm( 9, 30 ) };
|
||||
parse_expected_value("1987-03-16T10:20+09:30"sv, val);
|
||||
parse_expected_value("1987-03-16 10:20+09:30"sv, val);
|
||||
}
|
||||
{
|
||||
const auto val = date_time{ { 1987, 3, 16 }, { 10, 20 }, time_offset{} };
|
||||
parse_expected_value("1987-03-16T10:20Z"sv, val);
|
||||
parse_expected_value("1987-03-16 10:20Z"sv, val);
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
parsing_should_fail("10:20"sv);
|
||||
parsing_should_fail("1987-03-16T10:20"sv);
|
||||
parsing_should_fail("1987-03-16 10:20"sv);
|
||||
parsing_should_fail("1987-03-16T10:20-09:30"sv);
|
||||
parsing_should_fail("1987-03-16 10:20-09:30"sv);
|
||||
parsing_should_fail("1987-03-16T10:20+09:30"sv);
|
||||
parsing_should_fail("1987-03-16 10:20+09:30"sv);
|
||||
parsing_should_fail("1987-03-16T10:20Z"sv);
|
||||
parsing_should_fail("1987-03-16 10:20Z"sv);
|
||||
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
TOML_POP_WARNINGS
|
||||
|
||||
@@ -47,43 +47,60 @@ flt8 = 224_617.445_991_228
|
||||
);
|
||||
|
||||
//value tests
|
||||
parse_expected_value( "1e1"sv, 1e1 );
|
||||
parse_expected_value( "1e-1"sv, 1e-1 );
|
||||
parse_expected_value( "1e+1"sv, 1e+1 );
|
||||
parse_expected_value( "1.0"sv, 1.0 );
|
||||
parse_expected_value( "0.1"sv, 0.1 );
|
||||
parse_expected_value( "0.001"sv, 0.001 );
|
||||
parse_expected_value( "0.100"sv, 0.1 );
|
||||
parse_expected_value( "+3.14"sv, 3.14 );
|
||||
parse_expected_value( "-3.14"sv, -3.14 );
|
||||
parse_expected_value( "3.1415_9265_3589"sv, 3.141592653589 );
|
||||
parse_expected_value( "+3.1415_9265_3589"sv, 3.141592653589 );
|
||||
parse_expected_value( "-3.1415_9265_3589"sv, -3.141592653589 );
|
||||
parse_expected_value( "123_456.789"sv, 123456.789 );
|
||||
parse_expected_value( "+123_456.789"sv, 123456.789 );
|
||||
parse_expected_value( "-123_456.789"sv, -123456.789 );
|
||||
parse_expected_value( "+0.0"sv, 0.0 );
|
||||
parse_expected_value( "-0.0"sv, -0.0 );
|
||||
parse_expected_value( "1e10"sv, 1e10 );
|
||||
parse_expected_value( "1e+10"sv, 1e10 );
|
||||
parse_expected_value( "1e-10"sv, 1e-10 );
|
||||
parse_expected_value( "+1e10"sv, 1e10 );
|
||||
parse_expected_value( "+1e+10"sv, 1e10 );
|
||||
parse_expected_value( "+1e-10"sv, 1e-10 );
|
||||
parse_expected_value( "-1e10"sv, -1e10 );
|
||||
parse_expected_value( "-1e+10"sv, -1e10 );
|
||||
parse_expected_value( "-1e-10"sv, -1e-10 );
|
||||
parse_expected_value( "123e-10"sv, 123e-10 );
|
||||
parse_expected_value( "1E10"sv, 1e10 );
|
||||
parse_expected_value( "1E+10"sv, 1e10 );
|
||||
parse_expected_value( "1E-10"sv, 1e-10 );
|
||||
parse_expected_value( "123E-10"sv, 123e-10 );
|
||||
parse_expected_value( "1_2_3E-10"sv, 123e-10 );
|
||||
parse_expected_value( "1_2_3E-1_0"sv, 123e-10 );
|
||||
parse_expected_value( "+0e0"sv, 0.0 );
|
||||
parse_expected_value( "-0e0"sv, -0.0 );
|
||||
parse_expected_value( "1_2_3E-01"sv, 123e-1 );
|
||||
parse_expected_value( "1_2_3E-0_1"sv, 123e-1 );
|
||||
parse_expected_value( "6.02e23"sv, 6.02e23 );
|
||||
parse_expected_value( "6.02e+23"sv, 6.02e23 );
|
||||
parse_expected_value( "1.112_650_06e-17"sv, 1.11265006e-17 );
|
||||
parse_expected_value( "1.0e1"sv, 1.0e1 );
|
||||
parse_expected_value( "1.0e-1"sv, 1.0e-1 );
|
||||
parse_expected_value( "1.0e+1"sv, 1.0e+1 );
|
||||
parse_expected_value( "+1e1"sv, +1e1 );
|
||||
parse_expected_value( "+1.0"sv, +1.0 );
|
||||
parse_expected_value( "+1.0e1"sv, +1.0e1 );
|
||||
parse_expected_value( "+1.0e+1"sv, +1.0e+1 );
|
||||
parse_expected_value( "+1.0e-1"sv, +1.0e-1 );
|
||||
parse_expected_value( "-1.0e+1"sv, -1.0e+1 );
|
||||
parse_expected_value( "-1e1"sv, -1e1 );
|
||||
parse_expected_value( "-1.0"sv, -1.0 );
|
||||
parse_expected_value( "-1.0e1"sv, -1.0e1 );
|
||||
parse_expected_value( "-1.0e-1"sv, -1.0e-1 );
|
||||
parse_expected_value( "1.0"sv, 1.0 );
|
||||
parse_expected_value( "0.1"sv, 0.1 );
|
||||
parse_expected_value( "0.001"sv, 0.001 );
|
||||
parse_expected_value( "0.100"sv, 0.100 );
|
||||
parse_expected_value( "+3.14"sv, +3.14 );
|
||||
parse_expected_value( "-3.14"sv, -3.14 );
|
||||
parse_expected_value( "3.1415_9265_3589"sv, 3.141592653589 );
|
||||
parse_expected_value( "+3.1415_9265_3589"sv, +3.141592653589 );
|
||||
parse_expected_value( "-3.1415_9265_3589"sv, -3.141592653589 );
|
||||
parse_expected_value( "123_456.789"sv, 123456.789 );
|
||||
parse_expected_value( "+123_456.789"sv, +123456.789 );
|
||||
parse_expected_value( "-123_456.789"sv, -123456.789 );
|
||||
parse_expected_value( "+0.0"sv, +0.0 );
|
||||
parse_expected_value( "-0.0"sv, -0.0 );
|
||||
parse_expected_value( "1e10"sv, 1e10 );
|
||||
parse_expected_value( "1e+10"sv, 1e+10 );
|
||||
parse_expected_value( "1e-10"sv, 1e-10 );
|
||||
parse_expected_value( "+1e10"sv, +1e10 );
|
||||
parse_expected_value( "+1e+10"sv, +1e+10 );
|
||||
parse_expected_value( "+1e-10"sv, +1e-10 );
|
||||
parse_expected_value( "-1e10"sv, -1e10 );
|
||||
parse_expected_value( "-1e+10"sv, -1e+10 );
|
||||
parse_expected_value( "-1e-10"sv, -1e-10 );
|
||||
parse_expected_value( "123e-10"sv, 123e-10 );
|
||||
parse_expected_value( "1E10"sv, 1E10 );
|
||||
parse_expected_value( "1E+10"sv, 1E+10 );
|
||||
parse_expected_value( "1E-10"sv, 1E-10 );
|
||||
parse_expected_value( "123E-10"sv, 123E-10 );
|
||||
parse_expected_value( "1_2_3E-10"sv, 123E-10 );
|
||||
parse_expected_value( "1_2_3E-1_0"sv, 123E-10 );
|
||||
parse_expected_value( "+0e0"sv, +0e0 );
|
||||
parse_expected_value( "-0e0"sv, -0e0 );
|
||||
parse_expected_value( "1_2_3E-01"sv, 123E-01 );
|
||||
parse_expected_value( "1_2_3E-0_1"sv, 123E-01 );
|
||||
parse_expected_value( "6.02e23"sv, 6.02e23 );
|
||||
parse_expected_value( "6.02e+23"sv, 6.02e+23 );
|
||||
parse_expected_value( "1.112_650_06e-17"sv, 1.11265006e-17 );
|
||||
|
||||
//toml/issues/562 - hexfloat literals
|
||||
#if TOML_LANG_HIGHER_THAN(0, 5, 0) && !TOML_USE_STREAMS_FOR_FLOATS
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#include "tests.h"
|
||||
|
||||
TOML_PUSH_WARNINGS
|
||||
TOML_DISABLE_FIELD_INIT_WARNING
|
||||
TOML_DISABLE_INIT_WARNINGS
|
||||
|
||||
TEST_CASE("parsing TOML spec example")
|
||||
{
|
||||
@@ -49,7 +49,7 @@ hosts = [
|
||||
CHECK(tbl[S("owner")]);
|
||||
CHECK(tbl[S("owner")].as<table>());
|
||||
CHECK(tbl[S("owner")][S("name")] == S("Tom Preston-Werner"sv));
|
||||
const auto dob = date_time{ { 1979, 5, 27 }, { 7, 32 }, time_offset{ -8 } };
|
||||
const auto dob = date_time{ { 1979, 5, 27 }, { 7, 32 }, time_offset::from_hh_mm(-8, 0) };
|
||||
CHECK(tbl[S("owner")][S("dob")] == dob);
|
||||
|
||||
CHECK(tbl[S("database")].as<table>());
|
||||
|
||||
@@ -16,14 +16,14 @@ void parsing_should_succeed(std::basic_string_view<CHAR> toml_str, FUNC&& func,
|
||||
{
|
||||
constexpr auto validate_table = [](table&& tabl, std::string_view path) noexcept -> table&&
|
||||
{
|
||||
CHECK(tabl.region().begin != source_position{});
|
||||
CHECK(tabl.region().end != source_position{});
|
||||
CHECK(tabl.source().begin != source_position{});
|
||||
CHECK(tabl.source().end != source_position{});
|
||||
if (path.empty())
|
||||
CHECK(tabl.region().path == nullptr);
|
||||
CHECK(tabl.source().path == nullptr);
|
||||
else
|
||||
{
|
||||
REQUIRE(tabl.region().path != nullptr);
|
||||
CHECK(*tabl.region().path == path);
|
||||
REQUIRE(tabl.source().path != nullptr);
|
||||
CHECK(*tabl.source().path == path);
|
||||
}
|
||||
|
||||
return std::move(tabl);
|
||||
@@ -58,9 +58,9 @@ void parsing_should_succeed(std::basic_string_view<CHAR> toml_str, FUNC&& func,
|
||||
else
|
||||
{
|
||||
FAIL(
|
||||
"Parse error on line "sv << result.error().where.begin.line
|
||||
<< ", column "sv << result.error().where.begin.column
|
||||
<< ":\n"sv << result.error().what
|
||||
"Parse error on line "sv << result.error().where().begin.line
|
||||
<< ", column "sv << result.error().where().begin.column
|
||||
<< ":\n"sv << result.error().what()
|
||||
);
|
||||
return;
|
||||
}
|
||||
@@ -75,9 +75,9 @@ void parsing_should_succeed(std::basic_string_view<CHAR> toml_str, FUNC&& func,
|
||||
else
|
||||
{
|
||||
FAIL(
|
||||
"Parse error on line "sv << result.error().where.begin.line
|
||||
<< ", column "sv << result.error().where.begin.column
|
||||
<< ":\n"sv << result.error().what
|
||||
"Parse error on line "sv << result.error().where().begin.line
|
||||
<< ", column "sv << result.error().where().begin.column
|
||||
<< ":\n"sv << result.error().what()
|
||||
);
|
||||
return;
|
||||
}
|
||||
@@ -160,13 +160,13 @@ void parse_expected_value(std::string_view value_str, const T& expected) noexcep
|
||||
|
||||
static constexpr auto is_val = [](char32_t codepoint) noexcept
|
||||
{
|
||||
if constexpr (std::is_same_v<string, value_of<T>>)
|
||||
if constexpr (std::is_same_v<string, promoted<T>>)
|
||||
return codepoint == U'"' || codepoint == U'\'';
|
||||
else
|
||||
return !impl::is_whitespace(codepoint);
|
||||
};
|
||||
|
||||
source_position pos{ 1, static_cast<uint32_t>(value_key.length()) };
|
||||
source_position pos{ 1, static_cast<source_index>(value_key.length()) };
|
||||
source_position begin{}, end{};
|
||||
impl::utf8_decoder decoder;
|
||||
for (auto c : value_str)
|
||||
@@ -180,7 +180,7 @@ void parse_expected_value(std::string_view value_str, const T& expected) noexcep
|
||||
if (decoder.codepoint != U'\r')
|
||||
{
|
||||
pos.line++;
|
||||
pos.column = 1u;
|
||||
pos.column = source_index{ 1 };
|
||||
}
|
||||
continue;
|
||||
}
|
||||
@@ -201,9 +201,9 @@ void parse_expected_value(std::string_view value_str, const T& expected) noexcep
|
||||
parsing_should_succeed(std::string_view{ value }, [&](table&& tbl) noexcept
|
||||
{
|
||||
CHECK(tbl.size() == 1);
|
||||
REQUIRE(tbl[S("val"sv)].as<value_of<T>>());
|
||||
CHECK(tbl[S("val"sv)].as<value_of<T>>()->get() == expected);
|
||||
CHECK(tbl[S("val"sv)].get()->region().begin == begin);
|
||||
CHECK(tbl[S("val"sv)].get()->region().end == end);
|
||||
REQUIRE(tbl[S("val"sv)].as<promoted<T>>());
|
||||
CHECK(tbl[S("val"sv)].as<promoted<T>>()->get() == expected);
|
||||
CHECK(tbl[S("val"sv)].get()->source().begin == begin);
|
||||
CHECK(tbl[S("val"sv)].get()->source().end == end);
|
||||
});
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user