diff --git a/tests/test_parse_file.cpp b/tests/test_parse_file.cpp index b3b1bbc..fa03d55 100644 --- a/tests/test_parse_file.cpp +++ b/tests/test_parse_file.cpp @@ -96,11 +96,34 @@ BOOST_AUTO_TEST_CASE(test_fruit) } } -// BOOST_AUTO_TEST_CASE(test_hard_example) -// { -// -// } -// +BOOST_AUTO_TEST_CASE(test_hard_example) +{ + const auto data = toml::parse("toml/tests/hard_example.toml"); + const auto the = toml::get(data.at("the")); + BOOST_CHECK_EQUAL(toml::get(the.at("test_string")), + "You'll hate me after this - #"); + + const auto hard = toml::get(the.at("hard")); + const std::vector expected_the_hard_test_array{"] ", " # "}; + BOOST_CHECK(toml::get>(hard.at("test_array")) == + expected_the_hard_test_array); + const std::vector expected_the_hard_test_array2{ + "Test #11 ]proved that", "Experiment #9 was a success"}; + BOOST_CHECK(toml::get>(hard.at("test_array2")) == + expected_the_hard_test_array2); + BOOST_CHECK_EQUAL(toml::get(hard.at("another_test_string")), + " Same thing, but with a string #"); + BOOST_CHECK_EQUAL(toml::get(hard.at("harder_test_string")), + " And when \"'s are in the string, along with # \""); + + const auto bit = toml::get(hard.at("bit#")); + BOOST_CHECK_EQUAL(toml::get(bit.at("what?")), + "You don't think some user won't do that?"); + const std::vector expected_multi_line_array{"]"}; + BOOST_CHECK(toml::get>(bit.at("multi_line_array")) == + expected_multi_line_array); +} + // BOOST_AUTO_TEST_CASE(test_hard_example_unicode) // { // ; diff --git a/toml/parser.hpp b/toml/parser.hpp index 3422264..f5e3197 100644 --- a/toml/parser.hpp +++ b/toml/parser.hpp @@ -944,12 +944,27 @@ struct parse_data } if(data.count(*iter) == 0) + { data.emplace(*iter, toml::Table()); - else if(data[*iter].type() != value_t::Table) - throw syntax_error("duplicate key: " + *iter); - - return push_table(data[*iter].template cast(), - std::move(v), std::next(iter), end); + return push_table(data[*iter].template cast(), + std::move(v), std::next(iter), end); + } + else if(data[*iter].type() == value_t::Table) + { + return push_table(data[*iter].template cast(), + std::move(v), std::next(iter), end); + } + else if(data[*iter].type() == value_t::Array) + { + auto& ar = data[*iter].template cast(); + if(ar.empty()) ar.emplace_back(toml::Table{}); + if(ar.back().type() != value_t::Table) + throw syntax_error("assign table into array having non-table type: " + *iter); + return push_table(ar.back().template cast(), + std::move(v), std::next(iter), end); + } + else + throw syntax_error("assign table into not table: " + *iter); } template(), - std::move(v), std::next(iter), end); + return push_array_of_table(data[*iter].template cast(), + std::move(v), std::next(iter), end); + } + else if(data[*iter].type() == value_t::Table) + { + return push_array_of_table(data[*iter].template cast(), + std::move(v), std::next(iter), end); + } + else if(data[*iter].type() == value_t::Array) + { + auto& ar = data[*iter].template cast(); + if(ar.empty()) ar.emplace_back(toml::Table{}); + if(ar.back().type() != value_t::Table) + throw syntax_error("assign table into array having non-table type: " + *iter); + return push_array_of_table(ar.back().template cast(), + std::move(v), std::next(iter), end); + } + else + throw syntax_error("assign array of table into not table: " + *iter); } };