summaryrefslogtreecommitdiff
path: root/tomlplusplus/tests
diff options
context:
space:
mode:
authorMehmet Samet Duman <yongdohyun@projecttick.org>2026-04-02 18:44:05 +0300
committerMehmet Samet Duman <yongdohyun@projecttick.org>2026-04-02 18:44:05 +0300
commit0b24459ac12b6cf9fd5a401d647796ca254a8fa8 (patch)
treef2fd66e2476976a51e2a51330fd95dc6e87b24c1 /tomlplusplus/tests
parentb85e90fc3480da0e6a48da73201a0b22488cc650 (diff)
parent1c8b7466e4946fcc3bf20484c0e1d001202cca5a (diff)
downloadProject-Tick-0b24459ac12b6cf9fd5a401d647796ca254a8fa8.tar.gz
Project-Tick-0b24459ac12b6cf9fd5a401d647796ca254a8fa8.zip
Add 'tomlplusplus/' from commit '1c8b7466e4946fcc3bf20484c0e1d001202cca5a'
git-subtree-dir: tomlplusplus git-subtree-mainline: b85e90fc3480da0e6a48da73201a0b22488cc650 git-subtree-split: 1c8b7466e4946fcc3bf20484c0e1d001202cca5a
Diffstat (limited to 'tomlplusplus/tests')
-rw-r--r--tomlplusplus/tests/at_path.cpp119
-rw-r--r--tomlplusplus/tests/conformance_burntsushi_invalid.cpp2022
-rw-r--r--tomlplusplus/tests/conformance_burntsushi_valid.cpp4734
-rw-r--r--tomlplusplus/tests/conformance_iarna_invalid.cpp451
-rw-r--r--tomlplusplus/tests/conformance_iarna_valid.cpp2210
-rw-r--r--tomlplusplus/tests/cpp.hint1
-rw-r--r--tomlplusplus/tests/for_each.cpp380
-rw-r--r--tomlplusplus/tests/formatters.cpp332
-rw-r--r--tomlplusplus/tests/impl_toml.cpp407
-rw-r--r--tomlplusplus/tests/leakproof.hpp19
-rw-r--r--tomlplusplus/tests/lib_catch2.hpp44
-rw-r--r--tomlplusplus/tests/main.cpp98
-rw-r--r--tomlplusplus/tests/manipulating_arrays.cpp629
-rw-r--r--tomlplusplus/tests/manipulating_parse_result.cpp115
-rw-r--r--tomlplusplus/tests/manipulating_tables.cpp760
-rw-r--r--tomlplusplus/tests/manipulating_values.cpp590
-rw-r--r--tomlplusplus/tests/meson.build106
-rw-r--r--tomlplusplus/tests/odr_test_1.cpp9
-rw-r--r--tomlplusplus/tests/odr_test_2.cpp2
-rw-r--r--tomlplusplus/tests/parsing_arrays.cpp192
-rw-r--r--tomlplusplus/tests/parsing_booleans.cpp32
-rw-r--r--tomlplusplus/tests/parsing_comments.cpp110
-rw-r--r--tomlplusplus/tests/parsing_dates_and_times.cpp174
-rw-r--r--tomlplusplus/tests/parsing_floats.cpp242
-rw-r--r--tomlplusplus/tests/parsing_integers.cpp177
-rw-r--r--tomlplusplus/tests/parsing_key_value_pairs.cpp399
-rw-r--r--tomlplusplus/tests/parsing_spec_example.cpp92
-rw-r--r--tomlplusplus/tests/parsing_strings.cpp211
-rw-r--r--tomlplusplus/tests/parsing_tables.cpp595
-rw-r--r--tomlplusplus/tests/path.cpp592
-rw-r--r--tomlplusplus/tests/settings.hpp98
-rw-r--r--tomlplusplus/tests/tests.cpp230
-rw-r--r--tomlplusplus/tests/tests.hpp410
-rw-r--r--tomlplusplus/tests/user_feedback.cpp503
-rw-r--r--tomlplusplus/tests/using_iterators.cpp52
-rw-r--r--tomlplusplus/tests/visit.cpp139
-rw-r--r--tomlplusplus/tests/vs/odr_test.vcxproj82
-rw-r--r--tomlplusplus/tests/vs/test_debug_x64.vcxproj127
-rw-r--r--tomlplusplus/tests/vs/test_debug_x64_cpplatest.vcxproj127
-rw-r--r--tomlplusplus/tests/vs/test_debug_x64_cpplatest_noexcept.vcxproj127
-rw-r--r--tomlplusplus/tests/vs/test_debug_x64_cpplatest_noexcept_unrel.vcxproj127
-rw-r--r--tomlplusplus/tests/vs/test_debug_x64_cpplatest_unrel.vcxproj127
-rw-r--r--tomlplusplus/tests/vs/test_debug_x64_noexcept.vcxproj127
-rw-r--r--tomlplusplus/tests/vs/test_debug_x64_noexcept_unrel.vcxproj127
-rw-r--r--tomlplusplus/tests/vs/test_debug_x64_unrel.vcxproj127
-rw-r--r--tomlplusplus/tests/vs/test_debug_x86.vcxproj127
-rw-r--r--tomlplusplus/tests/vs/test_debug_x86_cpplatest.vcxproj127
-rw-r--r--tomlplusplus/tests/vs/test_debug_x86_cpplatest_noexcept.vcxproj127
-rw-r--r--tomlplusplus/tests/vs/test_debug_x86_cpplatest_noexcept_unrel.vcxproj127
-rw-r--r--tomlplusplus/tests/vs/test_debug_x86_cpplatest_unrel.vcxproj127
-rw-r--r--tomlplusplus/tests/vs/test_debug_x86_noexcept.vcxproj127
-rw-r--r--tomlplusplus/tests/vs/test_debug_x86_noexcept_unrel.vcxproj127
-rw-r--r--tomlplusplus/tests/vs/test_debug_x86_unrel.vcxproj127
-rw-r--r--tomlplusplus/tests/vs/test_release_x64.vcxproj127
-rw-r--r--tomlplusplus/tests/vs/test_release_x64_cpplatest.vcxproj127
-rw-r--r--tomlplusplus/tests/vs/test_release_x64_cpplatest_noexcept.vcxproj127
-rw-r--r--tomlplusplus/tests/vs/test_release_x64_cpplatest_noexcept_unrel.vcxproj127
-rw-r--r--tomlplusplus/tests/vs/test_release_x64_cpplatest_unrel.vcxproj127
-rw-r--r--tomlplusplus/tests/vs/test_release_x64_legacy_lambda.vcxproj128
-rw-r--r--tomlplusplus/tests/vs/test_release_x64_noexcept.vcxproj127
-rw-r--r--tomlplusplus/tests/vs/test_release_x64_noexcept_unrel.vcxproj127
-rw-r--r--tomlplusplus/tests/vs/test_release_x64_unrel.vcxproj127
-rw-r--r--tomlplusplus/tests/vs/test_release_x86.vcxproj127
-rw-r--r--tomlplusplus/tests/vs/test_release_x86_cpplatest.vcxproj127
-rw-r--r--tomlplusplus/tests/vs/test_release_x86_cpplatest_noexcept.vcxproj127
-rw-r--r--tomlplusplus/tests/vs/test_release_x86_cpplatest_noexcept_unrel.vcxproj127
-rw-r--r--tomlplusplus/tests/vs/test_release_x86_cpplatest_unrel.vcxproj127
-rw-r--r--tomlplusplus/tests/vs/test_release_x86_noexcept.vcxproj127
-rw-r--r--tomlplusplus/tests/vs/test_release_x86_noexcept_unrel.vcxproj127
-rw-r--r--tomlplusplus/tests/vs/test_release_x86_unrel.vcxproj127
-rw-r--r--tomlplusplus/tests/windows_compat.cpp97
71 files changed, 21647 insertions, 0 deletions
diff --git a/tomlplusplus/tests/at_path.cpp b/tomlplusplus/tests/at_path.cpp
new file mode 100644
index 0000000000..9d9d851059
--- /dev/null
+++ b/tomlplusplus/tests/at_path.cpp
@@ -0,0 +1,119 @@
+// This file is a part of toml++ and is subject to the the terms of the MIT license.
+// Copyright (c) Mark Gillard <mark.gillard@outlook.com.au>
+// See https://github.com/marzer/tomlplusplus/blob/master/LICENSE for the full license text.
+// SPDX-License-Identifier: MIT
+
+#include "tests.hpp"
+TOML_DISABLE_SPAM_WARNINGS;
+
+TEST_CASE("at_path")
+{
+ // clang-format off
+
+ const auto tbl = table
+ {
+ { ""sv, 0 }, // blank key
+ { "a"sv, 1 },
+ {
+ "b"sv,
+ array
+ {
+ 2,
+ array{ 3 },
+ table { { "c", 4 } }
+ },
+ },
+ { "d", table{ {"e", 5, }, {""sv, -1 } } }
+ };
+
+ // clang-format on
+
+ /*
+
+ # equivalent to the following TOML:
+
+ "" = 0
+ a = 1
+ b = [
+ 2,
+ [ 3 ],
+ { "c" = 4 }
+ ]
+ d = { "e" = 5, "" = -1 }
+
+ */
+
+ SECTION("table")
+ {
+ // this section uses the free function version of at_path
+
+ CHECK(tbl[""]);
+ CHECK(tbl[""] == at_path(tbl, ""));
+
+ CHECK(tbl["a"]);
+ CHECK(tbl["a"] == at_path(tbl, "a"));
+ CHECK(tbl["a"] != at_path(tbl, ".a")); // equivalent to ""."a"
+ CHECK(!at_path(tbl, ".a"));
+
+ CHECK(tbl["b"]);
+ CHECK(tbl["b"] == at_path(tbl, "b"));
+
+ CHECK(tbl["b"][0]);
+ CHECK(tbl["b"][0] == at_path(tbl, "b[0]"));
+ CHECK(tbl["b"][0] == at_path(tbl, "b[0] "));
+ CHECK(tbl["b"][0] == at_path(tbl, "b[ 0\t]")); // whitespace is allowed inside indexer
+
+ CHECK(tbl["b"][1]);
+ CHECK(tbl["b"][1] != tbl["b"][0]);
+ CHECK(tbl["b"][1] == at_path(tbl, "b[1]"));
+
+ CHECK(tbl["b"][1][0]);
+ CHECK(tbl["b"][1][0] == at_path(tbl, "b[1][0]"));
+ CHECK(tbl["b"][1][0] == at_path(tbl, "b[1] \t [0]")); // whitespace is allowed after indexers
+
+ CHECK(tbl["b"][2]["c"]);
+ CHECK(tbl["b"][2]["c"] == at_path(tbl, "b[2].c"));
+ CHECK(tbl["b"][2]["c"] == at_path(tbl, "b[2] \t.c")); // whitespace is allowed after indexers
+
+ // permissivity checks for missing trailing ']'
+ // (this permissivity is undocumented but serves to reduce error paths in user code)
+ CHECK(tbl["b"][1][0] == at_path(tbl, "b[1[0]"));
+ CHECK(tbl["b"][1][0] == at_path(tbl, "b[1[0"));
+ CHECK(tbl["b"][2]["c"] == at_path(tbl, "b[2.c"));
+
+ CHECK(tbl["d"]);
+ CHECK(tbl["d"] == at_path(tbl, "d"));
+
+ CHECK(tbl["d"]["e"]);
+ CHECK(tbl["d"]["e"] == at_path(tbl, "d.e"));
+ CHECK(tbl["d"]["e"] != at_path(tbl, "d. e")); // equivalent to "d"." e"
+ CHECK(!at_path(tbl, "d. e"));
+
+ CHECK(tbl["d"][""]);
+ CHECK(tbl["d"][""] == at_path(tbl, "d."));
+ }
+
+ SECTION("array")
+ {
+ // this section uses the node_view member function version of at_path
+
+ auto arr = tbl["b"];
+
+ CHECK(tbl["b"][0]);
+ CHECK(tbl["b"][0] == arr.at_path("[0]"));
+ CHECK(tbl["b"][0] == arr.at_path("[0] "));
+ CHECK(tbl["b"][0] == arr.at_path("[ 0\t]")); // whitespace is allowed inside indexer
+
+ CHECK(tbl["b"][1]);
+ CHECK(tbl["b"][1].node() != arr[0].node());
+ CHECK(tbl["b"][1] == arr.at_path("[1]"));
+
+ CHECK(tbl["b"][1][0]);
+ CHECK(tbl["b"][1][0] == arr.at_path("[1][0]"));
+ CHECK(tbl["b"][1][0] == arr.at_path("[1] \t [0]")); // whitespace is allowed after indexers
+
+ CHECK(tbl["b"][2]["c"]);
+ CHECK(tbl["b"][2]["c"] == arr.at_path("[2].c"));
+ CHECK(tbl["b"][2]["c"] == arr.at_path("[2] \t.c")); // whitespace is allowed after indexers
+ }
+}
diff --git a/tomlplusplus/tests/conformance_burntsushi_invalid.cpp b/tomlplusplus/tests/conformance_burntsushi_invalid.cpp
new file mode 100644
index 0000000000..974a873dff
--- /dev/null
+++ b/tomlplusplus/tests/conformance_burntsushi_invalid.cpp
@@ -0,0 +1,2022 @@
+// This file is a part of toml++ and is subject to the the terms of the MIT license.
+// Copyright (c) Mark Gillard <mark.gillard@outlook.com.au>
+// See https://github.com/marzer/tomlplusplus/blob/master/LICENSE for the full license text.
+// SPDX-License-Identifier: MIT
+//-----
+// this file was generated by generate_conformance_tests.py - do not modify it directly
+
+#include "tests.hpp"
+
+namespace
+{
+ static constexpr auto array_double_comma_1 = R"(array = [1,,2])"sv;
+ static constexpr auto array_double_comma_2 = R"(array = [1,2,,])"sv;
+ static constexpr auto array_extending_table = R"(a = [{ b = 1 }]
+
+# Cannot extend tables within static arrays
+# https://github.com/toml-lang/toml/issues/908
+[a.c]
+foo = 1)"sv;
+ static constexpr auto array_missing_separator = R"(wrong = [ 1 2 3 ])"sv;
+ static constexpr auto array_no_close_2 = R"(x = [42 #)"sv;
+ static constexpr auto array_no_close_table_2 = R"(x = [{ key = 42 #)"sv;
+ static constexpr auto array_no_close_table = R"(x = [{ key = 42)"sv;
+ static constexpr auto array_no_close = R"(long_array = [ 1, 2, 3)"sv;
+ static constexpr auto array_tables_1 = R"(# INVALID TOML DOC
+fruit = []
+
+[[fruit]] # Not allowed)"sv;
+ static constexpr auto array_tables_2 = R"(# INVALID TOML DOC
+[[fruit]]
+ name = "apple"
+
+ [[fruit.variety]]
+ name = "red delicious"
+
+ # This table conflicts with the previous table
+ [fruit.variety]
+ name = "granny smith")"sv;
+ static constexpr auto array_text_after_array_entries = R"(array = [
+ "Is there life after an array separator?", No
+ "Entry"
+])"sv;
+ static constexpr auto array_text_before_array_separator = R"(array = [
+ "Is there life before an array separator?" No,
+ "Entry"
+])"sv;
+ static constexpr auto array_text_in_array = R"(array = [
+ "Entry 1",
+ I don't belong,
+ "Entry 2",
+])"sv;
+
+ static constexpr auto bool_almost_false_with_extra = R"(a = falsify)"sv;
+ static constexpr auto bool_almost_false = R"(a = fals)"sv;
+ static constexpr auto bool_almost_true_with_extra = R"(a = truthy)"sv;
+ static constexpr auto bool_almost_true = R"(a = tru)"sv;
+ static constexpr auto bool_just_f = R"(a = f)"sv;
+ static constexpr auto bool_just_t = R"(a = t)"sv;
+ static constexpr auto bool_mixed_case = R"(valid = False)"sv;
+ static constexpr auto bool_starting_same_false = R"(a = falsey)"sv;
+ static constexpr auto bool_starting_same_true = R"(a = truer)"sv;
+ static constexpr auto bool_wrong_case_false = R"(b = FALSE)"sv;
+ static constexpr auto bool_wrong_case_true = R"(a = TRUE)"sv;
+
+ static constexpr auto control_bare_cr =
+ "# The following line contains a single carriage return control character\r\n"
+ "\r"sv;
+ static constexpr auto control_bare_formfeed = "bare-formfeed = \f"sv;
+ static constexpr auto control_bare_null = "bare-null = \"some value\" \x00"sv;
+ static constexpr auto control_bare_vertical_tab = "bare-vertical-tab = \v"sv;
+ static constexpr auto control_comment_cr = "comment-cr = \"Carriage return in comment\" # \ra=1"sv;
+ static constexpr auto control_comment_del = "comment-del = \"0x7f\" # \x7F"sv;
+ static constexpr auto control_comment_lf = "comment-lf = \"ctrl-P\" # \x10"sv;
+ static constexpr auto control_comment_null = "comment-null = \"null\" # \x00"sv;
+ static constexpr auto control_comment_us = "comment-us = \"ctrl-_\" # \x1F"sv;
+ static constexpr auto control_multi_del = "multi-del = \"\"\"null\x7F\"\"\""sv;
+ static constexpr auto control_multi_lf = "multi-lf = \"\"\"null\x10\"\"\""sv;
+ static constexpr auto control_multi_null = "multi-null = \"\"\"null\x00\"\"\""sv;
+ static constexpr auto control_multi_us = "multi-us = \"\"\"null\x1F\"\"\""sv;
+ static constexpr auto control_rawmulti_del = "rawmulti-del = '''null\x7F'''"sv;
+ static constexpr auto control_rawmulti_lf = "rawmulti-lf = '''null\x10'''"sv;
+ static constexpr auto control_rawmulti_null = "rawmulti-null = '''null\x00'''"sv;
+ static constexpr auto control_rawmulti_us = "rawmulti-us = '''null\x1F'''"sv;
+ static constexpr auto control_rawstring_del = "rawstring-del = 'null\x7F'"sv;
+ static constexpr auto control_rawstring_lf = "rawstring-lf = 'null\x10'"sv;
+ static constexpr auto control_rawstring_null = "rawstring-null = 'null\x00'"sv;
+ static constexpr auto control_rawstring_us = "rawstring-us = 'null\x1F'"sv;
+ static constexpr auto control_string_bs = "string-bs = \"backspace\x08\""sv;
+ static constexpr auto control_string_del = "string-del = \"null\x7F\""sv;
+ static constexpr auto control_string_lf = "string-lf = \"null\x10\""sv;
+ static constexpr auto control_string_null = "string-null = \"null\x00\""sv;
+ static constexpr auto control_string_us = "string-us = \"null\x1F\""sv;
+
+ static constexpr auto datetime_hour_over = R"(# time-hour = 2DIGIT ; 00-23
+d = 2006-01-01T24:00:00-00:00)"sv;
+ static constexpr auto datetime_mday_over = R"(# date-mday = 2DIGIT ; 01-28, 01-29, 01-30, 01-31 based on
+# ; month/year
+d = 2006-01-32T00:00:00-00:00)"sv;
+ static constexpr auto datetime_mday_under = R"(# date-mday = 2DIGIT ; 01-28, 01-29, 01-30, 01-31 based on
+# ; month/year
+d = 2006-01-00T00:00:00-00:00)"sv;
+ static constexpr auto datetime_minute_over = R"(# time-minute = 2DIGIT ; 00-59
+d = 2006-01-01T00:60:00-00:00)"sv;
+ static constexpr auto datetime_month_over = R"(# date-month = 2DIGIT ; 01-12
+d = 2006-13-01T00:00:00-00:00)"sv;
+ static constexpr auto datetime_month_under = R"(# date-month = 2DIGIT ; 01-12
+d = 2007-00-01T00:00:00-00:00)"sv;
+ static constexpr auto datetime_no_leads_month = R"(# Month "7" instead of "07"; the leading zero is required.
+no-leads = 1987-7-05T17:45:00Z)"sv;
+ static constexpr auto datetime_no_leads_with_milli = R"(# Day "5" instead of "05"; the leading zero is required.
+with-milli = 1987-07-5T17:45:00.12Z)"sv;
+ static constexpr auto datetime_no_leads = R"(# Month "7" instead of "07"; the leading zero is required.
+no-leads = 1987-7-05T17:45:00Z)"sv;
+ static constexpr auto datetime_no_t = R"(# No "t" or "T" between the date and time.
+no-t = 1987-07-0517:45:00Z)"sv;
+ static constexpr auto datetime_second_over =
+ R"(# time-second = 2DIGIT ; 00-58, 00-59, 00-60 based on leap second
+# ; rules
+d = 2006-01-01T00:00:61-00:00)"sv;
+ static constexpr auto datetime_time_no_leads = R"(# Leading 0 is always required.
+d = 2023-10-01T1:32:00Z)"sv;
+
+#if !TOML_LANG_UNRELEASED
+
+ static constexpr auto datetime_no_secs = R"(# No seconds in time.
+no-secs = 1987-07-05T17:45Z)"sv;
+
+#endif // !TOML_LANG_UNRELEASED
+
+ static constexpr auto encoding_bad_codepoint =
+ "\x23\x20\x49\x6E\x76\x61\x6C\x69\x64\x20\x63\x6F\x64\x65\x70\x6F\x69\x6E\x74\x20\x55\x2B\x44\x38\x30"
+ "\x30\x20\x3A\x20\xED\xA0\x80\x0A"sv;
+ static constexpr auto encoding_bad_utf8_at_end =
+ "\x23\x20\x54\x68\x65\x72\x65\x20\x69\x73\x20\x61\x20\x30\x78\x64\x61\x20\x61\x74\x20\x61\x66\x74\x65"
+ "\x72\x20\x74\x68\x65\x20\x71\x75\x6F\x74\x65\x73\x2C\x20\x61\x6E\x64\x20\x6E\x6F\x20\x45\x4F\x4C\x20"
+ "\x61\x74\x20\x74\x68\x65\x20\x65\x6E\x64\x20\x6F\x66\x20\x74\x68\x65\x20\x66\x69\x6C\x65\x2E\x0A\x23"
+ "\x0A\x23\x20\x54\x68\x69\x73\x20\x69\x73\x20\x61\x20\x62\x69\x74\x20\x6F\x66\x20\x61\x6E\x20\x65\x64"
+ "\x67\x65\x20\x63\x61\x73\x65\x3A\x20\x54\x68\x69\x73\x20\x69\x6E\x64\x69\x63\x61\x74\x65\x73\x20\x74"
+ "\x68\x65\x72\x65\x20\x73\x68\x6F\x75\x6C\x64\x20\x62\x65\x20\x74\x77\x6F\x20\x62\x79\x74\x65\x73\x0A"
+ "\x23\x20\x28\x30\x62\x31\x31\x30\x31\x5F\x31\x30\x31\x30\x29\x20\x62\x75\x74\x20\x74\x68\x65\x72\x65"
+ "\x20\x69\x73\x20\x6E\x6F\x20\x62\x79\x74\x65\x20\x74\x6F\x20\x66\x6F\x6C\x6C\x6F\x77\x20\x62\x65\x63"
+ "\x61\x75\x73\x65\x20\x69\x74\x27\x73\x20\x74\x68\x65\x20\x65\x6E\x64\x20\x6F\x66\x20\x74\x68\x65\x20"
+ "\x66\x69\x6C\x65\x2E\x0A\x78\x20\x3D\x20\x22\x22\x22\x22\x22\x22\xDA"sv;
+ static constexpr auto encoding_bad_utf8_in_comment = "\x23\x20\xC3\x0A"sv;
+ static constexpr auto encoding_bad_utf8_in_multiline_literal =
+ "\x23\x20\x54\x68\x65\x20\x66\x6F\x6C\x6C\x6F\x77\x69\x6E\x67\x20\x6C\x69\x6E\x65\x20\x63\x6F\x6E\x74"
+ "\x61\x69\x6E\x73\x20\x61\x6E\x20\x69\x6E\x76\x61\x6C\x69\x64\x20\x55\x54\x46\x2D\x38\x20\x73\x65\x71"
+ "\x75\x65\x6E\x63\x65\x2E\x0A\x62\x61\x64\x20\x3D\x20\x27\x27\x27\xC3\x27\x27\x27\x0A"sv;
+ static constexpr auto encoding_bad_utf8_in_multiline =
+ "\x23\x20\x54\x68\x65\x20\x66\x6F\x6C\x6C\x6F\x77\x69\x6E\x67\x20\x6C\x69\x6E\x65\x20\x63\x6F\x6E\x74"
+ "\x61\x69\x6E\x73\x20\x61\x6E\x20\x69\x6E\x76\x61\x6C\x69\x64\x20\x55\x54\x46\x2D\x38\x20\x73\x65\x71"
+ "\x75\x65\x6E\x63\x65\x2E\x0A\x62\x61\x64\x20\x3D\x20\x22\x22\x22\xC3\x22\x22\x22\x0A"sv;
+ static constexpr auto encoding_bad_utf8_in_string_literal =
+ "\x23\x20\x54\x68\x65\x20\x66\x6F\x6C\x6C\x6F\x77\x69\x6E\x67\x20\x6C\x69\x6E\x65\x20\x63\x6F\x6E\x74"
+ "\x61\x69\x6E\x73\x20\x61\x6E\x20\x69\x6E\x76\x61\x6C\x69\x64\x20\x55\x54\x46\x2D\x38\x20\x73\x65\x71"
+ "\x75\x65\x6E\x63\x65\x2E\x0A\x62\x61\x64\x20\x3D\x20\x27\xC3\x27\x0A"sv;
+ static constexpr auto encoding_bad_utf8_in_string =
+ "\x23\x20\x54\x68\x65\x20\x66\x6F\x6C\x6C\x6F\x77\x69\x6E\x67\x20\x6C\x69\x6E\x65\x20\x63\x6F\x6E\x74"
+ "\x61\x69\x6E\x73\x20\x61\x6E\x20\x69\x6E\x76\x61\x6C\x69\x64\x20\x55\x54\x46\x2D\x38\x20\x73\x65\x71"
+ "\x75\x65\x6E\x63\x65\x2E\x0A\x62\x61\x64\x20\x3D\x20\x22\xC3\x22\x0A"sv;
+ static constexpr auto encoding_bom_not_at_start_1 =
+ "\x62\x6F\x6D\x2D\x6E\x6F\x74\x2D\x61\x74\x2D\x73\x74\x61\x72\x74\x20\xFF\xFD\x0A"sv;
+ static constexpr auto encoding_bom_not_at_start_2 =
+ "\x62\x6F\x6D\x2D\x6E\x6F\x74\x2D\x61\x74\x2D\x73\x74\x61\x72\x74\x3D\x20\xFF\xFD\x0A"sv;
+ static constexpr auto encoding_utf16_bom =
+ "\xFE\xFF\x00\x23\x00\x20\x00\x55\x00\x54\x00\x46\x00\x2D\x00\x31\x00\x36\x00\x20\x00\x77\x00\x69\x00"
+ "\x74\x00\x68\x00\x20\x00\x42\x00\x4F\x00\x4D\x00\x0A"sv;
+ static constexpr auto encoding_utf16 =
+ "\x00#\x00 \x00U\x00T\x00F\x00-\x001\x006\x00 \x00w\x00i\x00t\x00h\x00o\x00u\x00t\x00 \x00B\x00O\x00M\x00"sv;
+
+ static constexpr auto float_double_point_1 = R"(double-point-1 = 0..1)"sv;
+ static constexpr auto float_double_point_2 = R"(double-point-2 = 0.1.2)"sv;
+ static constexpr auto float_exp_double_e_1 = R"(exp-double-e-1 = 1ee2)"sv;
+ static constexpr auto float_exp_double_e_2 = R"(exp-double-e-2 = 1e2e3)"sv;
+ static constexpr auto float_exp_double_us = R"(exp-double-us = 1e__23)"sv;
+ static constexpr auto float_exp_leading_us = R"(exp-leading-us = 1e_23)"sv;
+ static constexpr auto float_exp_point_1 = R"(exp-point-1 = 1e2.3)"sv;
+ static constexpr auto float_exp_point_2 = R"(exp-point-2 = 1.e2)"sv;
+ static constexpr auto float_exp_trailing_us = R"(exp-trailing-us = 1e23_)"sv;
+ static constexpr auto float_inf_capital = R"(v = Inf)"sv;
+ static constexpr auto float_inf_incomplete_1 = R"(inf-incomplete-1 = in)"sv;
+ static constexpr auto float_inf_incomplete_2 = R"(inf-incomplete-2 = +in)"sv;
+ static constexpr auto float_inf_incomplete_3 = R"(inf-incomplete-3 = -in)"sv;
+ static constexpr auto float_inf_underscore = R"(inf_underscore = in_f)"sv;
+ static constexpr auto float_leading_point_neg = R"(leading-point-neg = -.12345)"sv;
+ static constexpr auto float_leading_point_plus = R"(leading-point-plus = +.12345)"sv;
+ static constexpr auto float_leading_point = R"(leading-point = .12345)"sv;
+ static constexpr auto float_leading_us = R"(leading-us = _1.2)"sv;
+ static constexpr auto float_leading_zero_neg = R"(leading-zero-neg = -03.14)"sv;
+ static constexpr auto float_leading_zero_plus = R"(leading-zero-plus = +03.14)"sv;
+ static constexpr auto float_leading_zero = R"(leading-zero = 03.14)"sv;
+ static constexpr auto float_nan_capital = R"(v = NaN)"sv;
+ static constexpr auto float_nan_incomplete_1 = R"(nan-incomplete-1 = na)"sv;
+ static constexpr auto float_nan_incomplete_2 = R"(nan-incomplete-2 = +na)"sv;
+ static constexpr auto float_nan_incomplete_3 = R"(nan-incomplete-3 = -na)"sv;
+ static constexpr auto float_nan_underscore = R"(nan_underscore = na_n)"sv;
+ static constexpr auto float_trailing_point_min = R"(trailing-point-min = -1.)"sv;
+ static constexpr auto float_trailing_point_plus = R"(trailing-point-plus = +1.)"sv;
+ static constexpr auto float_trailing_point = R"(trailing-point = 1.)"sv;
+ static constexpr auto float_trailing_us_exp_1 = R"(trailing-us-exp-1 = 1_e2)"sv;
+ static constexpr auto float_trailing_us_exp_2 = R"(trailing-us-exp-2 = 1.2_e2)"sv;
+ static constexpr auto float_trailing_us = R"(trailing-us = 1.2_)"sv;
+ static constexpr auto float_us_after_point = R"(us-after-point = 1._2)"sv;
+ static constexpr auto float_us_before_point = R"(us-before-point = 1_.2)"sv;
+
+ static constexpr auto inline_table_add = R"(a={}
+# Inline tables are immutable and can't be extended
+[a.b])"sv;
+ static constexpr auto inline_table_bad_key_syntax = R"(tbl = { a = 1, [b] })"sv;
+ static constexpr auto inline_table_dotted_key_conflict = R"(tbl = { a.b = "a_b", a.b.c = "a_b_c" })"sv;
+ static constexpr auto inline_table_double_comma = R"(t = {x=3,,y=4})"sv;
+ static constexpr auto inline_table_duplicate_key = R"(# Duplicate keys within an inline table are invalid
+a={b=1, b=2})"sv;
+ static constexpr auto inline_table_empty = R"(t = {,})"sv;
+ static constexpr auto inline_table_nested_key_conflict =
+ R"(tbl = { fruit = { apple.color = "red" }, fruit.apple.texture = { smooth = true } })"sv;
+ static constexpr auto inline_table_no_comma = R"(t = {x = 3 y = 4})"sv;
+ static constexpr auto inline_table_overwrite = R"(a.b=0
+# Since table "a" is already defined, it can't be replaced by an inline table.
+a={})"sv;
+
+#if !TOML_LANG_UNRELEASED
+
+ static constexpr auto inline_table_linebreak_1 =
+ R"(# No newlines are allowed between the curly braces unless they are valid within
+# a value.
+simple = { a = 1
+})"sv;
+ static constexpr auto inline_table_linebreak_2 = R"(t = {a=1,
+b=2})"sv;
+ static constexpr auto inline_table_linebreak_3 = R"(t = {a=1
+,b=2})"sv;
+ static constexpr auto inline_table_linebreak_4 = R"(json_like = {
+ first = "Tom",
+ last = "Preston-Werner"
+})"sv;
+ static constexpr auto inline_table_trailing_comma =
+ R"(# A terminating comma (also called trailing comma) is not permitted after the
+# last key/value pair in an inline table
+abc = { abc = 123, })"sv;
+
+#endif // !TOML_LANG_UNRELEASED
+
+ static constexpr auto integer_capital_bin = R"(capital-bin = 0B0)"sv;
+ static constexpr auto integer_capital_hex = R"(capital-hex = 0X1)"sv;
+ static constexpr auto integer_capital_oct = R"(capital-oct = 0O0)"sv;
+ static constexpr auto integer_double_sign_nex = R"(double-sign-nex = --99)"sv;
+ static constexpr auto integer_double_sign_plus = R"(double-sign-plus = ++99)"sv;
+ static constexpr auto integer_double_us = R"(double-us = 1__23)"sv;
+ static constexpr auto integer_incomplete_bin = R"(incomplete-bin = 0b)"sv;
+ static constexpr auto integer_incomplete_hex = R"(incomplete-hex = 0x)"sv;
+ static constexpr auto integer_incomplete_oct = R"(incomplete-oct = 0o)"sv;
+ static constexpr auto integer_invalid_bin = R"(invalid-bin = 0b0012)"sv;
+ static constexpr auto integer_invalid_hex = R"(invalid-hex = 0xaafz)"sv;
+ static constexpr auto integer_invalid_oct = R"(invalid-oct = 0o778)"sv;
+ static constexpr auto integer_leading_us_bin = R"(leading-us-bin = _0o1)"sv;
+ static constexpr auto integer_leading_us_hex = R"(leading-us-hex = _0o1)"sv;
+ static constexpr auto integer_leading_us_oct = R"(leading-us-oct = _0o1)"sv;
+ static constexpr auto integer_leading_us = R"(leading-us = _123)"sv;
+ static constexpr auto integer_leading_zero_1 = R"(leading-zero-1 = 01)"sv;
+ static constexpr auto integer_leading_zero_2 = R"(leading-zero-2 = 00)"sv;
+ static constexpr auto integer_leading_zero_3 = R"(leading-zero-3 = 0_0)"sv;
+ static constexpr auto integer_leading_zero_sign_1 = R"(leading-zero-sign-1 = -01)"sv;
+ static constexpr auto integer_leading_zero_sign_2 = R"(leading-zero-sign-2 = +01)"sv;
+ static constexpr auto integer_leading_zero_sign_3 = R"(leading-zero-sign-3 = +0_1)"sv;
+ static constexpr auto integer_negative_bin = R"(negative-bin = -0b11010110)"sv;
+ static constexpr auto integer_negative_hex = R"(negative-hex = -0xff)"sv;
+ static constexpr auto integer_negative_oct = R"(negative-oct = -0o99)"sv;
+ static constexpr auto integer_positive_bin = R"(positive-bin = +0b11010110)"sv;
+ static constexpr auto integer_positive_hex = R"(positive-hex = +0xff)"sv;
+ static constexpr auto integer_positive_oct = R"(positive-oct = +0o99)"sv;
+ static constexpr auto integer_text_after_integer = R"(answer = 42 the ultimate answer?)"sv;
+ static constexpr auto integer_trailing_us_bin = R"(trailing-us-bin = 0b1_)"sv;
+ static constexpr auto integer_trailing_us_hex = R"(trailing-us-hex = 0x1_)"sv;
+ static constexpr auto integer_trailing_us_oct = R"(trailing-us-oct = 0o1_)"sv;
+ static constexpr auto integer_trailing_us = R"(trailing-us = 123_)"sv;
+ static constexpr auto integer_us_after_bin = R"(us-after-bin = 0b_1)"sv;
+ static constexpr auto integer_us_after_hex = R"(us-after-hex = 0x_1)"sv;
+ static constexpr auto integer_us_after_oct = R"(us-after-oct = 0o_1)"sv;
+
+ static constexpr auto key_after_array = R"([[agencies]] owner = "S Cjelli")"sv;
+ static constexpr auto key_after_table = R"([error] this = "should not be here")"sv;
+ static constexpr auto key_after_value = R"(first = "Tom" last = "Preston-Werner" # INVALID)"sv;
+ static constexpr auto key_bare_invalid_character = R"(bare!key = 123)"sv;
+ static constexpr auto key_dotted_redefine_table = R"(# Defined a.b as int
+a.b = 1
+# Tries to access it as table: error
+a.b.c = 2)"sv;
+ static constexpr auto key_duplicate_keys = R"(dupe = false
+dupe = true)"sv;
+ static constexpr auto key_duplicate = R"(# DO NOT DO THIS
+name = "Tom"
+name = "Pradyun")"sv;
+ static constexpr auto key_empty = R"( = 1)"sv;
+ static constexpr auto key_escape = R"(\u00c0 = "latin capital letter A with grave")"sv;
+ static constexpr auto key_hash = R"(a# = 1)"sv;
+ static constexpr auto key_multiline = R"("""long
+key""" = 1)"sv;
+ static constexpr auto key_newline = R"(barekey
+ = 123)"sv;
+ static constexpr auto key_no_eol = R"(a = 1 b = 2)"sv;
+ static constexpr auto key_open_bracket = R"([abc = 1)"sv;
+ static constexpr auto key_partial_quoted = R"(partial"quoted" = 5)"sv;
+ static constexpr auto key_quoted_unclosed_1 = R"("key = x)"sv;
+ static constexpr auto key_quoted_unclosed_2 = R"("key)"sv;
+ static constexpr auto key_single_open_bracket = R"([)"sv;
+ static constexpr auto key_space = R"(a b = 1)"sv;
+ static constexpr auto key_start_bracket = R"([a]
+[xyz = 5
+[b])"sv;
+ static constexpr auto key_start_dot = R"(.key = 1)"sv;
+ static constexpr auto key_two_equals = R"(key= = 1)"sv;
+ static constexpr auto key_two_equals2 = R"(a==1)"sv;
+ static constexpr auto key_two_equals3 = R"(a=b=1)"sv;
+ static constexpr auto key_without_value_1 = R"(key)"sv;
+ static constexpr auto key_without_value_2 = R"(key = )"sv;
+ static constexpr auto key_without_value_3 = R"("key")"sv;
+ static constexpr auto key_without_value_4 = R"("key" = )"sv;
+
+#if !TOML_LANG_UNRELEASED && UNICODE_LITERALS_OK
+
+ static constexpr auto key_special_character = R"(μ = "greek small letter mu")"sv;
+
+#endif // !TOML_LANG_UNRELEASED && UNICODE_LITERALS_OK
+
+ static constexpr auto local_date_mday_over = R"(# date-mday = 2DIGIT ; 01-28, 01-29, 01-30, 01-31 based on
+# ; month/year
+d = 2006-01-32)"sv;
+ static constexpr auto local_date_mday_under = R"(# date-mday = 2DIGIT ; 01-28, 01-29, 01-30, 01-31 based on
+# ; month/year
+d = 2006-01-00)"sv;
+ static constexpr auto local_date_month_over = R"(# date-month = 2DIGIT ; 01-12
+d = 2006-13-01)"sv;
+ static constexpr auto local_date_month_under = R"(# date-month = 2DIGIT ; 01-12
+d = 2007-00-01)"sv;
+ static constexpr auto local_date_no_leads_with_milli = R"(# Day "5" instead of "05"; the leading zero is required.
+with-milli = 1987-07-5)"sv;
+ static constexpr auto local_date_no_leads = R"(# Month "7" instead of "07"; the leading zero is required.
+no-leads = 1987-7-05)"sv;
+ static constexpr auto local_date_trailing_t = R"(# Date cannot end with trailing T
+d = 2006-01-30T)"sv;
+ static constexpr auto local_datetime_hour_over = R"(# time-hour = 2DIGIT ; 00-23
+d = 2006-01-01T24:00:00)"sv;
+ static constexpr auto local_datetime_mday_over =
+ R"(# date-mday = 2DIGIT ; 01-28, 01-29, 01-30, 01-31 based on
+# ; month/year
+d = 2006-01-32T00:00:00)"sv;
+ static constexpr auto local_datetime_mday_under =
+ R"(# date-mday = 2DIGIT ; 01-28, 01-29, 01-30, 01-31 based on
+# ; month/year
+d = 2006-01-00T00:00:00)"sv;
+ static constexpr auto local_datetime_minute_over = R"(# time-minute = 2DIGIT ; 00-59
+d = 2006-01-01T00:60:00)"sv;
+ static constexpr auto local_datetime_month_over = R"(# date-month = 2DIGIT ; 01-12
+d = 2006-13-01T00:00:00)"sv;
+ static constexpr auto local_datetime_month_under = R"(# date-month = 2DIGIT ; 01-12
+d = 2007-00-01T00:00:00)"sv;
+ static constexpr auto local_datetime_no_leads_with_milli =
+ R"(# Day "5" instead of "05"; the leading zero is required.
+with-milli = 1987-07-5T17:45:00.12)"sv;
+ static constexpr auto local_datetime_no_leads = R"(# Month "7" instead of "07"; the leading zero is required.
+no-leads = 1987-7-05T17:45:00)"sv;
+ static constexpr auto local_datetime_no_secs = R"(# No seconds in time.
+no-secs = 1987-07-05T17:45)"sv;
+ static constexpr auto local_datetime_no_t = R"(# No "t" or "T" between the date and time.
+no-t = 1987-07-0517:45:00)"sv;
+ static constexpr auto local_datetime_second_over =
+ R"(# time-second = 2DIGIT ; 00-58, 00-59, 00-60 based on leap second
+# ; rules
+d = 2006-01-01T00:00:61)"sv;
+ static constexpr auto local_datetime_time_no_leads = R"(# Leading 0 is always required.
+d = 2023-10-01T1:32:00Z)"sv;
+ static constexpr auto local_time_hour_over = R"(# time-hour = 2DIGIT ; 00-23
+d = 24:00:00)"sv;
+ static constexpr auto local_time_minute_over = R"(# time-minute = 2DIGIT ; 00-59
+d = 00:60:00)"sv;
+ static constexpr auto local_time_no_secs = R"(# No seconds in time.
+no-secs = 17:45)"sv;
+ static constexpr auto local_time_second_over =
+ R"(# time-second = 2DIGIT ; 00-58, 00-59, 00-60 based on leap second
+# ; rules
+d = 00:00:61)"sv;
+ static constexpr auto local_time_time_no_leads_2 = R"(# Leading 0 is always required.
+d = 01:32:0)"sv;
+ static constexpr auto local_time_time_no_leads = R"(# Leading 0 is always required.
+d = 1:32:00)"sv;
+
+ static constexpr auto spec_inline_table_2_0 = R"([product]
+type = { name = "Nail" }
+type.edible = false # INVALID)"sv;
+ static constexpr auto spec_inline_table_3_0 = R"([product]
+type.name = "Nail"
+type = { edible = false } # INVALID)"sv;
+ static constexpr auto spec_key_value_pair_1 = R"(key = # INVALID)"sv;
+ static constexpr auto spec_keys_2 = R"(= "no key name" # INVALID
+"" = "blank" # VALID but discouraged
+'' = 'blank' # VALID but discouraged)"sv;
+ static constexpr auto spec_string_4_0 = R"(str4 = """Here are two quotation marks: "". Simple enough."""
+str5 = """Here are three quotation marks: """.""" # INVALID
+str5 = """Here are three quotation marks: ""\"."""
+str6 = """Here are fifteen quotation marks: ""\"""\"""\"""\"""\"."""
+
+# "This," she said, "is just a pointless statement."
+str7 = """"This," she said, "is just a pointless statement."""")"sv;
+ static constexpr auto spec_string_7_0 = R"(quot15 = '''Here are fifteen quotation marks: """""""""""""""'''
+
+apos15 = '''Here are fifteen apostrophes: '''''''''''''''''' # INVALID
+apos15 = "Here are fifteen apostrophes: '''''''''''''''"
+
+# 'That,' she said, 'is still pointless.'
+str = ''''That,' she said, 'is still pointless.'''')"sv;
+ static constexpr auto spec_table_9_0 = R"([fruit]
+apple.color = "red"
+apple.taste.sweet = true
+
+[fruit.apple] # INVALID
+# [fruit.apple.taste] # INVALID
+
+[fruit.apple.texture] # you can add sub-tables
+smooth = true)"sv;
+ static constexpr auto spec_table_9_1 = R"([fruit]
+apple.color = "red"
+apple.taste.sweet = true
+
+# [fruit.apple] # INVALID
+[fruit.apple.taste] # INVALID
+
+[fruit.apple.texture] # you can add sub-tables
+smooth = true)"sv;
+
+ static constexpr auto string_bad_byte_escape = R"(naughty = "\xAg")"sv;
+ static constexpr auto string_bad_codepoint =
+ R"(invalid-codepoint = "This string contains a non scalar unicode codepoint \uD801")"sv;
+ static constexpr auto string_bad_concat = R"(no_concat = "first" "second")"sv;
+ static constexpr auto string_bad_escape_1 = R"(invalid-escape = "This string has a bad \a escape character.")"sv;
+ static constexpr auto string_bad_escape_2 = R"(invalid-escape = "This string has a bad \ escape character.")"sv;
+ static constexpr auto string_bad_hex_esc_1 = R"(bad-hex-esc-1 = "\x0g")"sv;
+ static constexpr auto string_bad_hex_esc_2 = R"(bad-hex-esc-2 = "\xG0")"sv;
+ static constexpr auto string_bad_hex_esc_3 = R"(bad-hex-esc-3 = "\x")"sv;
+ static constexpr auto string_bad_hex_esc_4 = R"(bad-hex-esc-4 = "\x 50")"sv;
+ static constexpr auto string_bad_hex_esc_5 = R"(bad-hex-esc-5 = "\x 50")"sv;
+ static constexpr auto string_bad_multiline = R"(multi = "first line
+second line")"sv;
+ static constexpr auto string_bad_slash_escape =
+ R"(invalid-escape = "This string has a bad \/ escape character.")"sv;
+ static constexpr auto string_bad_uni_esc_1 = R"(str = "val\ue")"sv;
+ static constexpr auto string_bad_uni_esc_2 = R"(str = "val\Ux")"sv;
+ static constexpr auto string_bad_uni_esc_3 = R"(str = "val\U0000000")"sv;
+ static constexpr auto string_bad_uni_esc_4 = R"(str = "val\U0000")"sv;
+ static constexpr auto string_bad_uni_esc_5 = R"(str = "val\Ugggggggg")"sv;
+ static constexpr auto string_basic_multiline_out_of_range_unicode_escape_1 = R"(a = """\UFFFFFFFF""")"sv;
+ static constexpr auto string_basic_multiline_out_of_range_unicode_escape_2 = R"(a = """\U00D80000""")"sv;
+ static constexpr auto string_basic_multiline_quotes = R"(str5 = """Here are three quotation marks: """.""")"sv;
+ static constexpr auto string_basic_multiline_unknown_escape = R"(a = """\@""")"sv;
+ static constexpr auto string_basic_out_of_range_unicode_escape_1 = R"(a = "\UFFFFFFFF")"sv;
+ static constexpr auto string_basic_out_of_range_unicode_escape_2 = R"(a = "\U00D80000")"sv;
+ static constexpr auto string_basic_unknown_escape = R"(a = "\@")"sv;
+ static constexpr auto string_literal_multiline_quotes_1 = R"(a = '''6 apostrophes: '''''')"sv;
+ static constexpr auto string_literal_multiline_quotes_2 = R"(a = '''15 apostrophes: '''''''''''''''''')"sv;
+ static constexpr auto string_missing_quotes = R"(name = value)"sv;
+ static constexpr auto string_multiline_bad_escape_1 = R"(k = """t\a""")"sv;
+ static constexpr auto string_multiline_bad_escape_2 = R"(# \<Space> is not a valid escape.
+k = """t\ t""")"sv;
+ static constexpr auto string_multiline_bad_escape_3 = R"(# \<Space> is not a valid escape.
+k = """t\ """)"sv;
+ static constexpr auto string_multiline_escape_space = R"(a = """
+ foo \ \n
+ bar""")"sv;
+ static constexpr auto string_multiline_no_close_2 = R"(x=""")"sv;
+ static constexpr auto string_multiline_no_close = R"(invalid = """
+ this will fail)"sv;
+ static constexpr auto string_multiline_quotes_1 = R"(a = """6 quotes: """""")"sv;
+ static constexpr auto string_no_close = R"(no-ending-quote = "One time, at band camp)"sv;
+ static constexpr auto string_text_after_string = R"(string = "Is there life after strings?" No.)"sv;
+ static constexpr auto string_wrong_close = R"(bad-ending-quote = "double and single')"sv;
+
+#if !TOML_LANG_UNRELEASED
+
+ static constexpr auto string_basic_byte_escapes = R"(answer = "\x33")"sv;
+
+#endif // !TOML_LANG_UNRELEASED
+
+ static constexpr auto table_append_to_array_with_dotted_keys = R"([[a.b]]
+
+[a]
+b.y = 2)"sv;
+ static constexpr auto table_append_with_dotted_keys_1 = R"(# First a.b.c defines a table: a.b.c = {z=9}
+#
+# Then we define a.b.c.t = "str" to add a str to the above table, making it:
+#
+# a.b.c = {z=9, t="..."}
+#
+# While this makes sense, logically, it was decided this is not valid TOML as
+# it's too confusing/convoluted.
+#
+# See: https://github.com/toml-lang/toml/issues/846
+# https://github.com/toml-lang/toml/pull/859
+
+[a.b.c]
+ z = 9
+
+[a]
+ b.c.t = "Using dotted keys to add to [a.b.c] after explicitly defining it above is not allowed")"sv;
+ static constexpr auto table_append_with_dotted_keys_2 =
+ R"(# This is the same issue as in injection-1.toml, except that nests one level
+# deeper. See that file for a more complete description.
+
+[a.b.c.d]
+ z = 9
+
+[a]
+ b.c.d.k.t = "Using dotted keys to add to [a.b.c.d] after explicitly defining it above is not allowed")"sv;
+ static constexpr auto table_array_empty = R"([[]]
+name = "Born to Run")"sv;
+ static constexpr auto table_array_implicit =
+ R"(# This test is a bit tricky. It should fail because the first use of
+# `[[albums.songs]]` without first declaring `albums` implies that `albums`
+# must be a table. The alternative would be quite weird. Namely, it wouldn't
+# comply with the TOML spec: "Each double-bracketed sub-table will belong to
+# the most *recently* defined table element *above* it."
+#
+# This is in contrast to the *valid* test, table-array-implicit where
+# `[[albums.songs]]` works by itself, so long as `[[albums]]` isn't declared
+# later. (Although, `[albums]` could be.)
+[[albums.songs]]
+name = "Glory Days"
+
+[[albums]]
+name = "Born in the USA")"sv;
+ static constexpr auto table_array_missing_bracket = R"([[albums]
+name = "Born to Run")"sv;
+ static constexpr auto table_duplicate_key_dotted_array = R"([fruit]
+apple.color = "red"
+
+[[fruit.apple]])"sv;
+ static constexpr auto table_duplicate_key_dotted_table = R"([fruit]
+apple.color = "red"
+
+[fruit.apple] # INVALID)"sv;
+ static constexpr auto table_duplicate_key_dotted_table2 = R"([fruit]
+apple.taste.sweet = true
+
+[fruit.apple.taste] # INVALID)"sv;
+ static constexpr auto table_duplicate_key_table = R"([fruit]
+type = "apple"
+
+[fruit.type]
+apple = "yes")"sv;
+ static constexpr auto table_duplicate_table_array = R"([tbl]
+[[tbl]])"sv;
+ static constexpr auto table_duplicate_table_array2 = R"([[tbl]]
+[tbl])"sv;
+ static constexpr auto table_duplicate = R"([a]
+b = 1
+
+[a]
+c = 2)"sv;
+ static constexpr auto table_empty_implicit_table = R"([naughty..naughty])"sv;
+ static constexpr auto table_empty = R"([])"sv;
+ static constexpr auto table_equals_sign = R"([name=bad])"sv;
+ static constexpr auto table_llbrace = R"([ [table]])"sv;
+ static constexpr auto table_nested_brackets_close = R"([a]b]
+zyx = 42)"sv;
+ static constexpr auto table_nested_brackets_open = R"([a[b]
+zyx = 42)"sv;
+ static constexpr auto table_quoted_no_close = R"(["where will it end]
+name = value)"sv;
+ static constexpr auto table_redefine = R"(# Define b as int, and try to use it as a table: error
+[a]
+b = 1
+
+[a.b]
+c = 2)"sv;
+ static constexpr auto table_rrbrace = R"([[table] ])"sv;
+ static constexpr auto table_text_after_table = R"([error] this shouldn't be here)"sv;
+ static constexpr auto table_whitespace = R"([invalid key])"sv;
+ static constexpr auto table_with_pound = R"([key#group]
+answer = 42)"sv;
+}
+
+TEST_CASE("conformance - burntsushi/invalid")
+{
+ SECTION("array-double-comma-1")
+ {
+ parsing_should_fail(FILE_LINE_ARGS, array_double_comma_1); // array-double-comma-1
+ }
+
+ SECTION("array-double-comma-2")
+ {
+ parsing_should_fail(FILE_LINE_ARGS, array_double_comma_2); // array-double-comma-2
+ }
+
+ SECTION("array-extending-table")
+ {
+ parsing_should_fail(FILE_LINE_ARGS, array_extending_table); // array-extending-table
+ }
+
+ SECTION("array-missing-separator")
+ {
+ parsing_should_fail(FILE_LINE_ARGS, array_missing_separator); // array-missing-separator
+ }
+
+ SECTION("array-no-close-2")
+ {
+ parsing_should_fail(FILE_LINE_ARGS, array_no_close_2); // array-no-close-2
+ }
+
+ SECTION("array-no-close-table-2")
+ {
+ parsing_should_fail(FILE_LINE_ARGS, array_no_close_table_2); // array-no-close-table-2
+ }
+
+ SECTION("array-no-close-table")
+ {
+ parsing_should_fail(FILE_LINE_ARGS, array_no_close_table); // array-no-close-table
+ }
+
+ SECTION("array-no-close")
+ {
+ parsing_should_fail(FILE_LINE_ARGS, array_no_close); // array-no-close
+ }
+
+ SECTION("array-tables-1")
+ {
+ parsing_should_fail(FILE_LINE_ARGS, array_tables_1); // array-tables-1
+ }
+
+ SECTION("array-tables-2")
+ {
+ parsing_should_fail(FILE_LINE_ARGS, array_tables_2); // array-tables-2
+ }
+
+ SECTION("array-text-after-array-entries")
+ {
+ parsing_should_fail(FILE_LINE_ARGS, array_text_after_array_entries); // array-text-after-array-entries
+ }
+
+ SECTION("array-text-before-array-separator")
+ {
+ parsing_should_fail(FILE_LINE_ARGS, array_text_before_array_separator); // array-text-before-array-separator
+ }
+
+ SECTION("array-text-in-array")
+ {
+ parsing_should_fail(FILE_LINE_ARGS, array_text_in_array); // array-text-in-array
+ }
+
+ SECTION("bool-almost-false-with-extra")
+ {
+ parsing_should_fail(FILE_LINE_ARGS, bool_almost_false_with_extra); // bool-almost-false-with-extra
+ }
+
+ SECTION("bool-almost-false")
+ {
+ parsing_should_fail(FILE_LINE_ARGS, bool_almost_false); // bool-almost-false
+ }
+
+ SECTION("bool-almost-true-with-extra")
+ {
+ parsing_should_fail(FILE_LINE_ARGS, bool_almost_true_with_extra); // bool-almost-true-with-extra
+ }
+
+ SECTION("bool-almost-true")
+ {
+ parsing_should_fail(FILE_LINE_ARGS, bool_almost_true); // bool-almost-true
+ }
+
+ SECTION("bool-just-f")
+ {
+ parsing_should_fail(FILE_LINE_ARGS, bool_just_f); // bool-just-f
+ }
+
+ SECTION("bool-just-t")
+ {
+ parsing_should_fail(FILE_LINE_ARGS, bool_just_t); // bool-just-t
+ }
+
+ SECTION("bool-mixed-case")
+ {
+ parsing_should_fail(FILE_LINE_ARGS, bool_mixed_case); // bool-mixed-case
+ }
+
+ SECTION("bool-starting-same-false")
+ {
+ parsing_should_fail(FILE_LINE_ARGS, bool_starting_same_false); // bool-starting-same-false
+ }
+
+ SECTION("bool-starting-same-true")
+ {
+ parsing_should_fail(FILE_LINE_ARGS, bool_starting_same_true); // bool-starting-same-true
+ }
+
+ SECTION("bool-wrong-case-false")
+ {
+ parsing_should_fail(FILE_LINE_ARGS, bool_wrong_case_false); // bool-wrong-case-false
+ }
+
+ SECTION("bool-wrong-case-true")
+ {
+ parsing_should_fail(FILE_LINE_ARGS, bool_wrong_case_true); // bool-wrong-case-true
+ }
+
+ SECTION("control-bare-cr")
+ {
+ parsing_should_fail(FILE_LINE_ARGS, control_bare_cr); // control-bare-cr
+ }
+
+ SECTION("control-bare-formfeed")
+ {
+ parsing_should_fail(FILE_LINE_ARGS, control_bare_formfeed); // control-bare-formfeed
+ }
+
+ SECTION("control-bare-null")
+ {
+ parsing_should_fail(FILE_LINE_ARGS, control_bare_null); // control-bare-null
+ }
+
+ SECTION("control-bare-vertical-tab")
+ {
+ parsing_should_fail(FILE_LINE_ARGS, control_bare_vertical_tab); // control-bare-vertical-tab
+ }
+
+ SECTION("control-comment-cr")
+ {
+ parsing_should_fail(FILE_LINE_ARGS, control_comment_cr); // control-comment-cr
+ }
+
+ SECTION("control-comment-del")
+ {
+ parsing_should_fail(FILE_LINE_ARGS, control_comment_del); // control-comment-del
+ }
+
+ SECTION("control-comment-lf")
+ {
+ parsing_should_fail(FILE_LINE_ARGS, control_comment_lf); // control-comment-lf
+ }
+
+ SECTION("control-comment-null")
+ {
+ parsing_should_fail(FILE_LINE_ARGS, control_comment_null); // control-comment-null
+ }
+
+ SECTION("control-comment-us")
+ {
+ parsing_should_fail(FILE_LINE_ARGS, control_comment_us); // control-comment-us
+ }
+
+ SECTION("control-multi-del")
+ {
+ parsing_should_fail(FILE_LINE_ARGS, control_multi_del); // control-multi-del
+ }
+
+ SECTION("control-multi-lf")
+ {
+ parsing_should_fail(FILE_LINE_ARGS, control_multi_lf); // control-multi-lf
+ }
+
+ SECTION("control-multi-null")
+ {
+ parsing_should_fail(FILE_LINE_ARGS, control_multi_null); // control-multi-null
+ }
+
+ SECTION("control-multi-us")
+ {
+ parsing_should_fail(FILE_LINE_ARGS, control_multi_us); // control-multi-us
+ }
+
+ SECTION("control-rawmulti-del")
+ {
+ parsing_should_fail(FILE_LINE_ARGS, control_rawmulti_del); // control-rawmulti-del
+ }
+
+ SECTION("control-rawmulti-lf")
+ {
+ parsing_should_fail(FILE_LINE_ARGS, control_rawmulti_lf); // control-rawmulti-lf
+ }
+
+ SECTION("control-rawmulti-null")
+ {
+ parsing_should_fail(FILE_LINE_ARGS, control_rawmulti_null); // control-rawmulti-null
+ }
+
+ SECTION("control-rawmulti-us")
+ {
+ parsing_should_fail(FILE_LINE_ARGS, control_rawmulti_us); // control-rawmulti-us
+ }
+
+ SECTION("control-rawstring-del")
+ {
+ parsing_should_fail(FILE_LINE_ARGS, control_rawstring_del); // control-rawstring-del
+ }
+
+ SECTION("control-rawstring-lf")
+ {
+ parsing_should_fail(FILE_LINE_ARGS, control_rawstring_lf); // control-rawstring-lf
+ }
+
+ SECTION("control-rawstring-null")
+ {
+ parsing_should_fail(FILE_LINE_ARGS, control_rawstring_null); // control-rawstring-null
+ }
+
+ SECTION("control-rawstring-us")
+ {
+ parsing_should_fail(FILE_LINE_ARGS, control_rawstring_us); // control-rawstring-us
+ }
+
+ SECTION("control-string-bs")
+ {
+ parsing_should_fail(FILE_LINE_ARGS, control_string_bs); // control-string-bs
+ }
+
+ SECTION("control-string-del")
+ {
+ parsing_should_fail(FILE_LINE_ARGS, control_string_del); // control-string-del
+ }
+
+ SECTION("control-string-lf")
+ {
+ parsing_should_fail(FILE_LINE_ARGS, control_string_lf); // control-string-lf
+ }
+
+ SECTION("control-string-null")
+ {
+ parsing_should_fail(FILE_LINE_ARGS, control_string_null); // control-string-null
+ }
+
+ SECTION("control-string-us")
+ {
+ parsing_should_fail(FILE_LINE_ARGS, control_string_us); // control-string-us
+ }
+
+ SECTION("datetime-hour-over")
+ {
+ parsing_should_fail(FILE_LINE_ARGS, datetime_hour_over); // datetime-hour-over
+ }
+
+ SECTION("datetime-mday-over")
+ {
+ parsing_should_fail(FILE_LINE_ARGS, datetime_mday_over); // datetime-mday-over
+ }
+
+ SECTION("datetime-mday-under")
+ {
+ parsing_should_fail(FILE_LINE_ARGS, datetime_mday_under); // datetime-mday-under
+ }
+
+ SECTION("datetime-minute-over")
+ {
+ parsing_should_fail(FILE_LINE_ARGS, datetime_minute_over); // datetime-minute-over
+ }
+
+ SECTION("datetime-month-over")
+ {
+ parsing_should_fail(FILE_LINE_ARGS, datetime_month_over); // datetime-month-over
+ }
+
+ SECTION("datetime-month-under")
+ {
+ parsing_should_fail(FILE_LINE_ARGS, datetime_month_under); // datetime-month-under
+ }
+
+ SECTION("datetime-no-leads-month")
+ {
+ parsing_should_fail(FILE_LINE_ARGS, datetime_no_leads_month); // datetime-no-leads-month
+ }
+
+ SECTION("datetime-no-leads-with-milli")
+ {
+ parsing_should_fail(FILE_LINE_ARGS, datetime_no_leads_with_milli); // datetime-no-leads-with-milli
+ }
+
+ SECTION("datetime-no-leads")
+ {
+ parsing_should_fail(FILE_LINE_ARGS, datetime_no_leads); // datetime-no-leads
+ }
+
+ SECTION("datetime-no-t")
+ {
+ parsing_should_fail(FILE_LINE_ARGS, datetime_no_t); // datetime-no-t
+ }
+
+ SECTION("datetime-second-over")
+ {
+ parsing_should_fail(FILE_LINE_ARGS, datetime_second_over); // datetime-second-over
+ }
+
+ SECTION("datetime-time-no-leads")
+ {
+ parsing_should_fail(FILE_LINE_ARGS, datetime_time_no_leads); // datetime-time-no-leads
+ }
+
+#if !TOML_LANG_UNRELEASED
+
+ SECTION("datetime-no-secs")
+ {
+ parsing_should_fail(FILE_LINE_ARGS, datetime_no_secs); // datetime-no-secs
+ }
+
+#endif // !TOML_LANG_UNRELEASED
+
+ SECTION("encoding-bad-codepoint")
+ {
+ parsing_should_fail(FILE_LINE_ARGS, encoding_bad_codepoint); // encoding-bad-codepoint
+ }
+
+ SECTION("encoding-bad-utf8-at-end")
+ {
+ parsing_should_fail(FILE_LINE_ARGS, encoding_bad_utf8_at_end); // encoding-bad-utf8-at-end
+ }
+
+ SECTION("encoding-bad-utf8-in-comment")
+ {
+ parsing_should_fail(FILE_LINE_ARGS, encoding_bad_utf8_in_comment); // encoding-bad-utf8-in-comment
+ }
+
+ SECTION("encoding-bad-utf8-in-multiline-literal")
+ {
+ parsing_should_fail(FILE_LINE_ARGS,
+ encoding_bad_utf8_in_multiline_literal); // encoding-bad-utf8-in-multiline-literal
+ }
+
+ SECTION("encoding-bad-utf8-in-multiline")
+ {
+ parsing_should_fail(FILE_LINE_ARGS, encoding_bad_utf8_in_multiline); // encoding-bad-utf8-in-multiline
+ }
+
+ SECTION("encoding-bad-utf8-in-string-literal")
+ {
+ parsing_should_fail(FILE_LINE_ARGS, encoding_bad_utf8_in_string_literal); // encoding-bad-utf8-in-string-literal
+ }
+
+ SECTION("encoding-bad-utf8-in-string")
+ {
+ parsing_should_fail(FILE_LINE_ARGS, encoding_bad_utf8_in_string); // encoding-bad-utf8-in-string
+ }
+
+ SECTION("encoding-bom-not-at-start-1")
+ {
+ parsing_should_fail(FILE_LINE_ARGS, encoding_bom_not_at_start_1); // encoding-bom-not-at-start-1
+ }
+
+ SECTION("encoding-bom-not-at-start-2")
+ {
+ parsing_should_fail(FILE_LINE_ARGS, encoding_bom_not_at_start_2); // encoding-bom-not-at-start-2
+ }
+
+ SECTION("encoding-utf16-bom")
+ {
+ parsing_should_fail(FILE_LINE_ARGS, encoding_utf16_bom); // encoding-utf16-bom
+ }
+
+ SECTION("encoding-utf16")
+ {
+ parsing_should_fail(FILE_LINE_ARGS, encoding_utf16); // encoding-utf16
+ }
+
+ SECTION("float-double-point-1")
+ {
+ parsing_should_fail(FILE_LINE_ARGS, float_double_point_1); // float-double-point-1
+ }
+
+ SECTION("float-double-point-2")
+ {
+ parsing_should_fail(FILE_LINE_ARGS, float_double_point_2); // float-double-point-2
+ }
+
+ SECTION("float-exp-double-e-1")
+ {
+ parsing_should_fail(FILE_LINE_ARGS, float_exp_double_e_1); // float-exp-double-e-1
+ }
+
+ SECTION("float-exp-double-e-2")
+ {
+ parsing_should_fail(FILE_LINE_ARGS, float_exp_double_e_2); // float-exp-double-e-2
+ }
+
+ SECTION("float-exp-double-us")
+ {
+ parsing_should_fail(FILE_LINE_ARGS, float_exp_double_us); // float-exp-double-us
+ }
+
+ SECTION("float-exp-leading-us")
+ {
+ parsing_should_fail(FILE_LINE_ARGS, float_exp_leading_us); // float-exp-leading-us
+ }
+
+ SECTION("float-exp-point-1")
+ {
+ parsing_should_fail(FILE_LINE_ARGS, float_exp_point_1); // float-exp-point-1
+ }
+
+ SECTION("float-exp-point-2")
+ {
+ parsing_should_fail(FILE_LINE_ARGS, float_exp_point_2); // float-exp-point-2
+ }
+
+ SECTION("float-exp-trailing-us")
+ {
+ parsing_should_fail(FILE_LINE_ARGS, float_exp_trailing_us); // float-exp-trailing-us
+ }
+
+ SECTION("float-inf-capital")
+ {
+ parsing_should_fail(FILE_LINE_ARGS, float_inf_capital); // float-inf-capital
+ }
+
+ SECTION("float-inf-incomplete-1")
+ {
+ parsing_should_fail(FILE_LINE_ARGS, float_inf_incomplete_1); // float-inf-incomplete-1
+ }
+
+ SECTION("float-inf-incomplete-2")
+ {
+ parsing_should_fail(FILE_LINE_ARGS, float_inf_incomplete_2); // float-inf-incomplete-2
+ }
+
+ SECTION("float-inf-incomplete-3")
+ {
+ parsing_should_fail(FILE_LINE_ARGS, float_inf_incomplete_3); // float-inf-incomplete-3
+ }
+
+ SECTION("float-inf_underscore")
+ {
+ parsing_should_fail(FILE_LINE_ARGS, float_inf_underscore); // float-inf_underscore
+ }
+
+ SECTION("float-leading-point-neg")
+ {
+ parsing_should_fail(FILE_LINE_ARGS, float_leading_point_neg); // float-leading-point-neg
+ }
+
+ SECTION("float-leading-point-plus")
+ {
+ parsing_should_fail(FILE_LINE_ARGS, float_leading_point_plus); // float-leading-point-plus
+ }
+
+ SECTION("float-leading-point")
+ {
+ parsing_should_fail(FILE_LINE_ARGS, float_leading_point); // float-leading-point
+ }
+
+ SECTION("float-leading-us")
+ {
+ parsing_should_fail(FILE_LINE_ARGS, float_leading_us); // float-leading-us
+ }
+
+ SECTION("float-leading-zero-neg")
+ {
+ parsing_should_fail(FILE_LINE_ARGS, float_leading_zero_neg); // float-leading-zero-neg
+ }
+
+ SECTION("float-leading-zero-plus")
+ {
+ parsing_should_fail(FILE_LINE_ARGS, float_leading_zero_plus); // float-leading-zero-plus
+ }
+
+ SECTION("float-leading-zero")
+ {
+ parsing_should_fail(FILE_LINE_ARGS, float_leading_zero); // float-leading-zero
+ }
+
+ SECTION("float-nan-capital")
+ {
+ parsing_should_fail(FILE_LINE_ARGS, float_nan_capital); // float-nan-capital
+ }
+
+ SECTION("float-nan-incomplete-1")
+ {
+ parsing_should_fail(FILE_LINE_ARGS, float_nan_incomplete_1); // float-nan-incomplete-1
+ }
+
+ SECTION("float-nan-incomplete-2")
+ {
+ parsing_should_fail(FILE_LINE_ARGS, float_nan_incomplete_2); // float-nan-incomplete-2
+ }
+
+ SECTION("float-nan-incomplete-3")
+ {
+ parsing_should_fail(FILE_LINE_ARGS, float_nan_incomplete_3); // float-nan-incomplete-3
+ }
+
+ SECTION("float-nan_underscore")
+ {
+ parsing_should_fail(FILE_LINE_ARGS, float_nan_underscore); // float-nan_underscore
+ }
+
+ SECTION("float-trailing-point-min")
+ {
+ parsing_should_fail(FILE_LINE_ARGS, float_trailing_point_min); // float-trailing-point-min
+ }
+
+ SECTION("float-trailing-point-plus")
+ {
+ parsing_should_fail(FILE_LINE_ARGS, float_trailing_point_plus); // float-trailing-point-plus
+ }
+
+ SECTION("float-trailing-point")
+ {
+ parsing_should_fail(FILE_LINE_ARGS, float_trailing_point); // float-trailing-point
+ }
+
+ SECTION("float-trailing-us-exp-1")
+ {
+ parsing_should_fail(FILE_LINE_ARGS, float_trailing_us_exp_1); // float-trailing-us-exp-1
+ }
+
+ SECTION("float-trailing-us-exp-2")
+ {
+ parsing_should_fail(FILE_LINE_ARGS, float_trailing_us_exp_2); // float-trailing-us-exp-2
+ }
+
+ SECTION("float-trailing-us")
+ {
+ parsing_should_fail(FILE_LINE_ARGS, float_trailing_us); // float-trailing-us
+ }
+
+ SECTION("float-us-after-point")
+ {
+ parsing_should_fail(FILE_LINE_ARGS, float_us_after_point); // float-us-after-point
+ }
+
+ SECTION("float-us-before-point")
+ {
+ parsing_should_fail(FILE_LINE_ARGS, float_us_before_point); // float-us-before-point
+ }
+
+ SECTION("inline-table-add")
+ {
+ parsing_should_fail(FILE_LINE_ARGS, inline_table_add); // inline-table-add
+ }
+
+ SECTION("inline-table-bad-key-syntax")
+ {
+ parsing_should_fail(FILE_LINE_ARGS, inline_table_bad_key_syntax); // inline-table-bad-key-syntax
+ }
+
+ SECTION("inline-table-dotted-key-conflict")
+ {
+ parsing_should_fail(FILE_LINE_ARGS, inline_table_dotted_key_conflict); // inline-table-dotted-key-conflict
+ }
+
+ SECTION("inline-table-double-comma")
+ {
+ parsing_should_fail(FILE_LINE_ARGS, inline_table_double_comma); // inline-table-double-comma
+ }
+
+ SECTION("inline-table-duplicate-key")
+ {
+ parsing_should_fail(FILE_LINE_ARGS, inline_table_duplicate_key); // inline-table-duplicate-key
+ }
+
+ SECTION("inline-table-empty")
+ {
+ parsing_should_fail(FILE_LINE_ARGS, inline_table_empty); // inline-table-empty
+ }
+
+ SECTION("inline-table-nested_key_conflict")
+ {
+ parsing_should_fail(FILE_LINE_ARGS, inline_table_nested_key_conflict); // inline-table-nested_key_conflict
+ }
+
+ SECTION("inline-table-no-comma")
+ {
+ parsing_should_fail(FILE_LINE_ARGS, inline_table_no_comma); // inline-table-no-comma
+ }
+
+ SECTION("inline-table-overwrite")
+ {
+ parsing_should_fail(FILE_LINE_ARGS, inline_table_overwrite); // inline-table-overwrite
+ }
+
+#if !TOML_LANG_UNRELEASED
+
+ SECTION("inline-table-linebreak-1")
+ {
+ parsing_should_fail(FILE_LINE_ARGS, inline_table_linebreak_1); // inline-table-linebreak-1
+ }
+
+ SECTION("inline-table-linebreak-2")
+ {
+ parsing_should_fail(FILE_LINE_ARGS, inline_table_linebreak_2); // inline-table-linebreak-2
+ }
+
+ SECTION("inline-table-linebreak-3")
+ {
+ parsing_should_fail(FILE_LINE_ARGS, inline_table_linebreak_3); // inline-table-linebreak-3
+ }
+
+ SECTION("inline-table-linebreak-4")
+ {
+ parsing_should_fail(FILE_LINE_ARGS, inline_table_linebreak_4); // inline-table-linebreak-4
+ }
+
+ SECTION("inline-table-trailing-comma")
+ {
+ parsing_should_fail(FILE_LINE_ARGS, inline_table_trailing_comma); // inline-table-trailing-comma
+ }
+
+#endif // !TOML_LANG_UNRELEASED
+
+ SECTION("integer-capital-bin")
+ {
+ parsing_should_fail(FILE_LINE_ARGS, integer_capital_bin); // integer-capital-bin
+ }
+
+ SECTION("integer-capital-hex")
+ {
+ parsing_should_fail(FILE_LINE_ARGS, integer_capital_hex); // integer-capital-hex
+ }
+
+ SECTION("integer-capital-oct")
+ {
+ parsing_should_fail(FILE_LINE_ARGS, integer_capital_oct); // integer-capital-oct
+ }
+
+ SECTION("integer-double-sign-nex")
+ {
+ parsing_should_fail(FILE_LINE_ARGS, integer_double_sign_nex); // integer-double-sign-nex
+ }
+
+ SECTION("integer-double-sign-plus")
+ {
+ parsing_should_fail(FILE_LINE_ARGS, integer_double_sign_plus); // integer-double-sign-plus
+ }
+
+ SECTION("integer-double-us")
+ {
+ parsing_should_fail(FILE_LINE_ARGS, integer_double_us); // integer-double-us
+ }
+
+ SECTION("integer-incomplete-bin")
+ {
+ parsing_should_fail(FILE_LINE_ARGS, integer_incomplete_bin); // integer-incomplete-bin
+ }
+
+ SECTION("integer-incomplete-hex")
+ {
+ parsing_should_fail(FILE_LINE_ARGS, integer_incomplete_hex); // integer-incomplete-hex
+ }
+
+ SECTION("integer-incomplete-oct")
+ {
+ parsing_should_fail(FILE_LINE_ARGS, integer_incomplete_oct); // integer-incomplete-oct
+ }
+
+ SECTION("integer-invalid-bin")
+ {
+ parsing_should_fail(FILE_LINE_ARGS, integer_invalid_bin); // integer-invalid-bin
+ }
+
+ SECTION("integer-invalid-hex")
+ {
+ parsing_should_fail(FILE_LINE_ARGS, integer_invalid_hex); // integer-invalid-hex
+ }
+
+ SECTION("integer-invalid-oct")
+ {
+ parsing_should_fail(FILE_LINE_ARGS, integer_invalid_oct); // integer-invalid-oct
+ }
+
+ SECTION("integer-leading-us-bin")
+ {
+ parsing_should_fail(FILE_LINE_ARGS, integer_leading_us_bin); // integer-leading-us-bin
+ }
+
+ SECTION("integer-leading-us-hex")
+ {
+ parsing_should_fail(FILE_LINE_ARGS, integer_leading_us_hex); // integer-leading-us-hex
+ }
+
+ SECTION("integer-leading-us-oct")
+ {
+ parsing_should_fail(FILE_LINE_ARGS, integer_leading_us_oct); // integer-leading-us-oct
+ }
+
+ SECTION("integer-leading-us")
+ {
+ parsing_should_fail(FILE_LINE_ARGS, integer_leading_us); // integer-leading-us
+ }
+
+ SECTION("integer-leading-zero-1")
+ {
+ parsing_should_fail(FILE_LINE_ARGS, integer_leading_zero_1); // integer-leading-zero-1
+ }
+
+ SECTION("integer-leading-zero-2")
+ {
+ parsing_should_fail(FILE_LINE_ARGS, integer_leading_zero_2); // integer-leading-zero-2
+ }
+
+ SECTION("integer-leading-zero-3")
+ {
+ parsing_should_fail(FILE_LINE_ARGS, integer_leading_zero_3); // integer-leading-zero-3
+ }
+
+ SECTION("integer-leading-zero-sign-1")
+ {
+ parsing_should_fail(FILE_LINE_ARGS, integer_leading_zero_sign_1); // integer-leading-zero-sign-1
+ }
+
+ SECTION("integer-leading-zero-sign-2")
+ {
+ parsing_should_fail(FILE_LINE_ARGS, integer_leading_zero_sign_2); // integer-leading-zero-sign-2
+ }
+
+ SECTION("integer-leading-zero-sign-3")
+ {
+ parsing_should_fail(FILE_LINE_ARGS, integer_leading_zero_sign_3); // integer-leading-zero-sign-3
+ }
+
+ SECTION("integer-negative-bin")
+ {
+ parsing_should_fail(FILE_LINE_ARGS, integer_negative_bin); // integer-negative-bin
+ }
+
+ SECTION("integer-negative-hex")
+ {
+ parsing_should_fail(FILE_LINE_ARGS, integer_negative_hex); // integer-negative-hex
+ }
+
+ SECTION("integer-negative-oct")
+ {
+ parsing_should_fail(FILE_LINE_ARGS, integer_negative_oct); // integer-negative-oct
+ }
+
+ SECTION("integer-positive-bin")
+ {
+ parsing_should_fail(FILE_LINE_ARGS, integer_positive_bin); // integer-positive-bin
+ }
+
+ SECTION("integer-positive-hex")
+ {
+ parsing_should_fail(FILE_LINE_ARGS, integer_positive_hex); // integer-positive-hex
+ }
+
+ SECTION("integer-positive-oct")
+ {
+ parsing_should_fail(FILE_LINE_ARGS, integer_positive_oct); // integer-positive-oct
+ }
+
+ SECTION("integer-text-after-integer")
+ {
+ parsing_should_fail(FILE_LINE_ARGS, integer_text_after_integer); // integer-text-after-integer
+ }
+
+ SECTION("integer-trailing-us-bin")
+ {
+ parsing_should_fail(FILE_LINE_ARGS, integer_trailing_us_bin); // integer-trailing-us-bin
+ }
+
+ SECTION("integer-trailing-us-hex")
+ {
+ parsing_should_fail(FILE_LINE_ARGS, integer_trailing_us_hex); // integer-trailing-us-hex
+ }
+
+ SECTION("integer-trailing-us-oct")
+ {
+ parsing_should_fail(FILE_LINE_ARGS, integer_trailing_us_oct); // integer-trailing-us-oct
+ }
+
+ SECTION("integer-trailing-us")
+ {
+ parsing_should_fail(FILE_LINE_ARGS, integer_trailing_us); // integer-trailing-us
+ }
+
+ SECTION("integer-us-after-bin")
+ {
+ parsing_should_fail(FILE_LINE_ARGS, integer_us_after_bin); // integer-us-after-bin
+ }
+
+ SECTION("integer-us-after-hex")
+ {
+ parsing_should_fail(FILE_LINE_ARGS, integer_us_after_hex); // integer-us-after-hex
+ }
+
+ SECTION("integer-us-after-oct")
+ {
+ parsing_should_fail(FILE_LINE_ARGS, integer_us_after_oct); // integer-us-after-oct
+ }
+
+ SECTION("key-after-array")
+ {
+ parsing_should_fail(FILE_LINE_ARGS, key_after_array); // key-after-array
+ }
+
+ SECTION("key-after-table")
+ {
+ parsing_should_fail(FILE_LINE_ARGS, key_after_table); // key-after-table
+ }
+
+ SECTION("key-after-value")
+ {
+ parsing_should_fail(FILE_LINE_ARGS, key_after_value); // key-after-value
+ }
+
+ SECTION("key-bare-invalid-character")
+ {
+ parsing_should_fail(FILE_LINE_ARGS, key_bare_invalid_character); // key-bare-invalid-character
+ }
+
+ SECTION("key-dotted-redefine-table")
+ {
+ parsing_should_fail(FILE_LINE_ARGS, key_dotted_redefine_table); // key-dotted-redefine-table
+ }
+
+ SECTION("key-duplicate-keys")
+ {
+ parsing_should_fail(FILE_LINE_ARGS, key_duplicate_keys); // key-duplicate-keys
+ }
+
+ SECTION("key-duplicate")
+ {
+ parsing_should_fail(FILE_LINE_ARGS, key_duplicate); // key-duplicate
+ }
+
+ SECTION("key-empty")
+ {
+ parsing_should_fail(FILE_LINE_ARGS, key_empty); // key-empty
+ }
+
+ SECTION("key-escape")
+ {
+ parsing_should_fail(FILE_LINE_ARGS, key_escape); // key-escape
+ }
+
+ SECTION("key-hash")
+ {
+ parsing_should_fail(FILE_LINE_ARGS, key_hash); // key-hash
+ }
+
+ SECTION("key-multiline")
+ {
+ parsing_should_fail(FILE_LINE_ARGS, key_multiline); // key-multiline
+ }
+
+ SECTION("key-newline")
+ {
+ parsing_should_fail(FILE_LINE_ARGS, key_newline); // key-newline
+ }
+
+ SECTION("key-no-eol")
+ {
+ parsing_should_fail(FILE_LINE_ARGS, key_no_eol); // key-no-eol
+ }
+
+ SECTION("key-open-bracket")
+ {
+ parsing_should_fail(FILE_LINE_ARGS, key_open_bracket); // key-open-bracket
+ }
+
+ SECTION("key-partial-quoted")
+ {
+ parsing_should_fail(FILE_LINE_ARGS, key_partial_quoted); // key-partial-quoted
+ }
+
+ SECTION("key-quoted-unclosed-1")
+ {
+ parsing_should_fail(FILE_LINE_ARGS, key_quoted_unclosed_1); // key-quoted-unclosed-1
+ }
+
+ SECTION("key-quoted-unclosed-2")
+ {
+ parsing_should_fail(FILE_LINE_ARGS, key_quoted_unclosed_2); // key-quoted-unclosed-2
+ }
+
+ SECTION("key-single-open-bracket")
+ {
+ parsing_should_fail(FILE_LINE_ARGS, key_single_open_bracket); // key-single-open-bracket
+ }
+
+ SECTION("key-space")
+ {
+ parsing_should_fail(FILE_LINE_ARGS, key_space); // key-space
+ }
+
+ SECTION("key-start-bracket")
+ {
+ parsing_should_fail(FILE_LINE_ARGS, key_start_bracket); // key-start-bracket
+ }
+
+ SECTION("key-start-dot")
+ {
+ parsing_should_fail(FILE_LINE_ARGS, key_start_dot); // key-start-dot
+ }
+
+ SECTION("key-two-equals")
+ {
+ parsing_should_fail(FILE_LINE_ARGS, key_two_equals); // key-two-equals
+ }
+
+ SECTION("key-two-equals2")
+ {
+ parsing_should_fail(FILE_LINE_ARGS, key_two_equals2); // key-two-equals2
+ }
+
+ SECTION("key-two-equals3")
+ {
+ parsing_should_fail(FILE_LINE_ARGS, key_two_equals3); // key-two-equals3
+ }
+
+ SECTION("key-without-value-1")
+ {
+ parsing_should_fail(FILE_LINE_ARGS, key_without_value_1); // key-without-value-1
+ }
+
+ SECTION("key-without-value-2")
+ {
+ parsing_should_fail(FILE_LINE_ARGS, key_without_value_2); // key-without-value-2
+ }
+
+ SECTION("key-without-value-3")
+ {
+ parsing_should_fail(FILE_LINE_ARGS, key_without_value_3); // key-without-value-3
+ }
+
+ SECTION("key-without-value-4")
+ {
+ parsing_should_fail(FILE_LINE_ARGS, key_without_value_4); // key-without-value-4
+ }
+
+#if !TOML_LANG_UNRELEASED && UNICODE_LITERALS_OK
+
+ SECTION("key-special-character")
+ {
+ parsing_should_fail(FILE_LINE_ARGS, key_special_character); // key-special-character
+ }
+
+#endif // !TOML_LANG_UNRELEASED && UNICODE_LITERALS_OK
+
+ SECTION("local-date-mday-over")
+ {
+ parsing_should_fail(FILE_LINE_ARGS, local_date_mday_over); // local-date-mday-over
+ }
+
+ SECTION("local-date-mday-under")
+ {
+ parsing_should_fail(FILE_LINE_ARGS, local_date_mday_under); // local-date-mday-under
+ }
+
+ SECTION("local-date-month-over")
+ {
+ parsing_should_fail(FILE_LINE_ARGS, local_date_month_over); // local-date-month-over
+ }
+
+ SECTION("local-date-month-under")
+ {
+ parsing_should_fail(FILE_LINE_ARGS, local_date_month_under); // local-date-month-under
+ }
+
+ SECTION("local-date-no-leads-with-milli")
+ {
+ parsing_should_fail(FILE_LINE_ARGS, local_date_no_leads_with_milli); // local-date-no-leads-with-milli
+ }
+
+ SECTION("local-date-no-leads")
+ {
+ parsing_should_fail(FILE_LINE_ARGS, local_date_no_leads); // local-date-no-leads
+ }
+
+ SECTION("local-date-trailing-t")
+ {
+ parsing_should_fail(FILE_LINE_ARGS, local_date_trailing_t); // local-date-trailing-t
+ }
+
+ SECTION("local-datetime-hour-over")
+ {
+ parsing_should_fail(FILE_LINE_ARGS, local_datetime_hour_over); // local-datetime-hour-over
+ }
+
+ SECTION("local-datetime-mday-over")
+ {
+ parsing_should_fail(FILE_LINE_ARGS, local_datetime_mday_over); // local-datetime-mday-over
+ }
+
+ SECTION("local-datetime-mday-under")
+ {
+ parsing_should_fail(FILE_LINE_ARGS, local_datetime_mday_under); // local-datetime-mday-under
+ }
+
+ SECTION("local-datetime-minute-over")
+ {
+ parsing_should_fail(FILE_LINE_ARGS, local_datetime_minute_over); // local-datetime-minute-over
+ }
+
+ SECTION("local-datetime-month-over")
+ {
+ parsing_should_fail(FILE_LINE_ARGS, local_datetime_month_over); // local-datetime-month-over
+ }
+
+ SECTION("local-datetime-month-under")
+ {
+ parsing_should_fail(FILE_LINE_ARGS, local_datetime_month_under); // local-datetime-month-under
+ }
+
+ SECTION("local-datetime-no-leads-with-milli")
+ {
+ parsing_should_fail(FILE_LINE_ARGS, local_datetime_no_leads_with_milli); // local-datetime-no-leads-with-milli
+ }
+
+ SECTION("local-datetime-no-leads")
+ {
+ parsing_should_fail(FILE_LINE_ARGS, local_datetime_no_leads); // local-datetime-no-leads
+ }
+
+ SECTION("local-datetime-no-secs")
+ {
+ parsing_should_fail(FILE_LINE_ARGS, local_datetime_no_secs); // local-datetime-no-secs
+ }
+
+ SECTION("local-datetime-no-t")
+ {
+ parsing_should_fail(FILE_LINE_ARGS, local_datetime_no_t); // local-datetime-no-t
+ }
+
+ SECTION("local-datetime-second-over")
+ {
+ parsing_should_fail(FILE_LINE_ARGS, local_datetime_second_over); // local-datetime-second-over
+ }
+
+ SECTION("local-datetime-time-no-leads")
+ {
+ parsing_should_fail(FILE_LINE_ARGS, local_datetime_time_no_leads); // local-datetime-time-no-leads
+ }
+
+ SECTION("local-time-hour-over")
+ {
+ parsing_should_fail(FILE_LINE_ARGS, local_time_hour_over); // local-time-hour-over
+ }
+
+ SECTION("local-time-minute-over")
+ {
+ parsing_should_fail(FILE_LINE_ARGS, local_time_minute_over); // local-time-minute-over
+ }
+
+ SECTION("local-time-no-secs")
+ {
+ parsing_should_fail(FILE_LINE_ARGS, local_time_no_secs); // local-time-no-secs
+ }
+
+ SECTION("local-time-second-over")
+ {
+ parsing_should_fail(FILE_LINE_ARGS, local_time_second_over); // local-time-second-over
+ }
+
+ SECTION("local-time-time-no-leads-2")
+ {
+ parsing_should_fail(FILE_LINE_ARGS, local_time_time_no_leads_2); // local-time-time-no-leads-2
+ }
+
+ SECTION("local-time-time-no-leads")
+ {
+ parsing_should_fail(FILE_LINE_ARGS, local_time_time_no_leads); // local-time-time-no-leads
+ }
+
+ SECTION("spec-inline-table-2-0")
+ {
+ parsing_should_fail(FILE_LINE_ARGS, spec_inline_table_2_0); // spec-inline-table-2-0
+ }
+
+ SECTION("spec-inline-table-3-0")
+ {
+ parsing_should_fail(FILE_LINE_ARGS, spec_inline_table_3_0); // spec-inline-table-3-0
+ }
+
+ SECTION("spec-key-value-pair-1")
+ {
+ parsing_should_fail(FILE_LINE_ARGS, spec_key_value_pair_1); // spec-key-value-pair-1
+ }
+
+ SECTION("spec-keys-2")
+ {
+ parsing_should_fail(FILE_LINE_ARGS, spec_keys_2); // spec-keys-2
+ }
+
+ SECTION("spec-string-4-0")
+ {
+ parsing_should_fail(FILE_LINE_ARGS, spec_string_4_0); // spec-string-4-0
+ }
+
+ SECTION("spec-string-7-0")
+ {
+ parsing_should_fail(FILE_LINE_ARGS, spec_string_7_0); // spec-string-7-0
+ }
+
+ SECTION("spec-table-9-0")
+ {
+ parsing_should_fail(FILE_LINE_ARGS, spec_table_9_0); // spec-table-9-0
+ }
+
+ SECTION("spec-table-9-1")
+ {
+ parsing_should_fail(FILE_LINE_ARGS, spec_table_9_1); // spec-table-9-1
+ }
+
+ SECTION("string-bad-byte-escape")
+ {
+ parsing_should_fail(FILE_LINE_ARGS, string_bad_byte_escape); // string-bad-byte-escape
+ }
+
+ SECTION("string-bad-codepoint")
+ {
+ parsing_should_fail(FILE_LINE_ARGS, string_bad_codepoint); // string-bad-codepoint
+ }
+
+ SECTION("string-bad-concat")
+ {
+ parsing_should_fail(FILE_LINE_ARGS, string_bad_concat); // string-bad-concat
+ }
+
+ SECTION("string-bad-escape-1")
+ {
+ parsing_should_fail(FILE_LINE_ARGS, string_bad_escape_1); // string-bad-escape-1
+ }
+
+ SECTION("string-bad-escape-2")
+ {
+ parsing_should_fail(FILE_LINE_ARGS, string_bad_escape_2); // string-bad-escape-2
+ }
+
+ SECTION("string-bad-hex-esc-1")
+ {
+ parsing_should_fail(FILE_LINE_ARGS, string_bad_hex_esc_1); // string-bad-hex-esc-1
+ }
+
+ SECTION("string-bad-hex-esc-2")
+ {
+ parsing_should_fail(FILE_LINE_ARGS, string_bad_hex_esc_2); // string-bad-hex-esc-2
+ }
+
+ SECTION("string-bad-hex-esc-3")
+ {
+ parsing_should_fail(FILE_LINE_ARGS, string_bad_hex_esc_3); // string-bad-hex-esc-3
+ }
+
+ SECTION("string-bad-hex-esc-4")
+ {
+ parsing_should_fail(FILE_LINE_ARGS, string_bad_hex_esc_4); // string-bad-hex-esc-4
+ }
+
+ SECTION("string-bad-hex-esc-5")
+ {
+ parsing_should_fail(FILE_LINE_ARGS, string_bad_hex_esc_5); // string-bad-hex-esc-5
+ }
+
+ SECTION("string-bad-multiline")
+ {
+ parsing_should_fail(FILE_LINE_ARGS, string_bad_multiline); // string-bad-multiline
+ }
+
+ SECTION("string-bad-slash-escape")
+ {
+ parsing_should_fail(FILE_LINE_ARGS, string_bad_slash_escape); // string-bad-slash-escape
+ }
+
+ SECTION("string-bad-uni-esc-1")
+ {
+ parsing_should_fail(FILE_LINE_ARGS, string_bad_uni_esc_1); // string-bad-uni-esc-1
+ }
+
+ SECTION("string-bad-uni-esc-2")
+ {
+ parsing_should_fail(FILE_LINE_ARGS, string_bad_uni_esc_2); // string-bad-uni-esc-2
+ }
+
+ SECTION("string-bad-uni-esc-3")
+ {
+ parsing_should_fail(FILE_LINE_ARGS, string_bad_uni_esc_3); // string-bad-uni-esc-3
+ }
+
+ SECTION("string-bad-uni-esc-4")
+ {
+ parsing_should_fail(FILE_LINE_ARGS, string_bad_uni_esc_4); // string-bad-uni-esc-4
+ }
+
+ SECTION("string-bad-uni-esc-5")
+ {
+ parsing_should_fail(FILE_LINE_ARGS, string_bad_uni_esc_5); // string-bad-uni-esc-5
+ }
+
+ SECTION("string-basic-multiline-out-of-range-unicode-escape-1")
+ {
+ parsing_should_fail(
+ FILE_LINE_ARGS,
+ string_basic_multiline_out_of_range_unicode_escape_1); // string-basic-multiline-out-of-range-unicode-escape-1
+ }
+
+ SECTION("string-basic-multiline-out-of-range-unicode-escape-2")
+ {
+ parsing_should_fail(
+ FILE_LINE_ARGS,
+ string_basic_multiline_out_of_range_unicode_escape_2); // string-basic-multiline-out-of-range-unicode-escape-2
+ }
+
+ SECTION("string-basic-multiline-quotes")
+ {
+ parsing_should_fail(FILE_LINE_ARGS, string_basic_multiline_quotes); // string-basic-multiline-quotes
+ }
+
+ SECTION("string-basic-multiline-unknown-escape")
+ {
+ parsing_should_fail(FILE_LINE_ARGS,
+ string_basic_multiline_unknown_escape); // string-basic-multiline-unknown-escape
+ }
+
+ SECTION("string-basic-out-of-range-unicode-escape-1")
+ {
+ parsing_should_fail(FILE_LINE_ARGS,
+ string_basic_out_of_range_unicode_escape_1); // string-basic-out-of-range-unicode-escape-1
+ }
+
+ SECTION("string-basic-out-of-range-unicode-escape-2")
+ {
+ parsing_should_fail(FILE_LINE_ARGS,
+ string_basic_out_of_range_unicode_escape_2); // string-basic-out-of-range-unicode-escape-2
+ }
+
+ SECTION("string-basic-unknown-escape")
+ {
+ parsing_should_fail(FILE_LINE_ARGS, string_basic_unknown_escape); // string-basic-unknown-escape
+ }
+
+ SECTION("string-literal-multiline-quotes-1")
+ {
+ parsing_should_fail(FILE_LINE_ARGS, string_literal_multiline_quotes_1); // string-literal-multiline-quotes-1
+ }
+
+ SECTION("string-literal-multiline-quotes-2")
+ {
+ parsing_should_fail(FILE_LINE_ARGS, string_literal_multiline_quotes_2); // string-literal-multiline-quotes-2
+ }
+
+ SECTION("string-missing-quotes")
+ {
+ parsing_should_fail(FILE_LINE_ARGS, string_missing_quotes); // string-missing-quotes
+ }
+
+ SECTION("string-multiline-bad-escape-1")
+ {
+ parsing_should_fail(FILE_LINE_ARGS, string_multiline_bad_escape_1); // string-multiline-bad-escape-1
+ }
+
+ SECTION("string-multiline-bad-escape-2")
+ {
+ parsing_should_fail(FILE_LINE_ARGS, string_multiline_bad_escape_2); // string-multiline-bad-escape-2
+ }
+
+ SECTION("string-multiline-bad-escape-3")
+ {
+ parsing_should_fail(FILE_LINE_ARGS, string_multiline_bad_escape_3); // string-multiline-bad-escape-3
+ }
+
+ SECTION("string-multiline-escape-space")
+ {
+ parsing_should_fail(FILE_LINE_ARGS, string_multiline_escape_space); // string-multiline-escape-space
+ }
+
+ SECTION("string-multiline-no-close-2")
+ {
+ parsing_should_fail(FILE_LINE_ARGS, string_multiline_no_close_2); // string-multiline-no-close-2
+ }
+
+ SECTION("string-multiline-no-close")
+ {
+ parsing_should_fail(FILE_LINE_ARGS, string_multiline_no_close); // string-multiline-no-close
+ }
+
+ SECTION("string-multiline-quotes-1")
+ {
+ parsing_should_fail(FILE_LINE_ARGS, string_multiline_quotes_1); // string-multiline-quotes-1
+ }
+
+ SECTION("string-no-close")
+ {
+ parsing_should_fail(FILE_LINE_ARGS, string_no_close); // string-no-close
+ }
+
+ SECTION("string-text-after-string")
+ {
+ parsing_should_fail(FILE_LINE_ARGS, string_text_after_string); // string-text-after-string
+ }
+
+ SECTION("string-wrong-close")
+ {
+ parsing_should_fail(FILE_LINE_ARGS, string_wrong_close); // string-wrong-close
+ }
+
+#if !TOML_LANG_UNRELEASED
+
+ SECTION("string-basic-byte-escapes")
+ {
+ parsing_should_fail(FILE_LINE_ARGS, string_basic_byte_escapes); // string-basic-byte-escapes
+ }
+
+#endif // !TOML_LANG_UNRELEASED
+
+ SECTION("table-append-to-array-with-dotted-keys")
+ {
+ parsing_should_fail(FILE_LINE_ARGS,
+ table_append_to_array_with_dotted_keys); // table-append-to-array-with-dotted-keys
+ }
+
+ SECTION("table-append-with-dotted-keys-1")
+ {
+ parsing_should_fail(FILE_LINE_ARGS, table_append_with_dotted_keys_1); // table-append-with-dotted-keys-1
+ }
+
+ SECTION("table-append-with-dotted-keys-2")
+ {
+ parsing_should_fail(FILE_LINE_ARGS, table_append_with_dotted_keys_2); // table-append-with-dotted-keys-2
+ }
+
+ SECTION("table-array-empty")
+ {
+ parsing_should_fail(FILE_LINE_ARGS, table_array_empty); // table-array-empty
+ }
+
+ SECTION("table-array-implicit")
+ {
+ parsing_should_fail(FILE_LINE_ARGS, table_array_implicit); // table-array-implicit
+ }
+
+ SECTION("table-array-missing-bracket")
+ {
+ parsing_should_fail(FILE_LINE_ARGS, table_array_missing_bracket); // table-array-missing-bracket
+ }
+
+ SECTION("table-duplicate-key-dotted-array")
+ {
+ parsing_should_fail(FILE_LINE_ARGS, table_duplicate_key_dotted_array); // table-duplicate-key-dotted-array
+ }
+
+ SECTION("table-duplicate-key-dotted-table")
+ {
+ parsing_should_fail(FILE_LINE_ARGS, table_duplicate_key_dotted_table); // table-duplicate-key-dotted-table
+ }
+
+ SECTION("table-duplicate-key-dotted-table2")
+ {
+ parsing_should_fail(FILE_LINE_ARGS, table_duplicate_key_dotted_table2); // table-duplicate-key-dotted-table2
+ }
+
+ SECTION("table-duplicate-key-table")
+ {
+ parsing_should_fail(FILE_LINE_ARGS, table_duplicate_key_table); // table-duplicate-key-table
+ }
+
+ SECTION("table-duplicate-table-array")
+ {
+ parsing_should_fail(FILE_LINE_ARGS, table_duplicate_table_array); // table-duplicate-table-array
+ }
+
+ SECTION("table-duplicate-table-array2")
+ {
+ parsing_should_fail(FILE_LINE_ARGS, table_duplicate_table_array2); // table-duplicate-table-array2
+ }
+
+ SECTION("table-duplicate")
+ {
+ parsing_should_fail(FILE_LINE_ARGS, table_duplicate); // table-duplicate
+ }
+
+ SECTION("table-empty-implicit-table")
+ {
+ parsing_should_fail(FILE_LINE_ARGS, table_empty_implicit_table); // table-empty-implicit-table
+ }
+
+ SECTION("table-empty")
+ {
+ parsing_should_fail(FILE_LINE_ARGS, table_empty); // table-empty
+ }
+
+ SECTION("table-equals-sign")
+ {
+ parsing_should_fail(FILE_LINE_ARGS, table_equals_sign); // table-equals-sign
+ }
+
+ SECTION("table-llbrace")
+ {
+ parsing_should_fail(FILE_LINE_ARGS, table_llbrace); // table-llbrace
+ }
+
+ SECTION("table-nested-brackets-close")
+ {
+ parsing_should_fail(FILE_LINE_ARGS, table_nested_brackets_close); // table-nested-brackets-close
+ }
+
+ SECTION("table-nested-brackets-open")
+ {
+ parsing_should_fail(FILE_LINE_ARGS, table_nested_brackets_open); // table-nested-brackets-open
+ }
+
+ SECTION("table-quoted-no-close")
+ {
+ parsing_should_fail(FILE_LINE_ARGS, table_quoted_no_close); // table-quoted-no-close
+ }
+
+ SECTION("table-redefine")
+ {
+ parsing_should_fail(FILE_LINE_ARGS, table_redefine); // table-redefine
+ }
+
+ SECTION("table-rrbrace")
+ {
+ parsing_should_fail(FILE_LINE_ARGS, table_rrbrace); // table-rrbrace
+ }
+
+ SECTION("table-text-after-table")
+ {
+ parsing_should_fail(FILE_LINE_ARGS, table_text_after_table); // table-text-after-table
+ }
+
+ SECTION("table-whitespace")
+ {
+ parsing_should_fail(FILE_LINE_ARGS, table_whitespace); // table-whitespace
+ }
+
+ SECTION("table-with-pound")
+ {
+ parsing_should_fail(FILE_LINE_ARGS, table_with_pound); // table-with-pound
+ }
+}
diff --git a/tomlplusplus/tests/conformance_burntsushi_valid.cpp b/tomlplusplus/tests/conformance_burntsushi_valid.cpp
new file mode 100644
index 0000000000..14520d6177
--- /dev/null
+++ b/tomlplusplus/tests/conformance_burntsushi_valid.cpp
@@ -0,0 +1,4734 @@
+// This file is a part of toml++ and is subject to the the terms of the MIT license.
+// Copyright (c) Mark Gillard <mark.gillard@outlook.com.au>
+// See https://github.com/marzer/tomlplusplus/blob/master/LICENSE for the full license text.
+// SPDX-License-Identifier: MIT
+//-----
+// this file was generated by generate_conformance_tests.py - do not modify it directly
+
+#include "tests.hpp"
+
+namespace
+{
+ static constexpr auto array_array = R"(ints = [1, 2, 3, ]
+floats = [1.1, 2.1, 3.1]
+strings = ["a", "b", "c"]
+dates = [
+ 1987-07-05T17:45:00Z,
+ 1979-05-27T07:32:00Z,
+ 2006-06-01T11:00:00Z,
+]
+comments = [
+ 1,
+ 2, #this is ok
+])"sv;
+ static constexpr auto array_bool = R"(a = [true, false])"sv;
+ static constexpr auto array_empty = R"(thevoid = [[[[[]]]]])"sv;
+ static constexpr auto array_hetergeneous = R"(mixed = [[1, 2], ["a", "b"], [1.1, 2.1]])"sv;
+ static constexpr auto array_mixed_int_array = R"(arrays-and-ints = [1, ["Arrays are not integers."]])"sv;
+ static constexpr auto array_mixed_int_float = R"(ints-and-floats = [1, 1.1])"sv;
+ static constexpr auto array_mixed_int_string = R"(strings-and-ints = ["hi", 42])"sv;
+ static constexpr auto array_mixed_string_table = R"(contributors = [
+ "Foo Bar <foo@example.com>",
+ { name = "Baz Qux", email = "bazqux@example.com", url = "https://example.com/bazqux" }
+]
+
+# Start with a table as the first element. This tests a case that some libraries
+# might have where they will check if the first entry is a table/map/hash/assoc
+# array and then encode it as a table array. This was a reasonable thing to do
+# before TOML 1.0 since arrays could only contain one type, but now it's no
+# longer.
+mixed = [{k="a"}, "b", 1])"sv;
+ static constexpr auto array_nested_double = R"(nest = [
+ [
+ ["a"],
+ [1, 2, [3]]
+ ]
+])"sv;
+ static constexpr auto array_nested_inline_table = R"(a = [ { b = {} } ])"sv;
+ static constexpr auto array_nested = R"(nest = [["a"], ["b"]])"sv;
+ static constexpr auto array_nospaces = R"(ints = [1,2,3])"sv;
+ static constexpr auto array_string_quote_comma_2 = R"(title = [ " \", ",])"sv;
+ static constexpr auto array_string_quote_comma = R"(title = [
+"Client: \"XXXX\", Job: XXXX",
+"Code: XXXX"
+])"sv;
+ static constexpr auto array_string_with_comma_2 = R"(title = [
+"""Client: XXXX,
+Job: XXXX""",
+"Code: XXXX"
+])"sv;
+ static constexpr auto array_string_with_comma = R"(title = [
+"Client: XXXX, Job: XXXX",
+"Code: XXXX"
+])"sv;
+ static constexpr auto array_strings = R"(string_array = [ "all", 'strings', """are the same""", '''type'''])"sv;
+ static constexpr auto array_table_array_string_backslash = R"(foo = [ { bar="\"{{baz}}\""} ])"sv;
+
+ static constexpr auto bool_bool = R"(t = true
+f = false)"sv;
+
+ static constexpr auto comment_after_literal_no_ws = R"(inf=inf#infinity
+nan=nan#not a number
+true=true#true
+false=false#false)"sv;
+ static constexpr auto comment_at_eof = R"(# This is a full-line comment
+key = "value" # This is a comment at the end of a line)"sv;
+ static constexpr auto comment_at_eof2 = R"(# This is a full-line comment
+key = "value" # This is a comment at the end of a line)"sv;
+ static constexpr auto comment_everywhere = R"(# Top comment.
+ # Top comment.
+# Top comment.
+
+# [no-extraneous-groups-please]
+
+[group] # Comment
+answer = 42 # Comment
+# no-extraneous-keys-please = 999
+# Inbetween comment.
+more = [ # Comment
+ # What about multiple # comments?
+ # Can you handle it?
+ #
+ # Evil.
+# Evil.
+ 42, 42, # Comments within arrays are fun.
+ # What about multiple # comments?
+ # Can you handle it?
+ #
+ # Evil.
+# Evil.
+# ] Did I fool you?
+] # Hopefully not.
+
+# Make sure the space between the datetime and "#" isn't lexed.
+dt = 1979-05-27T07:32:12-07:00 # c
+d = 1979-05-27 # Comment)"sv;
+ static constexpr auto comment_noeol = R"(# single comment without any eol characters)"sv;
+ static constexpr auto comment_tricky = R"([section]#attached comment
+#[notsection]
+one = "11"#cmt
+two = "22#"
+three = '#'
+
+four = """# no comment
+# nor this
+#also not comment"""#is_comment
+
+five = 5.5#66
+six = 6#7
+8 = "eight"
+#nine = 99
+ten = 10e2#1
+eleven = 1.11e1#23
+
+["hash#tag"]
+"#!" = "hash bang"
+arr3 = [ "#", '#', """###""" ]
+arr4 = [ 1,# 9, 9,
+2#,9
+,#9
+3#]
+,4]
+arr5 = [[[[#["#"],
+["#"]]]]#]
+]
+tbl1 = { "#" = '}#'}#}})"sv;
+
+#if UNICODE_LITERALS_OK
+
+ static constexpr auto comment_nonascii = R"(# ~ € ÿ ퟿  ￿ 𐀀 􏿿)"sv;
+
+#endif // UNICODE_LITERALS_OK
+
+ static constexpr auto datetime_datetime = R"(space = 1987-07-05 17:45:00Z
+lower = 1987-07-05t17:45:00z)"sv;
+ static constexpr auto datetime_local_date = R"(bestdayever = 1987-07-05)"sv;
+ static constexpr auto datetime_local_time = R"(besttimeever = 17:45:00
+milliseconds = 10:32:00.555)"sv;
+ static constexpr auto datetime_local = R"(local = 1987-07-05T17:45:00
+milli = 1977-12-21T10:32:00.555
+space = 1987-07-05 17:45:00)"sv;
+ static constexpr auto datetime_milliseconds = R"(utc1 = 1987-07-05T17:45:56.123Z
+utc2 = 1987-07-05T17:45:56.6Z
+wita1 = 1987-07-05T17:45:56.123+08:00
+wita2 = 1987-07-05T17:45:56.6+08:00)"sv;
+ static constexpr auto datetime_timezone = R"(utc = 1987-07-05T17:45:56Z
+pdt = 1987-07-05T17:45:56-05:00
+nzst = 1987-07-05T17:45:56+12:00
+nzdt = 1987-07-05T17:45:56+13:00 # DST)"sv;
+
+#if TOML_LANG_UNRELEASED
+
+ static constexpr auto datetime_no_seconds = R"(# Seconds are optional in date-time and time.
+without-seconds-1 = 13:37
+without-seconds-2 = 1979-05-27 07:32Z
+without-seconds-3 = 1979-05-27 07:32-07:00
+without-seconds-4 = 1979-05-27T07:32)"sv;
+
+#endif // TOML_LANG_UNRELEASED
+
+ static constexpr auto empty_file = R"()"sv;
+
+ static constexpr auto example = R"(best-day-ever = 1987-07-05T17:45:00Z
+
+[numtheory]
+boring = false
+perfection = [6, 28, 496])"sv;
+
+ static constexpr auto float_exponent = R"(lower = 3e2
+upper = 3E2
+neg = 3e-2
+pos = 3E+2
+zero = 3e0
+pointlower = 3.1e2
+pointupper = 3.1E2
+minustenth = -1E-1)"sv;
+ static constexpr auto float_float = R"(pi = 3.14
+pospi = +3.14
+negpi = -3.14
+zero-intpart = 0.123)"sv;
+ static constexpr auto float_inf_and_nan =
+ R"(# We don't encode +nan and -nan back with the signs; many languages don't
+# support a sign on NaN (it doesn't really make much sense).
+nan = nan
+nan_neg = -nan
+nan_plus = +nan
+infinity = inf
+infinity_neg = -inf
+infinity_plus = +inf)"sv;
+ static constexpr auto float_long = R"(longpi = 3.141592653589793
+neglongpi = -3.141592653589793)"sv;
+ static constexpr auto float_underscore = R"(before = 3_141.5927
+after = 3141.592_7
+exponent = 3e1_4)"sv;
+ static constexpr auto float_zero = R"(zero = 0.0
+signed-pos = +0.0
+signed-neg = -0.0
+exponent = 0e0
+exponent-two-0 = 0e00
+exponent-signed-pos = +0e0
+exponent-signed-neg = -0e0)"sv;
+
+ static constexpr auto implicit_and_explicit_after = R"([a.b.c]
+answer = 42
+
+[a]
+better = 43)"sv;
+ static constexpr auto implicit_and_explicit_before = R"([a]
+better = 43
+
+[a.b.c]
+answer = 42)"sv;
+ static constexpr auto implicit_groups = R"([a.b.c]
+answer = 42)"sv;
+
+ static constexpr auto inline_table_array = R"(people = [{first_name = "Bruce", last_name = "Springsteen"},
+ {first_name = "Eric", last_name = "Clapton"},
+ {first_name = "Bob", last_name = "Seger"}])"sv;
+ static constexpr auto inline_table_bool = R"(a = {a = true, b = false})"sv;
+ static constexpr auto inline_table_empty = R"(empty1 = {}
+empty2 = { }
+empty_in_array = [ { not_empty = 1 }, {} ]
+empty_in_array2 = [{},{not_empty=1}]
+many_empty = [{},{},{}]
+nested_empty = {"empty"={}})"sv;
+ static constexpr auto inline_table_end_in_bool =
+ R"(black = { python=">3.6", version=">=18.9b0", allow_prereleases=true })"sv;
+ static constexpr auto inline_table_inline_table = R"(name = { first = "Tom", last = "Preston-Werner" }
+point = { x = 1, y = 2 }
+simple = { a = 1 }
+str-key = { "a" = 1 }
+table-array = [{ "a" = 1 }, { "b" = 2 }])"sv;
+ static constexpr auto inline_table_multiline = R"(tbl_multiline = { a = 1, b = """
+multiline
+""", c = """and yet
+another line""", d = 4 })"sv;
+ static constexpr auto inline_table_nest = R"(tbl_tbl_empty = { tbl_0 = {} }
+tbl_tbl_val = { tbl_1 = { one = 1 } }
+tbl_arr_tbl = { arr_tbl = [ { one = 1 } ] }
+arr_tbl_tbl = [ { tbl = { one = 1 } } ]
+
+# Array-of-array-of-table is interesting because it can only
+# be represented in inline form.
+arr_arr_tbl_empty = [ [ {} ] ]
+arr_arr_tbl_val = [ [ { one = 1 } ] ]
+arr_arr_tbls = [ [ { one = 1 }, { two = 2 } ] ])"sv;
+
+#if !TOML_MSVC
+
+ static constexpr auto inline_table_key_dotted = R"(inline = {a.b = 42}
+
+many.dots.here.dot.dot.dot = {a.b.c = 1, a.b.d = 2}
+
+a = { a.b = 1 }
+b = { "a"."b" = 1 }
+c = { a . b = 1 }
+d = { 'a' . "b" = 1 }
+e = {a.b=1}
+
+[tbl]
+a.b.c = {d.e=1}
+
+[tbl.x]
+a.b.c = {d.e=1}
+
+[[arr]]
+t = {a.b=1}
+T = {a.b=1}
+
+[[arr]]
+t = {a.b=2}
+T = {a.b=2})"sv;
+
+#endif // !TOML_MSVC
+
+#if TOML_LANG_UNRELEASED
+
+ static constexpr auto inline_table_newline = R"(# TOML 1.1 supports newlines in inline tables and trailing commas.
+
+trailing-comma-1 = {
+ c = 1,
+}
+trailing-comma-2 = { c = 1, }
+
+tbl-1 = {
+ hello = "world",
+ 1 = 2,
+ arr = [1,
+ 2,
+ 3,
+ ],
+ tbl = {
+ k = 1,
+ }
+}
+
+tbl-2 = {
+ k = """
+ Hello
+ """
+})"sv;
+
+#endif // TOML_LANG_UNRELEASED
+
+ static constexpr auto integer_integer = R"(answer = 42
+posanswer = +42
+neganswer = -42
+zero = 0)"sv;
+ static constexpr auto integer_literals = R"(bin1 = 0b11010110
+bin2 = 0b1_0_1
+
+oct1 = 0o01234567
+oct2 = 0o755
+oct3 = 0o7_6_5
+
+hex1 = 0xDEADBEEF
+hex2 = 0xdeadbeef
+hex3 = 0xdead_beef
+hex4 = 0x00987)"sv;
+ static constexpr auto integer_long = R"(int64-max = 9223372036854775807
+int64-max-neg = -9223372036854775808)"sv;
+ static constexpr auto integer_underscore = R"(kilo = 1_000
+x = 1_1_1_1)"sv;
+ static constexpr auto integer_zero = R"(d1 = 0
+d2 = +0
+d3 = -0
+
+h1 = 0x0
+h2 = 0x00
+h3 = 0x00000
+
+o1 = 0o0
+a2 = 0o00
+a3 = 0o00000
+
+b1 = 0b0
+b2 = 0b00
+b3 = 0b00000)"sv;
+
+#if UNICODE_LITERALS_OK
+
+ static constexpr auto key_case_sensitive = R"(sectioN = "NN"
+
+[section]
+name = "lower"
+NAME = "upper"
+Name = "capitalized"
+
+[Section]
+name = "different section!!"
+"μ" = "greek small letter mu"
+"Μ" = "greek capital letter MU"
+M = "latin letter M")"sv;
+ static constexpr auto key_escapes = R"("\n" = "newline"
+"\u00c0" = "latin capital letter A with grave"
+"\"" = "just a quote"
+
+["backsp\b\b"]
+
+["\"quoted\""]
+quote = true
+
+["a.b"."\u00c0"])"sv;
+ static constexpr auto key_quoted_unicode = R"(
+"\u0000" = "null"
+'\u0000' = "different key"
+"\u0008 \u000c \U00000041 \u007f \u0080 \u00ff \ud7ff \ue000 \uffff \U00010000 \U0010ffff" = "escaped key"
+
+"~ € ÿ ퟿  ￿ 𐀀 􏿿" = "basic key"
+'l ~ € ÿ ퟿  ￿ 𐀀 􏿿' = "literal key")"sv;
+
+#endif // UNICODE_LITERALS_OK
+
+ static constexpr auto key_dotted_empty = R"(''.x = "empty.x"
+x."" = "x.empty"
+[a]
+"".'' = "empty.empty")"sv;
+ static constexpr auto key_dotted = R"(# Note: this file contains literal tab characters.
+
+name.first = "Arthur"
+"name".'last' = "Dent"
+
+many.dots.here.dot.dot.dot = 42
+
+# Space are ignored, and key parts can be quoted.
+count.a = 1
+count . b = 2
+"count"."c" = 3
+"count" . "d" = 4
+'count'.'e' = 5
+'count' . 'f' = 6
+"count".'g' = 7
+"count" . 'h' = 8
+count.'i' = 9
+count . 'j' = 10
+"count".k = 11
+"count" . l = 12
+
+[tbl]
+a.b.c = 42.666
+
+[a.few.dots]
+polka.dot = "again?"
+polka.dance-with = "Dot"
+
+[[arr]]
+a.b.c=1
+a.b.d=2
+
+[[arr]]
+a.b.c=3
+a.b.d=4)"sv;
+ static constexpr auto key_empty = R"("" = "blank")"sv;
+ static constexpr auto key_equals_nospace = R"(answer=42)"sv;
+ static constexpr auto key_numeric_dotted = R"(1.2 = 3)"sv;
+ static constexpr auto key_numeric = R"(1 = 1)"sv;
+ static constexpr auto key_quoted_dots = R"(plain = 1
+"with.dot" = 2
+
+[plain_table]
+plain = 3
+"with.dot" = 4
+
+[table.withdot]
+plain = 5
+"key.with.dots" = 6)"sv;
+ static constexpr auto key_space = R"(# Keep whitespace inside quotes keys at all positions.
+"a b" = 1
+" c d " = 2
+
+[ " tbl " ]
+"\ttab\ttab\t" = "tab")"sv;
+ static constexpr auto key_special_chars = R"("=~!@$^&*()_+-`1234567890[]|/?><.,;:'=" = 1)"sv;
+ static constexpr auto key_special_word = R"(false = false
+true = 1
+inf = 100000000
+nan = "ceci n'est pas un nombre")"sv;
+
+#if TOML_LANG_UNRELEASED && UNICODE_LITERALS_OK
+
+ static constexpr auto key_unicode = R"(# TOML 1.1 supports Unicode for bare keys.
+
+€ = 'Euro'
+😂 = "rofl"
+a‍b = "zwj"
+ÅÅ = "U+00C5 U+0041 U+030A"
+
+[中文]
+中文 = {中文 = "Chinese language"}
+
+[[tiếng-Việt]]
+tiəŋ˧˦.viət̚˧˨ʔ = "north"
+
+[[tiếng-Việt]]
+tiəŋ˦˧˥.viək̚˨˩ʔ = "central")"sv;
+
+#endif // TOML_LANG_UNRELEASED && UNICODE_LITERALS_OK
+
+ static constexpr auto newline_crlf = "os = \"DOS\"\r\n"
+ "newline = \"crlf\""sv;
+ static constexpr auto newline_lf = R"(os = "unix"
+newline = "lf")"sv;
+
+ static constexpr auto spec_array_0 = R"(integers = [ 1, 2, 3 ]
+colors = [ "red", "yellow", "green" ]
+nested_arrays_of_ints = [ [ 1, 2 ], [3, 4, 5] ]
+nested_mixed_array = [ [ 1, 2 ], ["a", "b", "c"] ]
+string_array = [ "all", 'strings', """are the same""", '''type''' ]
+
+# Mixed-type arrays are allowed
+numbers = [ 0.1, 0.2, 0.5, 1, 2, 5 ]
+contributors = [
+ "Foo Bar <foo@example.com>",
+ { name = "Baz Qux", email = "bazqux@example.com", url = "https://example.com/bazqux" }
+])"sv;
+ static constexpr auto spec_array_1 = R"(integers2 = [
+ 1, 2, 3
+]
+
+integers3 = [
+ 1,
+ 2, # this is ok
+])"sv;
+ static constexpr auto spec_array_of_tables_0 = R"([[products]]
+name = "Hammer"
+sku = 738594937
+
+[[products]] # empty table within the array
+
+[[products]]
+name = "Nail"
+sku = 284758393
+
+color = "gray")"sv;
+ static constexpr auto spec_array_of_tables_1 = R"([[fruits]]
+name = "apple"
+
+[fruits.physical] # subtable
+color = "red"
+shape = "round"
+
+[[fruits.varieties]] # nested array of tables
+name = "red delicious"
+
+[[fruits.varieties]]
+name = "granny smith"
+
+
+[[fruits]]
+name = "banana"
+
+[[fruits.varieties]]
+name = "plantain")"sv;
+ static constexpr auto spec_array_of_tables_2 = R"(points = [ { x = 1, y = 2, z = 3 },
+ { x = 7, y = 8, z = 9 },
+ { x = 2, y = 4, z = 8 } ])"sv;
+ static constexpr auto spec_boolean_0 = R"(bool1 = true
+bool2 = false)"sv;
+ static constexpr auto spec_comment_0 = R"(# This is a full-line comment
+key = "value" # This is a comment at the end of a line
+another = "# This is not a comment")"sv;
+ static constexpr auto spec_float_0 = R"(# fractional
+flt1 = +1.0
+flt2 = 3.1415
+flt3 = -0.01
+
+# exponent
+flt4 = 5e+22
+flt5 = 1e06
+flt6 = -2E-2
+
+# both
+flt7 = 6.626e-34)"sv;
+ static constexpr auto spec_float_1 = R"(flt8 = 224_617.445_991_228)"sv;
+ static constexpr auto spec_float_2 = R"(# infinity
+sf1 = inf # positive infinity
+sf2 = +inf # positive infinity
+sf3 = -inf # negative infinity
+
+# not a number
+sf4 = nan # actual sNaN/qNaN encoding is implementation-specific
+sf5 = +nan # same as `nan`
+sf6 = -nan # valid, actual encoding is implementation-specific)"sv;
+ static constexpr auto spec_inline_table_0 = R"(name = { first = "Tom", last = "Preston-Werner" }
+point = { x = 1, y = 2 }
+animal = { type.name = "pug" })"sv;
+ static constexpr auto spec_inline_table_1 = R"([name]
+first = "Tom"
+last = "Preston-Werner"
+
+[point]
+x = 1
+y = 2
+
+[animal]
+type.name = "pug")"sv;
+ static constexpr auto spec_inline_table_2 = R"([product]
+type = { name = "Nail" }
+# type.edible = false # INVALID)"sv;
+ static constexpr auto spec_inline_table_3 = R"([product]
+type.name = "Nail"
+# type = { edible = false } # INVALID)"sv;
+ static constexpr auto spec_integer_0 = R"(int1 = +99
+int2 = 42
+int3 = 0
+int4 = -17)"sv;
+ static constexpr auto spec_integer_1 = R"(int5 = 1_000
+int6 = 5_349_221
+int7 = 53_49_221 # Indian number system grouping
+int8 = 1_2_3_4_5 # VALID but discouraged)"sv;
+ static constexpr auto spec_integer_2 = R"(# hexadecimal with prefix `0x`
+hex1 = 0xDEADBEEF
+hex2 = 0xdeadbeef
+hex3 = 0xdead_beef
+
+# octal with prefix `0o`
+oct1 = 0o01234567
+oct2 = 0o755 # useful for Unix file permissions
+
+# binary with prefix `0b`
+bin1 = 0b11010110)"sv;
+ static constexpr auto spec_key_value_pair_0 = R"(key = "value")"sv;
+ static constexpr auto spec_keys_0 = R"(key = "value"
+bare_key = "value"
+bare-key = "value"
+1234 = "value")"sv;
+ static constexpr auto spec_keys_3 = R"(name = "Orange"
+physical.color = "orange"
+physical.shape = "round"
+site."google.com" = true)"sv;
+ static constexpr auto spec_keys_4 = R"(fruit.name = "banana" # this is best practice
+fruit. color = "yellow" # same as fruit.color
+fruit . flavor = "banana" # same as fruit.flavor)"sv;
+ static constexpr auto spec_keys_5 = R"(# VALID BUT DISCOURAGED
+
+apple.type = "fruit"
+orange.type = "fruit"
+
+apple.skin = "thin"
+orange.skin = "thick"
+
+apple.color = "red"
+orange.color = "orange")"sv;
+ static constexpr auto spec_keys_6 = R"(# RECOMMENDED
+
+apple.type = "fruit"
+apple.skin = "thin"
+apple.color = "red"
+
+orange.type = "fruit"
+orange.skin = "thick"
+orange.color = "orange")"sv;
+ static constexpr auto spec_keys_7 = R"(3.14159 = "pi")"sv;
+ static constexpr auto spec_local_date_0 = R"(ld1 = 1979-05-27)"sv;
+ static constexpr auto spec_local_date_time_0 = R"(ldt1 = 1979-05-27T07:32:00
+ldt2 = 1979-05-27T00:32:00.999999)"sv;
+ static constexpr auto spec_local_time_0 = R"(lt1 = 07:32:00
+lt2 = 00:32:00.999999)"sv;
+ static constexpr auto spec_offset_date_time_0 = R"(odt1 = 1979-05-27T07:32:00Z
+odt2 = 1979-05-27T00:32:00-07:00
+odt3 = 1979-05-27T00:32:00.999999-07:00)"sv;
+ static constexpr auto spec_offset_date_time_1 = R"(odt4 = 1979-05-27 07:32:00Z)"sv;
+ static constexpr auto spec_string_1 = R"(str1 = """
+Roses are red
+Violets are blue""")"sv;
+ static constexpr auto spec_string_2 =
+ R"(# On a Unix system, the above multi-line string will most likely be the same as:
+str2 = "Roses are red\nViolets are blue"
+
+# On a Windows system, it will most likely be equivalent to:
+str3 = "Roses are red\r\nViolets are blue")"sv;
+ static constexpr auto spec_string_3 = R"(# The following strings are byte-for-byte equivalent:
+str1 = "The quick brown fox jumps over the lazy dog."
+
+str2 = """
+The quick brown \
+
+
+ fox jumps over \
+ the lazy dog."""
+
+str3 = """\
+ The quick brown \
+ fox jumps over \
+ the lazy dog.\
+ """)"sv;
+ static constexpr auto spec_string_4 = R"(str4 = """Here are two quotation marks: "". Simple enough."""
+# str5 = """Here are three quotation marks: """.""" # INVALID
+str5 = """Here are three quotation marks: ""\"."""
+str6 = """Here are fifteen quotation marks: ""\"""\"""\"""\"""\"."""
+
+# "This," she said, "is just a pointless statement."
+str7 = """"This," she said, "is just a pointless statement."""")"sv;
+ static constexpr auto spec_string_5 = R"(# What you see is what you get.
+winpath = 'C:\Users\nodejs\templates'
+winpath2 = '\\ServerX\admin$\system32\'
+quoted = 'Tom "Dubs" Preston-Werner'
+regex = '<\i\c*\s*>')"sv;
+ static constexpr auto spec_string_6 = R"(regex2 = '''I [dw]on't need \d{2} apples'''
+lines = '''
+The first newline is
+trimmed in raw strings.
+ All other whitespace
+ is preserved.
+''')"sv;
+ static constexpr auto spec_string_7 = R"(quot15 = '''Here are fifteen quotation marks: """""""""""""""'''
+
+# apos15 = '''Here are fifteen apostrophes: '''''''''''''''''' # INVALID
+apos15 = "Here are fifteen apostrophes: '''''''''''''''"
+
+# 'That,' she said, 'is still pointless.'
+str = ''''That,' she said, 'is still pointless.'''')"sv;
+ static constexpr auto spec_table_0 = R"([table])"sv;
+ static constexpr auto spec_table_1 = R"([table-1]
+key1 = "some string"
+key2 = 123
+
+[table-2]
+key1 = "another string"
+key2 = 456)"sv;
+ static constexpr auto spec_table_2 = R"([dog."tater.man"]
+type.name = "pug")"sv;
+ static constexpr auto spec_table_4 = R"(# [x] you
+# [x.y] don't
+# [x.y.z] need these
+[x.y.z.w] # for this to work
+
+[x] # defining a super-table afterward is ok)"sv;
+ static constexpr auto spec_table_5 = R"(# VALID BUT DISCOURAGED
+[fruit.apple]
+[animal]
+[fruit.orange])"sv;
+ static constexpr auto spec_table_6 = R"(# RECOMMENDED
+[fruit.apple]
+[fruit.orange]
+[animal])"sv;
+ static constexpr auto spec_table_7 = R"(# Top-level table begins.
+name = "Fido"
+breed = "pug"
+
+# Top-level table ends.
+[owner]
+name = "Regina Dogman"
+member_since = 1999-08-04)"sv;
+ static constexpr auto spec_table_8 = R"(fruit.apple.color = "red"
+# Defines a table named fruit
+# Defines a table named fruit.apple
+
+fruit.apple.taste.sweet = true
+# Defines a table named fruit.apple.taste
+# fruit and fruit.apple were already created)"sv;
+ static constexpr auto spec_table_9 = R"([fruit]
+apple.color = "red"
+apple.taste.sweet = true
+
+# [fruit.apple] # INVALID
+# [fruit.apple.taste] # INVALID
+
+[fruit.apple.texture] # you can add sub-tables
+smooth = true)"sv;
+ static constexpr auto spec_example_1_compact = R"(#Useless spaces eliminated.
+title="TOML Example"
+[owner]
+name="Lance Uppercut"
+dob=1979-05-27T07:32:00-08:00#First class dates
+[database]
+server="192.168.1.1"
+ports=[8001,8001,8002]
+connection_max=5000
+enabled=true
+[servers]
+[servers.alpha]
+ip="10.0.0.1"
+dc="eqdc10"
+[servers.beta]
+ip="10.0.0.2"
+dc="eqdc10"
+[clients]
+data=[["gamma","delta"],[1,2]]
+hosts=[
+"alpha",
+"omega"
+])"sv;
+ static constexpr auto spec_example_1 = R"(# This is a TOML document. Boom.
+
+title = "TOML Example"
+
+[owner]
+name = "Lance Uppercut"
+dob = 1979-05-27T07:32:00-08:00 # First class dates? Why not?
+
+[database]
+server = "192.168.1.1"
+ports = [ 8001, 8001, 8002 ]
+connection_max = 5000
+enabled = true
+
+[servers]
+
+ # You can indent as you please. Tabs or spaces. TOML don't care.
+ [servers.alpha]
+ ip = "10.0.0.1"
+ dc = "eqdc10"
+
+ [servers.beta]
+ ip = "10.0.0.2"
+ dc = "eqdc10"
+
+[clients]
+data = [ ["gamma", "delta"], [1, 2] ]
+
+# Line breaks are OK when inside arrays
+hosts = [
+ "alpha",
+ "omega"
+])"sv;
+
+#if UNICODE_LITERALS_OK
+
+ static constexpr auto spec_keys_1 = R"("127.0.0.1" = "value"
+"character encoding" = "value"
+"ʎǝʞ" = "value"
+'key2' = "value"
+'quoted "value"' = "value")"sv;
+ static constexpr auto spec_string_0 =
+ R"(str = "I'm a string. \"You can quote me\". Name\tJos\u00E9\nLocation\tSF.")"sv;
+ static constexpr auto spec_table_3 = R"([a.b.c] # this is best practice
+[ d.e.f ] # same as [d.e.f]
+[ g . h . i ] # same as [g.h.i]
+[ j . "ʞ" . 'l' ] # same as [j."ʞ".'l'])"sv;
+
+#endif // UNICODE_LITERALS_OK
+
+ static constexpr auto string_double_quote_escape = R"(test = "\"one\"")"sv;
+ static constexpr auto string_empty = R"(answer = "")"sv;
+ static constexpr auto string_escaped_escape = R"(answer = "\\x64")"sv;
+ static constexpr auto string_escapes = R"(backspace = "This string has a \b backspace character."
+tab = "This string has a \t tab character."
+newline = "This string has a \n new line character."
+formfeed = "This string has a \f form feed character."
+carriage = "This string has a \r carriage return character."
+quote = "This string has a \" quote character."
+backslash = "This string has a \\ backslash character."
+notunicode1 = "This string does not have a unicode \\u escape."
+notunicode2 = "This string does not have a unicode \u005Cu escape."
+notunicode3 = "This string does not have a unicode \\u0075 escape."
+notunicode4 = "This string does not have a unicode \\\u0075 escape."
+delete = "This string has a \u007F delete control code."
+unitseparator = "This string has a \u001F unit separator control code.")"sv;
+ static constexpr auto string_multiline_escaped_crlf =
+ "# The following line should be an unescaped backslash followed by a Windows\r\n"
+ "# newline sequence (\"\\r\\n\")\r\n"
+ "0=\"\"\"\\\r\n"
+ "\"\"\""sv;
+ static constexpr auto string_multiline_quotes =
+ R"(# Make sure that quotes inside multiline strings are allowed, including right
+# after the opening '''/""" and before the closing '''/"""
+
+lit_one = ''''one quote''''
+lit_two = '''''two quotes'''''
+lit_one_space = ''' 'one quote' '''
+lit_two_space = ''' ''two quotes'' '''
+
+one = """"one quote""""
+two = """""two quotes"""""
+one_space = """ "one quote" """
+two_space = """ ""two quotes"" """
+
+mismatch1 = """aaa'''bbb"""
+mismatch2 = '''aaa"""bbb'''
+
+# Three opening """, then one escaped ", then two "" (allowed), and then three
+# closing """
+escaped = """lol\"""""")"sv;
+ static constexpr auto string_multiline =
+ "# NOTE: this file includes some literal tab characters.\n"
+ "\n"
+ "multiline_empty_one = \"\"\"\"\"\"\n"
+ "\n"
+ "# A newline immediately following the opening delimiter will be trimmed.\n"
+ "multiline_empty_two = \"\"\"\n"
+ "\"\"\"\n"
+ "\n"
+ "# \\ at the end of line trims newlines as well; note that last \\ is followed by\n"
+ "# two spaces, which are ignored.\n"
+ "multiline_empty_three = \"\"\"\\\n"
+ " \"\"\"\n"
+ "multiline_empty_four = \"\"\"\\\n"
+ " \\\n"
+ " \\ \n"
+ " \"\"\"\n"
+ "\n"
+ "equivalent_one = \"The quick brown fox jumps over the lazy dog.\"\n"
+ "equivalent_two = \"\"\"\n"
+ "The quick brown \\\n"
+ "\n"
+ "\n"
+ " fox jumps over \\\n"
+ " the lazy dog.\"\"\"\n"
+ "\n"
+ "equivalent_three = \"\"\"\\\n"
+ " The quick brown \\\n"
+ " fox jumps over \\\n"
+ " the lazy dog.\\\n"
+ " \"\"\"\n"
+ "\n"
+ "whitespace-after-bs = \"\"\"\\\n"
+ " The quick brown \\\n"
+ " fox jumps over \\ \n"
+ " the lazy dog.\\ \n"
+ " \"\"\"\n"
+ "\n"
+ "no-space = \"\"\"a\\\n"
+ " b\"\"\"\n"
+ "\n"
+ "# Has tab character.\n"
+ "keep-ws-before = \"\"\"a \\\n"
+ " b\"\"\"\n"
+ "\n"
+ "escape-bs-1 = \"\"\"a \\\\\n"
+ "b\"\"\"\n"
+ "\n"
+ "escape-bs-2 = \"\"\"a \\\\\\\n"
+ "b\"\"\"\n"
+ "\n"
+ "escape-bs-3 = \"\"\"a \\\\\\\\\n"
+ " b\"\"\""sv;
+ static constexpr auto string_nl = R"(nl_mid = "val\nue"
+nl_end = """value\n"""
+
+lit_nl_end = '''value\n'''
+lit_nl_mid = 'val\nue'
+lit_nl_uni = 'val\ue')"sv;
+ static constexpr auto string_raw_multiline = R"(# Single ' should be allowed.
+oneline = '''This string has a ' quote character.'''
+
+# A newline immediately following the opening delimiter will be trimmed.
+firstnl = '''
+This string has a ' quote character.'''
+
+# All other whitespace and newline characters remain intact.
+multiline = '''
+This string
+has ' a quote character
+and more than
+one newline
+in it.'''
+
+# Tab character in literal string does not need to be escaped
+multiline_with_tab = '''First line
+ Followed by a tab''')"sv;
+ static constexpr auto string_raw = R"(backspace = 'This string has a \b backspace character.'
+tab = 'This string has a \t tab character.'
+unescaped_tab = 'This string has an unescaped tab character.'
+newline = 'This string has a \n new line character.'
+formfeed = 'This string has a \f form feed character.'
+carriage = 'This string has a \r carriage return character.'
+slash = 'This string has a \/ slash character.'
+backslash = 'This string has a \\ backslash character.')"sv;
+ static constexpr auto string_simple = R"(answer = "You are not drinking enough whisky.")"sv;
+ static constexpr auto string_with_pound = R"(pound = "We see no # comments here."
+poundcomment = "But there are # some comments here." # Did I # mess you up?)"sv;
+
+#if TOML_LANG_UNRELEASED
+
+ static constexpr auto string_escape_esc = R"(esc = "\e There is no escape! \e")"sv;
+
+#endif // TOML_LANG_UNRELEASED
+
+#if UNICODE_LITERALS_OK
+
+ static constexpr auto string_escape_tricky = R"(end_esc = "String does not end here\" but ends here\\"
+lit_end_esc = 'String ends here\'
+
+multiline_unicode = """
+\u00a0"""
+
+multiline_not_unicode = """
+\\u0041"""
+
+multiline_end_esc = """When will it end? \"""...""\" should be here\""""
+
+lit_multiline_not_unicode = '''
+\u007f'''
+
+lit_multiline_end = '''There is no escape\''')"sv;
+ static constexpr auto string_quoted_unicode = R"(
+escaped_string = "\u0000 \u0008 \u000c \U00000041 \u007f \u0080 \u00ff \ud7ff \ue000 \uffff \U00010000 \U0010ffff"
+not_escaped_string = '\u0000 \u0008 \u000c \U00000041 \u007f \u0080 \u00ff \ud7ff \ue000 \uffff \U00010000 \U0010ffff'
+
+basic_string = "~ € ÿ ퟿  ￿ 𐀀 􏿿"
+literal_string = '~ € ÿ ퟿  ￿ 𐀀 􏿿')"sv;
+ static constexpr auto string_unicode_escape = R"(answer4 = "\u03B4"
+answer8 = "\U000003B4")"sv;
+ static constexpr auto string_unicode_literal = R"(answer = "δ")"sv;
+
+#endif // UNICODE_LITERALS_OK
+
+#if TOML_LANG_UNRELEASED && UNICODE_LITERALS_OK
+
+ static constexpr auto string_hex_escape = R"(# \x for the first 255 codepoints
+
+whitespace = "\x20 \x09 \x1b \x0d\x0a"
+bs = "\x7f"
+nul = "\x00"
+hello = "\x68\x65\x6c\x6c\x6f\x0a"
+higher-than-127 = "S\xf8rmirb\xe6ren"
+
+multiline = """
+\x20 \x09 \x1b \x0d\x0a
+\x7f
+\x00
+\x68\x65\x6c\x6c\x6f\x0a
+\x53\xF8\x72\x6D\x69\x72\x62\xE6\x72\x65\x6E
+"""
+
+# Not inside literals.
+literal = '\x20 \x09 \x0d\x0a'
+multiline-literal = '''
+\x20 \x09 \x0d\x0a
+''')"sv;
+
+#endif // TOML_LANG_UNRELEASED && UNICODE_LITERALS_OK
+
+ static constexpr auto table_array_implicit_and_explicit_after = R"([[a.b]]
+x = 1
+
+[a]
+y = 2)"sv;
+ static constexpr auto table_array_implicit = R"([[albums.songs]]
+name = "Glory Days")"sv;
+ static constexpr auto table_array_many = R"([[people]]
+first_name = "Bruce"
+last_name = "Springsteen"
+
+[[people]]
+first_name = "Eric"
+last_name = "Clapton"
+
+[[people]]
+first_name = "Bob"
+last_name = "Seger")"sv;
+ static constexpr auto table_array_nest = R"([[albums]]
+name = "Born to Run"
+
+ [[albums.songs]]
+ name = "Jungleland"
+
+ [[albums.songs]]
+ name = "Meeting Across the River"
+
+[[albums]]
+name = "Born in the USA"
+
+ [[albums.songs]]
+ name = "Glory Days"
+
+ [[albums.songs]]
+ name = "Dancing in the Dark")"sv;
+ static constexpr auto table_array_one = R"([[people]]
+first_name = "Bruce"
+last_name = "Springsteen")"sv;
+ static constexpr auto table_array_table_array = R"([[a]]
+ [[a.b]]
+ [a.b.c]
+ d = "val0"
+ [[a.b]]
+ [a.b.c]
+ d = "val1")"sv;
+ static constexpr auto table_array_within_dotted = R"([fruit]
+apple.color = "red"
+
+[[fruit.apple.seeds]]
+size = 2)"sv;
+ static constexpr auto table_empty_name = R"(['']
+x = 1
+
+["".a]
+x = 2
+
+[a.'']
+x = 3)"sv;
+ static constexpr auto table_empty = R"([a])"sv;
+ static constexpr auto table_keyword = R"([true]
+
+[false]
+
+[inf]
+
+[nan])"sv;
+ static constexpr auto table_no_eol = R"([table])"sv;
+ static constexpr auto table_sub_empty = R"([a]
+[a.b])"sv;
+ static constexpr auto table_sub = R"([a]
+key = 1
+
+# a.extend is a key inside the "a" table.
+[a.extend]
+key = 2
+
+[a.extend.more]
+key = 3)"sv;
+ static constexpr auto table_whitespace = R"(["valid key"])"sv;
+ static constexpr auto table_with_literal_string = R"(['a']
+[a.'"b"']
+[a.'"b"'.c]
+answer = 42 )"sv;
+ static constexpr auto table_with_pound = R"(["key#group"]
+answer = 42)"sv;
+ static constexpr auto table_with_single_quotes = R"(['a']
+[a.'b']
+[a.'b'.c]
+answer = 42 )"sv;
+ static constexpr auto table_without_super = R"(# [x] you
+# [x.y] don't
+# [x.y.z] need these
+[x.y.z.w] # for this to work
+[x] # defining a super-table afterwards is ok)"sv;
+
+#if UNICODE_LITERALS_OK
+
+ static constexpr auto table_names = R"([a.b.c]
+[a."b.c"]
+[a.'d.e']
+[a.' x ']
+[ d.e.f ]
+[ g . h . i ]
+[ j . "ʞ" . 'l' ]
+
+[x.1.2])"sv;
+
+#endif // UNICODE_LITERALS_OK
+}
+
+TEST_CASE("conformance - burntsushi/valid")
+{
+ SECTION("array-array")
+ {
+ parsing_should_succeed(FILE_LINE_ARGS,
+ array_array,
+ [](toml::table&& tbl) // array-array
+ {
+ const auto expected = toml::table{
+ { R"(comments)"sv,
+ toml::array{
+ 1,
+ 2,
+ } },
+ { R"(dates)"sv,
+ toml::array{
+ toml::date_time{ { 1987, 7, 5 }, { 17, 45 }, { 0, 0 } },
+ toml::date_time{ { 1979, 5, 27 }, { 7, 32 }, { 0, 0 } },
+ toml::date_time{ { 2006, 6, 1 }, { 11, 0 }, { 0, 0 } },
+ } },
+ { R"(floats)"sv,
+ toml::array{
+ 1.1,
+ 2.1,
+ 3.1,
+ } },
+ { R"(ints)"sv,
+ toml::array{
+ 1,
+ 2,
+ 3,
+ } },
+ { R"(strings)"sv,
+ toml::array{
+ R"(a)"sv,
+ R"(b)"sv,
+ R"(c)"sv,
+ } },
+ };
+ REQUIRE(tbl == expected);
+ });
+ }
+
+ SECTION("array-bool")
+ {
+ parsing_should_succeed(FILE_LINE_ARGS,
+ array_bool,
+ [](toml::table&& tbl) // array-bool
+ {
+ const auto expected = toml::table{
+ { R"(a)"sv,
+ toml::array{
+ true,
+ false,
+ } },
+ };
+ REQUIRE(tbl == expected);
+ });
+ }
+
+ SECTION("array-empty")
+ {
+ parsing_should_succeed(FILE_LINE_ARGS,
+ array_empty,
+ [](toml::table&& tbl) // array-empty
+ {
+ const auto expected = toml::table{
+ { R"(thevoid)"sv,
+ toml::array{
+ toml::inserter{ toml::array{
+ toml::inserter{ toml::array{
+ toml::inserter{ toml::array{
+ toml::inserter{ toml::array{} },
+ } },
+ } },
+ } },
+ } },
+ };
+ REQUIRE(tbl == expected);
+ });
+ }
+
+ SECTION("array-hetergeneous")
+ {
+ parsing_should_succeed(FILE_LINE_ARGS,
+ array_hetergeneous,
+ [](toml::table&& tbl) // array-hetergeneous
+ {
+ const auto expected = toml::table{
+ { R"(mixed)"sv,
+ toml::array{
+ toml::array{
+ 1,
+ 2,
+ },
+ toml::array{
+ R"(a)"sv,
+ R"(b)"sv,
+ },
+ toml::array{
+ 1.1,
+ 2.1,
+ },
+ } },
+ };
+ REQUIRE(tbl == expected);
+ });
+ }
+
+ SECTION("array-mixed-int-array")
+ {
+ parsing_should_succeed(FILE_LINE_ARGS,
+ array_mixed_int_array,
+ [](toml::table&& tbl) // array-mixed-int-array
+ {
+ const auto expected = toml::table{
+ { R"(arrays-and-ints)"sv,
+ toml::array{
+ 1,
+ toml::array{
+ R"(Arrays are not integers.)"sv,
+ },
+ } },
+ };
+ REQUIRE(tbl == expected);
+ });
+ }
+
+ SECTION("array-mixed-int-float")
+ {
+ parsing_should_succeed(FILE_LINE_ARGS,
+ array_mixed_int_float,
+ [](toml::table&& tbl) // array-mixed-int-float
+ {
+ const auto expected = toml::table{
+ { R"(ints-and-floats)"sv,
+ toml::array{
+ 1,
+ 1.1,
+ } },
+ };
+ REQUIRE(tbl == expected);
+ });
+ }
+
+ SECTION("array-mixed-int-string")
+ {
+ parsing_should_succeed(FILE_LINE_ARGS,
+ array_mixed_int_string,
+ [](toml::table&& tbl) // array-mixed-int-string
+ {
+ const auto expected = toml::table{
+ { R"(strings-and-ints)"sv,
+ toml::array{
+ R"(hi)"sv,
+ 42,
+ } },
+ };
+ REQUIRE(tbl == expected);
+ });
+ }
+
+ SECTION("array-mixed-string-table")
+ {
+ parsing_should_succeed(FILE_LINE_ARGS,
+ array_mixed_string_table,
+ [](toml::table&& tbl) // array-mixed-string-table
+ {
+ const auto expected = toml::table{
+ { R"(contributors)"sv,
+ toml::array{
+ R"(Foo Bar <foo@example.com>)"sv,
+ toml::table{
+ { R"(email)"sv, R"(bazqux@example.com)"sv },
+ { R"(name)"sv, R"(Baz Qux)"sv },
+ { R"(url)"sv, R"(https://example.com/bazqux)"sv },
+ },
+ } },
+ { R"(mixed)"sv,
+ toml::array{
+ toml::table{
+ { R"(k)"sv, R"(a)"sv },
+ },
+ R"(b)"sv,
+ 1,
+ } },
+ };
+ REQUIRE(tbl == expected);
+ });
+ }
+
+ SECTION("array-nested-double")
+ {
+ parsing_should_succeed(FILE_LINE_ARGS,
+ array_nested_double,
+ [](toml::table&& tbl) // array-nested-double
+ {
+ const auto expected = toml::table{
+ { R"(nest)"sv,
+ toml::array{
+ toml::inserter{ toml::array{
+ toml::array{
+ R"(a)"sv,
+ },
+ toml::array{
+ 1,
+ 2,
+ toml::array{
+ 3,
+ },
+ },
+ } },
+ } },
+ };
+ REQUIRE(tbl == expected);
+ });
+ }
+
+ SECTION("array-nested-inline-table")
+ {
+ parsing_should_succeed(FILE_LINE_ARGS,
+ array_nested_inline_table,
+ [](toml::table&& tbl) // array-nested-inline-table
+ {
+ const auto expected = toml::table{
+ { R"(a)"sv,
+ toml::array{
+ toml::table{
+ { R"(b)"sv, toml::table{} },
+ },
+ } },
+ };
+ REQUIRE(tbl == expected);
+ });
+ }
+
+ SECTION("array-nested")
+ {
+ parsing_should_succeed(FILE_LINE_ARGS,
+ array_nested,
+ [](toml::table&& tbl) // array-nested
+ {
+ const auto expected = toml::table{
+ { R"(nest)"sv,
+ toml::array{
+ toml::array{
+ R"(a)"sv,
+ },
+ toml::array{
+ R"(b)"sv,
+ },
+ } },
+ };
+ REQUIRE(tbl == expected);
+ });
+ }
+
+ SECTION("array-nospaces")
+ {
+ parsing_should_succeed(FILE_LINE_ARGS,
+ array_nospaces,
+ [](toml::table&& tbl) // array-nospaces
+ {
+ const auto expected = toml::table{
+ { R"(ints)"sv,
+ toml::array{
+ 1,
+ 2,
+ 3,
+ } },
+ };
+ REQUIRE(tbl == expected);
+ });
+ }
+
+ SECTION("array-string-quote-comma-2")
+ {
+ parsing_should_succeed(FILE_LINE_ARGS,
+ array_string_quote_comma_2,
+ [](toml::table&& tbl) // array-string-quote-comma-2
+ {
+ const auto expected = toml::table{
+ { R"(title)"sv,
+ toml::array{
+ R"( ", )"sv,
+ } },
+ };
+ REQUIRE(tbl == expected);
+ });
+ }
+
+ SECTION("array-string-quote-comma")
+ {
+ parsing_should_succeed(FILE_LINE_ARGS,
+ array_string_quote_comma,
+ [](toml::table&& tbl) // array-string-quote-comma
+ {
+ const auto expected = toml::table{
+ { R"(title)"sv,
+ toml::array{
+ R"(Client: "XXXX", Job: XXXX)"sv,
+ R"(Code: XXXX)"sv,
+ } },
+ };
+ REQUIRE(tbl == expected);
+ });
+ }
+
+ SECTION("array-string-with-comma-2")
+ {
+ parsing_should_succeed(FILE_LINE_ARGS,
+ array_string_with_comma_2,
+ [](toml::table&& tbl) // array-string-with-comma-2
+ {
+ const auto expected = toml::table{
+ { R"(title)"sv,
+ toml::array{
+ R"(Client: XXXX,
+Job: XXXX)"sv,
+ R"(Code: XXXX)"sv,
+ } },
+ };
+ REQUIRE(tbl == expected);
+ });
+ }
+
+ SECTION("array-string-with-comma")
+ {
+ parsing_should_succeed(FILE_LINE_ARGS,
+ array_string_with_comma,
+ [](toml::table&& tbl) // array-string-with-comma
+ {
+ const auto expected = toml::table{
+ { R"(title)"sv,
+ toml::array{
+ R"(Client: XXXX, Job: XXXX)"sv,
+ R"(Code: XXXX)"sv,
+ } },
+ };
+ REQUIRE(tbl == expected);
+ });
+ }
+
+ SECTION("array-strings")
+ {
+ parsing_should_succeed(FILE_LINE_ARGS,
+ array_strings,
+ [](toml::table&& tbl) // array-strings
+ {
+ const auto expected = toml::table{
+ { R"(string_array)"sv,
+ toml::array{
+ R"(all)"sv,
+ R"(strings)"sv,
+ R"(are the same)"sv,
+ R"(type)"sv,
+ } },
+ };
+ REQUIRE(tbl == expected);
+ });
+ }
+
+ SECTION("array-table-array-string-backslash")
+ {
+ parsing_should_succeed(FILE_LINE_ARGS,
+ array_table_array_string_backslash,
+ [](toml::table&& tbl) // array-table-array-string-backslash
+ {
+ const auto expected = toml::table{
+ { R"(foo)"sv,
+ toml::array{
+ toml::table{
+ { R"(bar)"sv, R"("{{baz}}")"sv },
+ },
+ } },
+ };
+ REQUIRE(tbl == expected);
+ });
+ }
+
+ SECTION("bool-bool")
+ {
+ parsing_should_succeed(FILE_LINE_ARGS,
+ bool_bool,
+ [](toml::table&& tbl) // bool-bool
+ {
+ const auto expected = toml::table{
+ { R"(f)"sv, false },
+ { R"(t)"sv, true },
+ };
+ REQUIRE(tbl == expected);
+ });
+ }
+
+ SECTION("comment-after-literal-no-ws")
+ {
+ parsing_should_succeed(FILE_LINE_ARGS,
+ comment_after_literal_no_ws,
+ [](toml::table&& tbl) // comment-after-literal-no-ws
+ {
+ const auto expected = toml::table{
+ { R"(false)"sv, false },
+ { R"(inf)"sv, std::numeric_limits<double>::infinity() },
+ { R"(nan)"sv, std::numeric_limits<double>::quiet_NaN() },
+ { R"(true)"sv, true },
+ };
+ REQUIRE(tbl == expected);
+ });
+ }
+
+ SECTION("comment-at-eof")
+ {
+ parsing_should_succeed(FILE_LINE_ARGS,
+ comment_at_eof,
+ [](toml::table&& tbl) // comment-at-eof
+ {
+ const auto expected = toml::table{
+ { R"(key)"sv, R"(value)"sv },
+ };
+ REQUIRE(tbl == expected);
+ });
+ }
+
+ SECTION("comment-at-eof2")
+ {
+ parsing_should_succeed(FILE_LINE_ARGS,
+ comment_at_eof2,
+ [](toml::table&& tbl) // comment-at-eof2
+ {
+ const auto expected = toml::table{
+ { R"(key)"sv, R"(value)"sv },
+ };
+ REQUIRE(tbl == expected);
+ });
+ }
+
+ SECTION("comment-everywhere")
+ {
+ parsing_should_succeed(
+ FILE_LINE_ARGS,
+ comment_everywhere,
+ [](toml::table&& tbl) // comment-everywhere
+ {
+ const auto expected = toml::table{
+ { R"(group)"sv,
+ toml::table{
+ { R"(answer)"sv, 42 },
+ { R"(d)"sv, toml::date{ 1979, 5, 27 } },
+ { R"(dt)"sv, toml::date_time{ { 1979, 5, 27 }, { 7, 32, 12 }, { -7, 0 } } },
+ { R"(more)"sv,
+ toml::array{
+ 42,
+ 42,
+ } },
+ } },
+ };
+ REQUIRE(tbl == expected);
+ });
+ }
+
+ SECTION("comment-noeol")
+ {
+ parsing_should_succeed(FILE_LINE_ARGS,
+ comment_noeol,
+ [](toml::table&& tbl) // comment-noeol
+ {
+ const auto expected = toml::table{};
+ REQUIRE(tbl == expected);
+ });
+ }
+
+ SECTION("comment-tricky")
+ {
+ parsing_should_succeed(FILE_LINE_ARGS,
+ comment_tricky,
+ [](toml::table&& tbl) // comment-tricky
+ {
+ const auto expected = toml::table{
+ { R"(hash#tag)"sv,
+ toml::table{
+ { R"(#!)"sv, R"(hash bang)"sv },
+ { R"(arr3)"sv,
+ toml::array{
+ R"(#)"sv,
+ R"(#)"sv,
+ R"(###)"sv,
+ } },
+ { R"(arr4)"sv,
+ toml::array{
+ 1,
+ 2,
+ 3,
+ 4,
+ } },
+ { R"(arr5)"sv,
+ toml::array{
+ toml::inserter{ toml::array{
+ toml::inserter{ toml::array{
+ toml::inserter{ toml::array{
+ toml::inserter{ toml::array{
+ R"(#)"sv,
+ } },
+ } },
+ } },
+ } },
+ } },
+ { R"(tbl1)"sv,
+ toml::table{
+ { R"(#)"sv, R"(}#)"sv },
+ } },
+ } },
+ { R"(section)"sv,
+ toml::table{
+ { R"(8)"sv, R"(eight)"sv },
+ { R"(eleven)"sv, 11.1 },
+ { R"(five)"sv, 5.5 },
+ { R"(four)"sv, R"(# no comment
+# nor this
+#also not comment)"sv },
+ { R"(one)"sv, R"(11)"sv },
+ { R"(six)"sv, 6 },
+ { R"(ten)"sv, 1000.0 },
+ { R"(three)"sv, R"(#)"sv },
+ { R"(two)"sv, R"(22#)"sv },
+ } },
+ };
+ REQUIRE(tbl == expected);
+ });
+ }
+
+#if UNICODE_LITERALS_OK
+
+ SECTION("comment-nonascii")
+ {
+ parsing_should_succeed(FILE_LINE_ARGS,
+ comment_nonascii,
+ [](toml::table&& tbl) // comment-nonascii
+ {
+ const auto expected = toml::table{};
+ REQUIRE(tbl == expected);
+ });
+ }
+
+#endif // UNICODE_LITERALS_OK
+
+ SECTION("datetime-datetime")
+ {
+ parsing_should_succeed(FILE_LINE_ARGS,
+ datetime_datetime,
+ [](toml::table&& tbl) // datetime-datetime
+ {
+ const auto expected = toml::table{
+ { R"(lower)"sv, toml::date_time{ { 1987, 7, 5 }, { 17, 45 }, { 0, 0 } } },
+ { R"(space)"sv, toml::date_time{ { 1987, 7, 5 }, { 17, 45 }, { 0, 0 } } },
+ };
+ REQUIRE(tbl == expected);
+ });
+ }
+
+ SECTION("datetime-local-date")
+ {
+ parsing_should_succeed(FILE_LINE_ARGS,
+ datetime_local_date,
+ [](toml::table&& tbl) // datetime-local-date
+ {
+ const auto expected = toml::table{
+ { R"(bestdayever)"sv, toml::date{ 1987, 7, 5 } },
+ };
+ REQUIRE(tbl == expected);
+ });
+ }
+
+ SECTION("datetime-local-time")
+ {
+ parsing_should_succeed(FILE_LINE_ARGS,
+ datetime_local_time,
+ [](toml::table&& tbl) // datetime-local-time
+ {
+ const auto expected = toml::table{
+ { R"(besttimeever)"sv, toml::time{ 17, 45 } },
+ { R"(milliseconds)"sv, toml::time{ 10, 32, 0, 555000000 } },
+ };
+ REQUIRE(tbl == expected);
+ });
+ }
+
+ SECTION("datetime-local")
+ {
+ parsing_should_succeed(FILE_LINE_ARGS,
+ datetime_local,
+ [](toml::table&& tbl) // datetime-local
+ {
+ const auto expected = toml::table{
+ { R"(local)"sv, toml::date_time{ { 1987, 7, 5 }, { 17, 45 } } },
+ { R"(milli)"sv, toml::date_time{ { 1977, 12, 21 }, { 10, 32, 0, 555000000 } } },
+ { R"(space)"sv, toml::date_time{ { 1987, 7, 5 }, { 17, 45 } } },
+ };
+ REQUIRE(tbl == expected);
+ });
+ }
+
+ SECTION("datetime-milliseconds")
+ {
+ parsing_should_succeed(
+ FILE_LINE_ARGS,
+ datetime_milliseconds,
+ [](toml::table&& tbl) // datetime-milliseconds
+ {
+ const auto expected = toml::table{
+ { R"(utc1)"sv, toml::date_time{ { 1987, 7, 5 }, { 17, 45, 56, 123000000 }, { 0, 0 } } },
+ { R"(utc2)"sv, toml::date_time{ { 1987, 7, 5 }, { 17, 45, 56, 600000000 }, { 0, 0 } } },
+ { R"(wita1)"sv, toml::date_time{ { 1987, 7, 5 }, { 17, 45, 56, 123000000 }, { 8, 0 } } },
+ { R"(wita2)"sv, toml::date_time{ { 1987, 7, 5 }, { 17, 45, 56, 600000000 }, { 8, 0 } } },
+ };
+ REQUIRE(tbl == expected);
+ });
+ }
+
+ SECTION("datetime-timezone")
+ {
+ parsing_should_succeed(FILE_LINE_ARGS,
+ datetime_timezone,
+ [](toml::table&& tbl) // datetime-timezone
+ {
+ const auto expected = toml::table{
+ { R"(nzdt)"sv, toml::date_time{ { 1987, 7, 5 }, { 17, 45, 56 }, { 13, 0 } } },
+ { R"(nzst)"sv, toml::date_time{ { 1987, 7, 5 }, { 17, 45, 56 }, { 12, 0 } } },
+ { R"(pdt)"sv, toml::date_time{ { 1987, 7, 5 }, { 17, 45, 56 }, { -5, 0 } } },
+ { R"(utc)"sv, toml::date_time{ { 1987, 7, 5 }, { 17, 45, 56 }, { 0, 0 } } },
+ };
+ REQUIRE(tbl == expected);
+ });
+ }
+
+#if TOML_LANG_UNRELEASED
+
+ SECTION("datetime-no-seconds")
+ {
+ parsing_should_succeed(
+ FILE_LINE_ARGS,
+ datetime_no_seconds,
+ [](toml::table&& tbl) // datetime-no-seconds
+ {
+ const auto expected = toml::table{
+ { R"(without-seconds-1)"sv, toml::time{ 13, 37 } },
+ { R"(without-seconds-2)"sv, toml::date_time{ { 1979, 5, 27 }, { 7, 32 }, { 0, 0 } } },
+ { R"(without-seconds-3)"sv, toml::date_time{ { 1979, 5, 27 }, { 7, 32 }, { -7, 0 } } },
+ { R"(without-seconds-4)"sv, toml::date_time{ { 1979, 5, 27 }, { 7, 32 } } },
+ };
+ REQUIRE(tbl == expected);
+ });
+ }
+
+#endif // TOML_LANG_UNRELEASED
+
+ SECTION("empty-file")
+ {
+ parsing_should_succeed(FILE_LINE_ARGS,
+ empty_file,
+ [](toml::table&& tbl) // empty-file
+ {
+ const auto expected = toml::table{};
+ REQUIRE(tbl == expected);
+ });
+ }
+
+ SECTION("example")
+ {
+ parsing_should_succeed(
+ FILE_LINE_ARGS,
+ example,
+ [](toml::table&& tbl) // example
+ {
+ const auto expected = toml::table{
+ { R"(best-day-ever)"sv, toml::date_time{ { 1987, 7, 5 }, { 17, 45 }, { 0, 0 } } },
+ { R"(numtheory)"sv,
+ toml::table{
+ { R"(boring)"sv, false },
+ { R"(perfection)"sv,
+ toml::array{
+ 6,
+ 28,
+ 496,
+ } },
+ } },
+ };
+ REQUIRE(tbl == expected);
+ });
+ }
+
+ SECTION("float-exponent")
+ {
+ parsing_should_succeed(FILE_LINE_ARGS,
+ float_exponent,
+ [](toml::table&& tbl) // float-exponent
+ {
+ const auto expected = toml::table{
+ { R"(lower)"sv, 300.0 }, { R"(minustenth)"sv, -0.1 },
+ { R"(neg)"sv, 0.03 }, { R"(pointlower)"sv, 310.0 },
+ { R"(pointupper)"sv, 310.0 }, { R"(pos)"sv, 300.0 },
+ { R"(upper)"sv, 300.0 }, { R"(zero)"sv, 3.0 },
+ };
+ REQUIRE(tbl == expected);
+ });
+ }
+
+ SECTION("float-float")
+ {
+ parsing_should_succeed(FILE_LINE_ARGS,
+ float_float,
+ [](toml::table&& tbl) // float-float
+ {
+ const auto expected = toml::table{
+ { R"(negpi)"sv, -3.14 },
+ { R"(pi)"sv, 3.14 },
+ { R"(pospi)"sv, 3.14 },
+ { R"(zero-intpart)"sv, 0.123 },
+ };
+ REQUIRE(tbl == expected);
+ });
+ }
+
+ SECTION("float-inf-and-nan")
+ {
+ parsing_should_succeed(FILE_LINE_ARGS,
+ float_inf_and_nan,
+ [](toml::table&& tbl) // float-inf-and-nan
+ {
+ const auto expected = toml::table{
+ { R"(infinity)"sv, std::numeric_limits<double>::infinity() },
+ { R"(infinity_neg)"sv, -std::numeric_limits<double>::infinity() },
+ { R"(infinity_plus)"sv, std::numeric_limits<double>::infinity() },
+ { R"(nan)"sv, std::numeric_limits<double>::quiet_NaN() },
+ { R"(nan_neg)"sv, std::numeric_limits<double>::quiet_NaN() },
+ { R"(nan_plus)"sv, std::numeric_limits<double>::quiet_NaN() },
+ };
+ REQUIRE(tbl == expected);
+ });
+ }
+
+ SECTION("float-long")
+ {
+ parsing_should_succeed(FILE_LINE_ARGS,
+ float_long,
+ [](toml::table&& tbl) // float-long
+ {
+ const auto expected = toml::table{
+ { R"(longpi)"sv, 3.141592653589793 },
+ { R"(neglongpi)"sv, -3.141592653589793 },
+ };
+ REQUIRE(tbl == expected);
+ });
+ }
+
+ SECTION("float-underscore")
+ {
+ parsing_should_succeed(FILE_LINE_ARGS,
+ float_underscore,
+ [](toml::table&& tbl) // float-underscore
+ {
+ const auto expected = toml::table{
+ { R"(after)"sv, 3141.5927 },
+ { R"(before)"sv, 3141.5927 },
+ { R"(exponent)"sv, 300000000000000.0 },
+ };
+ REQUIRE(tbl == expected);
+ });
+ }
+
+ SECTION("float-zero")
+ {
+ parsing_should_succeed(FILE_LINE_ARGS,
+ float_zero,
+ [](toml::table&& tbl) // float-zero
+ {
+ const auto expected = toml::table{
+ { R"(exponent)"sv, 0.0 },
+ { R"(exponent-signed-neg)"sv, -0.0 },
+ { R"(exponent-signed-pos)"sv, 0.0 },
+ { R"(exponent-two-0)"sv, 0.0 },
+ { R"(signed-neg)"sv, -0.0 },
+ { R"(signed-pos)"sv, 0.0 },
+ { R"(zero)"sv, 0.0 },
+ };
+ REQUIRE(tbl == expected);
+ });
+ }
+
+ SECTION("implicit-and-explicit-after")
+ {
+ parsing_should_succeed(FILE_LINE_ARGS,
+ implicit_and_explicit_after,
+ [](toml::table&& tbl) // implicit-and-explicit-after
+ {
+ const auto expected = toml::table{
+ { R"(a)"sv,
+ toml::table{
+ { R"(b)"sv,
+ toml::table{
+ { R"(c)"sv,
+ toml::table{
+ { R"(answer)"sv, 42 },
+ } },
+ } },
+ { R"(better)"sv, 43 },
+ } },
+ };
+ REQUIRE(tbl == expected);
+ });
+ }
+
+ SECTION("implicit-and-explicit-before")
+ {
+ parsing_should_succeed(FILE_LINE_ARGS,
+ implicit_and_explicit_before,
+ [](toml::table&& tbl) // implicit-and-explicit-before
+ {
+ const auto expected = toml::table{
+ { R"(a)"sv,
+ toml::table{
+ { R"(b)"sv,
+ toml::table{
+ { R"(c)"sv,
+ toml::table{
+ { R"(answer)"sv, 42 },
+ } },
+ } },
+ { R"(better)"sv, 43 },
+ } },
+ };
+ REQUIRE(tbl == expected);
+ });
+ }
+
+ SECTION("implicit-groups")
+ {
+ parsing_should_succeed(FILE_LINE_ARGS,
+ implicit_groups,
+ [](toml::table&& tbl) // implicit-groups
+ {
+ const auto expected = toml::table{
+ { R"(a)"sv,
+ toml::table{
+ { R"(b)"sv,
+ toml::table{
+ { R"(c)"sv,
+ toml::table{
+ { R"(answer)"sv, 42 },
+ } },
+ } },
+ } },
+ };
+ REQUIRE(tbl == expected);
+ });
+ }
+
+ SECTION("inline-table-array")
+ {
+ parsing_should_succeed(FILE_LINE_ARGS,
+ inline_table_array,
+ [](toml::table&& tbl) // inline-table-array
+ {
+ const auto expected = toml::table{
+ { R"(people)"sv,
+ toml::array{
+ toml::table{
+ { R"(first_name)"sv, R"(Bruce)"sv },
+ { R"(last_name)"sv, R"(Springsteen)"sv },
+ },
+ toml::table{
+ { R"(first_name)"sv, R"(Eric)"sv },
+ { R"(last_name)"sv, R"(Clapton)"sv },
+ },
+ toml::table{
+ { R"(first_name)"sv, R"(Bob)"sv },
+ { R"(last_name)"sv, R"(Seger)"sv },
+ },
+ } },
+ };
+ REQUIRE(tbl == expected);
+ });
+ }
+
+ SECTION("inline-table-bool")
+ {
+ parsing_should_succeed(FILE_LINE_ARGS,
+ inline_table_bool,
+ [](toml::table&& tbl) // inline-table-bool
+ {
+ const auto expected = toml::table{
+ { R"(a)"sv,
+ toml::table{
+ { R"(a)"sv, true },
+ { R"(b)"sv, false },
+ } },
+ };
+ REQUIRE(tbl == expected);
+ });
+ }
+
+ SECTION("inline-table-empty")
+ {
+ parsing_should_succeed(FILE_LINE_ARGS,
+ inline_table_empty,
+ [](toml::table&& tbl) // inline-table-empty
+ {
+ const auto expected = toml::table{
+ { R"(empty1)"sv, toml::table{} },
+ { R"(empty2)"sv, toml::table{} },
+ { R"(empty_in_array)"sv,
+ toml::array{
+ toml::table{
+ { R"(not_empty)"sv, 1 },
+ },
+ toml::table{},
+ } },
+ { R"(empty_in_array2)"sv,
+ toml::array{
+ toml::table{},
+ toml::table{
+ { R"(not_empty)"sv, 1 },
+ },
+ } },
+ { R"(many_empty)"sv,
+ toml::array{
+ toml::table{},
+ toml::table{},
+ toml::table{},
+ } },
+ { R"(nested_empty)"sv,
+ toml::table{
+ { R"(empty)"sv, toml::table{} },
+ } },
+ };
+ REQUIRE(tbl == expected);
+ });
+ }
+
+ SECTION("inline-table-end-in-bool")
+ {
+ parsing_should_succeed(FILE_LINE_ARGS,
+ inline_table_end_in_bool,
+ [](toml::table&& tbl) // inline-table-end-in-bool
+ {
+ const auto expected = toml::table{
+ { R"(black)"sv,
+ toml::table{
+ { R"(allow_prereleases)"sv, true },
+ { R"(python)"sv, R"(>3.6)"sv },
+ { R"(version)"sv, R"(>=18.9b0)"sv },
+ } },
+ };
+ REQUIRE(tbl == expected);
+ });
+ }
+
+ SECTION("inline-table-inline-table")
+ {
+ parsing_should_succeed(FILE_LINE_ARGS,
+ inline_table_inline_table,
+ [](toml::table&& tbl) // inline-table-inline-table
+ {
+ const auto expected = toml::table{
+ { R"(name)"sv,
+ toml::table{
+ { R"(first)"sv, R"(Tom)"sv },
+ { R"(last)"sv, R"(Preston-Werner)"sv },
+ } },
+ { R"(point)"sv,
+ toml::table{
+ { R"(x)"sv, 1 },
+ { R"(y)"sv, 2 },
+ } },
+ { R"(simple)"sv,
+ toml::table{
+ { R"(a)"sv, 1 },
+ } },
+ { R"(str-key)"sv,
+ toml::table{
+ { R"(a)"sv, 1 },
+ } },
+ { R"(table-array)"sv,
+ toml::array{
+ toml::table{
+ { R"(a)"sv, 1 },
+ },
+ toml::table{
+ { R"(b)"sv, 2 },
+ },
+ } },
+ };
+ REQUIRE(tbl == expected);
+ });
+ }
+
+ SECTION("inline-table-multiline")
+ {
+ parsing_should_succeed(FILE_LINE_ARGS,
+ inline_table_multiline,
+ [](toml::table&& tbl) // inline-table-multiline
+ {
+ const auto expected = toml::table{
+ { R"(tbl_multiline)"sv,
+ toml::table{
+ { R"(a)"sv, 1 },
+ { R"(b)"sv, R"(multiline
+)"sv },
+ { R"(c)"sv, R"(and yet
+another line)"sv },
+ { R"(d)"sv, 4 },
+ } },
+ };
+ REQUIRE(tbl == expected);
+ });
+ }
+
+ SECTION("inline-table-nest")
+ {
+ parsing_should_succeed(FILE_LINE_ARGS,
+ inline_table_nest,
+ [](toml::table&& tbl) // inline-table-nest
+ {
+ const auto expected = toml::table{
+ { R"(arr_arr_tbl_empty)"sv,
+ toml::array{
+ toml::inserter{ toml::array{
+ toml::table{},
+ } },
+ } },
+ { R"(arr_arr_tbl_val)"sv,
+ toml::array{
+ toml::inserter{ toml::array{
+ toml::table{
+ { R"(one)"sv, 1 },
+ },
+ } },
+ } },
+ { R"(arr_arr_tbls)"sv,
+ toml::array{
+ toml::inserter{ toml::array{
+ toml::table{
+ { R"(one)"sv, 1 },
+ },
+ toml::table{
+ { R"(two)"sv, 2 },
+ },
+ } },
+ } },
+ { R"(arr_tbl_tbl)"sv,
+ toml::array{
+ toml::table{
+ { R"(tbl)"sv,
+ toml::table{
+ { R"(one)"sv, 1 },
+ } },
+ },
+ } },
+ { R"(tbl_arr_tbl)"sv,
+ toml::table{
+ { R"(arr_tbl)"sv,
+ toml::array{
+ toml::table{
+ { R"(one)"sv, 1 },
+ },
+ } },
+ } },
+ { R"(tbl_tbl_empty)"sv,
+ toml::table{
+ { R"(tbl_0)"sv, toml::table{} },
+ } },
+ { R"(tbl_tbl_val)"sv,
+ toml::table{
+ { R"(tbl_1)"sv,
+ toml::table{
+ { R"(one)"sv, 1 },
+ } },
+ } },
+ };
+ REQUIRE(tbl == expected);
+ });
+ }
+
+#if !TOML_MSVC
+
+ SECTION("inline-table-key-dotted")
+ {
+ parsing_should_succeed(FILE_LINE_ARGS,
+ inline_table_key_dotted,
+ [](toml::table&& tbl) // inline-table-key-dotted
+ {
+ const auto expected = toml::table{
+ { R"(a)"sv,
+ toml::table{
+ { R"(a)"sv,
+ toml::table{
+ { R"(b)"sv, 1 },
+ } },
+ } },
+ { R"(arr)"sv,
+ toml::array{
+ toml::table{
+ { R"(T)"sv,
+ toml::table{
+ { R"(a)"sv,
+ toml::table{
+ { R"(b)"sv, 1 },
+ } },
+ } },
+ { R"(t)"sv,
+ toml::table{
+ { R"(a)"sv,
+ toml::table{
+ { R"(b)"sv, 1 },
+ } },
+ } },
+ },
+ toml::table{
+ { R"(T)"sv,
+ toml::table{
+ { R"(a)"sv,
+ toml::table{
+ { R"(b)"sv, 2 },
+ } },
+ } },
+ { R"(t)"sv,
+ toml::table{
+ { R"(a)"sv,
+ toml::table{
+ { R"(b)"sv, 2 },
+ } },
+ } },
+ },
+ } },
+ { R"(b)"sv,
+ toml::table{
+ { R"(a)"sv,
+ toml::table{
+ { R"(b)"sv, 1 },
+ } },
+ } },
+ { R"(c)"sv,
+ toml::table{
+ { R"(a)"sv,
+ toml::table{
+ { R"(b)"sv, 1 },
+ } },
+ } },
+ { R"(d)"sv,
+ toml::table{
+ { R"(a)"sv,
+ toml::table{
+ { R"(b)"sv, 1 },
+ } },
+ } },
+ { R"(e)"sv,
+ toml::table{
+ { R"(a)"sv,
+ toml::table{
+ { R"(b)"sv, 1 },
+ } },
+ } },
+ { R"(inline)"sv,
+ toml::table{
+ { R"(a)"sv,
+ toml::table{
+ { R"(b)"sv, 42 },
+ } },
+ } },
+ { R"(many)"sv,
+ toml::table{
+ { R"(dots)"sv,
+ toml::table{
+ { R"(here)"sv,
+ toml::table{
+ { R"(dot)"sv,
+ toml::table{
+ { R"(dot)"sv,
+ toml::table{
+ { R"(dot)"sv,
+ toml::table{
+ { R"(a)"sv,
+ toml::table{
+ { R"(b)"sv,
+ toml::table{
+ { R"(c)"sv, 1 },
+ { R"(d)"sv, 2 },
+ } },
+ } },
+ } },
+ } },
+ } },
+ } },
+ } },
+ } },
+ { R"(tbl)"sv,
+ toml::table{
+ { R"(a)"sv,
+ toml::table{
+ { R"(b)"sv,
+ toml::table{
+ { R"(c)"sv,
+ toml::table{
+ { R"(d)"sv,
+ toml::table{
+ { R"(e)"sv, 1 },
+ } },
+ } },
+ } },
+ } },
+ { R"(x)"sv,
+ toml::table{
+ { R"(a)"sv,
+ toml::table{
+ { R"(b)"sv,
+ toml::table{
+ { R"(c)"sv,
+ toml::table{
+ { R"(d)"sv,
+ toml::table{
+ { R"(e)"sv, 1 },
+ } },
+ } },
+ } },
+ } },
+ } },
+ } },
+ };
+ REQUIRE(tbl == expected);
+ });
+ }
+
+#endif // !TOML_MSVC
+
+#if TOML_LANG_UNRELEASED
+
+ SECTION("inline-table-newline")
+ {
+ parsing_should_succeed(FILE_LINE_ARGS,
+ inline_table_newline,
+ [](toml::table&& tbl) // inline-table-newline
+ {
+ const auto expected = toml::table{
+ { R"(tbl-1)"sv,
+ toml::table{
+ { R"(1)"sv, 2 },
+ { R"(arr)"sv,
+ toml::array{
+ 1,
+ 2,
+ 3,
+ } },
+ { R"(hello)"sv, R"(world)"sv },
+ { R"(tbl)"sv,
+ toml::table{
+ { R"(k)"sv, 1 },
+ } },
+ } },
+ { R"(tbl-2)"sv,
+ toml::table{
+ { R"(k)"sv, R"( Hello
+ )"sv },
+ } },
+ { R"(trailing-comma-1)"sv,
+ toml::table{
+ { R"(c)"sv, 1 },
+ } },
+ { R"(trailing-comma-2)"sv,
+ toml::table{
+ { R"(c)"sv, 1 },
+ } },
+ };
+ REQUIRE(tbl == expected);
+ });
+ }
+
+#endif // TOML_LANG_UNRELEASED
+
+ SECTION("integer-integer")
+ {
+ parsing_should_succeed(FILE_LINE_ARGS,
+ integer_integer,
+ [](toml::table&& tbl) // integer-integer
+ {
+ const auto expected = toml::table{
+ { R"(answer)"sv, 42 },
+ { R"(neganswer)"sv, -42 },
+ { R"(posanswer)"sv, 42 },
+ { R"(zero)"sv, 0 },
+ };
+ REQUIRE(tbl == expected);
+ });
+ }
+
+ SECTION("integer-literals")
+ {
+ parsing_should_succeed(
+ FILE_LINE_ARGS,
+ integer_literals,
+ [](toml::table&& tbl) // integer-literals
+ {
+ const auto expected = toml::table{
+ { R"(bin1)"sv, 214 }, { R"(bin2)"sv, 5 }, { R"(hex1)"sv, 3735928559 },
+ { R"(hex2)"sv, 3735928559 }, { R"(hex3)"sv, 3735928559 }, { R"(hex4)"sv, 2439 },
+ { R"(oct1)"sv, 342391 }, { R"(oct2)"sv, 493 }, { R"(oct3)"sv, 501 },
+ };
+ REQUIRE(tbl == expected);
+ });
+ }
+
+ SECTION("integer-long")
+ {
+ parsing_should_succeed(FILE_LINE_ARGS,
+ integer_long,
+ [](toml::table&& tbl) // integer-long
+ {
+ const auto expected = toml::table{
+ { R"(int64-max)"sv, std::numeric_limits<int64_t>::max() },
+ { R"(int64-max-neg)"sv, std::numeric_limits<int64_t>::min() },
+ };
+ REQUIRE(tbl == expected);
+ });
+ }
+
+ SECTION("integer-underscore")
+ {
+ parsing_should_succeed(FILE_LINE_ARGS,
+ integer_underscore,
+ [](toml::table&& tbl) // integer-underscore
+ {
+ const auto expected = toml::table{
+ { R"(kilo)"sv, 1000 },
+ { R"(x)"sv, 1111 },
+ };
+ REQUIRE(tbl == expected);
+ });
+ }
+
+ SECTION("integer-zero")
+ {
+ parsing_should_succeed(FILE_LINE_ARGS,
+ integer_zero,
+ [](toml::table&& tbl) // integer-zero
+ {
+ const auto expected = toml::table{
+ { R"(a2)"sv, 0 }, { R"(a3)"sv, 0 }, { R"(b1)"sv, 0 }, { R"(b2)"sv, 0 },
+ { R"(b3)"sv, 0 }, { R"(d1)"sv, 0 }, { R"(d2)"sv, 0 }, { R"(d3)"sv, 0 },
+ { R"(h1)"sv, 0 }, { R"(h2)"sv, 0 }, { R"(h3)"sv, 0 }, { R"(o1)"sv, 0 },
+ };
+ REQUIRE(tbl == expected);
+ });
+ }
+
+#if UNICODE_LITERALS_OK
+
+ SECTION("key-case-sensitive")
+ {
+ parsing_should_succeed(FILE_LINE_ARGS,
+ key_case_sensitive,
+ [](toml::table&& tbl) // key-case-sensitive
+ {
+ const auto expected = toml::table{
+ { R"(Section)"sv,
+ toml::table{
+ { R"(M)"sv, R"(latin letter M)"sv },
+ { R"(name)"sv, R"(different section!!)"sv },
+ { R"(Μ)"sv, R"(greek capital letter MU)"sv },
+ { R"(μ)"sv, R"(greek small letter mu)"sv },
+ } },
+ { R"(sectioN)"sv, R"(NN)"sv },
+ { R"(section)"sv,
+ toml::table{
+ { R"(NAME)"sv, R"(upper)"sv },
+ { R"(Name)"sv, R"(capitalized)"sv },
+ { R"(name)"sv, R"(lower)"sv },
+ } },
+ };
+ REQUIRE(tbl == expected);
+ });
+ }
+
+ SECTION("key-escapes")
+ {
+ parsing_should_succeed(FILE_LINE_ARGS,
+ key_escapes,
+ [](toml::table&& tbl) // key-escapes
+ {
+ const auto expected = toml::table{
+ { R"(
+)"sv,
+ R"(newline)"sv },
+ { R"(")"sv, R"(just a quote)"sv },
+ { R"("quoted")"sv,
+ toml::table{
+ { R"(quote)"sv, true },
+ } },
+ { R"(a.b)"sv,
+ toml::table{
+ { R"(À)"sv, toml::table{} },
+ } },
+ { "backsp\x08\x08"sv, toml::table{} },
+ { R"(À)"sv, R"(latin capital letter A with grave)"sv },
+ };
+ REQUIRE(tbl == expected);
+ });
+ }
+
+ SECTION("key-quoted-unicode")
+ {
+ parsing_should_succeed(FILE_LINE_ARGS,
+ key_quoted_unicode,
+ [](toml::table&& tbl) // key-quoted-unicode
+ {
+ const auto expected = toml::table{
+ { "\x00"sv, R"(null)"sv },
+ { R"(\u0000)"sv, R"(different key)"sv },
+ { "\x08 \f A \x7F € ÿ ퟿  ￿ 𐀀 􏿿"sv, R"(escaped key)"sv },
+ { R"(~ € ÿ ퟿  ￿ 𐀀 􏿿)"sv, R"(basic key)"sv },
+ { R"(l ~ € ÿ ퟿  ￿ 𐀀 􏿿)"sv, R"(literal key)"sv },
+ };
+ REQUIRE(tbl == expected);
+ });
+ }
+
+#endif // UNICODE_LITERALS_OK
+
+ SECTION("key-dotted-empty")
+ {
+ parsing_should_succeed(FILE_LINE_ARGS,
+ key_dotted_empty,
+ [](toml::table&& tbl) // key-dotted-empty
+ {
+ const auto expected = toml::table{
+ { ""sv,
+ toml::table{
+ { R"(x)"sv, R"(empty.x)"sv },
+ } },
+ { R"(a)"sv,
+ toml::table{
+ { ""sv,
+ toml::table{
+ { ""sv, R"(empty.empty)"sv },
+ } },
+ } },
+ { R"(x)"sv,
+ toml::table{
+ { ""sv, R"(x.empty)"sv },
+ } },
+ };
+ REQUIRE(tbl == expected);
+ });
+ }
+
+ SECTION("key-dotted")
+ {
+ parsing_should_succeed(FILE_LINE_ARGS,
+ key_dotted,
+ [](toml::table&& tbl) // key-dotted
+ {
+ const auto expected = toml::table{
+ { R"(a)"sv,
+ toml::table{
+ { R"(few)"sv,
+ toml::table{
+ { R"(dots)"sv,
+ toml::table{
+ { R"(polka)"sv,
+ toml::table{
+ { R"(dance-with)"sv, R"(Dot)"sv },
+ { R"(dot)"sv, R"(again?)"sv },
+ } },
+ } },
+ } },
+ } },
+ { R"(arr)"sv,
+ toml::array{
+ toml::table{
+ { R"(a)"sv,
+ toml::table{
+ { R"(b)"sv,
+ toml::table{
+ { R"(c)"sv, 1 },
+ { R"(d)"sv, 2 },
+ } },
+ } },
+ },
+ toml::table{
+ { R"(a)"sv,
+ toml::table{
+ { R"(b)"sv,
+ toml::table{
+ { R"(c)"sv, 3 },
+ { R"(d)"sv, 4 },
+ } },
+ } },
+ },
+ } },
+ { R"(count)"sv,
+ toml::table{
+ { R"(a)"sv, 1 },
+ { R"(b)"sv, 2 },
+ { R"(c)"sv, 3 },
+ { R"(d)"sv, 4 },
+ { R"(e)"sv, 5 },
+ { R"(f)"sv, 6 },
+ { R"(g)"sv, 7 },
+ { R"(h)"sv, 8 },
+ { R"(i)"sv, 9 },
+ { R"(j)"sv, 10 },
+ { R"(k)"sv, 11 },
+ { R"(l)"sv, 12 },
+ } },
+ { R"(many)"sv,
+ toml::table{
+ { R"(dots)"sv,
+ toml::table{
+ { R"(here)"sv,
+ toml::table{
+ { R"(dot)"sv,
+ toml::table{
+ { R"(dot)"sv,
+ toml::table{
+ { R"(dot)"sv, 42 },
+ } },
+ } },
+ } },
+ } },
+ } },
+ { R"(name)"sv,
+ toml::table{
+ { R"(first)"sv, R"(Arthur)"sv },
+ { R"(last)"sv, R"(Dent)"sv },
+ } },
+ { R"(tbl)"sv,
+ toml::table{
+ { R"(a)"sv,
+ toml::table{
+ { R"(b)"sv,
+ toml::table{
+ { R"(c)"sv, 42.666 },
+ } },
+ } },
+ } },
+ };
+ REQUIRE(tbl == expected);
+ });
+ }
+
+ SECTION("key-empty")
+ {
+ parsing_should_succeed(FILE_LINE_ARGS,
+ key_empty,
+ [](toml::table&& tbl) // key-empty
+ {
+ const auto expected = toml::table{
+ { ""sv, R"(blank)"sv },
+ };
+ REQUIRE(tbl == expected);
+ });
+ }
+
+ SECTION("key-equals-nospace")
+ {
+ parsing_should_succeed(FILE_LINE_ARGS,
+ key_equals_nospace,
+ [](toml::table&& tbl) // key-equals-nospace
+ {
+ const auto expected = toml::table{
+ { R"(answer)"sv, 42 },
+ };
+ REQUIRE(tbl == expected);
+ });
+ }
+
+ SECTION("key-numeric-dotted")
+ {
+ parsing_should_succeed(FILE_LINE_ARGS,
+ key_numeric_dotted,
+ [](toml::table&& tbl) // key-numeric-dotted
+ {
+ const auto expected = toml::table{
+ { R"(1)"sv,
+ toml::table{
+ { R"(2)"sv, 3 },
+ } },
+ };
+ REQUIRE(tbl == expected);
+ });
+ }
+
+ SECTION("key-numeric")
+ {
+ parsing_should_succeed(FILE_LINE_ARGS,
+ key_numeric,
+ [](toml::table&& tbl) // key-numeric
+ {
+ const auto expected = toml::table{
+ { R"(1)"sv, 1 },
+ };
+ REQUIRE(tbl == expected);
+ });
+ }
+
+ SECTION("key-quoted-dots")
+ {
+ parsing_should_succeed(FILE_LINE_ARGS,
+ key_quoted_dots,
+ [](toml::table&& tbl) // key-quoted-dots
+ {
+ const auto expected = toml::table{
+ { R"(plain)"sv, 1 },
+ { R"(plain_table)"sv,
+ toml::table{
+ { R"(plain)"sv, 3 },
+ { R"(with.dot)"sv, 4 },
+ } },
+ { R"(table)"sv,
+ toml::table{
+ { R"(withdot)"sv,
+ toml::table{
+ { R"(key.with.dots)"sv, 6 },
+ { R"(plain)"sv, 5 },
+ } },
+ } },
+ { R"(with.dot)"sv, 2 },
+ };
+ REQUIRE(tbl == expected);
+ });
+ }
+
+ SECTION("key-space")
+ {
+ parsing_should_succeed(FILE_LINE_ARGS,
+ key_space,
+ [](toml::table&& tbl) // key-space
+ {
+ const auto expected = toml::table{
+ { R"( c d )"sv, 2 },
+ { R"( tbl )"sv,
+ toml::table{
+ { R"( tab tab )"sv, R"(tab)"sv },
+ } },
+ { R"(a b)"sv, 1 },
+ };
+ REQUIRE(tbl == expected);
+ });
+ }
+
+ SECTION("key-special-chars")
+ {
+ parsing_should_succeed(FILE_LINE_ARGS,
+ key_special_chars,
+ [](toml::table&& tbl) // key-special-chars
+ {
+ const auto expected = toml::table{
+ { R"(=~!@$^&*()_+-`1234567890[]|/?><.,;:'=)"sv, 1 },
+ };
+ REQUIRE(tbl == expected);
+ });
+ }
+
+ SECTION("key-special-word")
+ {
+ parsing_should_succeed(FILE_LINE_ARGS,
+ key_special_word,
+ [](toml::table&& tbl) // key-special-word
+ {
+ const auto expected = toml::table{
+ { R"(false)"sv, false },
+ { R"(inf)"sv, 100000000 },
+ { R"(nan)"sv, R"(ceci n'est pas un nombre)"sv },
+ { R"(true)"sv, 1 },
+ };
+ REQUIRE(tbl == expected);
+ });
+ }
+
+#if TOML_LANG_UNRELEASED && UNICODE_LITERALS_OK
+
+ SECTION("key-unicode")
+ {
+ parsing_should_succeed(FILE_LINE_ARGS,
+ key_unicode,
+ [](toml::table&& tbl) // key-unicode
+ {
+ const auto expected = toml::table{
+ { R"(a‍b)"sv, R"(zwj)"sv },
+ { R"(tiếng-Việt)"sv,
+ toml::array{
+ toml::table{
+ { R"(tiəŋ˧˦)"sv,
+ toml::table{
+ { R"(viət̚˧˨ʔ)"sv, R"(north)"sv },
+ } },
+ },
+ toml::table{
+ { R"(tiəŋ˦˧˥)"sv,
+ toml::table{
+ { R"(viək̚˨˩ʔ)"sv, R"(central)"sv },
+ } },
+ },
+ } },
+ { R"(ÅÅ)"sv, R"(U+00C5 U+0041 U+030A)"sv },
+ { R"(€)"sv, R"(Euro)"sv },
+ { R"(中文)"sv,
+ toml::table{
+ { R"(中文)"sv,
+ toml::table{
+ { R"(中文)"sv, R"(Chinese language)"sv },
+ } },
+ } },
+ { R"(😂)"sv, R"(rofl)"sv },
+ };
+ REQUIRE(tbl == expected);
+ });
+ }
+
+#endif // TOML_LANG_UNRELEASED && UNICODE_LITERALS_OK
+
+ SECTION("newline-crlf")
+ {
+ parsing_should_succeed(FILE_LINE_ARGS,
+ newline_crlf,
+ [](toml::table&& tbl) // newline-crlf
+ {
+ const auto expected = toml::table{
+ { R"(newline)"sv, R"(crlf)"sv },
+ { R"(os)"sv, R"(DOS)"sv },
+ };
+ REQUIRE(tbl == expected);
+ });
+ }
+
+ SECTION("newline-lf")
+ {
+ parsing_should_succeed(FILE_LINE_ARGS,
+ newline_lf,
+ [](toml::table&& tbl) // newline-lf
+ {
+ const auto expected = toml::table{
+ { R"(newline)"sv, R"(lf)"sv },
+ { R"(os)"sv, R"(unix)"sv },
+ };
+ REQUIRE(tbl == expected);
+ });
+ }
+
+ SECTION("spec-array-0")
+ {
+ parsing_should_succeed(FILE_LINE_ARGS,
+ spec_array_0,
+ [](toml::table&& tbl) // spec-array-0
+ {
+ const auto expected = toml::table{
+ { R"(colors)"sv,
+ toml::array{
+ R"(red)"sv,
+ R"(yellow)"sv,
+ R"(green)"sv,
+ } },
+ { R"(contributors)"sv,
+ toml::array{
+ R"(Foo Bar <foo@example.com>)"sv,
+ toml::table{
+ { R"(email)"sv, R"(bazqux@example.com)"sv },
+ { R"(name)"sv, R"(Baz Qux)"sv },
+ { R"(url)"sv, R"(https://example.com/bazqux)"sv },
+ },
+ } },
+ { R"(integers)"sv,
+ toml::array{
+ 1,
+ 2,
+ 3,
+ } },
+ { R"(nested_arrays_of_ints)"sv,
+ toml::array{
+ toml::array{
+ 1,
+ 2,
+ },
+ toml::array{
+ 3,
+ 4,
+ 5,
+ },
+ } },
+ { R"(nested_mixed_array)"sv,
+ toml::array{
+ toml::array{
+ 1,
+ 2,
+ },
+ toml::array{
+ R"(a)"sv,
+ R"(b)"sv,
+ R"(c)"sv,
+ },
+ } },
+ { R"(numbers)"sv,
+ toml::array{
+ 0.1,
+ 0.2,
+ 0.5,
+ 1,
+ 2,
+ 5,
+ } },
+ { R"(string_array)"sv,
+ toml::array{
+ R"(all)"sv,
+ R"(strings)"sv,
+ R"(are the same)"sv,
+ R"(type)"sv,
+ } },
+ };
+ REQUIRE(tbl == expected);
+ });
+ }
+
+ SECTION("spec-array-1")
+ {
+ parsing_should_succeed(FILE_LINE_ARGS,
+ spec_array_1,
+ [](toml::table&& tbl) // spec-array-1
+ {
+ const auto expected = toml::table{
+ { R"(integers2)"sv,
+ toml::array{
+ 1,
+ 2,
+ 3,
+ } },
+ { R"(integers3)"sv,
+ toml::array{
+ 1,
+ 2,
+ } },
+ };
+ REQUIRE(tbl == expected);
+ });
+ }
+
+ SECTION("spec-array-of-tables-0")
+ {
+ parsing_should_succeed(FILE_LINE_ARGS,
+ spec_array_of_tables_0,
+ [](toml::table&& tbl) // spec-array-of-tables-0
+ {
+ const auto expected = toml::table{
+ { R"(products)"sv,
+ toml::array{
+ toml::table{
+ { R"(name)"sv, R"(Hammer)"sv },
+ { R"(sku)"sv, 738594937 },
+ },
+ toml::table{},
+ toml::table{
+ { R"(color)"sv, R"(gray)"sv },
+ { R"(name)"sv, R"(Nail)"sv },
+ { R"(sku)"sv, 284758393 },
+ },
+ } },
+ };
+ REQUIRE(tbl == expected);
+ });
+ }
+
+ SECTION("spec-array-of-tables-1")
+ {
+ parsing_should_succeed(FILE_LINE_ARGS,
+ spec_array_of_tables_1,
+ [](toml::table&& tbl) // spec-array-of-tables-1
+ {
+ const auto expected = toml::table{
+ { R"(fruits)"sv,
+ toml::array{
+ toml::table{
+ { R"(name)"sv, R"(apple)"sv },
+ { R"(physical)"sv,
+ toml::table{
+ { R"(color)"sv, R"(red)"sv },
+ { R"(shape)"sv, R"(round)"sv },
+ } },
+ { R"(varieties)"sv,
+ toml::array{
+ toml::table{
+ { R"(name)"sv, R"(red delicious)"sv },
+ },
+ toml::table{
+ { R"(name)"sv, R"(granny smith)"sv },
+ },
+ } },
+ },
+ toml::table{
+ { R"(name)"sv, R"(banana)"sv },
+ { R"(varieties)"sv,
+ toml::array{
+ toml::table{
+ { R"(name)"sv, R"(plantain)"sv },
+ },
+ } },
+ },
+ } },
+ };
+ REQUIRE(tbl == expected);
+ });
+ }
+
+ SECTION("spec-array-of-tables-2")
+ {
+ parsing_should_succeed(FILE_LINE_ARGS,
+ spec_array_of_tables_2,
+ [](toml::table&& tbl) // spec-array-of-tables-2
+ {
+ const auto expected = toml::table{
+ { R"(points)"sv,
+ toml::array{
+ toml::table{
+ { R"(x)"sv, 1 },
+ { R"(y)"sv, 2 },
+ { R"(z)"sv, 3 },
+ },
+ toml::table{
+ { R"(x)"sv, 7 },
+ { R"(y)"sv, 8 },
+ { R"(z)"sv, 9 },
+ },
+ toml::table{
+ { R"(x)"sv, 2 },
+ { R"(y)"sv, 4 },
+ { R"(z)"sv, 8 },
+ },
+ } },
+ };
+ REQUIRE(tbl == expected);
+ });
+ }
+
+ SECTION("spec-boolean-0")
+ {
+ parsing_should_succeed(FILE_LINE_ARGS,
+ spec_boolean_0,
+ [](toml::table&& tbl) // spec-boolean-0
+ {
+ const auto expected = toml::table{
+ { R"(bool1)"sv, true },
+ { R"(bool2)"sv, false },
+ };
+ REQUIRE(tbl == expected);
+ });
+ }
+
+ SECTION("spec-comment-0")
+ {
+ parsing_should_succeed(FILE_LINE_ARGS,
+ spec_comment_0,
+ [](toml::table&& tbl) // spec-comment-0
+ {
+ const auto expected = toml::table{
+ { R"(another)"sv, R"(# This is not a comment)"sv },
+ { R"(key)"sv, R"(value)"sv },
+ };
+ REQUIRE(tbl == expected);
+ });
+ }
+
+ SECTION("spec-float-0")
+ {
+ parsing_should_succeed(FILE_LINE_ARGS,
+ spec_float_0,
+ [](toml::table&& tbl) // spec-float-0
+ {
+ const auto expected = toml::table{
+ { R"(flt1)"sv, 1.0 }, { R"(flt2)"sv, 3.1415 }, { R"(flt3)"sv, -0.01 },
+ { R"(flt4)"sv, 5e+22 }, { R"(flt5)"sv, 1000000.0 }, { R"(flt6)"sv, -0.02 },
+ { R"(flt7)"sv, 6.626e-34 },
+ };
+ REQUIRE(tbl == expected);
+ });
+ }
+
+ SECTION("spec-float-1")
+ {
+ parsing_should_succeed(FILE_LINE_ARGS,
+ spec_float_1,
+ [](toml::table&& tbl) // spec-float-1
+ {
+ const auto expected = toml::table{
+ { R"(flt8)"sv, 224617.445991228 },
+ };
+ REQUIRE(tbl == expected);
+ });
+ }
+
+ SECTION("spec-float-2")
+ {
+ parsing_should_succeed(FILE_LINE_ARGS,
+ spec_float_2,
+ [](toml::table&& tbl) // spec-float-2
+ {
+ const auto expected = toml::table{
+ { R"(sf1)"sv, std::numeric_limits<double>::infinity() },
+ { R"(sf2)"sv, std::numeric_limits<double>::infinity() },
+ { R"(sf3)"sv, -std::numeric_limits<double>::infinity() },
+ { R"(sf4)"sv, std::numeric_limits<double>::quiet_NaN() },
+ { R"(sf5)"sv, std::numeric_limits<double>::quiet_NaN() },
+ { R"(sf6)"sv, std::numeric_limits<double>::quiet_NaN() },
+ };
+ REQUIRE(tbl == expected);
+ });
+ }
+
+ SECTION("spec-inline-table-0")
+ {
+ parsing_should_succeed(FILE_LINE_ARGS,
+ spec_inline_table_0,
+ [](toml::table&& tbl) // spec-inline-table-0
+ {
+ const auto expected = toml::table{
+ { R"(animal)"sv,
+ toml::table{
+ { R"(type)"sv,
+ toml::table{
+ { R"(name)"sv, R"(pug)"sv },
+ } },
+ } },
+ { R"(name)"sv,
+ toml::table{
+ { R"(first)"sv, R"(Tom)"sv },
+ { R"(last)"sv, R"(Preston-Werner)"sv },
+ } },
+ { R"(point)"sv,
+ toml::table{
+ { R"(x)"sv, 1 },
+ { R"(y)"sv, 2 },
+ } },
+ };
+ REQUIRE(tbl == expected);
+ });
+ }
+
+ SECTION("spec-inline-table-1")
+ {
+ parsing_should_succeed(FILE_LINE_ARGS,
+ spec_inline_table_1,
+ [](toml::table&& tbl) // spec-inline-table-1
+ {
+ const auto expected = toml::table{
+ { R"(animal)"sv,
+ toml::table{
+ { R"(type)"sv,
+ toml::table{
+ { R"(name)"sv, R"(pug)"sv },
+ } },
+ } },
+ { R"(name)"sv,
+ toml::table{
+ { R"(first)"sv, R"(Tom)"sv },
+ { R"(last)"sv, R"(Preston-Werner)"sv },
+ } },
+ { R"(point)"sv,
+ toml::table{
+ { R"(x)"sv, 1 },
+ { R"(y)"sv, 2 },
+ } },
+ };
+ REQUIRE(tbl == expected);
+ });
+ }
+
+ SECTION("spec-inline-table-2")
+ {
+ parsing_should_succeed(FILE_LINE_ARGS,
+ spec_inline_table_2,
+ [](toml::table&& tbl) // spec-inline-table-2
+ {
+ const auto expected = toml::table{
+ { R"(product)"sv,
+ toml::table{
+ { R"(type)"sv,
+ toml::table{
+ { R"(name)"sv, R"(Nail)"sv },
+ } },
+ } },
+ };
+ REQUIRE(tbl == expected);
+ });
+ }
+
+ SECTION("spec-inline-table-3")
+ {
+ parsing_should_succeed(FILE_LINE_ARGS,
+ spec_inline_table_3,
+ [](toml::table&& tbl) // spec-inline-table-3
+ {
+ const auto expected = toml::table{
+ { R"(product)"sv,
+ toml::table{
+ { R"(type)"sv,
+ toml::table{
+ { R"(name)"sv, R"(Nail)"sv },
+ } },
+ } },
+ };
+ REQUIRE(tbl == expected);
+ });
+ }
+
+ SECTION("spec-integer-0")
+ {
+ parsing_should_succeed(FILE_LINE_ARGS,
+ spec_integer_0,
+ [](toml::table&& tbl) // spec-integer-0
+ {
+ const auto expected = toml::table{
+ { R"(int1)"sv, 99 },
+ { R"(int2)"sv, 42 },
+ { R"(int3)"sv, 0 },
+ { R"(int4)"sv, -17 },
+ };
+ REQUIRE(tbl == expected);
+ });
+ }
+
+ SECTION("spec-integer-1")
+ {
+ parsing_should_succeed(FILE_LINE_ARGS,
+ spec_integer_1,
+ [](toml::table&& tbl) // spec-integer-1
+ {
+ const auto expected = toml::table{
+ { R"(int5)"sv, 1000 },
+ { R"(int6)"sv, 5349221 },
+ { R"(int7)"sv, 5349221 },
+ { R"(int8)"sv, 12345 },
+ };
+ REQUIRE(tbl == expected);
+ });
+ }
+
+ SECTION("spec-integer-2")
+ {
+ parsing_should_succeed(FILE_LINE_ARGS,
+ spec_integer_2,
+ [](toml::table&& tbl) // spec-integer-2
+ {
+ const auto expected = toml::table{
+ { R"(bin1)"sv, 214 }, { R"(hex1)"sv, 3735928559 },
+ { R"(hex2)"sv, 3735928559 }, { R"(hex3)"sv, 3735928559 },
+ { R"(oct1)"sv, 342391 }, { R"(oct2)"sv, 493 },
+ };
+ REQUIRE(tbl == expected);
+ });
+ }
+
+ SECTION("spec-key-value-pair-0")
+ {
+ parsing_should_succeed(FILE_LINE_ARGS,
+ spec_key_value_pair_0,
+ [](toml::table&& tbl) // spec-key-value-pair-0
+ {
+ const auto expected = toml::table{
+ { R"(key)"sv, R"(value)"sv },
+ };
+ REQUIRE(tbl == expected);
+ });
+ }
+
+ SECTION("spec-keys-0")
+ {
+ parsing_should_succeed(FILE_LINE_ARGS,
+ spec_keys_0,
+ [](toml::table&& tbl) // spec-keys-0
+ {
+ const auto expected = toml::table{
+ { R"(1234)"sv, R"(value)"sv },
+ { R"(bare-key)"sv, R"(value)"sv },
+ { R"(bare_key)"sv, R"(value)"sv },
+ { R"(key)"sv, R"(value)"sv },
+ };
+ REQUIRE(tbl == expected);
+ });
+ }
+
+ SECTION("spec-keys-3")
+ {
+ parsing_should_succeed(FILE_LINE_ARGS,
+ spec_keys_3,
+ [](toml::table&& tbl) // spec-keys-3
+ {
+ const auto expected = toml::table{
+ { R"(name)"sv, R"(Orange)"sv },
+ { R"(physical)"sv,
+ toml::table{
+ { R"(color)"sv, R"(orange)"sv },
+ { R"(shape)"sv, R"(round)"sv },
+ } },
+ { R"(site)"sv,
+ toml::table{
+ { R"(google.com)"sv, true },
+ } },
+ };
+ REQUIRE(tbl == expected);
+ });
+ }
+
+ SECTION("spec-keys-4")
+ {
+ parsing_should_succeed(FILE_LINE_ARGS,
+ spec_keys_4,
+ [](toml::table&& tbl) // spec-keys-4
+ {
+ const auto expected = toml::table{
+ { R"(fruit)"sv,
+ toml::table{
+ { R"(color)"sv, R"(yellow)"sv },
+ { R"(flavor)"sv, R"(banana)"sv },
+ { R"(name)"sv, R"(banana)"sv },
+ } },
+ };
+ REQUIRE(tbl == expected);
+ });
+ }
+
+ SECTION("spec-keys-5")
+ {
+ parsing_should_succeed(FILE_LINE_ARGS,
+ spec_keys_5,
+ [](toml::table&& tbl) // spec-keys-5
+ {
+ const auto expected = toml::table{
+ { R"(apple)"sv,
+ toml::table{
+ { R"(color)"sv, R"(red)"sv },
+ { R"(skin)"sv, R"(thin)"sv },
+ { R"(type)"sv, R"(fruit)"sv },
+ } },
+ { R"(orange)"sv,
+ toml::table{
+ { R"(color)"sv, R"(orange)"sv },
+ { R"(skin)"sv, R"(thick)"sv },
+ { R"(type)"sv, R"(fruit)"sv },
+ } },
+ };
+ REQUIRE(tbl == expected);
+ });
+ }
+
+ SECTION("spec-keys-6")
+ {
+ parsing_should_succeed(FILE_LINE_ARGS,
+ spec_keys_6,
+ [](toml::table&& tbl) // spec-keys-6
+ {
+ const auto expected = toml::table{
+ { R"(apple)"sv,
+ toml::table{
+ { R"(color)"sv, R"(red)"sv },
+ { R"(skin)"sv, R"(thin)"sv },
+ { R"(type)"sv, R"(fruit)"sv },
+ } },
+ { R"(orange)"sv,
+ toml::table{
+ { R"(color)"sv, R"(orange)"sv },
+ { R"(skin)"sv, R"(thick)"sv },
+ { R"(type)"sv, R"(fruit)"sv },
+ } },
+ };
+ REQUIRE(tbl == expected);
+ });
+ }
+
+ SECTION("spec-keys-7")
+ {
+ parsing_should_succeed(FILE_LINE_ARGS,
+ spec_keys_7,
+ [](toml::table&& tbl) // spec-keys-7
+ {
+ const auto expected = toml::table{
+ { R"(3)"sv,
+ toml::table{
+ { R"(14159)"sv, R"(pi)"sv },
+ } },
+ };
+ REQUIRE(tbl == expected);
+ });
+ }
+
+ SECTION("spec-local-date-0")
+ {
+ parsing_should_succeed(FILE_LINE_ARGS,
+ spec_local_date_0,
+ [](toml::table&& tbl) // spec-local-date-0
+ {
+ const auto expected = toml::table{
+ { R"(ld1)"sv, toml::date{ 1979, 5, 27 } },
+ };
+ REQUIRE(tbl == expected);
+ });
+ }
+
+ SECTION("spec-local-date-time-0")
+ {
+ parsing_should_succeed(FILE_LINE_ARGS,
+ spec_local_date_time_0,
+ [](toml::table&& tbl) // spec-local-date-time-0
+ {
+ const auto expected = toml::table{
+ { R"(ldt1)"sv, toml::date_time{ { 1979, 5, 27 }, { 7, 32 } } },
+ { R"(ldt2)"sv, toml::date_time{ { 1979, 5, 27 }, { 0, 32, 0, 999999000 } } },
+ };
+ REQUIRE(tbl == expected);
+ });
+ }
+
+ SECTION("spec-local-time-0")
+ {
+ parsing_should_succeed(FILE_LINE_ARGS,
+ spec_local_time_0,
+ [](toml::table&& tbl) // spec-local-time-0
+ {
+ const auto expected = toml::table{
+ { R"(lt1)"sv, toml::time{ 7, 32 } },
+ { R"(lt2)"sv, toml::time{ 0, 32, 0, 999999000 } },
+ };
+ REQUIRE(tbl == expected);
+ });
+ }
+
+ SECTION("spec-offset-date-time-0")
+ {
+ parsing_should_succeed(
+ FILE_LINE_ARGS,
+ spec_offset_date_time_0,
+ [](toml::table&& tbl) // spec-offset-date-time-0
+ {
+ const auto expected = toml::table{
+ { R"(odt1)"sv, toml::date_time{ { 1979, 5, 27 }, { 7, 32 }, { 0, 0 } } },
+ { R"(odt2)"sv, toml::date_time{ { 1979, 5, 27 }, { 0, 32 }, { -7, 0 } } },
+ { R"(odt3)"sv, toml::date_time{ { 1979, 5, 27 }, { 0, 32, 0, 999999000 }, { -7, 0 } } },
+ };
+ REQUIRE(tbl == expected);
+ });
+ }
+
+ SECTION("spec-offset-date-time-1")
+ {
+ parsing_should_succeed(FILE_LINE_ARGS,
+ spec_offset_date_time_1,
+ [](toml::table&& tbl) // spec-offset-date-time-1
+ {
+ const auto expected = toml::table{
+ { R"(odt4)"sv, toml::date_time{ { 1979, 5, 27 }, { 7, 32 }, { 0, 0 } } },
+ };
+ REQUIRE(tbl == expected);
+ });
+ }
+
+ SECTION("spec-string-1")
+ {
+ parsing_should_succeed(FILE_LINE_ARGS,
+ spec_string_1,
+ [](toml::table&& tbl) // spec-string-1
+ {
+ const auto expected = toml::table{
+ { R"(str1)"sv, R"(Roses are red
+Violets are blue)"sv },
+ };
+ REQUIRE(tbl == expected);
+ });
+ }
+
+ SECTION("spec-string-2")
+ {
+ parsing_should_succeed(FILE_LINE_ARGS,
+ spec_string_2,
+ [](toml::table&& tbl) // spec-string-2
+ {
+ const auto expected = toml::table{
+ { R"(str2)"sv, R"(Roses are red
+Violets are blue)"sv },
+ { R"(str3)"sv,
+ "Roses are red\r\n"
+ "Violets are blue"sv },
+ };
+ REQUIRE(tbl == expected);
+ });
+ }
+
+ SECTION("spec-string-3")
+ {
+ parsing_should_succeed(FILE_LINE_ARGS,
+ spec_string_3,
+ [](toml::table&& tbl) // spec-string-3
+ {
+ const auto expected = toml::table{
+ { R"(str1)"sv, R"(The quick brown fox jumps over the lazy dog.)"sv },
+ { R"(str2)"sv, R"(The quick brown fox jumps over the lazy dog.)"sv },
+ { R"(str3)"sv, R"(The quick brown fox jumps over the lazy dog.)"sv },
+ };
+ REQUIRE(tbl == expected);
+ });
+ }
+
+ SECTION("spec-string-4")
+ {
+ parsing_should_succeed(FILE_LINE_ARGS,
+ spec_string_4,
+ [](toml::table&& tbl) // spec-string-4
+ {
+ const auto expected = toml::table{
+ { R"(str4)"sv, R"(Here are two quotation marks: "". Simple enough.)"sv },
+ { R"(str5)"sv, R"(Here are three quotation marks: """.)"sv },
+ { R"(str6)"sv, R"(Here are fifteen quotation marks: """"""""""""""".)"sv },
+ { R"(str7)"sv, R"("This," she said, "is just a pointless statement.")"sv },
+ };
+ REQUIRE(tbl == expected);
+ });
+ }
+
+ SECTION("spec-string-5")
+ {
+ parsing_should_succeed(FILE_LINE_ARGS,
+ spec_string_5,
+ [](toml::table&& tbl) // spec-string-5
+ {
+ const auto expected = toml::table{
+ { R"(quoted)"sv, R"(Tom "Dubs" Preston-Werner)"sv },
+ { R"(regex)"sv, R"(<\i\c*\s*>)"sv },
+ { R"(winpath)"sv, R"(C:\Users\nodejs\templates)"sv },
+ { R"(winpath2)"sv, R"(\\ServerX\admin$\system32\)"sv },
+ };
+ REQUIRE(tbl == expected);
+ });
+ }
+
+ SECTION("spec-string-6")
+ {
+ parsing_should_succeed(FILE_LINE_ARGS,
+ spec_string_6,
+ [](toml::table&& tbl) // spec-string-6
+ {
+ const auto expected = toml::table{
+ { R"(lines)"sv, R"(The first newline is
+trimmed in raw strings.
+ All other whitespace
+ is preserved.
+)"sv },
+ { R"(regex2)"sv, R"(I [dw]on't need \d{2} apples)"sv },
+ };
+ REQUIRE(tbl == expected);
+ });
+ }
+
+ SECTION("spec-string-7")
+ {
+ parsing_should_succeed(FILE_LINE_ARGS,
+ spec_string_7,
+ [](toml::table&& tbl) // spec-string-7
+ {
+ const auto expected = toml::table{
+ { R"(apos15)"sv, R"(Here are fifteen apostrophes: ''''''''''''''')"sv },
+ { R"(quot15)"sv, R"(Here are fifteen quotation marks: """"""""""""""")"sv },
+ { R"(str)"sv, R"('That,' she said, 'is still pointless.')"sv },
+ };
+ REQUIRE(tbl == expected);
+ });
+ }
+
+ SECTION("spec-table-0")
+ {
+ parsing_should_succeed(FILE_LINE_ARGS,
+ spec_table_0,
+ [](toml::table&& tbl) // spec-table-0
+ {
+ const auto expected = toml::table{
+ { R"(table)"sv, toml::table{} },
+ };
+ REQUIRE(tbl == expected);
+ });
+ }
+
+ SECTION("spec-table-1")
+ {
+ parsing_should_succeed(FILE_LINE_ARGS,
+ spec_table_1,
+ [](toml::table&& tbl) // spec-table-1
+ {
+ const auto expected = toml::table{
+ { R"(table-1)"sv,
+ toml::table{
+ { R"(key1)"sv, R"(some string)"sv },
+ { R"(key2)"sv, 123 },
+ } },
+ { R"(table-2)"sv,
+ toml::table{
+ { R"(key1)"sv, R"(another string)"sv },
+ { R"(key2)"sv, 456 },
+ } },
+ };
+ REQUIRE(tbl == expected);
+ });
+ }
+
+ SECTION("spec-table-2")
+ {
+ parsing_should_succeed(FILE_LINE_ARGS,
+ spec_table_2,
+ [](toml::table&& tbl) // spec-table-2
+ {
+ const auto expected = toml::table{
+ { R"(dog)"sv,
+ toml::table{
+ { R"(tater.man)"sv,
+ toml::table{
+ { R"(type)"sv,
+ toml::table{
+ { R"(name)"sv, R"(pug)"sv },
+ } },
+ } },
+ } },
+ };
+ REQUIRE(tbl == expected);
+ });
+ }
+
+ SECTION("spec-table-4")
+ {
+ parsing_should_succeed(FILE_LINE_ARGS,
+ spec_table_4,
+ [](toml::table&& tbl) // spec-table-4
+ {
+ const auto expected = toml::table{
+ { R"(x)"sv,
+ toml::table{
+ { R"(y)"sv,
+ toml::table{
+ { R"(z)"sv,
+ toml::table{
+ { R"(w)"sv, toml::table{} },
+ } },
+ } },
+ } },
+ };
+ REQUIRE(tbl == expected);
+ });
+ }
+
+ SECTION("spec-table-5")
+ {
+ parsing_should_succeed(FILE_LINE_ARGS,
+ spec_table_5,
+ [](toml::table&& tbl) // spec-table-5
+ {
+ const auto expected = toml::table{
+ { R"(animal)"sv, toml::table{} },
+ { R"(fruit)"sv,
+ toml::table{
+ { R"(apple)"sv, toml::table{} },
+ { R"(orange)"sv, toml::table{} },
+ } },
+ };
+ REQUIRE(tbl == expected);
+ });
+ }
+
+ SECTION("spec-table-6")
+ {
+ parsing_should_succeed(FILE_LINE_ARGS,
+ spec_table_6,
+ [](toml::table&& tbl) // spec-table-6
+ {
+ const auto expected = toml::table{
+ { R"(animal)"sv, toml::table{} },
+ { R"(fruit)"sv,
+ toml::table{
+ { R"(apple)"sv, toml::table{} },
+ { R"(orange)"sv, toml::table{} },
+ } },
+ };
+ REQUIRE(tbl == expected);
+ });
+ }
+
+ SECTION("spec-table-7")
+ {
+ parsing_should_succeed(FILE_LINE_ARGS,
+ spec_table_7,
+ [](toml::table&& tbl) // spec-table-7
+ {
+ const auto expected = toml::table{
+ { R"(breed)"sv, R"(pug)"sv },
+ { R"(name)"sv, R"(Fido)"sv },
+ { R"(owner)"sv,
+ toml::table{
+ { R"(member_since)"sv, toml::date{ 1999, 8, 4 } },
+ { R"(name)"sv, R"(Regina Dogman)"sv },
+ } },
+ };
+ REQUIRE(tbl == expected);
+ });
+ }
+
+ SECTION("spec-table-8")
+ {
+ parsing_should_succeed(FILE_LINE_ARGS,
+ spec_table_8,
+ [](toml::table&& tbl) // spec-table-8
+ {
+ const auto expected = toml::table{
+ { R"(fruit)"sv,
+ toml::table{
+ { R"(apple)"sv,
+ toml::table{
+ { R"(color)"sv, R"(red)"sv },
+ { R"(taste)"sv,
+ toml::table{
+ { R"(sweet)"sv, true },
+ } },
+ } },
+ } },
+ };
+ REQUIRE(tbl == expected);
+ });
+ }
+
+ SECTION("spec-table-9")
+ {
+ parsing_should_succeed(FILE_LINE_ARGS,
+ spec_table_9,
+ [](toml::table&& tbl) // spec-table-9
+ {
+ const auto expected = toml::table{
+ { R"(fruit)"sv,
+ toml::table{
+ { R"(apple)"sv,
+ toml::table{
+ { R"(color)"sv, R"(red)"sv },
+ { R"(taste)"sv,
+ toml::table{
+ { R"(sweet)"sv, true },
+ } },
+ { R"(texture)"sv,
+ toml::table{
+ { R"(smooth)"sv, true },
+ } },
+ } },
+ } },
+ };
+ REQUIRE(tbl == expected);
+ });
+ }
+
+ SECTION("spec-example-1-compact")
+ {
+ parsing_should_succeed(FILE_LINE_ARGS,
+ spec_example_1_compact,
+ [](toml::table&& tbl) // spec-example-1-compact
+ {
+ const auto expected = toml::table{
+ { R"(clients)"sv,
+ toml::table{
+ { R"(data)"sv,
+ toml::array{
+ toml::array{
+ R"(gamma)"sv,
+ R"(delta)"sv,
+ },
+ toml::array{
+ 1,
+ 2,
+ },
+ } },
+ { R"(hosts)"sv,
+ toml::array{
+ R"(alpha)"sv,
+ R"(omega)"sv,
+ } },
+ } },
+ { R"(database)"sv,
+ toml::table{
+ { R"(connection_max)"sv, 5000 },
+ { R"(enabled)"sv, true },
+ { R"(ports)"sv,
+ toml::array{
+ 8001,
+ 8001,
+ 8002,
+ } },
+ { R"(server)"sv, R"(192.168.1.1)"sv },
+ } },
+ { R"(owner)"sv,
+ toml::table{
+ { R"(dob)"sv, toml::date_time{ { 1979, 5, 27 }, { 7, 32 }, { -8, 0 } } },
+ { R"(name)"sv, R"(Lance Uppercut)"sv },
+ } },
+ { R"(servers)"sv,
+ toml::table{
+ { R"(alpha)"sv,
+ toml::table{
+ { R"(dc)"sv, R"(eqdc10)"sv },
+ { R"(ip)"sv, R"(10.0.0.1)"sv },
+ } },
+ { R"(beta)"sv,
+ toml::table{
+ { R"(dc)"sv, R"(eqdc10)"sv },
+ { R"(ip)"sv, R"(10.0.0.2)"sv },
+ } },
+ } },
+ { R"(title)"sv, R"(TOML Example)"sv },
+ };
+ REQUIRE(tbl == expected);
+ });
+ }
+
+ SECTION("spec-example-1")
+ {
+ parsing_should_succeed(FILE_LINE_ARGS,
+ spec_example_1,
+ [](toml::table&& tbl) // spec-example-1
+ {
+ const auto expected = toml::table{
+ { R"(clients)"sv,
+ toml::table{
+ { R"(data)"sv,
+ toml::array{
+ toml::array{
+ R"(gamma)"sv,
+ R"(delta)"sv,
+ },
+ toml::array{
+ 1,
+ 2,
+ },
+ } },
+ { R"(hosts)"sv,
+ toml::array{
+ R"(alpha)"sv,
+ R"(omega)"sv,
+ } },
+ } },
+ { R"(database)"sv,
+ toml::table{
+ { R"(connection_max)"sv, 5000 },
+ { R"(enabled)"sv, true },
+ { R"(ports)"sv,
+ toml::array{
+ 8001,
+ 8001,
+ 8002,
+ } },
+ { R"(server)"sv, R"(192.168.1.1)"sv },
+ } },
+ { R"(owner)"sv,
+ toml::table{
+ { R"(dob)"sv, toml::date_time{ { 1979, 5, 27 }, { 7, 32 }, { -8, 0 } } },
+ { R"(name)"sv, R"(Lance Uppercut)"sv },
+ } },
+ { R"(servers)"sv,
+ toml::table{
+ { R"(alpha)"sv,
+ toml::table{
+ { R"(dc)"sv, R"(eqdc10)"sv },
+ { R"(ip)"sv, R"(10.0.0.1)"sv },
+ } },
+ { R"(beta)"sv,
+ toml::table{
+ { R"(dc)"sv, R"(eqdc10)"sv },
+ { R"(ip)"sv, R"(10.0.0.2)"sv },
+ } },
+ } },
+ { R"(title)"sv, R"(TOML Example)"sv },
+ };
+ REQUIRE(tbl == expected);
+ });
+ }
+
+#if UNICODE_LITERALS_OK
+
+ SECTION("spec-keys-1")
+ {
+ parsing_should_succeed(FILE_LINE_ARGS,
+ spec_keys_1,
+ [](toml::table&& tbl) // spec-keys-1
+ {
+ const auto expected = toml::table{
+ { R"(127.0.0.1)"sv, R"(value)"sv }, { R"(character encoding)"sv, R"(value)"sv },
+ { R"(key2)"sv, R"(value)"sv }, { R"(quoted "value")"sv, R"(value)"sv },
+ { R"(ʎǝʞ)"sv, R"(value)"sv },
+ };
+ REQUIRE(tbl == expected);
+ });
+ }
+
+ SECTION("spec-string-0")
+ {
+ parsing_should_succeed(FILE_LINE_ARGS,
+ spec_string_0,
+ [](toml::table&& tbl) // spec-string-0
+ {
+ const auto expected = toml::table{
+ { R"(str)"sv, R"(I'm a string. "You can quote me". Name José
+Location SF.)"sv },
+ };
+ REQUIRE(tbl == expected);
+ });
+ }
+
+ SECTION("spec-table-3")
+ {
+ parsing_should_succeed(FILE_LINE_ARGS,
+ spec_table_3,
+ [](toml::table&& tbl) // spec-table-3
+ {
+ const auto expected = toml::table{
+ { R"(a)"sv,
+ toml::table{
+ { R"(b)"sv,
+ toml::table{
+ { R"(c)"sv, toml::table{} },
+ } },
+ } },
+ { R"(d)"sv,
+ toml::table{
+ { R"(e)"sv,
+ toml::table{
+ { R"(f)"sv, toml::table{} },
+ } },
+ } },
+ { R"(g)"sv,
+ toml::table{
+ { R"(h)"sv,
+ toml::table{
+ { R"(i)"sv, toml::table{} },
+ } },
+ } },
+ { R"(j)"sv,
+ toml::table{
+ { R"(ʞ)"sv,
+ toml::table{
+ { R"(l)"sv, toml::table{} },
+ } },
+ } },
+ };
+ REQUIRE(tbl == expected);
+ });
+ }
+
+#endif // UNICODE_LITERALS_OK
+
+ SECTION("string-double-quote-escape")
+ {
+ parsing_should_succeed(FILE_LINE_ARGS,
+ string_double_quote_escape,
+ [](toml::table&& tbl) // string-double-quote-escape
+ {
+ const auto expected = toml::table{
+ { R"(test)"sv, R"("one")"sv },
+ };
+ REQUIRE(tbl == expected);
+ });
+ }
+
+ SECTION("string-empty")
+ {
+ parsing_should_succeed(FILE_LINE_ARGS,
+ string_empty,
+ [](toml::table&& tbl) // string-empty
+ {
+ const auto expected = toml::table{
+ { R"(answer)"sv, ""sv },
+ };
+ REQUIRE(tbl == expected);
+ });
+ }
+
+ SECTION("string-escaped-escape")
+ {
+ parsing_should_succeed(FILE_LINE_ARGS,
+ string_escaped_escape,
+ [](toml::table&& tbl) // string-escaped-escape
+ {
+ const auto expected = toml::table{
+ { R"(answer)"sv, R"(\x64)"sv },
+ };
+ REQUIRE(tbl == expected);
+ });
+ }
+
+ SECTION("string-escapes")
+ {
+ parsing_should_succeed(
+ FILE_LINE_ARGS,
+ string_escapes,
+ [](toml::table&& tbl) // string-escapes
+ {
+ const auto expected = toml::table{
+ { R"(backslash)"sv, R"(This string has a \ backslash character.)"sv },
+ { R"(backspace)"sv, "This string has a \x08 backspace character."sv },
+ { R"(carriage)"sv, "This string has a \r carriage return character."sv },
+ { R"(delete)"sv, "This string has a \x7F delete control code."sv },
+ { R"(formfeed)"sv, "This string has a \f form feed character."sv },
+ { R"(newline)"sv, R"(This string has a
+ new line character.)"sv },
+ { R"(notunicode1)"sv, R"(This string does not have a unicode \u escape.)"sv },
+ { R"(notunicode2)"sv, R"(This string does not have a unicode \u escape.)"sv },
+ { R"(notunicode3)"sv, R"(This string does not have a unicode \u0075 escape.)"sv },
+ { R"(notunicode4)"sv, R"(This string does not have a unicode \u escape.)"sv },
+ { R"(quote)"sv, R"(This string has a " quote character.)"sv },
+ { R"(tab)"sv, R"(This string has a tab character.)"sv },
+ { R"(unitseparator)"sv, "This string has a \x1F unit separator control code."sv },
+ };
+ REQUIRE(tbl == expected);
+ });
+ }
+
+ SECTION("string-multiline-escaped-crlf")
+ {
+ parsing_should_succeed(FILE_LINE_ARGS,
+ string_multiline_escaped_crlf,
+ [](toml::table&& tbl) // string-multiline-escaped-crlf
+ {
+ const auto expected = toml::table{
+ { R"(0)"sv, ""sv },
+ };
+ REQUIRE(tbl == expected);
+ });
+ }
+
+ SECTION("string-multiline-quotes")
+ {
+ parsing_should_succeed(FILE_LINE_ARGS,
+ string_multiline_quotes,
+ [](toml::table&& tbl) // string-multiline-quotes
+ {
+ const auto expected = toml::table{
+ { R"(escaped)"sv, R"(lol""")"sv },
+ { R"(lit_one)"sv, R"('one quote')"sv },
+ { R"(lit_one_space)"sv, R"( 'one quote' )"sv },
+ { R"(lit_two)"sv, R"(''two quotes'')"sv },
+ { R"(lit_two_space)"sv, R"( ''two quotes'' )"sv },
+ { R"(mismatch1)"sv, R"(aaa'''bbb)"sv },
+ { R"(mismatch2)"sv, R"(aaa"""bbb)"sv },
+ { R"(one)"sv, R"("one quote")"sv },
+ { R"(one_space)"sv, R"( "one quote" )"sv },
+ { R"(two)"sv, R"(""two quotes"")"sv },
+ { R"(two_space)"sv, R"( ""two quotes"" )"sv },
+ };
+ REQUIRE(tbl == expected);
+ });
+ }
+
+ SECTION("string-multiline")
+ {
+ parsing_should_succeed(
+ FILE_LINE_ARGS,
+ string_multiline,
+ [](toml::table&& tbl) // string-multiline
+ {
+ const auto expected = toml::table{
+ { R"(equivalent_one)"sv, R"(The quick brown fox jumps over the lazy dog.)"sv },
+ { R"(equivalent_three)"sv, R"(The quick brown fox jumps over the lazy dog.)"sv },
+ { R"(equivalent_two)"sv, R"(The quick brown fox jumps over the lazy dog.)"sv },
+ { R"(escape-bs-1)"sv, R"(a \
+b)"sv },
+ { R"(escape-bs-2)"sv, R"(a \b)"sv },
+ { R"(escape-bs-3)"sv, R"(a \\
+ b)"sv },
+ { R"(keep-ws-before)"sv, R"(a b)"sv },
+ { R"(multiline_empty_four)"sv, ""sv },
+ { R"(multiline_empty_one)"sv, ""sv },
+ { R"(multiline_empty_three)"sv, ""sv },
+ { R"(multiline_empty_two)"sv, ""sv },
+ { R"(no-space)"sv, R"(ab)"sv },
+ { R"(whitespace-after-bs)"sv, R"(The quick brown fox jumps over the lazy dog.)"sv },
+ };
+ REQUIRE(tbl == expected);
+ });
+ }
+
+ SECTION("string-nl")
+ {
+ parsing_should_succeed(FILE_LINE_ARGS,
+ string_nl,
+ [](toml::table&& tbl) // string-nl
+ {
+ const auto expected = toml::table{
+ { R"(lit_nl_end)"sv, R"(value\n)"sv },
+ { R"(lit_nl_mid)"sv, R"(val\nue)"sv },
+ { R"(lit_nl_uni)"sv, R"(val\ue)"sv },
+ { R"(nl_end)"sv, R"(value
+)"sv },
+ { R"(nl_mid)"sv, R"(val
+ue)"sv },
+ };
+ REQUIRE(tbl == expected);
+ });
+ }
+
+ SECTION("string-raw-multiline")
+ {
+ parsing_should_succeed(FILE_LINE_ARGS,
+ string_raw_multiline,
+ [](toml::table&& tbl) // string-raw-multiline
+ {
+ const auto expected = toml::table{
+ { R"(firstnl)"sv, R"(This string has a ' quote character.)"sv },
+ { R"(multiline)"sv, R"(This string
+has ' a quote character
+and more than
+one newline
+in it.)"sv },
+ { R"(multiline_with_tab)"sv, R"(First line
+ Followed by a tab)"sv },
+ { R"(oneline)"sv, R"(This string has a ' quote character.)"sv },
+ };
+ REQUIRE(tbl == expected);
+ });
+ }
+
+ SECTION("string-raw")
+ {
+ parsing_should_succeed(FILE_LINE_ARGS,
+ string_raw,
+ [](toml::table&& tbl) // string-raw
+ {
+ const auto expected = toml::table{
+ { R"(backslash)"sv, R"(This string has a \\ backslash character.)"sv },
+ { R"(backspace)"sv, R"(This string has a \b backspace character.)"sv },
+ { R"(carriage)"sv, R"(This string has a \r carriage return character.)"sv },
+ { R"(formfeed)"sv, R"(This string has a \f form feed character.)"sv },
+ { R"(newline)"sv, R"(This string has a \n new line character.)"sv },
+ { R"(slash)"sv, R"(This string has a \/ slash character.)"sv },
+ { R"(tab)"sv, R"(This string has a \t tab character.)"sv },
+ { R"(unescaped_tab)"sv, R"(This string has an unescaped tab character.)"sv },
+ };
+ REQUIRE(tbl == expected);
+ });
+ }
+
+ SECTION("string-simple")
+ {
+ parsing_should_succeed(FILE_LINE_ARGS,
+ string_simple,
+ [](toml::table&& tbl) // string-simple
+ {
+ const auto expected = toml::table{
+ { R"(answer)"sv, R"(You are not drinking enough whisky.)"sv },
+ };
+ REQUIRE(tbl == expected);
+ });
+ }
+
+ SECTION("string-with-pound")
+ {
+ parsing_should_succeed(FILE_LINE_ARGS,
+ string_with_pound,
+ [](toml::table&& tbl) // string-with-pound
+ {
+ const auto expected = toml::table{
+ { R"(pound)"sv, R"(We see no # comments here.)"sv },
+ { R"(poundcomment)"sv, R"(But there are # some comments here.)"sv },
+ };
+ REQUIRE(tbl == expected);
+ });
+ }
+
+#if TOML_LANG_UNRELEASED
+
+ SECTION("string-escape-esc")
+ {
+ parsing_should_succeed(FILE_LINE_ARGS,
+ string_escape_esc,
+ [](toml::table&& tbl) // string-escape-esc
+ {
+ const auto expected = toml::table{
+ { R"(esc)"sv, "\x1B There is no escape! \x1B"sv },
+ };
+ REQUIRE(tbl == expected);
+ });
+ }
+
+#endif // TOML_LANG_UNRELEASED
+
+#if UNICODE_LITERALS_OK
+
+ SECTION("string-escape-tricky")
+ {
+ parsing_should_succeed(FILE_LINE_ARGS,
+ string_escape_tricky,
+ [](toml::table&& tbl) // string-escape-tricky
+ {
+ const auto expected = toml::table{
+ { R"(end_esc)"sv, R"(String does not end here" but ends here\)"sv },
+ { R"(lit_end_esc)"sv, R"(String ends here\)"sv },
+ { R"(lit_multiline_end)"sv, R"(There is no escape\)"sv },
+ { R"(lit_multiline_not_unicode)"sv, R"(\u007f)"sv },
+ { R"(multiline_end_esc)"sv, R"(When will it end? """...""" should be here")"sv },
+ { R"(multiline_not_unicode)"sv, R"(\u0041)"sv },
+ { R"(multiline_unicode)"sv, R"( )"sv },
+ };
+ REQUIRE(tbl == expected);
+ });
+ }
+
+ SECTION("string-quoted-unicode")
+ {
+ parsing_should_succeed(
+ FILE_LINE_ARGS,
+ string_quoted_unicode,
+ [](toml::table&& tbl) // string-quoted-unicode
+ {
+ const auto expected = toml::table{
+ { R"(escaped_string)"sv, "\x00 \x08 \f A \x7F € ÿ ퟿  ￿ 𐀀 􏿿"sv },
+ { R"(not_escaped_string)"sv,
+ R"(\u0000 \u0008 \u000c \U00000041 \u007f \u0080 \u00ff \ud7ff \ue000 \uffff \U00010000 \U0010ffff)"sv },
+ { R"(basic_string)"sv, R"(~ € ÿ ퟿  ￿ 𐀀 􏿿)"sv },
+ { R"(literal_string)"sv, R"(~ € ÿ ퟿  ￿ 𐀀 􏿿)"sv },
+ };
+ REQUIRE(tbl == expected);
+ });
+ }
+
+ SECTION("string-unicode-escape")
+ {
+ parsing_should_succeed(FILE_LINE_ARGS,
+ string_unicode_escape,
+ [](toml::table&& tbl) // string-unicode-escape
+ {
+ const auto expected = toml::table{
+ { R"(answer4)"sv, R"(δ)"sv },
+ { R"(answer8)"sv, R"(δ)"sv },
+ };
+ REQUIRE(tbl == expected);
+ });
+ }
+
+ SECTION("string-unicode-literal")
+ {
+ parsing_should_succeed(FILE_LINE_ARGS,
+ string_unicode_literal,
+ [](toml::table&& tbl) // string-unicode-literal
+ {
+ const auto expected = toml::table{
+ { R"(answer)"sv, R"(δ)"sv },
+ };
+ REQUIRE(tbl == expected);
+ });
+ }
+
+#endif // UNICODE_LITERALS_OK
+
+#if TOML_LANG_UNRELEASED && UNICODE_LITERALS_OK
+
+ SECTION("string-hex-escape")
+ {
+ parsing_should_succeed(FILE_LINE_ARGS,
+ string_hex_escape,
+ [](toml::table&& tbl) // string-hex-escape
+ {
+ const auto expected = toml::table{
+ { R"(bs)"sv, "\x7F"sv },
+ { R"(hello)"sv, R"(hello
+)"sv },
+ { R"(higher-than-127)"sv, R"(Sørmirbæren)"sv },
+ { R"(literal)"sv, R"(\x20 \x09 \x0d\x0a)"sv },
+ { R"(multiline)"sv,
+ " \x1B \r\n"
+ "\n"
+ "\x7F\n"
+ "\x00\n"
+ "hello\n"
+ "\n"
+ "Sørmirbæren\n"
+ ""sv },
+ { R"(multiline-literal)"sv, R"(\x20 \x09 \x0d\x0a
+)"sv },
+ { R"(nul)"sv, "\x00"sv },
+ { R"(whitespace)"sv,
+ " \x1B \r\n"
+ ""sv },
+ };
+ REQUIRE(tbl == expected);
+ });
+ }
+
+#endif // TOML_LANG_UNRELEASED && UNICODE_LITERALS_OK
+
+ SECTION("table-array-implicit-and-explicit-after")
+ {
+ parsing_should_succeed(FILE_LINE_ARGS,
+ table_array_implicit_and_explicit_after,
+ [](toml::table&& tbl) // table-array-implicit-and-explicit-after
+ {
+ const auto expected = toml::table{
+ { R"(a)"sv,
+ toml::table{
+ { R"(b)"sv,
+ toml::array{
+ toml::table{
+ { R"(x)"sv, 1 },
+ },
+ } },
+ { R"(y)"sv, 2 },
+ } },
+ };
+ REQUIRE(tbl == expected);
+ });
+ }
+
+ SECTION("table-array-implicit")
+ {
+ parsing_should_succeed(FILE_LINE_ARGS,
+ table_array_implicit,
+ [](toml::table&& tbl) // table-array-implicit
+ {
+ const auto expected = toml::table{
+ { R"(albums)"sv,
+ toml::table{
+ { R"(songs)"sv,
+ toml::array{
+ toml::table{
+ { R"(name)"sv, R"(Glory Days)"sv },
+ },
+ } },
+ } },
+ };
+ REQUIRE(tbl == expected);
+ });
+ }
+
+ SECTION("table-array-many")
+ {
+ parsing_should_succeed(FILE_LINE_ARGS,
+ table_array_many,
+ [](toml::table&& tbl) // table-array-many
+ {
+ const auto expected = toml::table{
+ { R"(people)"sv,
+ toml::array{
+ toml::table{
+ { R"(first_name)"sv, R"(Bruce)"sv },
+ { R"(last_name)"sv, R"(Springsteen)"sv },
+ },
+ toml::table{
+ { R"(first_name)"sv, R"(Eric)"sv },
+ { R"(last_name)"sv, R"(Clapton)"sv },
+ },
+ toml::table{
+ { R"(first_name)"sv, R"(Bob)"sv },
+ { R"(last_name)"sv, R"(Seger)"sv },
+ },
+ } },
+ };
+ REQUIRE(tbl == expected);
+ });
+ }
+
+ SECTION("table-array-nest")
+ {
+ parsing_should_succeed(FILE_LINE_ARGS,
+ table_array_nest,
+ [](toml::table&& tbl) // table-array-nest
+ {
+ const auto expected = toml::table{
+ { R"(albums)"sv,
+ toml::array{
+ toml::table{
+ { R"(name)"sv, R"(Born to Run)"sv },
+ { R"(songs)"sv,
+ toml::array{
+ toml::table{
+ { R"(name)"sv, R"(Jungleland)"sv },
+ },
+ toml::table{
+ { R"(name)"sv, R"(Meeting Across the River)"sv },
+ },
+ } },
+ },
+ toml::table{
+ { R"(name)"sv, R"(Born in the USA)"sv },
+ { R"(songs)"sv,
+ toml::array{
+ toml::table{
+ { R"(name)"sv, R"(Glory Days)"sv },
+ },
+ toml::table{
+ { R"(name)"sv, R"(Dancing in the Dark)"sv },
+ },
+ } },
+ },
+ } },
+ };
+ REQUIRE(tbl == expected);
+ });
+ }
+
+ SECTION("table-array-one")
+ {
+ parsing_should_succeed(FILE_LINE_ARGS,
+ table_array_one,
+ [](toml::table&& tbl) // table-array-one
+ {
+ const auto expected = toml::table{
+ { R"(people)"sv,
+ toml::array{
+ toml::table{
+ { R"(first_name)"sv, R"(Bruce)"sv },
+ { R"(last_name)"sv, R"(Springsteen)"sv },
+ },
+ } },
+ };
+ REQUIRE(tbl == expected);
+ });
+ }
+
+ SECTION("table-array-table-array")
+ {
+ parsing_should_succeed(FILE_LINE_ARGS,
+ table_array_table_array,
+ [](toml::table&& tbl) // table-array-table-array
+ {
+ const auto expected = toml::table{
+ { R"(a)"sv,
+ toml::array{
+ toml::table{
+ { R"(b)"sv,
+ toml::array{
+ toml::table{
+ { R"(c)"sv,
+ toml::table{
+ { R"(d)"sv, R"(val0)"sv },
+ } },
+ },
+ toml::table{
+ { R"(c)"sv,
+ toml::table{
+ { R"(d)"sv, R"(val1)"sv },
+ } },
+ },
+ } },
+ },
+ } },
+ };
+ REQUIRE(tbl == expected);
+ });
+ }
+
+ SECTION("table-array-within-dotted")
+ {
+ parsing_should_succeed(FILE_LINE_ARGS,
+ table_array_within_dotted,
+ [](toml::table&& tbl) // table-array-within-dotted
+ {
+ const auto expected = toml::table{
+ { R"(fruit)"sv,
+ toml::table{
+ { R"(apple)"sv,
+ toml::table{
+ { R"(color)"sv, R"(red)"sv },
+ { R"(seeds)"sv,
+ toml::array{
+ toml::table{
+ { R"(size)"sv, 2 },
+ },
+ } },
+ } },
+ } },
+ };
+ REQUIRE(tbl == expected);
+ });
+ }
+
+ SECTION("table-empty-name")
+ {
+ parsing_should_succeed(FILE_LINE_ARGS,
+ table_empty_name,
+ [](toml::table&& tbl) // table-empty-name
+ {
+ const auto expected = toml::table{
+ { ""sv,
+ toml::table{
+ { R"(a)"sv,
+ toml::table{
+ { R"(x)"sv, 2 },
+ } },
+ { R"(x)"sv, 1 },
+ } },
+ { R"(a)"sv,
+ toml::table{
+ { ""sv,
+ toml::table{
+ { R"(x)"sv, 3 },
+ } },
+ } },
+ };
+ REQUIRE(tbl == expected);
+ });
+ }
+
+ SECTION("table-empty")
+ {
+ parsing_should_succeed(FILE_LINE_ARGS,
+ table_empty,
+ [](toml::table&& tbl) // table-empty
+ {
+ const auto expected = toml::table{
+ { R"(a)"sv, toml::table{} },
+ };
+ REQUIRE(tbl == expected);
+ });
+ }
+
+ SECTION("table-keyword")
+ {
+ parsing_should_succeed(FILE_LINE_ARGS,
+ table_keyword,
+ [](toml::table&& tbl) // table-keyword
+ {
+ const auto expected = toml::table{
+ { R"(false)"sv, toml::table{} },
+ { R"(inf)"sv, toml::table{} },
+ { R"(nan)"sv, toml::table{} },
+ { R"(true)"sv, toml::table{} },
+ };
+ REQUIRE(tbl == expected);
+ });
+ }
+
+ SECTION("table-no-eol")
+ {
+ parsing_should_succeed(FILE_LINE_ARGS,
+ table_no_eol,
+ [](toml::table&& tbl) // table-no-eol
+ {
+ const auto expected = toml::table{
+ { R"(table)"sv, toml::table{} },
+ };
+ REQUIRE(tbl == expected);
+ });
+ }
+
+ SECTION("table-sub-empty")
+ {
+ parsing_should_succeed(FILE_LINE_ARGS,
+ table_sub_empty,
+ [](toml::table&& tbl) // table-sub-empty
+ {
+ const auto expected = toml::table{
+ { R"(a)"sv,
+ toml::table{
+ { R"(b)"sv, toml::table{} },
+ } },
+ };
+ REQUIRE(tbl == expected);
+ });
+ }
+
+ SECTION("table-sub")
+ {
+ parsing_should_succeed(FILE_LINE_ARGS,
+ table_sub,
+ [](toml::table&& tbl) // table-sub
+ {
+ const auto expected = toml::table{
+ { R"(a)"sv,
+ toml::table{
+ { R"(extend)"sv,
+ toml::table{
+ { R"(key)"sv, 2 },
+ { R"(more)"sv,
+ toml::table{
+ { R"(key)"sv, 3 },
+ } },
+ } },
+ { R"(key)"sv, 1 },
+ } },
+ };
+ REQUIRE(tbl == expected);
+ });
+ }
+
+ SECTION("table-whitespace")
+ {
+ parsing_should_succeed(FILE_LINE_ARGS,
+ table_whitespace,
+ [](toml::table&& tbl) // table-whitespace
+ {
+ const auto expected = toml::table{
+ { R"(valid key)"sv, toml::table{} },
+ };
+ REQUIRE(tbl == expected);
+ });
+ }
+
+ SECTION("table-with-literal-string")
+ {
+ parsing_should_succeed(FILE_LINE_ARGS,
+ table_with_literal_string,
+ [](toml::table&& tbl) // table-with-literal-string
+ {
+ const auto expected = toml::table{
+ { R"(a)"sv,
+ toml::table{
+ { R"("b")"sv,
+ toml::table{
+ { R"(c)"sv,
+ toml::table{
+ { R"(answer)"sv, 42 },
+ } },
+ } },
+ } },
+ };
+ REQUIRE(tbl == expected);
+ });
+ }
+
+ SECTION("table-with-pound")
+ {
+ parsing_should_succeed(FILE_LINE_ARGS,
+ table_with_pound,
+ [](toml::table&& tbl) // table-with-pound
+ {
+ const auto expected = toml::table{
+ { R"(key#group)"sv,
+ toml::table{
+ { R"(answer)"sv, 42 },
+ } },
+ };
+ REQUIRE(tbl == expected);
+ });
+ }
+
+ SECTION("table-with-single-quotes")
+ {
+ parsing_should_succeed(FILE_LINE_ARGS,
+ table_with_single_quotes,
+ [](toml::table&& tbl) // table-with-single-quotes
+ {
+ const auto expected = toml::table{
+ { R"(a)"sv,
+ toml::table{
+ { R"(b)"sv,
+ toml::table{
+ { R"(c)"sv,
+ toml::table{
+ { R"(answer)"sv, 42 },
+ } },
+ } },
+ } },
+ };
+ REQUIRE(tbl == expected);
+ });
+ }
+
+ SECTION("table-without-super")
+ {
+ parsing_should_succeed(FILE_LINE_ARGS,
+ table_without_super,
+ [](toml::table&& tbl) // table-without-super
+ {
+ const auto expected = toml::table{
+ { R"(x)"sv,
+ toml::table{
+ { R"(y)"sv,
+ toml::table{
+ { R"(z)"sv,
+ toml::table{
+ { R"(w)"sv, toml::table{} },
+ } },
+ } },
+ } },
+ };
+ REQUIRE(tbl == expected);
+ });
+ }
+
+#if UNICODE_LITERALS_OK
+
+ SECTION("table-names")
+ {
+ parsing_should_succeed(FILE_LINE_ARGS,
+ table_names,
+ [](toml::table&& tbl) // table-names
+ {
+ const auto expected = toml::table{
+ { R"(a)"sv,
+ toml::table{
+ { R"( x )"sv, toml::table{} },
+ { R"(b)"sv,
+ toml::table{
+ { R"(c)"sv, toml::table{} },
+ } },
+ { R"(b.c)"sv, toml::table{} },
+ { R"(d.e)"sv, toml::table{} },
+ } },
+ { R"(d)"sv,
+ toml::table{
+ { R"(e)"sv,
+ toml::table{
+ { R"(f)"sv, toml::table{} },
+ } },
+ } },
+ { R"(g)"sv,
+ toml::table{
+ { R"(h)"sv,
+ toml::table{
+ { R"(i)"sv, toml::table{} },
+ } },
+ } },
+ { R"(j)"sv,
+ toml::table{
+ { R"(ʞ)"sv,
+ toml::table{
+ { R"(l)"sv, toml::table{} },
+ } },
+ } },
+ { R"(x)"sv,
+ toml::table{
+ { R"(1)"sv,
+ toml::table{
+ { R"(2)"sv, toml::table{} },
+ } },
+ } },
+ };
+ REQUIRE(tbl == expected);
+ });
+ }
+
+#endif // UNICODE_LITERALS_OK
+}
diff --git a/tomlplusplus/tests/conformance_iarna_invalid.cpp b/tomlplusplus/tests/conformance_iarna_invalid.cpp
new file mode 100644
index 0000000000..28c32b3097
--- /dev/null
+++ b/tomlplusplus/tests/conformance_iarna_invalid.cpp
@@ -0,0 +1,451 @@
+// This file is a part of toml++ and is subject to the the terms of the MIT license.
+// Copyright (c) Mark Gillard <mark.gillard@outlook.com.au>
+// See https://github.com/marzer/tomlplusplus/blob/master/LICENSE for the full license text.
+// SPDX-License-Identifier: MIT
+//-----
+// this file was generated by generate_conformance_tests.py - do not modify it directly
+
+#include "tests.hpp"
+
+namespace
+{
+ static constexpr auto array_of_tables_1 = "# INVALID TOML DOC\r\n"
+ "fruit = []\r\n"
+ "\r\n"
+ "[[fruit]] # Not allowed"sv;
+ static constexpr auto array_of_tables_2 = "# INVALID TOML DOC\r\n"
+ "[[fruit]]\r\n"
+ " name = \"apple\"\r\n"
+ "\r\n"
+ " [[fruit.variety]]\r\n"
+ " name = \"red delicious\"\r\n"
+ "\r\n"
+ " # This table conflicts with the previous table\r\n"
+ " [fruit.variety]\r\n"
+ " name = \"granny smith\""sv;
+
+ static constexpr auto bare_key_1 = "bare!key = 123"sv;
+ static constexpr auto bare_key_2 = "barekey\r\n"
+ " = 123"sv;
+ static constexpr auto bare_key_3 = R"(barekey =)"sv;
+
+ static constexpr auto comment_control_1 = "a = \"null\" # \x00"sv;
+ static constexpr auto comment_control_2 = "a = \"ctrl-P\" # \x10"sv;
+ static constexpr auto comment_control_3 = "a = \"ctrl-_\" # \x1F"sv;
+ static constexpr auto comment_control_4 = "a = \"0x7f\" # \x7F"sv;
+
+ static constexpr auto inline_table_imutable_1 = "[product]\r\n"
+ "type = { name = \"Nail\" }\r\n"
+ "type.edible = false # INVALID"sv;
+ static constexpr auto inline_table_imutable_2 = "[product]\r\n"
+ "type.name = \"Nail\"\r\n"
+ "type = { edible = false } # INVALID"sv;
+
+#if !TOML_LANG_UNRELEASED
+
+ static constexpr auto inline_table_trailing_comma = "abc = { abc = 123, }"sv;
+
+#endif // !TOML_LANG_UNRELEASED
+
+ static constexpr auto int_0_padded = "int = 0123"sv;
+ static constexpr auto int_signed_bin = "bin = +0b10"sv;
+ static constexpr auto int_signed_hex = "hex = +0xab"sv;
+ static constexpr auto int_signed_oct = "oct = +0o23"sv;
+
+ static constexpr auto key_value_pair_1 = "key = # INVALID"sv;
+ static constexpr auto key_value_pair_2 = "first = \"Tom\" last = \"Preston-Werner\" # INVALID"sv;
+
+ static constexpr auto multiple_dot_key = "# THE FOLLOWING IS INVALID\r\n"
+ "\r\n"
+ "# This defines the value of fruit.apple to be an integer.\r\n"
+ "fruit.apple = 1\r\n"
+ "\r\n"
+ "# But then this treats fruit.apple like it's a table.\r\n"
+ "# You can't turn an integer into a table.\r\n"
+ "fruit.apple.smooth = true"sv;
+ static constexpr auto multiple_key = "# DO NOT DO THIS\r\n"
+ "name = \"Tom\"\r\n"
+ "name = \"Pradyun\""sv;
+
+ static constexpr auto no_key_name = "= \"no key name\" # INVALID"sv;
+
+ static constexpr auto string_basic_control_1 = "a = \"null\x00\""sv;
+ static constexpr auto string_basic_control_2 = "a = \"ctrl-P\x10\""sv;
+ static constexpr auto string_basic_control_3 = "a = \"ctrl-_\x1F\""sv;
+ static constexpr auto string_basic_control_4 = "a = \"0x7f\x7F\""sv;
+ static constexpr auto string_basic_multiline_control_1 = "a = \"\"\"null\x00\"\"\""sv;
+ static constexpr auto string_basic_multiline_control_2 = "a = \"\"\"null\x10\"\"\""sv;
+ static constexpr auto string_basic_multiline_control_3 = "a = \"\"\"null\x1F\"\"\""sv;
+ static constexpr auto string_basic_multiline_control_4 = "a = \"\"\"null\x7F\"\"\""sv;
+ static constexpr auto string_basic_multiline_invalid_backslash = "a = \"\"\"\r\n"
+ " foo \\ \\n\r\n"
+ " bar\"\"\""sv;
+ static constexpr auto string_basic_multiline_out_of_range_unicode_escape_1 = "a = \"\"\"\\UFFFFFFFF\"\"\""sv;
+ static constexpr auto string_basic_multiline_out_of_range_unicode_escape_2 = "a = \"\"\"\\U00D80000\"\"\""sv;
+ static constexpr auto string_basic_multiline_quotes =
+ "str5 = \"\"\"Here are three quotation marks: \"\"\".\"\"\""sv;
+ static constexpr auto string_basic_multiline_unknown_escape = "a = \"\"\"\\@\"\"\""sv;
+ static constexpr auto string_basic_out_of_range_unicode_escape_1 = "a = \"\\UFFFFFFFF\""sv;
+ static constexpr auto string_basic_out_of_range_unicode_escape_2 = "a = \"\\U00D80000\""sv;
+ static constexpr auto string_basic_unknown_escape = "a = \"\\@\""sv;
+ static constexpr auto string_literal_control_1 = "a = 'null\x00'"sv;
+ static constexpr auto string_literal_control_2 = "a = 'null\x10'"sv;
+ static constexpr auto string_literal_control_3 = "a = 'null\x1F'"sv;
+ static constexpr auto string_literal_control_4 = "a = 'null\x7F'"sv;
+ static constexpr auto string_literal_multiline_control_1 = "a = '''null\x00'''"sv;
+ static constexpr auto string_literal_multiline_control_2 = "a = '''null\x10'''"sv;
+ static constexpr auto string_literal_multiline_control_3 = "a = '''null\x1F'''"sv;
+ static constexpr auto string_literal_multiline_control_4 = "a = '''null\x7F'''"sv;
+ static constexpr auto string_literal_multiline_quotes =
+ "apos15 = '''Here are fifteen apostrophes: '''''''''''''''''' # INVALID"sv;
+
+ static constexpr auto table_1 = "# DO NOT DO THIS\r\n"
+ "\r\n"
+ "[fruit]\r\n"
+ "apple = \"red\"\r\n"
+ "\r\n"
+ "[fruit]\r\n"
+ "orange = \"orange\""sv;
+ static constexpr auto table_2 = "# DO NOT DO THIS EITHER\r\n"
+ "\r\n"
+ "[fruit]\r\n"
+ "apple = \"red\"\r\n"
+ "\r\n"
+ "[fruit.apple]\r\n"
+ "texture = \"smooth\""sv;
+ static constexpr auto table_3 = "[fruit]\r\n"
+ "apple.color = \"red\"\r\n"
+ "apple.taste.sweet = true\r\n"
+ "\r\n"
+ "[fruit.apple] # INVALID"sv;
+ static constexpr auto table_4 = "[fruit]\r\n"
+ "apple.color = \"red\"\r\n"
+ "apple.taste.sweet = true\r\n"
+ "\r\n"
+ "[fruit.apple.taste] # INVALID"sv;
+ static constexpr auto table_invalid_1 =
+ "[fruit.physical] # subtable, but to which parent element should it belong?\r\n"
+ " color = \"red\"\r\n"
+ " shape = \"round\"\r\n"
+ "\r\n"
+ "[[fruit]] # parser must throw an error upon discovering that \"fruit\" is\r\n"
+ " # an array rather than a table\r\n"
+ " name = \"apple\""sv;
+ static constexpr auto table_invalid_2 = "# INVALID TOML DOC\r\n"
+ "fruit = []\r\n"
+ "\r\n"
+ "[[fruit]] # Not allowed"sv;
+ static constexpr auto table_invalid_3 = "# INVALID TOML DOC\r\n"
+ "[[fruit]]\r\n"
+ " name = \"apple\"\r\n"
+ "\r\n"
+ " [[fruit.variety]]\r\n"
+ " name = \"red delicious\"\r\n"
+ "\r\n"
+ " # INVALID: This table conflicts with the previous array of tables\r\n"
+ " [fruit.variety]\r\n"
+ " name = \"granny smith\"\r\n"
+ "\r\n"
+ " [fruit.physical]\r\n"
+ " color = \"red\"\r\n"
+ " shape = \"round\""sv;
+ static constexpr auto table_invalid_4 = "# INVALID TOML DOC\r\n"
+ "[[fruit]]\r\n"
+ " name = \"apple\"\r\n"
+ "\r\n"
+ " [[fruit.variety]]\r\n"
+ " name = \"red delicious\"\r\n"
+ "\r\n"
+ " [fruit.physical]\r\n"
+ " color = \"red\"\r\n"
+ " shape = \"round\"\r\n"
+ "\r\n"
+ " # INVALID: This array of tables conflicts with the previous table\r\n"
+ " [[fruit.physical]]\r\n"
+ " color = \"green\""sv;
+}
+
+TEST_CASE("conformance - iarna/invalid")
+{
+ SECTION("array-of-tables-1")
+ {
+ parsing_should_fail(FILE_LINE_ARGS, array_of_tables_1); // array-of-tables-1
+ }
+
+ SECTION("array-of-tables-2")
+ {
+ parsing_should_fail(FILE_LINE_ARGS, array_of_tables_2); // array-of-tables-2
+ }
+
+ SECTION("bare-key-1")
+ {
+ parsing_should_fail(FILE_LINE_ARGS, bare_key_1); // bare-key-1
+ }
+
+ SECTION("bare-key-2")
+ {
+ parsing_should_fail(FILE_LINE_ARGS, bare_key_2); // bare-key-2
+ }
+
+ SECTION("bare-key-3")
+ {
+ parsing_should_fail(FILE_LINE_ARGS, bare_key_3); // bare-key-3
+ }
+
+ SECTION("comment-control-1")
+ {
+ parsing_should_fail(FILE_LINE_ARGS, comment_control_1); // comment-control-1
+ }
+
+ SECTION("comment-control-2")
+ {
+ parsing_should_fail(FILE_LINE_ARGS, comment_control_2); // comment-control-2
+ }
+
+ SECTION("comment-control-3")
+ {
+ parsing_should_fail(FILE_LINE_ARGS, comment_control_3); // comment-control-3
+ }
+
+ SECTION("comment-control-4")
+ {
+ parsing_should_fail(FILE_LINE_ARGS, comment_control_4); // comment-control-4
+ }
+
+ SECTION("inline-table-imutable-1")
+ {
+ parsing_should_fail(FILE_LINE_ARGS, inline_table_imutable_1); // inline-table-imutable-1
+ }
+
+ SECTION("inline-table-imutable-2")
+ {
+ parsing_should_fail(FILE_LINE_ARGS, inline_table_imutable_2); // inline-table-imutable-2
+ }
+
+#if !TOML_LANG_UNRELEASED
+
+ SECTION("inline-table-trailing-comma")
+ {
+ parsing_should_fail(FILE_LINE_ARGS, inline_table_trailing_comma); // inline-table-trailing-comma
+ }
+
+#endif // !TOML_LANG_UNRELEASED
+
+ SECTION("int-0-padded")
+ {
+ parsing_should_fail(FILE_LINE_ARGS, int_0_padded); // int-0-padded
+ }
+
+ SECTION("int-signed-bin")
+ {
+ parsing_should_fail(FILE_LINE_ARGS, int_signed_bin); // int-signed-bin
+ }
+
+ SECTION("int-signed-hex")
+ {
+ parsing_should_fail(FILE_LINE_ARGS, int_signed_hex); // int-signed-hex
+ }
+
+ SECTION("int-signed-oct")
+ {
+ parsing_should_fail(FILE_LINE_ARGS, int_signed_oct); // int-signed-oct
+ }
+
+ SECTION("key-value-pair-1")
+ {
+ parsing_should_fail(FILE_LINE_ARGS, key_value_pair_1); // key-value-pair-1
+ }
+
+ SECTION("key-value-pair-2")
+ {
+ parsing_should_fail(FILE_LINE_ARGS, key_value_pair_2); // key-value-pair-2
+ }
+
+ SECTION("multiple-dot-key")
+ {
+ parsing_should_fail(FILE_LINE_ARGS, multiple_dot_key); // multiple-dot-key
+ }
+
+ SECTION("multiple-key")
+ {
+ parsing_should_fail(FILE_LINE_ARGS, multiple_key); // multiple-key
+ }
+
+ SECTION("no-key-name")
+ {
+ parsing_should_fail(FILE_LINE_ARGS, no_key_name); // no-key-name
+ }
+
+ SECTION("string-basic-control-1")
+ {
+ parsing_should_fail(FILE_LINE_ARGS, string_basic_control_1); // string-basic-control-1
+ }
+
+ SECTION("string-basic-control-2")
+ {
+ parsing_should_fail(FILE_LINE_ARGS, string_basic_control_2); // string-basic-control-2
+ }
+
+ SECTION("string-basic-control-3")
+ {
+ parsing_should_fail(FILE_LINE_ARGS, string_basic_control_3); // string-basic-control-3
+ }
+
+ SECTION("string-basic-control-4")
+ {
+ parsing_should_fail(FILE_LINE_ARGS, string_basic_control_4); // string-basic-control-4
+ }
+
+ SECTION("string-basic-multiline-control-1")
+ {
+ parsing_should_fail(FILE_LINE_ARGS, string_basic_multiline_control_1); // string-basic-multiline-control-1
+ }
+
+ SECTION("string-basic-multiline-control-2")
+ {
+ parsing_should_fail(FILE_LINE_ARGS, string_basic_multiline_control_2); // string-basic-multiline-control-2
+ }
+
+ SECTION("string-basic-multiline-control-3")
+ {
+ parsing_should_fail(FILE_LINE_ARGS, string_basic_multiline_control_3); // string-basic-multiline-control-3
+ }
+
+ SECTION("string-basic-multiline-control-4")
+ {
+ parsing_should_fail(FILE_LINE_ARGS, string_basic_multiline_control_4); // string-basic-multiline-control-4
+ }
+
+ SECTION("string-basic-multiline-invalid-backslash")
+ {
+ parsing_should_fail(FILE_LINE_ARGS,
+ string_basic_multiline_invalid_backslash); // string-basic-multiline-invalid-backslash
+ }
+
+ SECTION("string-basic-multiline-out-of-range-unicode-escape-1")
+ {
+ parsing_should_fail(
+ FILE_LINE_ARGS,
+ string_basic_multiline_out_of_range_unicode_escape_1); // string-basic-multiline-out-of-range-unicode-escape-1
+ }
+
+ SECTION("string-basic-multiline-out-of-range-unicode-escape-2")
+ {
+ parsing_should_fail(
+ FILE_LINE_ARGS,
+ string_basic_multiline_out_of_range_unicode_escape_2); // string-basic-multiline-out-of-range-unicode-escape-2
+ }
+
+ SECTION("string-basic-multiline-quotes")
+ {
+ parsing_should_fail(FILE_LINE_ARGS, string_basic_multiline_quotes); // string-basic-multiline-quotes
+ }
+
+ SECTION("string-basic-multiline-unknown-escape")
+ {
+ parsing_should_fail(FILE_LINE_ARGS,
+ string_basic_multiline_unknown_escape); // string-basic-multiline-unknown-escape
+ }
+
+ SECTION("string-basic-out-of-range-unicode-escape-1")
+ {
+ parsing_should_fail(FILE_LINE_ARGS,
+ string_basic_out_of_range_unicode_escape_1); // string-basic-out-of-range-unicode-escape-1
+ }
+
+ SECTION("string-basic-out-of-range-unicode-escape-2")
+ {
+ parsing_should_fail(FILE_LINE_ARGS,
+ string_basic_out_of_range_unicode_escape_2); // string-basic-out-of-range-unicode-escape-2
+ }
+
+ SECTION("string-basic-unknown-escape")
+ {
+ parsing_should_fail(FILE_LINE_ARGS, string_basic_unknown_escape); // string-basic-unknown-escape
+ }
+
+ SECTION("string-literal-control-1")
+ {
+ parsing_should_fail(FILE_LINE_ARGS, string_literal_control_1); // string-literal-control-1
+ }
+
+ SECTION("string-literal-control-2")
+ {
+ parsing_should_fail(FILE_LINE_ARGS, string_literal_control_2); // string-literal-control-2
+ }
+
+ SECTION("string-literal-control-3")
+ {
+ parsing_should_fail(FILE_LINE_ARGS, string_literal_control_3); // string-literal-control-3
+ }
+
+ SECTION("string-literal-control-4")
+ {
+ parsing_should_fail(FILE_LINE_ARGS, string_literal_control_4); // string-literal-control-4
+ }
+
+ SECTION("string-literal-multiline-control-1")
+ {
+ parsing_should_fail(FILE_LINE_ARGS, string_literal_multiline_control_1); // string-literal-multiline-control-1
+ }
+
+ SECTION("string-literal-multiline-control-2")
+ {
+ parsing_should_fail(FILE_LINE_ARGS, string_literal_multiline_control_2); // string-literal-multiline-control-2
+ }
+
+ SECTION("string-literal-multiline-control-3")
+ {
+ parsing_should_fail(FILE_LINE_ARGS, string_literal_multiline_control_3); // string-literal-multiline-control-3
+ }
+
+ SECTION("string-literal-multiline-control-4")
+ {
+ parsing_should_fail(FILE_LINE_ARGS, string_literal_multiline_control_4); // string-literal-multiline-control-4
+ }
+
+ SECTION("string-literal-multiline-quotes")
+ {
+ parsing_should_fail(FILE_LINE_ARGS, string_literal_multiline_quotes); // string-literal-multiline-quotes
+ }
+
+ SECTION("table-1")
+ {
+ parsing_should_fail(FILE_LINE_ARGS, table_1); // table-1
+ }
+
+ SECTION("table-2")
+ {
+ parsing_should_fail(FILE_LINE_ARGS, table_2); // table-2
+ }
+
+ SECTION("table-3")
+ {
+ parsing_should_fail(FILE_LINE_ARGS, table_3); // table-3
+ }
+
+ SECTION("table-4")
+ {
+ parsing_should_fail(FILE_LINE_ARGS, table_4); // table-4
+ }
+
+ SECTION("table-invalid-1")
+ {
+ parsing_should_fail(FILE_LINE_ARGS, table_invalid_1); // table-invalid-1
+ }
+
+ SECTION("table-invalid-2")
+ {
+ parsing_should_fail(FILE_LINE_ARGS, table_invalid_2); // table-invalid-2
+ }
+
+ SECTION("table-invalid-3")
+ {
+ parsing_should_fail(FILE_LINE_ARGS, table_invalid_3); // table-invalid-3
+ }
+
+ SECTION("table-invalid-4")
+ {
+ parsing_should_fail(FILE_LINE_ARGS, table_invalid_4); // table-invalid-4
+ }
+}
diff --git a/tomlplusplus/tests/conformance_iarna_valid.cpp b/tomlplusplus/tests/conformance_iarna_valid.cpp
new file mode 100644
index 0000000000..88489064ba
--- /dev/null
+++ b/tomlplusplus/tests/conformance_iarna_valid.cpp
@@ -0,0 +1,2210 @@
+// This file is a part of toml++ and is subject to the the terms of the MIT license.
+// Copyright (c) Mark Gillard <mark.gillard@outlook.com.au>
+// See https://github.com/marzer/tomlplusplus/blob/master/LICENSE for the full license text.
+// SPDX-License-Identifier: MIT
+//-----
+// this file was generated by generate_conformance_tests.py - do not modify it directly
+
+#include "tests.hpp"
+
+namespace
+{
+ static constexpr auto spec_array_1 = "integers = [ 1, 2, 3 ]"sv;
+ static constexpr auto spec_array_2 = "colors = [ \"red\", \"yellow\", \"green\" ]"sv;
+ static constexpr auto spec_array_3 = "nested_array_of_int = [ [ 1, 2 ], [3, 4, 5] ]"sv;
+ static constexpr auto spec_array_4 = "string_array = [ \"all\", 'strings', \"\"\"are the same\"\"\", '''type''']"sv;
+ static constexpr auto spec_array_5 = "nested_mixed_array = [ [ 1, 2 ], [\"a\", \"b\", \"c\"] ]"sv;
+ static constexpr auto spec_array_7 = "integers2 = [\r\n"
+ " 1, 2, 3\r\n"
+ "]"sv;
+ static constexpr auto spec_array_8 = "integers3 = [\r\n"
+ " 1,\r\n"
+ " 2, # this is ok\r\n"
+ "]"sv;
+ static constexpr auto spec_array_mixed_number_types = "numbers = [ 0.1, 0.2, 0.5, 1, 2, 5 ]"sv;
+ static constexpr auto spec_array_more_mixed_types =
+ "contributors = [\r\n"
+ " \"Foo Bar <foo@example.com>\",\r\n"
+ " { name = \"Baz Qux\", email = \"bazqux@example.com\", url = \"https://example.com/bazqux\" }\r\n"
+ "]"sv;
+ static constexpr auto spec_array_of_tables_1 = "[[products]]\r\n"
+ "name = \"Hammer\"\r\n"
+ "sku = 738594937\r\n"
+ "\r\n"
+ "[[products]]\r\n"
+ "\r\n"
+ "[[products]]\r\n"
+ "name = \"Nail\"\r\n"
+ "sku = 284758393\r\n"
+ "color = \"gray\""sv;
+ static constexpr auto spec_array_of_tables_2 = "[[fruit]]\r\n"
+ " name = \"apple\"\r\n"
+ "\r\n"
+ " [fruit.physical]\r\n"
+ " color = \"red\"\r\n"
+ " shape = \"round\"\r\n"
+ "\r\n"
+ " [[fruit.variety]]\r\n"
+ " name = \"red delicious\"\r\n"
+ "\r\n"
+ " [[fruit.variety]]\r\n"
+ " name = \"granny smith\"\r\n"
+ "\r\n"
+ "[[fruit]]\r\n"
+ " name = \"banana\"\r\n"
+ "\r\n"
+ " [[fruit.variety]]\r\n"
+ " name = \"plantain\""sv;
+ static constexpr auto spec_array_of_tables_3 = "points = [ { x = 1, y = 2, z = 3 },\r\n"
+ " { x = 7, y = 8, z = 9 },\r\n"
+ " { x = 2, y = 4, z = 8 } ]"sv;
+ static constexpr auto spec_boolean_1 = "bool1 = true"sv;
+ static constexpr auto spec_boolean_2 = "bool1 = false"sv;
+ static constexpr auto spec_case_sensitive = "# TOML is case sensitive.\r\n"
+ "abc = 123\r\n"
+ "ABC = 456"sv;
+ static constexpr auto spec_comment_mid_array = "# eol commetns can go anywhere\r\n"
+ "abc = [ # this is valid\r\n"
+ " 123,#as is this\r\n"
+ " 456 #so is this\r\n"
+ " ]# and this\r\n"
+ "# here too"sv;
+ static constexpr auto spec_comment_mid_string = "another = \"# This is not a comment\""sv;
+ static constexpr auto spec_comment_tab =
+ "# This is a full-line comment with a tab in the middle\r\n"
+ "key = \"value\" # This is a commen with a tab in the middle at the end of a line"sv;
+ static constexpr auto spec_comment = "# This is a full-line comment\r\n"
+ "key = \"value\" # This is a comment at the end of a line"sv;
+ static constexpr auto spec_date_local_1 = "ld1 = 1979-05-27"sv;
+ static constexpr auto spec_date_time_1 = "odt1 = 1979-05-27T07:32:00Z"sv;
+ static constexpr auto spec_date_time_2 = "odt2 = 1979-05-27T00:32:00-07:00"sv;
+ static constexpr auto spec_date_time_3 = "odt3 = 1979-05-27T00:32:00.999999-07:00"sv;
+ static constexpr auto spec_date_time_4 = "odt4 = 1979-05-27 07:32:00Z"sv;
+ static constexpr auto spec_date_time_5 = "odt5 = 1979-05-27T07:32:00.123Z"sv;
+ static constexpr auto spec_date_time_local_1 = "ldt1 = 1979-05-27T07:32:00"sv;
+ static constexpr auto spec_dotted_keys_1 = "name = \"Orange\"\r\n"
+ "physical.color = \"orange\"\r\n"
+ "physical.shape = \"round\"\r\n"
+ "site.\"google.com\" = true"sv;
+ static constexpr auto spec_dotted_keys_2 = "a . b = 23"sv;
+ static constexpr auto spec_dotted_keys_3 = "a . b = 23"sv;
+ static constexpr auto spec_empty_key_name_1 = "\"\" = \"blank\" # VALID but discouraged"sv;
+ static constexpr auto spec_empty_key_name_2 = "'' = \"blank\" # VALID but discouraged"sv;
+ static constexpr auto spec_extend_dotted_object_1 = "# This makes the key \"fruit\" into a table.\r\n"
+ "fruit.apple.smooth = true\r\n"
+ "\r\n"
+ "# So then you can add to the table \"fruit\" like so:\r\n"
+ "fruit.orange = 2"sv;
+ static constexpr auto spec_extend_dotted_object_2 = "# VALID BUT DISCOURAGED\r\n"
+ "\r\n"
+ "apple.type = \"fruit\"\r\n"
+ "orange.type = \"fruit\"\r\n"
+ "\r\n"
+ "apple.skin = \"thin\"\r\n"
+ "orange.skin = \"thick\"\r\n"
+ "\r\n"
+ "apple.color = \"red\"\r\n"
+ "orange.color = \"orange\""sv;
+ static constexpr auto spec_extend_dotted_object_3 = "# RECOMMENDED\r\n"
+ "\r\n"
+ "apple.type = \"fruit\"\r\n"
+ "apple.skin = \"thin\"\r\n"
+ "apple.color = \"red\"\r\n"
+ "\r\n"
+ "orange.type = \"fruit\"\r\n"
+ "orange.skin = \"thick\"\r\n"
+ "orange.color = \"orange\""sv;
+ static constexpr auto spec_float_1 = "flt1 = +1.0"sv;
+ static constexpr auto spec_float_10 = "sf1 = inf # positive infinity"sv;
+ static constexpr auto spec_float_11 = "sf2 = +inf # positive infinity"sv;
+ static constexpr auto spec_float_12 = "sf2 = -inf # negative infinity"sv;
+ static constexpr auto spec_float_13 = "sf4 = nan # actual sNaN/qNaN encoding is implementation specific"sv;
+ static constexpr auto spec_float_14 = "sf5 = +nan # same as `nan`"sv;
+ static constexpr auto spec_float_15 = "sf6 = -nan # valid, actual encoding is implementation specific"sv;
+ static constexpr auto spec_float_2 = "flt2 = 3.1415"sv;
+ static constexpr auto spec_float_3 = "flt3 = -0.01"sv;
+ static constexpr auto spec_float_4 = "flt4 = 5e+22"sv;
+ static constexpr auto spec_float_5 = "flt5 = 1e06"sv;
+ static constexpr auto spec_float_6 = "flt6 = -2E-2"sv;
+ static constexpr auto spec_float_7 = "flt7 = 6.626e-34"sv;
+ static constexpr auto spec_float_8 = "flt8 = 224_617.445_991_228"sv;
+ static constexpr auto spec_float_9 = "flt9 = -0e0"sv;
+ static constexpr auto spec_int_1 = "int1 = +99"sv;
+ static constexpr auto spec_int_2 = "int2 = 42"sv;
+ static constexpr auto spec_int_3 = "int3 = 0"sv;
+ static constexpr auto spec_int_3a = "int3 = +0"sv;
+ static constexpr auto spec_int_3b = "int3 = -0"sv;
+ static constexpr auto spec_int_4 = "int4 = -17"sv;
+ static constexpr auto spec_int_5 = "int5 = 1_000"sv;
+ static constexpr auto spec_int_6 = "int6 = 5_349_221"sv;
+ static constexpr auto spec_int_7 = "int7 = 1_2_3_4_5 # VALID but discouraged"sv;
+ static constexpr auto spec_int_bin1 = "bin1 = 0b11010110"sv;
+ static constexpr auto spec_int_hex1 = "hex1 = 0xDEADBEEF"sv;
+ static constexpr auto spec_int_hex2 = "hex2 = 0xdeadbeef"sv;
+ static constexpr auto spec_int_hex3 = "hex3 = 0xdead_beef"sv;
+ static constexpr auto spec_int_max = "max=9_223_372_036_854_775_807"sv;
+ static constexpr auto spec_int_min = "min=-9_223_372_036_854_775_808"sv;
+ static constexpr auto spec_int_oct1 = "oct1 = 0o01234567"sv;
+ static constexpr auto spec_int_oct2 = "oct2 = 0o755 # useful for Unix file permissions"sv;
+ static constexpr auto spec_key_value_pair_1 = "key = \"value\""sv;
+ static constexpr auto spec_key_value_pair_2 = "bare_key = \"value\""sv;
+ static constexpr auto spec_key_value_pair_3 = "bare-key = \"value\""sv;
+ static constexpr auto spec_key_value_pair_4 = "1234 = \"value\""sv;
+ static constexpr auto spec_key_value_pair_5 = "1234=\"value\""sv;
+ static constexpr auto spec_key_value_pair_6 = "-=1"sv;
+ static constexpr auto spec_key_value_pair_7 = "_=1"sv;
+ static constexpr auto spec_key_value_pair_8 = "-_-_-_-_-=1"sv;
+ static constexpr auto spec_key_value_pair_9 = "3.14159 = \"pi\""sv;
+ static constexpr auto spec_newline_1 = R"(abc = 123
+def = 456)"sv;
+ static constexpr auto spec_newline_2 = "abc = 123\r\n"
+ "def = 456"sv;
+ static constexpr auto spec_newline_3 = "abc = 123\r\n"
+ "def = 456\n"
+ "ghi = 789"sv;
+ static constexpr auto spec_quoted_literal_keys_1 = "'quoted \"value\"' = \"value\""sv;
+ static constexpr auto spec_readme_example = "# This is a TOML document.\r\n"
+ "\r\n"
+ "title = \"TOML Example\"\r\n"
+ "\r\n"
+ "[owner]\r\n"
+ "name = \"Tom Preston-Werner\"\r\n"
+ "dob = 1979-05-27T07:32:00-08:00 # First class dates\r\n"
+ "\r\n"
+ "[database]\r\n"
+ "server = \"192.168.1.1\"\r\n"
+ "ports = [ 8001, 8001, 8002 ]\r\n"
+ "connection_max = 5000\r\n"
+ "enabled = true\r\n"
+ "\r\n"
+ "[servers]\r\n"
+ "\r\n"
+ " # Indentation (tabs and/or spaces) is allowed but not required\r\n"
+ " [servers.alpha]\r\n"
+ " ip = \"10.0.0.1\"\r\n"
+ " dc = \"eqdc10\"\r\n"
+ "\r\n"
+ " [servers.beta]\r\n"
+ " ip = \"10.0.0.2\"\r\n"
+ " dc = \"eqdc10\"\r\n"
+ "\r\n"
+ "[clients]\r\n"
+ "data = [ [\"gamma\", \"delta\"], [1, 2] ]\r\n"
+ "\r\n"
+ "# Line breaks are OK when inside arrays\r\n"
+ "hosts = [\r\n"
+ " \"alpha\",\r\n"
+ " \"omega\"\r\n"
+ "]"sv;
+ static constexpr auto spec_string_basic_multiline_1 = "str1 = \"\"\"\r\n"
+ "Roses are red\r\n"
+ "Violets are blue\"\"\""sv;
+ static constexpr auto spec_string_basic_multiline_2 = "str = \"\"\"\r\n"
+ "The quick brown \\\r\n"
+ "\r\n"
+ "\r\n"
+ " fox jumps over \\\r\n"
+ " the lazy dog.\"\"\""sv;
+ static constexpr auto spec_string_basic_multiline_3 = "str = \"\"\"\\\r\n"
+ " The quick brown \\\r\n"
+ " fox jumps over \\\r\n"
+ " the lazy dog.\\\r\n"
+ " \"\"\""sv;
+ static constexpr auto spec_string_basic_multiline_4 = "a = \"\"\"abc\\ \r\n"
+ "def\"\"\""sv;
+ static constexpr auto spec_string_basic_multiline_5 = "ml-escaped-nl = \"\"\"\r\n"
+ " foo \\\r\n"
+ " bar \\\\\r\n"
+ " baz \\\\\\\r\n"
+ " quux\"\"\""sv;
+ static constexpr auto spec_string_basic_multiline_6 =
+ "str4 = \"\"\"Here are two quotation marks: \"\". Simple enough.\"\"\""sv;
+ static constexpr auto spec_string_basic_multiline_7 =
+ "str5 = \"\"\"Here are three quotation marks: \"\"\\\".\"\"\""sv;
+ static constexpr auto spec_string_basic_multiline_8 =
+ "str6 = \"\"\"Here are fifteen quotation marks: \"\"\\\"\"\"\\\"\"\"\\\"\"\"\\\"\"\"\\\".\"\"\""sv;
+ static constexpr auto spec_string_basic_multiline_9 =
+ "str7 = \"\"\"\"This,\" she said, \"is just a pointless statement.\"\"\"\""sv;
+ static constexpr auto spec_string_basic_tab_multiline = "str = \"\"\"This is a tab\"\"\""sv;
+ static constexpr auto spec_string_basic_tab = "str = \"This is a tab\""sv;
+ static constexpr auto spec_string_escape_1 = "a = \"\\b\""sv;
+ static constexpr auto spec_string_escape_2 = "a = \"\\t\""sv;
+ static constexpr auto spec_string_escape_3 = "a = \"\\n\""sv;
+ static constexpr auto spec_string_escape_4 = "a = \"\\f\""sv;
+ static constexpr auto spec_string_escape_5 = "a = \"\\r\""sv;
+ static constexpr auto spec_string_escape_6 = "a = \"\\\"\""sv;
+ static constexpr auto spec_string_escape_7 = "a = \"\\\\\""sv;
+ static constexpr auto spec_string_escape_8 = "a = \"\\u0000\""sv;
+ static constexpr auto spec_string_escape_9 = "a = \"\\U00000000\""sv;
+ static constexpr auto spec_string_literal_1 = "winpath = 'C:\\Users\\nodejs\\templates'"sv;
+ static constexpr auto spec_string_literal_2 = "winpath2 = '\\\\ServerX\\admin$\\system32\\'"sv;
+ static constexpr auto spec_string_literal_3 = "quoted = 'Tom \"Dubs\" Preston-Werner'"sv;
+ static constexpr auto spec_string_literal_4 = "regex = '<\\i\\c*\\s*>'"sv;
+ static constexpr auto spec_string_literal_multiline_1 = "regex2 = '''I [dw]on't need \\d{2} apples'''"sv;
+ static constexpr auto spec_string_literal_multiline_2 = "lines = '''\r\n"
+ "The first newline is\r\n"
+ "trimmed in raw strings.\r\n"
+ " All other whitespace\r\n"
+ " is preserved.\r\n"
+ "'''"sv;
+ static constexpr auto spec_string_literal_multiline_3 =
+ "quot15 = '''Here are fifteen quotation marks: \"\"\"\"\"\"\"\"\"\"\"\"\"\"\"'''"sv;
+ static constexpr auto spec_string_literal_multiline_4 = "str = ''''That,' she said, 'is still pointless.''''"sv;
+ static constexpr auto spec_table_1 = "[table-1]\r\n"
+ "key1 = \"some string\"\r\n"
+ "key2 = 123\r\n"
+ "\r\n"
+ "[table-2]\r\n"
+ "key1 = \"another string\"\r\n"
+ "key2 = 456"sv;
+ static constexpr auto spec_table_2 = "[dog.\"tater.man\"]\r\n"
+ "type.name = \"pug\""sv;
+ static constexpr auto spec_table_3 = "[a.b.c]"sv;
+ static constexpr auto spec_table_4 = "[ d.e.f ] # same as [d.e.f]"sv;
+ static constexpr auto spec_table_5 = "[ g . h . i ] # same as [g.h.i]"sv;
+ static constexpr auto spec_table_7 = "# [x] you\r\n"
+ "# [x.y] don't\r\n"
+ "# [x.y.z] need these\r\n"
+ "[x.y.z.w] # for this to work\r\n"
+ "[x] # defining a super-table afterwards is ok"sv;
+ static constexpr auto spec_table_8 = "[fruit]\r\n"
+ "apple.color = \"red\"\r\n"
+ "apple.taste.sweet = true\r\n"
+ "\r\n"
+ "[fruit.apple.texture] # you can add sub-tables\r\n"
+ "smooth = true"sv;
+ static constexpr auto spec_table_inline_1 = "name = { first = \"Tom\", last = \"Preston-Werner\" }"sv;
+ static constexpr auto spec_table_inline_2 = "point = { x = 1, y = 2 }"sv;
+ static constexpr auto spec_table_inline_3 = "animal = { type.name = \"pug\" } "sv;
+ static constexpr auto spec_table = "[table]"sv;
+ static constexpr auto spec_time_1 = "lt1 = 07:32:00"sv;
+
+#if UNICODE_LITERALS_OK
+
+ static constexpr auto spec_quoted_basic_keys_1 = "\"ʎǝʞ\" = \"value\""sv;
+ static constexpr auto spec_string_basic =
+ "str = \"I'm a string. \\\"You can quote me\\\". Name\\tJos\\u00E9\\nLocation\\tSF.\""sv;
+ static constexpr auto spec_table_6 = "[ j . \"ʞ\" . 'l' ] # same as [j.\"ʞ\".'l']"sv;
+
+#endif // UNICODE_LITERALS_OK
+}
+
+TEST_CASE("conformance - iarna/valid")
+{
+ SECTION("spec-array-1")
+ {
+ parsing_should_succeed(FILE_LINE_ARGS,
+ spec_array_1,
+ [](toml::table&& tbl) // spec-array-1
+ {
+ const auto expected = toml::table{
+ { R"(integers)"sv,
+ toml::array{
+ 1,
+ 2,
+ 3,
+ } },
+ };
+ REQUIRE(tbl == expected);
+ });
+ }
+
+ SECTION("spec-array-2")
+ {
+ parsing_should_succeed(FILE_LINE_ARGS,
+ spec_array_2,
+ [](toml::table&& tbl) // spec-array-2
+ {
+ const auto expected = toml::table{
+ { R"(colors)"sv,
+ toml::array{
+ R"(red)"sv,
+ R"(yellow)"sv,
+ R"(green)"sv,
+ } },
+ };
+ REQUIRE(tbl == expected);
+ });
+ }
+
+ SECTION("spec-array-3")
+ {
+ parsing_should_succeed(FILE_LINE_ARGS,
+ spec_array_3,
+ [](toml::table&& tbl) // spec-array-3
+ {
+ const auto expected = toml::table{
+ { R"(nested_array_of_int)"sv,
+ toml::array{
+ toml::array{
+ 1,
+ 2,
+ },
+ toml::array{
+ 3,
+ 4,
+ 5,
+ },
+ } },
+ };
+ REQUIRE(tbl == expected);
+ });
+ }
+
+ SECTION("spec-array-4")
+ {
+ parsing_should_succeed(FILE_LINE_ARGS,
+ spec_array_4,
+ [](toml::table&& tbl) // spec-array-4
+ {
+ const auto expected = toml::table{
+ { R"(string_array)"sv,
+ toml::array{
+ R"(all)"sv,
+ R"(strings)"sv,
+ R"(are the same)"sv,
+ R"(type)"sv,
+ } },
+ };
+ REQUIRE(tbl == expected);
+ });
+ }
+
+ SECTION("spec-array-5")
+ {
+ parsing_should_succeed(FILE_LINE_ARGS,
+ spec_array_5,
+ [](toml::table&& tbl) // spec-array-5
+ {
+ const auto expected = toml::table{
+ { R"(nested_mixed_array)"sv,
+ toml::array{
+ toml::array{
+ 1,
+ 2,
+ },
+ toml::array{
+ R"(a)"sv,
+ R"(b)"sv,
+ R"(c)"sv,
+ },
+ } },
+ };
+ REQUIRE(tbl == expected);
+ });
+ }
+
+ SECTION("spec-array-7")
+ {
+ parsing_should_succeed(FILE_LINE_ARGS,
+ spec_array_7,
+ [](toml::table&& tbl) // spec-array-7
+ {
+ const auto expected = toml::table{
+ { R"(integers2)"sv,
+ toml::array{
+ 1,
+ 2,
+ 3,
+ } },
+ };
+ REQUIRE(tbl == expected);
+ });
+ }
+
+ SECTION("spec-array-8")
+ {
+ parsing_should_succeed(FILE_LINE_ARGS,
+ spec_array_8,
+ [](toml::table&& tbl) // spec-array-8
+ {
+ const auto expected = toml::table{
+ { R"(integers3)"sv,
+ toml::array{
+ 1,
+ 2,
+ } },
+ };
+ REQUIRE(tbl == expected);
+ });
+ }
+
+ SECTION("spec-array-mixed-number-types")
+ {
+ parsing_should_succeed(FILE_LINE_ARGS,
+ spec_array_mixed_number_types,
+ [](toml::table&& tbl) // spec-array-mixed-number-types
+ {
+ const auto expected = toml::table{
+ { R"(numbers)"sv,
+ toml::array{
+ 0.1,
+ 0.2,
+ 0.5,
+ 1,
+ 2,
+ 5,
+ } },
+ };
+ REQUIRE(tbl == expected);
+ });
+ }
+
+ SECTION("spec-array-more-mixed-types")
+ {
+ parsing_should_succeed(FILE_LINE_ARGS,
+ spec_array_more_mixed_types,
+ [](toml::table&& tbl) // spec-array-more-mixed-types
+ {
+ const auto expected = toml::table{
+ { R"(contributors)"sv,
+ toml::array{
+ R"(Foo Bar <foo@example.com>)"sv,
+ toml::table{
+ { R"(name)"sv, R"(Baz Qux)"sv },
+ { R"(email)"sv, R"(bazqux@example.com)"sv },
+ { R"(url)"sv, R"(https://example.com/bazqux)"sv },
+ },
+ } },
+ };
+ REQUIRE(tbl == expected);
+ });
+ }
+
+ SECTION("spec-array-of-tables-1")
+ {
+ parsing_should_succeed(FILE_LINE_ARGS,
+ spec_array_of_tables_1,
+ [](toml::table&& tbl) // spec-array-of-tables-1
+ {
+ const auto expected = toml::table{
+ { R"(products)"sv,
+ toml::array{
+ toml::table{
+ { R"(name)"sv, R"(Hammer)"sv },
+ { R"(sku)"sv, 738594937 },
+ },
+ toml::table{},
+ toml::table{
+ { R"(name)"sv, R"(Nail)"sv },
+ { R"(sku)"sv, 284758393 },
+ { R"(color)"sv, R"(gray)"sv },
+ },
+ } },
+ };
+ REQUIRE(tbl == expected);
+ });
+ }
+
+ SECTION("spec-array-of-tables-2")
+ {
+ parsing_should_succeed(FILE_LINE_ARGS,
+ spec_array_of_tables_2,
+ [](toml::table&& tbl) // spec-array-of-tables-2
+ {
+ const auto expected = toml::table{
+ { R"(fruit)"sv,
+ toml::array{
+ toml::table{
+ { R"(name)"sv, R"(apple)"sv },
+ { R"(physical)"sv,
+ toml::table{
+ { R"(color)"sv, R"(red)"sv },
+ { R"(shape)"sv, R"(round)"sv },
+ } },
+ { R"(variety)"sv,
+ toml::array{
+ toml::table{
+ { R"(name)"sv, R"(red delicious)"sv },
+ },
+ toml::table{
+ { R"(name)"sv, R"(granny smith)"sv },
+ },
+ } },
+ },
+ toml::table{
+ { R"(name)"sv, R"(banana)"sv },
+ { R"(variety)"sv,
+ toml::array{
+ toml::table{
+ { R"(name)"sv, R"(plantain)"sv },
+ },
+ } },
+ },
+ } },
+ };
+ REQUIRE(tbl == expected);
+ });
+ }
+
+ SECTION("spec-array-of-tables-3")
+ {
+ parsing_should_succeed(FILE_LINE_ARGS,
+ spec_array_of_tables_3,
+ [](toml::table&& tbl) // spec-array-of-tables-3
+ {
+ const auto expected = toml::table{
+ { R"(points)"sv,
+ toml::array{
+ toml::table{
+ { R"(x)"sv, 1 },
+ { R"(y)"sv, 2 },
+ { R"(z)"sv, 3 },
+ },
+ toml::table{
+ { R"(x)"sv, 7 },
+ { R"(y)"sv, 8 },
+ { R"(z)"sv, 9 },
+ },
+ toml::table{
+ { R"(x)"sv, 2 },
+ { R"(y)"sv, 4 },
+ { R"(z)"sv, 8 },
+ },
+ } },
+ };
+ REQUIRE(tbl == expected);
+ });
+ }
+
+ SECTION("spec-boolean-1")
+ {
+ parsing_should_succeed(FILE_LINE_ARGS,
+ spec_boolean_1,
+ [](toml::table&& tbl) // spec-boolean-1
+ {
+ const auto expected = toml::table{
+ { R"(bool1)"sv, true },
+ };
+ REQUIRE(tbl == expected);
+ });
+ }
+
+ SECTION("spec-boolean-2")
+ {
+ parsing_should_succeed(FILE_LINE_ARGS,
+ spec_boolean_2,
+ [](toml::table&& tbl) // spec-boolean-2
+ {
+ const auto expected = toml::table{
+ { R"(bool1)"sv, false },
+ };
+ REQUIRE(tbl == expected);
+ });
+ }
+
+ SECTION("spec-case-sensitive")
+ {
+ parsing_should_succeed(FILE_LINE_ARGS,
+ spec_case_sensitive,
+ [](toml::table&& tbl) // spec-case-sensitive
+ {
+ const auto expected = toml::table{
+ { R"(abc)"sv, 123 },
+ { R"(ABC)"sv, 456 },
+ };
+ REQUIRE(tbl == expected);
+ });
+ }
+
+ SECTION("spec-comment-mid-array")
+ {
+ parsing_should_succeed(FILE_LINE_ARGS,
+ spec_comment_mid_array,
+ [](toml::table&& tbl) // spec-comment-mid-array
+ {
+ const auto expected = toml::table{
+ { R"(abc)"sv,
+ toml::array{
+ 123,
+ 456,
+ } },
+ };
+ REQUIRE(tbl == expected);
+ });
+ }
+
+ SECTION("spec-comment-mid-string")
+ {
+ parsing_should_succeed(FILE_LINE_ARGS,
+ spec_comment_mid_string,
+ [](toml::table&& tbl) // spec-comment-mid-string
+ {
+ const auto expected = toml::table{
+ { R"(another)"sv, R"(# This is not a comment)"sv },
+ };
+ REQUIRE(tbl == expected);
+ });
+ }
+
+ SECTION("spec-comment-tab")
+ {
+ parsing_should_succeed(FILE_LINE_ARGS,
+ spec_comment_tab,
+ [](toml::table&& tbl) // spec-comment-tab
+ {
+ const auto expected = toml::table{
+ { R"(key)"sv, R"(value)"sv },
+ };
+ REQUIRE(tbl == expected);
+ });
+ }
+
+ SECTION("spec-comment")
+ {
+ parsing_should_succeed(FILE_LINE_ARGS,
+ spec_comment,
+ [](toml::table&& tbl) // spec-comment
+ {
+ const auto expected = toml::table{
+ { R"(key)"sv, R"(value)"sv },
+ };
+ REQUIRE(tbl == expected);
+ });
+ }
+
+ SECTION("spec-date-local-1")
+ {
+ parsing_should_succeed(FILE_LINE_ARGS,
+ spec_date_local_1,
+ [](toml::table&& tbl) // spec-date-local-1
+ {
+ const auto expected = toml::table{
+ { R"(ld1)"sv, toml::date{ 1979, 5, 27 } },
+ };
+ REQUIRE(tbl == expected);
+ });
+ }
+
+ SECTION("spec-date-time-1")
+ {
+ parsing_should_succeed(FILE_LINE_ARGS,
+ spec_date_time_1,
+ [](toml::table&& tbl) // spec-date-time-1
+ {
+ const auto expected = toml::table{
+ { R"(odt1)"sv, toml::date_time{ { 1979, 5, 27 }, { 7, 32 }, { 0, 0 } } },
+ };
+ REQUIRE(tbl == expected);
+ });
+ }
+
+ SECTION("spec-date-time-2")
+ {
+ parsing_should_succeed(FILE_LINE_ARGS,
+ spec_date_time_2,
+ [](toml::table&& tbl) // spec-date-time-2
+ {
+ const auto expected = toml::table{
+ { R"(odt2)"sv, toml::date_time{ { 1979, 5, 27 }, { 0, 32 }, { -7, 0 } } },
+ };
+ REQUIRE(tbl == expected);
+ });
+ }
+
+ SECTION("spec-date-time-3")
+ {
+ parsing_should_succeed(
+ FILE_LINE_ARGS,
+ spec_date_time_3,
+ [](toml::table&& tbl) // spec-date-time-3
+ {
+ const auto expected = toml::table{
+ { R"(odt3)"sv, toml::date_time{ { 1979, 5, 27 }, { 0, 32, 0, 999999000 }, { -7, 0 } } },
+ };
+ REQUIRE(tbl == expected);
+ });
+ }
+
+ SECTION("spec-date-time-4")
+ {
+ parsing_should_succeed(FILE_LINE_ARGS,
+ spec_date_time_4,
+ [](toml::table&& tbl) // spec-date-time-4
+ {
+ const auto expected = toml::table{
+ { R"(odt4)"sv, toml::date_time{ { 1979, 5, 27 }, { 7, 32 }, { 0, 0 } } },
+ };
+ REQUIRE(tbl == expected);
+ });
+ }
+
+ SECTION("spec-date-time-5")
+ {
+ parsing_should_succeed(
+ FILE_LINE_ARGS,
+ spec_date_time_5,
+ [](toml::table&& tbl) // spec-date-time-5
+ {
+ const auto expected = toml::table{
+ { R"(odt5)"sv, toml::date_time{ { 1979, 5, 27 }, { 7, 32, 0, 123000000 }, { 0, 0 } } },
+ };
+ REQUIRE(tbl == expected);
+ });
+ }
+
+ SECTION("spec-date-time-local-1")
+ {
+ parsing_should_succeed(FILE_LINE_ARGS,
+ spec_date_time_local_1,
+ [](toml::table&& tbl) // spec-date-time-local-1
+ {
+ const auto expected = toml::table{
+ { R"(ldt1)"sv, toml::date_time{ { 1979, 5, 27 }, { 7, 32 } } },
+ };
+ REQUIRE(tbl == expected);
+ });
+ }
+
+ SECTION("spec-dotted-keys-1")
+ {
+ parsing_should_succeed(FILE_LINE_ARGS,
+ spec_dotted_keys_1,
+ [](toml::table&& tbl) // spec-dotted-keys-1
+ {
+ const auto expected = toml::table{
+ { R"(name)"sv, R"(Orange)"sv },
+ { R"(physical)"sv,
+ toml::table{
+ { R"(color)"sv, R"(orange)"sv },
+ { R"(shape)"sv, R"(round)"sv },
+ } },
+ { R"(site)"sv,
+ toml::table{
+ { R"(google.com)"sv, true },
+ } },
+ };
+ REQUIRE(tbl == expected);
+ });
+ }
+
+ SECTION("spec-dotted-keys-2")
+ {
+ parsing_should_succeed(FILE_LINE_ARGS,
+ spec_dotted_keys_2,
+ [](toml::table&& tbl) // spec-dotted-keys-2
+ {
+ const auto expected = toml::table{
+ { R"(a)"sv,
+ toml::table{
+ { R"(b)"sv, 23 },
+ } },
+ };
+ REQUIRE(tbl == expected);
+ });
+ }
+
+ SECTION("spec-dotted-keys-3")
+ {
+ parsing_should_succeed(FILE_LINE_ARGS,
+ spec_dotted_keys_3,
+ [](toml::table&& tbl) // spec-dotted-keys-3
+ {
+ const auto expected = toml::table{
+ { R"(a)"sv,
+ toml::table{
+ { R"(b)"sv, 23 },
+ } },
+ };
+ REQUIRE(tbl == expected);
+ });
+ }
+
+ SECTION("spec-empty-key-name-1")
+ {
+ parsing_should_succeed(FILE_LINE_ARGS,
+ spec_empty_key_name_1,
+ [](toml::table&& tbl) // spec-empty-key-name-1
+ {
+ const auto expected = toml::table{
+ { ""sv, R"(blank)"sv },
+ };
+ REQUIRE(tbl == expected);
+ });
+ }
+
+ SECTION("spec-empty-key-name-2")
+ {
+ parsing_should_succeed(FILE_LINE_ARGS,
+ spec_empty_key_name_2,
+ [](toml::table&& tbl) // spec-empty-key-name-2
+ {
+ const auto expected = toml::table{
+ { ""sv, R"(blank)"sv },
+ };
+ REQUIRE(tbl == expected);
+ });
+ }
+
+ SECTION("spec-extend-dotted-object-1")
+ {
+ parsing_should_succeed(FILE_LINE_ARGS,
+ spec_extend_dotted_object_1,
+ [](toml::table&& tbl) // spec-extend-dotted-object-1
+ {
+ const auto expected = toml::table{
+ { R"(fruit)"sv,
+ toml::table{
+ { R"(apple)"sv,
+ toml::table{
+ { R"(smooth)"sv, true },
+ } },
+ { R"(orange)"sv, 2 },
+ } },
+ };
+ REQUIRE(tbl == expected);
+ });
+ }
+
+ SECTION("spec-extend-dotted-object-2")
+ {
+ parsing_should_succeed(FILE_LINE_ARGS,
+ spec_extend_dotted_object_2,
+ [](toml::table&& tbl) // spec-extend-dotted-object-2
+ {
+ const auto expected = toml::table{
+ { R"(apple)"sv,
+ toml::table{
+ { R"(type)"sv, R"(fruit)"sv },
+ { R"(skin)"sv, R"(thin)"sv },
+ { R"(color)"sv, R"(red)"sv },
+ } },
+ { R"(orange)"sv,
+ toml::table{
+ { R"(type)"sv, R"(fruit)"sv },
+ { R"(skin)"sv, R"(thick)"sv },
+ { R"(color)"sv, R"(orange)"sv },
+ } },
+ };
+ REQUIRE(tbl == expected);
+ });
+ }
+
+ SECTION("spec-extend-dotted-object-3")
+ {
+ parsing_should_succeed(FILE_LINE_ARGS,
+ spec_extend_dotted_object_3,
+ [](toml::table&& tbl) // spec-extend-dotted-object-3
+ {
+ const auto expected = toml::table{
+ { R"(apple)"sv,
+ toml::table{
+ { R"(type)"sv, R"(fruit)"sv },
+ { R"(skin)"sv, R"(thin)"sv },
+ { R"(color)"sv, R"(red)"sv },
+ } },
+ { R"(orange)"sv,
+ toml::table{
+ { R"(type)"sv, R"(fruit)"sv },
+ { R"(skin)"sv, R"(thick)"sv },
+ { R"(color)"sv, R"(orange)"sv },
+ } },
+ };
+ REQUIRE(tbl == expected);
+ });
+ }
+
+ SECTION("spec-float-1")
+ {
+ parsing_should_succeed(FILE_LINE_ARGS,
+ spec_float_1,
+ [](toml::table&& tbl) // spec-float-1
+ {
+ const auto expected = toml::table{
+ { R"(flt1)"sv, 1.0 },
+ };
+ REQUIRE(tbl == expected);
+ });
+ }
+
+ SECTION("spec-float-10")
+ {
+ parsing_should_succeed(FILE_LINE_ARGS,
+ spec_float_10,
+ [](toml::table&& tbl) // spec-float-10
+ {
+ const auto expected = toml::table{
+ { R"(sf1)"sv, std::numeric_limits<double>::infinity() },
+ };
+ REQUIRE(tbl == expected);
+ });
+ }
+
+ SECTION("spec-float-11")
+ {
+ parsing_should_succeed(FILE_LINE_ARGS,
+ spec_float_11,
+ [](toml::table&& tbl) // spec-float-11
+ {
+ const auto expected = toml::table{
+ { R"(sf2)"sv, std::numeric_limits<double>::infinity() },
+ };
+ REQUIRE(tbl == expected);
+ });
+ }
+
+ SECTION("spec-float-12")
+ {
+ parsing_should_succeed(FILE_LINE_ARGS,
+ spec_float_12,
+ [](toml::table&& tbl) // spec-float-12
+ {
+ const auto expected = toml::table{
+ { R"(sf2)"sv, -std::numeric_limits<double>::infinity() },
+ };
+ REQUIRE(tbl == expected);
+ });
+ }
+
+ SECTION("spec-float-13")
+ {
+ parsing_should_succeed(FILE_LINE_ARGS,
+ spec_float_13,
+ [](toml::table&& tbl) // spec-float-13
+ {
+ const auto expected = toml::table{
+ { R"(sf4)"sv, std::numeric_limits<double>::quiet_NaN() },
+ };
+ REQUIRE(tbl == expected);
+ });
+ }
+
+ SECTION("spec-float-14")
+ {
+ parsing_should_succeed(FILE_LINE_ARGS,
+ spec_float_14,
+ [](toml::table&& tbl) // spec-float-14
+ {
+ const auto expected = toml::table{
+ { R"(sf5)"sv, std::numeric_limits<double>::quiet_NaN() },
+ };
+ REQUIRE(tbl == expected);
+ });
+ }
+
+ SECTION("spec-float-15")
+ {
+ parsing_should_succeed(FILE_LINE_ARGS,
+ spec_float_15,
+ [](toml::table&& tbl) // spec-float-15
+ {
+ const auto expected = toml::table{
+ { R"(sf6)"sv, std::numeric_limits<double>::quiet_NaN() },
+ };
+ REQUIRE(tbl == expected);
+ });
+ }
+
+ SECTION("spec-float-2")
+ {
+ parsing_should_succeed(FILE_LINE_ARGS,
+ spec_float_2,
+ [](toml::table&& tbl) // spec-float-2
+ {
+ const auto expected = toml::table{
+ { R"(flt2)"sv, 3.1415 },
+ };
+ REQUIRE(tbl == expected);
+ });
+ }
+
+ SECTION("spec-float-3")
+ {
+ parsing_should_succeed(FILE_LINE_ARGS,
+ spec_float_3,
+ [](toml::table&& tbl) // spec-float-3
+ {
+ const auto expected = toml::table{
+ { R"(flt3)"sv, -0.01 },
+ };
+ REQUIRE(tbl == expected);
+ });
+ }
+
+ SECTION("spec-float-4")
+ {
+ parsing_should_succeed(FILE_LINE_ARGS,
+ spec_float_4,
+ [](toml::table&& tbl) // spec-float-4
+ {
+ const auto expected = toml::table{
+ { R"(flt4)"sv, 5e+22 },
+ };
+ REQUIRE(tbl == expected);
+ });
+ }
+
+ SECTION("spec-float-5")
+ {
+ parsing_should_succeed(FILE_LINE_ARGS,
+ spec_float_5,
+ [](toml::table&& tbl) // spec-float-5
+ {
+ const auto expected = toml::table{
+ { R"(flt5)"sv, 1000000.0 },
+ };
+ REQUIRE(tbl == expected);
+ });
+ }
+
+ SECTION("spec-float-6")
+ {
+ parsing_should_succeed(FILE_LINE_ARGS,
+ spec_float_6,
+ [](toml::table&& tbl) // spec-float-6
+ {
+ const auto expected = toml::table{
+ { R"(flt6)"sv, -0.02 },
+ };
+ REQUIRE(tbl == expected);
+ });
+ }
+
+ SECTION("spec-float-7")
+ {
+ parsing_should_succeed(FILE_LINE_ARGS,
+ spec_float_7,
+ [](toml::table&& tbl) // spec-float-7
+ {
+ const auto expected = toml::table{
+ { R"(flt7)"sv, 6.626e-34 },
+ };
+ REQUIRE(tbl == expected);
+ });
+ }
+
+ SECTION("spec-float-8")
+ {
+ parsing_should_succeed(FILE_LINE_ARGS,
+ spec_float_8,
+ [](toml::table&& tbl) // spec-float-8
+ {
+ const auto expected = toml::table{
+ { R"(flt8)"sv, 224617.445991228 },
+ };
+ REQUIRE(tbl == expected);
+ });
+ }
+
+ SECTION("spec-float-9")
+ {
+ parsing_should_succeed(FILE_LINE_ARGS,
+ spec_float_9,
+ [](toml::table&& tbl) // spec-float-9
+ {
+ const auto expected = toml::table{
+ { R"(flt9)"sv, -0.0 },
+ };
+ REQUIRE(tbl == expected);
+ });
+ }
+
+ SECTION("spec-int-1")
+ {
+ parsing_should_succeed(FILE_LINE_ARGS,
+ spec_int_1,
+ [](toml::table&& tbl) // spec-int-1
+ {
+ const auto expected = toml::table{
+ { R"(int1)"sv, 99 },
+ };
+ REQUIRE(tbl == expected);
+ });
+ }
+
+ SECTION("spec-int-2")
+ {
+ parsing_should_succeed(FILE_LINE_ARGS,
+ spec_int_2,
+ [](toml::table&& tbl) // spec-int-2
+ {
+ const auto expected = toml::table{
+ { R"(int2)"sv, 42 },
+ };
+ REQUIRE(tbl == expected);
+ });
+ }
+
+ SECTION("spec-int-3")
+ {
+ parsing_should_succeed(FILE_LINE_ARGS,
+ spec_int_3,
+ [](toml::table&& tbl) // spec-int-3
+ {
+ const auto expected = toml::table{
+ { R"(int3)"sv, 0 },
+ };
+ REQUIRE(tbl == expected);
+ });
+ }
+
+ SECTION("spec-int-3a")
+ {
+ parsing_should_succeed(FILE_LINE_ARGS,
+ spec_int_3a,
+ [](toml::table&& tbl) // spec-int-3a
+ {
+ const auto expected = toml::table{
+ { R"(int3)"sv, 0 },
+ };
+ REQUIRE(tbl == expected);
+ });
+ }
+
+ SECTION("spec-int-3b")
+ {
+ parsing_should_succeed(FILE_LINE_ARGS,
+ spec_int_3b,
+ [](toml::table&& tbl) // spec-int-3b
+ {
+ const auto expected = toml::table{
+ { R"(int3)"sv, 0 },
+ };
+ REQUIRE(tbl == expected);
+ });
+ }
+
+ SECTION("spec-int-4")
+ {
+ parsing_should_succeed(FILE_LINE_ARGS,
+ spec_int_4,
+ [](toml::table&& tbl) // spec-int-4
+ {
+ const auto expected = toml::table{
+ { R"(int4)"sv, -17 },
+ };
+ REQUIRE(tbl == expected);
+ });
+ }
+
+ SECTION("spec-int-5")
+ {
+ parsing_should_succeed(FILE_LINE_ARGS,
+ spec_int_5,
+ [](toml::table&& tbl) // spec-int-5
+ {
+ const auto expected = toml::table{
+ { R"(int5)"sv, 1000 },
+ };
+ REQUIRE(tbl == expected);
+ });
+ }
+
+ SECTION("spec-int-6")
+ {
+ parsing_should_succeed(FILE_LINE_ARGS,
+ spec_int_6,
+ [](toml::table&& tbl) // spec-int-6
+ {
+ const auto expected = toml::table{
+ { R"(int6)"sv, 5349221 },
+ };
+ REQUIRE(tbl == expected);
+ });
+ }
+
+ SECTION("spec-int-7")
+ {
+ parsing_should_succeed(FILE_LINE_ARGS,
+ spec_int_7,
+ [](toml::table&& tbl) // spec-int-7
+ {
+ const auto expected = toml::table{
+ { R"(int7)"sv, 12345 },
+ };
+ REQUIRE(tbl == expected);
+ });
+ }
+
+ SECTION("spec-int-bin1")
+ {
+ parsing_should_succeed(FILE_LINE_ARGS,
+ spec_int_bin1,
+ [](toml::table&& tbl) // spec-int-bin1
+ {
+ const auto expected = toml::table{
+ { R"(bin1)"sv, 214 },
+ };
+ REQUIRE(tbl == expected);
+ });
+ }
+
+ SECTION("spec-int-hex1")
+ {
+ parsing_should_succeed(FILE_LINE_ARGS,
+ spec_int_hex1,
+ [](toml::table&& tbl) // spec-int-hex1
+ {
+ const auto expected = toml::table{
+ { R"(hex1)"sv, 3735928559 },
+ };
+ REQUIRE(tbl == expected);
+ });
+ }
+
+ SECTION("spec-int-hex2")
+ {
+ parsing_should_succeed(FILE_LINE_ARGS,
+ spec_int_hex2,
+ [](toml::table&& tbl) // spec-int-hex2
+ {
+ const auto expected = toml::table{
+ { R"(hex2)"sv, 3735928559 },
+ };
+ REQUIRE(tbl == expected);
+ });
+ }
+
+ SECTION("spec-int-hex3")
+ {
+ parsing_should_succeed(FILE_LINE_ARGS,
+ spec_int_hex3,
+ [](toml::table&& tbl) // spec-int-hex3
+ {
+ const auto expected = toml::table{
+ { R"(hex3)"sv, 3735928559 },
+ };
+ REQUIRE(tbl == expected);
+ });
+ }
+
+ SECTION("spec-int-max")
+ {
+ parsing_should_succeed(FILE_LINE_ARGS,
+ spec_int_max,
+ [](toml::table&& tbl) // spec-int-max
+ {
+ const auto expected = toml::table{
+ { R"(max)"sv, std::numeric_limits<int64_t>::max() },
+ };
+ REQUIRE(tbl == expected);
+ });
+ }
+
+ SECTION("spec-int-min")
+ {
+ parsing_should_succeed(FILE_LINE_ARGS,
+ spec_int_min,
+ [](toml::table&& tbl) // spec-int-min
+ {
+ const auto expected = toml::table{
+ { R"(min)"sv, std::numeric_limits<int64_t>::min() },
+ };
+ REQUIRE(tbl == expected);
+ });
+ }
+
+ SECTION("spec-int-oct1")
+ {
+ parsing_should_succeed(FILE_LINE_ARGS,
+ spec_int_oct1,
+ [](toml::table&& tbl) // spec-int-oct1
+ {
+ const auto expected = toml::table{
+ { R"(oct1)"sv, 342391 },
+ };
+ REQUIRE(tbl == expected);
+ });
+ }
+
+ SECTION("spec-int-oct2")
+ {
+ parsing_should_succeed(FILE_LINE_ARGS,
+ spec_int_oct2,
+ [](toml::table&& tbl) // spec-int-oct2
+ {
+ const auto expected = toml::table{
+ { R"(oct2)"sv, 493 },
+ };
+ REQUIRE(tbl == expected);
+ });
+ }
+
+ SECTION("spec-key-value-pair-1")
+ {
+ parsing_should_succeed(FILE_LINE_ARGS,
+ spec_key_value_pair_1,
+ [](toml::table&& tbl) // spec-key-value-pair-1
+ {
+ const auto expected = toml::table{
+ { R"(key)"sv, R"(value)"sv },
+ };
+ REQUIRE(tbl == expected);
+ });
+ }
+
+ SECTION("spec-key-value-pair-2")
+ {
+ parsing_should_succeed(FILE_LINE_ARGS,
+ spec_key_value_pair_2,
+ [](toml::table&& tbl) // spec-key-value-pair-2
+ {
+ const auto expected = toml::table{
+ { R"(bare_key)"sv, R"(value)"sv },
+ };
+ REQUIRE(tbl == expected);
+ });
+ }
+
+ SECTION("spec-key-value-pair-3")
+ {
+ parsing_should_succeed(FILE_LINE_ARGS,
+ spec_key_value_pair_3,
+ [](toml::table&& tbl) // spec-key-value-pair-3
+ {
+ const auto expected = toml::table{
+ { R"(bare-key)"sv, R"(value)"sv },
+ };
+ REQUIRE(tbl == expected);
+ });
+ }
+
+ SECTION("spec-key-value-pair-4")
+ {
+ parsing_should_succeed(FILE_LINE_ARGS,
+ spec_key_value_pair_4,
+ [](toml::table&& tbl) // spec-key-value-pair-4
+ {
+ const auto expected = toml::table{
+ { R"(1234)"sv, R"(value)"sv },
+ };
+ REQUIRE(tbl == expected);
+ });
+ }
+
+ SECTION("spec-key-value-pair-5")
+ {
+ parsing_should_succeed(FILE_LINE_ARGS,
+ spec_key_value_pair_5,
+ [](toml::table&& tbl) // spec-key-value-pair-5
+ {
+ const auto expected = toml::table{
+ { R"(1234)"sv, R"(value)"sv },
+ };
+ REQUIRE(tbl == expected);
+ });
+ }
+
+ SECTION("spec-key-value-pair-6")
+ {
+ parsing_should_succeed(FILE_LINE_ARGS,
+ spec_key_value_pair_6,
+ [](toml::table&& tbl) // spec-key-value-pair-6
+ {
+ const auto expected = toml::table{
+ { R"(-)"sv, 1 },
+ };
+ REQUIRE(tbl == expected);
+ });
+ }
+
+ SECTION("spec-key-value-pair-7")
+ {
+ parsing_should_succeed(FILE_LINE_ARGS,
+ spec_key_value_pair_7,
+ [](toml::table&& tbl) // spec-key-value-pair-7
+ {
+ const auto expected = toml::table{
+ { R"(_)"sv, 1 },
+ };
+ REQUIRE(tbl == expected);
+ });
+ }
+
+ SECTION("spec-key-value-pair-8")
+ {
+ parsing_should_succeed(FILE_LINE_ARGS,
+ spec_key_value_pair_8,
+ [](toml::table&& tbl) // spec-key-value-pair-8
+ {
+ const auto expected = toml::table{
+ { R"(-_-_-_-_-)"sv, 1 },
+ };
+ REQUIRE(tbl == expected);
+ });
+ }
+
+ SECTION("spec-key-value-pair-9")
+ {
+ parsing_should_succeed(FILE_LINE_ARGS,
+ spec_key_value_pair_9,
+ [](toml::table&& tbl) // spec-key-value-pair-9
+ {
+ const auto expected = toml::table{
+ { R"(3)"sv,
+ toml::table{
+ { R"(14159)"sv, R"(pi)"sv },
+ } },
+ };
+ REQUIRE(tbl == expected);
+ });
+ }
+
+ SECTION("spec-newline-1")
+ {
+ parsing_should_succeed(FILE_LINE_ARGS,
+ spec_newline_1,
+ [](toml::table&& tbl) // spec-newline-1
+ {
+ const auto expected = toml::table{
+ { R"(abc)"sv, 123 },
+ { R"(def)"sv, 456 },
+ };
+ REQUIRE(tbl == expected);
+ });
+ }
+
+ SECTION("spec-newline-2")
+ {
+ parsing_should_succeed(FILE_LINE_ARGS,
+ spec_newline_2,
+ [](toml::table&& tbl) // spec-newline-2
+ {
+ const auto expected = toml::table{
+ { R"(abc)"sv, 123 },
+ { R"(def)"sv, 456 },
+ };
+ REQUIRE(tbl == expected);
+ });
+ }
+
+ SECTION("spec-newline-3")
+ {
+ parsing_should_succeed(FILE_LINE_ARGS,
+ spec_newline_3,
+ [](toml::table&& tbl) // spec-newline-3
+ {
+ const auto expected = toml::table{
+ { R"(abc)"sv, 123 },
+ { R"(def)"sv, 456 },
+ { R"(ghi)"sv, 789 },
+ };
+ REQUIRE(tbl == expected);
+ });
+ }
+
+ SECTION("spec-quoted-literal-keys-1")
+ {
+ parsing_should_succeed(FILE_LINE_ARGS,
+ spec_quoted_literal_keys_1,
+ [](toml::table&& tbl) // spec-quoted-literal-keys-1
+ {
+ const auto expected = toml::table{
+ { R"(quoted "value")"sv, R"(value)"sv },
+ };
+ REQUIRE(tbl == expected);
+ });
+ }
+
+ SECTION("spec-readme-example")
+ {
+ parsing_should_succeed(FILE_LINE_ARGS,
+ spec_readme_example,
+ [](toml::table&& tbl) // spec-readme-example
+ {
+ const auto expected = toml::table{
+ { R"(title)"sv, R"(TOML Example)"sv },
+ { R"(owner)"sv,
+ toml::table{
+ { R"(name)"sv, R"(Tom Preston-Werner)"sv },
+ { R"(dob)"sv, toml::date_time{ { 1979, 5, 27 }, { 7, 32 }, { -8, 0 } } },
+ } },
+ { R"(database)"sv,
+ toml::table{
+ { R"(server)"sv, R"(192.168.1.1)"sv },
+ { R"(ports)"sv,
+ toml::array{
+ 8001,
+ 8001,
+ 8002,
+ } },
+ { R"(connection_max)"sv, 5000 },
+ { R"(enabled)"sv, true },
+ } },
+ { R"(servers)"sv,
+ toml::table{
+ { R"(alpha)"sv,
+ toml::table{
+ { R"(ip)"sv, R"(10.0.0.1)"sv },
+ { R"(dc)"sv, R"(eqdc10)"sv },
+ } },
+ { R"(beta)"sv,
+ toml::table{
+ { R"(ip)"sv, R"(10.0.0.2)"sv },
+ { R"(dc)"sv, R"(eqdc10)"sv },
+ } },
+ } },
+ { R"(clients)"sv,
+ toml::table{
+ { R"(data)"sv,
+ toml::array{
+ toml::array{
+ R"(gamma)"sv,
+ R"(delta)"sv,
+ },
+ toml::array{
+ 1,
+ 2,
+ },
+ } },
+ { R"(hosts)"sv,
+ toml::array{
+ R"(alpha)"sv,
+ R"(omega)"sv,
+ } },
+ } },
+ };
+ REQUIRE(tbl == expected);
+ });
+ }
+
+ SECTION("spec-string-basic-multiline-1")
+ {
+ parsing_should_succeed(FILE_LINE_ARGS,
+ spec_string_basic_multiline_1,
+ [](toml::table&& tbl) // spec-string-basic-multiline-1
+ {
+ const auto expected = toml::table{
+ { R"(str1)"sv, R"(Roses are red
+Violets are blue)"sv },
+ };
+ REQUIRE(tbl == expected);
+ });
+ }
+
+ SECTION("spec-string-basic-multiline-2")
+ {
+ parsing_should_succeed(FILE_LINE_ARGS,
+ spec_string_basic_multiline_2,
+ [](toml::table&& tbl) // spec-string-basic-multiline-2
+ {
+ const auto expected = toml::table{
+ { R"(str)"sv, R"(The quick brown fox jumps over the lazy dog.)"sv },
+ };
+ REQUIRE(tbl == expected);
+ });
+ }
+
+ SECTION("spec-string-basic-multiline-3")
+ {
+ parsing_should_succeed(FILE_LINE_ARGS,
+ spec_string_basic_multiline_3,
+ [](toml::table&& tbl) // spec-string-basic-multiline-3
+ {
+ const auto expected = toml::table{
+ { R"(str)"sv, R"(The quick brown fox jumps over the lazy dog.)"sv },
+ };
+ REQUIRE(tbl == expected);
+ });
+ }
+
+ SECTION("spec-string-basic-multiline-4")
+ {
+ parsing_should_succeed(FILE_LINE_ARGS,
+ spec_string_basic_multiline_4,
+ [](toml::table&& tbl) // spec-string-basic-multiline-4
+ {
+ const auto expected = toml::table{
+ { R"(a)"sv, R"(abcdef)"sv },
+ };
+ REQUIRE(tbl == expected);
+ });
+ }
+
+ SECTION("spec-string-basic-multiline-5")
+ {
+ parsing_should_succeed(FILE_LINE_ARGS,
+ spec_string_basic_multiline_5,
+ [](toml::table&& tbl) // spec-string-basic-multiline-5
+ {
+ const auto expected = toml::table{
+ { R"(ml-escaped-nl)"sv, R"( foo bar \
+ baz \quux)"sv },
+ };
+ REQUIRE(tbl == expected);
+ });
+ }
+
+ SECTION("spec-string-basic-multiline-6")
+ {
+ parsing_should_succeed(FILE_LINE_ARGS,
+ spec_string_basic_multiline_6,
+ [](toml::table&& tbl) // spec-string-basic-multiline-6
+ {
+ const auto expected = toml::table{
+ { R"(str4)"sv, R"(Here are two quotation marks: "". Simple enough.)"sv },
+ };
+ REQUIRE(tbl == expected);
+ });
+ }
+
+ SECTION("spec-string-basic-multiline-7")
+ {
+ parsing_should_succeed(FILE_LINE_ARGS,
+ spec_string_basic_multiline_7,
+ [](toml::table&& tbl) // spec-string-basic-multiline-7
+ {
+ const auto expected = toml::table{
+ { R"(str5)"sv, R"(Here are three quotation marks: """.)"sv },
+ };
+ REQUIRE(tbl == expected);
+ });
+ }
+
+ SECTION("spec-string-basic-multiline-8")
+ {
+ parsing_should_succeed(FILE_LINE_ARGS,
+ spec_string_basic_multiline_8,
+ [](toml::table&& tbl) // spec-string-basic-multiline-8
+ {
+ const auto expected = toml::table{
+ { R"(str6)"sv, R"(Here are fifteen quotation marks: """"""""""""""".)"sv },
+ };
+ REQUIRE(tbl == expected);
+ });
+ }
+
+ SECTION("spec-string-basic-multiline-9")
+ {
+ parsing_should_succeed(FILE_LINE_ARGS,
+ spec_string_basic_multiline_9,
+ [](toml::table&& tbl) // spec-string-basic-multiline-9
+ {
+ const auto expected = toml::table{
+ { R"(str7)"sv, R"("This," she said, "is just a pointless statement.")"sv },
+ };
+ REQUIRE(tbl == expected);
+ });
+ }
+
+ SECTION("spec-string-basic-tab-multiline")
+ {
+ parsing_should_succeed(FILE_LINE_ARGS,
+ spec_string_basic_tab_multiline,
+ [](toml::table&& tbl) // spec-string-basic-tab-multiline
+ {
+ const auto expected = toml::table{
+ { R"(str)"sv, R"(This is a tab)"sv },
+ };
+ REQUIRE(tbl == expected);
+ });
+ }
+
+ SECTION("spec-string-basic-tab")
+ {
+ parsing_should_succeed(FILE_LINE_ARGS,
+ spec_string_basic_tab,
+ [](toml::table&& tbl) // spec-string-basic-tab
+ {
+ const auto expected = toml::table{
+ { R"(str)"sv, R"(This is a tab)"sv },
+ };
+ REQUIRE(tbl == expected);
+ });
+ }
+
+ SECTION("spec-string-escape-1")
+ {
+ parsing_should_succeed(FILE_LINE_ARGS,
+ spec_string_escape_1,
+ [](toml::table&& tbl) // spec-string-escape-1
+ {
+ const auto expected = toml::table{
+ { R"(a)"sv, "\x08"sv },
+ };
+ REQUIRE(tbl == expected);
+ });
+ }
+
+ SECTION("spec-string-escape-2")
+ {
+ parsing_should_succeed(FILE_LINE_ARGS,
+ spec_string_escape_2,
+ [](toml::table&& tbl) // spec-string-escape-2
+ {
+ const auto expected = toml::table{
+ { R"(a)"sv, R"( )"sv },
+ };
+ REQUIRE(tbl == expected);
+ });
+ }
+
+ SECTION("spec-string-escape-3")
+ {
+ parsing_should_succeed(FILE_LINE_ARGS,
+ spec_string_escape_3,
+ [](toml::table&& tbl) // spec-string-escape-3
+ {
+ const auto expected = toml::table{
+ { R"(a)"sv, R"(
+)"sv },
+ };
+ REQUIRE(tbl == expected);
+ });
+ }
+
+ SECTION("spec-string-escape-4")
+ {
+ parsing_should_succeed(FILE_LINE_ARGS,
+ spec_string_escape_4,
+ [](toml::table&& tbl) // spec-string-escape-4
+ {
+ const auto expected = toml::table{
+ { R"(a)"sv, "\f"sv },
+ };
+ REQUIRE(tbl == expected);
+ });
+ }
+
+ SECTION("spec-string-escape-5")
+ {
+ parsing_should_succeed(FILE_LINE_ARGS,
+ spec_string_escape_5,
+ [](toml::table&& tbl) // spec-string-escape-5
+ {
+ const auto expected = toml::table{
+ { R"(a)"sv, "\r"sv },
+ };
+ REQUIRE(tbl == expected);
+ });
+ }
+
+ SECTION("spec-string-escape-6")
+ {
+ parsing_should_succeed(FILE_LINE_ARGS,
+ spec_string_escape_6,
+ [](toml::table&& tbl) // spec-string-escape-6
+ {
+ const auto expected = toml::table{
+ { R"(a)"sv, R"(")"sv },
+ };
+ REQUIRE(tbl == expected);
+ });
+ }
+
+ SECTION("spec-string-escape-7")
+ {
+ parsing_should_succeed(FILE_LINE_ARGS,
+ spec_string_escape_7,
+ [](toml::table&& tbl) // spec-string-escape-7
+ {
+ const auto expected = toml::table{
+ { R"(a)"sv, R"(\)"sv },
+ };
+ REQUIRE(tbl == expected);
+ });
+ }
+
+ SECTION("spec-string-escape-8")
+ {
+ parsing_should_succeed(FILE_LINE_ARGS,
+ spec_string_escape_8,
+ [](toml::table&& tbl) // spec-string-escape-8
+ {
+ const auto expected = toml::table{
+ { R"(a)"sv, "\x00"sv },
+ };
+ REQUIRE(tbl == expected);
+ });
+ }
+
+ SECTION("spec-string-escape-9")
+ {
+ parsing_should_succeed(FILE_LINE_ARGS,
+ spec_string_escape_9,
+ [](toml::table&& tbl) // spec-string-escape-9
+ {
+ const auto expected = toml::table{
+ { R"(a)"sv, "\x00"sv },
+ };
+ REQUIRE(tbl == expected);
+ });
+ }
+
+ SECTION("spec-string-literal-1")
+ {
+ parsing_should_succeed(FILE_LINE_ARGS,
+ spec_string_literal_1,
+ [](toml::table&& tbl) // spec-string-literal-1
+ {
+ const auto expected = toml::table{
+ { R"(winpath)"sv, R"(C:\Users\nodejs\templates)"sv },
+ };
+ REQUIRE(tbl == expected);
+ });
+ }
+
+ SECTION("spec-string-literal-2")
+ {
+ parsing_should_succeed(FILE_LINE_ARGS,
+ spec_string_literal_2,
+ [](toml::table&& tbl) // spec-string-literal-2
+ {
+ const auto expected = toml::table{
+ { R"(winpath2)"sv, R"(\\ServerX\admin$\system32\)"sv },
+ };
+ REQUIRE(tbl == expected);
+ });
+ }
+
+ SECTION("spec-string-literal-3")
+ {
+ parsing_should_succeed(FILE_LINE_ARGS,
+ spec_string_literal_3,
+ [](toml::table&& tbl) // spec-string-literal-3
+ {
+ const auto expected = toml::table{
+ { R"(quoted)"sv, R"(Tom "Dubs" Preston-Werner)"sv },
+ };
+ REQUIRE(tbl == expected);
+ });
+ }
+
+ SECTION("spec-string-literal-4")
+ {
+ parsing_should_succeed(FILE_LINE_ARGS,
+ spec_string_literal_4,
+ [](toml::table&& tbl) // spec-string-literal-4
+ {
+ const auto expected = toml::table{
+ { R"(regex)"sv, R"(<\i\c*\s*>)"sv },
+ };
+ REQUIRE(tbl == expected);
+ });
+ }
+
+ SECTION("spec-string-literal-multiline-1")
+ {
+ parsing_should_succeed(FILE_LINE_ARGS,
+ spec_string_literal_multiline_1,
+ [](toml::table&& tbl) // spec-string-literal-multiline-1
+ {
+ const auto expected = toml::table{
+ { R"(regex2)"sv, R"(I [dw]on't need \d{2} apples)"sv },
+ };
+ REQUIRE(tbl == expected);
+ });
+ }
+
+ SECTION("spec-string-literal-multiline-2")
+ {
+ parsing_should_succeed(FILE_LINE_ARGS,
+ spec_string_literal_multiline_2,
+ [](toml::table&& tbl) // spec-string-literal-multiline-2
+ {
+ const auto expected = toml::table{
+ { R"(lines)"sv, R"(The first newline is
+trimmed in raw strings.
+ All other whitespace
+ is preserved.
+)"sv },
+ };
+ REQUIRE(tbl == expected);
+ });
+ }
+
+ SECTION("spec-string-literal-multiline-3")
+ {
+ parsing_should_succeed(FILE_LINE_ARGS,
+ spec_string_literal_multiline_3,
+ [](toml::table&& tbl) // spec-string-literal-multiline-3
+ {
+ const auto expected = toml::table{
+ { R"(quot15)"sv, R"(Here are fifteen quotation marks: """"""""""""""")"sv },
+ };
+ REQUIRE(tbl == expected);
+ });
+ }
+
+ SECTION("spec-string-literal-multiline-4")
+ {
+ parsing_should_succeed(FILE_LINE_ARGS,
+ spec_string_literal_multiline_4,
+ [](toml::table&& tbl) // spec-string-literal-multiline-4
+ {
+ const auto expected = toml::table{
+ { R"(str)"sv, R"('That,' she said, 'is still pointless.')"sv },
+ };
+ REQUIRE(tbl == expected);
+ });
+ }
+
+ SECTION("spec-table-1")
+ {
+ parsing_should_succeed(FILE_LINE_ARGS,
+ spec_table_1,
+ [](toml::table&& tbl) // spec-table-1
+ {
+ const auto expected = toml::table{
+ { R"(table-1)"sv,
+ toml::table{
+ { R"(key1)"sv, R"(some string)"sv },
+ { R"(key2)"sv, 123 },
+ } },
+ { R"(table-2)"sv,
+ toml::table{
+ { R"(key1)"sv, R"(another string)"sv },
+ { R"(key2)"sv, 456 },
+ } },
+ };
+ REQUIRE(tbl == expected);
+ });
+ }
+
+ SECTION("spec-table-2")
+ {
+ parsing_should_succeed(FILE_LINE_ARGS,
+ spec_table_2,
+ [](toml::table&& tbl) // spec-table-2
+ {
+ const auto expected = toml::table{
+ { R"(dog)"sv,
+ toml::table{
+ { R"(tater.man)"sv,
+ toml::table{
+ { R"(type)"sv,
+ toml::table{
+ { R"(name)"sv, R"(pug)"sv },
+ } },
+ } },
+ } },
+ };
+ REQUIRE(tbl == expected);
+ });
+ }
+
+ SECTION("spec-table-3")
+ {
+ parsing_should_succeed(FILE_LINE_ARGS,
+ spec_table_3,
+ [](toml::table&& tbl) // spec-table-3
+ {
+ const auto expected = toml::table{
+ { R"(a)"sv,
+ toml::table{
+ { R"(b)"sv,
+ toml::table{
+ { R"(c)"sv, toml::table{} },
+ } },
+ } },
+ };
+ REQUIRE(tbl == expected);
+ });
+ }
+
+ SECTION("spec-table-4")
+ {
+ parsing_should_succeed(FILE_LINE_ARGS,
+ spec_table_4,
+ [](toml::table&& tbl) // spec-table-4
+ {
+ const auto expected = toml::table{
+ { R"(d)"sv,
+ toml::table{
+ { R"(e)"sv,
+ toml::table{
+ { R"(f)"sv, toml::table{} },
+ } },
+ } },
+ };
+ REQUIRE(tbl == expected);
+ });
+ }
+
+ SECTION("spec-table-5")
+ {
+ parsing_should_succeed(FILE_LINE_ARGS,
+ spec_table_5,
+ [](toml::table&& tbl) // spec-table-5
+ {
+ const auto expected = toml::table{
+ { R"(g)"sv,
+ toml::table{
+ { R"(h)"sv,
+ toml::table{
+ { R"(i)"sv, toml::table{} },
+ } },
+ } },
+ };
+ REQUIRE(tbl == expected);
+ });
+ }
+
+ SECTION("spec-table-7")
+ {
+ parsing_should_succeed(FILE_LINE_ARGS,
+ spec_table_7,
+ [](toml::table&& tbl) // spec-table-7
+ {
+ const auto expected = toml::table{
+ { R"(x)"sv,
+ toml::table{
+ { R"(y)"sv,
+ toml::table{
+ { R"(z)"sv,
+ toml::table{
+ { R"(w)"sv, toml::table{} },
+ } },
+ } },
+ } },
+ };
+ REQUIRE(tbl == expected);
+ });
+ }
+
+ SECTION("spec-table-8")
+ {
+ parsing_should_succeed(FILE_LINE_ARGS,
+ spec_table_8,
+ [](toml::table&& tbl) // spec-table-8
+ {
+ const auto expected = toml::table{
+ { R"(fruit)"sv,
+ toml::table{
+ { R"(apple)"sv,
+ toml::table{
+ { R"(color)"sv, R"(red)"sv },
+ { R"(taste)"sv,
+ toml::table{
+ { R"(sweet)"sv, true },
+ } },
+ { R"(texture)"sv,
+ toml::table{
+ { R"(smooth)"sv, true },
+ } },
+ } },
+ } },
+ };
+ REQUIRE(tbl == expected);
+ });
+ }
+
+ SECTION("spec-table-inline-1")
+ {
+ parsing_should_succeed(FILE_LINE_ARGS,
+ spec_table_inline_1,
+ [](toml::table&& tbl) // spec-table-inline-1
+ {
+ const auto expected = toml::table{
+ { R"(name)"sv,
+ toml::table{
+ { R"(first)"sv, R"(Tom)"sv },
+ { R"(last)"sv, R"(Preston-Werner)"sv },
+ } },
+ };
+ REQUIRE(tbl == expected);
+ });
+ }
+
+ SECTION("spec-table-inline-2")
+ {
+ parsing_should_succeed(FILE_LINE_ARGS,
+ spec_table_inline_2,
+ [](toml::table&& tbl) // spec-table-inline-2
+ {
+ const auto expected = toml::table{
+ { R"(point)"sv,
+ toml::table{
+ { R"(x)"sv, 1 },
+ { R"(y)"sv, 2 },
+ } },
+ };
+ REQUIRE(tbl == expected);
+ });
+ }
+
+ SECTION("spec-table-inline-3")
+ {
+ parsing_should_succeed(FILE_LINE_ARGS,
+ spec_table_inline_3,
+ [](toml::table&& tbl) // spec-table-inline-3
+ {
+ const auto expected = toml::table{
+ { R"(animal)"sv,
+ toml::table{
+ { R"(type)"sv,
+ toml::table{
+ { R"(name)"sv, R"(pug)"sv },
+ } },
+ } },
+ };
+ REQUIRE(tbl == expected);
+ });
+ }
+
+ SECTION("spec-table")
+ {
+ parsing_should_succeed(FILE_LINE_ARGS,
+ spec_table,
+ [](toml::table&& tbl) // spec-table
+ {
+ const auto expected = toml::table{
+ { R"(table)"sv, toml::table{} },
+ };
+ REQUIRE(tbl == expected);
+ });
+ }
+
+ SECTION("spec-time-1")
+ {
+ parsing_should_succeed(FILE_LINE_ARGS,
+ spec_time_1,
+ [](toml::table&& tbl) // spec-time-1
+ {
+ const auto expected = toml::table{
+ { R"(lt1)"sv, toml::time{ 7, 32 } },
+ };
+ REQUIRE(tbl == expected);
+ });
+ }
+
+#if UNICODE_LITERALS_OK
+
+ SECTION("spec-quoted-basic-keys-1")
+ {
+ parsing_should_succeed(FILE_LINE_ARGS,
+ spec_quoted_basic_keys_1,
+ [](toml::table&& tbl) // spec-quoted-basic-keys-1
+ {
+ const auto expected = toml::table{
+ { R"(ʎǝʞ)"sv, R"(value)"sv },
+ };
+ REQUIRE(tbl == expected);
+ });
+ }
+
+ SECTION("spec-string-basic")
+ {
+ parsing_should_succeed(FILE_LINE_ARGS,
+ spec_string_basic,
+ [](toml::table&& tbl) // spec-string-basic
+ {
+ const auto expected = toml::table{
+ { R"(str)"sv, R"(I'm a string. "You can quote me". Name José
+Location SF.)"sv },
+ };
+ REQUIRE(tbl == expected);
+ });
+ }
+
+ SECTION("spec-table-6")
+ {
+ parsing_should_succeed(FILE_LINE_ARGS,
+ spec_table_6,
+ [](toml::table&& tbl) // spec-table-6
+ {
+ const auto expected = toml::table{
+ { R"(j)"sv,
+ toml::table{
+ { R"(ʞ)"sv,
+ toml::table{
+ { R"(l)"sv, toml::table{} },
+ } },
+ } },
+ };
+ REQUIRE(tbl == expected);
+ });
+ }
+
+#endif // UNICODE_LITERALS_OK
+}
diff --git a/tomlplusplus/tests/cpp.hint b/tomlplusplus/tests/cpp.hint
new file mode 100644
index 0000000000..9bb942ad41
--- /dev/null
+++ b/tomlplusplus/tests/cpp.hint
@@ -0,0 +1 @@
+#define TEST_CASE(...) void func()
diff --git a/tomlplusplus/tests/for_each.cpp b/tomlplusplus/tests/for_each.cpp
new file mode 100644
index 0000000000..6d28581281
--- /dev/null
+++ b/tomlplusplus/tests/for_each.cpp
@@ -0,0 +1,380 @@
+// This file is a part of toml++ and is subject to the the terms of the MIT license.
+// Copyright (c) Mark Gillard <mark.gillard@outlook.com.au>
+// See https://github.com/marzer/tomlplusplus/blob/master/LICENSE for the full license text.
+// SPDX-License-Identifier: MIT
+
+#include "tests.hpp"
+TOML_DISABLE_SPAM_WARNINGS;
+
+TEST_CASE("array::for_each")
+{
+ toml::array arr{ 0, 1, 2, 3.0, "four", "five", 6 };
+
+ // check lvalue propagates correctly
+ static_cast<array&>(arr).for_each(
+ [](auto&& elem, size_t) noexcept
+ {
+ using elem_ref_type = decltype(elem);
+ static_assert(std::is_lvalue_reference_v<elem_ref_type>);
+
+ using elem_type = std::remove_reference_t<elem_ref_type>;
+ static_assert(!std::is_const_v<elem_type>);
+ static_assert(!std::is_volatile_v<elem_type>);
+ });
+ static_cast<array&>(arr).for_each(
+ [](size_t, auto&& elem) noexcept
+ {
+ using elem_ref_type = decltype(elem);
+ static_assert(std::is_lvalue_reference_v<elem_ref_type>);
+
+ using elem_type = std::remove_reference_t<elem_ref_type>;
+ static_assert(!std::is_const_v<elem_type>);
+ static_assert(!std::is_volatile_v<elem_type>);
+ });
+ static_cast<array&>(arr).for_each(
+ [](auto&& elem) noexcept
+ {
+ using elem_ref_type = decltype(elem);
+ static_assert(std::is_lvalue_reference_v<elem_ref_type>);
+
+ using elem_type = std::remove_reference_t<elem_ref_type>;
+ static_assert(!std::is_const_v<elem_type>);
+ static_assert(!std::is_volatile_v<elem_type>);
+ });
+
+ // check rvalue propagates correctly
+ static_cast<array&&>(arr).for_each(
+ [](auto&& elem, size_t) noexcept
+ {
+ using elem_ref_type = decltype(elem);
+ static_assert(std::is_rvalue_reference_v<elem_ref_type>);
+
+ using elem_type = std::remove_reference_t<elem_ref_type>;
+ static_assert(!std::is_const_v<elem_type>);
+ static_assert(!std::is_volatile_v<elem_type>);
+ });
+ static_cast<array&&>(arr).for_each(
+ [](size_t, auto&& elem) noexcept
+ {
+ using elem_ref_type = decltype(elem);
+ static_assert(std::is_rvalue_reference_v<elem_ref_type>);
+
+ using elem_type = std::remove_reference_t<elem_ref_type>;
+ static_assert(!std::is_const_v<elem_type>);
+ static_assert(!std::is_volatile_v<elem_type>);
+ });
+ static_cast<array&&>(arr).for_each(
+ [](auto&& elem) noexcept
+ {
+ using elem_ref_type = decltype(elem);
+ static_assert(std::is_rvalue_reference_v<elem_ref_type>);
+
+ using elem_type = std::remove_reference_t<elem_ref_type>;
+ static_assert(!std::is_const_v<elem_type>);
+ static_assert(!std::is_volatile_v<elem_type>);
+ });
+
+ // check const lvalue propagates correctly
+ static_cast<const array&>(arr).for_each(
+ [](auto&& elem, size_t) noexcept
+ {
+ using elem_ref_type = decltype(elem);
+ static_assert(std::is_lvalue_reference_v<elem_ref_type>);
+
+ using elem_type = std::remove_reference_t<elem_ref_type>;
+ static_assert(std::is_const_v<elem_type>);
+ static_assert(!std::is_volatile_v<elem_type>);
+ });
+ static_cast<const array&>(arr).for_each(
+ [](size_t, auto&& elem) noexcept
+ {
+ using elem_ref_type = decltype(elem);
+ static_assert(std::is_lvalue_reference_v<elem_ref_type>);
+
+ using elem_type = std::remove_reference_t<elem_ref_type>;
+ static_assert(std::is_const_v<elem_type>);
+ static_assert(!std::is_volatile_v<elem_type>);
+ });
+ static_cast<const array&>(arr).for_each(
+ [](auto&& elem) noexcept
+ {
+ using elem_ref_type = decltype(elem);
+ static_assert(std::is_lvalue_reference_v<elem_ref_type>);
+
+ using elem_type = std::remove_reference_t<elem_ref_type>;
+ static_assert(std::is_const_v<elem_type>);
+ static_assert(!std::is_volatile_v<elem_type>);
+ });
+
+ // check const rvalue propagates correctly
+ static_cast<const array&&>(arr).for_each(
+ [](auto&& elem, size_t) noexcept
+ {
+ using elem_ref_type = decltype(elem);
+ static_assert(std::is_rvalue_reference_v<elem_ref_type>);
+
+ using elem_type = std::remove_reference_t<elem_ref_type>;
+ static_assert(std::is_const_v<elem_type>);
+ static_assert(!std::is_volatile_v<elem_type>);
+ });
+ static_cast<const array&&>(arr).for_each(
+ [](size_t, auto&& elem) noexcept
+ {
+ using elem_ref_type = decltype(elem);
+ static_assert(std::is_rvalue_reference_v<elem_ref_type>);
+
+ using elem_type = std::remove_reference_t<elem_ref_type>;
+ static_assert(std::is_const_v<elem_type>);
+ static_assert(!std::is_volatile_v<elem_type>);
+ });
+ static_cast<const array&&>(arr).for_each(
+ [](auto&& elem) noexcept
+ {
+ using elem_ref_type = decltype(elem);
+ static_assert(std::is_rvalue_reference_v<elem_ref_type>);
+
+ using elem_type = std::remove_reference_t<elem_ref_type>;
+ static_assert(std::is_const_v<elem_type>);
+ static_assert(!std::is_volatile_v<elem_type>);
+ });
+
+ // check noexcept - func(elem, i)
+ {
+ static constexpr auto throwing_visitor = [](auto&&, size_t) noexcept(false) {};
+ static constexpr auto non_throwing_visitor = [](auto&&, size_t) noexcept(true) {};
+ static_assert(!noexcept(static_cast<array&>(arr).for_each(throwing_visitor)));
+ static_assert(!noexcept(static_cast<array&&>(arr).for_each(throwing_visitor)));
+ static_assert(!noexcept(static_cast<const array&>(arr).for_each(throwing_visitor)));
+ static_assert(!noexcept(static_cast<const array&&>(arr).for_each(throwing_visitor)));
+ static_assert(noexcept(static_cast<array&>(arr).for_each(non_throwing_visitor)));
+ static_assert(noexcept(static_cast<array&&>(arr).for_each(non_throwing_visitor)));
+ static_assert(noexcept(static_cast<const array&>(arr).for_each(non_throwing_visitor)));
+ static_assert(noexcept(static_cast<const array&&>(arr).for_each(non_throwing_visitor)));
+ }
+
+ // check noexcept - func(i, elem)
+ {
+ static constexpr auto throwing_visitor = [](size_t, auto&&) noexcept(false) {};
+ static constexpr auto non_throwing_visitor = [](size_t, auto&&) noexcept(true) {};
+ static_assert(!noexcept(static_cast<array&>(arr).for_each(throwing_visitor)));
+ static_assert(!noexcept(static_cast<array&&>(arr).for_each(throwing_visitor)));
+ static_assert(!noexcept(static_cast<const array&>(arr).for_each(throwing_visitor)));
+ static_assert(!noexcept(static_cast<const array&&>(arr).for_each(throwing_visitor)));
+ static_assert(noexcept(static_cast<array&>(arr).for_each(non_throwing_visitor)));
+ static_assert(noexcept(static_cast<array&&>(arr).for_each(non_throwing_visitor)));
+ static_assert(noexcept(static_cast<const array&>(arr).for_each(non_throwing_visitor)));
+ static_assert(noexcept(static_cast<const array&&>(arr).for_each(non_throwing_visitor)));
+ }
+
+ // check noexcept - func(elem)
+ {
+ static constexpr auto throwing_visitor = [](auto&&) noexcept(false) {};
+ static constexpr auto non_throwing_visitor = [](auto&&) noexcept(true) {};
+ static_assert(!noexcept(static_cast<array&>(arr).for_each(throwing_visitor)));
+ static_assert(!noexcept(static_cast<array&&>(arr).for_each(throwing_visitor)));
+ static_assert(!noexcept(static_cast<const array&>(arr).for_each(throwing_visitor)));
+ static_assert(!noexcept(static_cast<const array&&>(arr).for_each(throwing_visitor)));
+ static_assert(noexcept(static_cast<array&>(arr).for_each(non_throwing_visitor)));
+ static_assert(noexcept(static_cast<array&&>(arr).for_each(non_throwing_visitor)));
+ static_assert(noexcept(static_cast<const array&>(arr).for_each(non_throwing_visitor)));
+ static_assert(noexcept(static_cast<const array&&>(arr).for_each(non_throwing_visitor)));
+ }
+
+ // check that the iteration actually does what it says on the box
+ {
+ toml::array arr2;
+ arr.for_each([&](const auto& val) { arr2.push_back(val); });
+ CHECK(arr == arr2);
+ }
+
+ // check that visitation works for a specific type
+ {
+ toml::array arr2;
+ arr.for_each([&](const toml::value<int64_t>& val) { arr2.push_back(val); });
+ CHECK(arr2 == toml::array{ 0, 1, 2, 6 });
+ }
+
+#if !TOML_RETURN_BOOL_FROM_FOR_EACH_BROKEN
+
+ // check that early-stopping works
+ {
+ toml::array arr2;
+ arr.for_each(
+ [&](const auto& val)
+ {
+ if constexpr (!toml::is_number<decltype(val)>)
+ return false;
+ else
+ {
+ arr2.push_back(val);
+ return true;
+ }
+ });
+ CHECK(arr2 == toml::array{ 0, 1, 2, 3.0 });
+ }
+
+#endif
+}
+
+TEST_CASE("table::for_each")
+{
+ table tbl{ { "zero", 0 }, //
+ { "one", 1 }, //
+ { "two", 2 }, //
+ { "three", 3.0 }, //
+ { "four", "four" }, //
+ { "five", "five" }, //
+ { "six", 6 } };
+
+ // check lvalue propagates correctly
+ static_cast<table&>(tbl).for_each(
+ [](const toml::key&, auto&& elem) noexcept
+ {
+ using elem_ref_type = decltype(elem);
+ static_assert(std::is_lvalue_reference_v<elem_ref_type>);
+
+ using elem_type = std::remove_reference_t<elem_ref_type>;
+ static_assert(!std::is_const_v<elem_type>);
+ static_assert(!std::is_volatile_v<elem_type>);
+ });
+ static_cast<table&>(tbl).for_each(
+ [](auto&& elem) noexcept
+ {
+ using elem_ref_type = decltype(elem);
+ static_assert(std::is_lvalue_reference_v<elem_ref_type>);
+
+ using elem_type = std::remove_reference_t<elem_ref_type>;
+ static_assert(!std::is_const_v<elem_type>);
+ static_assert(!std::is_volatile_v<elem_type>);
+ });
+
+ // check rvalue propagates correctly
+ static_cast<table&&>(tbl).for_each(
+ [](const toml::key&, auto&& elem) noexcept
+ {
+ using elem_ref_type = decltype(elem);
+ static_assert(std::is_rvalue_reference_v<elem_ref_type>);
+
+ using elem_type = std::remove_reference_t<elem_ref_type>;
+ static_assert(!std::is_const_v<elem_type>);
+ static_assert(!std::is_volatile_v<elem_type>);
+ });
+ static_cast<table&&>(tbl).for_each(
+ [](auto&& elem) noexcept
+ {
+ using elem_ref_type = decltype(elem);
+ static_assert(std::is_rvalue_reference_v<elem_ref_type>);
+
+ using elem_type = std::remove_reference_t<elem_ref_type>;
+ static_assert(!std::is_const_v<elem_type>);
+ static_assert(!std::is_volatile_v<elem_type>);
+ });
+
+ // check const lvalue propagates correctly
+ static_cast<const table&>(tbl).for_each(
+ [](const toml::key&, auto&& elem) noexcept
+ {
+ using elem_ref_type = decltype(elem);
+ static_assert(std::is_lvalue_reference_v<elem_ref_type>);
+
+ using elem_type = std::remove_reference_t<elem_ref_type>;
+ static_assert(std::is_const_v<elem_type>);
+ static_assert(!std::is_volatile_v<elem_type>);
+ });
+ static_cast<const table&>(tbl).for_each(
+ [](auto&& elem) noexcept
+ {
+ using elem_ref_type = decltype(elem);
+ static_assert(std::is_lvalue_reference_v<elem_ref_type>);
+
+ using elem_type = std::remove_reference_t<elem_ref_type>;
+ static_assert(std::is_const_v<elem_type>);
+ static_assert(!std::is_volatile_v<elem_type>);
+ });
+
+ // check const rvalue propagates correctly
+ static_cast<const table&&>(tbl).for_each(
+ [](const toml::key&, auto&& elem) noexcept
+ {
+ using elem_ref_type = decltype(elem);
+ static_assert(std::is_rvalue_reference_v<elem_ref_type>);
+
+ using elem_type = std::remove_reference_t<elem_ref_type>;
+ static_assert(std::is_const_v<elem_type>);
+ static_assert(!std::is_volatile_v<elem_type>);
+ });
+ static_cast<const table&&>(tbl).for_each(
+ [](auto&& elem) noexcept
+ {
+ using elem_ref_type = decltype(elem);
+ static_assert(std::is_rvalue_reference_v<elem_ref_type>);
+
+ using elem_type = std::remove_reference_t<elem_ref_type>;
+ static_assert(std::is_const_v<elem_type>);
+ static_assert(!std::is_volatile_v<elem_type>);
+ });
+
+ // check noexcept - func(key, value)
+ {
+ static constexpr auto throwing_visitor = [](const toml::key&, auto&&) noexcept(false) {};
+ static constexpr auto non_throwing_visitor = [](const toml::key&, auto&&) noexcept(true) {};
+ static_assert(!noexcept(static_cast<table&>(tbl).for_each(throwing_visitor)));
+ static_assert(!noexcept(static_cast<table&&>(tbl).for_each(throwing_visitor)));
+ static_assert(!noexcept(static_cast<const table&>(tbl).for_each(throwing_visitor)));
+ static_assert(!noexcept(static_cast<const table&&>(tbl).for_each(throwing_visitor)));
+ static_assert(noexcept(static_cast<table&>(tbl).for_each(non_throwing_visitor)));
+ static_assert(noexcept(static_cast<table&&>(tbl).for_each(non_throwing_visitor)));
+ static_assert(noexcept(static_cast<const table&>(tbl).for_each(non_throwing_visitor)));
+ static_assert(noexcept(static_cast<const table&&>(tbl).for_each(non_throwing_visitor)));
+ }
+
+ // check noexcept - func(value)
+ {
+ static constexpr auto throwing_visitor = [](auto&&) noexcept(false) {};
+ static constexpr auto non_throwing_visitor = [](auto&&) noexcept(true) {};
+ static_assert(!noexcept(static_cast<table&>(tbl).for_each(throwing_visitor)));
+ static_assert(!noexcept(static_cast<table&&>(tbl).for_each(throwing_visitor)));
+ static_assert(!noexcept(static_cast<const table&>(tbl).for_each(throwing_visitor)));
+ static_assert(!noexcept(static_cast<const table&&>(tbl).for_each(throwing_visitor)));
+ static_assert(noexcept(static_cast<table&>(tbl).for_each(non_throwing_visitor)));
+ static_assert(noexcept(static_cast<table&&>(tbl).for_each(non_throwing_visitor)));
+ static_assert(noexcept(static_cast<const table&>(tbl).for_each(non_throwing_visitor)));
+ static_assert(noexcept(static_cast<const table&&>(tbl).for_each(non_throwing_visitor)));
+ }
+
+ // check that the iteration actually does what it says on the box
+ {
+ toml::table tbl2;
+ tbl.for_each([&](auto&& key, auto&& val) { tbl2.insert_or_assign(key, val); });
+ CHECK(tbl == tbl2);
+ }
+
+ // check that visitation works for a specific type
+ {
+ toml::table tbl2;
+ tbl.for_each([&](auto&& key, const toml::value<int64_t>& val) { tbl2.insert_or_assign(key, val); });
+ CHECK(tbl2
+ == table{ { "zero", 0 }, //
+ { "one", 1 }, //
+ { "two", 2 }, //
+ { "six", 6 } });
+ }
+
+#if !TOML_RETURN_BOOL_FROM_FOR_EACH_BROKEN
+
+ // check that early-stopping works
+ {
+ toml::table tbl2;
+ size_t added{};
+ tbl.for_each(
+ [&](auto&& key, const auto& val)
+ {
+ tbl2.insert_or_assign(key, val);
+ added++;
+ return added < 3u;
+ });
+ CHECK(tbl2.size() == 3u);
+ }
+
+#endif
+}
diff --git a/tomlplusplus/tests/formatters.cpp b/tomlplusplus/tests/formatters.cpp
new file mode 100644
index 0000000000..a0cd35f914
--- /dev/null
+++ b/tomlplusplus/tests/formatters.cpp
@@ -0,0 +1,332 @@
+// This file is a part of toml++ and is subject to the the terms of the MIT license.
+// Copyright (c) Mark Gillard <mark.gillard@outlook.com.au>
+// See https://github.com/marzer/tomlplusplus/blob/master/LICENSE for the full license text.
+// SPDX-License-Identifier: MIT
+
+#include "tests.hpp"
+
+namespace
+{
+ template <typename Formatter, typename T>
+ static auto format_to_string(const T& obj,
+ format_flags flags = Formatter::default_flags,
+ format_flags exclude_flags = format_flags::none)
+ {
+ std::stringstream ss;
+ ss << "*****\n" << Formatter{ obj, flags & ~(exclude_flags) } << "\n*****";
+ return ss.str();
+ }
+
+ struct char32_printer
+ {
+ char32_t value;
+
+ friend std::ostream& operator<<(std::ostream& os, const char32_printer& p)
+ {
+ if (p.value <= U'\x1F')
+ return os << '\'' << impl::control_char_escapes[static_cast<size_t>(p.value)] << '\'';
+ else if (p.value == U'\x7F')
+ return os << "'\\u007F'"sv;
+ else if (p.value < 127u)
+ return os << '\'' << static_cast<char>(static_cast<uint8_t>(p.value)) << '\'';
+ else
+ return os << static_cast<uint_least32_t>(p.value);
+ }
+ };
+
+ struct string_difference
+ {
+ source_position position;
+ size_t index;
+ char32_t a, b;
+
+ friend std::ostream& operator<<(std::ostream& os, const string_difference& diff)
+ {
+ if (diff.a && diff.b && diff.a != diff.b)
+ os << char32_printer{ diff.a } << " vs "sv << char32_printer{ diff.b } << " at "sv;
+ return os << diff.position << ", index "sv << diff.index;
+ }
+ };
+
+ static optional<string_difference> find_first_difference(std::string_view str_a, std::string_view str_b) noexcept
+ {
+ string_difference diff{ { 1u, 1u } };
+ impl::utf8_decoder a, b;
+
+ for (size_t i = 0, e = std::min(str_a.length(), str_b.length()); i < e; i++, diff.index++)
+ {
+ a(static_cast<uint8_t>(str_a[i]));
+ b(static_cast<uint8_t>(str_b[i]));
+ if (a.has_code_point() != b.has_code_point() || a.error() != b.error())
+ return diff;
+
+ if (a.error())
+ {
+ a.reset();
+ b.reset();
+ continue;
+ }
+
+ if (!a.has_code_point())
+ continue;
+
+ if (a.codepoint != b.codepoint)
+ {
+ diff.a = a.codepoint;
+ diff.b = b.codepoint;
+ return diff;
+ }
+
+ if (a.codepoint == U'\n')
+ {
+ diff.position.line++;
+ diff.position.column = 1u;
+ }
+ else
+ diff.position.column++;
+ }
+ if (str_a.length() != str_b.length())
+ return diff;
+ return {};
+ }
+}
+
+#define CHECK_FORMATTER(formatter, data, expected) \
+ do \
+ { \
+ const auto str = format_to_string<formatter>(data); \
+ const auto diff = find_first_difference(str, expected); \
+ if (diff) \
+ FORCE_FAIL("string mismatch: "sv << *diff); \
+ } \
+ while (false)
+
+TEST_CASE("formatters")
+{
+ const auto data_date = toml::date{ 2021, 11, 2 };
+ const auto data_time = toml::time{ 20, 33, 0 };
+ const auto data = toml::table{
+ { "integers"sv,
+ toml::table{ { "zero"sv, 0 },
+ { "one"sv, 1 },
+ { "dec"sv, 10 },
+ { "bin"sv, 10, toml::value_flags::format_as_binary },
+ { "oct"sv, 10, toml::value_flags::format_as_octal },
+ { "hex"sv, 10, toml::value_flags::format_as_hexadecimal } } },
+ { "floats"sv,
+ toml::table{ { "pos_zero"sv, +0.0 },
+ { "neg_zero"sv, -0.0 },
+ { "one"sv, 1.0 },
+ { "pos_inf"sv, +std::numeric_limits<double>::infinity() },
+ { "neg_inf"sv, -std::numeric_limits<double>::infinity() },
+ { "pos_nan"sv, +std::numeric_limits<double>::quiet_NaN() },
+ { "neg_nan"sv, -std::numeric_limits<double>::quiet_NaN() }
+
+ } },
+
+ { "dates and times"sv,
+ toml::table{
+
+ { "dates"sv, toml::table{ { "val"sv, data_date } } },
+
+ { "times"sv, toml::table{ { "val"sv, data_time } } },
+
+ { "date-times"sv,
+ toml::table{
+
+ { "local"sv, toml::table{ { "val"sv, toml::date_time{ data_date, data_time } } } },
+ { "offset"sv,
+ toml::table{
+ { "val"sv, toml::date_time{ data_date, data_time, toml::time_offset{} } } } } } } } },
+
+ { "bools"sv,
+ toml::table{ { "true"sv, true }, //
+ { "false"sv, false } } },
+
+ {
+ "strings"sv,
+ toml::array{ R"()"sv,
+ R"(string)"sv,
+ R"(string with a single quote in it: ')"sv,
+ R"(string with a double quote in it: ")"sv,
+ "string with a tab: \t"sv,
+ R"(a long string to force the array over multiple lines)"sv },
+ },
+
+ { "a"sv,
+ toml::table{ { "val", true },
+ { "b"sv, toml::table{ { "val", true }, { "c"sv, toml::table{ { "val", true } } } } } } }
+
+ };
+
+ SECTION("toml_formatter")
+ {
+ static constexpr auto expected = R"(*****
+strings = [
+ '',
+ 'string',
+ "string with a single quote in it: '",
+ 'string with a double quote in it: "',
+ 'string with a tab: ',
+ 'a long string to force the array over multiple lines'
+]
+
+[a]
+val = true
+
+ [a.b]
+ val = true
+
+ [a.b.c]
+ val = true
+
+[bools]
+false = false
+true = true
+
+['dates and times'.date-times.local]
+val = 2021-11-02T20:33:00
+
+['dates and times'.date-times.offset]
+val = 2021-11-02T20:33:00Z
+
+['dates and times'.dates]
+val = 2021-11-02
+
+['dates and times'.times]
+val = 20:33:00
+
+[floats]
+neg_inf = -inf
+neg_nan = nan
+neg_zero = -0.0
+one = 1.0
+pos_inf = inf
+pos_nan = nan
+pos_zero = 0.0
+
+[integers]
+bin = 0b1010
+dec = 10
+hex = 0xA
+oct = 0o12
+one = 1
+zero = 0
+*****)"sv;
+
+ CHECK_FORMATTER(toml_formatter, data, expected);
+ }
+
+ SECTION("json_formatter")
+ {
+ static constexpr auto expected = R"(*****
+{
+ "a" : {
+ "b" : {
+ "c" : {
+ "val" : true
+ },
+ "val" : true
+ },
+ "val" : true
+ },
+ "bools" : {
+ "false" : false,
+ "true" : true
+ },
+ "dates and times" : {
+ "date-times" : {
+ "local" : {
+ "val" : "2021-11-02T20:33:00"
+ },
+ "offset" : {
+ "val" : "2021-11-02T20:33:00Z"
+ }
+ },
+ "dates" : {
+ "val" : "2021-11-02"
+ },
+ "times" : {
+ "val" : "20:33:00"
+ }
+ },
+ "floats" : {
+ "neg_inf" : "-Infinity",
+ "neg_nan" : "NaN",
+ "neg_zero" : -0.0,
+ "one" : 1.0,
+ "pos_inf" : "Infinity",
+ "pos_nan" : "NaN",
+ "pos_zero" : 0.0
+ },
+ "integers" : {
+ "bin" : 10,
+ "dec" : 10,
+ "hex" : 10,
+ "oct" : 10,
+ "one" : 1,
+ "zero" : 0
+ },
+ "strings" : [
+ "",
+ "string",
+ "string with a single quote in it: '",
+ "string with a double quote in it: \"",
+ "string with a tab: \t",
+ "a long string to force the array over multiple lines"
+ ]
+}
+*****)"sv;
+
+ CHECK_FORMATTER(json_formatter, data, expected);
+ }
+
+ SECTION("yaml_formatter")
+ {
+ static constexpr auto expected = R"(*****
+a:
+ b:
+ c:
+ val: true
+ val: true
+ val: true
+bools:
+ false: false
+ true: true
+'dates and times':
+ date-times:
+ local:
+ val: '2021-11-02T20:33:00'
+ offset:
+ val: '2021-11-02T20:33:00Z'
+ dates:
+ val: '2021-11-02'
+ times:
+ val: '20:33:00'
+floats:
+ neg_inf: -.inf
+ neg_nan: .NAN
+ neg_zero: -0.0
+ one: 1.0
+ pos_inf: .inf
+ pos_nan: .NAN
+ pos_zero: 0.0
+integers:
+ bin: 10
+ dec: 10
+ hex: 0xA
+ oct: 0o12
+ one: 1
+ zero: 0
+strings:
+ - ''
+ - string
+ - "string with a single quote in it: '"
+ - 'string with a double quote in it: "'
+ - "string with a tab: \t"
+ - 'a long string to force the array over multiple lines'
+*****)"sv;
+
+ CHECK_FORMATTER(yaml_formatter, data, expected);
+ }
+}
diff --git a/tomlplusplus/tests/impl_toml.cpp b/tomlplusplus/tests/impl_toml.cpp
new file mode 100644
index 0000000000..bdf23a3119
--- /dev/null
+++ b/tomlplusplus/tests/impl_toml.cpp
@@ -0,0 +1,407 @@
+// This file is a part of toml++ and is subject to the the terms of the MIT license.
+// Copyright (c) Mark Gillard <mark.gillard@outlook.com.au>
+// See https://github.com/marzer/tomlplusplus/blob/master/LICENSE for the full license text.
+// SPDX-License-Identifier: MIT
+
+#include "settings.hpp"
+#if !TOML_HEADER_ONLY && !TOML_SHARED_LIB
+#define TOML_IMPLEMENTATION
+#endif
+
+#if USE_SINGLE_HEADER
+#include "../toml.hpp"
+#else
+#include "../include/toml++/toml.hpp"
+#endif
+
+namespace toml
+{
+ using std::declval;
+ using std::is_same_v;
+
+#define CHECK_NODE_TYPE_MAPPING(T, expected) \
+ static_assert(impl::node_type_of<T> == expected); \
+ static_assert(impl::node_type_of<T&> == expected); \
+ static_assert(impl::node_type_of<T&&> == expected); \
+ static_assert(impl::node_type_of<const T> == expected); \
+ static_assert(impl::node_type_of<const T&> == expected); \
+ static_assert(impl::node_type_of<const T&&> == expected); \
+ static_assert(impl::node_type_of<volatile T> == expected); \
+ static_assert(impl::node_type_of<volatile T&> == expected); \
+ static_assert(impl::node_type_of<volatile T&&> == expected); \
+ static_assert(impl::node_type_of<const volatile T> == expected); \
+ static_assert(impl::node_type_of<const volatile T&> == expected); \
+ static_assert(impl::node_type_of<const volatile T&&> == expected)
+
+ CHECK_NODE_TYPE_MAPPING(int64_t, node_type::integer);
+ CHECK_NODE_TYPE_MAPPING(double, node_type::floating_point);
+ CHECK_NODE_TYPE_MAPPING(std::string, node_type::string);
+ CHECK_NODE_TYPE_MAPPING(bool, node_type::boolean);
+ CHECK_NODE_TYPE_MAPPING(toml::date, node_type::date);
+ CHECK_NODE_TYPE_MAPPING(toml::time, node_type::time);
+ CHECK_NODE_TYPE_MAPPING(toml::date_time, node_type::date_time);
+ CHECK_NODE_TYPE_MAPPING(toml::array, node_type::array);
+ CHECK_NODE_TYPE_MAPPING(toml::table, node_type::table);
+
+#define CHECK_CAN_REPRESENT_NATIVE(T, expected) \
+ static_assert((impl::value_traits<T>::is_native || impl::value_traits<T>::can_represent_native) == expected)
+
+ CHECK_CAN_REPRESENT_NATIVE(time, true);
+ CHECK_CAN_REPRESENT_NATIVE(date, true);
+ CHECK_CAN_REPRESENT_NATIVE(date_time, true);
+ CHECK_CAN_REPRESENT_NATIVE(bool, true);
+ CHECK_CAN_REPRESENT_NATIVE(int8_t, false);
+ CHECK_CAN_REPRESENT_NATIVE(int16_t, false);
+ CHECK_CAN_REPRESENT_NATIVE(int32_t, false);
+ CHECK_CAN_REPRESENT_NATIVE(int64_t, true);
+ CHECK_CAN_REPRESENT_NATIVE(uint8_t, false);
+ CHECK_CAN_REPRESENT_NATIVE(uint16_t, false);
+ CHECK_CAN_REPRESENT_NATIVE(uint32_t, false);
+ CHECK_CAN_REPRESENT_NATIVE(uint64_t, false);
+ CHECK_CAN_REPRESENT_NATIVE(float, false);
+ CHECK_CAN_REPRESENT_NATIVE(double, true);
+#ifdef TOML_INT128
+ CHECK_CAN_REPRESENT_NATIVE(TOML_INT128, true);
+ CHECK_CAN_REPRESENT_NATIVE(TOML_UINT128, false);
+#endif
+#if TOML_ENABLE_FLOAT16
+ CHECK_CAN_REPRESENT_NATIVE(_Float16, false);
+#endif
+#ifdef TOML_FLOAT128
+ CHECK_CAN_REPRESENT_NATIVE(TOML_FLOAT128, true);
+#endif
+
+ CHECK_CAN_REPRESENT_NATIVE(char*, false);
+ CHECK_CAN_REPRESENT_NATIVE(char* const, false);
+ CHECK_CAN_REPRESENT_NATIVE(char[2], false);
+ CHECK_CAN_REPRESENT_NATIVE(const char[2], false);
+ CHECK_CAN_REPRESENT_NATIVE(char (&)[2], false);
+ CHECK_CAN_REPRESENT_NATIVE(const char (&)[2], false);
+ CHECK_CAN_REPRESENT_NATIVE(char (&&)[2], false);
+ CHECK_CAN_REPRESENT_NATIVE(const char (&&)[2], false);
+ CHECK_CAN_REPRESENT_NATIVE(const char*, true);
+ CHECK_CAN_REPRESENT_NATIVE(const char* const, true);
+ CHECK_CAN_REPRESENT_NATIVE(std::string, true);
+ CHECK_CAN_REPRESENT_NATIVE(std::string_view, true);
+#if TOML_HAS_CHAR8
+ CHECK_CAN_REPRESENT_NATIVE(char8_t*, false);
+ CHECK_CAN_REPRESENT_NATIVE(char8_t* const, false);
+ CHECK_CAN_REPRESENT_NATIVE(char8_t[2], false);
+ CHECK_CAN_REPRESENT_NATIVE(const char8_t[2], false);
+ CHECK_CAN_REPRESENT_NATIVE(char8_t (&)[2], false);
+ CHECK_CAN_REPRESENT_NATIVE(const char8_t (&)[2], false);
+ CHECK_CAN_REPRESENT_NATIVE(char (&&)[2], false);
+ CHECK_CAN_REPRESENT_NATIVE(const char8_t (&&)[2], false);
+ CHECK_CAN_REPRESENT_NATIVE(const char8_t*, true);
+ CHECK_CAN_REPRESENT_NATIVE(const char8_t* const, true);
+ CHECK_CAN_REPRESENT_NATIVE(std::u8string, true);
+ CHECK_CAN_REPRESENT_NATIVE(std::u8string_view, true);
+#endif
+ CHECK_CAN_REPRESENT_NATIVE(wchar_t*, false);
+ CHECK_CAN_REPRESENT_NATIVE(wchar_t* const, false);
+ CHECK_CAN_REPRESENT_NATIVE(wchar_t[2], false);
+ CHECK_CAN_REPRESENT_NATIVE(const wchar_t[2], false);
+ CHECK_CAN_REPRESENT_NATIVE(wchar_t (&)[2], false);
+ CHECK_CAN_REPRESENT_NATIVE(const wchar_t (&)[2], false);
+ CHECK_CAN_REPRESENT_NATIVE(wchar_t (&&)[2], false);
+ CHECK_CAN_REPRESENT_NATIVE(const wchar_t (&&)[2], false);
+ CHECK_CAN_REPRESENT_NATIVE(const wchar_t*, false);
+ CHECK_CAN_REPRESENT_NATIVE(const wchar_t* const, false);
+ CHECK_CAN_REPRESENT_NATIVE(std::wstring, !!TOML_ENABLE_WINDOWS_COMPAT);
+ CHECK_CAN_REPRESENT_NATIVE(std::wstring_view, false);
+
+#define CHECK_VALUE_EXACT(T, expected) \
+ static_assert(is_same_v<decltype(declval<node>().value_exact<T>()), optional<expected>>); \
+ static_assert(is_same_v<decltype(declval<node_view<node>>().value_exact<T>()), optional<expected>>); \
+ static_assert(is_same_v<decltype(declval<node_view<const node>>().value_exact<T>()), optional<expected>>)
+
+#define CHECK_VALUE_OR(T, expected) \
+ static_assert(is_same_v<decltype(declval<node>().value_or(declval<T>())), expected>); \
+ static_assert(is_same_v<decltype(declval<node_view<node>>().value_or(declval<T>())), expected>); \
+ static_assert(is_same_v<decltype(declval<node_view<const node>>().value_or(declval<T>())), expected>)
+
+ CHECK_VALUE_EXACT(time, time);
+ CHECK_VALUE_EXACT(date, date);
+ CHECK_VALUE_EXACT(date_time, date_time);
+ CHECK_VALUE_EXACT(bool, bool);
+ CHECK_VALUE_EXACT(double, double);
+ CHECK_VALUE_EXACT(int64_t, int64_t);
+ CHECK_VALUE_EXACT(const char*, const char*);
+ CHECK_VALUE_EXACT(std::string_view, std::string_view);
+ CHECK_VALUE_EXACT(std::string, std::string);
+#if TOML_HAS_CHAR8
+ CHECK_VALUE_EXACT(const char8_t*, const char8_t*);
+ CHECK_VALUE_EXACT(std::u8string_view, std::u8string_view);
+ CHECK_VALUE_EXACT(std::u8string, std::u8string);
+#endif
+
+ CHECK_VALUE_OR(time, time);
+ CHECK_VALUE_OR(time&, time);
+ CHECK_VALUE_OR(time&&, time);
+ CHECK_VALUE_OR(time const, time);
+ CHECK_VALUE_OR(date, date);
+ CHECK_VALUE_OR(date&, date);
+ CHECK_VALUE_OR(date&&, date);
+ CHECK_VALUE_OR(date const, date);
+ CHECK_VALUE_OR(date_time, date_time);
+ CHECK_VALUE_OR(date_time&, date_time);
+ CHECK_VALUE_OR(date_time&&, date_time);
+ CHECK_VALUE_OR(date_time const, date_time);
+ CHECK_VALUE_OR(bool, bool);
+ CHECK_VALUE_OR(bool&, bool);
+ CHECK_VALUE_OR(bool&&, bool);
+ CHECK_VALUE_OR(bool const, bool);
+ CHECK_VALUE_OR(int32_t, int32_t);
+ CHECK_VALUE_OR(int32_t&, int32_t);
+ CHECK_VALUE_OR(int32_t&&, int32_t);
+ CHECK_VALUE_OR(int32_t const, int32_t);
+ CHECK_VALUE_OR(int64_t, int64_t);
+ CHECK_VALUE_OR(int64_t&, int64_t);
+ CHECK_VALUE_OR(int64_t&&, int64_t);
+ CHECK_VALUE_OR(int64_t const, int64_t);
+#ifdef TOML_INT128
+ CHECK_VALUE_OR(TOML_INT128, TOML_INT128);
+ CHECK_VALUE_OR(TOML_INT128&, TOML_INT128);
+ CHECK_VALUE_OR(TOML_INT128&&, TOML_INT128);
+ CHECK_VALUE_OR(TOML_INT128 const, TOML_INT128);
+ CHECK_VALUE_OR(TOML_UINT128, TOML_UINT128);
+ CHECK_VALUE_OR(TOML_UINT128&, TOML_UINT128);
+ CHECK_VALUE_OR(TOML_UINT128&&, TOML_UINT128);
+ CHECK_VALUE_OR(TOML_UINT128 const, TOML_UINT128);
+#endif
+ CHECK_VALUE_OR(float, float);
+ CHECK_VALUE_OR(float&, float);
+ CHECK_VALUE_OR(float&&, float);
+ CHECK_VALUE_OR(float const, float);
+ CHECK_VALUE_OR(double, double);
+ CHECK_VALUE_OR(double&, double);
+ CHECK_VALUE_OR(double&&, double);
+ CHECK_VALUE_OR(double const, double);
+#ifdef TOML_FLOAT128
+ CHECK_VALUE_OR(TOML_FLOAT128, TOML_FLOAT128);
+ CHECK_VALUE_OR(TOML_FLOAT128&, TOML_FLOAT128);
+ CHECK_VALUE_OR(TOML_FLOAT128&&, TOML_FLOAT128);
+ CHECK_VALUE_OR(TOML_FLOAT128 const, TOML_FLOAT128);
+#endif
+ CHECK_VALUE_OR(char*, const char*);
+ CHECK_VALUE_OR(char*&, const char*);
+ CHECK_VALUE_OR(char*&&, const char*);
+ CHECK_VALUE_OR(char* const, const char*);
+ CHECK_VALUE_OR(char[2], const char*);
+ CHECK_VALUE_OR(char (&)[2], const char*);
+ CHECK_VALUE_OR(char (&&)[2], const char*);
+ CHECK_VALUE_OR(const char*, const char*);
+ CHECK_VALUE_OR(const char*&, const char*);
+ CHECK_VALUE_OR(const char*&&, const char*);
+ CHECK_VALUE_OR(const char* const, const char*);
+ CHECK_VALUE_OR(const char[2], const char*);
+ CHECK_VALUE_OR(const char (&)[2], const char*);
+ CHECK_VALUE_OR(const char (&&)[2], const char*);
+ CHECK_VALUE_OR(std::string_view, std::string_view);
+ CHECK_VALUE_OR(std::string_view&, std::string_view);
+ CHECK_VALUE_OR(std::string_view&&, std::string_view);
+ CHECK_VALUE_OR(const std::string_view, std::string_view);
+ CHECK_VALUE_OR(const std::string_view&, std::string_view);
+ CHECK_VALUE_OR(const std::string_view&&, std::string_view);
+ CHECK_VALUE_OR(std::string, std::string);
+ CHECK_VALUE_OR(std::string&, std::string);
+ CHECK_VALUE_OR(std::string&&, std::string);
+ CHECK_VALUE_OR(const std::string, std::string);
+ CHECK_VALUE_OR(const std::string&, std::string);
+ CHECK_VALUE_OR(const std::string&&, std::string);
+#if TOML_HAS_CHAR8
+ CHECK_VALUE_OR(char8_t*, const char8_t*);
+ CHECK_VALUE_OR(char8_t*&, const char8_t*);
+ CHECK_VALUE_OR(char8_t*&&, const char8_t*);
+ CHECK_VALUE_OR(char8_t* const, const char8_t*);
+ CHECK_VALUE_OR(char8_t[2], const char8_t*);
+ CHECK_VALUE_OR(char8_t (&)[2], const char8_t*);
+ CHECK_VALUE_OR(char8_t (&&)[2], const char8_t*);
+ CHECK_VALUE_OR(const char8_t*, const char8_t*);
+ CHECK_VALUE_OR(const char8_t*&, const char8_t*);
+ CHECK_VALUE_OR(const char8_t*&&, const char8_t*);
+ CHECK_VALUE_OR(const char8_t* const, const char8_t*);
+ CHECK_VALUE_OR(const char8_t[2], const char8_t*);
+ CHECK_VALUE_OR(const char8_t (&)[2], const char8_t*);
+ CHECK_VALUE_OR(const char8_t (&&)[2], const char8_t*);
+ CHECK_VALUE_OR(std::u8string_view, std::u8string_view);
+ CHECK_VALUE_OR(std::u8string_view&, std::u8string_view);
+ CHECK_VALUE_OR(std::u8string_view&&, std::u8string_view);
+ CHECK_VALUE_OR(const std::u8string_view, std::u8string_view);
+ CHECK_VALUE_OR(const std::u8string_view&, std::u8string_view);
+ CHECK_VALUE_OR(const std::u8string_view&&, std::u8string_view);
+ CHECK_VALUE_OR(std::u8string, std::u8string);
+ CHECK_VALUE_OR(std::u8string&, std::u8string);
+ CHECK_VALUE_OR(std::u8string&&, std::u8string);
+ CHECK_VALUE_OR(const std::u8string, std::u8string);
+ CHECK_VALUE_OR(const std::u8string&, std::u8string);
+ CHECK_VALUE_OR(const std::u8string&&, std::u8string);
+#endif
+#if TOML_ENABLE_WINDOWS_COMPAT
+ CHECK_VALUE_OR(wchar_t*, std::wstring);
+ CHECK_VALUE_OR(wchar_t*&, std::wstring);
+ CHECK_VALUE_OR(wchar_t*&&, std::wstring);
+ CHECK_VALUE_OR(wchar_t* const, std::wstring);
+ CHECK_VALUE_OR(wchar_t[2], std::wstring);
+ CHECK_VALUE_OR(wchar_t (&)[2], std::wstring);
+ CHECK_VALUE_OR(wchar_t (&&)[2], std::wstring);
+ CHECK_VALUE_OR(const wchar_t*, std::wstring);
+ CHECK_VALUE_OR(const wchar_t*&, std::wstring);
+ CHECK_VALUE_OR(const wchar_t*&&, std::wstring);
+ CHECK_VALUE_OR(const wchar_t* const, std::wstring);
+ CHECK_VALUE_OR(const wchar_t[2], std::wstring);
+ CHECK_VALUE_OR(const wchar_t (&)[2], std::wstring);
+ CHECK_VALUE_OR(const wchar_t (&&)[2], std::wstring);
+ CHECK_VALUE_OR(std::wstring_view, std::wstring);
+ CHECK_VALUE_OR(std::wstring_view&, std::wstring);
+ CHECK_VALUE_OR(std::wstring_view&&, std::wstring);
+ CHECK_VALUE_OR(const std::wstring_view, std::wstring);
+ CHECK_VALUE_OR(const std::wstring_view&, std::wstring);
+ CHECK_VALUE_OR(const std::wstring_view&&, std::wstring);
+ CHECK_VALUE_OR(std::wstring, std::wstring);
+ CHECK_VALUE_OR(std::wstring&, std::wstring);
+ CHECK_VALUE_OR(std::wstring&&, std::wstring);
+ CHECK_VALUE_OR(const std::wstring, std::wstring);
+ CHECK_VALUE_OR(const std::wstring&, std::wstring);
+ CHECK_VALUE_OR(const std::wstring&&, std::wstring);
+#endif
+
+#define CHECK_INSERTED_AS(T, expected) \
+ static_assert(std::is_same_v<toml::inserted_type_of<T>, expected>); \
+ static_assert(std::is_same_v<toml::inserted_type_of<const T>, expected>); \
+ static_assert(std::is_same_v<toml::inserted_type_of<T&>, expected>); \
+ static_assert(std::is_same_v<toml::inserted_type_of<const T&>, expected>); \
+ static_assert(std::is_same_v<toml::inserted_type_of<T&&>, expected>)
+
+ CHECK_INSERTED_AS(table, table);
+ CHECK_INSERTED_AS(array, array);
+ CHECK_INSERTED_AS(node, node);
+ CHECK_INSERTED_AS(time, value<time>);
+ CHECK_INSERTED_AS(date, value<date>);
+ CHECK_INSERTED_AS(date_time, value<date_time>);
+ CHECK_INSERTED_AS(bool, value<bool>);
+ CHECK_INSERTED_AS(int8_t, value<int64_t>);
+ CHECK_INSERTED_AS(int16_t, value<int64_t>);
+ CHECK_INSERTED_AS(int32_t, value<int64_t>);
+ CHECK_INSERTED_AS(int64_t, value<int64_t>);
+ CHECK_INSERTED_AS(uint8_t, value<int64_t>);
+ CHECK_INSERTED_AS(uint16_t, value<int64_t>);
+ CHECK_INSERTED_AS(uint32_t, value<int64_t>);
+ CHECK_INSERTED_AS(float, value<double>);
+ CHECK_INSERTED_AS(double, value<double>);
+#if TOML_ENABLE_FLOAT16
+ CHECK_INSERTED_AS(_Float16, value<double>);
+#endif
+
+#define CHECK_NODE_REF_TYPE(T) \
+ static_assert(is_same_v<decltype(declval<node&>().ref<T>()), T&>); \
+ static_assert(is_same_v<decltype(declval<node&>().ref<const T>()), const T&>); \
+ static_assert(is_same_v<decltype(declval<node&>().ref<volatile T>()), volatile T&>); \
+ static_assert(is_same_v<decltype(declval<node&>().ref<const volatile T>()), const volatile T&>); \
+ static_assert(is_same_v<decltype(declval<node&>().ref<T&>()), T&>); \
+ static_assert(is_same_v<decltype(declval<node&>().ref<const T&>()), const T&>); \
+ static_assert(is_same_v<decltype(declval<node&>().ref<volatile T&>()), volatile T&>); \
+ static_assert(is_same_v<decltype(declval<node&>().ref<const volatile T&>()), const volatile T&>); \
+ static_assert(is_same_v<decltype(declval<node&>().ref<T&&>()), T&&>); \
+ static_assert(is_same_v<decltype(declval<node&>().ref<const T&&>()), const T&&>); \
+ static_assert(is_same_v<decltype(declval<node&>().ref<volatile T&&>()), volatile T&&>); \
+ static_assert(is_same_v<decltype(declval<node&>().ref<const volatile T&&>()), const volatile T&&>); \
+ \
+ static_assert(is_same_v<decltype(declval<node&&>().ref<T>()), T&&>); \
+ static_assert(is_same_v<decltype(declval<node&&>().ref<const T>()), const T&&>); \
+ static_assert(is_same_v<decltype(declval<node&&>().ref<volatile T>()), volatile T&&>); \
+ static_assert(is_same_v<decltype(declval<node&&>().ref<const volatile T>()), const volatile T&&>); \
+ static_assert(is_same_v<decltype(declval<node&&>().ref<T&>()), T&>); \
+ static_assert(is_same_v<decltype(declval<node&&>().ref<const T&>()), const T&>); \
+ static_assert(is_same_v<decltype(declval<node&&>().ref<volatile T&>()), volatile T&>); \
+ static_assert(is_same_v<decltype(declval<node&&>().ref<const volatile T&>()), const volatile T&>); \
+ static_assert(is_same_v<decltype(declval<node&&>().ref<T&&>()), T&&>); \
+ static_assert(is_same_v<decltype(declval<node&&>().ref<const T&&>()), const T&&>); \
+ static_assert(is_same_v<decltype(declval<node&&>().ref<volatile T&&>()), volatile T&&>); \
+ static_assert(is_same_v<decltype(declval<node&&>().ref<const volatile T&&>()), const volatile T&&>); \
+ \
+ static_assert(is_same_v<decltype(declval<const node&>().ref<T>()), const T&>); \
+ static_assert(is_same_v<decltype(declval<const node&>().ref<const T>()), const T&>); \
+ static_assert(is_same_v<decltype(declval<const node&>().ref<volatile T>()), const volatile T&>); \
+ static_assert(is_same_v<decltype(declval<const node&>().ref<const volatile T>()), const volatile T&>); \
+ static_assert(is_same_v<decltype(declval<const node&>().ref<T&>()), const T&>); \
+ static_assert(is_same_v<decltype(declval<const node&>().ref<const T&>()), const T&>); \
+ static_assert(is_same_v<decltype(declval<const node&>().ref<volatile T&>()), const volatile T&>); \
+ static_assert(is_same_v<decltype(declval<const node&>().ref<const volatile T&>()), const volatile T&>); \
+ static_assert(is_same_v<decltype(declval<const node&>().ref<T&&>()), const T&&>); \
+ static_assert(is_same_v<decltype(declval<const node&>().ref<const T&&>()), const T&&>); \
+ static_assert(is_same_v<decltype(declval<const node&>().ref<volatile T&&>()), const volatile T&&>); \
+ static_assert(is_same_v<decltype(declval<const node&>().ref<const volatile T&&>()), const volatile T&&>); \
+ \
+ static_assert(is_same_v<decltype(declval<const node&&>().ref<T>()), const T&&>); \
+ static_assert(is_same_v<decltype(declval<const node&&>().ref<const T>()), const T&&>); \
+ static_assert(is_same_v<decltype(declval<const node&&>().ref<volatile T>()), const volatile T&&>); \
+ static_assert(is_same_v<decltype(declval<const node&&>().ref<const volatile T>()), const volatile T&&>); \
+ static_assert(is_same_v<decltype(declval<const node&&>().ref<T&>()), const T&>); \
+ static_assert(is_same_v<decltype(declval<const node&&>().ref<const T&>()), const T&>); \
+ static_assert(is_same_v<decltype(declval<const node&&>().ref<volatile T&>()), const volatile T&>); \
+ static_assert(is_same_v<decltype(declval<const node&&>().ref<const volatile T&>()), const volatile T&>); \
+ static_assert(is_same_v<decltype(declval<const node&&>().ref<T&&>()), const T&&>); \
+ static_assert(is_same_v<decltype(declval<const node&&>().ref<const T&&>()), const T&&>); \
+ static_assert(is_same_v<decltype(declval<const node&&>().ref<volatile T&&>()), const volatile T&&>); \
+ static_assert(is_same_v<decltype(declval<const node&&>().ref<const volatile T&&>()), const volatile T&&>)
+
+ CHECK_NODE_REF_TYPE(table);
+ CHECK_NODE_REF_TYPE(array);
+ CHECK_NODE_REF_TYPE(std::string);
+ CHECK_NODE_REF_TYPE(int64_t);
+ CHECK_NODE_REF_TYPE(double);
+ CHECK_NODE_REF_TYPE(bool);
+ CHECK_NODE_REF_TYPE(date);
+ CHECK_NODE_REF_TYPE(time);
+ CHECK_NODE_REF_TYPE(date_time);
+
+#define CHECK_NODE_VIEW_REF_TYPE(T) \
+ static_assert(is_same_v<decltype(declval<node_view<node>>().ref<T>()), T&>); \
+ static_assert(is_same_v<decltype(declval<node_view<node>>().ref<const T>()), const T&>); \
+ static_assert(is_same_v<decltype(declval<node_view<node>>().ref<volatile T>()), volatile T&>); \
+ static_assert(is_same_v<decltype(declval<node_view<node>>().ref<const volatile T>()), const volatile T&>); \
+ static_assert(is_same_v<decltype(declval<node_view<node>>().ref<T&>()), T&>); \
+ static_assert(is_same_v<decltype(declval<node_view<node>>().ref<const T&>()), const T&>); \
+ static_assert(is_same_v<decltype(declval<node_view<node>>().ref<volatile T&>()), volatile T&>); \
+ static_assert(is_same_v<decltype(declval<node_view<node>>().ref<const volatile T&>()), const volatile T&>); \
+ static_assert(is_same_v<decltype(declval<node_view<node>>().ref<T&&>()), T&&>); \
+ static_assert(is_same_v<decltype(declval<node_view<node>>().ref<const T&&>()), const T&&>); \
+ static_assert(is_same_v<decltype(declval<node_view<node>>().ref<volatile T&&>()), volatile T&&>); \
+ static_assert(is_same_v<decltype(declval<node_view<node>>().ref<const volatile T&&>()), const volatile T&&>)
+
+ CHECK_NODE_VIEW_REF_TYPE(table);
+ CHECK_NODE_VIEW_REF_TYPE(array);
+ CHECK_NODE_VIEW_REF_TYPE(std::string);
+ CHECK_NODE_VIEW_REF_TYPE(int64_t);
+ CHECK_NODE_VIEW_REF_TYPE(double);
+ CHECK_NODE_VIEW_REF_TYPE(bool);
+ CHECK_NODE_VIEW_REF_TYPE(date);
+ CHECK_NODE_VIEW_REF_TYPE(time);
+ CHECK_NODE_VIEW_REF_TYPE(date_time);
+
+#define CHECK_CONST_NODE_VIEW_REF_TYPE(T) \
+ static_assert(is_same_v<decltype(declval<node_view<const node>>().ref<T>()), const T&>); \
+ static_assert(is_same_v<decltype(declval<node_view<const node>>().ref<const T>()), const T&>); \
+ static_assert(is_same_v<decltype(declval<node_view<const node>>().ref<volatile T>()), const volatile T&>); \
+ static_assert(is_same_v<decltype(declval<node_view<const node>>().ref<const volatile T>()), const volatile T&>); \
+ static_assert(is_same_v<decltype(declval<node_view<const node>>().ref<T&>()), const T&>); \
+ static_assert(is_same_v<decltype(declval<node_view<const node>>().ref<const T&>()), const T&>); \
+ static_assert(is_same_v<decltype(declval<node_view<const node>>().ref<volatile T&>()), const volatile T&>); \
+ static_assert(is_same_v<decltype(declval<node_view<const node>>().ref<const volatile T&>()), const volatile T&>); \
+ static_assert(is_same_v<decltype(declval<node_view<const node>>().ref<T&&>()), const T&&>); \
+ static_assert(is_same_v<decltype(declval<node_view<const node>>().ref<const T&&>()), const T&&>); \
+ static_assert(is_same_v<decltype(declval<node_view<const node>>().ref<volatile T&&>()), const volatile T&&>); \
+ static_assert(is_same_v<decltype(declval<node_view<const node>>().ref<const volatile T&&>()), const volatile T&&>)
+
+ CHECK_CONST_NODE_VIEW_REF_TYPE(table);
+ CHECK_CONST_NODE_VIEW_REF_TYPE(array);
+ CHECK_CONST_NODE_VIEW_REF_TYPE(std::string);
+ CHECK_CONST_NODE_VIEW_REF_TYPE(int64_t);
+ CHECK_CONST_NODE_VIEW_REF_TYPE(double);
+ CHECK_CONST_NODE_VIEW_REF_TYPE(bool);
+ CHECK_CONST_NODE_VIEW_REF_TYPE(date);
+ CHECK_CONST_NODE_VIEW_REF_TYPE(time);
+ CHECK_CONST_NODE_VIEW_REF_TYPE(date_time);
+
+}
diff --git a/tomlplusplus/tests/leakproof.hpp b/tomlplusplus/tests/leakproof.hpp
new file mode 100644
index 0000000000..2ec271e784
--- /dev/null
+++ b/tomlplusplus/tests/leakproof.hpp
@@ -0,0 +1,19 @@
+#pragma once
+
+namespace leakproof
+{
+ void table_created() noexcept;
+ void array_created() noexcept;
+ void value_created() noexcept;
+ void table_destroyed() noexcept;
+ void array_destroyed() noexcept;
+ void value_destroyed() noexcept;
+}
+
+#define TOML_LIFETIME_HOOKS 1
+#define TOML_TABLE_CREATED ::leakproof::table_created()
+#define TOML_TABLE_DESTROYED ::leakproof::table_destroyed()
+#define TOML_ARRAY_CREATED ::leakproof::array_created()
+#define TOML_ARRAY_DESTROYED ::leakproof::array_destroyed()
+#define TOML_VALUE_CREATED ::leakproof::value_created()
+#define TOML_VALUE_DESTROYED ::leakproof::value_destroyed()
diff --git a/tomlplusplus/tests/lib_catch2.hpp b/tomlplusplus/tests/lib_catch2.hpp
new file mode 100644
index 0000000000..17e2da9fe7
--- /dev/null
+++ b/tomlplusplus/tests/lib_catch2.hpp
@@ -0,0 +1,44 @@
+// This file is a part of toml++ and is subject to the the terms of the MIT license.
+// Copyright (c) Mark Gillard <mark.gillard@outlook.com.au>
+// See https://github.com/marzer/tomlplusplus/blob/master/LICENSE for the full license text.
+// SPDX-License-Identifier: MIT
+#pragma once
+
+#include "settings.hpp"
+
+#ifdef __clang__
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Weverything"
+#elif defined(__GNUC__)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wall"
+#pragma GCC diagnostic ignored "-Wextra"
+#pragma GCC diagnostic ignored "-Wpadded"
+#pragma GCC diagnostic ignored "-Wfloat-equal"
+#elif defined(_MSC_VER)
+#pragma warning(push, 0)
+#pragma warning(disable : 4619)
+#pragma warning(disable : 4365)
+#pragma warning(disable : 4868)
+#pragma warning(disable : 5105)
+#pragma warning(disable : 5262)
+#pragma warning(disable : 5264)
+#endif
+
+#if !defined(USE_VENDORED_LIBS) || USE_VENDORED_LIBS
+#include "../vendor/catch.hpp"
+#elif __has_include(<Catch2/single_include/catch2/catch.hpp>)
+#include <Catch2/single_include/catch2/catch.hpp>
+#elif __has_include(<catch2/catch.hpp>)
+#include <catch2/catch.hpp>
+#else
+#error Catch2 is missing!
+#endif
+
+#ifdef __clang__
+#pragma clang diagnostic pop
+#elif defined(__GNUC__)
+#pragma GCC diagnostic pop
+#elif defined(_MSC_VER)
+#pragma warning(pop)
+#endif
diff --git a/tomlplusplus/tests/main.cpp b/tomlplusplus/tests/main.cpp
new file mode 100644
index 0000000000..67c98cc7a8
--- /dev/null
+++ b/tomlplusplus/tests/main.cpp
@@ -0,0 +1,98 @@
+// This file is a part of toml++ and is subject to the the terms of the MIT license.
+// Copyright (c) Mark Gillard <mark.gillard@outlook.com.au>
+// See https://github.com/marzer/tomlplusplus/blob/master/LICENSE for the full license text.
+// SPDX-License-Identifier: MIT
+
+#ifdef _MSC_VER
+#pragma warning(disable : 4619)
+#pragma warning(disable : 5262)
+#pragma warning(disable : 5264)
+#endif
+
+#define CATCH_CONFIG_RUNNER
+#include "lib_catch2.hpp"
+#include <clocale>
+
+#if LEAK_TESTS
+
+#include <iostream>
+#include <iomanip>
+#include <atomic>
+#include "leakproof.hpp"
+using namespace std::string_view_literals;
+
+namespace leakproof
+{
+ static std::atomic_llong total_created_ = 0LL;
+ static std::atomic_llong tables_ = 0LL;
+ static std::atomic_llong arrays_ = 0LL;
+ static std::atomic_llong values_ = 0LL;
+
+ void table_created() noexcept
+ {
+ tables_++;
+ total_created_++;
+ }
+
+ void table_destroyed() noexcept
+ {
+ tables_--;
+ }
+
+ void array_created() noexcept
+ {
+ arrays_++;
+ total_created_++;
+ }
+
+ void array_destroyed() noexcept
+ {
+ arrays_--;
+ }
+
+ void value_created() noexcept
+ {
+ values_++;
+ total_created_++;
+ }
+
+ void value_destroyed() noexcept
+ {
+ values_--;
+ }
+}
+
+#endif // LEAK_TESTS
+
+int main(int argc, char* argv[])
+{
+#ifdef _WIN32
+ SetConsoleOutputCP(65001);
+#endif
+ std::setlocale(LC_ALL, "");
+ std::locale::global(std::locale(""));
+ if (auto result = Catch::Session().run(argc, argv))
+ return result;
+
+#if LEAK_TESTS
+ constexpr auto handle_leak_result = [](std::string_view name, long long count) noexcept
+ {
+ std::cout << "\n"sv << name << ": "sv << std::right << std::setw(6) << count;
+ if (count > 0LL)
+ std::cout << " *** LEAK DETECTED ***"sv;
+ if (count < 0LL)
+ std::cout << " *** UNBALANCED LIFETIME CALLS ***"sv;
+ return count == 0LL;
+ };
+ std::cout << "\n---------- leak test results ----------"sv;
+ bool ok = true;
+ ok = handle_leak_result("tables"sv, leakproof::tables_.load()) && ok;
+ ok = handle_leak_result("arrays"sv, leakproof::arrays_.load()) && ok;
+ ok = handle_leak_result("values"sv, leakproof::values_.load()) && ok;
+ std::cout << "\n(total objects created: "sv << leakproof::total_created_.load() << ")"sv;
+ std::cout << "\n---------------------------------------"sv;
+ return ok ? 0 : -1;
+#else
+ return 0;
+#endif
+}
diff --git a/tomlplusplus/tests/manipulating_arrays.cpp b/tomlplusplus/tests/manipulating_arrays.cpp
new file mode 100644
index 0000000000..2e42cfdfd7
--- /dev/null
+++ b/tomlplusplus/tests/manipulating_arrays.cpp
@@ -0,0 +1,629 @@
+// This file is a part of toml++ and is subject to the the terms of the MIT license.
+// Copyright (c) Mark Gillard <mark.gillard@outlook.com.au>
+// See https://github.com/marzer/tomlplusplus/blob/master/LICENSE for the full license text.
+// SPDX-License-Identifier: MIT
+
+#include "tests.hpp"
+
+TEST_CASE("arrays - moving")
+{
+ static constexpr auto filename = "foo.toml"sv;
+
+ parsing_should_succeed(
+ FILE_LINE_ARGS,
+ R"(test = [ "foo" ])"sv,
+ [&](table&& tbl)
+ {
+ // sanity-check initial state of a freshly-parsed array
+ auto arr1 = tbl["test"].as<array>();
+ REQUIRE(arr1);
+ CHECK(arr1->size() == 1u);
+ CHECK(arr1->source().begin == source_position{ 1, 8 });
+ CHECK(arr1->source().end == source_position{ 1, 17 });
+ CHECK(arr1->source().path);
+ CHECK(*arr1->source().path == filename);
+ REQUIRE(arr1->get_as<std::string>(0u));
+ CHECK(*arr1->get_as<std::string>(0u) == "foo"sv);
+
+ // sanity check the virtual type checks
+ CHECK(arr1->type() == node_type::array);
+ CHECK(!arr1->is_table());
+ CHECK(arr1->is_array());
+ CHECK(!arr1->is_array_of_tables());
+ CHECK(!arr1->is_value());
+ CHECK(!arr1->is_string());
+ CHECK(!arr1->is_integer());
+ CHECK(!arr1->is_floating_point());
+ CHECK(!arr1->is_number());
+ CHECK(!arr1->is_boolean());
+ CHECK(!arr1->is_date());
+ CHECK(!arr1->is_time());
+ CHECK(!arr1->is_date_time());
+
+ // sanity check the virtual type casts (non-const)
+ CHECK(!arr1->as_table());
+ CHECK(arr1->as_array() == arr1);
+ CHECK(!arr1->as_string());
+ CHECK(!arr1->as_integer());
+ CHECK(!arr1->as_floating_point());
+ CHECK(!arr1->as_boolean());
+ CHECK(!arr1->as_date());
+ CHECK(!arr1->as_time());
+ CHECK(!arr1->as_date_time());
+
+ // sanity check the virtual type casts (const)
+ const auto carr1 = &std::as_const(*arr1);
+ CHECK(!carr1->as_table());
+ CHECK(carr1->as_array() == carr1);
+ CHECK(!carr1->as_string());
+ CHECK(!carr1->as_integer());
+ CHECK(!carr1->as_floating_point());
+ CHECK(!carr1->as_boolean());
+ CHECK(!carr1->as_date());
+ CHECK(!carr1->as_time());
+ CHECK(!carr1->as_date_time());
+
+ // sanity-check initial state of default-constructed array
+ array arr2;
+ CHECK(arr2.source().begin == source_position{});
+ CHECK(arr2.source().end == source_position{});
+ CHECK(!arr2.source().path);
+ CHECK(arr2.size() == 0u);
+
+ // check the results of move-assignment
+ arr2 = std::move(*arr1);
+ CHECK(arr2.source().begin == source_position{ 1, 8 });
+ CHECK(arr2.source().end == source_position{ 1, 17 });
+ CHECK(arr2.source().path);
+ CHECK(*arr2.source().path == filename);
+ CHECK(arr2.size() == 1u);
+ REQUIRE(arr2.get_as<std::string>(0u));
+ CHECK(*arr2.get_as<std::string>(0u) == "foo"sv);
+
+ // check that moved-from array is now the same as default-constructed
+ CHECK(arr1->source().begin == source_position{});
+ CHECK(arr1->source().end == source_position{});
+ CHECK(!arr1->source().path);
+ CHECK(arr1->size() == 0u);
+
+ // check the results of move-construction
+ array arr3{ std::move(arr2) };
+ CHECK(arr3.source().begin == source_position{ 1, 8 });
+ CHECK(arr3.source().end == source_position{ 1, 17 });
+ CHECK(arr3.source().path);
+ CHECK(*arr3.source().path == filename);
+ CHECK(arr3.size() == 1u);
+ REQUIRE(arr3.get_as<std::string>(0u));
+ CHECK(*arr3.get_as<std::string>(0u) == "foo"sv);
+
+ // check that moved-from array is now the same as default-constructed
+ CHECK(arr2.source().begin == source_position{});
+ CHECK(arr2.source().end == source_position{});
+ CHECK(!arr2.source().path);
+ CHECK(arr2.size() == 0u);
+ },
+ filename);
+}
+
+TEST_CASE("arrays - copying")
+{
+ static constexpr auto filename = "foo.toml"sv;
+
+ parsing_should_succeed(
+ FILE_LINE_ARGS,
+ R"(test = [ "foo" ])"sv,
+ [&](table&& tbl)
+ {
+ // sanity-check initial state of a freshly-parsed array
+ auto arr1 = tbl["test"].as<array>();
+ REQUIRE(arr1);
+ CHECK(arr1->size() == 1u);
+ CHECK(arr1->source().begin == source_position{ 1, 8 });
+ CHECK(arr1->source().end == source_position{ 1, 17 });
+ CHECK(arr1->source().path);
+ CHECK(*arr1->source().path == filename);
+ REQUIRE(arr1->get_as<std::string>(0u));
+ CHECK(*arr1->get_as<std::string>(0u) == "foo"sv);
+
+ // sanity-check initial state of default-constructed array
+ array arr2;
+ CHECK(arr2.source().begin == source_position{});
+ CHECK(arr2.source().end == source_position{});
+ CHECK(!arr2.source().path);
+ CHECK(arr2.size() == 0u);
+
+ // check the results of copy-assignment
+ arr2 = *arr1;
+ CHECK(arr2.source().begin == source_position{});
+ CHECK(arr2.source().end == source_position{});
+ CHECK(!arr2.source().path);
+ CHECK(arr2.size() == 1u);
+ REQUIRE(arr2.get_as<std::string>(0u));
+ CHECK(*arr2.get_as<std::string>(0u) == "foo"sv);
+ CHECK(arr2 == *arr1);
+
+ // check the results of copy-construction
+ array arr3{ arr2 };
+ CHECK(arr3.source().begin == source_position{});
+ CHECK(arr3.source().end == source_position{});
+ CHECK(!arr3.source().path);
+ CHECK(arr3.size() == 1u);
+ REQUIRE(arr3.get_as<std::string>(0u));
+ CHECK(*arr3.get_as<std::string>(0u) == "foo"sv);
+ CHECK(arr3 == *arr1);
+ CHECK(arr3 == arr2);
+ },
+ filename);
+}
+
+TEST_CASE("arrays - construction")
+{
+ {
+ array arr;
+ CHECK(arr.size() == 0u);
+ CHECK(arr.empty());
+ CHECK(arr.begin() == arr.end());
+ CHECK(arr.cbegin() == arr.cend());
+ CHECK(arr.source().begin == source_position{});
+ CHECK(arr.source().end == source_position{});
+ CHECK(!arr.source().path);
+ CHECK(!arr.is_homogeneous());
+ }
+
+ {
+ array arr{ 42 };
+ CHECK(arr.size() == 1u);
+ CHECK(!arr.empty());
+ CHECK(arr.begin() != arr.end());
+ CHECK(arr.cbegin() != arr.cend());
+ REQUIRE(arr.get_as<int64_t>(0u));
+ CHECK(*arr.get_as<int64_t>(0u) == 42);
+ CHECK(arr.get(0u) == &arr[0u]);
+ CHECK(arr.is_homogeneous());
+ CHECK(arr.is_homogeneous<int64_t>());
+ CHECK(!arr.is_homogeneous<double>());
+ CHECK(arr.get(0u) == &arr.at(0u));
+
+ const array& carr = arr;
+ CHECK(carr.size() == 1u);
+ CHECK(!carr.empty());
+ CHECK(carr.begin() != carr.end());
+ CHECK(carr.cbegin() != carr.cend());
+ REQUIRE(carr.get_as<int64_t>(0u));
+ CHECK(*carr.get_as<int64_t>(0u) == 42);
+ CHECK(carr.get(0u) == &carr[0u]);
+ CHECK(carr.is_homogeneous());
+ CHECK(carr.is_homogeneous<int64_t>());
+ CHECK(!carr.is_homogeneous<double>());
+ CHECK(carr.get(0u) == &carr.at(0u));
+ }
+
+ {
+ array arr{ 42, "test"sv, 10.0f, array{}, value{ 3 } };
+ CHECK(arr.size() == 5u);
+ CHECK(!arr.empty());
+ REQUIRE(arr.get_as<int64_t>(0u));
+ CHECK(*arr.get_as<int64_t>(0u) == 42);
+ CHECK(arr.get(0u) == &arr[0u]);
+ REQUIRE(arr.get_as<std::string>(1u));
+ CHECK(*arr.get_as<std::string>(1u) == "test"sv);
+ CHECK(arr.get(1u) == &arr[1u]);
+ REQUIRE(arr.get_as<double>(2u));
+ CHECK(*arr.get_as<double>(2u) == 10.0);
+ REQUIRE(arr.get_as<array>(3u));
+ REQUIRE(arr.get_as<int64_t>(4u));
+ CHECK(*arr.get_as<int64_t>(4u) == 3);
+ CHECK(!arr.is_homogeneous());
+ CHECK(arr.get(0u) == &arr.at(0u));
+ CHECK(arr.get(1u) == &arr.at(1u));
+ }
+
+#if TOML_ENABLE_WINDOWS_COMPAT
+ {
+ array arr{ "mixed", "string"sv, L"test", L"kek"sv };
+ CHECK(arr.size() == 4u);
+ CHECK(arr.is_homogeneous());
+ CHECK(arr.is_homogeneous<std::string>());
+ CHECK(*arr.get_as<std::string>(0) == "mixed"sv);
+ CHECK(*arr.get_as<std::string>(1) == "string"sv);
+ CHECK(*arr.get_as<std::string>(2) == "test"sv);
+ CHECK(*arr.get_as<std::string>(3) == "kek"sv);
+ }
+#endif // TOML_ENABLE_WINDOWS_COMPAT
+}
+
+TEST_CASE("arrays - equality")
+{
+ array arr1{ 1, 2, 3 };
+ CHECK(arr1 == arr1);
+ {
+ auto ilist = { 1, 2, 3 };
+ CHECK(arr1 == ilist);
+ CHECK(ilist == arr1);
+
+ ilist = { 2, 3, 4 };
+ CHECK(arr1 != ilist);
+ CHECK(ilist != arr1);
+
+ auto ivec = std::vector{ 1, 2, 3 };
+ CHECK(arr1 == ivec);
+ CHECK(ivec == arr1);
+
+ ivec = std::vector{ 2, 3, 4 };
+ CHECK(arr1 != ivec);
+ CHECK(ivec != arr1);
+ }
+
+ array arr2{ 1, 2, 3 };
+ CHECK(arr1 == arr2);
+
+ array arr3{ 1, 2 };
+ CHECK(arr1 != arr3);
+
+ array arr4{ 1, 2, 3, 4 };
+ CHECK(arr1 != arr4);
+
+ array arr5{ 1, 2, 3.0 };
+ CHECK(arr1 != arr5);
+
+ array arr6{};
+ CHECK(arr1 != arr6);
+ CHECK(arr6 == arr6);
+
+ array arr7{};
+ CHECK(arr6 == arr7);
+}
+
+TEST_CASE("arrays - insertion and erasure")
+{
+ array arr;
+
+ // insert(const_iterator pos, ElemType&& val)
+ auto it = arr.insert(arr.cbegin(), 42);
+ CHECK(it == arr.begin());
+ CHECK(arr.size() == 1u);
+ CHECK(!arr.empty());
+ REQUIRE(arr.get_as<int64_t>(0u));
+ CHECK(*arr.get_as<int64_t>(0u) == 42);
+ REQUIRE(arr == array{ 42 });
+
+ // insert(const_iterator pos, size_t count, ElemType&& val)
+ it = arr.insert(arr.cend(), 3, 10.0f);
+ CHECK(it == arr.begin() + 1);
+ CHECK(arr.size() == 4u);
+ REQUIRE(arr.get_as<double>(1u));
+ CHECK(*arr.get_as<double>(1u) == 10.0);
+ REQUIRE(arr.get_as<double>(2u));
+ CHECK(*arr.get_as<double>(2u) == 10.0);
+ REQUIRE(arr.get_as<double>(3u));
+ CHECK(*arr.get_as<double>(3u) == 10.0);
+ REQUIRE(arr == array{ 42, 10.0, 10.0, 10.0 });
+
+ // emplace(const_iterator pos, Args &&... args) noexcept
+ it = arr.emplace<array>(arr.cbegin(), 1, 2, 3);
+ CHECK(it == arr.begin());
+ CHECK(arr.size() == 5u);
+ REQUIRE(arr.get_as<array>(0u));
+ CHECK(arr.get_as<array>(0u)->size() == 3u);
+ REQUIRE(arr == array{ array{ 1, 2, 3 }, 42, 10.0, 10.0, 10.0 });
+
+ // push_back(ElemType&& val) noexcept
+ {
+ arr.push_back("test"sv);
+ auto& val = *arr.back().as_string();
+ CHECK(arr.size() == 6u);
+ REQUIRE(arr.get_as<std::string>(5u));
+ CHECK(*arr.get_as<std::string>(5u) == "test"sv);
+ CHECK(val == "test"sv);
+ CHECK(&val == &arr.back());
+ REQUIRE(arr == array{ array{ 1, 2, 3 }, 42, 10.0, 10.0, 10.0, "test"sv });
+ }
+
+ // decltype(auto) emplace_back(Args&&... args) noexcept
+ {
+ decltype(auto) val = arr.emplace_back<std::string>("test2"sv);
+ CHECK(arr.size() == 7u);
+ REQUIRE(arr.get_as<std::string>(6u));
+ CHECK(*arr.get_as<std::string>(6u) == "test2"sv);
+ CHECK(val == "test2"sv);
+ CHECK(&val == &arr.back());
+ REQUIRE(arr == array{ array{ 1, 2, 3 }, 42, 10.0, 10.0, 10.0, "test"sv, "test2"sv });
+ }
+
+ // erase(const_iterator pos) noexcept;
+ it = arr.erase(arr.cbegin());
+ REQUIRE(arr == array{ 42, 10.0, 10.0, 10.0, "test"sv, "test2"sv });
+ CHECK(it == arr.begin());
+ CHECK(arr.size() == 6u);
+
+ // erase(const_iterator first, const_iterator last) noexcept;
+ it = arr.erase(arr.cbegin() + 2, arr.cbegin() + 4);
+ REQUIRE(arr == array{ 42, 10.0, "test"sv, "test2"sv });
+ CHECK(it == arr.begin() + 2);
+ CHECK(arr.size() == 4u);
+
+ arr.pop_back();
+ REQUIRE(arr == array{ 42, 10.0, "test"sv });
+ CHECK(arr.size() == 3u);
+
+ arr.clear();
+ REQUIRE(arr == array{});
+ CHECK(arr.size() == 0u);
+ CHECK(arr.empty());
+
+ // insert(const_iterator pos, Iter first, Iter last)
+ {
+ auto vals = std::vector{ 1.0, 2.0, 3.0 };
+ arr.insert(arr.cbegin(), vals.begin(), vals.end());
+ CHECK(arr.size() == 3u);
+ REQUIRE(arr.get_as<double>(0u));
+ CHECK(*arr.get_as<double>(0u) == 1.0);
+ REQUIRE(arr.get_as<double>(1u));
+ CHECK(*arr.get_as<double>(1u) == 2.0);
+ REQUIRE(arr.get_as<double>(2u));
+ CHECK(*arr.get_as<double>(2u) == 3.0);
+
+ arr.insert(arr.cbegin() + 1, vals.begin(), vals.end());
+ CHECK(arr.size() == 6u);
+ REQUIRE(arr.get_as<double>(0u));
+ CHECK(*arr.get_as<double>(0u) == 1.0);
+ REQUIRE(arr.get_as<double>(1u));
+ CHECK(*arr.get_as<double>(1u) == 1.0);
+ REQUIRE(arr.get_as<double>(2u));
+ CHECK(*arr.get_as<double>(2u) == 2.0);
+ REQUIRE(arr.get_as<double>(3u));
+ CHECK(*arr.get_as<double>(3u) == 3.0);
+ REQUIRE(arr.get_as<double>(4u));
+ CHECK(*arr.get_as<double>(4u) == 2.0);
+ REQUIRE(arr.get_as<double>(5u));
+ CHECK(*arr.get_as<double>(5u) == 3.0);
+ }
+
+ // insert(const_iterator pos, Iter first, Iter last) (with move iterators)
+ {
+ arr.clear();
+
+ std::vector<std::string> vals{ "foo", "bar", "kek" };
+ arr.insert(arr.cbegin(), std::make_move_iterator(vals.begin()), std::make_move_iterator(vals.end()));
+ CHECK(arr.size() == 3u);
+ REQUIRE(arr.get_as<std::string>(0));
+ CHECK(*arr.get_as<std::string>(0) == "foo");
+ REQUIRE(arr.get_as<std::string>(1));
+ CHECK(*arr.get_as<std::string>(1) == "bar");
+ REQUIRE(arr.get_as<std::string>(2));
+ CHECK(*arr.get_as<std::string>(2) == "kek");
+
+ REQUIRE(vals.size() == 3u);
+ CHECK(vals[0] == "");
+ CHECK(vals[1] == "");
+ CHECK(vals[2] == "");
+ }
+
+ // iterator insert(const_iterator pos, std::initializer_list<ElemType> ilist) noexcept
+ {
+ arr.clear();
+
+ arr.insert(arr.cbegin(), { 1.0, 2.0, 3.0 });
+ CHECK(arr.size() == 3u);
+ REQUIRE(arr.get_as<double>(0u));
+ CHECK(*arr.get_as<double>(0u) == 1.0);
+ REQUIRE(arr.get_as<double>(1u));
+ CHECK(*arr.get_as<double>(1u) == 2.0);
+ REQUIRE(arr.get_as<double>(2u));
+ CHECK(*arr.get_as<double>(2u) == 3.0);
+
+ arr.insert(arr.cbegin() + 1, { 1.0, 2.0, 3.0 });
+ CHECK(arr.size() == 6u);
+ REQUIRE(arr.get_as<double>(0u));
+ CHECK(*arr.get_as<double>(0u) == 1.0);
+ REQUIRE(arr.get_as<double>(1u));
+ CHECK(*arr.get_as<double>(1u) == 1.0);
+ REQUIRE(arr.get_as<double>(2u));
+ CHECK(*arr.get_as<double>(2u) == 2.0);
+ REQUIRE(arr.get_as<double>(3u));
+ CHECK(*arr.get_as<double>(3u) == 3.0);
+ REQUIRE(arr.get_as<double>(4u));
+ CHECK(*arr.get_as<double>(4u) == 2.0);
+ REQUIRE(arr.get_as<double>(5u));
+ CHECK(*arr.get_as<double>(5u) == 3.0);
+ }
+
+ // iterator replace(const_iterator pos, ElemType&& elem) noexcept
+ {
+ arr.clear();
+ arr.insert(arr.begin(), { 1, 2, 3 });
+ CHECK(arr == array{ 1, 2, 3 });
+ arr.replace(arr.begin() + 1u, "two"sv);
+ CHECK(arr == array{ 1, "two"sv, 3 });
+ }
+
+#if TOML_ENABLE_WINDOWS_COMPAT
+
+ arr.clear();
+ it = arr.insert(arr.cbegin(), L"test");
+ CHECK(*arr.get_as<std::string>(0u) == "test"sv);
+
+ it = arr.emplace<std::string>(arr.cbegin(), L"test2"sv);
+ CHECK(*arr.get_as<std::string>(0u) == "test2"sv);
+
+ arr.push_back(L"test3"s);
+ CHECK(*arr.back().as_string() == "test3"sv);
+
+ arr.emplace_back<std::string>(L"test4");
+ CHECK(*arr.back().as_string() == "test4"sv);
+
+#endif // TOML_ENABLE_WINDOWS_COMPAT
+
+ // push_back with value_flags
+ {
+ arr.clear();
+
+ auto hex = toml::value{ 1 };
+ hex.flags(value_flags::format_as_hexadecimal);
+ CHECK(hex.flags() == value_flags::format_as_hexadecimal);
+
+ arr.push_back(hex);
+ CHECK(hex.flags() == value_flags::format_as_hexadecimal);
+ CHECK(arr.back().as_integer()->flags() == value_flags::format_as_hexadecimal);
+
+ arr.push_back(std::move(hex));
+ CHECK(hex.flags() == value_flags{});
+ CHECK(arr.back().as_integer()->flags() == value_flags::format_as_hexadecimal);
+ }
+}
+
+TEST_CASE("arrays - flattening")
+{
+ {
+ array arr{
+ 1,
+ 2,
+ 3,
+ array{ 4, 5 },
+ 6,
+ array{},
+ array{ 7,
+ array{
+ 8,
+ array{ 9 },
+ 10,
+ array{},
+ },
+ 11 },
+ };
+ arr.flatten();
+ CHECK(arr == array{ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 });
+ }
+
+ {
+ array arr{ array{},
+ array{ inserter{ array{} } },
+ array{ array{}, array{ array{}, array{} }, array{} },
+ array{ array{ array{ array{ array{ array{ 1 } } } } } } };
+ arr.flatten();
+ CHECK(arr == array{ 1 });
+ }
+}
+
+TEST_CASE("arrays - pruning")
+{
+ // [ 1, [ 2, [], 3 ], { 4 = 5, 6 = 7 }, [], 8, [{}], 9, 10 ]
+ const auto arr =
+ array{ 1, array{ 2, array{}, 3 }, table{ { "4", 5 }, { "6", array{} } }, array{}, 8, array{ table{} }, 9, 10 };
+
+ // [ 1, [ 2, 3 ], { 4 = 5, 6 = 7 }, 8, 9, 10 ]
+ const auto pruned_recursive = array{ 1, array{ 2, 3 }, table{ { "4", 5 } }, 8, 9, 10 };
+ CHECK(array{ arr }.prune(true) == pruned_recursive);
+
+ // [ 1, [ 2, [], 3 ], { 4 = 5, 6 = 7 }, [], 8, [{}], 9, 10 ]
+ const auto pruned_flat =
+ array{ 1, array{ 2, array{}, 3 }, table{ { "4", 5 }, { "6", array{} } }, 8, array{ table{} }, 9, 10 };
+ CHECK(array{ arr }.prune(false) == pruned_flat);
+}
+
+TEST_CASE("arrays - resizing and truncation")
+{
+ array arr{ 1, 2, 3, 4, 5 };
+ CHECK(arr.size() == 5u);
+
+ // truncate with no change
+ arr.truncate(5u);
+ CHECK(arr.size() == 5u);
+ CHECK(arr == array{ 1, 2, 3, 4, 5 });
+
+ // truncate down to three elements
+ arr.truncate(3u);
+ CHECK(arr.size() == 3u);
+ CHECK(arr == array{ 1, 2, 3 });
+
+ // resize down to two elements
+ arr.resize(2u, 42);
+ CHECK(arr.size() == 2u);
+ CHECK(arr == array{ 1, 2 });
+
+ // resize with no change
+ arr.resize(2u, 42);
+ CHECK(arr.size() == 2u);
+ CHECK(arr == array{ 1, 2 });
+
+ // resize up to six elements
+ arr.resize(6u, 42);
+ CHECK(arr.size() == 6u);
+ CHECK(arr == array{ 1, 2, 42, 42, 42, 42 });
+}
+
+TEST_CASE("arrays - for_each")
+{
+ const auto arr = array{ 1, 2.0, 3, "four", false };
+
+ SECTION("type checking")
+ {
+ int count = 0;
+ int ints = 0;
+ int floats = 0;
+ int numbers = 0;
+ int strings = 0;
+ int bools = 0;
+ arr.for_each(
+ [&](const auto& v) noexcept
+ {
+ count++;
+ if constexpr (toml::is_integer<decltype(v)>)
+ ints++;
+ if constexpr (toml::is_floating_point<decltype(v)>)
+ floats++;
+ if constexpr (toml::is_number<decltype(v)>)
+ numbers++;
+ if constexpr (toml::is_string<decltype(v)>)
+ strings++;
+ if constexpr (toml::is_boolean<decltype(v)>)
+ bools++;
+ });
+ CHECK(count == 5);
+ CHECK(ints == 2);
+ CHECK(floats == 1);
+ CHECK(numbers == (ints + floats));
+ CHECK(strings == 1);
+ CHECK(bools == 1);
+ }
+
+#if !TOML_RETURN_BOOL_FROM_FOR_EACH_BROKEN
+
+ SECTION("early-exit (elem, index)")
+ {
+ int count = 0;
+ arr.for_each(
+ [&](const auto& elem, size_t /*idx*/) noexcept -> bool
+ {
+ count++;
+ return !toml::is_string<decltype(elem)>;
+ });
+ CHECK(count == 4);
+ }
+
+ SECTION("early-exit (elem)")
+ {
+ int count = 0;
+ arr.for_each(
+ [&](const auto& elem) noexcept -> bool
+ {
+ count++;
+ return !toml::is_string<decltype(elem)>;
+ });
+ CHECK(count == 4);
+ }
+
+ SECTION("early-exit (index, elem)")
+ {
+ int count = 0;
+ arr.for_each(
+ [&](size_t /*idx*/, const auto& elem) noexcept -> bool
+ {
+ count++;
+ return !toml::is_string<decltype(elem)>;
+ });
+ CHECK(count == 4);
+ }
+
+#endif
+}
diff --git a/tomlplusplus/tests/manipulating_parse_result.cpp b/tomlplusplus/tests/manipulating_parse_result.cpp
new file mode 100644
index 0000000000..c0ef4bea66
--- /dev/null
+++ b/tomlplusplus/tests/manipulating_parse_result.cpp
@@ -0,0 +1,115 @@
+// This file is a part of toml++ and is subject to the the terms of the MIT license.
+// Copyright (c) Mark Gillard <mark.gillard@outlook.com.au>
+// See https://github.com/marzer/tomlplusplus/blob/master/LICENSE for the full license text.
+// SPDX-License-Identifier: MIT
+
+#include "tests.hpp"
+
+#if !TOML_EXCEPTIONS
+
+TEST_CASE("parse_result - good parse")
+{
+ auto result = "key = true"_toml;
+ static_assert(std::is_same_v<decltype(result), parse_result>);
+ static_assert(!std::is_same_v<decltype(result), table>);
+
+ REQUIRE(result.succeeded());
+ REQUIRE(!result.failed());
+ REQUIRE(result);
+
+ REQUIRE(!result.table().empty());
+ REQUIRE(result.table().size() == 1);
+ REQUIRE(!std::move(result).table().empty());
+ REQUIRE(!static_cast<const parse_result&>(result).table().empty());
+
+ REQUIRE(!static_cast<table&>(result).empty());
+ REQUIRE(!static_cast<table&&>(result).empty());
+ REQUIRE(!static_cast<const table&>(result).empty());
+
+ auto& tbl = static_cast<table&>(result);
+ CHECK(tbl["key"sv]);
+ CHECK(result["key"sv]);
+ CHECK(&result["key"sv].ref<bool>() == &tbl["key"sv].ref<bool>());
+ CHECK(result.begin() == tbl.begin());
+ CHECK(result.end() == tbl.end());
+ CHECK(result.begin() != tbl.end());
+ CHECK(result.cbegin() == tbl.cbegin());
+ CHECK(result.cend() == tbl.cend());
+ CHECK(result.cbegin() != tbl.cend());
+
+ auto& cresult = static_cast<const parse_result&>(result);
+ auto& ctbl = static_cast<const table&>(cresult);
+ CHECK(cresult.begin() == ctbl.begin());
+ CHECK(cresult.end() == ctbl.end());
+ CHECK(cresult.begin() != ctbl.end());
+ CHECK(cresult.cbegin() == ctbl.cbegin());
+ CHECK(cresult.cend() == ctbl.cend());
+ CHECK(cresult.cbegin() != ctbl.cend());
+ CHECK(ctbl["key"sv]);
+ CHECK(cresult["key"sv]);
+ CHECK(&cresult["key"sv].ref<bool>() == &ctbl["key"sv].ref<bool>());
+
+ size_t tbl_iterations{};
+ for (auto&& [k, v] : tbl)
+ {
+ (void)k;
+ (void)v;
+ tbl_iterations++;
+ }
+ size_t result_iterations{};
+ for (auto& [k, v] : result)
+ {
+ (void)k;
+ (void)v;
+ result_iterations++;
+ }
+ size_t cresult_iterations{};
+ for (auto [k, v] : cresult)
+ {
+ (void)k;
+ (void)v;
+ cresult_iterations++;
+ }
+ CHECK(tbl_iterations == tbl.size());
+ CHECK(tbl_iterations == result_iterations);
+ CHECK(tbl_iterations == cresult_iterations);
+}
+
+TEST_CASE("parse_result - bad parse")
+{
+ auto result = "key = trUe"_toml;
+ static_assert(std::is_same_v<decltype(result), parse_result>);
+ static_assert(!std::is_same_v<decltype(result), table>);
+
+ REQUIRE(!result.succeeded());
+ REQUIRE(result.failed());
+ REQUIRE(!result);
+
+ CHECK(!result["key"sv]);
+ CHECK(result.begin() == decltype(result.begin()){});
+ CHECK(result.end() == decltype(result.end()){});
+ CHECK(result.cbegin() == decltype(result.cbegin()){});
+ CHECK(result.cend() == decltype(result.cend()){});
+
+ auto& cresult = static_cast<const parse_result&>(result);
+ CHECK(!result["key"sv]);
+ CHECK(cresult.begin() == decltype(cresult.begin()){});
+ CHECK(cresult.end() == decltype(cresult.end()){});
+ CHECK(cresult.cbegin() == decltype(cresult.cbegin()){});
+ CHECK(cresult.cend() == decltype(cresult.cend()){});
+
+ for (auto [k, v] : result)
+ {
+ (void)k;
+ (void)v;
+ FAIL("This code should not run");
+ }
+ for (auto [k, v] : cresult)
+ {
+ (void)k;
+ (void)v;
+ FAIL("This code should not run");
+ }
+}
+
+#endif //!TOML_EXCEPTIONS
diff --git a/tomlplusplus/tests/manipulating_tables.cpp b/tomlplusplus/tests/manipulating_tables.cpp
new file mode 100644
index 0000000000..56f7b3bf3c
--- /dev/null
+++ b/tomlplusplus/tests/manipulating_tables.cpp
@@ -0,0 +1,760 @@
+// This file is a part of toml++ and is subject to the the terms of the MIT license.
+// Copyright (c) Mark Gillard <mark.gillard@outlook.com.au>
+// See https://github.com/marzer/tomlplusplus/blob/master/LICENSE for the full license text.
+// SPDX-License-Identifier: MIT
+
+#include "tests.hpp"
+
+TEST_CASE("tables - moving")
+{
+ static constexpr auto filename = "foo.toml"sv;
+
+ parsing_should_succeed(
+ FILE_LINE_ARGS,
+ R"(test = { val1 = "foo" })"sv,
+ [&](table&& tbl)
+ {
+ // sanity-check initial state of a freshly-parsed table
+ REQUIRE(tbl["test"].as<table>());
+ CHECK(tbl["test"].as<table>()->size() == 1u);
+ CHECK(tbl["test"].as<table>()->source().begin == source_position{ 1, 8 });
+ CHECK(tbl["test"].as<table>()->source().end == source_position{ 1, 24 });
+ CHECK(tbl["test"].node() == tbl.get("test"sv));
+ CHECK(tbl["test"].node() == &tbl.at("test"sv));
+
+ // sanity-check initial state of a freshly-parsed table (const)
+ const table& ctbl = tbl;
+ REQUIRE(ctbl["test"].as<table>());
+ CHECK(ctbl["test"].as<table>()->size() == 1u);
+ CHECK(ctbl["test"].as<table>()->source().begin == source_position{ 1, 8 });
+ CHECK(ctbl["test"].as<table>()->source().end == source_position{ 1, 24 });
+ CHECK(ctbl["test"].node() == ctbl.get("test"sv));
+ CHECK(ctbl["test"].node() == &ctbl.at("test"sv));
+
+ // sanity check the virtual type checks
+ CHECK(tbl.type() == node_type::table);
+ CHECK(tbl.is_table());
+ CHECK(!tbl.is_array());
+ CHECK(!tbl.is_array_of_tables());
+ CHECK(!tbl.is_value());
+ CHECK(!tbl.is_string());
+ CHECK(!tbl.is_integer());
+ CHECK(!tbl.is_floating_point());
+ CHECK(!tbl.is_number());
+ CHECK(!tbl.is_boolean());
+ CHECK(!tbl.is_date());
+ CHECK(!tbl.is_time());
+ CHECK(!tbl.is_date_time());
+
+ // sanity check the virtual type casts (non-const)
+ CHECK(tbl.as_table() == &tbl);
+ CHECK(!tbl.as_array());
+ CHECK(!tbl.as_string());
+ CHECK(!tbl.as_integer());
+ CHECK(!tbl.as_floating_point());
+ CHECK(!tbl.as_boolean());
+ CHECK(!tbl.as_date());
+ CHECK(!tbl.as_time());
+ CHECK(!tbl.as_date_time());
+
+ // sanity check the virtual type casts (const)
+ CHECK(ctbl.as_table() == &ctbl);
+ CHECK(!ctbl.as_array());
+ CHECK(!ctbl.as_string());
+ CHECK(!ctbl.as_integer());
+ CHECK(!ctbl.as_floating_point());
+ CHECK(!ctbl.as_boolean());
+ CHECK(!ctbl.as_date());
+ CHECK(!ctbl.as_time());
+ CHECK(!ctbl.as_date_time());
+
+ // sanity-check initial state of default-constructed table
+ table tbl2;
+ CHECK(tbl2.source().begin == source_position{});
+ CHECK(tbl2.source().end == source_position{});
+ CHECK(!tbl2.source().path);
+ CHECK(tbl2.size() == 0u);
+
+ // check the results of move-assignment
+ tbl2 = std::move(tbl);
+ CHECK(tbl2.source().begin == source_position{ 1, 1 });
+ CHECK(tbl2.source().end == source_position{ 1, 24 });
+ CHECK(tbl2.source().path);
+ CHECK(*tbl2.source().path == filename);
+ CHECK(tbl2.size() == 1u);
+ REQUIRE(tbl2["test"].as<table>());
+ CHECK(tbl2["test"].as<table>()->size() == 1u);
+ CHECK(tbl2["test"]["val1"] == "foo"sv);
+
+ // check that moved-from table is now the same as default-constructed
+ CHECK(tbl.source().begin == source_position{});
+ CHECK(tbl.source().end == source_position{});
+ CHECK(!tbl.source().path);
+ CHECK(tbl.size() == 0u);
+ CHECK(!tbl["test"].as<table>());
+
+ // check the results of move-construction
+ table tbl3{ std::move(tbl2) };
+ CHECK(tbl3.source().begin == source_position{ 1, 1 });
+ CHECK(tbl3.source().end == source_position{ 1, 24 });
+ CHECK(tbl3.source().path);
+ CHECK(*tbl3.source().path == filename);
+ CHECK(tbl3.size() == 1u);
+ REQUIRE(tbl3["test"].as<table>());
+ CHECK(tbl3["test"].as<table>()->size() == 1u);
+ CHECK(tbl3["test"]["val1"] == "foo"sv);
+
+ // check that moved-from table is now the same as default-constructed
+ CHECK(tbl2.source().begin == source_position{});
+ CHECK(tbl2.source().end == source_position{});
+ CHECK(!tbl2.source().path);
+ CHECK(tbl2.size() == 0u);
+ CHECK(!tbl2["test"].as<table>());
+ },
+ filename);
+}
+
+TEST_CASE("tables - copying")
+{
+ static constexpr auto filename = "foo.toml"sv;
+
+ parsing_should_succeed(
+ FILE_LINE_ARGS,
+ R"(test = { val1 = "foo" })"sv,
+ [&](table&& tbl)
+ {
+ // sanity-check initial state of a freshly-parsed table
+ REQUIRE(tbl["test"].as<table>());
+ CHECK(tbl["test"].as<table>()->size() == 1u);
+ CHECK(tbl["test"].as<table>()->source().begin == source_position{ 1, 8 });
+ CHECK(tbl["test"].as<table>()->source().end == source_position{ 1, 24 });
+ CHECK(tbl["test"]["val1"] == "foo");
+
+ // sanity-check initial state of default-constructed table
+ table tbl2;
+ CHECK(tbl2.source().begin == source_position{});
+ CHECK(tbl2.source().end == source_position{});
+ CHECK(!tbl2.source().path);
+ CHECK(tbl2.size() == 0u);
+
+ // check the results of copy-assignment
+ tbl2 = tbl;
+ CHECK(tbl2.source().begin == source_position{});
+ CHECK(tbl2.source().end == source_position{});
+ CHECK(!tbl2.source().path);
+ CHECK(tbl2.size() == 1u);
+ REQUIRE(tbl2["test"].as<table>());
+ CHECK(tbl2["test"].as<table>()->size() == 1u);
+ CHECK(tbl2["test"]["val1"] == "foo"sv);
+ CHECK(tbl2 == tbl);
+
+ // check the results of copy-construction
+ table tbl3{ tbl2 };
+ CHECK(tbl3.source().begin == source_position{});
+ CHECK(tbl3.source().end == source_position{});
+ CHECK(!tbl3.source().path);
+ CHECK(tbl3.size() == 1u);
+ REQUIRE(tbl3["test"].as<table>());
+ CHECK(tbl3["test"].as<table>()->size() == 1u);
+ CHECK(tbl3["test"]["val1"] == "foo"sv);
+ CHECK(tbl3 == tbl2);
+ CHECK(tbl3 == tbl);
+ },
+ filename);
+}
+
+TEST_CASE("tables - construction")
+{
+ {
+ table tbl;
+ CHECK(tbl.size() == 0u);
+ CHECK(tbl.empty());
+ CHECK(tbl.begin() == tbl.end());
+ CHECK(tbl.cbegin() == tbl.cend());
+ CHECK(tbl.source().begin == source_position{});
+ CHECK(tbl.source().end == source_position{});
+ CHECK(!tbl.source().path);
+ }
+
+ {
+ table tbl{ { "foo"sv, 42 } };
+ CHECK(tbl.size() == 1u);
+ CHECK(!tbl.empty());
+ CHECK(tbl.begin() != tbl.end());
+ CHECK(tbl.cbegin() != tbl.cend());
+ REQUIRE(tbl.get_as<int64_t>("foo"sv));
+ CHECK(*tbl.get_as<int64_t>("foo"sv) == 42);
+ }
+
+ {
+ table tbl{ { "foo"sv, 42 }, { "bar"sv, 10.0 }, { "kek"sv, false }, { "qux"sv, array{ 1 } } };
+ CHECK(tbl.size() == 4u);
+ CHECK(!tbl.empty());
+ REQUIRE(tbl.get_as<int64_t>("foo"sv));
+ CHECK(*tbl.get_as<int64_t>("foo"sv) == 42);
+ REQUIRE(tbl.get_as<double>("bar"sv));
+ CHECK(*tbl.get_as<double>("bar"sv) == 10.0);
+ REQUIRE(tbl.get_as<bool>("kek"sv));
+ CHECK(*tbl.get_as<bool>("kek"sv) == false);
+ REQUIRE(tbl.get_as<array>("qux"sv));
+ CHECK(*tbl.get_as<array>("qux"sv) == array{ 1 });
+ }
+
+#if TOML_ENABLE_WINDOWS_COMPAT
+ {
+ table tbl{ { L"foo", L"test1" },
+ { L"bar"sv, L"test2"sv },
+ { L"kek"s, L"test3"sv },
+ { L"qux"sv.data(), L"test4"sv.data() } };
+ CHECK(tbl.size() == 4u);
+ CHECK(!tbl.empty());
+ REQUIRE(tbl.get_as<std::string>("foo"sv));
+ CHECK(*tbl.get_as<std::string>("foo"sv) == "test1"sv);
+ REQUIRE(tbl.get_as<std::string>("bar"sv));
+ CHECK(*tbl.get_as<std::string>("bar"sv) == "test2"sv);
+ REQUIRE(tbl.get_as<std::string>("kek"sv));
+ CHECK(*tbl.get_as<std::string>("kek"sv) == "test3"sv);
+ REQUIRE(tbl.get_as<std::string>("qux"sv));
+ CHECK(*tbl.get_as<std::string>("qux"sv) == "test4"sv);
+ }
+#endif // TOML_ENABLE_WINDOWS_COMPAT
+}
+
+TEST_CASE("tables - equality")
+{
+ static constexpr const char* one = "one";
+
+ table tbl1{ { one, 1 }, { "two", 2 }, { "three", 3 } };
+ CHECK(tbl1 == tbl1);
+
+ table tbl2{ { "one"sv, 1 }, { "two"sv, 2 }, { "three"sv, 3 } };
+ CHECK(tbl1 == tbl2);
+
+ table tbl3{ { "one"sv, 1 }, { "two"sv, 2 } };
+ CHECK(tbl1 != tbl3);
+
+ table tbl4{ { "one"sv, 1 }, { "two"sv, 2 }, { "three"sv, 3 }, { "four"sv, 4 } };
+ CHECK(tbl1 != tbl4);
+
+ table tbl5{ { "one"sv, 1 }, { "two"sv, 2 }, { "three"sv, 3.0 } };
+ CHECK(tbl1 != tbl5);
+
+ table tbl6;
+ CHECK(tbl1 != tbl6);
+ CHECK(tbl6 == tbl6);
+
+ table tbl7;
+ CHECK(tbl6 == tbl7);
+}
+
+namespace
+{
+ template <typename T>
+ static auto advance(T iter, ptrdiff_t offset)
+ {
+ while (offset > 0)
+ {
+ iter++;
+ offset--;
+ }
+ while (offset < 0)
+ {
+ iter--;
+ offset++;
+ }
+ return iter;
+ }
+}
+
+TEST_CASE("tables - insertion and erasure")
+{
+ table tbl;
+ auto res = tbl.insert("a", 42);
+ CHECK(res.first == tbl.begin());
+ CHECK(res.second == true);
+ CHECK(tbl.size() == 1u);
+ CHECK(!tbl.empty());
+ REQUIRE(tbl.get_as<int64_t>("a"sv));
+ CHECK(*tbl.get_as<int64_t>("a"sv) == 42);
+ REQUIRE(tbl == table{ { "a"sv, 42 } });
+
+ res = tbl.insert("a", 69);
+ CHECK(res.first == tbl.begin());
+ CHECK(res.second == false);
+ CHECK(tbl.size() == 1u);
+ REQUIRE(tbl.get_as<int64_t>("a"));
+ CHECK(*tbl.get_as<int64_t>("a") == 42);
+ REQUIRE(tbl == table{ { "a"sv, 42 } });
+
+ static constexpr const char* a = "a";
+ res = tbl.insert_or_assign(a, 69);
+ CHECK(res.first == tbl.begin());
+ CHECK(res.second == false); // should assign
+ CHECK(tbl.size() == 1u);
+ REQUIRE(tbl.get_as<int64_t>("a"));
+ CHECK(*tbl.get_as<int64_t>("a") == 69);
+ REQUIRE(tbl == table{ { "a"sv, 69 } });
+
+ res = tbl.insert_or_assign("b", "kek");
+ CHECK(res.first == advance(tbl.begin(), 1));
+ CHECK(res.second == true); // should insert
+ CHECK(tbl.size() == 2u);
+ REQUIRE(tbl.get_as<std::string>("b"));
+ CHECK(*tbl.get_as<std::string>("b") == "kek"sv);
+ REQUIRE(tbl == table{ { "a"sv, 69 }, { "b"sv, "kek" } });
+
+ res = tbl.emplace<array>("c", 1, 2, 3);
+ CHECK(res.first == advance(tbl.begin(), 2));
+ CHECK(res.second == true);
+ CHECK(tbl.size() == 3u);
+ REQUIRE(tbl.get_as<array>("c"));
+ CHECK(*tbl.get_as<array>("c") == array{ 1, 2, 3 });
+ REQUIRE(tbl == table{ { "a"sv, 69 }, { "b"sv, "kek"sv }, { "c"sv, array{ 1, 2, 3 } } });
+
+ res = tbl.emplace<int64_t>("c", 1);
+ CHECK(res.first == advance(tbl.begin(), 2));
+ CHECK(res.second == false);
+ CHECK(tbl.size() == 3u);
+ REQUIRE(!tbl.get_as<int64_t>("c"));
+ REQUIRE(tbl.get_as<array>("c"));
+ REQUIRE(tbl == table{ { "a"sv, 69 }, { "b"sv, "kek"s }, { "c"sv, array{ 1, 2, 3 } } });
+
+ auto it = tbl.erase(tbl.cbegin());
+ REQUIRE(tbl == table{ { { "b"sv, "kek" }, { "c"sv, array{ 1, 2, 3 } } } });
+ CHECK(it == tbl.begin());
+ CHECK(tbl.size() == 2u);
+
+ res = tbl.insert_or_assign("a"sv, 69);
+ CHECK(res.first == tbl.begin());
+ CHECK(res.second == true); // should insert
+ CHECK(tbl.size() == 3u);
+ REQUIRE(tbl.get_as<int64_t>("a"));
+ CHECK(*tbl.get_as<int64_t>("a") == 69);
+ REQUIRE(tbl == table{ { "a"sv, 69 }, { "b"sv, "kek" }, { "c"sv, array{ 1, 2, 3 } } });
+
+ it = tbl.erase(advance(tbl.cbegin(), 1), advance(tbl.cbegin(), 3));
+ REQUIRE(tbl == table{ { "a"sv, 69 } });
+ CHECK(it == tbl.end());
+ CHECK(tbl.size() == 1u);
+
+ tbl.clear();
+ REQUIRE(tbl == table{});
+ CHECK(tbl.size() == 0u);
+ CHECK(tbl.empty());
+
+ // void insert(Iter first, Iter last)
+ {
+ std::vector<std::pair<std::string, std::string>> vals{ { "foo", "foo" }, { "bar", "bar" }, { "kek", "kek" } };
+ tbl.insert(vals.begin(), vals.end());
+ CHECK(tbl.size() == 3u);
+ REQUIRE(tbl.get_as<std::string>("foo"));
+ CHECK(*tbl.get_as<std::string>("foo") == "foo");
+ REQUIRE(tbl.get_as<std::string>("bar"));
+ CHECK(*tbl.get_as<std::string>("bar") == "bar");
+ REQUIRE(tbl.get_as<std::string>("kek"));
+ CHECK(*tbl.get_as<std::string>("kek") == "kek");
+
+ REQUIRE(vals.size() == 3u);
+ CHECK(vals[0].first == "foo");
+ CHECK(vals[0].second == "foo");
+ CHECK(vals[1].first == "bar");
+ CHECK(vals[1].second == "bar");
+ CHECK(vals[2].first == "kek");
+ CHECK(vals[2].second == "kek");
+
+ tbl.clear();
+ }
+
+ // void insert(Iter first, Iter last) (with move iterators)
+ {
+ std::vector<std::pair<std::string, std::string>> vals{ { "foo", "foo" }, { "bar", "bar" }, { "kek", "kek" } };
+ tbl.insert(std::make_move_iterator(vals.begin()), std::make_move_iterator(vals.end()));
+ CHECK(tbl.size() == 3u);
+ REQUIRE(tbl.get_as<std::string>("foo"));
+ CHECK(*tbl.get_as<std::string>("foo") == "foo");
+ REQUIRE(tbl.get_as<std::string>("bar"));
+ CHECK(*tbl.get_as<std::string>("bar") == "bar");
+ REQUIRE(tbl.get_as<std::string>("kek"));
+ CHECK(*tbl.get_as<std::string>("kek") == "kek");
+
+ REQUIRE(vals.size() == 3u);
+ CHECK(vals[0].first == "");
+ CHECK(vals[0].second == "");
+ CHECK(vals[1].first == "");
+ CHECK(vals[1].second == "");
+ CHECK(vals[2].first == "");
+ CHECK(vals[2].second == "");
+
+ tbl.clear();
+ }
+
+#if TOML_ENABLE_WINDOWS_COMPAT
+
+ tbl.insert(L"a", L"test1");
+ REQUIRE(*tbl.get_as<std::string>(L"a"sv) == "test1"sv);
+ tbl.insert_or_assign(L"a"sv, L"test2");
+ REQUIRE(*tbl.get_as<std::string>(L"a"sv) == "test2"sv);
+ tbl.emplace<std::string>(L"b", L"test3");
+ REQUIRE(*tbl.get_as<std::string>(L"b"sv) == "test3"sv);
+ CHECK(tbl.size() == 2u);
+ tbl.erase(L"b");
+ CHECK(tbl.size() == 1u);
+ tbl.erase(L"a"s);
+ CHECK(tbl.size() == 0u);
+
+#endif // TOML_ENABLE_WINDOWS_COMPAT
+
+ // insert with value_flags
+ {
+ tbl.clear();
+
+ auto hex = toml::value{ 1 };
+ hex.flags(value_flags::format_as_hexadecimal);
+ CHECK(hex.flags() == value_flags::format_as_hexadecimal);
+
+ tbl.insert("hex", hex);
+ CHECK(hex.flags() == value_flags::format_as_hexadecimal);
+ CHECK(tbl["hex"].as_integer()->flags() == value_flags::format_as_hexadecimal);
+
+ tbl.insert("hex2", std::move(hex));
+ CHECK(hex.flags() == value_flags{});
+ CHECK(tbl["hex2"].as_integer()->flags() == value_flags::format_as_hexadecimal);
+ }
+}
+
+TEST_CASE("tables - toml_formatter")
+{
+ static constexpr auto to_string = [](std::string_view some_toml,
+ format_flags flags = toml_formatter::default_flags,
+ format_flags exclude_flags = format_flags::none)
+ {
+ auto val = toml::parse(some_toml);
+ std::stringstream ss;
+ ss << toml_formatter{ val, flags & ~(exclude_flags) };
+ return ss.str();
+ };
+
+ {
+ static constexpr auto some_toml = R"(val1 = 1
+val2 = 2
+val3 = 3)"sv;
+
+ CHECK(to_string(some_toml) == some_toml);
+ }
+
+ {
+ static constexpr auto some_toml = R"([a_table]
+a = 1
+b = 2
+c = 3)"sv;
+
+ CHECK(to_string(some_toml) == some_toml);
+ }
+
+ {
+ static constexpr auto some_toml = R"(val1 = 1
+val2 = 2
+val3 = 3
+
+[a_table]
+a = 1
+b = 2
+c = 3)"sv;
+
+ CHECK(to_string(some_toml) == some_toml);
+ }
+
+ {
+ static constexpr auto some_toml = "[a]\n\n[b]\n\n[c]"sv;
+ CHECK(to_string(some_toml) == some_toml);
+ }
+
+ {
+ static constexpr auto some_toml = "[a]\nkey = 1\n\n[b]\n\n[c]"sv;
+ CHECK(to_string(some_toml) == some_toml);
+ }
+
+ {
+ static constexpr auto some_toml = "key = 1\n\n[a]\nkey = 1\n\n[b]\n\n[c]"sv;
+ CHECK(to_string(some_toml) == some_toml);
+ }
+
+ {
+ static constexpr auto some_toml = "key = 1\n\n[a]\nkey = 1\n\n[b]\n\n[[c]]\n\n[[c]]"sv;
+ CHECK(to_string(some_toml) == some_toml);
+ }
+
+ {
+ constexpr auto input = R"(key1 = 'val1'
+key2 = [ 1, 2, 3, 4, '5' ]
+key3 = [ 'this is a really long array', 'and should be split over multiple lines', 'by the formatter', 'unless i dun goofed', 'i guess thats what tests are for' ]
+
+[sub1]
+key4 = 'val'
+
+[sub2]
+key5 = 'val'
+
+ [sub2.sub3]
+ key6 = 'val'
+ key7 = [ 1, 2, 3, 4, '5' ]
+ key8 = [ 'this is a really long array', 'and should be split over multiple lines', 'by the formatter', 'unless i dun goofed', 'i guess thats what tests are for' ])"sv;
+
+ constexpr auto expected_default = R"(key1 = 'val1'
+key2 = [ 1, 2, 3, 4, '5' ]
+key3 = [
+ 'this is a really long array',
+ 'and should be split over multiple lines',
+ 'by the formatter',
+ 'unless i dun goofed',
+ 'i guess thats what tests are for'
+]
+
+[sub1]
+key4 = 'val'
+
+[sub2]
+key5 = 'val'
+
+ [sub2.sub3]
+ key6 = 'val'
+ key7 = [ 1, 2, 3, 4, '5' ]
+ key8 = [
+ 'this is a really long array',
+ 'and should be split over multiple lines',
+ 'by the formatter',
+ 'unless i dun goofed',
+ 'i guess thats what tests are for'
+ ])"sv;
+ CHECK(to_string(input) == expected_default);
+
+ constexpr auto expected_without_indented_subtables = R"(key1 = 'val1'
+key2 = [ 1, 2, 3, 4, '5' ]
+key3 = [
+ 'this is a really long array',
+ 'and should be split over multiple lines',
+ 'by the formatter',
+ 'unless i dun goofed',
+ 'i guess thats what tests are for'
+]
+
+[sub1]
+key4 = 'val'
+
+[sub2]
+key5 = 'val'
+
+[sub2.sub3]
+key6 = 'val'
+key7 = [ 1, 2, 3, 4, '5' ]
+key8 = [
+ 'this is a really long array',
+ 'and should be split over multiple lines',
+ 'by the formatter',
+ 'unless i dun goofed',
+ 'i guess thats what tests are for'
+])"sv;
+ CHECK(to_string(input, toml_formatter::default_flags, format_flags::indent_sub_tables)
+ == expected_without_indented_subtables);
+
+ constexpr auto expected_without_indented_arrays = R"(key1 = 'val1'
+key2 = [ 1, 2, 3, 4, '5' ]
+key3 = [
+'this is a really long array',
+'and should be split over multiple lines',
+'by the formatter',
+'unless i dun goofed',
+'i guess thats what tests are for'
+]
+
+[sub1]
+key4 = 'val'
+
+[sub2]
+key5 = 'val'
+
+ [sub2.sub3]
+ key6 = 'val'
+ key7 = [ 1, 2, 3, 4, '5' ]
+ key8 = [
+ 'this is a really long array',
+ 'and should be split over multiple lines',
+ 'by the formatter',
+ 'unless i dun goofed',
+ 'i guess thats what tests are for'
+ ])"sv;
+ CHECK(to_string(input, toml_formatter::default_flags, format_flags::indent_array_elements)
+ == expected_without_indented_arrays);
+
+ constexpr auto expected_without_indentation = R"(key1 = 'val1'
+key2 = [ 1, 2, 3, 4, '5' ]
+key3 = [
+'this is a really long array',
+'and should be split over multiple lines',
+'by the formatter',
+'unless i dun goofed',
+'i guess thats what tests are for'
+]
+
+[sub1]
+key4 = 'val'
+
+[sub2]
+key5 = 'val'
+
+[sub2.sub3]
+key6 = 'val'
+key7 = [ 1, 2, 3, 4, '5' ]
+key8 = [
+'this is a really long array',
+'and should be split over multiple lines',
+'by the formatter',
+'unless i dun goofed',
+'i guess thats what tests are for'
+])"sv;
+ CHECK(to_string(input, toml_formatter::default_flags, format_flags::indentation)
+ == expected_without_indentation);
+
+ // forcing multiline arrays: even short arrays become one-per-line (with array elements indented)
+ constexpr auto expected_forced_multiline = R"(key1 = 'val1'
+key2 = [
+ 1,
+ 2,
+ 3,
+ 4,
+ '5'
+]
+key3 = [
+ 'this is a really long array',
+ 'and should be split over multiple lines',
+ 'by the formatter',
+ 'unless i dun goofed',
+ 'i guess thats what tests are for'
+]
+
+[sub1]
+key4 = 'val'
+
+[sub2]
+key5 = 'val'
+
+ [sub2.sub3]
+ key6 = 'val'
+ key7 = [
+ 1,
+ 2,
+ 3,
+ 4,
+ '5'
+ ]
+ key8 = [
+ 'this is a really long array',
+ 'and should be split over multiple lines',
+ 'by the formatter',
+ 'unless i dun goofed',
+ 'i guess thats what tests are for'
+ ])"sv;
+
+ CHECK(to_string(input, toml_formatter::default_flags | format_flags::force_multiline_arrays)
+ == expected_forced_multiline);
+
+ // forcing multiline arrays without indenting array elements
+ constexpr auto expected_forced_without_indented_arrays = R"(key1 = 'val1'
+key2 = [
+1,
+2,
+3,
+4,
+'5'
+]
+key3 = [
+'this is a really long array',
+'and should be split over multiple lines',
+'by the formatter',
+'unless i dun goofed',
+'i guess thats what tests are for'
+]
+
+[sub1]
+key4 = 'val'
+
+[sub2]
+key5 = 'val'
+
+ [sub2.sub3]
+ key6 = 'val'
+ key7 = [
+ 1,
+ 2,
+ 3,
+ 4,
+ '5'
+ ]
+ key8 = [
+ 'this is a really long array',
+ 'and should be split over multiple lines',
+ 'by the formatter',
+ 'unless i dun goofed',
+ 'i guess thats what tests are for'
+ ])"sv;
+
+ CHECK(to_string(input,
+ toml_formatter::default_flags | format_flags::force_multiline_arrays,
+ format_flags::indent_array_elements)
+ == expected_forced_without_indented_arrays);
+ }
+}
+
+TEST_CASE("tables - for_each")
+{
+ const auto tbl = table{ { "a", 1 }, { "b", 2.0 }, { "c", 3 }, { "d", "four" }, { "e", false } };
+
+ SECTION("type checking")
+ {
+ int count = 0;
+ int ints = 0;
+ int floats = 0;
+ int numbers = 0;
+ int strings = 0;
+ int bools = 0;
+ tbl.for_each(
+ [&](const auto& v) noexcept
+ {
+ count++;
+ if constexpr (toml::is_integer<decltype(v)>)
+ ints++;
+ if constexpr (toml::is_floating_point<decltype(v)>)
+ floats++;
+ if constexpr (toml::is_number<decltype(v)>)
+ numbers++;
+ if constexpr (toml::is_string<decltype(v)>)
+ strings++;
+ if constexpr (toml::is_boolean<decltype(v)>)
+ bools++;
+ });
+ CHECK(count == 5);
+ CHECK(ints == 2);
+ CHECK(floats == 1);
+ CHECK(numbers == (ints + floats));
+ CHECK(strings == 1);
+ CHECK(bools == 1);
+ }
+
+#if !TOML_RETURN_BOOL_FROM_FOR_EACH_BROKEN
+
+ SECTION("early-exit (key, val)")
+ {
+ int count = 0;
+ tbl.for_each([&](const key& /*k*/, const auto& /*v*/) noexcept -> bool { return ++count < 3; });
+ CHECK(count == 3);
+ }
+
+ SECTION("early-exit (val)")
+ {
+ int count = 0;
+ tbl.for_each([&](const auto& /*v*/) noexcept -> bool { return ++count < 3; });
+ CHECK(count == 3);
+ }
+
+#endif
+}
diff --git a/tomlplusplus/tests/manipulating_values.cpp b/tomlplusplus/tests/manipulating_values.cpp
new file mode 100644
index 0000000000..416dfe158f
--- /dev/null
+++ b/tomlplusplus/tests/manipulating_values.cpp
@@ -0,0 +1,590 @@
+// This file is a part of toml++ and is subject to the the terms of the MIT license.
+// Copyright (c) Mark Gillard <mark.gillard@outlook.com.au>
+// See https://github.com/marzer/tomlplusplus/blob/master/LICENSE for the full license text.
+// SPDX-License-Identifier: MIT
+
+#include "tests.hpp"
+
+#ifdef _WIN32
+TOML_DISABLE_WARNINGS;
+#include <Windows.h>
+TOML_ENABLE_WARNINGS;
+#endif
+
+template <typename T>
+static constexpr T one = static_cast<T>(1);
+
+TEST_CASE("values - construction")
+{
+ static constexpr auto check_value = [](const auto& init_value, auto expected_native_type_tag)
+ {
+ using init_type = impl::remove_cvref<decltype(init_value)>;
+ using native_type = impl::native_type_of<init_type>;
+ using expected_native_type = typename decltype(expected_native_type_tag)::type;
+ static_assert(std::is_same_v<native_type, expected_native_type>);
+
+ auto v = value{ init_value };
+ using value_type = decltype(v);
+ static_assert(std::is_same_v<value_type, value<native_type>>);
+
+ if constexpr (std::is_same_v<std::string, native_type>)
+ {
+#if TOML_HAS_CHAR8
+ using char8_type = char8_t;
+#else
+ using char8_type = char;
+#endif
+
+ using init_char_type = impl::remove_cvref<decltype(init_value[0])>;
+ using init_view_type = std::basic_string_view<init_char_type>;
+ static_assert(impl::is_one_of<init_char_type, char, wchar_t, char8_type>);
+
+ const auto init_view = init_view_type{ init_value };
+ if constexpr (impl::is_one_of<init_char_type, char, char8_type>)
+ {
+ const auto coerced_view =
+ std::string_view{ reinterpret_cast<const char*>(init_view.data()), init_view.length() };
+
+ CHECK(v == coerced_view);
+ CHECK(coerced_view == v);
+ }
+#if TOML_ENABLE_WINDOWS_COMPAT
+ else if constexpr (impl::is_one_of<init_char_type, wchar_t>)
+ {
+ const auto narrowed_string = impl::narrow(init_view);
+
+ CHECK(v == narrowed_string);
+ CHECK(narrowed_string == v);
+ }
+#endif
+ else
+ {
+ static_assert(impl::always_false<init_char_type>, "evaluated unreachable branch");
+ }
+ }
+ else if constexpr (impl::is_one_of<native_type, int64_t, double, bool>)
+ {
+ CHECK(v == static_cast<native_type>(init_value));
+ CHECK(static_cast<native_type>(init_value) == v);
+ }
+ else // dates + times
+ {
+ CHECK(v == init_value);
+ CHECK(init_value == v);
+ }
+
+ static constexpr auto expected_node_type = impl::node_type_of<native_type>;
+
+ CHECK(v.is_homogeneous());
+ CHECK(v.template is_homogeneous<native_type>());
+ CHECK(v.is_homogeneous(expected_node_type));
+
+ // sanity check the virtual type checks
+ CHECK(v.type() == expected_node_type);
+ CHECK(!v.is_table());
+ CHECK(!v.is_array());
+ CHECK(!v.is_array_of_tables());
+ CHECK(v.is_value());
+ CHECK(v.is_string() == (expected_node_type == node_type::string));
+ CHECK(v.is_integer() == (expected_node_type == node_type::integer));
+ CHECK(v.is_floating_point() == (expected_node_type == node_type::floating_point));
+ CHECK(v.is_number()
+ == (expected_node_type == node_type::integer || expected_node_type == node_type::floating_point));
+ CHECK(v.is_boolean() == (expected_node_type == node_type::boolean));
+ CHECK(v.is_date() == (expected_node_type == node_type::date));
+ CHECK(v.is_time() == (expected_node_type == node_type::time));
+ CHECK(v.is_date_time() == (expected_node_type == node_type::date_time));
+
+ // sanity check the virtual type casts (non-const)
+ CHECK(!v.as_table());
+ CHECK(!v.as_array());
+ if constexpr (expected_node_type == node_type::string)
+ CHECK(v.as_string() == &v);
+ else
+ CHECK(!v.as_string());
+ if constexpr (expected_node_type == node_type::integer)
+ CHECK(v.as_integer() == &v);
+ else
+ CHECK(!v.as_integer());
+ if constexpr (expected_node_type == node_type::floating_point)
+ CHECK(v.as_floating_point() == &v);
+ else
+ CHECK(!v.as_floating_point());
+ if constexpr (expected_node_type == node_type::boolean)
+ CHECK(v.as_boolean() == &v);
+ else
+ CHECK(!v.as_boolean());
+ if constexpr (expected_node_type == node_type::date)
+ CHECK(v.as_date() == &v);
+ else
+ CHECK(!v.as_date());
+ if constexpr (expected_node_type == node_type::time)
+ CHECK(v.as_time() == &v);
+ else
+ CHECK(!v.as_time());
+ if constexpr (expected_node_type == node_type::date_time)
+ CHECK(v.as_date_time() == &v);
+ else
+ CHECK(!v.as_date_time());
+
+ // sanity check the virtual type casts (const)
+ const auto& cv = std::as_const(v);
+ CHECK(!cv.as_table());
+ CHECK(!cv.as_array());
+ if constexpr (expected_node_type == node_type::string)
+ CHECK(cv.as_string() == &v);
+ else
+ CHECK(!cv.as_string());
+ if constexpr (expected_node_type == node_type::integer)
+ CHECK(cv.as_integer() == &v);
+ else
+ CHECK(!cv.as_integer());
+ if constexpr (expected_node_type == node_type::floating_point)
+ CHECK(cv.as_floating_point() == &v);
+ else
+ CHECK(!cv.as_floating_point());
+ if constexpr (expected_node_type == node_type::boolean)
+ CHECK(cv.as_boolean() == &v);
+ else
+ CHECK(!cv.as_boolean());
+ if constexpr (expected_node_type == node_type::date)
+ CHECK(cv.as_date() == &v);
+ else
+ CHECK(!cv.as_date());
+ if constexpr (expected_node_type == node_type::time)
+ CHECK(cv.as_time() == &v);
+ else
+ CHECK(!cv.as_time());
+ if constexpr (expected_node_type == node_type::date_time)
+ CHECK(cv.as_date_time() == &v);
+ else
+ CHECK(!cv.as_date_time());
+ };
+
+ check_value(one<signed char>, type_tag<int64_t>{});
+ check_value(one<signed short>, type_tag<int64_t>{});
+ check_value(one<signed int>, type_tag<int64_t>{});
+ check_value(one<signed long>, type_tag<int64_t>{});
+ check_value(one<signed long long>, type_tag<int64_t>{});
+ check_value(one<unsigned char>, type_tag<int64_t>{});
+ check_value(one<unsigned short>, type_tag<int64_t>{});
+ check_value(one<unsigned int>, type_tag<int64_t>{});
+ check_value(one<unsigned long>, type_tag<int64_t>{});
+ check_value(one<unsigned long long>, type_tag<int64_t>{});
+ check_value(true, type_tag<bool>{});
+ check_value(false, type_tag<bool>{});
+ check_value("kek", type_tag<std::string>{});
+ check_value("kek"s, type_tag<std::string>{});
+ check_value("kek"sv, type_tag<std::string>{});
+ check_value("kek"sv.data(), type_tag<std::string>{});
+#if TOML_HAS_CHAR8
+ check_value(u8"kek", type_tag<std::string>{});
+ check_value(u8"kek"s, type_tag<std::string>{});
+ check_value(u8"kek"sv, type_tag<std::string>{});
+ check_value(u8"kek"sv.data(), type_tag<std::string>{});
+#endif
+
+#ifdef _WIN32
+ check_value(one<BOOL>, type_tag<int64_t>{});
+ check_value(one<SHORT>, type_tag<int64_t>{});
+ check_value(one<INT>, type_tag<int64_t>{});
+ check_value(one<LONG>, type_tag<int64_t>{});
+ check_value(one<INT_PTR>, type_tag<int64_t>{});
+ check_value(one<LONG_PTR>, type_tag<int64_t>{});
+ check_value(one<USHORT>, type_tag<int64_t>{});
+ check_value(one<UINT>, type_tag<int64_t>{});
+ check_value(one<ULONG>, type_tag<int64_t>{});
+ check_value(one<UINT_PTR>, type_tag<int64_t>{});
+ check_value(one<ULONG_PTR>, type_tag<int64_t>{});
+ check_value(one<WORD>, type_tag<int64_t>{});
+ check_value(one<DWORD>, type_tag<int64_t>{});
+ check_value(one<DWORD32>, type_tag<int64_t>{});
+ check_value(one<DWORD64>, type_tag<int64_t>{});
+ check_value(one<DWORDLONG>, type_tag<int64_t>{});
+
+#if TOML_ENABLE_WINDOWS_COMPAT
+
+ check_value(L"kek", type_tag<std::string>{});
+ check_value(L"kek"s, type_tag<std::string>{});
+ check_value(L"kek"sv, type_tag<std::string>{});
+ check_value(L"kek"sv.data(), type_tag<std::string>{});
+
+#endif // TOML_ENABLE_WINDOWS_COMPAT
+
+#endif
+}
+
+TEST_CASE("values - toml_formatter")
+{
+ static constexpr auto print_value = [](auto&& raw)
+ {
+ auto val = toml::value{ std::forward<decltype(raw)>(raw) };
+ std::stringstream ss;
+ ss << val;
+ return ss.str();
+ };
+
+ CHECK(print_value(1) == "1");
+ CHECK(print_value(1.0f) == "1.0");
+ CHECK(print_value(1.0) == "1.0");
+
+ CHECK(print_value(1.5f) == "1.5");
+ CHECK(print_value(1.5) == "1.5");
+
+ CHECK(print_value(10) == "10");
+ CHECK(print_value(10.0f) == "10.0");
+ CHECK(print_value(10.0) == "10.0");
+
+ CHECK(print_value(100) == "100");
+ CHECK(print_value(100.0f) == "100.0");
+ CHECK(print_value(100.0) == "100.0");
+
+ CHECK(print_value(1000) == "1000");
+ CHECK(print_value(1000.0f) == "1000.0");
+ CHECK(print_value(1000.0) == "1000.0");
+
+ CHECK(print_value(10000) == "10000");
+ CHECK(print_value(10000.0f) == "10000.0");
+ CHECK(print_value(10000.0) == "10000.0");
+
+ CHECK(print_value(std::numeric_limits<double>::infinity()) == "inf");
+ CHECK(print_value(-std::numeric_limits<double>::infinity()) == "-inf");
+ CHECK(print_value(std::numeric_limits<double>::quiet_NaN()) == "nan");
+
+ // only integers for large values;
+ // large floats might get output as scientific notation and that's fine
+ CHECK(print_value(10000000000) == "10000000000");
+ CHECK(print_value(100000000000000) == "100000000000000");
+}
+
+TEST_CASE("nodes - value() int/float/bool conversions")
+{
+#define CHECK_VALUE_PASS(type, v) CHECK(n.value<type>() == static_cast<type>(v))
+#define CHECK_VALUE_FAIL(type) CHECK(!n.value<type>())
+
+ // bools
+ {
+ value val{ false };
+ const node& n = val;
+ CHECK_VALUE_PASS(bool, false);
+ CHECK_VALUE_PASS(int8_t, 0);
+ CHECK_VALUE_PASS(uint8_t, 0);
+ CHECK_VALUE_PASS(int16_t, 0);
+ CHECK_VALUE_PASS(uint16_t, 0);
+ CHECK_VALUE_PASS(int32_t, 0);
+ CHECK_VALUE_PASS(uint32_t, 0);
+ CHECK_VALUE_PASS(int64_t, 0);
+ CHECK_VALUE_PASS(uint64_t, 0);
+ CHECK_VALUE_FAIL(float);
+ CHECK_VALUE_FAIL(double);
+ CHECK_VALUE_FAIL(std::string);
+ CHECK_VALUE_FAIL(std::string_view);
+ CHECK_VALUE_FAIL(toml::date);
+ CHECK_VALUE_FAIL(toml::time);
+ CHECK_VALUE_FAIL(toml::date_time);
+
+ *val = true;
+ CHECK_VALUE_PASS(bool, true);
+ CHECK_VALUE_PASS(int8_t, 1);
+ CHECK_VALUE_PASS(uint8_t, 1);
+ CHECK_VALUE_PASS(int16_t, 1);
+ CHECK_VALUE_PASS(uint16_t, 1);
+ CHECK_VALUE_PASS(int32_t, 1);
+ CHECK_VALUE_PASS(uint32_t, 1);
+ CHECK_VALUE_PASS(int64_t, 1);
+ CHECK_VALUE_PASS(uint64_t, 1);
+ CHECK_VALUE_FAIL(float);
+ CHECK_VALUE_FAIL(double);
+ CHECK_VALUE_FAIL(std::string);
+ CHECK_VALUE_FAIL(std::string_view);
+ CHECK_VALUE_FAIL(toml::date);
+ CHECK_VALUE_FAIL(toml::time);
+ CHECK_VALUE_FAIL(toml::date_time);
+ }
+
+ // ints
+ {
+ value val{ 0 };
+ const node& n = val;
+ CHECK_VALUE_PASS(bool, false); // int -> bool coercion
+ CHECK_VALUE_PASS(int8_t, 0);
+ CHECK_VALUE_PASS(uint8_t, 0);
+ CHECK_VALUE_PASS(int16_t, 0);
+ CHECK_VALUE_PASS(uint16_t, 0);
+ CHECK_VALUE_PASS(int32_t, 0);
+ CHECK_VALUE_PASS(uint32_t, 0);
+ CHECK_VALUE_PASS(int64_t, 0);
+ CHECK_VALUE_PASS(uint64_t, 0);
+ CHECK_VALUE_PASS(float, 0);
+ CHECK_VALUE_PASS(double, 0);
+ CHECK_VALUE_FAIL(std::string);
+ CHECK_VALUE_FAIL(std::string_view);
+ CHECK_VALUE_FAIL(toml::date);
+ CHECK_VALUE_FAIL(toml::time);
+ CHECK_VALUE_FAIL(toml::date_time);
+
+ *val = 100;
+ CHECK_VALUE_PASS(bool, true); // int -> bool coercion
+ CHECK_VALUE_PASS(int8_t, 100);
+ CHECK_VALUE_PASS(uint8_t, 100);
+ CHECK_VALUE_PASS(int16_t, 100);
+ CHECK_VALUE_PASS(uint16_t, 100);
+ CHECK_VALUE_PASS(int32_t, 100);
+ CHECK_VALUE_PASS(uint32_t, 100);
+ CHECK_VALUE_PASS(int64_t, 100);
+ CHECK_VALUE_PASS(uint64_t, 100);
+ CHECK_VALUE_PASS(float, 100);
+ CHECK_VALUE_PASS(double, 100);
+ CHECK_VALUE_FAIL(std::string);
+ CHECK_VALUE_FAIL(std::string_view);
+ CHECK_VALUE_FAIL(toml::date);
+ CHECK_VALUE_FAIL(toml::time);
+ CHECK_VALUE_FAIL(toml::date_time);
+
+ *val = -100;
+ CHECK_VALUE_PASS(bool, true); // int -> bool coercion
+ CHECK_VALUE_PASS(int8_t, -100);
+ CHECK_VALUE_FAIL(uint8_t);
+ CHECK_VALUE_PASS(int16_t, -100);
+ CHECK_VALUE_FAIL(uint16_t);
+ CHECK_VALUE_PASS(int32_t, -100);
+ CHECK_VALUE_FAIL(uint32_t);
+ CHECK_VALUE_PASS(int64_t, -100);
+ CHECK_VALUE_FAIL(uint64_t);
+ CHECK_VALUE_PASS(float, -100);
+ CHECK_VALUE_PASS(double, -100);
+ CHECK_VALUE_FAIL(std::string);
+ CHECK_VALUE_FAIL(std::string_view);
+ CHECK_VALUE_FAIL(toml::date);
+ CHECK_VALUE_FAIL(toml::time);
+ CHECK_VALUE_FAIL(toml::date_time);
+
+ *val = 1000;
+ CHECK_VALUE_PASS(bool, true); // int -> bool coercion
+ CHECK_VALUE_FAIL(int8_t);
+ CHECK_VALUE_FAIL(uint8_t);
+ CHECK_VALUE_PASS(int16_t, 1000);
+ CHECK_VALUE_PASS(uint16_t, 1000);
+ CHECK_VALUE_PASS(int32_t, 1000);
+ CHECK_VALUE_PASS(uint32_t, 1000);
+ CHECK_VALUE_PASS(int64_t, 1000);
+ CHECK_VALUE_PASS(uint64_t, 1000);
+ CHECK_VALUE_PASS(float, 1000);
+ CHECK_VALUE_PASS(double, 1000);
+ CHECK_VALUE_FAIL(std::string);
+ CHECK_VALUE_FAIL(std::string_view);
+ CHECK_VALUE_FAIL(toml::date);
+ CHECK_VALUE_FAIL(toml::time);
+ CHECK_VALUE_FAIL(toml::date_time);
+
+ *val = -1000;
+ CHECK_VALUE_PASS(bool, true); // int -> bool coercion
+ CHECK_VALUE_FAIL(int8_t);
+ CHECK_VALUE_FAIL(uint8_t);
+ CHECK_VALUE_PASS(int16_t, -1000);
+ CHECK_VALUE_FAIL(uint16_t);
+ CHECK_VALUE_PASS(int32_t, -1000);
+ CHECK_VALUE_FAIL(uint32_t);
+ CHECK_VALUE_PASS(int64_t, -1000);
+ CHECK_VALUE_FAIL(uint64_t);
+ CHECK_VALUE_PASS(float, -1000);
+ CHECK_VALUE_PASS(double, -1000);
+ CHECK_VALUE_FAIL(std::string);
+ CHECK_VALUE_FAIL(std::string_view);
+ CHECK_VALUE_FAIL(toml::date);
+ CHECK_VALUE_FAIL(toml::time);
+ CHECK_VALUE_FAIL(toml::date_time);
+
+ *val = (std::numeric_limits<int64_t>::max)();
+ CHECK_VALUE_PASS(bool, true); // int -> bool coercion
+ CHECK_VALUE_FAIL(int8_t);
+ CHECK_VALUE_FAIL(uint8_t);
+ CHECK_VALUE_FAIL(int16_t);
+ CHECK_VALUE_FAIL(uint16_t);
+ CHECK_VALUE_FAIL(int32_t);
+ CHECK_VALUE_FAIL(uint32_t);
+ CHECK_VALUE_PASS(int64_t, (std::numeric_limits<int64_t>::max)());
+ CHECK_VALUE_PASS(uint64_t, (std::numeric_limits<int64_t>::max)());
+ CHECK_VALUE_FAIL(float);
+ CHECK_VALUE_FAIL(double);
+ CHECK_VALUE_FAIL(std::string);
+ CHECK_VALUE_FAIL(std::string_view);
+ CHECK_VALUE_FAIL(toml::date);
+ CHECK_VALUE_FAIL(toml::time);
+ CHECK_VALUE_FAIL(toml::date_time);
+
+ *val = (std::numeric_limits<int64_t>::min)();
+ CHECK_VALUE_PASS(bool, true); // int -> bool coercion
+ CHECK_VALUE_FAIL(int8_t);
+ CHECK_VALUE_FAIL(uint8_t);
+ CHECK_VALUE_FAIL(int16_t);
+ CHECK_VALUE_FAIL(uint16_t);
+ CHECK_VALUE_FAIL(int32_t);
+ CHECK_VALUE_FAIL(uint32_t);
+ CHECK_VALUE_PASS(int64_t, (std::numeric_limits<int64_t>::min)());
+ CHECK_VALUE_FAIL(uint64_t);
+ CHECK_VALUE_FAIL(float);
+ CHECK_VALUE_FAIL(double);
+ CHECK_VALUE_FAIL(std::string);
+ CHECK_VALUE_FAIL(std::string_view);
+ CHECK_VALUE_FAIL(toml::date);
+ CHECK_VALUE_FAIL(toml::time);
+ CHECK_VALUE_FAIL(toml::date_time);
+ }
+
+ // floats
+ {
+ value val{ 0.0 };
+ const node& n = val;
+ CHECK_VALUE_FAIL(bool);
+ CHECK_VALUE_PASS(int8_t, 0);
+ CHECK_VALUE_PASS(uint8_t, 0);
+ CHECK_VALUE_PASS(int16_t, 0);
+ CHECK_VALUE_PASS(uint16_t, 0);
+ CHECK_VALUE_PASS(int32_t, 0);
+ CHECK_VALUE_PASS(uint32_t, 0);
+ CHECK_VALUE_PASS(int64_t, 0);
+ CHECK_VALUE_PASS(uint64_t, 0);
+ CHECK_VALUE_PASS(float, 0);
+ CHECK_VALUE_PASS(double, 0);
+ CHECK_VALUE_FAIL(std::string);
+ CHECK_VALUE_FAIL(std::string_view);
+ CHECK_VALUE_FAIL(toml::date);
+ CHECK_VALUE_FAIL(toml::time);
+ CHECK_VALUE_FAIL(toml::date_time);
+
+ *val = 1.0;
+ CHECK_VALUE_FAIL(bool);
+ CHECK_VALUE_PASS(int8_t, 1);
+ CHECK_VALUE_PASS(uint8_t, 1);
+ CHECK_VALUE_PASS(int16_t, 1);
+ CHECK_VALUE_PASS(uint16_t, 1);
+ CHECK_VALUE_PASS(int32_t, 1);
+ CHECK_VALUE_PASS(uint32_t, 1);
+ CHECK_VALUE_PASS(int64_t, 1);
+ CHECK_VALUE_PASS(uint64_t, 1);
+ CHECK_VALUE_PASS(float, 1);
+ CHECK_VALUE_PASS(double, 1);
+ CHECK_VALUE_FAIL(std::string);
+ CHECK_VALUE_FAIL(std::string_view);
+ CHECK_VALUE_FAIL(toml::date);
+ CHECK_VALUE_FAIL(toml::time);
+ CHECK_VALUE_FAIL(toml::date_time);
+
+ *val = -1.0;
+ CHECK_VALUE_FAIL(bool);
+ CHECK_VALUE_PASS(int8_t, -1);
+ CHECK_VALUE_FAIL(uint8_t);
+ CHECK_VALUE_PASS(int16_t, -1);
+ CHECK_VALUE_FAIL(uint16_t);
+ CHECK_VALUE_PASS(int32_t, -1);
+ CHECK_VALUE_FAIL(uint32_t);
+ CHECK_VALUE_PASS(int64_t, -1);
+ CHECK_VALUE_FAIL(uint64_t);
+ CHECK_VALUE_PASS(float, -1);
+ CHECK_VALUE_PASS(double, -1);
+ CHECK_VALUE_FAIL(std::string);
+ CHECK_VALUE_FAIL(std::string_view);
+ CHECK_VALUE_FAIL(toml::date);
+ CHECK_VALUE_FAIL(toml::time);
+ CHECK_VALUE_FAIL(toml::date_time);
+
+ *val = 1.5;
+ CHECK_VALUE_FAIL(bool);
+ CHECK_VALUE_FAIL(int8_t);
+ CHECK_VALUE_FAIL(uint8_t);
+ CHECK_VALUE_FAIL(int16_t);
+ CHECK_VALUE_FAIL(uint16_t);
+ CHECK_VALUE_FAIL(int32_t);
+ CHECK_VALUE_FAIL(uint32_t);
+ CHECK_VALUE_FAIL(int64_t);
+ CHECK_VALUE_FAIL(uint64_t);
+ CHECK_VALUE_PASS(float, 1.5);
+ CHECK_VALUE_PASS(double, 1.5);
+ CHECK_VALUE_FAIL(std::string);
+ CHECK_VALUE_FAIL(std::string_view);
+ CHECK_VALUE_FAIL(toml::date);
+ CHECK_VALUE_FAIL(toml::time);
+ CHECK_VALUE_FAIL(toml::date_time);
+
+ *val = -1.5;
+ CHECK_VALUE_FAIL(bool);
+ CHECK_VALUE_FAIL(int8_t);
+ CHECK_VALUE_FAIL(uint8_t);
+ CHECK_VALUE_FAIL(int16_t);
+ CHECK_VALUE_FAIL(uint16_t);
+ CHECK_VALUE_FAIL(int32_t);
+ CHECK_VALUE_FAIL(uint32_t);
+ CHECK_VALUE_FAIL(int64_t);
+ CHECK_VALUE_FAIL(uint64_t);
+ CHECK_VALUE_PASS(float, -1.5);
+ CHECK_VALUE_PASS(double, -1.5);
+ CHECK_VALUE_FAIL(std::string);
+ CHECK_VALUE_FAIL(std::string_view);
+ CHECK_VALUE_FAIL(toml::date);
+ CHECK_VALUE_FAIL(toml::time);
+ CHECK_VALUE_FAIL(toml::date_time);
+
+ *val = std::numeric_limits<double>::infinity();
+ CHECK_VALUE_FAIL(bool);
+ CHECK_VALUE_FAIL(int8_t);
+ CHECK_VALUE_FAIL(uint8_t);
+ CHECK_VALUE_FAIL(int16_t);
+ CHECK_VALUE_FAIL(uint16_t);
+ CHECK_VALUE_FAIL(int32_t);
+ CHECK_VALUE_FAIL(uint32_t);
+ CHECK_VALUE_FAIL(int64_t);
+ CHECK_VALUE_FAIL(uint64_t);
+ CHECK_VALUE_PASS(float, std::numeric_limits<float>::infinity());
+ CHECK_VALUE_PASS(double, std::numeric_limits<double>::infinity());
+ CHECK_VALUE_FAIL(std::string);
+ CHECK_VALUE_FAIL(std::string_view);
+ CHECK_VALUE_FAIL(toml::date);
+ CHECK_VALUE_FAIL(toml::time);
+ CHECK_VALUE_FAIL(toml::date_time);
+
+ *val = -std::numeric_limits<double>::infinity();
+ CHECK_VALUE_FAIL(bool);
+ CHECK_VALUE_FAIL(int8_t);
+ CHECK_VALUE_FAIL(uint8_t);
+ CHECK_VALUE_FAIL(int16_t);
+ CHECK_VALUE_FAIL(uint16_t);
+ CHECK_VALUE_FAIL(int32_t);
+ CHECK_VALUE_FAIL(uint32_t);
+ CHECK_VALUE_FAIL(int64_t);
+ CHECK_VALUE_FAIL(uint64_t);
+ CHECK_VALUE_PASS(float, -std::numeric_limits<float>::infinity());
+ CHECK_VALUE_PASS(double, -std::numeric_limits<double>::infinity());
+ CHECK_VALUE_FAIL(std::string);
+ CHECK_VALUE_FAIL(std::string_view);
+ CHECK_VALUE_FAIL(toml::date);
+ CHECK_VALUE_FAIL(toml::time);
+ CHECK_VALUE_FAIL(toml::date_time);
+
+ *val = std::numeric_limits<double>::quiet_NaN();
+ CHECK_VALUE_FAIL(bool);
+ CHECK_VALUE_FAIL(int8_t);
+ CHECK_VALUE_FAIL(uint8_t);
+ CHECK_VALUE_FAIL(int16_t);
+ CHECK_VALUE_FAIL(uint16_t);
+ CHECK_VALUE_FAIL(int32_t);
+ CHECK_VALUE_FAIL(uint32_t);
+ CHECK_VALUE_FAIL(int64_t);
+ CHECK_VALUE_FAIL(uint64_t);
+ {
+ auto fval = n.value<float>();
+ REQUIRE(fval.has_value());
+ CHECK(impl::fpclassify(*fval) == impl::fp_class::nan);
+ }
+ {
+ auto fval = n.value<double>();
+ REQUIRE(fval.has_value());
+ CHECK(impl::fpclassify(*fval) == impl::fp_class::nan);
+ }
+ CHECK_VALUE_FAIL(std::string);
+ CHECK_VALUE_FAIL(std::string_view);
+ CHECK_VALUE_FAIL(toml::date);
+ CHECK_VALUE_FAIL(toml::time);
+ CHECK_VALUE_FAIL(toml::date_time);
+ }
+}
diff --git a/tomlplusplus/tests/meson.build b/tomlplusplus/tests/meson.build
new file mode 100644
index 0000000000..41329788d7
--- /dev/null
+++ b/tomlplusplus/tests/meson.build
@@ -0,0 +1,106 @@
+# This file is a part of toml++ and is subject to the the terms of the MIT license.
+# Copyright (c) Mark Gillard <mark.gillard@outlook.com.au>
+# See https://github.com/marzer/tomlplusplus/blob/master/LICENSE for the full license text.
+# SPDX-License-Identifier: MIT
+
+assert(build_tests)
+
+test_sources = files(
+ 'at_path.cpp',
+ 'conformance_burntsushi_invalid.cpp',
+ 'conformance_burntsushi_valid.cpp',
+ 'conformance_iarna_invalid.cpp',
+ 'conformance_iarna_valid.cpp',
+ 'formatters.cpp',
+ 'for_each.cpp',
+ 'impl_toml.cpp',
+ 'main.cpp',
+ 'manipulating_arrays.cpp',
+ 'manipulating_parse_result.cpp',
+ 'manipulating_tables.cpp',
+ 'manipulating_values.cpp',
+ 'parsing_arrays.cpp',
+ 'parsing_booleans.cpp',
+ 'parsing_comments.cpp',
+ 'parsing_dates_and_times.cpp',
+ 'parsing_floats.cpp',
+ 'parsing_integers.cpp',
+ 'parsing_key_value_pairs.cpp',
+ 'parsing_spec_example.cpp',
+ 'parsing_strings.cpp',
+ 'parsing_tables.cpp',
+ 'path.cpp',
+ 'tests.cpp',
+ 'user_feedback.cpp',
+ 'using_iterators.cpp',
+ 'visit.cpp',
+ 'windows_compat.cpp'
+)
+
+test_deps = [ tomlplusplus_dep ]
+if not get_option('use_vendored_libs')
+ test_deps += dependency('catch2')
+endif
+
+#-----------------------------------------------------------------------------------------------------------------------
+# tests.exe
+#-----------------------------------------------------------------------------------------------------------------------
+
+test_args = []
+test_args += global_args
+if has_exceptions
+ test_args += cpp.get_supported_arguments('-DSHOULD_HAVE_EXCEPTIONS=1')
+else
+ test_args += cpp.get_supported_arguments('-DSHOULD_HAVE_EXCEPTIONS=0')
+endif
+if get_option('use_vendored_libs')
+ test_args += cpp.get_supported_arguments('-DUSE_VENDORED_LIBS=1')
+else
+ test_args += cpp.get_supported_arguments('-DUSE_VENDORED_LIBS=0')
+endif
+
+
+test_exe = executable(
+ 'tomlplusplus_tests',
+ test_sources,
+ cpp_args: test_args,
+ dependencies: test_deps,
+ override_options: global_overrides
+)
+
+#-----------------------------------------------------------------------------------------------------------------------
+# per-locale invocations
+#-----------------------------------------------------------------------------------------------------------------------
+
+test_locales = [
+ 'C',
+ 'en_US.utf8',
+ 'ja_JP.utf8',
+ 'it_IT.utf8',
+ 'tr_TR.utf8',
+ 'fi_FI.utf8',
+ 'fr_FR.utf8',
+ 'zh_CN.utf8',
+ 'de_DE.utf8'
+]
+
+foreach locale : test_locales
+ test(
+ 'tests - ' + locale,
+ test_exe,
+ env: ['LC_ALL=' + locale],
+ workdir: meson.project_source_root()/'tests'
+ )
+endforeach
+
+#-----------------------------------------------------------------------------------------------------------------------
+# ODR build test
+#-----------------------------------------------------------------------------------------------------------------------
+
+# add the ODR-test build project
+executable(
+ 'tomlplusplus_odr_test',
+ files( 'odr_test_1.cpp', 'odr_test_2.cpp' ),
+ cpp_args: test_args,
+ dependencies: test_deps
+)
diff --git a/tomlplusplus/tests/odr_test_1.cpp b/tomlplusplus/tests/odr_test_1.cpp
new file mode 100644
index 0000000000..27befe112e
--- /dev/null
+++ b/tomlplusplus/tests/odr_test_1.cpp
@@ -0,0 +1,9 @@
+#define TOML_UNDEF_MACROS 0
+#include "../toml.hpp"
+
+TOML_DISABLE_WARNINGS;
+
+int main()
+{
+ return 0;
+}
diff --git a/tomlplusplus/tests/odr_test_2.cpp b/tomlplusplus/tests/odr_test_2.cpp
new file mode 100644
index 0000000000..763c0c9446
--- /dev/null
+++ b/tomlplusplus/tests/odr_test_2.cpp
@@ -0,0 +1,2 @@
+#include "../toml.hpp"
+#include "../toml.hpp" // make sure it behaves if included more than once
diff --git a/tomlplusplus/tests/parsing_arrays.cpp b/tomlplusplus/tests/parsing_arrays.cpp
new file mode 100644
index 0000000000..eef9d22eee
--- /dev/null
+++ b/tomlplusplus/tests/parsing_arrays.cpp
@@ -0,0 +1,192 @@
+// This file is a part of toml++ and is subject to the the terms of the MIT license.
+// Copyright (c) Mark Gillard <mark.gillard@outlook.com.au>
+// See https://github.com/marzer/tomlplusplus/blob/master/LICENSE for the full license text.
+// SPDX-License-Identifier: MIT
+
+#include "tests.hpp"
+
+TEST_CASE("parsing - arrays")
+{
+ parsing_should_succeed(
+ FILE_LINE_ARGS,
+ R"(
+ integers = [ 1, 2, 3 ]
+ integers2 = [
+ 1, 2, 3
+ ]
+ integers3 = [
+ 1,
+ 2, # this is ok
+ ]
+ colors = [ "red", "yellow", "green" ]
+ nested_array_of_int = [ [ 1, 2 ], [3, 4, 5] ]
+ nested_mixed_array = [ [ 1, 2 ], ["a", "b", "c"] ]
+ string_array = [ "all", 'strings', """are the same""", '''type''' ]
+ )"sv,
+ [](table&& tbl)
+ {
+ node* first_nonmatch = {};
+ REQUIRE(tbl["integers"].as<array>());
+ CHECK(tbl["integers"].is_homogeneous());
+ CHECK(tbl["integers"].is_homogeneous(node_type::integer));
+ CHECK(!tbl["integers"].is_homogeneous(node_type::floating_point));
+ CHECK(!tbl["integers"].is_homogeneous(node_type::floating_point, first_nonmatch));
+ CHECK(first_nonmatch != nullptr);
+ first_nonmatch = {};
+
+ CHECK(tbl["integers"].is_homogeneous<int64_t>());
+ CHECK(!tbl["integers"].is_homogeneous<double>());
+ CHECK(tbl["integers"].as<array>()->is_homogeneous());
+ CHECK(tbl["integers"].as<array>()->is_homogeneous(node_type::integer));
+ CHECK(!tbl["integers"].as<array>()->is_homogeneous(node_type::floating_point));
+ CHECK(!tbl["integers"].as<array>()->is_homogeneous(node_type::floating_point, first_nonmatch));
+ CHECK(first_nonmatch != nullptr);
+ first_nonmatch = {};
+
+ CHECK(tbl["integers"].as<array>()->is_homogeneous<int64_t>());
+ CHECK(!tbl["integers"].as<array>()->is_homogeneous<double>());
+
+ CHECK(tbl["integers"].as<array>()->size() == 3);
+ CHECK(tbl["integers"][0] == 1);
+ CHECK(tbl["integers"][1] == 2);
+ CHECK(tbl["integers"][2] == 3);
+
+ REQUIRE(tbl["integers2"].as<array>());
+ CHECK(tbl["integers2"].is_homogeneous());
+ CHECK(tbl["integers2"].is_homogeneous(node_type::integer));
+ CHECK(!tbl["integers2"].is_homogeneous(node_type::floating_point));
+ CHECK(tbl["integers2"].is_homogeneous<int64_t>());
+ CHECK(!tbl["integers2"].is_homogeneous<double>());
+ CHECK(tbl["integers2"].as<array>()->is_homogeneous());
+ CHECK(tbl["integers2"].as<array>()->is_homogeneous(node_type::integer));
+ CHECK(!tbl["integers2"].as<array>()->is_homogeneous(node_type::floating_point));
+ CHECK(tbl["integers2"].as<array>()->is_homogeneous<int64_t>());
+ CHECK(!tbl["integers2"].as<array>()->is_homogeneous<double>());
+ CHECK(tbl["integers2"].as<array>()->size() == 3);
+ CHECK(tbl["integers2"][0] == 1);
+ CHECK(tbl["integers2"][1] == 2);
+ CHECK(tbl["integers2"][2] == 3);
+
+ REQUIRE(tbl["integers3"].as<array>());
+ CHECK(tbl["integers3"].is_homogeneous());
+ CHECK(tbl["integers3"].is_homogeneous(node_type::integer));
+ CHECK(!tbl["integers3"].is_homogeneous(node_type::floating_point));
+ CHECK(tbl["integers3"].is_homogeneous<int64_t>());
+ CHECK(!tbl["integers3"].is_homogeneous<double>());
+ CHECK(tbl["integers3"].as<array>()->is_homogeneous());
+ CHECK(tbl["integers3"].as<array>()->is_homogeneous(node_type::integer));
+ CHECK(!tbl["integers3"].as<array>()->is_homogeneous(node_type::floating_point));
+ CHECK(tbl["integers3"].as<array>()->is_homogeneous<int64_t>());
+ CHECK(!tbl["integers3"].as<array>()->is_homogeneous<double>());
+ CHECK(tbl["integers3"].as<array>()->size() == 2);
+ CHECK(tbl["integers3"][0] == 1);
+ CHECK(tbl["integers3"][1] == 2);
+
+ REQUIRE(tbl["colors"].as<array>());
+ CHECK(tbl["colors"].is_homogeneous());
+ CHECK(tbl["colors"].is_homogeneous(node_type::string));
+ CHECK(!tbl["colors"].is_homogeneous(node_type::floating_point));
+ CHECK(tbl["colors"].is_homogeneous<std::string>());
+ CHECK(!tbl["colors"].is_homogeneous<double>());
+ CHECK(tbl["colors"].as<array>()->is_homogeneous());
+ CHECK(tbl["colors"].as<array>()->is_homogeneous(node_type::string));
+ CHECK(!tbl["colors"].as<array>()->is_homogeneous(node_type::floating_point));
+ CHECK(tbl["colors"].as<array>()->is_homogeneous<std::string>());
+ CHECK(!tbl["colors"].as<array>()->is_homogeneous<double>());
+ CHECK(tbl["colors"].as<array>()->size() == 3);
+ CHECK(tbl["colors"][0] == "red"sv);
+ CHECK(tbl["colors"][1] == "yellow"sv);
+ CHECK(tbl["colors"][2] == "green"sv);
+
+ REQUIRE(tbl["nested_array_of_int"].as<array>());
+ CHECK(tbl["nested_array_of_int"].as<array>()->is_homogeneous());
+ CHECK(tbl["nested_array_of_int"].as<array>()->size() == 2);
+ REQUIRE(tbl["nested_array_of_int"][0].as<array>());
+ CHECK(tbl["nested_array_of_int"][0].as<array>()->is_homogeneous());
+ CHECK(tbl["nested_array_of_int"][0].as<array>()->size() == 2);
+ CHECK(tbl["nested_array_of_int"][0][0] == 1);
+ CHECK(tbl["nested_array_of_int"][0][1] == 2);
+ REQUIRE(tbl["nested_array_of_int"][1].as<array>());
+ CHECK(tbl["nested_array_of_int"][1].as<array>()->is_homogeneous());
+ CHECK(tbl["nested_array_of_int"][1].as<array>()->size() == 3);
+ CHECK(tbl["nested_array_of_int"][1][0] == 3);
+ CHECK(tbl["nested_array_of_int"][1][1] == 4);
+ CHECK(tbl["nested_array_of_int"][1][2] == 5);
+
+ REQUIRE(tbl["nested_mixed_array"].as<array>());
+ CHECK(tbl["nested_mixed_array"].as<array>()->is_homogeneous());
+ CHECK(tbl["nested_mixed_array"].as<array>()->size() == 2);
+ REQUIRE(tbl["nested_mixed_array"][0].as<array>());
+ CHECK(tbl["nested_mixed_array"][0].as<array>()->is_homogeneous());
+ CHECK(tbl["nested_mixed_array"][0].as<array>()->size() == 2);
+ CHECK(tbl["nested_mixed_array"][0][0] == 1);
+ CHECK(tbl["nested_mixed_array"][0][1] == 2);
+ REQUIRE(tbl["nested_mixed_array"][1].as<array>());
+ CHECK(tbl["nested_mixed_array"][1].as<array>()->is_homogeneous());
+ CHECK(tbl["nested_mixed_array"][1].as<array>()->size() == 3);
+ CHECK(tbl["nested_mixed_array"][1][0] == "a"sv);
+ CHECK(tbl["nested_mixed_array"][1][1] == "b"sv);
+ CHECK(tbl["nested_mixed_array"][1][2] == "c"sv);
+
+ REQUIRE(tbl["string_array"].as<array>());
+ CHECK(tbl["string_array"].as<array>()->is_homogeneous());
+ CHECK(tbl["string_array"].as<array>()->size() == 4);
+ CHECK(tbl["string_array"][0] == "all"sv);
+ CHECK(tbl["string_array"][1] == "strings"sv);
+ CHECK(tbl["string_array"][2] == "are the same"sv);
+ CHECK(tbl["string_array"][3] == "type"sv);
+ REQUIRE(tbl["integers"].as<array>());
+ CHECK(tbl["integers"].as<array>()->is_homogeneous());
+ CHECK(tbl["integers"].as<array>()->size() == 3);
+ CHECK(tbl["integers"][0] == 1);
+ CHECK(tbl["integers"][1] == 2);
+ CHECK(tbl["integers"][2] == 3);
+ });
+
+// toml/issues/665 (heterogeneous arrays)
+#if TOML_LANG_AT_LEAST(1, 0, 0)
+
+ parsing_should_succeed(FILE_LINE_ARGS,
+ R"(
+ # Mixed-type arrays are allowed
+ numbers = [ 0.1, 0.2, 0.5, 1, 2, 5 ]
+ contributors = [
+ "Foo Bar <foo@example.com>",
+ { name = "Baz Qux", email = "bazqux@example.com", url = "https://example.com/bazqux" }
+ ]
+ )"sv,
+ [](table&& tbl)
+ {
+ REQUIRE(tbl["numbers"].as<array>());
+ CHECK(!tbl["numbers"].as<array>()->is_homogeneous());
+ CHECK(tbl["numbers"].as<array>()->size() == 6);
+ CHECK(tbl["numbers"][0].as<double>());
+ CHECK(tbl["numbers"][1].as<double>());
+ CHECK(tbl["numbers"][2].as<double>());
+ CHECK(tbl["numbers"][3].as<int64_t>());
+ CHECK(tbl["numbers"][4].as<int64_t>());
+ CHECK(tbl["numbers"][5].as<int64_t>());
+ CHECK(tbl["numbers"][0] == 0.1);
+ CHECK(tbl["numbers"][1] == 0.2);
+ CHECK(tbl["numbers"][2] == 0.5);
+ CHECK(tbl["numbers"][3] == 1);
+ CHECK(tbl["numbers"][4] == 2);
+ CHECK(tbl["numbers"][5] == 5);
+
+ REQUIRE(tbl["contributors"].as<array>());
+ CHECK(!tbl["contributors"].as<array>()->is_homogeneous());
+ CHECK(tbl["contributors"].as<array>()->size() == 2);
+ CHECK(tbl["contributors"][0].as<std::string>());
+ CHECK(tbl["contributors"][1].as<table>());
+ CHECK(tbl["contributors"][0] == "Foo Bar <foo@example.com>"sv);
+ CHECK(tbl["contributors"][1]["name"] == "Baz Qux"sv);
+ CHECK(tbl["contributors"][1]["email"] == "bazqux@example.com"sv);
+ CHECK(tbl["contributors"][1]["url"] == "https://example.com/bazqux"sv);
+ });
+
+#else
+
+ parsing_should_fail(FILE_LINE_ARGS, "numbers = [ 0.1, 0.2, 0.5, 1, 2, 5 ]"sv);
+
+#endif
+}
diff --git a/tomlplusplus/tests/parsing_booleans.cpp b/tomlplusplus/tests/parsing_booleans.cpp
new file mode 100644
index 0000000000..c81cdf1a82
--- /dev/null
+++ b/tomlplusplus/tests/parsing_booleans.cpp
@@ -0,0 +1,32 @@
+// This file is a part of toml++ and is subject to the the terms of the MIT license.
+// Copyright (c) Mark Gillard <mark.gillard@outlook.com.au>
+// See https://github.com/marzer/tomlplusplus/blob/master/LICENSE for the full license text.
+// SPDX-License-Identifier: MIT
+
+#include "tests.hpp"
+
+TEST_CASE("parsing - booleans")
+{
+ parsing_should_succeed(FILE_LINE_ARGS,
+ R"(
+ bool1 = true
+ bool2 = false
+ )"sv,
+ [](table&& tbl)
+ {
+ CHECK(tbl["bool1"] == true);
+ CHECK(tbl["bool2"] == false);
+ });
+
+ // "Always lowercase."
+ parsing_should_fail(FILE_LINE_ARGS, "bool = True"sv);
+ parsing_should_fail(FILE_LINE_ARGS, "bool = TRUE"sv);
+ parsing_should_fail(FILE_LINE_ARGS, "bool = tRUE"sv);
+ parsing_should_fail(FILE_LINE_ARGS, "bool = False"sv);
+ parsing_should_fail(FILE_LINE_ARGS, "bool = FALSE"sv);
+ parsing_should_fail(FILE_LINE_ARGS, "bool = fALSE"sv);
+
+ // value tests
+ parse_expected_value(FILE_LINE_ARGS, " true", true);
+ parse_expected_value(FILE_LINE_ARGS, "false", false);
+}
diff --git a/tomlplusplus/tests/parsing_comments.cpp b/tomlplusplus/tests/parsing_comments.cpp
new file mode 100644
index 0000000000..c6ed34ac31
--- /dev/null
+++ b/tomlplusplus/tests/parsing_comments.cpp
@@ -0,0 +1,110 @@
+// This file is a part of toml++ and is subject to the the terms of the MIT license.
+// Copyright (c) Mark Gillard <mark.gillard@outlook.com.au>
+// See https://github.com/marzer/tomlplusplus/blob/master/LICENSE for the full license text.
+// SPDX-License-Identifier: MIT
+
+#include "tests.hpp"
+
+TEST_CASE("parsing - comments")
+{
+ parsing_should_succeed(FILE_LINE_ARGS,
+ R"(
+ # This is a full-line comment
+ key = "value" # This is a comment at the end of a line
+ another = "# This is not a comment"
+ )"sv,
+ [](table&& tbl)
+ {
+ CHECK(tbl.size() == 2);
+ CHECK(tbl["key"] == "value"sv);
+ CHECK(tbl["another"] == "# This is not a comment"sv);
+ });
+
+ parsing_should_succeed(FILE_LINE_ARGS,
+ R"(# this = "looks like a KVP but is commented out)"sv,
+ [](table&& tbl) { CHECK(tbl.size() == 0); });
+
+#if TOML_LANG_AT_LEAST(1, 0, 0)
+ {
+ // toml/issues/567 (disallow non-TAB control characters in comments)
+ // 00 - 08
+ parsing_should_fail(FILE_LINE_ARGS, "# \u0000 some trailing garbage"sv);
+ parsing_should_fail(FILE_LINE_ARGS, "# \u0001"sv);
+ parsing_should_fail(FILE_LINE_ARGS, "# \u0002"sv);
+ parsing_should_fail(FILE_LINE_ARGS, "# \u0003"sv);
+ parsing_should_fail(FILE_LINE_ARGS, "# \u0004"sv);
+ parsing_should_fail(FILE_LINE_ARGS, "# \u0005"sv);
+ parsing_should_fail(FILE_LINE_ARGS, "# \u0006"sv);
+ parsing_should_fail(FILE_LINE_ARGS, "# \u0007"sv);
+ parsing_should_fail(FILE_LINE_ARGS, "# \u0008"sv);
+
+ // skip tab and line breaks (real and otherwise)
+ // \u0009 is \t
+ // \u000A is \n
+ // \u000B is \v (vertical tab)
+ // \u000C is \f (form feed)
+ // \u000D is \r
+
+ // 0E - 1F
+ parsing_should_fail(FILE_LINE_ARGS, "# \u000E"sv);
+ parsing_should_fail(FILE_LINE_ARGS, "# \u000F"sv);
+ parsing_should_fail(FILE_LINE_ARGS, "# \u0010"sv);
+ parsing_should_fail(FILE_LINE_ARGS, "# \u0011"sv);
+ parsing_should_fail(FILE_LINE_ARGS, "# \u0012"sv);
+ parsing_should_fail(FILE_LINE_ARGS, "# \u0013"sv);
+ parsing_should_fail(FILE_LINE_ARGS, "# \u0014"sv);
+ parsing_should_fail(FILE_LINE_ARGS, "# \u0015"sv);
+ parsing_should_fail(FILE_LINE_ARGS, "# \u0016"sv);
+ parsing_should_fail(FILE_LINE_ARGS, "# \u0017"sv);
+ parsing_should_fail(FILE_LINE_ARGS, "# \u0018"sv);
+ parsing_should_fail(FILE_LINE_ARGS, "# \u0019"sv);
+ parsing_should_fail(FILE_LINE_ARGS, "# \u001A"sv);
+ parsing_should_fail(FILE_LINE_ARGS, "# \u001B"sv);
+ parsing_should_fail(FILE_LINE_ARGS, "# \u001C"sv);
+ parsing_should_fail(FILE_LINE_ARGS, "# \u001D"sv);
+ parsing_should_fail(FILE_LINE_ARGS, "# \u001E"sv);
+ parsing_should_fail(FILE_LINE_ARGS, "# \u001F"sv);
+ // 7F
+ parsing_should_fail(FILE_LINE_ARGS, "# \u007F"sv);
+ }
+#else
+ {
+ parsing_should_succeed(FILE_LINE_ARGS,
+ S("## 00 - 08"
+ "# \u0000 "
+ "# \u0001 "
+ "# \u0002 "
+ "# \u0003 "
+ "# \u0004 "
+ "# \u0005 "
+ "# \u0006 "
+ "# \u0007 "
+ "# \u0008 "
+ "## 0A - 1F"
+ "# \u000A "
+ "# \u000B "
+ "# \u000C "
+ "# \u000D "
+ "# \u000E "
+ "# \u000F "
+ "# \u0010 "
+ "# \u0011 "
+ "# \u0012 "
+ "# \u0013 "
+ "# \u0014 "
+ "# \u0015 "
+ "# \u0016 "
+ "# \u0017 "
+ "# \u0018 "
+ "# \u0019 "
+ "# \u001A "
+ "# \u001B "
+ "# \u001C "
+ "# \u001D "
+ "# \u001E "
+ "# \u001F "
+ "## 7F "
+ "# \u007F "sv));
+ }
+#endif
+}
diff --git a/tomlplusplus/tests/parsing_dates_and_times.cpp b/tomlplusplus/tests/parsing_dates_and_times.cpp
new file mode 100644
index 0000000000..eb336b85ae
--- /dev/null
+++ b/tomlplusplus/tests/parsing_dates_and_times.cpp
@@ -0,0 +1,174 @@
+// This file is a part of toml++ and is subject to the the terms of the MIT license.
+// Copyright (c) Mark Gillard <mark.gillard@outlook.com.au>
+// See https://github.com/marzer/tomlplusplus/blob/master/LICENSE for the full license text.
+// SPDX-License-Identifier: MIT
+
+#include "tests.hpp"
+TOML_DISABLE_SPAM_WARNINGS;
+
+TEST_CASE("parsing - dates and times")
+{
+ parsing_should_succeed(
+ FILE_LINE_ARGS,
+ R"(
+ odt1 = 1979-05-27T07:32:00Z
+ odt2 = 1979-05-27T00:32:00-07:00
+ odt3 = 1979-05-27T00:32:00.999999-07:00
+ odt4 = 1979-05-27 07:32:00Z
+ ldt1 = 1979-05-27T07:32:00
+ ldt2 = 1979-05-27T00:32:00.999999
+ ld1 = 1979-05-27
+ lt1 = 07:32:00
+ lt2 = 00:32:00.999999
+ )"sv,
+ [](table&& tbl)
+ {
+ static constexpr auto odt1 = date_time{ { 1979, 5, 27 }, { 7, 32 }, {} };
+ CHECK(tbl["odt1"] == odt1);
+ static constexpr auto odt2 = date_time{ { 1979, 5, 27 }, { 0, 32 }, { -7, 0 } };
+ CHECK(tbl["odt2"] == odt2);
+ static constexpr auto odt3 = date_time{ { 1979, 5, 27 }, { 0, 32, 0, 999999000u }, { -7, 0 } };
+ CHECK(tbl["odt3"] == odt3);
+ static constexpr auto odt4 = date_time{ { 1979, 5, 27 }, { 7, 32 }, {} };
+ CHECK(tbl["odt4"] == odt4);
+ static constexpr auto ldt1 = date_time{ { 1979, 5, 27 }, { 7, 32 } };
+ CHECK(tbl["ldt1"] == ldt1);
+ static constexpr auto ldt2 = date_time{ { 1979, 5, 27 }, { 0, 32, 0, 999999000u } };
+ CHECK(tbl["ldt2"] == ldt2);
+ static constexpr auto ld1 = date{ 1979, 5, 27 };
+ CHECK(tbl["ld1"] == ld1);
+ static constexpr auto lt1 = toml::time{ 7, 32 };
+ CHECK(tbl["lt1"] == lt1);
+ static constexpr auto lt2 = toml::time{ 0, 32, 0, 999999000u };
+ CHECK(tbl["lt2"] == lt2);
+ });
+
+ // value tests
+ parse_expected_value(FILE_LINE_ARGS, "1987-03-16"sv, date{ 1987, 3, 16 });
+ parse_expected_value(FILE_LINE_ARGS, "10:20:30"sv, toml::time{ 10, 20, 30 });
+ parse_expected_value(FILE_LINE_ARGS, "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(FILE_LINE_ARGS, "1987-03-16T10:20:30"sv, val);
+ parse_expected_value(FILE_LINE_ARGS, "1987-03-16t10:20:30"sv, val);
+ parse_expected_value(FILE_LINE_ARGS, "1987-03-16 10:20:30"sv, val);
+ }
+ {
+ const auto val = date_time{ { 1987, 3, 16 }, { 10, 20, 30 }, { -9, -30 } };
+ parse_expected_value(FILE_LINE_ARGS, "1987-03-16T10:20:30-09:30"sv, val);
+ parse_expected_value(FILE_LINE_ARGS, "1987-03-16t10:20:30-09:30"sv, val);
+ parse_expected_value(FILE_LINE_ARGS, "1987-03-16 10:20:30-09:30"sv, val);
+ }
+ {
+ const auto val = date_time{ { 1987, 3, 16 }, { 10, 20, 30 }, { 9, 30 } };
+ parse_expected_value(FILE_LINE_ARGS, "1987-03-16T10:20:30+09:30"sv, val);
+ parse_expected_value(FILE_LINE_ARGS, "1987-03-16t10:20:30+09:30"sv, val);
+ parse_expected_value(FILE_LINE_ARGS, "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(FILE_LINE_ARGS, "1987-03-16T10:20:30.04"sv, val);
+ parse_expected_value(FILE_LINE_ARGS, "1987-03-16t10:20:30.04"sv, val);
+ parse_expected_value(FILE_LINE_ARGS, "1987-03-16 10:20:30.04"sv, val);
+ }
+ {
+ const auto val = date_time{ { 1987, 3, 16 }, { 10, 20, 30, 40000000 }, { -9, -30 } };
+ parse_expected_value(FILE_LINE_ARGS, "1987-03-16T10:20:30.04-09:30"sv, val);
+ parse_expected_value(FILE_LINE_ARGS, "1987-03-16t10:20:30.04-09:30"sv, val);
+ parse_expected_value(FILE_LINE_ARGS, "1987-03-16 10:20:30.04-09:30"sv, val);
+ }
+ {
+ const auto val = date_time{ { 1987, 3, 16 }, { 10, 20, 30, 40000000 }, { 9, 30 } };
+ parse_expected_value(FILE_LINE_ARGS, "1987-03-16T10:20:30.04+09:30"sv, val);
+ parse_expected_value(FILE_LINE_ARGS, "1987-03-16t10:20:30.04+09:30"sv, val);
+ parse_expected_value(FILE_LINE_ARGS, "1987-03-16 10:20:30.04+09:30"sv, val);
+ }
+ {
+ const auto val = date_time{ { 1987, 3, 16 }, { 10, 20, 30 }, {} };
+ parse_expected_value(FILE_LINE_ARGS, "1987-03-16T10:20:30Z"sv, val);
+ parse_expected_value(FILE_LINE_ARGS, "1987-03-16t10:20:30Z"sv, val);
+ parse_expected_value(FILE_LINE_ARGS, "1987-03-16 10:20:30Z"sv, val);
+ parse_expected_value(FILE_LINE_ARGS, "1987-03-16T10:20:30z"sv, val);
+ parse_expected_value(FILE_LINE_ARGS, "1987-03-16t10:20:30z"sv, val);
+ parse_expected_value(FILE_LINE_ARGS, "1987-03-16 10:20:30z"sv, val);
+ }
+ {
+ const auto val = date_time{ { 1987, 3, 16 }, { 10, 20, 30, 40000000 }, {} };
+ parse_expected_value(FILE_LINE_ARGS, "1987-03-16T10:20:30.04Z"sv, val);
+ parse_expected_value(FILE_LINE_ARGS, "1987-03-16t10:20:30.04Z"sv, val);
+ parse_expected_value(FILE_LINE_ARGS, "1987-03-16 10:20:30.04Z"sv, val);
+ parse_expected_value(FILE_LINE_ARGS, "1987-03-16T10:20:30.04z"sv, val);
+ parse_expected_value(FILE_LINE_ARGS, "1987-03-16t10:20:30.04z"sv, val);
+ parse_expected_value(FILE_LINE_ARGS, "1987-03-16 10:20:30.04z"sv, val);
+ }
+
+// toml/issues/671 (allow omission of seconds)
+#if TOML_LANG_UNRELEASED
+
+ parse_expected_value(FILE_LINE_ARGS, "10:20"sv, toml::time{ 10, 20 });
+ {
+ const auto val = date_time{ { 1987, 3, 16 }, { 10, 20 } };
+ parse_expected_value(FILE_LINE_ARGS, "1987-03-16T10:20"sv, val);
+ parse_expected_value(FILE_LINE_ARGS, "1987-03-16 10:20"sv, val);
+ }
+ {
+ const auto val = date_time{ { 1987, 3, 16 }, { 10, 20 }, { -9, -30 } };
+ parse_expected_value(FILE_LINE_ARGS, "1987-03-16T10:20-09:30"sv, val);
+ parse_expected_value(FILE_LINE_ARGS, "1987-03-16 10:20-09:30"sv, val);
+ }
+ {
+ const auto val = date_time{ { 1987, 3, 16 }, { 10, 20 }, { 9, 30 } };
+ parse_expected_value(FILE_LINE_ARGS, "1987-03-16T10:20+09:30"sv, val);
+ parse_expected_value(FILE_LINE_ARGS, "1987-03-16 10:20+09:30"sv, val);
+ }
+ {
+ const auto val = date_time{ { 1987, 3, 16 }, { 10, 20 }, {} };
+ parse_expected_value(FILE_LINE_ARGS, "1987-03-16T10:20Z"sv, val);
+ parse_expected_value(FILE_LINE_ARGS, "1987-03-16 10:20Z"sv, val);
+ }
+
+#else
+
+ parsing_should_fail(FILE_LINE_ARGS, "10:20"sv);
+ parsing_should_fail(FILE_LINE_ARGS, "1987-03-16T10:20"sv);
+ parsing_should_fail(FILE_LINE_ARGS, "1987-03-16 10:20"sv);
+ parsing_should_fail(FILE_LINE_ARGS, "1987-03-16T10:20-09:30"sv);
+ parsing_should_fail(FILE_LINE_ARGS, "1987-03-16 10:20-09:30"sv);
+ parsing_should_fail(FILE_LINE_ARGS, "1987-03-16T10:20+09:30"sv);
+ parsing_should_fail(FILE_LINE_ARGS, "1987-03-16 10:20+09:30"sv);
+ parsing_should_fail(FILE_LINE_ARGS, "1987-03-16T10:20Z"sv);
+ parsing_should_fail(FILE_LINE_ARGS, "1987-03-16 10:20Z"sv);
+
+#endif
+
+ // eof tests
+ parsing_should_fail(FILE_LINE_ARGS, "val = 1987-03-1"sv);
+ parsing_should_fail(FILE_LINE_ARGS, "val = 1987-03-"sv);
+ parsing_should_fail(FILE_LINE_ARGS, "val = 1987-03"sv);
+ parsing_should_fail(FILE_LINE_ARGS, "val = 1987-0"sv);
+ parsing_should_fail(FILE_LINE_ARGS, "val = 1987-"sv);
+ parsing_should_fail(FILE_LINE_ARGS, "val = 10:20:30."sv);
+ parsing_should_fail(FILE_LINE_ARGS, "val = 10:20:3"sv);
+ parsing_should_fail(FILE_LINE_ARGS, "val = 10:20:"sv);
+#if !TOML_LANG_UNRELEASED // toml/issues/671 (allow omission of seconds)
+ parsing_should_fail(FILE_LINE_ARGS, "val = 10:20"sv);
+#endif
+ parsing_should_fail(FILE_LINE_ARGS, "val = 10:2"sv);
+ parsing_should_fail(FILE_LINE_ARGS, "val = 10:"sv);
+
+ parsing_should_fail(FILE_LINE_ARGS, "val = 1987-03-16 10:20:30.04-09:3"sv);
+ parsing_should_fail(FILE_LINE_ARGS, "val = 1987-03-16 10:20:30.04-09:"sv);
+ parsing_should_fail(FILE_LINE_ARGS, "val = 1987-03-16 10:20:30.04-09"sv);
+ parsing_should_fail(FILE_LINE_ARGS, "val = 1987-03-16 10:20:30.04-0"sv);
+ parsing_should_fail(FILE_LINE_ARGS, "val = 1987-03-16 10:20:30.04-"sv);
+ parsing_should_fail(FILE_LINE_ARGS, "val = 1987-03-16 10:20:30."sv);
+ parsing_should_fail(FILE_LINE_ARGS, "val = 1987-03-16 10:20:3"sv);
+ parsing_should_fail(FILE_LINE_ARGS, "val = 1987-03-16 10:20:"sv);
+#if !TOML_LANG_UNRELEASED // toml/issues/671 (allow omission of seconds)
+ parsing_should_fail(FILE_LINE_ARGS, "val = 1987-03-16 10:20"sv);
+#endif
+ parsing_should_fail(FILE_LINE_ARGS, "val = 1987-03-16 10:2"sv);
+ parsing_should_fail(FILE_LINE_ARGS, "val = 1987-03-16 10:"sv);
+ parsing_should_fail(FILE_LINE_ARGS, "val = 1987-03-16 10"sv);
+ parsing_should_fail(FILE_LINE_ARGS, "val = 1987-03-16 1"sv);
+}
diff --git a/tomlplusplus/tests/parsing_floats.cpp b/tomlplusplus/tests/parsing_floats.cpp
new file mode 100644
index 0000000000..fceab80174
--- /dev/null
+++ b/tomlplusplus/tests/parsing_floats.cpp
@@ -0,0 +1,242 @@
+// This file is a part of toml++ and is subject to the the terms of the MIT license.
+// Copyright (c) Mark Gillard <mark.gillard@outlook.com.au>
+// See https://github.com/marzer/tomlplusplus/blob/master/LICENSE for the full license text.
+// SPDX-License-Identifier: MIT
+
+#include "tests.hpp"
+
+TEST_CASE("parsing - floats")
+{
+ parsing_should_succeed(FILE_LINE_ARGS,
+ R"(
+ # fractional
+ flt1 = +1.0
+ flt2 = 3.1415
+ flt3 = -0.01
+
+ # exponent
+ flt4 = 5e+22
+ flt5 = 1e06
+ flt6 = -2E-2
+
+ # both
+ flt7 = 6.626e-34
+
+ flt8 = 224_617.445_991_228
+ )"sv,
+ [](table&& tbl)
+ {
+ CHECK(tbl["flt1"] == 1.0);
+ CHECK(tbl["flt2"] == 3.1415);
+ CHECK(tbl["flt3"] == -0.01);
+ CHECK(tbl["flt4"].as<double>()->get() == 5e+22_a);
+ CHECK(tbl["flt5"].as<double>()->get() == 1e6_a);
+ CHECK(tbl["flt6"] == -2E-2);
+ CHECK(tbl["flt7"].as<double>()->get() == 6.626e-34_a);
+ CHECK(tbl["flt8"].as<double>()->get() == 224617.445991228_a);
+ });
+
+ // "Each underscore must be surrounded by at least one digit on each side."
+ parsing_should_fail(FILE_LINE_ARGS, "flt8 = 224_617.445_991_228_"sv);
+ parsing_should_fail(FILE_LINE_ARGS, "flt8 = _224_617.445_991_228"sv);
+ parsing_should_fail(FILE_LINE_ARGS, "flt8 = 224__617.445_991_228"sv);
+
+ // "Float values -0.0 and +0.0 are valid and should map according to IEEE 754."
+ parsing_should_succeed(FILE_LINE_ARGS,
+ R"(zeroes = [-0.0, +0.0])"sv,
+ [](table&& tbl)
+ {
+ CHECK(tbl["zeroes"][0] == -0.0);
+ CHECK(tbl["zeroes"][1] == +0.0);
+ });
+
+ // "A float consists of an integer part followed by a fractional part and/or an exponent part"
+ // (i.e. omitting the leading digits before the '.' is not legal in TOML)
+ parsing_should_fail(FILE_LINE_ARGS, "flt = .1"sv);
+ parsing_should_fail(FILE_LINE_ARGS, "flt = +.1"sv);
+ parsing_should_fail(FILE_LINE_ARGS, "flt = -.1"sv);
+ parsing_should_fail(FILE_LINE_ARGS, "flt = .1e1"sv);
+ parsing_should_fail(FILE_LINE_ARGS, "flt = .1e+1"sv);
+ parsing_should_fail(FILE_LINE_ARGS, "flt = .1e-1"sv);
+ parsing_should_fail(FILE_LINE_ARGS, "flt = +.1e1"sv);
+ parsing_should_fail(FILE_LINE_ARGS, "flt = +.1e+1"sv);
+ parsing_should_fail(FILE_LINE_ARGS, "flt = +.1e-1"sv);
+ parsing_should_fail(FILE_LINE_ARGS, "flt = -.1e1"sv);
+ parsing_should_fail(FILE_LINE_ARGS, "flt = -.1e+1"sv);
+ parsing_should_fail(FILE_LINE_ARGS, "flt = -.1e-1"sv);
+
+ // likewise, so is omitting digits _after_ the '.'
+ parsing_should_fail(FILE_LINE_ARGS, "flt = 1."sv);
+ parsing_should_fail(FILE_LINE_ARGS, "flt = +1."sv);
+ parsing_should_fail(FILE_LINE_ARGS, "flt = -1."sv);
+ parsing_should_fail(FILE_LINE_ARGS, "flt = 1.e1"sv);
+ parsing_should_fail(FILE_LINE_ARGS, "flt = 1.e+1"sv);
+ parsing_should_fail(FILE_LINE_ARGS, "flt = 1.e-1"sv);
+ parsing_should_fail(FILE_LINE_ARGS, "flt = +1.e1"sv);
+ parsing_should_fail(FILE_LINE_ARGS, "flt = +1.e+1"sv);
+ parsing_should_fail(FILE_LINE_ARGS, "flt = +1.e-1"sv);
+ parsing_should_fail(FILE_LINE_ARGS, "flt = -1.e1"sv);
+ parsing_should_fail(FILE_LINE_ARGS, "flt = -1.e+1"sv);
+ parsing_should_fail(FILE_LINE_ARGS, "flt = -1.e-1"sv);
+
+ // value tests
+ parse_expected_value(FILE_LINE_ARGS, "1e1"sv, 1e1);
+ parse_expected_value(FILE_LINE_ARGS, "1e+1"sv, 1e+1);
+ parse_expected_value(FILE_LINE_ARGS, "1e-1"sv, 1e-1);
+ parse_expected_value(FILE_LINE_ARGS, "1.0"sv, 1.0);
+ parse_expected_value(FILE_LINE_ARGS, "1.0e1"sv, 1.0e1);
+ parse_expected_value(FILE_LINE_ARGS, "1.0e+1"sv, 1.0e+1);
+ parse_expected_value(FILE_LINE_ARGS, "1.0e-1"sv, 1.0e-1);
+ parse_expected_value(FILE_LINE_ARGS, "+1e1"sv, +1e1);
+ parse_expected_value(FILE_LINE_ARGS, "+1.0"sv, +1.0);
+ parse_expected_value(FILE_LINE_ARGS, "+1.0e1"sv, +1.0e1);
+ parse_expected_value(FILE_LINE_ARGS, "+1.0e+1"sv, +1.0e+1);
+ parse_expected_value(FILE_LINE_ARGS, "+1.0e-1"sv, +1.0e-1);
+ parse_expected_value(FILE_LINE_ARGS, "-1.0e+1"sv, -1.0e+1);
+ parse_expected_value(FILE_LINE_ARGS, "-1e1"sv, -1e1);
+ parse_expected_value(FILE_LINE_ARGS, "-1.0"sv, -1.0);
+ parse_expected_value(FILE_LINE_ARGS, "-1.0e1"sv, -1.0e1);
+ parse_expected_value(FILE_LINE_ARGS, "-1.0e-1"sv, -1.0e-1);
+ parse_expected_value(FILE_LINE_ARGS, "0.1"sv, 0.1);
+ parse_expected_value(FILE_LINE_ARGS, "0.001"sv, 0.001);
+ parse_expected_value(FILE_LINE_ARGS, "0.100"sv, 0.100);
+ parse_expected_value(FILE_LINE_ARGS, "+3.14"sv, +3.14);
+ parse_expected_value(FILE_LINE_ARGS, "-3.14"sv, -3.14);
+ parse_expected_value(FILE_LINE_ARGS, "3.1415_9265_3589"sv, 3.141592653589);
+ parse_expected_value(FILE_LINE_ARGS, "+3.1415_9265_3589"sv, +3.141592653589);
+ parse_expected_value(FILE_LINE_ARGS, "-3.1415_9265_3589"sv, -3.141592653589);
+ parse_expected_value(FILE_LINE_ARGS, "123_456.789"sv, 123456.789);
+ parse_expected_value(FILE_LINE_ARGS, "+123_456.789"sv, +123456.789);
+ parse_expected_value(FILE_LINE_ARGS, "-123_456.789"sv, -123456.789);
+ parse_expected_value(FILE_LINE_ARGS, "+0.0"sv, +0.0);
+ parse_expected_value(FILE_LINE_ARGS, "-0.0"sv, -0.0);
+ parse_expected_value(FILE_LINE_ARGS, "1e10"sv, 1e10);
+ parse_expected_value(FILE_LINE_ARGS, "1e+10"sv, 1e+10);
+ parse_expected_value(FILE_LINE_ARGS, "1e-10"sv, 1e-10);
+ parse_expected_value(FILE_LINE_ARGS, "+1e10"sv, +1e10);
+ parse_expected_value(FILE_LINE_ARGS, "+1e+10"sv, +1e+10);
+ parse_expected_value(FILE_LINE_ARGS, "+1e-10"sv, +1e-10);
+ parse_expected_value(FILE_LINE_ARGS, "-1e10"sv, -1e10);
+ parse_expected_value(FILE_LINE_ARGS, "-1e+10"sv, -1e+10);
+ parse_expected_value(FILE_LINE_ARGS, "-1e-10"sv, -1e-10);
+ parse_expected_value(FILE_LINE_ARGS, "123e-10"sv, 123e-10);
+ parse_expected_value(FILE_LINE_ARGS, "1E10"sv, 1E10);
+ parse_expected_value(FILE_LINE_ARGS, "1E+10"sv, 1E+10);
+ parse_expected_value(FILE_LINE_ARGS, "1E-10"sv, 1E-10);
+ parse_expected_value(FILE_LINE_ARGS, "123E-10"sv, 123E-10);
+ parse_expected_value(FILE_LINE_ARGS, "1_2_3E-10"sv, 123E-10);
+ parse_expected_value(FILE_LINE_ARGS, "1_2_3E-1_0"sv, 123E-10);
+ parse_expected_value(FILE_LINE_ARGS, "+0e0"sv, +0e0);
+ parse_expected_value(FILE_LINE_ARGS, "-0e0"sv, -0e0);
+ parse_expected_value(FILE_LINE_ARGS, "1_2_3E-01"sv, 123E-01);
+ parse_expected_value(FILE_LINE_ARGS, "1_2_3E-0_1"sv, 123E-01);
+ parse_expected_value(FILE_LINE_ARGS, "6.02e23"sv, 6.02e23);
+ parse_expected_value(FILE_LINE_ARGS, "6.02e+23"sv, 6.02e+23);
+ parse_expected_value(FILE_LINE_ARGS, "1.112_650_06e-17"sv, 1.11265006e-17);
+ parse_expected_value(FILE_LINE_ARGS, "0.010284358729827818"sv, 0.010284358729827818);
+ parse_expected_value(FILE_LINE_ARGS, "0.010284358729827818"sv, 0.010284358729827818);
+ parse_expected_value(FILE_LINE_ARGS, "0.0102"sv, 0.0102);
+ parse_expected_value(FILE_LINE_ARGS, "10.0102"sv, 10.0102);
+ parse_expected_value(FILE_LINE_ARGS, "10.010284358729828"sv, 10.010284358729828);
+ parse_expected_value(FILE_LINE_ARGS, "10.0"sv, 10.0);
+
+// toml/issues/562 (hexfloats)
+#if TOML_LANG_UNRELEASED
+ parse_expected_value(FILE_LINE_ARGS, " 0x1.2p3"sv, 0x1.2p3);
+ parse_expected_value(FILE_LINE_ARGS, " 0x10p1"sv, 0x10p1);
+ parse_expected_value(FILE_LINE_ARGS, " 0x10p-1"sv, 0x10p-1);
+ parse_expected_value(FILE_LINE_ARGS, " 0x10p+1"sv, 0x10p+1);
+ parse_expected_value(FILE_LINE_ARGS, " -0x10p1"sv, -0x10p1);
+ parse_expected_value(FILE_LINE_ARGS, " -0x10p-1"sv, -0x10p-1);
+ parse_expected_value(FILE_LINE_ARGS, " +0x10p1"sv, +0x10p1);
+ parse_expected_value(FILE_LINE_ARGS, " +0x10p+1"sv, +0x10p+1);
+ parse_expected_value(FILE_LINE_ARGS, " -0x10p+1"sv, -0x10p+1);
+ parse_expected_value(FILE_LINE_ARGS, " +0x10p-1"sv, +0x10p-1);
+ parse_expected_value(FILE_LINE_ARGS, " 0x10.1p1"sv, 0x10.1p1);
+ parse_expected_value(FILE_LINE_ARGS, " 0x10.1p-1"sv, 0x10.1p-1);
+ parse_expected_value(FILE_LINE_ARGS, " 0x10.1p+1"sv, 0x10.1p+1);
+ parse_expected_value(FILE_LINE_ARGS, " -0x10.1p1"sv, -0x10.1p1);
+ parse_expected_value(FILE_LINE_ARGS, " -0x10.1p-1"sv, -0x10.1p-1);
+ parse_expected_value(FILE_LINE_ARGS, " +0x10.1p1"sv, +0x10.1p1);
+ parse_expected_value(FILE_LINE_ARGS, " +0x10.1p+1"sv, +0x10.1p+1);
+ parse_expected_value(FILE_LINE_ARGS, " -0x10.1p+1"sv, -0x10.1p+1);
+ parse_expected_value(FILE_LINE_ARGS, " +0x10.1p-1"sv, +0x10.1p-1);
+#else
+ parsing_should_fail(FILE_LINE_ARGS, " val = 0x10p1"sv);
+ parsing_should_fail(FILE_LINE_ARGS, " val = 0x10p-1"sv);
+ parsing_should_fail(FILE_LINE_ARGS, " val = 0x10p+1"sv);
+ parsing_should_fail(FILE_LINE_ARGS, " val = -0x10p1"sv);
+ parsing_should_fail(FILE_LINE_ARGS, " val = -0x10p-1"sv);
+ parsing_should_fail(FILE_LINE_ARGS, " val = +0x10p1"sv);
+ parsing_should_fail(FILE_LINE_ARGS, " val = +0x10p+1"sv);
+ parsing_should_fail(FILE_LINE_ARGS, " val = -0x10p+1"sv);
+ parsing_should_fail(FILE_LINE_ARGS, " val = +0x10p-1"sv);
+ parsing_should_fail(FILE_LINE_ARGS, " val = 0x10.1p1"sv);
+ parsing_should_fail(FILE_LINE_ARGS, " val = 0x10.1p-1"sv);
+ parsing_should_fail(FILE_LINE_ARGS, " val = 0x10.1p+1"sv);
+ parsing_should_fail(FILE_LINE_ARGS, " val = -0x10.1p1"sv);
+ parsing_should_fail(FILE_LINE_ARGS, " val = -0x10.1p-1"sv);
+ parsing_should_fail(FILE_LINE_ARGS, " val = +0x10.1p1"sv);
+ parsing_should_fail(FILE_LINE_ARGS, " val = +0x10.1p+1"sv);
+ parsing_should_fail(FILE_LINE_ARGS, " val = -0x10.1p+1"sv);
+ parsing_should_fail(FILE_LINE_ARGS, " val = +0x10.1p-1"sv);
+#endif
+}
+
+TEST_CASE("parsing - inf and nan")
+{
+ parsing_should_succeed(FILE_LINE_ARGS,
+ R"(
+ # infinity
+ sf1 = inf # positive infinity
+ sf2 = +inf # positive infinity
+ sf3 = -inf # negative infinity
+
+ # not a number
+ sf4 = nan # actual sNaN/qNaN encoding is implementation specific
+ sf5 = +nan # same as `nan`
+ sf6 = -nan # valid, actual encoding is implementation specific
+ )"sv,
+ [](table&& tbl)
+ {
+ CHECK(impl::fpclassify(**tbl["sf1"].as<double>()) == impl::fp_class::pos_inf);
+ CHECK(impl::fpclassify(**tbl["sf2"].as<double>()) == impl::fp_class::pos_inf);
+ CHECK(impl::fpclassify(**tbl["sf3"].as<double>()) == impl::fp_class::neg_inf);
+ CHECK(impl::fpclassify(**tbl["sf4"].as<double>()) == impl::fp_class::nan);
+ CHECK(impl::fpclassify(**tbl["sf5"].as<double>()) == impl::fp_class::nan);
+ CHECK(impl::fpclassify(**tbl["sf6"].as<double>()) == impl::fp_class::nan);
+ });
+
+ parsing_should_fail(FILE_LINE_ARGS, " val = NaN "sv);
+ parsing_should_fail(FILE_LINE_ARGS, " val = Nan "sv);
+ parsing_should_fail(FILE_LINE_ARGS, " val = NAN "sv);
+ parsing_should_fail(FILE_LINE_ARGS, " val = +NaN "sv);
+ parsing_should_fail(FILE_LINE_ARGS, " val = +Nan "sv);
+ parsing_should_fail(FILE_LINE_ARGS, " val = +NAN "sv);
+ parsing_should_fail(FILE_LINE_ARGS, " val = -NaN "sv);
+ parsing_should_fail(FILE_LINE_ARGS, " val = -Nan "sv);
+ parsing_should_fail(FILE_LINE_ARGS, " val = -NAN "sv);
+ parsing_should_fail(FILE_LINE_ARGS, " val = 1.nan "sv);
+ parsing_should_fail(FILE_LINE_ARGS, " val = 1,nan "sv);
+ parsing_should_fail(FILE_LINE_ARGS, " val = .nan "sv);
+ parsing_should_fail(FILE_LINE_ARGS, " val = ,nan "sv);
+ parsing_should_fail(FILE_LINE_ARGS, " val = nan.1 "sv);
+ parsing_should_fail(FILE_LINE_ARGS, " val = nan,1 "sv);
+ parsing_should_fail(FILE_LINE_ARGS, " val = nan. "sv);
+ parsing_should_fail(FILE_LINE_ARGS, " val = nan, "sv);
+
+ parsing_should_fail(FILE_LINE_ARGS, " val = Inf "sv);
+ parsing_should_fail(FILE_LINE_ARGS, " val = INF "sv);
+ parsing_should_fail(FILE_LINE_ARGS, " val = +Inf "sv);
+ parsing_should_fail(FILE_LINE_ARGS, " val = +INF "sv);
+ parsing_should_fail(FILE_LINE_ARGS, " val = -Inf "sv);
+ parsing_should_fail(FILE_LINE_ARGS, " val = -INF "sv);
+ parsing_should_fail(FILE_LINE_ARGS, " val = 1.inf "sv);
+ parsing_should_fail(FILE_LINE_ARGS, " val = 1,inf "sv);
+ parsing_should_fail(FILE_LINE_ARGS, " val = .inf "sv);
+ parsing_should_fail(FILE_LINE_ARGS, " val = ,inf "sv);
+ parsing_should_fail(FILE_LINE_ARGS, " val = inf.1 "sv);
+ parsing_should_fail(FILE_LINE_ARGS, " val = inf,1 "sv);
+ parsing_should_fail(FILE_LINE_ARGS, " val = inf. "sv);
+ parsing_should_fail(FILE_LINE_ARGS, " val = inf, "sv);
+}
diff --git a/tomlplusplus/tests/parsing_integers.cpp b/tomlplusplus/tests/parsing_integers.cpp
new file mode 100644
index 0000000000..c49858cf08
--- /dev/null
+++ b/tomlplusplus/tests/parsing_integers.cpp
@@ -0,0 +1,177 @@
+// This file is a part of toml++ and is subject to the the terms of the MIT license.
+// Copyright (c) Mark Gillard <mark.gillard@outlook.com.au>
+// See https://github.com/marzer/tomlplusplus/blob/master/LICENSE for the full license text.
+// SPDX-License-Identifier: MIT
+
+#include "tests.hpp"
+
+TEST_CASE("parsing - integers (decimal)")
+{
+ parsing_should_succeed(FILE_LINE_ARGS,
+ BOM_PREFIX R"(
+ int1 = +99
+ int2 = 42
+ int3 = 0
+ int4 = -17
+ int5 = 1_000
+ int6 = 5_349_221
+ int7 = 1_2_3_4_5 # VALID but discouraged
+ )"sv,
+ [](table&& tbl)
+ {
+ CHECK(tbl["int1"] == 99);
+ CHECK(tbl["int2"] == 42);
+ CHECK(tbl["int3"] == 0);
+ CHECK(tbl["int4"] == -17);
+ CHECK(tbl["int5"] == 1000);
+ CHECK(tbl["int6"] == 5349221);
+ CHECK(tbl["int7"] == 12345);
+ });
+
+ // "Each underscore must be surrounded by at least one digit on each side."
+ parsing_should_fail(FILE_LINE_ARGS, "int5 = 1__000"sv);
+ parsing_should_fail(FILE_LINE_ARGS, "int5 = _1_000"sv);
+ parsing_should_fail(FILE_LINE_ARGS, "int5 = 1_000_"sv);
+
+ // "Leading zeroes are not allowed."
+ parsing_should_fail(FILE_LINE_ARGS, "int1 = +099"sv);
+ parsing_should_fail(FILE_LINE_ARGS, "int2 = 042"sv);
+ parsing_should_fail(FILE_LINE_ARGS, "int3 = 00"sv);
+ parsing_should_fail(FILE_LINE_ARGS, "int4 = -017"sv);
+ parsing_should_fail(FILE_LINE_ARGS, "int5 = 01_000"sv);
+ parsing_should_fail(FILE_LINE_ARGS, "int6 = 05_349_221"sv);
+ parsing_should_fail(FILE_LINE_ARGS, "int7 = 01_2_3_4_5"sv);
+
+ // "Integer values -0 and +0 are valid and identical to an unprefixed zero."
+ parsing_should_succeed(FILE_LINE_ARGS,
+ "zeroes = [-0, +0]"sv,
+ [](table&& tbl)
+ {
+ CHECK(tbl["zeroes"][0] == 0);
+ CHECK(tbl["zeroes"][1] == 0);
+ });
+
+ // "64 bit (signed long) range expected (−9,223,372,036,854,775,808 to 9,223,372,036,854,775,807)."
+ parse_expected_value(FILE_LINE_ARGS, "9223372036854775807"sv, INT64_MAX);
+ parse_expected_value(FILE_LINE_ARGS, "-9223372036854775808"sv, INT64_MIN);
+ parsing_should_fail(FILE_LINE_ARGS, "val = 9223372036854775808"sv); // INT64_MAX + 1
+ parsing_should_fail(FILE_LINE_ARGS, "val = -9223372036854775809"sv); // INT64_MIN - 1
+
+ // signs in weird places
+ parsing_should_fail(FILE_LINE_ARGS, "val = +-1"sv);
+ parsing_should_fail(FILE_LINE_ARGS, "val = -+1"sv);
+ parsing_should_fail(FILE_LINE_ARGS, "val = ++1"sv);
+ parsing_should_fail(FILE_LINE_ARGS, "val = --1"sv);
+ parsing_should_fail(FILE_LINE_ARGS, "val = 1-"sv);
+ parsing_should_fail(FILE_LINE_ARGS, "val = 1+"sv);
+ parsing_should_fail(FILE_LINE_ARGS, "val = -1+"sv);
+ parsing_should_fail(FILE_LINE_ARGS, "val = +1-"sv);
+
+ // value tests
+ parse_expected_value(FILE_LINE_ARGS, "0"sv, 0);
+ parse_expected_value(FILE_LINE_ARGS, "1"sv, 1);
+ parse_expected_value(FILE_LINE_ARGS, "+1"sv, 1);
+ parse_expected_value(FILE_LINE_ARGS, "-1"sv, -1);
+ parse_expected_value(FILE_LINE_ARGS, "1234"sv, 1234);
+ parse_expected_value(FILE_LINE_ARGS, "+1234"sv, 1234);
+ parse_expected_value(FILE_LINE_ARGS, "-1234"sv, -1234);
+ parse_expected_value(FILE_LINE_ARGS, "1_2_3_4"sv, 1234);
+ parse_expected_value(FILE_LINE_ARGS, "+1_2_3_4"sv, 1234);
+ parse_expected_value(FILE_LINE_ARGS, "-1_2_3_4"sv, -1234);
+ parse_expected_value(FILE_LINE_ARGS, "123_456_789"sv, 123456789);
+}
+
+TEST_CASE("parsing - integers (hex, bin, oct)")
+{
+ parsing_should_succeed(FILE_LINE_ARGS,
+ R"(
+ # hexadecimal with prefix `0x`
+ hex1 = 0xDEADBEEF
+ hex2 = 0xdeadbeef
+ hex3 = 0xdead_beef
+
+ # octal with prefix `0o`
+ oct1 = 0o01234567
+ oct2 = 0o755 # useful for Unix file permissions
+
+ # binary with prefix `0b`
+ bin1 = 0b11010110
+ )"sv,
+ [](table&& tbl)
+ {
+ CHECK(tbl["hex1"] == 0xDEADBEEF);
+ CHECK(tbl["hex2"] == 0xDEADBEEF);
+ CHECK(tbl["hex3"] == 0xDEADBEEF);
+ CHECK(tbl["oct1"] == 01234567);
+ CHECK(tbl["oct2"] == 0755);
+ CHECK(tbl["bin1"] == 0b11010110);
+ });
+
+ // "leading + is not allowed"
+ parsing_should_fail(FILE_LINE_ARGS, "hex1 = +0xDEADBEEF"sv);
+ parsing_should_fail(FILE_LINE_ARGS, "hex2 = +0xdeadbeef"sv);
+ parsing_should_fail(FILE_LINE_ARGS, "hex3 = +0xdead_beef"sv);
+ parsing_should_fail(FILE_LINE_ARGS, "oct1 = +0o01234567"sv);
+ parsing_should_fail(FILE_LINE_ARGS, "oct2 = +0o7550"sv);
+ parsing_should_fail(FILE_LINE_ARGS, "int6 = +05_349_221"sv);
+ parsing_should_fail(FILE_LINE_ARGS, "bin1 = +0b11010110"sv);
+
+ // "leading zeros are allowed (after the prefix)"
+ parsing_should_succeed(FILE_LINE_ARGS,
+ R"(
+ hex1 = 0x000DEADBEEF
+ hex2 = 0x00000deadbeef
+ hex3 = 0x0dead_beef
+ oct1 = 0o0001234567
+ oct2 = 0o000755
+ bin1 = 0b0000011010110
+ )"sv,
+ [](table&& tbl)
+ {
+ CHECK(tbl["hex1"] == 0xDEADBEEF);
+ CHECK(tbl["hex2"] == 0xDEADBEEF);
+ CHECK(tbl["hex3"] == 0xDEADBEEF);
+ CHECK(tbl["oct1"] == 01234567);
+ CHECK(tbl["oct2"] == 0755);
+ CHECK(tbl["bin1"] == 0b11010110);
+ });
+
+ // "***Non-negative*** integer values may also be expressed in hexadecimal, octal, or binary"
+ parsing_should_fail(FILE_LINE_ARGS, "val = -0x1"sv);
+ parsing_should_fail(FILE_LINE_ARGS, "val = -0o1"sv);
+ parsing_should_fail(FILE_LINE_ARGS, "val = -0b1"sv);
+
+ // "64 bit (signed long) range expected (−9,223,372,036,854,775,808 to 9,223,372,036,854,775,807)."
+ // (ignoring INT64_MIN because toml doesn't allow these forms to represent negative values)
+ parse_expected_value(FILE_LINE_ARGS, "0x7FFFFFFFFFFFFFFF"sv, INT64_MAX);
+ parse_expected_value(FILE_LINE_ARGS, "0o777777777777777777777"sv, INT64_MAX);
+ parse_expected_value(FILE_LINE_ARGS,
+ "0b111111111111111111111111111111111111111111111111111111111111111"sv,
+ INT64_MAX);
+ parsing_should_fail(FILE_LINE_ARGS, "val = 0x8000000000000000"sv); // INT64_MAX + 1
+ parsing_should_fail(FILE_LINE_ARGS, "val = 0o1000000000000000000000"sv);
+ parsing_should_fail(FILE_LINE_ARGS, "val = 0b1000000000000000000000000000000000000000000000000000000000000000"sv);
+
+ // missing values after base prefix
+ parsing_should_fail(FILE_LINE_ARGS, "val = 0x "sv);
+ parsing_should_fail(FILE_LINE_ARGS, "val = 0o "sv);
+ parsing_should_fail(FILE_LINE_ARGS, "val = 0b "sv);
+
+ // value tests
+ parse_expected_value(FILE_LINE_ARGS, "0xDEADBEEF"sv, 0xDEADBEEF);
+ parse_expected_value(FILE_LINE_ARGS, "0xdeadbeef"sv, 0xDEADBEEF);
+ parse_expected_value(FILE_LINE_ARGS, "0xDEADbeef"sv, 0xDEADBEEF);
+ parse_expected_value(FILE_LINE_ARGS, "0xDEAD_BEEF"sv, 0xDEADBEEF);
+ parse_expected_value(FILE_LINE_ARGS, "0xdead_beef"sv, 0xDEADBEEF);
+ parse_expected_value(FILE_LINE_ARGS, "0xdead_BEEF"sv, 0xDEADBEEF);
+ parse_expected_value(FILE_LINE_ARGS, "0xFF"sv, 0xFF);
+ parse_expected_value(FILE_LINE_ARGS, "0x00FF"sv, 0xFF);
+ parse_expected_value(FILE_LINE_ARGS, "0x0000FF"sv, 0xFF);
+ parse_expected_value(FILE_LINE_ARGS, "0o777"sv, 0777);
+ parse_expected_value(FILE_LINE_ARGS, "0o7_7_7"sv, 0777);
+ parse_expected_value(FILE_LINE_ARGS, "0o007"sv, 0007);
+ parse_expected_value(FILE_LINE_ARGS, "0b10000"sv, 0b10000);
+ parse_expected_value(FILE_LINE_ARGS, "0b010000"sv, 0b10000);
+ parse_expected_value(FILE_LINE_ARGS, "0b01_00_00"sv, 0b10000);
+ parse_expected_value(FILE_LINE_ARGS, "0b111111"sv, 0b111111);
+}
diff --git a/tomlplusplus/tests/parsing_key_value_pairs.cpp b/tomlplusplus/tests/parsing_key_value_pairs.cpp
new file mode 100644
index 0000000000..b91320390a
--- /dev/null
+++ b/tomlplusplus/tests/parsing_key_value_pairs.cpp
@@ -0,0 +1,399 @@
+// This file is a part of toml++ and is subject to the the terms of the MIT license.
+// Copyright (c) Mark Gillard <mark.gillard@outlook.com.au>
+// See https://github.com/marzer/tomlplusplus/blob/master/LICENSE for the full license text.
+// SPDX-License-Identifier: MIT
+
+#include "tests.hpp"
+
+TEST_CASE("parsing - key-value pairs")
+{
+ parsing_should_succeed(FILE_LINE_ARGS,
+ R"(
+ key = "value"
+ bare_key = "value"
+ bare-key = "value"
+ 1234 = "value"
+ "" = "blank"
+ )"sv,
+ [](table&& tbl)
+ {
+ CHECK(tbl.size() == 5);
+ CHECK(tbl["key"] == "value"sv);
+ CHECK(tbl["bare_key"] == "value"sv);
+ CHECK(tbl["bare-key"] == "value"sv);
+ CHECK(tbl["1234"] == "value"sv);
+ CHECK(tbl[""] == "blank"sv);
+ });
+
+ parsing_should_fail(FILE_LINE_ARGS, R"(key = # INVALID)"sv);
+
+#if UNICODE_LITERALS_OK
+ parsing_should_succeed(FILE_LINE_ARGS,
+ R"(
+ "127.0.0.1" = "value"
+ "character encoding" = "value"
+ "ʎǝʞ" = "value"
+ 'key2' = "value"
+ 'quoted "value"' = "value"
+ '' = 'blank'
+ )"sv,
+ [](table&& tbl)
+ {
+ CHECK(tbl["127.0.0.1"] == "value"sv);
+ CHECK(tbl["character encoding"] == "value"sv);
+ CHECK(tbl["ʎǝʞ"] == "value"sv);
+ CHECK(tbl["key2"] == "value"sv);
+ CHECK(tbl["quoted \"value\""] == "value"sv);
+ CHECK(tbl[""] == "blank"sv);
+ });
+#endif // UNICODE_LITERALS_OK
+
+ parsing_should_fail(FILE_LINE_ARGS, R"(= "no key name")"sv);
+
+ parsing_should_fail(FILE_LINE_ARGS, R"(
+ # DO NOT DO THIS
+ name = "Tom"
+ name = "Pradyun"
+ )"sv);
+}
+
+TEST_CASE("parsing - key-value pairs (dotted)")
+{
+ parsing_should_succeed(FILE_LINE_ARGS,
+ R"(
+ name = "Orange"
+ physical.color = "orange"
+ physical.shape = "round"
+ site."google.com" = true
+ 3.14159 = "pi"
+ )"sv,
+ [](table&& tbl)
+ {
+ CHECK(tbl.size() == 4);
+ CHECK(tbl["name"] == "Orange"sv);
+ CHECK(tbl["physical"]["color"] == "orange"sv);
+ CHECK(tbl["physical"]["shape"] == "round"sv);
+ CHECK(tbl["site"]["google.com"] == true);
+ CHECK(tbl["3"]["14159"] == "pi"sv);
+ });
+
+ parsing_should_succeed(FILE_LINE_ARGS,
+ R"(
+ fruit.apple.smooth = true
+ fruit.orange = 2
+ )"sv,
+ [](table&& tbl)
+ {
+ CHECK(tbl["fruit"]["apple"]["smooth"] == true);
+ CHECK(tbl["fruit"]["orange"] == 2);
+ });
+
+ parsing_should_fail(FILE_LINE_ARGS, R"(
+ # THIS IS INVALID
+ fruit.apple = 1
+ fruit.apple.smooth = true
+ )"sv);
+
+ parsing_should_succeed(FILE_LINE_ARGS,
+ R"(
+ # VALID BUT DISCOURAGED
+
+ apple.type = "fruit"
+ orange.type = "fruit"
+
+ apple.skin = "thin"
+ orange.skin = "thick"
+
+ apple.color = "red"
+ orange.color = "orange"
+ )"sv,
+ [](table&& tbl)
+ {
+ CHECK(tbl["apple"]["type"] == "fruit"sv);
+ CHECK(tbl["apple"]["skin"] == "thin"sv);
+ CHECK(tbl["apple"]["color"] == "red"sv);
+ CHECK(tbl["orange"]["type"] == "fruit"sv);
+ CHECK(tbl["orange"]["skin"] == "thick"sv);
+ CHECK(tbl["orange"]["color"] == "orange"sv);
+ });
+
+ parsing_should_succeed(FILE_LINE_ARGS,
+ R"(
+ # RECOMMENDED
+
+ apple.type = "fruit"
+ apple.skin = "thin"
+ apple.color = "red"
+
+ orange.type = "fruit"
+ orange.skin = "thick"
+ orange.color = "orange"
+ )"sv,
+ [](table&& tbl)
+ {
+ CHECK(tbl["apple"]["type"] == "fruit"sv);
+ CHECK(tbl["apple"]["skin"] == "thin"sv);
+ CHECK(tbl["apple"]["color"] == "red"sv);
+ CHECK(tbl["orange"]["type"] == "fruit"sv);
+ CHECK(tbl["orange"]["skin"] == "thick"sv);
+ CHECK(tbl["orange"]["color"] == "orange"sv);
+ });
+
+// toml/issues/644 ('+' in bare keys)
+#if TOML_LANG_UNRELEASED
+ parsing_should_succeed(FILE_LINE_ARGS, "key+1 = 0"sv, [](table&& tbl) { CHECK(tbl["key+1"] == 0); });
+#else
+ parsing_should_fail(FILE_LINE_ARGS, "key+1 = 0"sv);
+#endif
+
+// toml/pull/891 (unicode bare keys)
+// clang-format off
+#if UNICODE_LITERALS_OK
+#if TOML_LANG_UNRELEASED
+ parsing_should_succeed(FILE_LINE_ARGS, R"(ʎǝʞ = 1)"sv, [](table&& tbl) { CHECK(tbl[R"(ʎǝʞ)"] == 1); });
+ parsing_should_succeed(FILE_LINE_ARGS, R"(Fuß = 2)"sv, [](table&& tbl) { CHECK(tbl[R"(Fuß)"] == 2); });
+ parsing_should_succeed(FILE_LINE_ARGS, R"(😂 = 3)"sv, [](table&& tbl) { CHECK(tbl[R"(😂)"] == 3); });
+ parsing_should_succeed(FILE_LINE_ARGS, R"(汉语大字典 = 4)"sv, [](table&& tbl) { CHECK(tbl[R"(汉语大字典)"] == 4); });
+ parsing_should_succeed(FILE_LINE_ARGS, R"(辭源 = 5)"sv, [](table&& tbl) { CHECK(tbl[R"(辭源)"] == 5); });
+ parsing_should_succeed(FILE_LINE_ARGS, R"(பெண்டிரேம் = 6)"sv, [](table&& tbl) { CHECK(tbl[R"(பெண்டிரேம்)"] == 6); });
+#else
+ parsing_should_fail(FILE_LINE_ARGS, R"(ʎǝʞ = 1)"sv);
+ parsing_should_fail(FILE_LINE_ARGS, R"(Fuß = 2)"sv);
+ parsing_should_fail(FILE_LINE_ARGS, R"(😂 = 3)"sv);
+ parsing_should_fail(FILE_LINE_ARGS, R"(汉语大字典 = 4)"sv);
+ parsing_should_fail(FILE_LINE_ARGS, R"(辭源 = 5)"sv);
+ parsing_should_fail(FILE_LINE_ARGS, R"(பெண்டிரேம் = 6)"sv);
+#endif
+#endif // UNICODE_LITERALS_OK
+ // clang-format on
+}
+
+TEST_CASE("parsing - key-value pairs (string keys)")
+{
+ // these are all derived from the discussion at
+ // https://github.com/toml-lang/toml/issues/733.
+
+ // whitespace stripped, fail duplicate keys
+ parsing_should_fail(FILE_LINE_ARGS, R"(
+ a = 2
+ a = 3
+ )"sv);
+
+ // only surrounding whitespace is stripped, fail: illegal key name or syntax error
+ parsing_should_fail(FILE_LINE_ARGS, "a b = 3"sv);
+
+ // whitespace is allowed when quoted, fail duplicate key
+ parsing_should_succeed(FILE_LINE_ARGS, "\"a b\" = 3"sv);
+ parsing_should_succeed(FILE_LINE_ARGS, "'a b' = 3"sv);
+ parsing_should_fail(FILE_LINE_ARGS, R"(
+ "a b" = 3
+ 'a b' = 3
+ )"sv);
+
+ // whitespace is allowed when quoted, but not collapsed, success
+ parsing_should_succeed(FILE_LINE_ARGS, R"(
+ "a b" = 3
+ 'a b' = 3
+ )"sv);
+
+ // whitespace relevant, but fail: duplicate key
+ parsing_should_fail(FILE_LINE_ARGS, R"(
+ "a " = 2
+ 'a ' = 3
+ )"sv);
+
+ // whitespace relevant, and not collapsed, success
+ parsing_should_succeed(FILE_LINE_ARGS, R"(
+ "a " = 2
+ "a " = 3
+ )"sv);
+
+ // whitespace can be escaped, success, different keys (whitespace escapes are not normalized)
+ parsing_should_succeed(FILE_LINE_ARGS, R"(
+ "a\n" = 2
+ "a\r" = 3
+ "a\t" = 3
+ "a\f" = 3
+ )"sv);
+
+ // valid keys composed of various string/non-string mixes types
+ parsing_should_succeed(FILE_LINE_ARGS, R"(a = 3)"sv);
+ parsing_should_succeed(FILE_LINE_ARGS, R"('a' = 3)"sv);
+ parsing_should_succeed(FILE_LINE_ARGS, R"("a" = 3)"sv);
+ parsing_should_succeed(FILE_LINE_ARGS, R"(a.b = 3)"sv);
+ parsing_should_succeed(FILE_LINE_ARGS, R"('a'.b = 3)"sv);
+ parsing_should_succeed(FILE_LINE_ARGS, R"("a".b = 3)"sv);
+ parsing_should_succeed(FILE_LINE_ARGS, R"(a.'b' = 3)"sv);
+ parsing_should_succeed(FILE_LINE_ARGS, R"('a'.'b' = 3)"sv);
+ parsing_should_succeed(FILE_LINE_ARGS, R"("a".'b' = 3)"sv);
+ parsing_should_succeed(FILE_LINE_ARGS, R"(a."b" = 3)"sv);
+ parsing_should_succeed(FILE_LINE_ARGS, R"('a'."b" = 3)"sv);
+ parsing_should_succeed(FILE_LINE_ARGS, R"("a"."b" = 3)"sv);
+
+ // multi-line strings can't be used in keys
+ parsing_should_fail(FILE_LINE_ARGS, R"('''a''' = 3)"sv);
+ parsing_should_fail(FILE_LINE_ARGS, R"("""a""" = 3)"sv);
+ parsing_should_fail(FILE_LINE_ARGS, R"(a.'''b''' = 3)"sv);
+ parsing_should_fail(FILE_LINE_ARGS, R"(a."""b""" = 3)"sv);
+
+ // whitespace relevant (success test, values are NOTE equal)
+ parsing_should_succeed(FILE_LINE_ARGS,
+ R"(
+ a = " to do "
+ b = "to do"
+ )"sv,
+ [](table&& tbl)
+ {
+ CHECK(tbl["a"] == " to do "sv);
+ CHECK(tbl["b"] == "to do"sv);
+ });
+
+ // values must be quoted, syntax error
+ parsing_should_fail(FILE_LINE_ARGS, R"(
+ a = to do
+ b = todo
+ )"sv);
+
+ // different quotes, fail duplicate keys
+ parsing_should_fail(FILE_LINE_ARGS, R"(
+ a = 2
+ 'a' = 2
+ )"sv);
+ parsing_should_fail(FILE_LINE_ARGS, R"(
+ 'a' = 2
+ "a" = 2
+ )"sv);
+ parsing_should_fail(FILE_LINE_ARGS, R"(
+ 'a' = 2
+ """a""" = 2
+ )"sv);
+ parsing_should_fail(FILE_LINE_ARGS, R"(
+ '''a''' = 2
+ """a""" = 2
+ )"sv);
+
+ // success test, capital not equal to small
+ parsing_should_succeed(FILE_LINE_ARGS, R"(
+ a = 2
+ A = 3
+ )"sv);
+
+ // inner quotes are not stripped from value, a & b are equal, value surrounded by quotes
+ parsing_should_succeed(FILE_LINE_ARGS,
+ R"(
+ a = "\"quoted\""
+ b = """"quoted""""
+ )"sv,
+ [](table&& tbl)
+ {
+ CHECK(tbl["a"] == "\"quoted\""sv);
+ CHECK(tbl["b"] == "\"quoted\""sv);
+ });
+
+ // quote correction is not applied, fail syntax error
+ parsing_should_fail(FILE_LINE_ARGS, R"("a = "test")"sv);
+ parsing_should_fail(FILE_LINE_ARGS, R"('a = 'test')"sv);
+ parsing_should_fail(FILE_LINE_ARGS, R"("a = 'test")"sv);
+ parsing_should_fail(FILE_LINE_ARGS, R"('a = "test')"sv);
+
+ // quotes cannot appear in keys this way, fail syntax error
+ parsing_should_fail(FILE_LINE_ARGS, R"("a'b = 3)"sv);
+ parsing_should_fail(FILE_LINE_ARGS, R"("a"b = 3)"sv);
+
+ // escaped quotes and single quotes can appear this way, fail duplicate keys
+ parsing_should_succeed(FILE_LINE_ARGS, R"("a'b" = 2)"sv);
+ parsing_should_succeed(FILE_LINE_ARGS, R"("a\u0027b" = 4)"sv);
+ parsing_should_fail(FILE_LINE_ARGS, R"(
+ "a'b" = 2
+ "a\u0027b" = 4
+ )"sv);
+
+ // literal strings, escapes are not escaped, success, since keys are valid and not equal
+ parsing_should_succeed(FILE_LINE_ARGS, R"(
+ 'a"b' = 2
+ 'a\"b' = 4
+ )"sv);
+
+ // escapes must be compared after unescaping, fail duplicate key
+ parsing_should_succeed(FILE_LINE_ARGS, R"(a = 1)"sv);
+ parsing_should_succeed(FILE_LINE_ARGS, R"("\u0061" = 2)"sv);
+ parsing_should_fail(FILE_LINE_ARGS, R"(
+ a = 1
+ "\u0061" = 2
+ )"sv);
+
+ // escaping requires quotes, syntax error
+ parsing_should_fail(FILE_LINE_ARGS, R"(\u0061 = 2)"sv);
+
+ // empty keys are allowed, but can only appear once, fail duplicate key
+ parsing_should_succeed(FILE_LINE_ARGS, R"("" = 2)"sv);
+ parsing_should_succeed(FILE_LINE_ARGS, R"('' = 3)"sv);
+ parsing_should_fail(FILE_LINE_ARGS, R"(
+ "" = 2
+ '' = 3
+ )"sv);
+
+ // bare keys can be numerals, but are interpreted as strings, fail duplicate key
+ parsing_should_succeed(FILE_LINE_ARGS, R"(1234 = 5)"sv);
+ parsing_should_succeed(FILE_LINE_ARGS, R"("1234" = 5)"sv);
+ parsing_should_fail(FILE_LINE_ARGS, R"(
+ 1234 = 5
+ "1234" = 5
+ )"sv);
+
+ // bare keys can be numerals, but are interpreted as strings, fail duplicate key
+ parsing_should_succeed(FILE_LINE_ARGS, R"(1234 = 5)"sv);
+ parsing_should_succeed(FILE_LINE_ARGS, R"('1234' = 5)"sv);
+ parsing_should_fail(FILE_LINE_ARGS, R"(
+ 1234 = 5
+ '1234' = 5
+ )"sv);
+
+ // bare keys can be numerals, but are interpreted as strings, valid, different keys
+ parsing_should_succeed(FILE_LINE_ARGS, R"(
+ 1234 = 5
+ 01234 = 5
+ )"sv);
+
+ // bare keys can be numerals, but are interpreted as strings, valid, different keys
+ parsing_should_succeed(FILE_LINE_ARGS, R"(
+ 12e3 = 4
+ 12000 = 5
+ )"sv);
+
+ // bare keys can be numerals, but are interpreted as strings, valid, different keys, one dotted
+ parsing_should_succeed(FILE_LINE_ARGS, R"(
+ 1.2e3 = 4
+ 1200 = 5
+ )"sv);
+
+ // bare keys can be numerals, but are interpreted as strings, success, cause one is dotted
+ parsing_should_succeed(FILE_LINE_ARGS, R"(
+ 1.2e3 = 4
+ "1.2e3" = 5
+ )"sv);
+
+ // bare keys can be numerals, but are interpreted as strings, fail duplicate keys
+ parsing_should_succeed(FILE_LINE_ARGS, R"(12e3 = 4)"sv);
+ parsing_should_succeed(FILE_LINE_ARGS, R"("12e3" = 5)"sv);
+ parsing_should_fail(FILE_LINE_ARGS, R"(
+ 12e3 = 4
+ "12e3" = 5
+ )"sv);
+
+ // bare keys can be numerals, but are interpreted as strings, fail duplicate dotted keys
+ parsing_should_succeed(FILE_LINE_ARGS, R"(1.2e3 = 4)"sv);
+ parsing_should_succeed(FILE_LINE_ARGS, R"(1."2e3" = 5)"sv);
+ parsing_should_fail(FILE_LINE_ARGS, R"(
+ 1.2e3 = 4
+ 1."2e3" = 5
+ )"sv);
+
+ // bare keys can be numerals, but are interpreted as strings, fail duplicate dotted keys
+ parsing_should_succeed(FILE_LINE_ARGS, R"(1.2e3 = 4)"sv);
+ parsing_should_succeed(FILE_LINE_ARGS, R"("1".2e3 = 5)"sv);
+ parsing_should_fail(FILE_LINE_ARGS, R"(
+ 1.2e3 = 4
+ "1".2e3 = 5
+ )"sv);
+}
diff --git a/tomlplusplus/tests/parsing_spec_example.cpp b/tomlplusplus/tests/parsing_spec_example.cpp
new file mode 100644
index 0000000000..254bbd3d5c
--- /dev/null
+++ b/tomlplusplus/tests/parsing_spec_example.cpp
@@ -0,0 +1,92 @@
+// This file is a part of toml++ and is subject to the the terms of the MIT license.
+// Copyright (c) Mark Gillard <mark.gillard@outlook.com.au>
+// See https://github.com/marzer/tomlplusplus/blob/master/LICENSE for the full license text.
+// SPDX-License-Identifier: MIT
+
+#include "tests.hpp"
+TOML_DISABLE_SPAM_WARNINGS;
+
+TEST_CASE("parsing - TOML spec example")
+{
+ static constexpr auto toml_text = R"(
+ # This is a TOML document.
+
+ title = "TOML Example"
+
+ [owner]
+ name = "Tom Preston-Werner"
+ dob = 1979-05-27T07:32:00-08:00 # First class dates
+
+ [database]
+ server = "192.168.1.1"
+ ports = [ 8001, 8001, 8002 ]
+ connection_max = 5000
+ enabled = true
+
+ [servers]
+
+ # Indentation (tabs and/or spaces) is allowed but not required
+ [servers.alpha]
+ ip = "10.0.0.1"
+ dc = "eqdc10"
+
+ [servers.beta]
+ ip = "10.0.0.2"
+ dc = "eqdc10"
+
+ [clients]
+ data = [ ["gamma", "delta"], [1, 2] ]
+
+ # Line breaks are OK when inside arrays
+ hosts = [
+ "alpha",
+ "omega"
+ ]
+ )"sv;
+
+ parsing_should_succeed(FILE_LINE_ARGS,
+ toml_text,
+ [](table&& tbl)
+ {
+ CHECK(tbl.size() == 5);
+
+ CHECK(tbl["title"] == "TOML Example"sv);
+
+ CHECK(tbl["owner"]);
+ CHECK(tbl["owner"].as<table>());
+ CHECK(tbl["owner"]["name"] == "Tom Preston-Werner"sv);
+ const auto dob = date_time{ { 1979, 5, 27 }, { 7, 32 }, { -8, 0 } };
+ CHECK(tbl["owner"]["dob"] == dob);
+
+ CHECK(tbl["database"].as<table>());
+ CHECK(tbl["database"]["server"] == "192.168.1.1"sv);
+ const auto ports = { 8001, 8001, 8002 };
+ CHECK(tbl["database"]["ports"] == ports);
+ CHECK(tbl["database"]["connection_max"] == 5000);
+ CHECK(tbl["database"]["enabled"] == true);
+
+ CHECK(tbl["servers"].as<table>());
+ CHECK(tbl["servers"]["alpha"].as<table>());
+ CHECK(tbl["servers"]["alpha"]["ip"] == "10.0.0.1"sv);
+ CHECK(tbl["servers"]["alpha"]["dc"] == "eqdc10"sv);
+ CHECK(tbl["servers"]["beta"].as<table>());
+ CHECK(tbl["servers"]["beta"]["ip"] == "10.0.0.2"sv);
+ CHECK(tbl["servers"]["beta"]["dc"] == "eqdc10"sv);
+
+ CHECK(tbl["clients"].as<table>());
+ REQUIRE(tbl["clients"]["data"].as<array>());
+ CHECK(tbl["clients"]["data"].as<array>()->size() == 2);
+ REQUIRE(tbl["clients"]["data"][0].as<array>());
+ CHECK(tbl["clients"]["data"][0].as<array>()->size() == 2);
+ CHECK(tbl["clients"]["data"][0][0] == "gamma"sv);
+ CHECK(tbl["clients"]["data"][0][1] == "delta"sv);
+ REQUIRE(tbl["clients"]["data"][1].as<array>());
+ CHECK(tbl["clients"]["data"][1].as<array>()->size() == 2);
+ CHECK(tbl["clients"]["data"][1][0] == 1);
+ CHECK(tbl["clients"]["data"][1][1] == 2);
+ REQUIRE(tbl["clients"]["hosts"].as<array>());
+ CHECK(tbl["clients"]["hosts"].as<array>()->size() == 2);
+ CHECK(tbl["clients"]["hosts"][0] == "alpha"sv);
+ CHECK(tbl["clients"]["hosts"][1] == "omega"sv);
+ });
+}
diff --git a/tomlplusplus/tests/parsing_strings.cpp b/tomlplusplus/tests/parsing_strings.cpp
new file mode 100644
index 0000000000..718fda019a
--- /dev/null
+++ b/tomlplusplus/tests/parsing_strings.cpp
@@ -0,0 +1,211 @@
+// This file is a part of toml++ and is subject to the the terms of the MIT license.
+// Copyright (c) Mark Gillard <mark.gillard@outlook.com.au>
+// See https://github.com/marzer/tomlplusplus/blob/master/LICENSE for the full license text.
+// SPDX-License-Identifier: MIT
+
+#include "tests.hpp"
+
+TEST_CASE("parsing - strings")
+{
+ parsing_should_succeed(FILE_LINE_ARGS,
+ R"(
+str = "I'm a string. \"You can quote me\". Name\tJos\u00E9\nLocation\tSF."
+
+str1 = """
+Roses are red
+Violets are blue"""
+
+str2 = """
+
+Roses are red
+Violets are blue"""
+)"sv,
+ [](table&& tbl)
+ {
+ CHECK(tbl["str"]
+ == "I'm a string. \"You can quote me\". Name\tJos\u00E9\nLocation\tSF."sv);
+ CHECK(tbl["str1"] == "Roses are red\nViolets are blue"sv);
+ CHECK(tbl["str2"] == "\nRoses are red\nViolets are blue"sv);
+ });
+
+ parsing_should_succeed(FILE_LINE_ARGS,
+ R"(
+# The following strings are byte-for-byte equivalent:
+str1 = "The quick brown fox jumps over the lazy dog."
+
+str2 = """
+The quick brown \
+
+
+ fox jumps over \
+ the lazy dog."""
+
+str3 = """\
+ The quick brown \
+ fox jumps over \
+ the lazy dog.\
+ """
+
+str4 = """Here are two quotation marks: "". Simple enough."""
+# str5 = """Here are three quotation marks: """.""" # INVALID
+str5 = """Here are three quotation marks: ""\"."""
+str6 = """Here are fifteen quotation marks: ""\"""\"""\"""\"""\"."""
+
+# "This," she said, "is just a pointless statement."
+str7 = """"This," she said, "is just a pointless statement.""""
+)"sv,
+ [](table&& tbl)
+ {
+ static constexpr auto quick_brown_fox = "The quick brown fox jumps over the lazy dog."sv;
+ CHECK(tbl["str1"] == quick_brown_fox);
+ CHECK(tbl["str2"] == quick_brown_fox);
+ CHECK(tbl["str3"] == quick_brown_fox);
+ CHECK(tbl["str4"] == R"(Here are two quotation marks: "". Simple enough.)"sv);
+ CHECK(tbl["str5"] == R"(Here are three quotation marks: """.)"sv);
+ CHECK(tbl["str6"] == R"(Here are fifteen quotation marks: """"""""""""""".)"sv);
+ CHECK(tbl["str7"] == R"("This," she said, "is just a pointless statement.")"sv);
+ });
+
+ parsing_should_fail(FILE_LINE_ARGS, R"(str5 = """Here are three quotation marks: """.""")"sv);
+
+ parsing_should_succeed(FILE_LINE_ARGS,
+ R"(
+# What you see is what you get.
+winpath = 'C:\Users\nodejs\templates'
+winpath2 = '\\ServerX\admin$\system32\'
+quoted = 'Tom "Dubs" Preston-Werner'
+regex = '<\i\c*\s*>'
+regex2 = '''I [dw]on't need \d{2} apples'''
+lines = '''
+The first newline is
+trimmed in raw strings.
+ All other whitespace
+ is preserved.
+'''
+lines2 = '''
+
+The first newline is
+trimmed in raw strings.
+ All other whitespace
+ is preserved.
+'''
+)"sv,
+ [](table&& tbl)
+ {
+ CHECK(tbl["winpath"] == R"(C:\Users\nodejs\templates)"sv);
+ CHECK(tbl["winpath2"] == R"(\\ServerX\admin$\system32\)"sv);
+ CHECK(tbl["quoted"] == R"(Tom "Dubs" Preston-Werner)"sv);
+ CHECK(tbl["regex"] == R"(<\i\c*\s*>)"sv);
+ CHECK(tbl["regex2"] == R"(I [dw]on't need \d{2} apples)"sv);
+ CHECK(tbl["lines"] == R"(The first newline is
+trimmed in raw strings.
+ All other whitespace
+ is preserved.
+)"sv);
+ CHECK(tbl["lines2"] == R"(
+The first newline is
+trimmed in raw strings.
+ All other whitespace
+ is preserved.
+)"sv);
+ });
+
+ parsing_should_succeed(FILE_LINE_ARGS,
+ R"(
+quot15 = '''Here are fifteen quotation marks: """""""""""""""'''
+
+# apos15 = '''Here are fifteen apostrophes: '''''''''''''''''' # INVALID
+apos15 = "Here are fifteen apostrophes: '''''''''''''''"
+
+# 'That's still pointless', she said.
+str = ''''That's still pointless', she said.'''
+)"sv,
+ [](table&& tbl)
+ {
+ CHECK(tbl["quot15"] == R"(Here are fifteen quotation marks: """"""""""""""")"sv);
+ CHECK(tbl["apos15"] == R"(Here are fifteen apostrophes: ''''''''''''''')"sv);
+ CHECK(tbl["str"] == R"('That's still pointless', she said.)"sv);
+ });
+
+ parsing_should_fail(FILE_LINE_ARGS, R"(apos15 = '''Here are fifteen apostrophes: '''''''''''''''''' # INVALID)"sv);
+
+ // value tests
+ parse_expected_value(FILE_LINE_ARGS,
+ R"("The quick brown fox jumps over the lazy dog")"sv,
+ "The quick brown fox jumps over the lazy dog"sv);
+ parse_expected_value(FILE_LINE_ARGS,
+ R"('The quick brown fox jumps over the lazy dog')"sv,
+ "The quick brown fox jumps over the lazy dog"sv);
+ parse_expected_value(FILE_LINE_ARGS,
+ R"("""The quick brown fox jumps over the lazy dog""")"sv,
+ "The quick brown fox jumps over the lazy dog"sv);
+ parse_expected_value(FILE_LINE_ARGS,
+ R"('''The quick brown fox jumps over the lazy dog''')"sv,
+ "The quick brown fox jumps over the lazy dog"sv);
+
+#if UNICODE_LITERALS_OK
+ parse_expected_value(FILE_LINE_ARGS, R"("Ýôú'ℓℓ λáƭè ₥è áƒƭèř ƭλïƨ - #")"sv, R"(Ýôú'ℓℓ λáƭè ₥è áƒƭèř ƭλïƨ - #)"sv);
+ parse_expected_value(FILE_LINE_ARGS,
+ R"(" Âñδ ωλèñ \"'ƨ ářè ïñ ƭλè ƨƭřïñϱ, áℓôñϱ ωïƭλ # \"")"sv,
+ R"( Âñδ ωλèñ "'ƨ ářè ïñ ƭλè ƨƭřïñϱ, áℓôñϱ ωïƭλ # ")"sv);
+ parse_expected_value(FILE_LINE_ARGS,
+ R"("Ýôú δôñ'ƭ ƭλïñƙ ƨô₥è úƨèř ωôñ'ƭ δô ƭλáƭ?")"sv,
+ R"(Ýôú δôñ'ƭ ƭλïñƙ ƨô₥è úƨèř ωôñ'ƭ δô ƭλáƭ?)"sv);
+#endif // UNICODE_LITERALS_OK
+
+ parse_expected_value(FILE_LINE_ARGS, R"("\"\u03B1\u03B2\u03B3\"")"sv, "\"\u03B1\u03B2\u03B3\""sv);
+
+// toml/pull/796 (\xHH unicode scalars)
+#if TOML_LANG_UNRELEASED
+ parse_expected_value(FILE_LINE_ARGS,
+ R"("\x00\x10\x20\x30\x40\x50\x60\x70\x80\x90\x11\xFF\xEE")"sv,
+ "\u0000\u0010\u0020\u0030\u0040\u0050\u0060\u0070\u0080\u0090\u0011\u00FF\u00EE"sv);
+#else
+ parsing_should_fail(FILE_LINE_ARGS, R"(str = "\x00\x10\x20\x30\x40\x50\x60\x70\x80\x90\x11\xFF\xEE")"sv);
+#endif
+
+ // toml/pull/790
+#if TOML_LANG_UNRELEASED
+ parse_expected_value(FILE_LINE_ARGS, R"("\e[31mfoo\e[0m")"sv, "\x1B[31mfoo\x1B[0m"sv);
+
+#else
+ parsing_should_fail(FILE_LINE_ARGS, R"("\e[31mfoo\e[0m")"sv);
+#endif
+
+ // check 8-digit \U scalars with insufficient digits
+ parsing_should_fail(FILE_LINE_ARGS, R"(str = "\U1234567")"sv);
+ parsing_should_fail(FILE_LINE_ARGS, R"(str = "\U123456")"sv);
+ parsing_should_fail(FILE_LINE_ARGS, R"(str = "\U12345")"sv);
+ parsing_should_fail(FILE_LINE_ARGS, R"(str = "\U1234")"sv);
+ parsing_should_fail(FILE_LINE_ARGS, R"(str = "\U123")"sv);
+ parsing_should_fail(FILE_LINE_ARGS, R"(str = "\U12")"sv);
+ parsing_should_fail(FILE_LINE_ARGS, R"(str = "\U1")"sv);
+
+ // check 4-digit \u scalars with insufficient digits
+ parsing_should_fail(FILE_LINE_ARGS, R"(str = "\u123")"sv);
+ parsing_should_fail(FILE_LINE_ARGS, R"(str = "\u12")"sv);
+ parsing_should_fail(FILE_LINE_ARGS, R"(str = "\u1")"sv);
+
+ // check 2-digit \x scalars with insufficient digits
+ parsing_should_fail(FILE_LINE_ARGS, R"(str = "\x1")"sv);
+
+ // ML string examples from https://github.com/toml-lang/toml/issues/725
+ parse_expected_value(FILE_LINE_ARGS, R"( """ """ )"sv, R"( )"sv);
+ parse_expected_value(FILE_LINE_ARGS, R"( """ """" )"sv, R"( ")"sv);
+ parse_expected_value(FILE_LINE_ARGS, R"( """ """"" )"sv, R"( "")"sv);
+ parsing_should_fail(FILE_LINE_ARGS, R"(v= """ """""" )"sv);
+ parse_expected_value(FILE_LINE_ARGS, R"( ''' ''' )"sv, R"( )"sv);
+ parse_expected_value(FILE_LINE_ARGS, R"( ''' '''' )"sv, R"( ')"sv);
+ parse_expected_value(FILE_LINE_ARGS, R"( ''' ''''' )"sv, R"( '')"sv);
+ parsing_should_fail(FILE_LINE_ARGS, R"(v= ''' '''''' )"sv);
+ parse_expected_value(FILE_LINE_ARGS, R"( """""" )"sv, R"()"sv);
+ parse_expected_value(FILE_LINE_ARGS, R"( """" """ )"sv, R"(" )"sv);
+ parse_expected_value(FILE_LINE_ARGS, R"( """"" """ )"sv, R"("" )"sv);
+ parsing_should_fail(FILE_LINE_ARGS, R"(v= """""" """ )"sv);
+ parse_expected_value(FILE_LINE_ARGS, R"( '''''' )"sv, R"()"sv);
+ parse_expected_value(FILE_LINE_ARGS, R"( '''' ''' )"sv, R"(' )"sv);
+ parse_expected_value(FILE_LINE_ARGS, R"( ''''' ''' )"sv, R"('' )"sv);
+ parsing_should_fail(FILE_LINE_ARGS, R"(v= '''''' ''' )"sv);
+ parse_expected_value(FILE_LINE_ARGS, R"( """""\"""""" )"sv, R"(""""")"sv);
+ parse_expected_value(FILE_LINE_ARGS, R"( """""\"""\"""""" )"sv, R"("""""""")"sv);
+}
diff --git a/tomlplusplus/tests/parsing_tables.cpp b/tomlplusplus/tests/parsing_tables.cpp
new file mode 100644
index 0000000000..417427e579
--- /dev/null
+++ b/tomlplusplus/tests/parsing_tables.cpp
@@ -0,0 +1,595 @@
+// This file is a part of toml++ and is subject to the the terms of the MIT license.
+// Copyright (c) Mark Gillard <mark.gillard@outlook.com.au>
+// See https://github.com/marzer/tomlplusplus/blob/master/LICENSE for the full license text.
+// SPDX-License-Identifier: MIT
+
+#include "tests.hpp"
+
+TEST_CASE("parsing - tables")
+{
+ // these are the examples from https://toml.io/en/v1.0.0#table
+
+ // "Tables are defined by headers, with square brackets on a line by themselves."
+ parsing_should_succeed(FILE_LINE_ARGS,
+ "[table]"sv,
+ [](table&& tbl)
+ {
+ REQUIRE(tbl["table"].as_table());
+ CHECK(tbl["table"].as_table()->empty());
+ CHECK(tbl["table"].as_table()->size() == 0u);
+ });
+ parsing_should_fail(FILE_LINE_ARGS, "[]"sv);
+
+ // "Under that, and until the next header or EOF, are the key/values of that table.
+ // Key/value pairs within tables are not guaranteed to be in any specific order."
+ parsing_should_succeed(FILE_LINE_ARGS,
+ R"(
+ [table-1]
+ key1 = "some string"
+ key2 = 123
+
+ [table-2]
+ key1 = "another string"
+ key2 = 456
+ )"sv,
+ [](table&& tbl)
+ {
+ REQUIRE(tbl["table-1"].as_table());
+ CHECK(tbl["table-1"].as_table()->size() == 2u);
+ CHECK(tbl["table-1"]["key1"] == "some string"sv);
+ CHECK(tbl["table-1"]["key2"] == 123);
+
+ REQUIRE(tbl["table-2"].as_table());
+ CHECK(tbl["table-2"].as_table()->size() == 2u);
+ CHECK(tbl["table-2"]["key1"] == "another string"sv);
+ CHECK(tbl["table-2"]["key2"] == 456);
+ });
+
+ // "Naming rules for tables are the same as for keys." (i.e. can be quoted)
+ parsing_should_succeed(FILE_LINE_ARGS,
+ R"(
+ [dog."tater.man"]
+ type.name = "pug"
+ )"sv,
+ [](table&& tbl)
+ {
+ REQUIRE(tbl["dog"].as_table());
+ CHECK(tbl["dog"].as_table()->size() == 1u);
+
+ REQUIRE(tbl["dog"]["tater.man"].as_table());
+ CHECK(tbl["dog"]["tater.man"].as_table()->size() == 1u);
+ CHECK(tbl["dog"]["tater.man"]["type"]["name"] == "pug"sv);
+ });
+
+ // "Whitespace around the key is ignored. However, best practice is to not use any extraneous whitespace."
+ parsing_should_succeed(FILE_LINE_ARGS,
+ R"(
+ [a.b.c] # this is best practice
+ [ d.e.f ] # same as [d.e.f]
+ [ g . h . i ] # same as [g.h.i]
+ [ j . "k" . 'l' ] # same as [j."k".'l']
+ )"sv,
+ [](table&& tbl)
+ {
+ CHECK(tbl["a"].as_table());
+ CHECK(tbl["a"]["b"].as_table());
+ CHECK(tbl["a"]["b"]["c"].as_table());
+
+ CHECK(tbl["d"].as_table());
+ CHECK(tbl["d"]["e"].as_table());
+ CHECK(tbl["d"]["e"]["f"].as_table());
+
+ CHECK(tbl["g"].as_table());
+ CHECK(tbl["g"]["h"].as_table());
+ CHECK(tbl["g"]["h"]["i"].as_table());
+
+ CHECK(tbl["j"].as_table());
+ CHECK(tbl["j"]["k"].as_table());
+ CHECK(tbl["j"]["k"]["l"].as_table());
+ });
+
+ // "You don't need to specify all the super-tables if you don't want to. TOML knows how to do it for you."
+ parsing_should_succeed(FILE_LINE_ARGS,
+ R"(
+ # [x] you
+ # [x.y] don't
+ # [x.y.z] need these
+ [x.y.z.w] # for this to work
+
+ [x] # defining a super-table afterwards is ok
+ )"sv,
+ [](table&& tbl)
+ {
+ CHECK(tbl["x"].as_table());
+ CHECK(tbl["x"]["y"].as_table());
+ CHECK(tbl["x"]["y"]["z"].as_table());
+ CHECK(tbl["x"]["y"]["z"]["w"].as_table());
+ });
+
+ // "Like keys, you cannot define a table more than once. Doing so is invalid."
+ parsing_should_fail(FILE_LINE_ARGS, R"(
+ # DO NOT DO THIS
+
+ [fruit]
+ apple = "red"
+
+ [fruit]
+ orange = "orange"
+ )"sv);
+ parsing_should_fail(FILE_LINE_ARGS, R"(
+ # DO NOT DO THIS EITHER
+
+ [fruit]
+ apple = "red"
+
+ [fruit.apple]
+ texture = "smooth"
+ )"sv);
+
+ // "Defining tables out-of-order is discouraged."
+ parsing_should_succeed(FILE_LINE_ARGS,
+ R"(
+ # VALID BUT DISCOURAGED
+ [fruit.apple]
+ [animal]
+ [fruit.orange]
+ )"sv,
+ [](table&& tbl)
+ {
+ CHECK(tbl["fruit"].as_table());
+ CHECK(tbl["fruit"]["apple"].as_table());
+ CHECK(tbl["animal"].as_table());
+ CHECK(tbl["fruit"]["orange"].as_table());
+ });
+ parsing_should_succeed(FILE_LINE_ARGS,
+ R"(
+ # RECOMMENDED
+ [fruit.apple]
+ [fruit.orange]
+ [animal]
+ )"sv,
+ [](table&& tbl)
+ {
+ CHECK(tbl["fruit"].as_table());
+ CHECK(tbl["fruit"]["apple"].as_table());
+ CHECK(tbl["fruit"]["orange"].as_table());
+ CHECK(tbl["animal"].as_table());
+ });
+
+ // "The top-level table, also called the root table, starts at the beginning of the document
+ // and ends just before the first table header (or EOF)."
+ parsing_should_succeed(FILE_LINE_ARGS,
+ R"(
+ # Top-level table begins.
+ name = "Fido"
+ breed = "pug"
+
+ # Top-level table ends.
+ [owner]
+ name = "Regina Dogman"
+ member_since = 1999-08-04
+ )"sv,
+ [](table&& tbl)
+ {
+ CHECK(tbl["name"].as_string());
+ CHECK(*tbl["name"].as_string() == "Fido"sv);
+ CHECK(tbl["breed"].as_string());
+ CHECK(*tbl["breed"].as_string() == "pug"sv);
+
+ CHECK(tbl["owner"].as_table());
+ CHECK(*tbl["owner"]["name"].as_string() == "Regina Dogman"sv);
+
+ static constexpr auto member_since = toml::date{ 1999, 8, 4 };
+ CHECK(*tbl["owner"]["member_since"].as_date() == member_since);
+ });
+
+ // "Dotted keys create and define a table for each key part before the last one,
+ // provided that such tables were not previously created."
+ parsing_should_succeed(FILE_LINE_ARGS,
+ R"(
+ fruit.apple.color = "red"
+ # Defines a table named fruit
+ # Defines a table named fruit.apple
+
+ fruit.apple.taste.sweet = true
+ # Defines a table named fruit.apple.taste
+ # fruit and fruit.apple were already created
+ )"sv,
+ [](table&& tbl)
+ {
+ CHECK(tbl["fruit"].as_table());
+ CHECK(tbl["fruit"]["apple"].as_table());
+ CHECK(tbl["fruit"]["apple"]["color"].as_string());
+ CHECK(*tbl["fruit"]["apple"]["color"].as_string() == "red"sv);
+
+ CHECK(tbl["fruit"]["apple"]["taste"].as_table());
+ CHECK(tbl["fruit"]["apple"]["taste"]["sweet"].as_boolean());
+ CHECK(*tbl["fruit"]["apple"]["taste"]["sweet"].as_boolean() == true);
+ });
+
+ // "Since tables cannot be defined more than once, redefining such tables using a [table] header is not allowed."
+ parsing_should_fail(FILE_LINE_ARGS, R"(
+ [fruit]
+ apple.color = "red"
+ apple.taste.sweet = true
+
+ [fruit.apple] # INVALID
+ )"sv);
+ parsing_should_fail(FILE_LINE_ARGS, R"(
+ [fruit]
+ apple.color = "red"
+ apple.taste.sweet = true
+
+ [fruit.apple.taste] # INVALID
+ )"sv);
+
+ // "Likewise, using dotted keys to redefine tables already defined in [table] form is not allowed."
+ parsing_should_fail(FILE_LINE_ARGS, R"(
+ [fruit.apple.taste]
+ sweet = true
+
+ [fruit]
+ apple.taste = { sweet = false } # INVALID
+ )"sv);
+ parsing_should_fail(FILE_LINE_ARGS, R"(
+ [fruit.apple.taste]
+ sweet = true
+
+ [fruit]
+ apple.taste.foo = "bar" # INVALID
+ )"sv);
+
+ // "The [table] form can, however, be used to define sub-tables within tables defined via dotted keys."
+ parsing_should_succeed(FILE_LINE_ARGS,
+ R"(
+ [fruit]
+ apple.color = "red"
+ apple.taste.sweet = true
+
+ [fruit.apple.texture] # you can add sub-tables
+ smooth = true
+ )"sv,
+ [](table&& tbl)
+ {
+ CHECK(tbl["fruit"].as_table());
+ CHECK(tbl["fruit"]["apple"].as_table());
+ CHECK(tbl["fruit"]["apple"]["color"].as_string());
+ CHECK(*tbl["fruit"]["apple"]["color"].as_string() == "red"sv);
+
+ CHECK(tbl["fruit"]["apple"]["texture"].as_table());
+ CHECK(tbl["fruit"]["apple"]["texture"]["smooth"].as_boolean());
+ CHECK(*tbl["fruit"]["apple"]["texture"]["smooth"].as_boolean() == true);
+ });
+ parsing_should_fail(FILE_LINE_ARGS, R"(
+ [fruit]
+ apple.color = "red"
+ apple.taste.sweet = true
+
+ [fruit.apple]
+ shape = "round"
+
+ [fruit.apple.texture]
+ smooth = true
+ )"sv);
+
+ // same as above but the table order is reversed.
+ // see: https://github.com/toml-lang/toml/issues/769
+ parsing_should_succeed(FILE_LINE_ARGS,
+ R"(
+ [fruit.apple.texture]
+ smooth = true
+
+ [fruit]
+ apple.color = "red"
+ apple.taste.sweet = true
+ )"sv,
+ [](table&& tbl)
+ {
+ CHECK(tbl["fruit"].as_table());
+ CHECK(tbl["fruit"]["apple"].as_table());
+ CHECK(tbl["fruit"]["apple"]["color"].as_string());
+ CHECK(*tbl["fruit"]["apple"]["color"].as_string() == "red"sv);
+
+ CHECK(tbl["fruit"]["apple"]["texture"].as_table());
+ CHECK(tbl["fruit"]["apple"]["texture"]["smooth"].as_boolean());
+ CHECK(*tbl["fruit"]["apple"]["texture"]["smooth"].as_boolean() == true);
+ });
+}
+
+TEST_CASE("parsing - inline tables")
+{
+ // these are the examples from https://toml.io/en/v1.0.0#inline-table
+
+ parsing_should_succeed(FILE_LINE_ARGS,
+ R"(
+ name = { first = "Tom", last = "Preston-Werner" }
+ point = { x = 1, y = 2 }
+ animal = { type.name = "pug" }
+ )"sv,
+ [](table&& tbl)
+ {
+ REQUIRE(tbl["name"].as_table());
+ CHECK(tbl["name"].as_table()->size() == 2u);
+ CHECK(tbl["name"].as_table()->is_inline());
+ CHECK(tbl["name"]["first"] == "Tom"sv);
+ CHECK(tbl["name"]["last"] == "Preston-Werner"sv);
+
+ REQUIRE(tbl["point"].as_table());
+ CHECK(tbl["point"].as_table()->size() == 2u);
+ CHECK(tbl["point"].as_table()->is_inline());
+ CHECK(tbl["point"]["x"] == 1);
+ CHECK(tbl["point"]["y"] == 2);
+
+ REQUIRE(tbl["animal"].as_table());
+ CHECK(tbl["animal"].as_table()->size() == 1u);
+ CHECK(tbl["animal"].as_table()->is_inline());
+ REQUIRE(tbl["animal"]["type"].as_table());
+ CHECK(tbl["animal"]["type"].as_table()->size() == 1u);
+ CHECK(tbl["animal"]["type"]["name"] == "pug"sv);
+ });
+
+ // "Inline tables are fully self-contained and define all keys and sub-tables within them.
+ // Keys and sub-tables cannot be added outside the braces."
+ parsing_should_fail(FILE_LINE_ARGS, R"(
+ [product]
+ type = { name = "Nail" }
+ type.edible = false # INVALID
+ )"sv);
+
+ // "Similarly, inline tables cannot be used to add keys or sub-tables to an already-defined table."
+ parsing_should_fail(FILE_LINE_ARGS, R"(
+ [product]
+ type.name = "Nail"
+ type = { edible = false } # INVALID
+ )"sv);
+
+ // "newlines are allowed between the curly braces [if] they are valid within a value."
+ parsing_should_succeed(FILE_LINE_ARGS,
+ R"(
+ test = { val1 = "foo", val2 = [
+ 1, 2,
+ 3
+ ], val3 = "bar" }
+ )"sv,
+ [](table&& tbl)
+ {
+ REQUIRE(tbl["test"].as_table());
+ CHECK(tbl["test"].as_table()->size() == 3u);
+ CHECK(tbl["test"]["val1"] == "foo"sv);
+ REQUIRE(tbl["test"]["val2"].as<array>());
+ CHECK(tbl["test"]["val2"].as<array>()->size() == 3u);
+ CHECK(tbl["test"]["val2"][0] == 1);
+ CHECK(tbl["test"]["val2"][1] == 2);
+ CHECK(tbl["test"]["val2"][2] == 3);
+ CHECK(tbl["test"]["val3"] == "bar"sv);
+ });
+
+// toml/issues/516 (newlines/trailing commas in inline tables)
+#if TOML_LANG_UNRELEASED
+ {
+ parsing_should_succeed(FILE_LINE_ARGS,
+ R"(
+ name = {
+ first = "Tom",
+ last = "Preston-Werner",
+ }
+ )"sv,
+ [](table&& tbl)
+ {
+ REQUIRE(tbl["name"].as_table());
+ CHECK(tbl["name"].as_table()->size() == 2u);
+ CHECK(tbl["name"]["first"] == "Tom"sv);
+ CHECK(tbl["name"]["last"] == "Preston-Werner"sv);
+ });
+ }
+#else
+ {
+ // "A terminating comma (also called trailing comma) is not permitted after the last key/value pair in an inline
+ // table."
+ parsing_should_fail(FILE_LINE_ARGS, R"(name = { first = "Tom", last = "Preston-Werner", })"sv);
+
+ // "No newlines are allowed between the curly braces unless they are valid within a value."
+ parsing_should_fail(FILE_LINE_ARGS, R"(
+ name = {
+ first = "Tom",
+ last = "Preston-Werner"
+ }
+ )"sv);
+ }
+#endif
+}
+
+TEST_CASE("parsing - arrays-of-tables")
+{
+ parsing_should_succeed(FILE_LINE_ARGS,
+ R"(
+ points = [ { x = 1, y = 2, z = 3 },
+ { x = 7, y = 8, z = 9 },
+ { x = 2, y = 4, z = 8 } ]
+
+ [[products]]
+ name = "Hammer"
+ sku = 738594937
+
+ [[products]]
+
+ [[products]]
+ name = "Nail"
+ sku = 284758393
+
+ color = "gray"
+
+ [[fruit]]
+ name = "apple"
+
+ [fruit.physical] # subtable
+ color = "red"
+ shape = "round"
+
+ [[fruit.variety]] # nested array of tables
+ name = "red delicious"
+
+ [[fruit.variety]]
+ name = "granny smith"
+
+ [[fruit]]
+ name = "banana"
+
+ [[fruit.variety]]
+ name = "plantain"
+
+ )"sv,
+ [](table&& tbl)
+ {
+ REQUIRE(tbl["points"].as<array>());
+ CHECK(tbl["points"].as<array>()->size() == 3u);
+ CHECK(tbl["points"].as<array>()->is_homogeneous());
+ CHECK(tbl["points"].as<array>()->is_array_of_tables());
+ CHECK(tbl["points"][0]["x"] == 1);
+ CHECK(tbl["points"][0]["y"] == 2);
+ CHECK(tbl["points"][0]["z"] == 3);
+ CHECK(tbl["points"][1]["x"] == 7);
+ CHECK(tbl["points"][1]["y"] == 8);
+ CHECK(tbl["points"][1]["z"] == 9);
+ CHECK(tbl["points"][2]["x"] == 2);
+ CHECK(tbl["points"][2]["y"] == 4);
+ CHECK(tbl["points"][2]["z"] == 8);
+
+ REQUIRE(tbl["products"].as<array>());
+ CHECK(tbl["products"].as<array>()->size() == 3u);
+ CHECK(tbl["products"].as<array>()->is_homogeneous());
+ CHECK(tbl["products"].as<array>()->is_array_of_tables());
+
+ REQUIRE(tbl["products"][0].as_table());
+ CHECK(tbl["products"][0].as_table()->size() == 2u);
+ CHECK(tbl["products"][0]["name"] == "Hammer"sv);
+ CHECK(tbl["products"][0]["sku"] == 738594937);
+
+ REQUIRE(tbl["products"][1].as_table());
+ CHECK(tbl["products"][1].as_table()->size() == 0u);
+
+ REQUIRE(tbl["products"][2].as_table());
+ CHECK(tbl["products"][2].as_table()->size() == 3u);
+ CHECK(tbl["products"][2]["name"] == "Nail"sv);
+ CHECK(tbl["products"][2]["sku"] == 284758393);
+ CHECK(tbl["products"][2]["color"] == "gray"sv);
+
+ REQUIRE(tbl["fruit"].as<array>());
+ CHECK(tbl["fruit"].as<array>()->size() == 2u);
+ CHECK(tbl["fruit"].as<array>()->is_homogeneous());
+ CHECK(tbl["fruit"].as<array>()->is_array_of_tables());
+
+ REQUIRE(tbl["fruit"][0].as_table());
+ CHECK(tbl["fruit"][0].as_table()->size() == 3u);
+ CHECK(tbl["fruit"][0]["name"] == "apple"sv);
+
+ REQUIRE(tbl["fruit"][0]["physical"].as_table());
+ CHECK(tbl["fruit"][0]["physical"].as_table()->size() == 2u);
+ CHECK(tbl["fruit"][0]["physical"]["color"] == "red"sv);
+ CHECK(tbl["fruit"][0]["physical"]["shape"] == "round"sv);
+
+ REQUIRE(tbl["fruit"][0]["variety"].as<array>());
+ CHECK(tbl["fruit"][0]["variety"].as<array>()->size() == 2u);
+ CHECK(tbl["fruit"][0]["variety"].as<array>()->is_homogeneous());
+ CHECK(tbl["fruit"][0]["variety"].as<array>()->is_array_of_tables());
+ CHECK(tbl["fruit"][0]["variety"][0]["name"] == "red delicious"sv);
+ CHECK(tbl["fruit"][0]["variety"][1]["name"] == "granny smith"sv);
+
+ REQUIRE(tbl["fruit"][1].as_table());
+ CHECK(tbl["fruit"][1].as_table()->size() == 2u);
+ CHECK(tbl["fruit"][1]["name"] == "banana"sv);
+
+ REQUIRE(tbl["fruit"][1]["variety"].as<array>());
+ CHECK(tbl["fruit"][1]["variety"].as<array>()->size() == 1u);
+ CHECK(tbl["fruit"][1]["variety"].as<array>()->is_homogeneous());
+ CHECK(tbl["fruit"][1]["variety"].as<array>()->is_array_of_tables());
+ CHECK(tbl["fruit"][1]["variety"][0]["name"] == "plantain"sv);
+ });
+
+ parsing_should_fail(FILE_LINE_ARGS, R"(
+# INVALID TOML DOC
+[fruit.physical] # subtable, but to which parent element should it belong?
+ color = "red"
+ shape = "round"
+
+[[fruit]] # parser must throw an error upon discovering that "fruit" is
+ # an array rather than a table
+ name = "apple"
+)"sv);
+
+ parsing_should_fail(FILE_LINE_ARGS, R"(
+# INVALID TOML DOC
+fruit = []
+
+[[fruit]] # Not allowed
+)"sv);
+
+ parsing_should_fail(FILE_LINE_ARGS, R"(
+# INVALID TOML DOC
+[[fruit]]
+ name = "apple"
+
+ [[fruit.variety]]
+ name = "red delicious"
+
+ # INVALID: This table conflicts with the previous array of tables
+ [fruit.variety]
+ name = "granny smith"
+)"sv);
+
+ parsing_should_fail(FILE_LINE_ARGS, R"(
+# INVALID TOML DOC
+[[fruit]]
+ name = "apple"
+
+ [fruit.physical]
+ color = "red"
+ shape = "round"
+
+ # INVALID: This array of tables conflicts with the previous table
+ [[fruit.physical]]
+ color = "green"
+)"sv);
+}
+
+TEST_CASE("parsing - keys")
+{
+ parsing_should_succeed(FILE_LINE_ARGS,
+ R"(
+[a.b]
+c = "10.0.0.1"
+d = "frontend"
+e = { f.g = 79.5, h = 72.0 }
+ )"sv,
+ [](table&& tbl)
+ {
+ // ensure types are sane first
+ REQUIRE(tbl["a"].is_table());
+ REQUIRE(tbl["a"]["b"].is_table());
+ REQUIRE(tbl["a"]["b"]["c"]);
+ REQUIRE(tbl["a"]["b"]["d"]);
+ REQUIRE(tbl["a"]["b"]["e"].is_table());
+ REQUIRE(tbl["a"]["b"]["e"]["f"].is_table());
+ REQUIRE(tbl["a"]["b"]["e"]["f"]["g"]);
+ REQUIRE(tbl["a"]["b"]["e"]["h"]);
+
+ const auto check_key =
+ [&](const auto& t, std::string_view k, source_position b, source_position e)
+ {
+ const toml::key& found_key = t.as_table()->find(k)->first;
+ CHECK(found_key.str() == k);
+ CHECK(found_key.source().begin == b);
+ CHECK(found_key.source().end == e);
+ CHECK(found_key.source().path == tbl.source().path);
+ };
+
+ check_key(tbl, "a", { 2, 2 }, { 2, 3 });
+ check_key(tbl["a"], "b", { 2, 4 }, { 2, 5 });
+ check_key(tbl["a"]["b"], "c", { 3, 1 }, { 3, 2 });
+ check_key(tbl["a"]["b"], "d", { 4, 1 }, { 4, 2 });
+ check_key(tbl["a"]["b"], "e", { 5, 1 }, { 5, 2 });
+ check_key(tbl["a"]["b"]["e"], "f", { 5, 7 }, { 5, 8 });
+ check_key(tbl["a"]["b"]["e"]["f"], "g", { 5, 9 }, { 5, 10 });
+ check_key(tbl["a"]["b"]["e"], "h", { 5, 19 }, { 5, 20 });
+ });
+}
diff --git a/tomlplusplus/tests/path.cpp b/tomlplusplus/tests/path.cpp
new file mode 100644
index 0000000000..be8131a959
--- /dev/null
+++ b/tomlplusplus/tests/path.cpp
@@ -0,0 +1,592 @@
+// This file is a part of toml++ and is subject to the the terms of the MIT license.
+// Copyright (c) Mark Gillard <mark.gillard@outlook.com.au>
+// See https://github.com/marzer/tomlplusplus/blob/master/LICENSE for the full license text.
+// SPDX-License-Identifier: MIT
+
+#include "tests.hpp"
+TOML_DISABLE_SPAM_WARNINGS;
+
+TEST_CASE("path - parsing")
+{
+ SECTION("parsing")
+ {
+ CHECK(toml::path("").str() == "");
+ CHECK(toml::path("[1]").str() == "[1]");
+ CHECK(toml::path("[1][2]").str() == "[1][2]");
+ CHECK(toml::path(" [1][2]").str() == " [1][2]");
+ CHECK(toml::path("a. .b").str() == "a. .b");
+ CHECK(toml::path("test[23]").str() == "test[23]");
+ CHECK(toml::path("[ 120 ]").str() == "[120]");
+ CHECK(toml::path("[ 120\t\t]").str() == "[120]");
+ CHECK(toml::path("test.value").str() == "test.value");
+ CHECK(toml::path("test[0].value").str() == "test[0].value");
+ CHECK(toml::path("test[1][2]\t .value").str() == "test[1][2].value");
+ CHECK(toml::path("test[1]\t[2].value").str() == "test[1][2].value");
+ CHECK(toml::path(".test[1][2]\t ..value").str() == ".test[1][2]..value");
+
+#if TOML_ENABLE_WINDOWS_COMPAT
+
+ CHECK(toml::path(L"").str() == "");
+ CHECK(toml::path(L"[1]").str() == "[1]");
+ CHECK(toml::path(L"[1][2]").str() == "[1][2]");
+ CHECK(toml::path(L" [1][2]").str() == " [1][2]");
+ CHECK(toml::path(L"a. .b").str() == "a. .b");
+ CHECK(toml::path(L"test[23]").str() == "test[23]");
+ CHECK(toml::path(L"[ 120 ]").str() == "[120]");
+ CHECK(toml::path(L"[ 120\t\t]").str() == "[120]");
+ CHECK(toml::path(L"test.value").str() == "test.value");
+ CHECK(toml::path(L"test[0].value").str() == "test[0].value");
+ CHECK(toml::path(L"test[1][2]\t .value").str() == "test[1][2].value");
+ CHECK(toml::path(L"test[1]\t[2].value").str() == "test[1][2].value");
+ CHECK(toml::path(L".test[1][2]\t ..value").str() == ".test[1][2]..value");
+
+#endif // TOML_ENABLE_WINDOWS_COMPAT
+ }
+
+ SECTION("parsing - errors")
+ {
+ CHECK(!toml::path("test[][2].value"));
+ CHECK(!toml::path("test[ "));
+ CHECK(!toml::path("test[1]a.b"));
+ CHECK(!toml::path("test[1] a.b"));
+ CHECK(!toml::path("test[1a]"));
+ CHECK(!toml::path("test[a1]"));
+ CHECK(!toml::path("test[1!]"));
+ CHECK(!toml::path("test[!1]"));
+ CHECK(!toml::path("test[1 2]"));
+ CHECK(!toml::path("test[1.2]"));
+ CHECK(!toml::path("test[0.2]"));
+
+#if TOML_ENABLE_WINDOWS_COMPAT
+
+ CHECK(!toml::path(L"test[][2].value"));
+ CHECK(!toml::path(L"test[ "));
+ CHECK(!toml::path(L"test[1]a.b"));
+ CHECK(!toml::path(L"test[1] a.b"));
+ CHECK(!toml::path(L"test[1a]"));
+ CHECK(!toml::path(L"test[a1]"));
+ CHECK(!toml::path(L"test[1!]"));
+ CHECK(!toml::path(L"test[!1]"));
+ CHECK(!toml::path(L"test[1 2]"));
+ CHECK(!toml::path(L"test[1.2]"));
+ CHECK(!toml::path(L"test[0.2]"));
+
+#endif // TOML_ENABLE_WINDOWS_COMPAT
+ }
+
+ SECTION("parsing from literal")
+ {
+ auto p0 = "a.b.c[1][12]"_tpath;
+ CHECK(p0);
+ CHECK(p0.str() == "a.b.c[1][12]");
+
+ CHECK("ab.cd[1]"_tpath == toml::path("ab.cd[1]"));
+
+ CHECK(("an.invalid.path[a1]"_tpath).str() == "");
+ }
+}
+
+TEST_CASE("path - manipulating")
+{
+ SECTION("parent_node and truncation")
+ {
+ toml::path p0("");
+ CHECK(p0.parent().str() == "");
+
+ toml::path p1("start.middle.end");
+ CHECK(p1.parent().str() == "start.middle");
+ CHECK(p1.parent().parent().str() == "start");
+ CHECK(p1.parent().parent().parent().str() == "");
+ CHECK(p1.parent().parent().parent().parent().str() == "");
+
+ toml::path p2("[1][2][3]");
+ CHECK(p2.parent().str() == "[1][2]");
+ CHECK(p2.parent().parent().str() == "[1]");
+ CHECK(p2.parent().parent().parent().str() == "");
+
+ toml::path p3(".test");
+ CHECK(p3.parent().str() == "");
+
+ toml::path p4("test..");
+ CHECK(p4.parent().str() == "test.");
+ CHECK(p4.parent().parent().str() == "test");
+ CHECK(p4.parent().parent().parent().str() == "");
+
+ toml::path p5("test.key[12].subkey");
+ CHECK(p5.parent().str() == "test.key[12]");
+ CHECK(p5.parent().parent().str() == "test.key");
+ CHECK(p5.parent().parent().parent().str() == "test");
+ CHECK(p5.parent().parent().parent().parent().str() == "");
+
+ toml::path p6("test.key1.key2.key3.key4");
+ CHECK(p6.truncated(0).str() == "test.key1.key2.key3.key4");
+ CHECK(p6.truncated(1).str() == "test.key1.key2.key3");
+ CHECK(p6.truncated(4).str() == "test");
+ CHECK(p6.truncated(5).str() == "");
+ CHECK(p6.truncated(20).str() == "");
+ CHECK(p6.str() == "test.key1.key2.key3.key4");
+
+ p6.truncate(0);
+ CHECK(p6.str() == "test.key1.key2.key3.key4");
+ p6.truncate(2);
+ CHECK(p6.str() == "test.key1.key2");
+ p6.truncate(3);
+ CHECK(p6.str() == "");
+ }
+
+ SECTION("subpath")
+ {
+ toml::path p0("a.simple[1].path[2].object");
+
+ CHECK(p0.subpath(p0.begin() + 1, p0.begin() + 4).str() == "simple[1].path");
+ CHECK(p0.subpath(p0.begin() + 1, p0.end() - 1).str() == "simple[1].path[2]");
+ CHECK(p0.subpath(p0.begin(), p0.begin()).str() == "");
+ CHECK(p0.subpath(p0.begin(), p0.end() - 5).str() == "a");
+ CHECK(p0.subpath(p0.begin() + 2, p0.end() - 1).str() == "[1].path[2]");
+
+ CHECK(p0.subpath(p0.begin() + 5, p0.end() - 5).str() == "");
+ CHECK(!p0.subpath(p0.end(), p0.begin()));
+
+ CHECK(p0.subpath(1, 4).str() == "simple[1].path[2]");
+ CHECK(p0.subpath(0, 0).str() == "");
+ CHECK(p0.subpath(2, 0).str() == "");
+ CHECK(p0.subpath(2, 1).str() == "[1]");
+ }
+
+ SECTION("leaf")
+ {
+ toml::path p0("one.two.three.four.five");
+ CHECK(p0.leaf(0).str() == "");
+ CHECK(p0.leaf().str() == "five");
+ CHECK(p0.leaf(3).str() == "three.four.five");
+ CHECK(p0.leaf(5).str() == "one.two.three.four.five");
+ CHECK(p0.leaf(10).str() == "one.two.three.four.five");
+
+ toml::path p1("[10][2][30][4][50]");
+ CHECK(p1.leaf(0).str() == "");
+ CHECK(p1.leaf().str() == "[50]");
+ CHECK(p1.leaf(3).str() == "[30][4][50]");
+ CHECK(p1.leaf(5).str() == "[10][2][30][4][50]");
+ CHECK(p1.leaf(10).str() == "[10][2][30][4][50]");
+
+ toml::path p2("one[1].two.three[3]");
+ CHECK(p2.leaf(0).str() == "");
+ CHECK(p2.leaf().str() == "[3]");
+ CHECK(p2.leaf(3).str() == "two.three[3]");
+ CHECK(p2.leaf(4).str() == "[1].two.three[3]");
+ CHECK(p2.leaf(10).str() == "one[1].two.three[3]");
+ }
+
+ SECTION("append - string")
+ {
+ toml::path p0("start");
+ CHECK(p0.size() == 1u);
+ CHECK(p0.append("middle.end").str() == "start.middle.end");
+ CHECK(p0.append("[12]").str() == "start.middle.end[12]");
+
+ toml::path p1("");
+ CHECK(p1.size() == 1u);
+ p1.append("[1].key"sv);
+ CHECK(p1.size() == 3u);
+ CHECK(p1.str() == "[1].key"sv);
+
+#if TOML_ENABLE_WINDOWS_COMPAT
+
+ toml::path p2("start");
+ CHECK(p2.size() == 1u);
+ CHECK(p2.append(L"middle.end").str() == "start.middle.end");
+ CHECK(p2.append(L"[12]").str() == "start.middle.end[12]");
+
+ toml::path p3("");
+ CHECK(p3.append(L"[1].key").str() == "[1].key");
+
+#endif // TOML_ENABLE_WINDOWS_COMPAT
+
+ toml::path p4;
+ CHECK(p4.size() == 0u);
+ CHECK(p4.append("[1].key").str() == "[1].key");
+ }
+
+ SECTION("append - toml::path copy")
+ {
+ toml::path p0("start");
+ toml::path appendee1("middle.end");
+ toml::path appendee2("[12]");
+ CHECK(p0.append(appendee1).str() == "start.middle.end");
+ CHECK(p0.append(appendee2).str() == "start.middle.end[12]");
+
+ // Ensure copies and not moves
+ CHECK(appendee1.str() == "middle.end");
+ CHECK(appendee2.str() == "[12]");
+
+ toml::path p1("");
+ toml::path appendee3("[1].key");
+ CHECK(p1.append(appendee3).str() == "[1].key");
+
+ // Ensure copies and not moves
+ CHECK(appendee3.str() == "[1].key");
+ }
+
+ SECTION("append - toml::path move")
+ {
+ toml::path p0("start");
+ CHECK(p0.append(toml::path{ "middle.end" }).str() == "start.middle.end");
+ CHECK(p0.append(toml::path{ "[12]" }).str() == "start.middle.end[12]");
+
+ toml::path p1("");
+ CHECK(p1.size() == 1u);
+ CHECK(p1.append(toml::path{ "[1].key" }).str() == "[1].key");
+
+ toml::path p2;
+ CHECK(p2.size() == 0u);
+ CHECK(p2.append(toml::path{ "[1].key" }).str() == "[1].key");
+ }
+
+ SECTION("prepend - string")
+ {
+ toml::path p0("start");
+ CHECK(p0.prepend("middle.end").str() == "middle.end.start");
+ CHECK(p0.prepend("[12]").str() == "[12].middle.end.start");
+
+ toml::path p1;
+ CHECK(p1.prepend("[1].key").str() == "[1].key");
+
+ toml::path p2("");
+ CHECK(p2.prepend("[1].key").str() == "[1].key.");
+
+#if TOML_ENABLE_WINDOWS_COMPAT
+
+ toml::path p3("start");
+ CHECK(p3.prepend(L"middle.end").str() == "middle.end.start");
+ CHECK(p3.prepend(L"[12]").str() == "[12].middle.end.start");
+
+#endif // TOML_ENABLE_WINDOWS_COMPAT
+ }
+
+ SECTION("prepend - toml::path copy")
+ {
+ toml::path p0("start");
+ toml::path prependee1("middle.end");
+ toml::path prependee2("[12]");
+ CHECK(p0.prepend(prependee1).str() == "middle.end.start");
+ CHECK(p0.prepend(prependee2).str() == "[12].middle.end.start");
+
+ // Ensure copies and not moves
+ CHECK(prependee1.str() == "middle.end");
+ CHECK(prependee2.str() == "[12]");
+
+ toml::path p1;
+ toml::path prependee3("[1].key");
+ CHECK(p1.prepend(prependee3).str() == "[1].key");
+
+ // Ensure copies and not moves
+ CHECK(prependee3.str() == "[1].key");
+ }
+
+ SECTION("prepend - toml::path move")
+ {
+ toml::path p0("start");
+ CHECK(p0.prepend(toml::path("middle.end")).str() == "middle.end.start");
+ CHECK(p0.prepend(toml::path("[12]")).str() == "[12].middle.end.start");
+
+ toml::path p1;
+ CHECK(p1.prepend(toml::path("[1].key")).str() == "[1].key");
+ }
+
+ SECTION("alter components")
+ {
+ toml::path p0("start.mid[1][2].end");
+
+ p0[3] = std::size_t{ 13 };
+ CHECK(p0.str() == "start.mid[1][13].end");
+
+ p0[0] = 2u;
+ CHECK(p0.str() == "[2].mid[1][13].end");
+
+ p0[0] = 10;
+ CHECK(p0.str() == "[10].mid[1][13].end");
+
+ p0[3] = "newkey";
+ CHECK(p0.str() == "[10].mid[1].newkey.end");
+ }
+
+ SECTION("assign")
+ {
+ toml::path p0("start.mid[1][2].end");
+ p0.assign("test.key[1]");
+ CHECK(p0.str() == "test.key[1]");
+ p0.assign("");
+ CHECK(p0.str() == "");
+
+ toml::path p1("a.test.path[1]");
+ p1.assign("invalid[abc]");
+ CHECK(!p1);
+ CHECK(p1.str() == "");
+
+ toml::path p2("another[1].test.path");
+ p2.assign(toml::path("test"));
+ CHECK(p2.str() == "test");
+ p2.assign(toml::path(""));
+ CHECK(p2.str() == "");
+
+ toml::path p3("final.test[1]");
+ p3.assign(toml::path("invalid[abc"));
+ CHECK(!p3);
+ CHECK(p3.str() == "");
+
+#if TOML_ENABLE_WINDOWS_COMPAT
+
+ toml::path p4("start.mid[1][2].end");
+ p4.assign(L"test.key[1]");
+ CHECK(p4.str() == "test.key[1]");
+ p4.assign("");
+ CHECK(p4.str() == "");
+
+ toml::path p5("a.test.path[1]");
+ p5.assign("invalid[abc]");
+ CHECK(!p5);
+ CHECK(p5.str() == "");
+
+#endif // TOML_ENABLE_WINDOWS_COMPAT
+ }
+}
+
+TEST_CASE("path - operators")
+{
+ SECTION("object equality")
+ {
+ CHECK(toml::path("a.b.c") == toml::path("a.b.c"));
+ CHECK(toml::path("[1].a") == toml::path("[1].a"));
+
+ CHECK(toml::path("a.b.c") != toml::path("a.b"));
+ CHECK(toml::path("[1].b") != toml::path("[1].b.c"));
+ }
+
+ SECTION("string equality")
+ {
+ CHECK(toml::path("a.b.c") == "a.b.c");
+ CHECK(toml::path("[1].a") == "[1].a");
+
+ CHECK(toml::path("a.b.c") != "a.b");
+ CHECK(toml::path("[1].b") != "[1].b.c");
+
+#if TOML_ENABLE_WINDOWS_COMPAT
+
+ CHECK(toml::path("a.b.c") == L"a.b.c");
+ CHECK(toml::path("[1].a") == L"[1].a");
+
+ CHECK(toml::path("a.b.c") != L"a.b");
+ CHECK(toml::path("[1].b") != L"[1].b.c");
+
+#endif // TOML_ENABLE_WINDOWS_COMPAT
+ }
+
+ SECTION("arithmetic")
+ {
+ CHECK(toml::path("a.b.c") + "a[1]" == "a.b.c.a[1]");
+ CHECK((toml::path("a.b.c") + "a[1]") == "a.b.c.a[1]");
+
+ CHECK(toml::path("a.b.c") + toml::path("a[1]") == "a.b.c.a[1]");
+
+ toml::path p1("a.b");
+ toml::path p2("c[1]");
+ CHECK(p1 + p2 == "a.b.c[1]");
+
+ CHECK(p1 + "c[1]" == "a.b.c[1]");
+
+ CHECK("a.b" + p2 == "a.b.c[1]");
+
+#if TOML_ENABLE_WINDOWS_COMPAT
+
+ CHECK(toml::path("a.b.c") + L"a[1]" == "a.b.c.a[1]");
+
+ CHECK(p1 + L"c[1]" == "a.b.c[1]");
+
+ CHECK(L"a.b" + p2 == "a.b.c[1]");
+
+#endif // TOML_ENABLE_WINDOWS_COMPAT
+ }
+}
+
+TEST_CASE("path - misc")
+{
+ CHECK(toml::path{ "" }.str() == "");
+ CHECK(toml::path{ "a" }.str() == "a");
+ CHECK(toml::path{ "a.b" }.str() == "a.b");
+ CHECK(toml::path{ "a.b.c" }.str() == "a.b.c");
+ CHECK(toml::path{ ".a.b.c" }.str() == ".a.b.c");
+
+ CHECK(toml::path{}.empty());
+ CHECK(!toml::path{ "" }.empty());
+ CHECK(!toml::path{ "a" }.empty());
+
+ CHECK(static_cast<std::string>(toml::path("a.b[1]")) == "a.b[1]");
+ CHECK(static_cast<bool>(toml::path("a.b[1]")));
+ CHECK(!static_cast<bool>(toml::path("a.b[a b]")));
+
+#if TOML_ENABLE_WINDOWS_COMPAT
+
+ CHECK(static_cast<std::wstring>(toml::path("a.b[1]")) == L"a.b[1]");
+
+#endif
+}
+
+TEST_CASE("path - accessing")
+{
+ // clang-format off
+
+ const auto tbl = table
+ {
+ { ""sv, 0 }, // blank key
+ { "a"sv, 1 },
+ {
+ "b"sv,
+ array
+ {
+ 2,
+ array{ 3 },
+ table { { "c", 4 } }
+ },
+ },
+ { "d", table{ {"e", 5, }, {""sv, -1 } } }
+ };
+
+ // clang-format on
+
+ /*
+
+ # equivalent to the following TOML:
+
+ "" = 0
+ a = 1
+ b = [
+ 2,
+ [ 3 ],
+ { "c" = 4 }
+ ]
+ d = { "e" = 5, "" = -1 }
+
+ */
+
+ SECTION("table")
+ {
+ // this section uses the free function version of at_path
+
+ CHECK(tbl[""]);
+ CHECK(tbl[""] == at_path(tbl, toml::path("")));
+
+ CHECK(tbl["a"]);
+ CHECK(tbl["a"] == at_path(tbl, toml::path("a")));
+ CHECK(tbl["a"] != at_path(tbl, toml::path(".a"))); // equivalent to ""."a"
+ CHECK(!at_path(tbl, toml::path(".a")));
+
+ CHECK(tbl["b"]);
+ CHECK(tbl["b"] == at_path(tbl, toml::path("b")));
+
+ CHECK(tbl["b"][0]);
+ CHECK(tbl["b"][0] == at_path(tbl, toml::path("b[0]")));
+ CHECK(tbl["b"][0] == at_path(tbl, toml::path("b[0] ")));
+ CHECK(tbl["b"][0] == at_path(tbl, toml::path("b[ 0\t]"))); // whitespace is allowed inside array indexer
+
+ CHECK(tbl["b"][1]);
+ CHECK(tbl["b"][1] != tbl["b"][0]);
+ CHECK(tbl["b"][1] == at_path(tbl, toml::path("b[1]")));
+
+ CHECK(tbl["b"][1][0]);
+ CHECK(tbl["b"][1][0] == at_path(tbl, toml::path("b[1][0]")));
+ CHECK(tbl["b"][1][0] == at_path(tbl, toml::path("b[1] \t [0]"))); // whitespace is allowed after array
+ // indexers
+
+ CHECK(tbl["b"][2]["c"]);
+ CHECK(tbl["b"][2]["c"] == at_path(tbl, toml::path("b[2].c")));
+ CHECK(tbl["b"][2]["c"] == at_path(tbl, toml::path("b[2] \t.c"))); // whitespace is allowed after array
+ // indexers
+
+ CHECK(tbl["d"]);
+ CHECK(tbl["d"] == at_path(tbl, toml::path("d")));
+
+ CHECK(tbl["d"]["e"]);
+ CHECK(tbl["d"]["e"] == at_path(tbl, toml::path("d.e")));
+ CHECK(tbl["d"]["e"] != at_path(tbl, toml::path("d. e"))); // equivalent to "d"." e"
+ CHECK(!at_path(tbl, toml::path("d. e")));
+
+ CHECK(tbl["d"][""]);
+ CHECK(tbl["d"][""] == at_path(tbl, toml::path("d.")));
+
+ CHECK(!at_path(tbl, toml::path("has.missing.component")));
+ }
+
+ SECTION("array")
+ {
+ // this section uses the node_view member function version of at_path
+
+ auto arr = tbl["b"];
+
+ CHECK(tbl["b"][0]);
+ CHECK(tbl["b"][0] == arr.at_path(toml::path("[0]")));
+ CHECK(tbl["b"][0] == arr.at_path(toml::path("[0] ")));
+ CHECK(tbl["b"][0] == arr.at_path(toml::path("[ 0\t]"))); // whitespace is allowed inside array indexer
+
+ CHECK(tbl["b"][1]);
+ CHECK(tbl["b"][1].node() != arr[0].node());
+ CHECK(tbl["b"][1] == arr.at_path(toml::path("[1]")));
+
+ CHECK(tbl["b"][1][0]);
+ CHECK(tbl["b"][1][0] == arr.at_path(toml::path("[1][0]")));
+ CHECK(tbl["b"][1][0] == arr.at_path(toml::path("[1] \t [0]"))); // whitespace is allowed after array
+ // indexers
+
+ CHECK(tbl["b"][2]["c"]);
+ CHECK(tbl["b"][2]["c"] == arr.at_path(toml::path("[2].c")));
+ CHECK(tbl["b"][2]["c"] == arr.at_path(toml::path("[2] \t.c"))); // whitespace is allowed after array indexers
+
+ CHECK(!arr.at_path(toml::path("[3].missing.component")));
+ }
+
+ SECTION("indexing operator")
+ {
+ // this section uses the operator[] of table and node_view
+ CHECK(tbl[""]);
+ CHECK(tbl[""] == tbl[toml::path("")]);
+
+ CHECK(tbl["a"]);
+ CHECK(tbl["a"] == tbl[toml::path("a")]);
+ CHECK(tbl["a"] != tbl[toml::path(".a")]); // equivalent to ""."a"
+ CHECK(!tbl[toml::path(".a")]);
+
+ CHECK(tbl["b"]);
+ CHECK(tbl["b"] == tbl[toml::path("b")]);
+
+ CHECK(tbl["b"][0]);
+ CHECK(tbl["b"][0] == tbl[toml::path("b[0]")]);
+ CHECK(tbl["b"][0] == tbl[toml::path("b[0] ")]);
+ CHECK(tbl["b"][0] == tbl[toml::path("b[ 0\t]")]); // whitespace is allowed inside array indexer
+
+ CHECK(tbl["b"][1]);
+ CHECK(tbl["b"][1] != tbl[toml::path("b")][0]);
+ CHECK(tbl["b"][1] == tbl[toml::path("b[1]")]);
+
+ CHECK(tbl["b"][1][0]);
+ CHECK(tbl["b"][1][0] == tbl[toml::path("b[1]")][0]);
+ CHECK(tbl["b"][1][0] == tbl[toml::path("b[1] \t [0]")]); // whitespace is allowed after array
+ // indexers
+
+ CHECK(tbl["b"][2]["c"]);
+ CHECK(tbl["b"][2]["c"] == tbl[toml::path("b")][toml::path("[2].c")]);
+ CHECK(tbl["b"][2]["c"] == tbl[toml::path("b[2] \t.c")]); // whitespace is allowed after array
+ // indexers
+
+ CHECK(tbl["d"]);
+ CHECK(tbl["d"] == tbl[toml::path("d")]);
+
+ CHECK(tbl["d"]["e"]);
+ CHECK(tbl["d"]["e"] == tbl[toml::path("d.e")]);
+ CHECK(tbl["d"]["e"] != tbl[toml::path("d. e")]); // equivalent to "d"." e"
+ CHECK(!tbl[toml::path("d. e")]);
+
+ CHECK(tbl["d"][""]);
+ CHECK(tbl["d"][""] == tbl[toml::path("d.")]);
+
+ CHECK(!tbl[toml::path("has.missing.component")]);
+ }
+}
diff --git a/tomlplusplus/tests/settings.hpp b/tomlplusplus/tests/settings.hpp
new file mode 100644
index 0000000000..f4ff2f5f8c
--- /dev/null
+++ b/tomlplusplus/tests/settings.hpp
@@ -0,0 +1,98 @@
+// This file is a part of toml++ and is subject to the the terms of the MIT license.
+// Copyright (c) Mark Gillard <mark.gillard@outlook.com.au>
+// See https://github.com/marzer/tomlplusplus/blob/master/LICENSE for the full license text.
+// SPDX-License-Identifier: MIT
+#pragma once
+
+// toml++ config
+#define TOML_UNDEF_MACROS 0
+#ifndef TOML_HEADER_ONLY
+#define TOML_HEADER_ONLY 0
+#endif
+#ifndef TOML_SHARED_LIB
+#define TOML_SHARED_LIB 0
+#endif
+#ifndef USE_SINGLE_HEADER
+#define USE_SINGLE_HEADER 0
+#endif
+#if defined(LEAK_TESTS) && LEAK_TESTS
+#define TOML_CONFIG_HEADER "leakproof.hpp"
+#else
+#undef LEAK_TESTS
+#define LEAK_TESTS 0
+#endif
+#ifdef _MSC_VER
+#define TOML_CALLCONV __stdcall // just to test that TOML_CALLCONV doesn't cause linker failures
+#endif
+
+// catch2 config
+#define CATCH_CONFIG_CPP11_TO_STRING
+#define CATCH_CONFIG_CPP17_OPTIONAL
+#define CATCH_CONFIG_CPP17_STRING_VIEW
+#define CATCH_CONFIG_FAST_COMPILE
+#define CATCH_CONFIG_CONSOLE_WIDTH 120
+#define CATCH_CONFIG_CPP11_TO_STRING
+#define CATCH_CONFIG_DISABLE_MATCHERS
+#define CATCH_CONFIG_NO_NOMINMAX
+
+// windows.h config (included transitively by catch2 on windows)
+#ifdef _WIN32
+#define WIN32_LEAN_AND_MEAN
+#define VC_EXTRALEAN
+#define NOATOM // Atom Manager routines
+#define NOBITMAP //
+#define NOCLIPBOARD // Clipboard routines
+#define NOCOLOR // Screen colors
+#define NOCOMM // COMM driver routines
+#define NOCTLMGR // Control and Dialog routines
+#define NODEFERWINDOWPOS // DeferWindowPos routines
+#define NODRAWTEXT // DrawText() and DT_*
+#define NOGDI // All GDI defines and routines
+#define NOGDICAPMASKS // CC_*, LC_*, PC_*, CP_*, TC_*, RC_
+#define NOHELP // Help engine interface.
+#define NOICONS // IDI_*
+#define NOKANJI // Kanji support stuff.
+#define NOKEYSTATES // MK_*
+#define NOKERNEL // All KERNEL defines and routines
+#define NOMB // MB_* and MessageBox()
+#define NOMCX // Modem Configuration Extensions
+#define NOMENUS // MF_*
+#define NOMEMMGR // GMEM_*, LMEM_*, GHND, LHND, associated routines
+#define NOMETAFILE // typedef METAFILEPICT
+#define NOMSG // typedef MSG and associated routines
+#define NOOPENFILE // OpenFile(), OemToAnsi, AnsiToOem, and OF_*
+#define NOPROFILER // Profiler interface.
+#define NORASTEROPS // Binary and Tertiary raster ops
+#define NOSCROLL // SB_* and scrolling routines
+#define NOSERVICE // All Service Controller routines, SERVICE_ equates, etc.
+#define NOSHOWWINDOW // SW_*
+#define NOSOUND // Sound driver routines
+#define NOSYSCOMMANDS // SC_*
+#define NOSYSMETRICS // SM_*
+#define NOTEXTMETRIC // typedef TEXTMETRIC and associated routines
+#define NOUSER // All USER defines and routines
+#define NOVIRTUALKEYCODES // VK_*
+#define NOWH // SetWindowsHook and WH_*
+#define NOWINOFFSETS // GWL_*, GCL_*, associated routines
+#define NOWINMESSAGES // WM_*, EM_*, LB_*, CB_*
+#define NOWINSTYLES // WS_*, CS_*, ES_*, LBS_*, SBS_*, CBS_*
+//#define NOMINMAX // Macros min(a,b) and max(a,b)
+//#define NONLS // All NLS defines and routines
+#endif
+
+// test harness stuff
+#ifndef SHOULD_HAVE_FP16
+#define SHOULD_HAVE_FP16 0
+#endif
+#ifndef SHOULD_HAVE_FLOAT16
+#define SHOULD_HAVE_FLOAT16 0
+#endif
+#ifndef SHOULD_HAVE_FLOAT128
+#define SHOULD_HAVE_FLOAT128 0
+#endif
+#ifndef SHOULD_HAVE_INT128
+#define SHOULD_HAVE_INT128 0
+#endif
+#ifndef SHOULD_HAVE_EXCEPTIONS
+#define SHOULD_HAVE_EXCEPTIONS 1
+#endif
diff --git a/tomlplusplus/tests/tests.cpp b/tomlplusplus/tests/tests.cpp
new file mode 100644
index 0000000000..1ba88057d7
--- /dev/null
+++ b/tomlplusplus/tests/tests.cpp
@@ -0,0 +1,230 @@
+// This file is a part of toml++ and is subject to the the terms of the MIT license.
+// Copyright (c) Mark Gillard <mark.gillard@outlook.com.au>
+// See https://github.com/marzer/tomlplusplus/blob/master/LICENSE for the full license text.
+// SPDX-License-Identifier: MIT
+
+#include "tests.hpp"
+
+bool parsing_should_succeed(std::string_view test_file,
+ uint32_t test_line,
+ std::string_view toml_str,
+ pss_func&& func,
+ std::string_view source_path)
+{
+ INFO("["sv << test_file << ", line "sv << test_line << "] "sv
+ << "parsing_should_succeed(\""sv << toml_str << "\")"sv)
+
+ constexpr auto validate_table = [](table&& tabl, std::string_view path) -> table&&
+ {
+ INFO("Validating table source information"sv)
+ CHECK(tabl.source().begin != source_position{});
+ CHECK(tabl.source().end != source_position{});
+ if (path.empty())
+ CHECK(tabl.source().path == nullptr);
+ else
+ {
+ REQUIRE(tabl.source().path != nullptr);
+ CHECK(*tabl.source().path == path);
+ }
+ return std::move(tabl);
+ };
+
+#if TOML_EXCEPTIONS
+
+ try
+ {
+ {
+ INFO("Parsing string directly"sv)
+ if (func)
+ func(validate_table(toml::parse(toml_str, source_path), source_path));
+ else
+ validate_table(toml::parse(toml_str, source_path), source_path);
+ }
+ {
+ INFO("Parsing from a string stream"sv)
+ std::stringstream ss;
+ ss.write(toml_str.data(), static_cast<std::streamsize>(toml_str.length()));
+ if (func)
+ func(validate_table(toml::parse(ss, source_path), source_path));
+ else
+ validate_table(toml::parse(ss, source_path), source_path);
+ }
+ }
+ catch (const parse_error& err)
+ {
+ FORCE_FAIL("Parse error on line "sv << err.source().begin.line << ", column "sv << err.source().begin.column
+ << ":\n"sv << err.description());
+ return false;
+ }
+
+#else
+
+ {
+ INFO("Parsing string directly"sv)
+ parse_result result = toml::parse(toml_str, source_path);
+ if (result)
+ {
+ if (func)
+ func(validate_table(std::move(result), source_path));
+ else
+ validate_table(std::move(result), source_path);
+ }
+ else
+ {
+ FORCE_FAIL("Parse error on line "sv << result.error().source().begin.line << ", column "sv
+ << result.error().source().begin.column << ":\n"sv
+ << result.error().description());
+ }
+ }
+
+ {
+ INFO("Parsing from a string stream"sv)
+ std::stringstream ss;
+ ss.write(toml_str.data(), static_cast<std::streamsize>(toml_str.length()));
+ parse_result result = toml::parse(ss, source_path);
+ if (result)
+ {
+ if (func)
+ func(validate_table(std::move(result), source_path));
+ else
+ validate_table(std::move(result), source_path);
+ }
+ else
+ {
+ FORCE_FAIL("Parse error on line "sv << result.error().source().begin.line << ", column "sv
+ << result.error().source().begin.column << ":\n"sv
+ << result.error().description());
+ }
+ }
+
+#endif
+
+ return true;
+}
+
+bool parsing_should_fail(std::string_view test_file,
+ uint32_t test_line,
+ std::string_view toml_str,
+ source_index expected_failure_line,
+ source_index expected_failure_column)
+{
+ INFO("["sv << test_file << ", line "sv << test_line << "] "sv
+ << "parsing_should_fail(\""sv << toml_str << "\")"sv)
+
+#if TOML_EXCEPTIONS
+
+ static constexpr auto run_tests = [](source_index ex_line, source_index ex_col, auto&& fn)
+ {
+ try
+ {
+ fn();
+ }
+ catch (const parse_error& err)
+ {
+ if (ex_line != static_cast<source_index>(-1) && err.source().begin.line != ex_line)
+ {
+ FORCE_FAIL("Expected parse_error at line "sv << ex_line << ", actually occured at line "sv
+ << err.source().begin.line);
+ return false;
+ }
+
+ if (ex_col != static_cast<source_index>(-1) && err.source().begin.column != ex_col)
+ {
+ FORCE_FAIL("Expected parse_error at column "sv << ex_col << ", actually occured at column "sv
+ << err.source().begin.column);
+ return false;
+ }
+
+ SUCCEED("parse_error thrown OK"sv);
+ return true;
+ }
+ catch (const std::exception& exc)
+ {
+ FORCE_FAIL("Expected parsing failure, saw exception: "sv << exc.what());
+ return false;
+ }
+ catch (...)
+ {
+ FORCE_FAIL("Expected parsing failure, saw unspecified exception"sv);
+ return false;
+ }
+
+ FORCE_FAIL("Expected parsing failure"sv);
+ return false;
+ };
+
+ auto result = run_tests(expected_failure_line,
+ expected_failure_column,
+ [=]() { [[maybe_unused]] auto res = toml::parse(toml_str); });
+ result = result
+ && run_tests(expected_failure_line,
+ expected_failure_column,
+ [=]()
+ {
+ std::stringstream ss;
+ ss.write(toml_str.data(), static_cast<std::streamsize>(toml_str.length()));
+ [[maybe_unused]] auto res = toml::parse(ss);
+ });
+ return result;
+
+#else
+
+ static constexpr auto run_tests = [](source_index ex_line, source_index ex_col, auto&& fn)
+ {
+ if (parse_result result = fn(); !result)
+ {
+ if (ex_line != static_cast<source_index>(-1) && result.error().source().begin.line != ex_line)
+ {
+ FORCE_FAIL("Expected parse_error at line "sv << ex_line << ", actually occured at line "sv
+ << result.error().source().begin.line);
+ }
+
+ if (ex_col != static_cast<source_index>(-1) && result.error().source().begin.column != ex_col)
+ {
+ FORCE_FAIL("Expected parse_error at column "sv << ex_col << ", actually occured at column "sv
+ << result.error().source().begin.column);
+ }
+
+ SUCCEED("parse_error generated OK"sv);
+ return true;
+ }
+
+ FORCE_FAIL("Expected parsing failure"sv);
+ };
+
+ return run_tests(expected_failure_line, expected_failure_column, [=]() { return toml::parse(toml_str); })
+ && run_tests(expected_failure_line,
+ expected_failure_column,
+ [=]()
+ {
+ std::stringstream ss;
+ ss.write(toml_str.data(), static_cast<std::streamsize>(toml_str.length()));
+ return toml::parse(ss);
+ });
+
+#endif
+}
+
+template bool parse_expected_value(std::string_view, uint32_t, std::string_view, const int&);
+template bool parse_expected_value(std::string_view, uint32_t, std::string_view, const unsigned int&);
+template bool parse_expected_value(std::string_view, uint32_t, std::string_view, const bool&);
+template bool parse_expected_value(std::string_view, uint32_t, std::string_view, const float&);
+template bool parse_expected_value(std::string_view, uint32_t, std::string_view, const double&);
+template bool parse_expected_value(std::string_view, uint32_t, std::string_view, const std::string_view&);
+
+namespace std
+{
+ template class unique_ptr<const Catch::IExceptionTranslator>;
+}
+namespace Catch
+{
+ template struct StringMaker<node_view<node>>;
+ template struct StringMaker<node_view<const node>>;
+ template ReusableStringStream& ReusableStringStream::operator<<(node_view<node> const&);
+ template ReusableStringStream& ReusableStringStream::operator<<(node_view<const node> const&);
+ namespace Detail
+ {
+ template std::string stringify(const node_view<node>&);
+ template std::string stringify(const node_view<const node>&);
+ }
+}
diff --git a/tomlplusplus/tests/tests.hpp b/tomlplusplus/tests/tests.hpp
new file mode 100644
index 0000000000..00baee88a9
--- /dev/null
+++ b/tomlplusplus/tests/tests.hpp
@@ -0,0 +1,410 @@
+// This file is a part of toml++ and is subject to the the terms of the MIT license.
+// Copyright (c) Mark Gillard <mark.gillard@outlook.com.au>
+// See https://github.com/marzer/tomlplusplus/blob/master/LICENSE for the full license text.
+// SPDX-License-Identifier: MIT
+
+#pragma once
+#include "settings.hpp"
+#include <toml++/toml.hpp>
+
+#if TOML_COMPILER_HAS_EXCEPTIONS ^ SHOULD_HAVE_EXCEPTIONS
+#error TOML_COMPILER_HAS_EXCEPTIONS was not deduced correctly
+#endif
+#if TOML_COMPILER_HAS_EXCEPTIONS ^ TOML_EXCEPTIONS
+#error TOML_EXCEPTIONS does not match TOML_COMPILER_HAS_EXCEPTIONS (default behaviour should be to match)
+#endif
+#if defined(_WIN32) ^ TOML_ENABLE_WINDOWS_COMPAT
+#error TOML_ENABLE_WINDOWS_COMPAT does not match _WIN32 (default behaviour should be to match)
+#endif
+#if TOML_LIB_SINGLE_HEADER ^ USE_SINGLE_HEADER
+#error TOML_LIB_SINGLE_HEADER was not set correctly
+#endif
+
+#if TOML_ICC
+#define UNICODE_LITERALS_OK 0
+#else
+#define UNICODE_LITERALS_OK 1
+#endif
+
+TOML_DISABLE_SPAM_WARNINGS;
+TOML_DISABLE_ARITHMETIC_WARNINGS;
+#if TOML_CLANG == 13
+#pragma clang diagnostic ignored "-Wreserved-identifier" // false-positive
+#endif
+
+TOML_DISABLE_WARNINGS;
+#include "lib_catch2.hpp"
+#include <sstream>
+namespace toml
+{
+}
+using namespace Catch::literals;
+using namespace toml;
+TOML_ENABLE_WARNINGS;
+
+TOML_NODISCARD
+TOML_ATTR(const)
+TOML_ALWAYS_INLINE
+constexpr size_t operator""_sz(unsigned long long n) noexcept
+{
+ return static_cast<size_t>(n);
+}
+
+#define FILE_LINE_ARGS trim_file_path(std::string_view{ __FILE__ }), __LINE__
+#define BOM_PREFIX "\xEF\xBB\xBF"
+
+#if TOML_EXCEPTIONS
+#define FORCE_FAIL(...) FAIL(__VA_ARGS__)
+#else
+#define FORCE_FAIL(...) \
+ do \
+ { \
+ FAIL(__VA_ARGS__); \
+ std::exit(-1); \
+ TOML_UNREACHABLE; \
+ } \
+ while (false)
+#endif
+
+#define CHECK_SYMMETRIC_RELOP(lhs, op, rhs, result) \
+ CHECK(((lhs)op(rhs)) == (result)); \
+ CHECK(((rhs)op(lhs)) == (result))
+
+#define CHECK_SYMMETRIC_EQUAL(lhs, rhs) \
+ CHECK_SYMMETRIC_RELOP(lhs, ==, rhs, true); \
+ CHECK_SYMMETRIC_RELOP(lhs, !=, rhs, false)
+
+#define CHECK_SYMMETRIC_INEQUAL(lhs, rhs) \
+ CHECK_SYMMETRIC_RELOP(lhs, ==, rhs, false); \
+ CHECK_SYMMETRIC_RELOP(lhs, !=, rhs, true)
+
+template <typename T>
+struct type_tag
+{
+ using type = T;
+};
+
+// function_view - adapted from here: https://vittorioromeo.info/index/blog/passing_functions_to_functions.html
+template <typename Func>
+class function_view;
+template <typename R, typename... P>
+class function_view<R(P...)> final
+{
+ private:
+ using func_type = R(P...);
+ using eraser_func_type = R(void*, P&&...);
+
+ mutable void* ptr_ = {};
+ mutable eraser_func_type* eraser = {};
+
+ public:
+ function_view() noexcept = default;
+
+ template <typename T>
+ function_view(T&& x) noexcept : ptr_{ reinterpret_cast<void*>(std::addressof(x)) }
+ {
+ eraser = [](void* ptr, P&&... xs) -> R
+ { return (*reinterpret_cast<std::add_pointer_t<std::remove_reference_t<T>>>(ptr))(std::forward<P>(xs)...); };
+ }
+
+ decltype(auto) operator()(P&&... xs) const
+ {
+ return eraser(ptr_, std::forward<P>(xs)...);
+ }
+
+ TOML_NODISCARD
+ operator bool() const noexcept
+ {
+ return !!ptr_;
+ }
+};
+
+using pss_func = function_view<void(table&&)>;
+
+bool parsing_should_succeed(std::string_view test_file,
+ uint32_t test_line,
+ std::string_view toml_str,
+ pss_func&& func = {},
+ std::string_view source_path = {});
+
+bool parsing_should_fail(std::string_view test_file,
+ uint32_t test_line,
+ std::string_view toml_str,
+ source_index expected_failure_line = static_cast<source_index>(-1),
+ source_index expected_failure_column = static_cast<source_index>(-1));
+
+TOML_PURE_GETTER
+constexpr std::string_view trim_file_path(std::string_view sv) noexcept
+{
+ const auto src = std::min(sv.rfind("\\"sv), sv.rfind("/"sv));
+ if (src != std::string_view::npos)
+ sv = sv.substr(src + 1_sz);
+ return sv;
+}
+
+template <typename T>
+inline bool parse_expected_value(std::string_view test_file,
+ uint32_t test_line,
+ std::string_view value_str,
+ const T& expected)
+{
+ INFO("["sv << test_file << ", line "sv << test_line << "] "sv
+ << "parse_expected_value(\""sv << value_str << "\")"sv)
+
+ std::string val;
+ static constexpr auto key = "val = "sv;
+ val.reserve(key.length() + value_str.length());
+ val.append(key);
+ val.append(value_str);
+
+ static constexpr auto is_val = [](char32_t codepoint)
+ {
+ if constexpr (impl::node_type_of<T> == node_type::string)
+ return codepoint == U'"' || codepoint == U'\'';
+ else
+ return !impl::is_whitespace(codepoint);
+ };
+
+ source_position pos{ 1, static_cast<source_index>(key.length()) };
+ source_position begin{}, end{};
+ {
+ impl::utf8_decoder decoder;
+ for (auto c : value_str)
+ {
+ decoder(static_cast<uint8_t>(c));
+ if (!decoder.has_code_point())
+ continue;
+
+ if (impl::is_ascii_vertical_whitespace(decoder.codepoint))
+ {
+ if (decoder.codepoint == U'\n')
+ {
+ pos.line++;
+ pos.column = source_index{ 1 };
+ }
+ continue;
+ }
+
+ pos.column++;
+ if (is_val(decoder.codepoint))
+ {
+ if (!begin)
+ begin = pos;
+ else
+ end = pos;
+ }
+ }
+ if (!end)
+ end = begin;
+ end.column++;
+ }
+
+ using value_type = impl::native_type_of<impl::remove_cvref<T>>;
+ value<value_type> val_parsed;
+ {
+ INFO("["sv << test_file << ", line "sv << test_line << "] "sv
+ << "parse_expected_value: Checking initial parse"sv)
+
+ bool stolen_value = false; // parsing_should_succeed invokes the functor more than once
+ const auto result = parsing_should_succeed(
+ test_file,
+ test_line,
+ std::string_view{ val },
+ [&](table&& tbl)
+ {
+ REQUIRE(tbl.size() == 1);
+ auto nv = tbl["val"sv];
+ REQUIRE(nv);
+ REQUIRE(nv.is<value_type>());
+ REQUIRE(nv.as<value_type>());
+ REQUIRE(nv.type() == impl::node_type_of<T>);
+ REQUIRE(nv.node());
+ REQUIRE(nv.node()->is<value_type>());
+ REQUIRE(nv.node()->as<value_type>());
+ REQUIRE(nv.node()->type() == impl::node_type_of<T>);
+
+ // check homogeneity
+ REQUIRE(nv.is_homogeneous());
+ REQUIRE(nv.is_homogeneous(node_type::none));
+ REQUIRE(nv.is_homogeneous(impl::node_type_of<T>));
+ REQUIRE(nv.is_homogeneous<value_type>());
+ REQUIRE(nv.node()->is_homogeneous());
+ REQUIRE(nv.node()->is_homogeneous(node_type::none));
+ REQUIRE(nv.node()->is_homogeneous(impl::node_type_of<T>));
+ REQUIRE(nv.node()->is_homogeneous<value_type>());
+ for (auto nt = impl::unwrap_enum(node_type::table); nt <= impl::unwrap_enum(node_type::date_time); nt++)
+ {
+ if (node_type{ nt } == impl::node_type_of<T>)
+ continue;
+ node* first_nonmatch{};
+ REQUIRE(!nv.is_homogeneous(node_type{ nt }));
+ REQUIRE(!nv.is_homogeneous(node_type{ nt }, first_nonmatch));
+ REQUIRE(first_nonmatch == nv.node());
+ REQUIRE(!nv.node()->is_homogeneous(node_type{ nt }));
+ REQUIRE(!nv.node()->is_homogeneous(node_type{ nt }, first_nonmatch));
+ REQUIRE(first_nonmatch == nv.node());
+ }
+
+ // check the raw value
+ REQUIRE(nv.node()->value<value_type>() == expected);
+ REQUIRE(nv.node()->value_or(T{}) == expected);
+ REQUIRE(nv.as<value_type>()->get() == expected);
+ REQUIRE(nv.value<value_type>() == expected);
+ REQUIRE(nv.value_or(T{}) == expected);
+ REQUIRE(nv.ref<value_type>() == expected);
+ REQUIRE(nv.node()->ref<value_type>() == expected);
+
+ // check the table relops
+ REQUIRE(tbl == table{ { { "val"sv, expected } } });
+ REQUIRE(!(tbl != table{ { { "val"sv, expected } } }));
+
+ // check value/node relops
+ CHECK_SYMMETRIC_EQUAL(*nv.as<value_type>(), *nv.as<value_type>());
+ CHECK_SYMMETRIC_EQUAL(*nv.as<value_type>(), expected);
+ CHECK_SYMMETRIC_EQUAL(nv, expected);
+
+ // make sure source info is correct
+ CHECK_SYMMETRIC_EQUAL(nv.node()->source().begin, begin);
+ CHECK_SYMMETRIC_EQUAL(nv.node()->source().end, end);
+
+ // check float identities etc
+ if constexpr (std::is_same_v<value_type, double>)
+ {
+ auto& float_node = *nv.as<value_type>();
+ const auto fpcls = impl::fpclassify(*float_node);
+ if (fpcls == impl::fp_class::nan)
+ {
+ CHECK_SYMMETRIC_EQUAL(float_node, std::numeric_limits<double>::quiet_NaN());
+ CHECK_SYMMETRIC_INEQUAL(float_node, std::numeric_limits<double>::infinity());
+ CHECK_SYMMETRIC_INEQUAL(float_node, -std::numeric_limits<double>::infinity());
+ CHECK_SYMMETRIC_INEQUAL(float_node, 1.0);
+ CHECK_SYMMETRIC_INEQUAL(float_node, 0.0);
+ CHECK_SYMMETRIC_INEQUAL(float_node, -1.0);
+ }
+ else if (fpcls == impl::fp_class::neg_inf || fpcls == impl::fp_class::pos_inf)
+ {
+ CHECK_SYMMETRIC_INEQUAL(float_node, std::numeric_limits<double>::quiet_NaN());
+ if (fpcls == impl::fp_class::neg_inf)
+ {
+ CHECK_SYMMETRIC_EQUAL(float_node, -std::numeric_limits<double>::infinity());
+ CHECK_SYMMETRIC_INEQUAL(float_node, std::numeric_limits<double>::infinity());
+ }
+ else
+ {
+ CHECK_SYMMETRIC_EQUAL(float_node, std::numeric_limits<double>::infinity());
+ CHECK_SYMMETRIC_INEQUAL(float_node, -std::numeric_limits<double>::infinity());
+ }
+ CHECK_SYMMETRIC_INEQUAL(float_node, 1.0);
+ CHECK_SYMMETRIC_INEQUAL(float_node, 0.0);
+ CHECK_SYMMETRIC_INEQUAL(float_node, -1.0);
+ }
+ else
+ {
+ CHECK_SYMMETRIC_INEQUAL(float_node, std::numeric_limits<double>::quiet_NaN());
+ CHECK_SYMMETRIC_INEQUAL(float_node, std::numeric_limits<double>::infinity());
+ CHECK_SYMMETRIC_INEQUAL(float_node, -std::numeric_limits<double>::infinity());
+ CHECK_SYMMETRIC_EQUAL(float_node, *float_node);
+ if (std::abs(*float_node) <= 1e10)
+ {
+ CHECK_SYMMETRIC_INEQUAL(float_node, *float_node + 100.0);
+ CHECK_SYMMETRIC_INEQUAL(float_node, *float_node - 100.0);
+ }
+ CHECK(float_node < std::numeric_limits<double>::infinity());
+ CHECK(float_node > -std::numeric_limits<double>::infinity());
+ }
+ }
+
+ // steal the val for round-trip tests
+ if (!stolen_value)
+ {
+ val_parsed = std::move(*nv.as<value_type>());
+ stolen_value = true;
+ }
+ });
+
+ if (!result)
+ return false;
+ }
+
+ // check round-tripping
+ {
+ INFO("["sv << test_file << ", line "sv << test_line << "] "sv
+ << "parse_expected_value: Checking round-trip"sv)
+ {
+ std::string str;
+ {
+ auto tbl = table{ { { "val"sv, *val_parsed } } };
+ std::ostringstream ss;
+ ss << tbl;
+ str = std::move(ss).str();
+ }
+
+ bool value_ok = true;
+ const auto parse_ok =
+ parsing_should_succeed(test_file,
+ test_line,
+ std::string_view{ str },
+ [&](table&& tbl)
+ {
+ REQUIRE(tbl.size() == 1);
+ auto nv = tbl["val"sv];
+ REQUIRE(nv);
+ REQUIRE(nv.as<value_type>());
+ REQUIRE(nv.node()->type() == impl::node_type_of<T>);
+
+ if (value_ok && nv.ref<value_type>() != expected)
+ {
+ value_ok = false;
+ FORCE_FAIL("Value was not the same after round-tripping"sv);
+ }
+ });
+
+ if (!parse_ok || value_ok)
+ return false;
+ }
+ }
+
+ return true;
+}
+
+// manually instantiate some templates to reduce obj bloat and test compilation time
+
+extern template bool parse_expected_value(std::string_view, uint32_t, std::string_view, const int&);
+extern template bool parse_expected_value(std::string_view, uint32_t, std::string_view, const unsigned int&);
+extern template bool parse_expected_value(std::string_view, uint32_t, std::string_view, const bool&);
+extern template bool parse_expected_value(std::string_view, uint32_t, std::string_view, const float&);
+extern template bool parse_expected_value(std::string_view, uint32_t, std::string_view, const double&);
+extern template bool parse_expected_value(std::string_view, uint32_t, std::string_view, const std::string_view&);
+namespace std
+{
+ extern template class unique_ptr<const Catch::IExceptionTranslator>;
+}
+namespace Catch
+{
+ extern template struct StringMaker<node_view<node>>;
+ extern template struct StringMaker<node_view<const node>>;
+ extern template ReusableStringStream& ReusableStringStream::operator<<(node_view<node> const&);
+ extern template ReusableStringStream& ReusableStringStream::operator<<(node_view<const node> const&);
+ namespace Detail
+ {
+ extern template std::string stringify(const node_view<node>&);
+ extern template std::string stringify(const node_view<const node>&);
+ }
+}
+
+#if TOML_CPP >= 20 && TOML_CLANG && TOML_CLANG <= 14 // https://github.com/llvm/llvm-project/issues/55560
+
+TOML_PUSH_WARNINGS;
+TOML_DISABLE_WARNINGS;
+
+namespace
+{
+ [[maybe_unused]] static std::u8string clang_string_workaround(const char8_t* a, const char8_t* b)
+ {
+ return { a, b };
+ }
+}
+
+TOML_POP_WARNINGS;
+
+#endif
diff --git a/tomlplusplus/tests/user_feedback.cpp b/tomlplusplus/tests/user_feedback.cpp
new file mode 100644
index 0000000000..aa1f36b1d6
--- /dev/null
+++ b/tomlplusplus/tests/user_feedback.cpp
@@ -0,0 +1,503 @@
+// This file is a part of toml++ and is subject to the the terms of the MIT license.
+// Copyright (c) Mark Gillard <mark.gillard@outlook.com.au>
+// See https://github.com/marzer/tomlplusplus/blob/master/LICENSE for the full license text.
+// SPDX-License-Identifier: MIT
+
+#include "tests.hpp"
+
+// this file is about testing user misc. repros submitted via github issues, et cetera.
+
+TEST_CASE("user feedback")
+{
+ SECTION("tomlplusplus/issues/49") // https://github.com/marzer/tomlplusplus/issues/49#issuecomment-664428571
+ {
+ toml::table t1;
+ t1.insert_or_assign("bar1", toml::array{ 1, 2, 3 });
+ CHECK(t1 == toml::table{ { "bar1"sv, toml::array{ 1, 2, 3 } } });
+
+ t1.insert_or_assign("foo1", *t1.get("bar1"));
+ CHECK(t1 == toml::table{ { "bar1"sv, toml::array{ 1, 2, 3 } }, { "foo1"sv, toml::array{ 1, 2, 3 } } });
+
+ // t1["foo1"] = t1["bar1"]; // does nothing, should this fail to compile?
+ // - yes -
+
+ //*t1["foo1"].node() = *t1["bar1"].node(); // compile failure; copying node_view would be a bad thing
+ // - correct; copying toml::node directly like that is impossible b.c. it's an abstract base class-
+
+ toml::array* array1 = t1["foo1"].node()->as_array();
+ array1->push_back(4);
+ CHECK(t1 == toml::table{ { "bar1"sv, toml::array{ 1, 2, 3 } }, { "foo1"sv, toml::array{ 1, 2, 3, 4 } } });
+
+ t1.insert_or_assign("foo3", t1["foo1"]);
+ CHECK(t1
+ == toml::table{ { "bar1"sv, toml::array{ 1, 2, 3 } },
+ { "foo1"sv, toml::array{ 1, 2, 3, 4 } },
+ { "foo3"sv, toml::array{ 1, 2, 3, 4 } } });
+
+ t1.insert_or_assign("foo2", *t1["foo1"].node());
+ CHECK(t1
+ == toml::table{ { "bar1"sv, toml::array{ 1, 2, 3 } },
+ { "foo1"sv, toml::array{ 1, 2, 3, 4 } },
+ { "foo2"sv, toml::array{ 1, 2, 3, 4 } },
+ { "foo3"sv, toml::array{ 1, 2, 3, 4 } } });
+
+ toml::array* array2 = t1["foo2"].node()->as_array();
+ array2->push_back("wrench");
+ CHECK(t1
+ == toml::table{ { "bar1"sv, toml::array{ 1, 2, 3 } },
+ { "foo1"sv, toml::array{ 1, 2, 3, 4 } },
+ { "foo2"sv, toml::array{ 1, 2, 3, 4, "wrench" } },
+ { "foo3"sv, toml::array{ 1, 2, 3, 4 } } });
+
+ toml::table t2 = t1;
+ CHECK(t2 == t1);
+ CHECK(&t2 != &t1);
+
+ // t2.emplace("bar", toml::array{6, 7}); // fails to compile? not sure what I did wrong
+ // - it should be this: -
+ t2.emplace<toml::array>("bar", 6, 7);
+ CHECK(t2
+ == toml::table{ { "bar"sv, toml::array{ 6, 7 } },
+ { "bar1"sv, toml::array{ 1, 2, 3 } },
+ { "foo1"sv, toml::array{ 1, 2, 3, 4 } },
+ { "foo2"sv, toml::array{ 1, 2, 3, 4, "wrench" } },
+ { "foo3"sv, toml::array{ 1, 2, 3, 4 } } });
+
+ t2.insert_or_assign("bar2", toml::array{ 6, 7 });
+ CHECK(t2
+ == toml::table{ { "bar"sv, toml::array{ 6, 7 } },
+ { "bar1"sv, toml::array{ 1, 2, 3 } },
+ { "bar2"sv, toml::array{ 6, 7 } },
+ { "foo1"sv, toml::array{ 1, 2, 3, 4 } },
+ { "foo2"sv, toml::array{ 1, 2, 3, 4, "wrench" } },
+ { "foo3"sv, toml::array{ 1, 2, 3, 4 } } });
+ }
+
+ SECTION("tomlplusplus/issues/65") // https://github.com/marzer/tomlplusplus/issues/65
+ {
+ // these test a number of things
+ // - a comment at EOF
+ // - a malformed UTF-8 sequence in a comment
+ // - a malformed UTF-8 sequence during a KVP
+ // - overlong numeric literals
+ // all should fail to parse, but correctly issue an error (not crash!)
+
+ parsing_should_fail(FILE_LINE_ARGS, "#\xf1\x63");
+ parsing_should_fail(FILE_LINE_ARGS, "1= 0x6cA#+\xf1");
+ parsing_should_fail(FILE_LINE_ARGS, "p=06:06:06#\x0b\xff");
+ parsing_should_fail(
+ FILE_LINE_ARGS,
+ "''''d' 't' '+o\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c"
+ "\x0c\x0c\x0c\x0c\x0c\r\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c"
+ "\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c"
+ "\x0c\x0c\x0c\x0c\x0c\x0c\x0cop1\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c"
+ "\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c"
+ "\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c' 'ml'\n\n%\x87");
+ parsing_should_fail(
+ FILE_LINE_ARGS,
+ R"(t =[ 9, 2, 1,"r", 100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000.0 ])");
+ }
+
+ SECTION("tomlplusplus/issues/67") // https://github.com/marzer/tomlplusplus/issues/67
+ {
+ const auto data = R"(array=["v1", "v2", "v3"])"sv;
+
+ parsing_should_succeed(FILE_LINE_ARGS,
+ data,
+ [](auto&& table)
+ {
+ auto arr = table["array"].as_array();
+ for (auto it = arr->cbegin(); it != arr->cend();)
+ if (it->value_or(std::string_view{}) == "v2"sv)
+ it = arr->erase(it);
+ else
+ ++it;
+ CHECK(arr->size() == 2);
+ });
+ }
+
+ SECTION("tomlplusplus/issues/68") // https://github.com/marzer/tomlplusplus/issues/68
+ {
+ const auto data = R"(array=["v1", "v2", "v3"])"sv;
+ parsing_should_succeed(FILE_LINE_ARGS,
+ data,
+ [](auto&& table)
+ {
+ std::stringstream ss;
+ ss << table;
+ CHECK(ss.str() == "array = [ 'v1', 'v2', 'v3' ]"sv);
+ });
+ }
+
+ SECTION("tomlplusplus/issues/69") // https://github.com/marzer/tomlplusplus/issues/69
+ {
+ using namespace toml::literals; // should compile without namespace ambiguity
+ auto table = "[table]\nkey=\"value\""_toml;
+ }
+
+ SECTION("tomlplusplus/pull/80") // https://github.com/marzer/tomlplusplus/pull/80
+ {
+ const auto data = R"(
+ a = { "key" = 1 } # inline table
+ b = [] # array value
+ [[c]] # array-of-tables with a single, empty table element
+ )"sv;
+
+ parsing_should_succeed(FILE_LINE_ARGS,
+ data,
+ [](auto&& table)
+ {
+ std::stringstream ss;
+ ss << table;
+ CHECK(ss.str() == R"(a = { key = 1 }
+b = []
+
+[[c]])"sv);
+ });
+ }
+
+ SECTION("tomlplusplus/issues/100") // https://github.com/marzer/tomlplusplus/issues/100
+ {
+ // this tests for two separate things that should fail gracefully, not crash:
+ // 1. pathologically-nested inputs
+ // 2. a particular sequence of malformed UTF-8
+
+ parsing_should_fail(FILE_LINE_ARGS, "fl =[ [[[[[[[[[[[[[[[\x36\x80\x86\x00\x00\x00\x2D\x36\x9F\x20\x00"sv);
+
+ std::string s(2048_sz, '[');
+ constexpr auto start = "fl =[ "sv;
+ memcpy(s.data(), start.data(), start.length());
+ parsing_should_fail(FILE_LINE_ARGS, std::string_view{ s });
+
+ // deeply nested inline tables should also fail gracefully, not stack overflow
+ {
+ // build: fl = {a={a={a={a=...{a=1}...}}}
+ std::string nested_tables = "fl = ";
+ for (size_t i = 0; i < 2048; i++)
+ nested_tables += "{a=";
+ nested_tables += "1";
+ for (size_t i = 0; i < 2048; i++)
+ nested_tables += "}";
+ parsing_should_fail(FILE_LINE_ARGS, std::string_view{ nested_tables });
+ }
+ }
+
+ SECTION("tomlplusplus/issues/112") // https://github.com/marzer/tomlplusplus/issues/112
+ {
+ parsing_should_fail(FILE_LINE_ARGS,
+ R"(
+ [a.b.c.d]
+ u = 6
+ [a]
+ b.t = 8
+ [a.b] # should cause redefinition error here
+ u = 0
+ )",
+ 6);
+
+ parsing_should_fail(FILE_LINE_ARGS,
+ R"(
+ [a]
+ b.t = 8
+ [a.b] # should cause redefinition error here
+ u = 0
+ )",
+ 4);
+ }
+
+ SECTION("tomlplusplus/issues/125") // https://github.com/marzer/tomlplusplus/issues/125
+ {
+ parse_expected_value(FILE_LINE_ARGS, R"("\u0800")"sv, "\xE0\xA0\x80"sv);
+ parse_expected_value(FILE_LINE_ARGS, R"("\u7840")"sv, "\xE7\xA1\x80"sv);
+ parse_expected_value(FILE_LINE_ARGS, R"("\uAA23")"sv, "\xEA\xA8\xA3"sv);
+ parse_expected_value(FILE_LINE_ARGS, R"("\uA928")"sv, "\xEA\xA4\xA8"sv);
+ parse_expected_value(FILE_LINE_ARGS, R"("\u9CBF")"sv, "\xE9\xB2\xBF"sv);
+ parse_expected_value(FILE_LINE_ARGS, R"("\u2247")"sv, "\xE2\x89\x87"sv);
+ parse_expected_value(FILE_LINE_ARGS, R"("\u13D9")"sv, "\xE1\x8F\x99"sv);
+ parse_expected_value(FILE_LINE_ARGS, R"("\u69FC")"sv, "\xE6\xA7\xBC"sv);
+ parse_expected_value(FILE_LINE_ARGS, R"("\u8DE5")"sv, "\xE8\xB7\xA5"sv);
+ parse_expected_value(FILE_LINE_ARGS, R"("\u699C")"sv, "\xE6\xA6\x9C"sv);
+ parse_expected_value(FILE_LINE_ARGS, R"("\u8CD4")"sv, "\xE8\xB3\x94"sv);
+ parse_expected_value(FILE_LINE_ARGS, R"("\u4ED4")"sv, "\xE4\xBB\x94"sv);
+ parse_expected_value(FILE_LINE_ARGS, R"("\u2597")"sv, "\xE2\x96\x97"sv);
+ }
+
+ SECTION("tomlplusplus/issues/127") // https://github.com/marzer/tomlplusplus/issues/127
+ {
+ parse_expected_value(FILE_LINE_ARGS,
+ "12:34:56.11122233345678"sv,
+ toml::time{
+ 12,
+ 34,
+ 56,
+ 111222333u // should truncate the .45678 part
+ });
+ }
+
+ SECTION("tomlplusplus/issues/128") // https://github.com/marzer/tomlplusplus/issues/128
+ {
+ parsing_should_fail(FILE_LINE_ARGS, "\f"sv);
+ parsing_should_fail(FILE_LINE_ARGS, "\v"sv);
+ parsing_should_succeed(FILE_LINE_ARGS, " "sv);
+ parsing_should_succeed(FILE_LINE_ARGS, "\t"sv);
+ parsing_should_succeed(FILE_LINE_ARGS, "\n"sv);
+ }
+
+ SECTION("tomlplusplus/issues/129") // https://github.com/marzer/tomlplusplus/issues/129
+ {
+ parsing_should_fail(FILE_LINE_ARGS, R"(
+ hex = 0x
+ oct = 0o
+ bin = 0b
+ )"sv);
+ }
+
+ SECTION("tomlplusplus/issues/130") // https://github.com/marzer/tomlplusplus/issues/130
+ {
+ parse_expected_value(FILE_LINE_ARGS, "0400-01-01 00:00:00"sv, toml::date_time{ { 400, 1, 1 }, { 0, 0, 0 } });
+ parse_expected_value(FILE_LINE_ARGS, "0400-01-01 "sv, toml::date{ 400, 1, 1 });
+ parse_expected_value(FILE_LINE_ARGS, "0400-01-01T00:00:00"sv, toml::date_time{ { 400, 1, 1 }, { 0, 0, 0 } });
+ parse_expected_value(FILE_LINE_ARGS, "1000-01-01 00:00:00"sv, toml::date_time{ { 1000, 1, 1 }, { 0, 0, 0 } });
+ }
+
+ SECTION("tomlplusplus/issues/131") // https://github.com/marzer/tomlplusplus/issues/131
+ {
+ parsing_should_fail(FILE_LINE_ARGS, R"(
+ a={}
+ [a.b]
+ )"sv);
+ }
+
+ SECTION("tomlplusplus/issues/132") // https://github.com/marzer/tomlplusplus/issues/132
+ {
+ parsing_should_fail(FILE_LINE_ARGS, "#\r"sv);
+ }
+
+ SECTION("tomlplusplus/issues/134") // https://github.com/marzer/tomlplusplus/issues/134
+ {
+ // binary
+ parsing_should_fail(
+ FILE_LINE_ARGS,
+ "val = 0b11111111_11111111_11111111_11111111_11111111_11111111_11111111_11111111"sv); // uint64_t
+ // max
+ parsing_should_fail(
+ FILE_LINE_ARGS,
+ "val = 0b10000000_00000000_00000000_00000000_00000000_00000000_00000000_00000000"sv); // int64_t
+ // max
+ // + 1
+ parse_expected_value(FILE_LINE_ARGS,
+ "0b01111111_11111111_11111111_11111111_11111111_11111111_11111111_11111111"sv,
+ INT64_MAX); // int64_t max
+
+ // octal
+ parsing_should_fail(FILE_LINE_ARGS, " val = 0o1777777777777777777777"sv); // uint64_t max
+ parsing_should_fail(FILE_LINE_ARGS, " val = 0o1000000000000000000000"sv); // int64_t max + 1
+ parse_expected_value(FILE_LINE_ARGS, " 0o0777777777777777777777"sv, INT64_MAX);
+
+ // decimal
+ parsing_should_fail(FILE_LINE_ARGS, " val = 100000000000000000000"sv);
+ parsing_should_fail(FILE_LINE_ARGS, " val = 18446744073709551615"sv); // uint64_t max
+ parsing_should_fail(FILE_LINE_ARGS, " val = 10000000000000000000"sv);
+ parsing_should_fail(FILE_LINE_ARGS, " val = 9999999999999999999"sv);
+ parsing_should_fail(FILE_LINE_ARGS, " val = 9223372036854775808"sv); // int64_t max + 1
+ parse_expected_value(FILE_LINE_ARGS, " 9223372036854775807"sv, INT64_MAX);
+ parse_expected_value(FILE_LINE_ARGS, " 1000000000000000000"sv, 1000000000000000000LL);
+ parse_expected_value(FILE_LINE_ARGS, " -1000000000000000000"sv, -1000000000000000000LL);
+ parse_expected_value(FILE_LINE_ARGS, " -9223372036854775808"sv, INT64_MIN);
+ parsing_should_fail(FILE_LINE_ARGS, " val = -9223372036854775809"sv); // int64_t min - 1
+ parsing_should_fail(FILE_LINE_ARGS, " val = -10000000000000000000"sv);
+ parsing_should_fail(FILE_LINE_ARGS, " val = -18446744073709551615"sv); // -(uint64_t max)
+ parsing_should_fail(FILE_LINE_ARGS, " val = -100000000000000000000"sv);
+
+ // hexadecimal
+ parsing_should_fail(FILE_LINE_ARGS, " val = 0xFFFFFFFFFFFFFFFF"sv); // uint64_t max
+ parsing_should_fail(FILE_LINE_ARGS, " val = 0x8000000000000000"sv); // int64_t max + 1
+ parse_expected_value(FILE_LINE_ARGS, " 0x7FFFFFFFFFFFFFFF"sv, INT64_MAX);
+ }
+
+ SECTION("tomlplusplus/issues/135") // https://github.com/marzer/tomlplusplus/issues/135
+ {
+ parsing_should_succeed(FILE_LINE_ARGS, "0=0"sv);
+ parsing_should_succeed(FILE_LINE_ARGS, "1=1"sv);
+ parsing_should_succeed(FILE_LINE_ARGS, "2=2"sv);
+
+ parsing_should_succeed(FILE_LINE_ARGS,
+ "0=0\n"
+ "1=1\n"
+ "2=2\n"sv);
+
+ parsing_should_fail(FILE_LINE_ARGS,
+ "0=0\n"
+ "\u2000\u2000\n"
+ "1=1\n"
+ "2=2\n"sv);
+ }
+
+ SECTION("tomlplusplus/issues/152") // https://github.com/marzer/tomlplusplus/issues/152
+ {
+ // clang-format off
+ static constexpr auto data = R"([shaders.room_darker])" "\n"
+ R"(file = "room_darker.frag")" "\n"
+ R"(args = { n = "integer", ambientLightLevel = "float" })";
+ // clang-format on
+
+ parsing_should_succeed(FILE_LINE_ARGS,
+ data,
+ [](auto&& tbl)
+ {
+ const auto check_location = [&](std::string_view path, auto line, auto col)
+ {
+ INFO("Checking source location of \""sv << path << "\""sv)
+ auto v = tbl.at_path(path);
+ REQUIRE(v.node());
+ CHECK(v.node()->source().begin.line == static_cast<toml::source_index>(line));
+ CHECK(v.node()->source().begin.column == static_cast<toml::source_index>(col));
+ };
+
+ check_location("shaders"sv, 1, 1);
+ check_location("shaders.room_darker"sv, 1, 1);
+ check_location("shaders.room_darker.file"sv, 2, 8);
+ check_location("shaders.room_darker.args"sv, 3, 8);
+ check_location("shaders.room_darker.args.n"sv, 3, 14);
+ check_location("shaders.room_darker.args.ambientLightLevel"sv, 3, 45);
+ });
+ }
+
+ SECTION("toml/issues/908") // https://github.com/toml-lang/toml/issues/908
+ {
+ parsing_should_fail(FILE_LINE_ARGS, R"(
+ a = [{ b = 1 }]
+ [a.c]
+ foo = 1
+ )"sv);
+
+ parsing_should_succeed(FILE_LINE_ARGS, R"(
+ [[a]]
+ b = 1
+
+ [a.c]
+ foo = 1
+ )"sv);
+ }
+
+ SECTION("tomlplusplus/issues/169") // https://github.com/marzer/tomlplusplus/issues/169
+ {
+ parsing_should_fail(FILE_LINE_ARGS, R"(
+ [a]
+ b = [c"]
+ )"sv);
+ }
+
+ SECTION("tomlplusplus/issues/179") // https://github.com/marzer/tomlplusplus/issues/179
+ {
+ parse_expected_value(FILE_LINE_ARGS, "0.848213"sv, 0.848213);
+ parse_expected_value(FILE_LINE_ARGS, "6.9342"sv, 6.9342);
+ parse_expected_value(FILE_LINE_ARGS, "-995.9214"sv, -995.9214);
+ }
+
+ SECTION("tomlplusplus/issues/187") // https://github.com/marzer/tomlplusplus/issues/187
+ {
+ parsing_should_succeed(FILE_LINE_ARGS, R"(
+ [[a.b]]
+ x = 1
+
+ [a]
+ y = 2
+ )"sv);
+ }
+
+ SECTION("tomlplusplus/issues/207") // https://github.com/marzer/tomlplusplus/issues/207
+ {
+ enum class an_enum
+ {
+ zero,
+ one,
+ two,
+ three
+ };
+
+ parsing_should_succeed(FILE_LINE_ARGS,
+ "val = 2\n",
+ [](auto&& tbl)
+ {
+ const auto val = tbl["val"].template value_or<an_enum>(an_enum::zero);
+ CHECK(val == an_enum::two);
+ });
+ }
+
+ SECTION("tomlplusplus/issues/176") // https://github.com/marzer/tomlplusplus/issues/176
+ {
+ parsing_should_succeed(FILE_LINE_ARGS, " a = \"x\\ty\""sv);
+ parsing_should_succeed(FILE_LINE_ARGS, "\"a\" = \"x\\ty\""sv);
+ parsing_should_succeed(FILE_LINE_ARGS, "\"a\tb\" = \"x\\ty\""sv);
+ parsing_should_fail(FILE_LINE_ARGS, "\"a\nb\" = \"x\\ty\""sv); // literal newline in single-line key
+
+ static constexpr auto input = R"(
+ "a" = "x\ty"
+ "a\tb" = "x\ty"
+ "a\nb" = "x\ty"
+ )"sv;
+
+ static constexpr auto output = "a = 'x\ty'\n"
+ "\"a\\tb\" = 'x\ty'\n" // tab and newlines in keys should be emitted
+ "\"a\\nb\" = 'x\ty'" // as escapes, not literals
+ ""sv;
+
+ parsing_should_succeed(FILE_LINE_ARGS,
+ input,
+ [&](auto&& tbl)
+ {
+ CHECK(tbl["a"]);
+ CHECK(tbl["a\tb"]);
+ CHECK(tbl["a\nb"]);
+
+ std::stringstream ss;
+ ss << tbl;
+ CHECK(ss.str() == output);
+ });
+ }
+
+ SECTION("tomlplusplus/pull/244") // https://github.com/marzer/tomlplusplus/pull/244
+ {
+ std::ostringstream oss;
+ oss << toml::source_region{ { 1, 2 }, { 3, 4 }, nullptr };
+ CHECK(oss.str() == "line 1, column 2 to line 3, column 4");
+ }
+
+ SECTION("tomlplusplus/issues/254") // https://github.com/marzer/tomlplusplus/issues/254
+ {
+ // Check constexpr support.
+ static_assert(!toml::get_line(""sv, 1));
+ static_assert(toml::get_line("alpha = 1\nbeta = 2\n # last line # "sv, 1) == "alpha = 1"sv);
+
+ for (const toml::source_index line_num : { 0u, 1u, 2u })
+ {
+ CHECK(!toml::get_line(""sv, line_num));
+ }
+
+ for (const auto input : {
+ "# \r (embedded carriage return)"sv,
+ "# \r (embedded carriage return)\n"sv,
+ "# \r (embedded carriage return)\r\n"sv,
+ })
+ {
+ CHECK(!toml::get_line(input, 0));
+ CHECK(toml::get_line(input, 1) == "# \r (embedded carriage return)"sv);
+ CHECK(!toml::get_line(input, 2));
+ }
+
+ for (const auto input : {
+ "alpha = 1\nbeta = 2\n\n # last line # "sv,
+ "alpha = 1\nbeta = 2\n\n # last line # \n"sv,
+ "alpha = 1\r\nbeta = 2\r\n\r\n # last line # \r\n"sv,
+ })
+ {
+ CHECK(!toml::get_line(input, 0));
+ CHECK(toml::get_line(input, 1) == "alpha = 1"sv);
+ CHECK(toml::get_line(input, 2) == "beta = 2"sv);
+ CHECK(toml::get_line(input, 3) == ""sv);
+ CHECK(toml::get_line(input, 4) == " # last line # "sv);
+ CHECK(!toml::get_line(input, 5));
+ }
+ }
+}
diff --git a/tomlplusplus/tests/using_iterators.cpp b/tomlplusplus/tests/using_iterators.cpp
new file mode 100644
index 0000000000..cbc4bbe636
--- /dev/null
+++ b/tomlplusplus/tests/using_iterators.cpp
@@ -0,0 +1,52 @@
+#include "tests.hpp"
+
+TOML_DISABLE_WARNINGS;
+#include <algorithm>
+TOML_ENABLE_WARNINGS;
+
+TEST_CASE("using iterators")
+{
+ constexpr auto data = R"(array=[1,"Foo",true]
+string="Bar"
+number=5)"sv;
+ parsing_should_succeed(
+ FILE_LINE_ARGS,
+ data,
+ [](auto&& tbl)
+ {
+ const auto tbl_begin = tbl.begin();
+ const auto tbl_end = tbl.end();
+
+ auto count_table_lambda = [tbl_begin, tbl_end](node_type type) noexcept {
+ return std::count_if(tbl_begin,
+ tbl_end,
+ [type](const auto& pair) noexcept { return pair.second.type() == type; });
+ };
+
+ CHECK(std::distance(tbl_begin, tbl_end) == 3);
+ CHECK(count_table_lambda(node_type::table) == 0);
+ CHECK(count_table_lambda(node_type::integer) == 1);
+ CHECK(count_table_lambda(node_type::string) == 1);
+ CHECK(std::next(tbl_begin, 3) == tbl_end);
+
+ const auto arr_iter =
+ std::find_if(tbl_begin, tbl_end, [](const auto& pair) noexcept { return pair.second.is_array(); });
+
+ REQUIRE(arr_iter != tbl_end);
+ const auto& arr = arr_iter->second.as_array();
+ const auto arr_begin = arr->begin();
+ const auto arr_end = arr->end();
+
+ auto count_array_lambda = [arr_begin, arr_end](node_type type) noexcept {
+ return std::count_if(arr_begin,
+ arr_end,
+ [type](const auto& node) noexcept { return node.type() == type; });
+ };
+
+ CHECK(std::distance(arr_begin, arr_end) == 3);
+ CHECK(count_array_lambda(node_type::table) == 0);
+ CHECK(count_array_lambda(node_type::integer) == 1);
+ CHECK(count_array_lambda(node_type::string) == 1);
+ CHECK(std::next(arr_begin, 2) != arr_end);
+ });
+}
diff --git a/tomlplusplus/tests/visit.cpp b/tomlplusplus/tests/visit.cpp
new file mode 100644
index 0000000000..efc3c5f30e
--- /dev/null
+++ b/tomlplusplus/tests/visit.cpp
@@ -0,0 +1,139 @@
+// This file is a part of toml++ and is subject to the the terms of the MIT license.
+// Copyright (c) Mark Gillard <mark.gillard@outlook.com.au>
+// See https://github.com/marzer/tomlplusplus/blob/master/LICENSE for the full license text.
+// SPDX-License-Identifier: MIT
+
+#include "tests.hpp"
+TOML_DISABLE_SPAM_WARNINGS;
+
+TEST_CASE("node::visit")
+{
+ value<int64_t> val{ 3 };
+
+ // check lvalue propagates correctly
+ static_cast<node&>(val).visit(
+ [](auto&& v) noexcept
+ {
+ using val_ref_type = decltype(v);
+ static_assert(std::is_lvalue_reference_v<val_ref_type>);
+
+ using val_type = std::remove_reference_t<val_ref_type>;
+ static_assert(!std::is_const_v<val_type>);
+ static_assert(!std::is_volatile_v<val_type>);
+ });
+
+ // check rvalue propagates correctly
+ static_cast<node&&>(val).visit(
+ [](auto&& v) noexcept
+ {
+ using val_ref_type = decltype(v);
+ static_assert(std::is_rvalue_reference_v<val_ref_type>);
+
+ using val_type = std::remove_reference_t<val_ref_type>;
+ static_assert(!std::is_const_v<val_type>);
+ static_assert(!std::is_volatile_v<val_type>);
+ });
+
+ // check const lvalue propagates correctly
+ static_cast<const node&>(val).visit(
+ [](auto&& v) noexcept
+ {
+ using val_ref_type = decltype(v);
+ static_assert(std::is_lvalue_reference_v<val_ref_type>);
+
+ using val_type = std::remove_reference_t<val_ref_type>;
+ static_assert(std::is_const_v<val_type>);
+ static_assert(!std::is_volatile_v<val_type>);
+ });
+
+ // check const rvalue propagates correctly
+ static_cast<const node&&>(val).visit(
+ [](auto&& v) noexcept
+ {
+ using val_ref_type = decltype(v);
+ static_assert(std::is_rvalue_reference_v<val_ref_type>);
+
+ using val_type = std::remove_reference_t<val_ref_type>;
+ static_assert(std::is_const_v<val_type>);
+ static_assert(!std::is_volatile_v<val_type>);
+ });
+
+ // check noexcept
+ static constexpr auto throwing_visitor = [](auto&&) noexcept(false) {};
+ static constexpr auto non_throwing_visitor = [](auto&&) noexcept(true) {};
+ static_assert(!noexcept(static_cast<node&>(val).visit(throwing_visitor)));
+ static_assert(!noexcept(static_cast<node&&>(val).visit(throwing_visitor)));
+ static_assert(!noexcept(static_cast<const node&>(val).visit(throwing_visitor)));
+ static_assert(!noexcept(static_cast<const node&&>(val).visit(throwing_visitor)));
+ static_assert(noexcept(static_cast<node&>(val).visit(non_throwing_visitor)));
+ static_assert(noexcept(static_cast<node&&>(val).visit(non_throwing_visitor)));
+ static_assert(noexcept(static_cast<const node&>(val).visit(non_throwing_visitor)));
+ static_assert(noexcept(static_cast<const node&&>(val).visit(non_throwing_visitor)));
+
+ // check return
+ static constexpr auto returns_boolean = [](auto& v) noexcept { return toml::is_integer<decltype(v)>; };
+ auto return_test = static_cast<node&>(val).visit(returns_boolean);
+ static_assert(std::is_same_v<decltype(return_test), bool>);
+ CHECK(return_test == true);
+}
+
+TEST_CASE("node_view::visit")
+{
+ value<int64_t> val{ 3 };
+
+ auto view = node_view{ val };
+ auto cview = node_view{ std::as_const(val) };
+ static_assert(!std::is_same_v<decltype(view), decltype(cview)>);
+
+ // check mutable views propagate correctly
+ view.visit(
+ [](auto&& v) noexcept
+ {
+ using val_ref_type = decltype(v);
+ static_assert(std::is_lvalue_reference_v<val_ref_type>);
+
+ using val_type = std::remove_reference_t<val_ref_type>;
+ static_assert(!std::is_const_v<val_type>);
+ static_assert(!std::is_volatile_v<val_type>);
+ });
+
+ // check const views propagate correctly
+ cview.visit(
+ [](auto&& v) noexcept
+ {
+ using val_ref_type = decltype(v);
+ static_assert(std::is_lvalue_reference_v<val_ref_type>);
+
+ using val_type = std::remove_reference_t<val_ref_type>;
+ static_assert(std::is_const_v<val_type>);
+ static_assert(!std::is_volatile_v<val_type>);
+ });
+
+ // check noexcept
+ static constexpr auto throwing_visitor = [](auto&&) noexcept(false) {};
+ static constexpr auto non_throwing_visitor = [](auto&&) noexcept(true) {};
+ static_assert(!noexcept(view.visit(throwing_visitor)));
+ static_assert(!noexcept(cview.visit(throwing_visitor)));
+ static_assert(noexcept(view.visit(non_throwing_visitor)));
+ static_assert(noexcept(cview.visit(non_throwing_visitor)));
+
+ // check return
+ static constexpr auto returns_boolean = [](auto&& v) noexcept { return toml::is_integer<decltype(v)>; };
+ auto return_test = view.visit(returns_boolean);
+ static_assert(std::is_same_v<decltype(return_test), bool>);
+ CHECK(return_test == true);
+
+ // check that null views don't invoke the visitor
+ // clang-format off
+ auto null_view = decltype(view){};
+ auto null_cview = decltype(cview){};
+ unsigned count{};
+ unsigned mask{};
+ view.visit([&](auto&&) noexcept { count++; mask |= 0b0001u; });
+ cview.visit([&](auto&&) noexcept { count++; mask |= 0b0010u; });
+ null_view.visit([&](auto&&) noexcept { count++; mask |= 0b0100u; });
+ null_cview.visit([&](auto&&) noexcept { count++; mask |= 0b1000u; });
+ CHECK(count == 2u);
+ CHECK(mask == 0b0011u);
+ // clang-format on
+}
diff --git a/tomlplusplus/tests/vs/odr_test.vcxproj b/tomlplusplus/tests/vs/odr_test.vcxproj
new file mode 100644
index 0000000000..31da645984
--- /dev/null
+++ b/tomlplusplus/tests/vs/odr_test.vcxproj
@@ -0,0 +1,82 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup Label="ProjectConfigurations">
+ <ProjectConfiguration Include="Debug|x64">
+ <Configuration>Debug</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|x64">
+ <Configuration>Release</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ </ItemGroup>
+ <PropertyGroup Label="Globals">
+ <VCProjectVersion>16.0</VCProjectVersion>
+ <ProjectGuid>{723FC4CA-0E24-4956-8FDC-E537EA3847AA}</ProjectGuid>
+ <WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
+ <PreferredToolArchitecture>x64</PreferredToolArchitecture>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <UseDebugLibraries>true</UseDebugLibraries>
+ <PlatformToolset>v143</PlatformToolset>
+ <CharacterSet>MultiByte</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <UseDebugLibraries>false</UseDebugLibraries>
+ <PlatformToolset>v143</PlatformToolset>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ <CharacterSet>MultiByte</CharacterSet>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <ImportGroup Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <Import Project="../../toml++.props" />
+ <ItemDefinitionGroup>
+ <ClCompile>
+ <AdditionalIncludeDirectories>..\tests;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <ExceptionHandling>Sync</ExceptionHandling>
+ <PrecompiledHeader>NotUsing</PrecompiledHeader>
+ <LanguageStandard>stdcpp17</LanguageStandard>
+ <MultiProcessorCompilation>true</MultiProcessorCompilation>
+ <WarningLevel>EnableAllWarnings</WarningLevel>
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4127</DisableSpecificWarnings> <!-- conditional expr is constant -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4324</DisableSpecificWarnings> <!-- structure was padded due to alignment specifier -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4464</DisableSpecificWarnings> <!-- relative include path contains '..' -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4505</DisableSpecificWarnings> <!-- unreferenced local function removed -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4514</DisableSpecificWarnings> <!-- unreferenced inline function has been removed -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4577</DisableSpecificWarnings> <!-- 'noexcept' used with no exception handling mode specified -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4582</DisableSpecificWarnings> <!-- constructor is not implicitly called -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4623</DisableSpecificWarnings> <!-- default constructor was implicitly defined as deleted -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4625</DisableSpecificWarnings> <!-- copy constructor was implicitly defined as deleted -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4626</DisableSpecificWarnings> <!-- assignment operator was implicitly defined as deleted -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4710</DisableSpecificWarnings> <!-- function not inlined -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4711</DisableSpecificWarnings> <!-- function selected for automatic expansion -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4738</DisableSpecificWarnings> <!-- storing 32-bit float result in memory -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4820</DisableSpecificWarnings> <!-- N bytes padding added -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4866</DisableSpecificWarnings> <!-- compiler may not enforce ltr eval in operator[] -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4868</DisableSpecificWarnings> <!-- compiler may not enforce ltr eval in initializer list -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4946</DisableSpecificWarnings> <!-- reinterpret_cast used between related classes -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);5026</DisableSpecificWarnings> <!-- move constructor was implicitly defined as deleted -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);5027</DisableSpecificWarnings> <!-- move assignment operator was implicitly defined as deleted -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);5039</DisableSpecificWarnings> <!-- potentially throwing function passed to 'extern "C"' -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);5045</DisableSpecificWarnings> <!-- Compiler will insert Spectre mitigation -->
+ </ClCompile>
+ </ItemDefinitionGroup>
+ <PropertyGroup>
+ <LocalDebuggerWorkingDirectory>$(ProjectDir)..\</LocalDebuggerWorkingDirectory>
+ </PropertyGroup>
+ <ItemGroup>
+ <ClCompile Include="..\odr_test_1.cpp" />
+ <ClCompile Include="..\odr_test_2.cpp" />
+ </ItemGroup>
+ <ItemGroup>
+ </ItemGroup>
+ <ItemGroup>
+ <None Include="..\meson.build" />
+ </ItemGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+</Project>
diff --git a/tomlplusplus/tests/vs/test_debug_x64.vcxproj b/tomlplusplus/tests/vs/test_debug_x64.vcxproj
new file mode 100644
index 0000000000..63573b02b2
--- /dev/null
+++ b/tomlplusplus/tests/vs/test_debug_x64.vcxproj
@@ -0,0 +1,127 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup Label="ProjectConfigurations">
+ <ProjectConfiguration Include="Debug|x64">
+ <Configuration>Debug</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ </ItemGroup>
+ <PropertyGroup Label="Globals">
+ <VCProjectVersion>16.0</VCProjectVersion>
+ <ProjectGuid>{202DCF23-B4E4-5FB9-AFA8-CC9A718067FF}</ProjectGuid>
+ <WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
+ <PreferredToolArchitecture>x64</PreferredToolArchitecture>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <UseDebugLibraries>true</UseDebugLibraries>
+ <PlatformToolset>v143</PlatformToolset>
+ <CharacterSet>MultiByte</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <UseDebugLibraries>false</UseDebugLibraries>
+ <PlatformToolset>v143</PlatformToolset>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ <CharacterSet>MultiByte</CharacterSet>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <ImportGroup Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props"
+ Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <Import Project="../../toml++.props" />
+ <ItemDefinitionGroup>
+ <ClCompile>
+ <AdditionalIncludeDirectories>..\tests;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <ExceptionHandling>Sync</ExceptionHandling>
+ <PrecompiledHeader>Use</PrecompiledHeader>
+ <PrecompiledHeaderFile>tests.hpp</PrecompiledHeaderFile>
+ <PreprocessorDefinitions>TOML_ENABLE_UNRELEASED_FEATURES=0;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <PreprocessorDefinitions>LEAK_TESTS=1;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'%(ExceptionHandling)'=='false'">_HAS_EXCEPTIONS=0;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'%(ExceptionHandling)'=='false'">SHOULD_HAVE_EXCEPTIONS=0;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'%(ExceptionHandling)'!='false'">SHOULD_HAVE_EXCEPTIONS=1;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <LanguageStandard>stdcpp17</LanguageStandard>
+ <MultiProcessorCompilation>true</MultiProcessorCompilation>
+ <WarningLevel>EnableAllWarnings</WarningLevel>
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4127</DisableSpecificWarnings> <!-- conditional expr is constant -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4324</DisableSpecificWarnings> <!-- structure was padded due to alignment specifier -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4464</DisableSpecificWarnings> <!-- relative include path contains '..' -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4505</DisableSpecificWarnings> <!-- unreferenced local function removed -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4514</DisableSpecificWarnings> <!-- unreferenced inline function has been removed -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4577</DisableSpecificWarnings> <!-- 'noexcept' used with no exception handling mode specified -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4582</DisableSpecificWarnings> <!-- constructor is not implicitly called -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4623</DisableSpecificWarnings> <!-- default constructor was implicitly defined as deleted -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4625</DisableSpecificWarnings> <!-- copy constructor was implicitly defined as deleted -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4626</DisableSpecificWarnings> <!-- assignment operator was implicitly defined as deleted -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4710</DisableSpecificWarnings> <!-- function not inlined -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4711</DisableSpecificWarnings> <!-- function selected for automatic expansion -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4738</DisableSpecificWarnings> <!-- storing 32-bit float result in memory -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4820</DisableSpecificWarnings> <!-- N bytes padding added -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4866</DisableSpecificWarnings> <!-- compiler may not enforce ltr eval in operator[] -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4868</DisableSpecificWarnings> <!-- compiler may not enforce ltr eval in initializer list -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4946</DisableSpecificWarnings> <!-- reinterpret_cast used between related classes -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);5026</DisableSpecificWarnings> <!-- move constructor was implicitly defined as deleted -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);5027</DisableSpecificWarnings> <!-- move assignment operator was implicitly defined as deleted -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);5039</DisableSpecificWarnings> <!-- potentially throwing function passed to 'extern "C"' -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);5045</DisableSpecificWarnings> <!-- Compiler will insert Spectre mitigation -->
+ </ClCompile>
+ </ItemDefinitionGroup>
+ <PropertyGroup>
+ <LocalDebuggerWorkingDirectory>$(ProjectDir)..\</LocalDebuggerWorkingDirectory>
+ </PropertyGroup>
+ <ItemGroup>
+ <ClCompile Include="..\at_path.cpp" />
+ <ClCompile Include="..\path.cpp" />
+ <ClCompile Include="..\conformance_burntsushi_invalid.cpp" />
+ <ClCompile Include="..\conformance_burntsushi_valid.cpp" />
+ <ClCompile Include="..\conformance_iarna_invalid.cpp" />
+ <ClCompile Include="..\conformance_iarna_valid.cpp" />
+ <ClCompile Include="..\for_each.cpp" />
+ <ClCompile Include="..\formatters.cpp" />
+ <ClCompile Include="..\impl_toml.cpp">
+ <PrecompiledHeader>NotUsing</PrecompiledHeader>
+ </ClCompile>
+ <ClCompile Include="..\main.cpp">
+ <PrecompiledHeader>NotUsing</PrecompiledHeader>
+ </ClCompile>
+ <ClCompile Include="..\manipulating_arrays.cpp" />
+ <ClCompile Include="..\manipulating_tables.cpp" />
+ <ClCompile Include="..\manipulating_parse_result.cpp" />
+ <ClCompile Include="..\manipulating_values.cpp" />
+ <ClCompile Include="..\parsing_arrays.cpp" />
+ <ClCompile Include="..\parsing_booleans.cpp" />
+ <ClCompile Include="..\parsing_comments.cpp" />
+ <ClCompile Include="..\parsing_dates_and_times.cpp" />
+ <ClCompile Include="..\parsing_floats.cpp" />
+ <ClCompile Include="..\parsing_integers.cpp" />
+ <ClCompile Include="..\parsing_key_value_pairs.cpp" />
+ <ClCompile Include="..\parsing_spec_example.cpp" />
+ <ClCompile Include="..\parsing_strings.cpp" />
+ <ClCompile Include="..\parsing_tables.cpp" />
+ <ClCompile Include="..\tests.cpp">
+ <PrecompiledHeader>Create</PrecompiledHeader>
+ </ClCompile>
+ <ClCompile Include="..\user_feedback.cpp" />
+ <ClCompile Include="..\using_iterators.cpp" />
+ <ClCompile Include="..\visit.cpp" />
+ <ClCompile Include="..\windows_compat.cpp" />
+ </ItemGroup>
+ <ItemGroup>
+ <Natvis Include="..\..\toml++.natvis" />
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="..\leakproof.hpp" />
+ <ClInclude Include="..\lib_catch2.hpp" />
+ <ClInclude Include="..\lib_tloptional.hpp" />
+ <ClInclude Include="..\settings.hpp" />
+ <ClInclude Include="..\tests.hpp" />
+ </ItemGroup>
+ <ItemGroup>
+ <None Include="..\cpp.hint" />
+ <None Include="..\meson.build" />
+ </ItemGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+</Project>
diff --git a/tomlplusplus/tests/vs/test_debug_x64_cpplatest.vcxproj b/tomlplusplus/tests/vs/test_debug_x64_cpplatest.vcxproj
new file mode 100644
index 0000000000..9580b5320f
--- /dev/null
+++ b/tomlplusplus/tests/vs/test_debug_x64_cpplatest.vcxproj
@@ -0,0 +1,127 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup Label="ProjectConfigurations">
+ <ProjectConfiguration Include="Debug|x64">
+ <Configuration>Debug</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ </ItemGroup>
+ <PropertyGroup Label="Globals">
+ <VCProjectVersion>16.0</VCProjectVersion>
+ <ProjectGuid>{B0B1EA1E-611A-59B6-939F-0A891C71BBF0}</ProjectGuid>
+ <WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
+ <PreferredToolArchitecture>x64</PreferredToolArchitecture>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <UseDebugLibraries>true</UseDebugLibraries>
+ <PlatformToolset>v143</PlatformToolset>
+ <CharacterSet>MultiByte</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <UseDebugLibraries>false</UseDebugLibraries>
+ <PlatformToolset>v143</PlatformToolset>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ <CharacterSet>MultiByte</CharacterSet>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <ImportGroup Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props"
+ Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <Import Project="../../toml++.props" />
+ <ItemDefinitionGroup>
+ <ClCompile>
+ <AdditionalIncludeDirectories>..\tests;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <ExceptionHandling>Sync</ExceptionHandling>
+ <PrecompiledHeader>Use</PrecompiledHeader>
+ <PrecompiledHeaderFile>tests.hpp</PrecompiledHeaderFile>
+ <PreprocessorDefinitions>TOML_ENABLE_UNRELEASED_FEATURES=0;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <PreprocessorDefinitions>LEAK_TESTS=1;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'%(ExceptionHandling)'=='false'">_HAS_EXCEPTIONS=0;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'%(ExceptionHandling)'=='false'">SHOULD_HAVE_EXCEPTIONS=0;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'%(ExceptionHandling)'!='false'">SHOULD_HAVE_EXCEPTIONS=1;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <LanguageStandard>stdcpplatest</LanguageStandard>
+ <MultiProcessorCompilation>true</MultiProcessorCompilation>
+ <WarningLevel>EnableAllWarnings</WarningLevel>
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4127</DisableSpecificWarnings> <!-- conditional expr is constant -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4324</DisableSpecificWarnings> <!-- structure was padded due to alignment specifier -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4464</DisableSpecificWarnings> <!-- relative include path contains '..' -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4505</DisableSpecificWarnings> <!-- unreferenced local function removed -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4514</DisableSpecificWarnings> <!-- unreferenced inline function has been removed -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4577</DisableSpecificWarnings> <!-- 'noexcept' used with no exception handling mode specified -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4582</DisableSpecificWarnings> <!-- constructor is not implicitly called -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4623</DisableSpecificWarnings> <!-- default constructor was implicitly defined as deleted -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4625</DisableSpecificWarnings> <!-- copy constructor was implicitly defined as deleted -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4626</DisableSpecificWarnings> <!-- assignment operator was implicitly defined as deleted -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4710</DisableSpecificWarnings> <!-- function not inlined -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4711</DisableSpecificWarnings> <!-- function selected for automatic expansion -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4738</DisableSpecificWarnings> <!-- storing 32-bit float result in memory -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4820</DisableSpecificWarnings> <!-- N bytes padding added -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4866</DisableSpecificWarnings> <!-- compiler may not enforce ltr eval in operator[] -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4868</DisableSpecificWarnings> <!-- compiler may not enforce ltr eval in initializer list -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4946</DisableSpecificWarnings> <!-- reinterpret_cast used between related classes -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);5026</DisableSpecificWarnings> <!-- move constructor was implicitly defined as deleted -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);5027</DisableSpecificWarnings> <!-- move assignment operator was implicitly defined as deleted -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);5039</DisableSpecificWarnings> <!-- potentially throwing function passed to 'extern "C"' -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);5045</DisableSpecificWarnings> <!-- Compiler will insert Spectre mitigation -->
+ </ClCompile>
+ </ItemDefinitionGroup>
+ <PropertyGroup>
+ <LocalDebuggerWorkingDirectory>$(ProjectDir)..\</LocalDebuggerWorkingDirectory>
+ </PropertyGroup>
+ <ItemGroup>
+ <ClCompile Include="..\at_path.cpp" />
+ <ClCompile Include="..\path.cpp" />
+ <ClCompile Include="..\conformance_burntsushi_invalid.cpp" />
+ <ClCompile Include="..\conformance_burntsushi_valid.cpp" />
+ <ClCompile Include="..\conformance_iarna_invalid.cpp" />
+ <ClCompile Include="..\conformance_iarna_valid.cpp" />
+ <ClCompile Include="..\for_each.cpp" />
+ <ClCompile Include="..\formatters.cpp" />
+ <ClCompile Include="..\impl_toml.cpp">
+ <PrecompiledHeader>NotUsing</PrecompiledHeader>
+ </ClCompile>
+ <ClCompile Include="..\main.cpp">
+ <PrecompiledHeader>NotUsing</PrecompiledHeader>
+ </ClCompile>
+ <ClCompile Include="..\manipulating_arrays.cpp" />
+ <ClCompile Include="..\manipulating_tables.cpp" />
+ <ClCompile Include="..\manipulating_parse_result.cpp" />
+ <ClCompile Include="..\manipulating_values.cpp" />
+ <ClCompile Include="..\parsing_arrays.cpp" />
+ <ClCompile Include="..\parsing_booleans.cpp" />
+ <ClCompile Include="..\parsing_comments.cpp" />
+ <ClCompile Include="..\parsing_dates_and_times.cpp" />
+ <ClCompile Include="..\parsing_floats.cpp" />
+ <ClCompile Include="..\parsing_integers.cpp" />
+ <ClCompile Include="..\parsing_key_value_pairs.cpp" />
+ <ClCompile Include="..\parsing_spec_example.cpp" />
+ <ClCompile Include="..\parsing_strings.cpp" />
+ <ClCompile Include="..\parsing_tables.cpp" />
+ <ClCompile Include="..\tests.cpp">
+ <PrecompiledHeader>Create</PrecompiledHeader>
+ </ClCompile>
+ <ClCompile Include="..\user_feedback.cpp" />
+ <ClCompile Include="..\using_iterators.cpp" />
+ <ClCompile Include="..\visit.cpp" />
+ <ClCompile Include="..\windows_compat.cpp" />
+ </ItemGroup>
+ <ItemGroup>
+ <Natvis Include="..\..\toml++.natvis" />
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="..\leakproof.hpp" />
+ <ClInclude Include="..\lib_catch2.hpp" />
+ <ClInclude Include="..\lib_tloptional.hpp" />
+ <ClInclude Include="..\settings.hpp" />
+ <ClInclude Include="..\tests.hpp" />
+ </ItemGroup>
+ <ItemGroup>
+ <None Include="..\cpp.hint" />
+ <None Include="..\meson.build" />
+ </ItemGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+</Project>
diff --git a/tomlplusplus/tests/vs/test_debug_x64_cpplatest_noexcept.vcxproj b/tomlplusplus/tests/vs/test_debug_x64_cpplatest_noexcept.vcxproj
new file mode 100644
index 0000000000..786eb737af
--- /dev/null
+++ b/tomlplusplus/tests/vs/test_debug_x64_cpplatest_noexcept.vcxproj
@@ -0,0 +1,127 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup Label="ProjectConfigurations">
+ <ProjectConfiguration Include="Debug|x64">
+ <Configuration>Debug</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ </ItemGroup>
+ <PropertyGroup Label="Globals">
+ <VCProjectVersion>16.0</VCProjectVersion>
+ <ProjectGuid>{2D040A50-F533-5977-AF7F-B25C29112025}</ProjectGuid>
+ <WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
+ <PreferredToolArchitecture>x64</PreferredToolArchitecture>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <UseDebugLibraries>true</UseDebugLibraries>
+ <PlatformToolset>v143</PlatformToolset>
+ <CharacterSet>MultiByte</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <UseDebugLibraries>false</UseDebugLibraries>
+ <PlatformToolset>v143</PlatformToolset>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ <CharacterSet>MultiByte</CharacterSet>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <ImportGroup Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props"
+ Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <Import Project="../../toml++.props" />
+ <ItemDefinitionGroup>
+ <ClCompile>
+ <AdditionalIncludeDirectories>..\tests;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <ExceptionHandling>false</ExceptionHandling>
+ <PrecompiledHeader>Use</PrecompiledHeader>
+ <PrecompiledHeaderFile>tests.hpp</PrecompiledHeaderFile>
+ <PreprocessorDefinitions>TOML_ENABLE_UNRELEASED_FEATURES=0;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <PreprocessorDefinitions>LEAK_TESTS=1;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'%(ExceptionHandling)'=='false'">_HAS_EXCEPTIONS=0;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'%(ExceptionHandling)'=='false'">SHOULD_HAVE_EXCEPTIONS=0;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'%(ExceptionHandling)'!='false'">SHOULD_HAVE_EXCEPTIONS=1;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <LanguageStandard>stdcpplatest</LanguageStandard>
+ <MultiProcessorCompilation>true</MultiProcessorCompilation>
+ <WarningLevel>EnableAllWarnings</WarningLevel>
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4127</DisableSpecificWarnings> <!-- conditional expr is constant -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4324</DisableSpecificWarnings> <!-- structure was padded due to alignment specifier -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4464</DisableSpecificWarnings> <!-- relative include path contains '..' -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4505</DisableSpecificWarnings> <!-- unreferenced local function removed -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4514</DisableSpecificWarnings> <!-- unreferenced inline function has been removed -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4577</DisableSpecificWarnings> <!-- 'noexcept' used with no exception handling mode specified -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4582</DisableSpecificWarnings> <!-- constructor is not implicitly called -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4623</DisableSpecificWarnings> <!-- default constructor was implicitly defined as deleted -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4625</DisableSpecificWarnings> <!-- copy constructor was implicitly defined as deleted -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4626</DisableSpecificWarnings> <!-- assignment operator was implicitly defined as deleted -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4710</DisableSpecificWarnings> <!-- function not inlined -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4711</DisableSpecificWarnings> <!-- function selected for automatic expansion -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4738</DisableSpecificWarnings> <!-- storing 32-bit float result in memory -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4820</DisableSpecificWarnings> <!-- N bytes padding added -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4866</DisableSpecificWarnings> <!-- compiler may not enforce ltr eval in operator[] -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4868</DisableSpecificWarnings> <!-- compiler may not enforce ltr eval in initializer list -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4946</DisableSpecificWarnings> <!-- reinterpret_cast used between related classes -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);5026</DisableSpecificWarnings> <!-- move constructor was implicitly defined as deleted -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);5027</DisableSpecificWarnings> <!-- move assignment operator was implicitly defined as deleted -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);5039</DisableSpecificWarnings> <!-- potentially throwing function passed to 'extern "C"' -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);5045</DisableSpecificWarnings> <!-- Compiler will insert Spectre mitigation -->
+ </ClCompile>
+ </ItemDefinitionGroup>
+ <PropertyGroup>
+ <LocalDebuggerWorkingDirectory>$(ProjectDir)..\</LocalDebuggerWorkingDirectory>
+ </PropertyGroup>
+ <ItemGroup>
+ <ClCompile Include="..\at_path.cpp" />
+ <ClCompile Include="..\path.cpp" />
+ <ClCompile Include="..\conformance_burntsushi_invalid.cpp" />
+ <ClCompile Include="..\conformance_burntsushi_valid.cpp" />
+ <ClCompile Include="..\conformance_iarna_invalid.cpp" />
+ <ClCompile Include="..\conformance_iarna_valid.cpp" />
+ <ClCompile Include="..\for_each.cpp" />
+ <ClCompile Include="..\formatters.cpp" />
+ <ClCompile Include="..\impl_toml.cpp">
+ <PrecompiledHeader>NotUsing</PrecompiledHeader>
+ </ClCompile>
+ <ClCompile Include="..\main.cpp">
+ <PrecompiledHeader>NotUsing</PrecompiledHeader>
+ </ClCompile>
+ <ClCompile Include="..\manipulating_arrays.cpp" />
+ <ClCompile Include="..\manipulating_tables.cpp" />
+ <ClCompile Include="..\manipulating_parse_result.cpp" />
+ <ClCompile Include="..\manipulating_values.cpp" />
+ <ClCompile Include="..\parsing_arrays.cpp" />
+ <ClCompile Include="..\parsing_booleans.cpp" />
+ <ClCompile Include="..\parsing_comments.cpp" />
+ <ClCompile Include="..\parsing_dates_and_times.cpp" />
+ <ClCompile Include="..\parsing_floats.cpp" />
+ <ClCompile Include="..\parsing_integers.cpp" />
+ <ClCompile Include="..\parsing_key_value_pairs.cpp" />
+ <ClCompile Include="..\parsing_spec_example.cpp" />
+ <ClCompile Include="..\parsing_strings.cpp" />
+ <ClCompile Include="..\parsing_tables.cpp" />
+ <ClCompile Include="..\tests.cpp">
+ <PrecompiledHeader>Create</PrecompiledHeader>
+ </ClCompile>
+ <ClCompile Include="..\user_feedback.cpp" />
+ <ClCompile Include="..\using_iterators.cpp" />
+ <ClCompile Include="..\visit.cpp" />
+ <ClCompile Include="..\windows_compat.cpp" />
+ </ItemGroup>
+ <ItemGroup>
+ <Natvis Include="..\..\toml++.natvis" />
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="..\leakproof.hpp" />
+ <ClInclude Include="..\lib_catch2.hpp" />
+ <ClInclude Include="..\lib_tloptional.hpp" />
+ <ClInclude Include="..\settings.hpp" />
+ <ClInclude Include="..\tests.hpp" />
+ </ItemGroup>
+ <ItemGroup>
+ <None Include="..\cpp.hint" />
+ <None Include="..\meson.build" />
+ </ItemGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+</Project>
diff --git a/tomlplusplus/tests/vs/test_debug_x64_cpplatest_noexcept_unrel.vcxproj b/tomlplusplus/tests/vs/test_debug_x64_cpplatest_noexcept_unrel.vcxproj
new file mode 100644
index 0000000000..eb327914eb
--- /dev/null
+++ b/tomlplusplus/tests/vs/test_debug_x64_cpplatest_noexcept_unrel.vcxproj
@@ -0,0 +1,127 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup Label="ProjectConfigurations">
+ <ProjectConfiguration Include="Debug|x64">
+ <Configuration>Debug</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ </ItemGroup>
+ <PropertyGroup Label="Globals">
+ <VCProjectVersion>16.0</VCProjectVersion>
+ <ProjectGuid>{50988C9F-99C8-59C2-BCAA-AA1F0848472E}</ProjectGuid>
+ <WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
+ <PreferredToolArchitecture>x64</PreferredToolArchitecture>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <UseDebugLibraries>true</UseDebugLibraries>
+ <PlatformToolset>v143</PlatformToolset>
+ <CharacterSet>MultiByte</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <UseDebugLibraries>false</UseDebugLibraries>
+ <PlatformToolset>v143</PlatformToolset>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ <CharacterSet>MultiByte</CharacterSet>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <ImportGroup Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props"
+ Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <Import Project="../../toml++.props" />
+ <ItemDefinitionGroup>
+ <ClCompile>
+ <AdditionalIncludeDirectories>..\tests;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <ExceptionHandling>false</ExceptionHandling>
+ <PrecompiledHeader>Use</PrecompiledHeader>
+ <PrecompiledHeaderFile>tests.hpp</PrecompiledHeaderFile>
+ <PreprocessorDefinitions>TOML_ENABLE_UNRELEASED_FEATURES=1;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <PreprocessorDefinitions>LEAK_TESTS=1;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'%(ExceptionHandling)'=='false'">_HAS_EXCEPTIONS=0;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'%(ExceptionHandling)'=='false'">SHOULD_HAVE_EXCEPTIONS=0;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'%(ExceptionHandling)'!='false'">SHOULD_HAVE_EXCEPTIONS=1;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <LanguageStandard>stdcpplatest</LanguageStandard>
+ <MultiProcessorCompilation>true</MultiProcessorCompilation>
+ <WarningLevel>EnableAllWarnings</WarningLevel>
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4127</DisableSpecificWarnings> <!-- conditional expr is constant -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4324</DisableSpecificWarnings> <!-- structure was padded due to alignment specifier -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4464</DisableSpecificWarnings> <!-- relative include path contains '..' -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4505</DisableSpecificWarnings> <!-- unreferenced local function removed -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4514</DisableSpecificWarnings> <!-- unreferenced inline function has been removed -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4577</DisableSpecificWarnings> <!-- 'noexcept' used with no exception handling mode specified -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4582</DisableSpecificWarnings> <!-- constructor is not implicitly called -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4623</DisableSpecificWarnings> <!-- default constructor was implicitly defined as deleted -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4625</DisableSpecificWarnings> <!-- copy constructor was implicitly defined as deleted -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4626</DisableSpecificWarnings> <!-- assignment operator was implicitly defined as deleted -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4710</DisableSpecificWarnings> <!-- function not inlined -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4711</DisableSpecificWarnings> <!-- function selected for automatic expansion -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4738</DisableSpecificWarnings> <!-- storing 32-bit float result in memory -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4820</DisableSpecificWarnings> <!-- N bytes padding added -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4866</DisableSpecificWarnings> <!-- compiler may not enforce ltr eval in operator[] -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4868</DisableSpecificWarnings> <!-- compiler may not enforce ltr eval in initializer list -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4946</DisableSpecificWarnings> <!-- reinterpret_cast used between related classes -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);5026</DisableSpecificWarnings> <!-- move constructor was implicitly defined as deleted -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);5027</DisableSpecificWarnings> <!-- move assignment operator was implicitly defined as deleted -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);5039</DisableSpecificWarnings> <!-- potentially throwing function passed to 'extern "C"' -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);5045</DisableSpecificWarnings> <!-- Compiler will insert Spectre mitigation -->
+ </ClCompile>
+ </ItemDefinitionGroup>
+ <PropertyGroup>
+ <LocalDebuggerWorkingDirectory>$(ProjectDir)..\</LocalDebuggerWorkingDirectory>
+ </PropertyGroup>
+ <ItemGroup>
+ <ClCompile Include="..\at_path.cpp" />
+ <ClCompile Include="..\path.cpp" />
+ <ClCompile Include="..\conformance_burntsushi_invalid.cpp" />
+ <ClCompile Include="..\conformance_burntsushi_valid.cpp" />
+ <ClCompile Include="..\conformance_iarna_invalid.cpp" />
+ <ClCompile Include="..\conformance_iarna_valid.cpp" />
+ <ClCompile Include="..\for_each.cpp" />
+ <ClCompile Include="..\formatters.cpp" />
+ <ClCompile Include="..\impl_toml.cpp">
+ <PrecompiledHeader>NotUsing</PrecompiledHeader>
+ </ClCompile>
+ <ClCompile Include="..\main.cpp">
+ <PrecompiledHeader>NotUsing</PrecompiledHeader>
+ </ClCompile>
+ <ClCompile Include="..\manipulating_arrays.cpp" />
+ <ClCompile Include="..\manipulating_tables.cpp" />
+ <ClCompile Include="..\manipulating_parse_result.cpp" />
+ <ClCompile Include="..\manipulating_values.cpp" />
+ <ClCompile Include="..\parsing_arrays.cpp" />
+ <ClCompile Include="..\parsing_booleans.cpp" />
+ <ClCompile Include="..\parsing_comments.cpp" />
+ <ClCompile Include="..\parsing_dates_and_times.cpp" />
+ <ClCompile Include="..\parsing_floats.cpp" />
+ <ClCompile Include="..\parsing_integers.cpp" />
+ <ClCompile Include="..\parsing_key_value_pairs.cpp" />
+ <ClCompile Include="..\parsing_spec_example.cpp" />
+ <ClCompile Include="..\parsing_strings.cpp" />
+ <ClCompile Include="..\parsing_tables.cpp" />
+ <ClCompile Include="..\tests.cpp">
+ <PrecompiledHeader>Create</PrecompiledHeader>
+ </ClCompile>
+ <ClCompile Include="..\user_feedback.cpp" />
+ <ClCompile Include="..\using_iterators.cpp" />
+ <ClCompile Include="..\visit.cpp" />
+ <ClCompile Include="..\windows_compat.cpp" />
+ </ItemGroup>
+ <ItemGroup>
+ <Natvis Include="..\..\toml++.natvis" />
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="..\leakproof.hpp" />
+ <ClInclude Include="..\lib_catch2.hpp" />
+ <ClInclude Include="..\lib_tloptional.hpp" />
+ <ClInclude Include="..\settings.hpp" />
+ <ClInclude Include="..\tests.hpp" />
+ </ItemGroup>
+ <ItemGroup>
+ <None Include="..\cpp.hint" />
+ <None Include="..\meson.build" />
+ </ItemGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+</Project>
diff --git a/tomlplusplus/tests/vs/test_debug_x64_cpplatest_unrel.vcxproj b/tomlplusplus/tests/vs/test_debug_x64_cpplatest_unrel.vcxproj
new file mode 100644
index 0000000000..a1e8fd72d1
--- /dev/null
+++ b/tomlplusplus/tests/vs/test_debug_x64_cpplatest_unrel.vcxproj
@@ -0,0 +1,127 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup Label="ProjectConfigurations">
+ <ProjectConfiguration Include="Debug|x64">
+ <Configuration>Debug</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ </ItemGroup>
+ <PropertyGroup Label="Globals">
+ <VCProjectVersion>16.0</VCProjectVersion>
+ <ProjectGuid>{39175FCA-1342-507B-90F3-E8DCFB4C48D0}</ProjectGuid>
+ <WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
+ <PreferredToolArchitecture>x64</PreferredToolArchitecture>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <UseDebugLibraries>true</UseDebugLibraries>
+ <PlatformToolset>v143</PlatformToolset>
+ <CharacterSet>MultiByte</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <UseDebugLibraries>false</UseDebugLibraries>
+ <PlatformToolset>v143</PlatformToolset>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ <CharacterSet>MultiByte</CharacterSet>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <ImportGroup Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props"
+ Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <Import Project="../../toml++.props" />
+ <ItemDefinitionGroup>
+ <ClCompile>
+ <AdditionalIncludeDirectories>..\tests;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <ExceptionHandling>Sync</ExceptionHandling>
+ <PrecompiledHeader>Use</PrecompiledHeader>
+ <PrecompiledHeaderFile>tests.hpp</PrecompiledHeaderFile>
+ <PreprocessorDefinitions>TOML_ENABLE_UNRELEASED_FEATURES=1;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <PreprocessorDefinitions>LEAK_TESTS=1;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'%(ExceptionHandling)'=='false'">_HAS_EXCEPTIONS=0;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'%(ExceptionHandling)'=='false'">SHOULD_HAVE_EXCEPTIONS=0;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'%(ExceptionHandling)'!='false'">SHOULD_HAVE_EXCEPTIONS=1;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <LanguageStandard>stdcpplatest</LanguageStandard>
+ <MultiProcessorCompilation>true</MultiProcessorCompilation>
+ <WarningLevel>EnableAllWarnings</WarningLevel>
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4127</DisableSpecificWarnings> <!-- conditional expr is constant -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4324</DisableSpecificWarnings> <!-- structure was padded due to alignment specifier -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4464</DisableSpecificWarnings> <!-- relative include path contains '..' -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4505</DisableSpecificWarnings> <!-- unreferenced local function removed -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4514</DisableSpecificWarnings> <!-- unreferenced inline function has been removed -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4577</DisableSpecificWarnings> <!-- 'noexcept' used with no exception handling mode specified -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4582</DisableSpecificWarnings> <!-- constructor is not implicitly called -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4623</DisableSpecificWarnings> <!-- default constructor was implicitly defined as deleted -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4625</DisableSpecificWarnings> <!-- copy constructor was implicitly defined as deleted -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4626</DisableSpecificWarnings> <!-- assignment operator was implicitly defined as deleted -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4710</DisableSpecificWarnings> <!-- function not inlined -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4711</DisableSpecificWarnings> <!-- function selected for automatic expansion -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4738</DisableSpecificWarnings> <!-- storing 32-bit float result in memory -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4820</DisableSpecificWarnings> <!-- N bytes padding added -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4866</DisableSpecificWarnings> <!-- compiler may not enforce ltr eval in operator[] -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4868</DisableSpecificWarnings> <!-- compiler may not enforce ltr eval in initializer list -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4946</DisableSpecificWarnings> <!-- reinterpret_cast used between related classes -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);5026</DisableSpecificWarnings> <!-- move constructor was implicitly defined as deleted -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);5027</DisableSpecificWarnings> <!-- move assignment operator was implicitly defined as deleted -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);5039</DisableSpecificWarnings> <!-- potentially throwing function passed to 'extern "C"' -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);5045</DisableSpecificWarnings> <!-- Compiler will insert Spectre mitigation -->
+ </ClCompile>
+ </ItemDefinitionGroup>
+ <PropertyGroup>
+ <LocalDebuggerWorkingDirectory>$(ProjectDir)..\</LocalDebuggerWorkingDirectory>
+ </PropertyGroup>
+ <ItemGroup>
+ <ClCompile Include="..\at_path.cpp" />
+ <ClCompile Include="..\path.cpp" />
+ <ClCompile Include="..\conformance_burntsushi_invalid.cpp" />
+ <ClCompile Include="..\conformance_burntsushi_valid.cpp" />
+ <ClCompile Include="..\conformance_iarna_invalid.cpp" />
+ <ClCompile Include="..\conformance_iarna_valid.cpp" />
+ <ClCompile Include="..\for_each.cpp" />
+ <ClCompile Include="..\formatters.cpp" />
+ <ClCompile Include="..\impl_toml.cpp">
+ <PrecompiledHeader>NotUsing</PrecompiledHeader>
+ </ClCompile>
+ <ClCompile Include="..\main.cpp">
+ <PrecompiledHeader>NotUsing</PrecompiledHeader>
+ </ClCompile>
+ <ClCompile Include="..\manipulating_arrays.cpp" />
+ <ClCompile Include="..\manipulating_tables.cpp" />
+ <ClCompile Include="..\manipulating_parse_result.cpp" />
+ <ClCompile Include="..\manipulating_values.cpp" />
+ <ClCompile Include="..\parsing_arrays.cpp" />
+ <ClCompile Include="..\parsing_booleans.cpp" />
+ <ClCompile Include="..\parsing_comments.cpp" />
+ <ClCompile Include="..\parsing_dates_and_times.cpp" />
+ <ClCompile Include="..\parsing_floats.cpp" />
+ <ClCompile Include="..\parsing_integers.cpp" />
+ <ClCompile Include="..\parsing_key_value_pairs.cpp" />
+ <ClCompile Include="..\parsing_spec_example.cpp" />
+ <ClCompile Include="..\parsing_strings.cpp" />
+ <ClCompile Include="..\parsing_tables.cpp" />
+ <ClCompile Include="..\tests.cpp">
+ <PrecompiledHeader>Create</PrecompiledHeader>
+ </ClCompile>
+ <ClCompile Include="..\user_feedback.cpp" />
+ <ClCompile Include="..\using_iterators.cpp" />
+ <ClCompile Include="..\visit.cpp" />
+ <ClCompile Include="..\windows_compat.cpp" />
+ </ItemGroup>
+ <ItemGroup>
+ <Natvis Include="..\..\toml++.natvis" />
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="..\leakproof.hpp" />
+ <ClInclude Include="..\lib_catch2.hpp" />
+ <ClInclude Include="..\lib_tloptional.hpp" />
+ <ClInclude Include="..\settings.hpp" />
+ <ClInclude Include="..\tests.hpp" />
+ </ItemGroup>
+ <ItemGroup>
+ <None Include="..\cpp.hint" />
+ <None Include="..\meson.build" />
+ </ItemGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+</Project>
diff --git a/tomlplusplus/tests/vs/test_debug_x64_noexcept.vcxproj b/tomlplusplus/tests/vs/test_debug_x64_noexcept.vcxproj
new file mode 100644
index 0000000000..24e110d1d5
--- /dev/null
+++ b/tomlplusplus/tests/vs/test_debug_x64_noexcept.vcxproj
@@ -0,0 +1,127 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup Label="ProjectConfigurations">
+ <ProjectConfiguration Include="Debug|x64">
+ <Configuration>Debug</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ </ItemGroup>
+ <PropertyGroup Label="Globals">
+ <VCProjectVersion>16.0</VCProjectVersion>
+ <ProjectGuid>{70F7C29B-3468-5C09-8D47-B649CEBAB09E}</ProjectGuid>
+ <WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
+ <PreferredToolArchitecture>x64</PreferredToolArchitecture>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <UseDebugLibraries>true</UseDebugLibraries>
+ <PlatformToolset>v143</PlatformToolset>
+ <CharacterSet>MultiByte</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <UseDebugLibraries>false</UseDebugLibraries>
+ <PlatformToolset>v143</PlatformToolset>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ <CharacterSet>MultiByte</CharacterSet>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <ImportGroup Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props"
+ Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <Import Project="../../toml++.props" />
+ <ItemDefinitionGroup>
+ <ClCompile>
+ <AdditionalIncludeDirectories>..\tests;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <ExceptionHandling>false</ExceptionHandling>
+ <PrecompiledHeader>Use</PrecompiledHeader>
+ <PrecompiledHeaderFile>tests.hpp</PrecompiledHeaderFile>
+ <PreprocessorDefinitions>TOML_ENABLE_UNRELEASED_FEATURES=0;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <PreprocessorDefinitions>LEAK_TESTS=1;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'%(ExceptionHandling)'=='false'">_HAS_EXCEPTIONS=0;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'%(ExceptionHandling)'=='false'">SHOULD_HAVE_EXCEPTIONS=0;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'%(ExceptionHandling)'!='false'">SHOULD_HAVE_EXCEPTIONS=1;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <LanguageStandard>stdcpp17</LanguageStandard>
+ <MultiProcessorCompilation>true</MultiProcessorCompilation>
+ <WarningLevel>EnableAllWarnings</WarningLevel>
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4127</DisableSpecificWarnings> <!-- conditional expr is constant -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4324</DisableSpecificWarnings> <!-- structure was padded due to alignment specifier -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4464</DisableSpecificWarnings> <!-- relative include path contains '..' -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4505</DisableSpecificWarnings> <!-- unreferenced local function removed -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4514</DisableSpecificWarnings> <!-- unreferenced inline function has been removed -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4577</DisableSpecificWarnings> <!-- 'noexcept' used with no exception handling mode specified -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4582</DisableSpecificWarnings> <!-- constructor is not implicitly called -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4623</DisableSpecificWarnings> <!-- default constructor was implicitly defined as deleted -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4625</DisableSpecificWarnings> <!-- copy constructor was implicitly defined as deleted -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4626</DisableSpecificWarnings> <!-- assignment operator was implicitly defined as deleted -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4710</DisableSpecificWarnings> <!-- function not inlined -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4711</DisableSpecificWarnings> <!-- function selected for automatic expansion -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4738</DisableSpecificWarnings> <!-- storing 32-bit float result in memory -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4820</DisableSpecificWarnings> <!-- N bytes padding added -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4866</DisableSpecificWarnings> <!-- compiler may not enforce ltr eval in operator[] -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4868</DisableSpecificWarnings> <!-- compiler may not enforce ltr eval in initializer list -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4946</DisableSpecificWarnings> <!-- reinterpret_cast used between related classes -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);5026</DisableSpecificWarnings> <!-- move constructor was implicitly defined as deleted -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);5027</DisableSpecificWarnings> <!-- move assignment operator was implicitly defined as deleted -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);5039</DisableSpecificWarnings> <!-- potentially throwing function passed to 'extern "C"' -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);5045</DisableSpecificWarnings> <!-- Compiler will insert Spectre mitigation -->
+ </ClCompile>
+ </ItemDefinitionGroup>
+ <PropertyGroup>
+ <LocalDebuggerWorkingDirectory>$(ProjectDir)..\</LocalDebuggerWorkingDirectory>
+ </PropertyGroup>
+ <ItemGroup>
+ <ClCompile Include="..\at_path.cpp" />
+ <ClCompile Include="..\path.cpp" />
+ <ClCompile Include="..\conformance_burntsushi_invalid.cpp" />
+ <ClCompile Include="..\conformance_burntsushi_valid.cpp" />
+ <ClCompile Include="..\conformance_iarna_invalid.cpp" />
+ <ClCompile Include="..\conformance_iarna_valid.cpp" />
+ <ClCompile Include="..\for_each.cpp" />
+ <ClCompile Include="..\formatters.cpp" />
+ <ClCompile Include="..\impl_toml.cpp">
+ <PrecompiledHeader>NotUsing</PrecompiledHeader>
+ </ClCompile>
+ <ClCompile Include="..\main.cpp">
+ <PrecompiledHeader>NotUsing</PrecompiledHeader>
+ </ClCompile>
+ <ClCompile Include="..\manipulating_arrays.cpp" />
+ <ClCompile Include="..\manipulating_tables.cpp" />
+ <ClCompile Include="..\manipulating_parse_result.cpp" />
+ <ClCompile Include="..\manipulating_values.cpp" />
+ <ClCompile Include="..\parsing_arrays.cpp" />
+ <ClCompile Include="..\parsing_booleans.cpp" />
+ <ClCompile Include="..\parsing_comments.cpp" />
+ <ClCompile Include="..\parsing_dates_and_times.cpp" />
+ <ClCompile Include="..\parsing_floats.cpp" />
+ <ClCompile Include="..\parsing_integers.cpp" />
+ <ClCompile Include="..\parsing_key_value_pairs.cpp" />
+ <ClCompile Include="..\parsing_spec_example.cpp" />
+ <ClCompile Include="..\parsing_strings.cpp" />
+ <ClCompile Include="..\parsing_tables.cpp" />
+ <ClCompile Include="..\tests.cpp">
+ <PrecompiledHeader>Create</PrecompiledHeader>
+ </ClCompile>
+ <ClCompile Include="..\user_feedback.cpp" />
+ <ClCompile Include="..\using_iterators.cpp" />
+ <ClCompile Include="..\visit.cpp" />
+ <ClCompile Include="..\windows_compat.cpp" />
+ </ItemGroup>
+ <ItemGroup>
+ <Natvis Include="..\..\toml++.natvis" />
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="..\leakproof.hpp" />
+ <ClInclude Include="..\lib_catch2.hpp" />
+ <ClInclude Include="..\lib_tloptional.hpp" />
+ <ClInclude Include="..\settings.hpp" />
+ <ClInclude Include="..\tests.hpp" />
+ </ItemGroup>
+ <ItemGroup>
+ <None Include="..\cpp.hint" />
+ <None Include="..\meson.build" />
+ </ItemGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+</Project>
diff --git a/tomlplusplus/tests/vs/test_debug_x64_noexcept_unrel.vcxproj b/tomlplusplus/tests/vs/test_debug_x64_noexcept_unrel.vcxproj
new file mode 100644
index 0000000000..5ae2df3dc0
--- /dev/null
+++ b/tomlplusplus/tests/vs/test_debug_x64_noexcept_unrel.vcxproj
@@ -0,0 +1,127 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup Label="ProjectConfigurations">
+ <ProjectConfiguration Include="Debug|x64">
+ <Configuration>Debug</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ </ItemGroup>
+ <PropertyGroup Label="Globals">
+ <VCProjectVersion>16.0</VCProjectVersion>
+ <ProjectGuid>{62191BB3-97A9-552E-93BF-BFDF4D9905DD}</ProjectGuid>
+ <WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
+ <PreferredToolArchitecture>x64</PreferredToolArchitecture>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <UseDebugLibraries>true</UseDebugLibraries>
+ <PlatformToolset>v143</PlatformToolset>
+ <CharacterSet>MultiByte</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <UseDebugLibraries>false</UseDebugLibraries>
+ <PlatformToolset>v143</PlatformToolset>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ <CharacterSet>MultiByte</CharacterSet>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <ImportGroup Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props"
+ Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <Import Project="../../toml++.props" />
+ <ItemDefinitionGroup>
+ <ClCompile>
+ <AdditionalIncludeDirectories>..\tests;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <ExceptionHandling>false</ExceptionHandling>
+ <PrecompiledHeader>Use</PrecompiledHeader>
+ <PrecompiledHeaderFile>tests.hpp</PrecompiledHeaderFile>
+ <PreprocessorDefinitions>TOML_ENABLE_UNRELEASED_FEATURES=1;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <PreprocessorDefinitions>LEAK_TESTS=1;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'%(ExceptionHandling)'=='false'">_HAS_EXCEPTIONS=0;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'%(ExceptionHandling)'=='false'">SHOULD_HAVE_EXCEPTIONS=0;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'%(ExceptionHandling)'!='false'">SHOULD_HAVE_EXCEPTIONS=1;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <LanguageStandard>stdcpp17</LanguageStandard>
+ <MultiProcessorCompilation>true</MultiProcessorCompilation>
+ <WarningLevel>EnableAllWarnings</WarningLevel>
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4127</DisableSpecificWarnings> <!-- conditional expr is constant -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4324</DisableSpecificWarnings> <!-- structure was padded due to alignment specifier -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4464</DisableSpecificWarnings> <!-- relative include path contains '..' -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4505</DisableSpecificWarnings> <!-- unreferenced local function removed -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4514</DisableSpecificWarnings> <!-- unreferenced inline function has been removed -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4577</DisableSpecificWarnings> <!-- 'noexcept' used with no exception handling mode specified -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4582</DisableSpecificWarnings> <!-- constructor is not implicitly called -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4623</DisableSpecificWarnings> <!-- default constructor was implicitly defined as deleted -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4625</DisableSpecificWarnings> <!-- copy constructor was implicitly defined as deleted -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4626</DisableSpecificWarnings> <!-- assignment operator was implicitly defined as deleted -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4710</DisableSpecificWarnings> <!-- function not inlined -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4711</DisableSpecificWarnings> <!-- function selected for automatic expansion -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4738</DisableSpecificWarnings> <!-- storing 32-bit float result in memory -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4820</DisableSpecificWarnings> <!-- N bytes padding added -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4866</DisableSpecificWarnings> <!-- compiler may not enforce ltr eval in operator[] -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4868</DisableSpecificWarnings> <!-- compiler may not enforce ltr eval in initializer list -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4946</DisableSpecificWarnings> <!-- reinterpret_cast used between related classes -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);5026</DisableSpecificWarnings> <!-- move constructor was implicitly defined as deleted -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);5027</DisableSpecificWarnings> <!-- move assignment operator was implicitly defined as deleted -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);5039</DisableSpecificWarnings> <!-- potentially throwing function passed to 'extern "C"' -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);5045</DisableSpecificWarnings> <!-- Compiler will insert Spectre mitigation -->
+ </ClCompile>
+ </ItemDefinitionGroup>
+ <PropertyGroup>
+ <LocalDebuggerWorkingDirectory>$(ProjectDir)..\</LocalDebuggerWorkingDirectory>
+ </PropertyGroup>
+ <ItemGroup>
+ <ClCompile Include="..\at_path.cpp" />
+ <ClCompile Include="..\path.cpp" />
+ <ClCompile Include="..\conformance_burntsushi_invalid.cpp" />
+ <ClCompile Include="..\conformance_burntsushi_valid.cpp" />
+ <ClCompile Include="..\conformance_iarna_invalid.cpp" />
+ <ClCompile Include="..\conformance_iarna_valid.cpp" />
+ <ClCompile Include="..\for_each.cpp" />
+ <ClCompile Include="..\formatters.cpp" />
+ <ClCompile Include="..\impl_toml.cpp">
+ <PrecompiledHeader>NotUsing</PrecompiledHeader>
+ </ClCompile>
+ <ClCompile Include="..\main.cpp">
+ <PrecompiledHeader>NotUsing</PrecompiledHeader>
+ </ClCompile>
+ <ClCompile Include="..\manipulating_arrays.cpp" />
+ <ClCompile Include="..\manipulating_tables.cpp" />
+ <ClCompile Include="..\manipulating_parse_result.cpp" />
+ <ClCompile Include="..\manipulating_values.cpp" />
+ <ClCompile Include="..\parsing_arrays.cpp" />
+ <ClCompile Include="..\parsing_booleans.cpp" />
+ <ClCompile Include="..\parsing_comments.cpp" />
+ <ClCompile Include="..\parsing_dates_and_times.cpp" />
+ <ClCompile Include="..\parsing_floats.cpp" />
+ <ClCompile Include="..\parsing_integers.cpp" />
+ <ClCompile Include="..\parsing_key_value_pairs.cpp" />
+ <ClCompile Include="..\parsing_spec_example.cpp" />
+ <ClCompile Include="..\parsing_strings.cpp" />
+ <ClCompile Include="..\parsing_tables.cpp" />
+ <ClCompile Include="..\tests.cpp">
+ <PrecompiledHeader>Create</PrecompiledHeader>
+ </ClCompile>
+ <ClCompile Include="..\user_feedback.cpp" />
+ <ClCompile Include="..\using_iterators.cpp" />
+ <ClCompile Include="..\visit.cpp" />
+ <ClCompile Include="..\windows_compat.cpp" />
+ </ItemGroup>
+ <ItemGroup>
+ <Natvis Include="..\..\toml++.natvis" />
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="..\leakproof.hpp" />
+ <ClInclude Include="..\lib_catch2.hpp" />
+ <ClInclude Include="..\lib_tloptional.hpp" />
+ <ClInclude Include="..\settings.hpp" />
+ <ClInclude Include="..\tests.hpp" />
+ </ItemGroup>
+ <ItemGroup>
+ <None Include="..\cpp.hint" />
+ <None Include="..\meson.build" />
+ </ItemGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+</Project>
diff --git a/tomlplusplus/tests/vs/test_debug_x64_unrel.vcxproj b/tomlplusplus/tests/vs/test_debug_x64_unrel.vcxproj
new file mode 100644
index 0000000000..50335835db
--- /dev/null
+++ b/tomlplusplus/tests/vs/test_debug_x64_unrel.vcxproj
@@ -0,0 +1,127 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup Label="ProjectConfigurations">
+ <ProjectConfiguration Include="Debug|x64">
+ <Configuration>Debug</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ </ItemGroup>
+ <PropertyGroup Label="Globals">
+ <VCProjectVersion>16.0</VCProjectVersion>
+ <ProjectGuid>{9A3431E3-4727-5FED-9C18-CCD300C2760E}</ProjectGuid>
+ <WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
+ <PreferredToolArchitecture>x64</PreferredToolArchitecture>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <UseDebugLibraries>true</UseDebugLibraries>
+ <PlatformToolset>v143</PlatformToolset>
+ <CharacterSet>MultiByte</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <UseDebugLibraries>false</UseDebugLibraries>
+ <PlatformToolset>v143</PlatformToolset>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ <CharacterSet>MultiByte</CharacterSet>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <ImportGroup Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props"
+ Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <Import Project="../../toml++.props" />
+ <ItemDefinitionGroup>
+ <ClCompile>
+ <AdditionalIncludeDirectories>..\tests;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <ExceptionHandling>Sync</ExceptionHandling>
+ <PrecompiledHeader>Use</PrecompiledHeader>
+ <PrecompiledHeaderFile>tests.hpp</PrecompiledHeaderFile>
+ <PreprocessorDefinitions>TOML_ENABLE_UNRELEASED_FEATURES=1;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <PreprocessorDefinitions>LEAK_TESTS=1;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'%(ExceptionHandling)'=='false'">_HAS_EXCEPTIONS=0;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'%(ExceptionHandling)'=='false'">SHOULD_HAVE_EXCEPTIONS=0;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'%(ExceptionHandling)'!='false'">SHOULD_HAVE_EXCEPTIONS=1;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <LanguageStandard>stdcpp17</LanguageStandard>
+ <MultiProcessorCompilation>true</MultiProcessorCompilation>
+ <WarningLevel>EnableAllWarnings</WarningLevel>
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4127</DisableSpecificWarnings> <!-- conditional expr is constant -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4324</DisableSpecificWarnings> <!-- structure was padded due to alignment specifier -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4464</DisableSpecificWarnings> <!-- relative include path contains '..' -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4505</DisableSpecificWarnings> <!-- unreferenced local function removed -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4514</DisableSpecificWarnings> <!-- unreferenced inline function has been removed -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4577</DisableSpecificWarnings> <!-- 'noexcept' used with no exception handling mode specified -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4582</DisableSpecificWarnings> <!-- constructor is not implicitly called -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4623</DisableSpecificWarnings> <!-- default constructor was implicitly defined as deleted -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4625</DisableSpecificWarnings> <!-- copy constructor was implicitly defined as deleted -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4626</DisableSpecificWarnings> <!-- assignment operator was implicitly defined as deleted -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4710</DisableSpecificWarnings> <!-- function not inlined -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4711</DisableSpecificWarnings> <!-- function selected for automatic expansion -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4738</DisableSpecificWarnings> <!-- storing 32-bit float result in memory -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4820</DisableSpecificWarnings> <!-- N bytes padding added -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4866</DisableSpecificWarnings> <!-- compiler may not enforce ltr eval in operator[] -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4868</DisableSpecificWarnings> <!-- compiler may not enforce ltr eval in initializer list -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4946</DisableSpecificWarnings> <!-- reinterpret_cast used between related classes -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);5026</DisableSpecificWarnings> <!-- move constructor was implicitly defined as deleted -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);5027</DisableSpecificWarnings> <!-- move assignment operator was implicitly defined as deleted -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);5039</DisableSpecificWarnings> <!-- potentially throwing function passed to 'extern "C"' -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);5045</DisableSpecificWarnings> <!-- Compiler will insert Spectre mitigation -->
+ </ClCompile>
+ </ItemDefinitionGroup>
+ <PropertyGroup>
+ <LocalDebuggerWorkingDirectory>$(ProjectDir)..\</LocalDebuggerWorkingDirectory>
+ </PropertyGroup>
+ <ItemGroup>
+ <ClCompile Include="..\at_path.cpp" />
+ <ClCompile Include="..\path.cpp" />
+ <ClCompile Include="..\conformance_burntsushi_invalid.cpp" />
+ <ClCompile Include="..\conformance_burntsushi_valid.cpp" />
+ <ClCompile Include="..\conformance_iarna_invalid.cpp" />
+ <ClCompile Include="..\conformance_iarna_valid.cpp" />
+ <ClCompile Include="..\for_each.cpp" />
+ <ClCompile Include="..\formatters.cpp" />
+ <ClCompile Include="..\impl_toml.cpp">
+ <PrecompiledHeader>NotUsing</PrecompiledHeader>
+ </ClCompile>
+ <ClCompile Include="..\main.cpp">
+ <PrecompiledHeader>NotUsing</PrecompiledHeader>
+ </ClCompile>
+ <ClCompile Include="..\manipulating_arrays.cpp" />
+ <ClCompile Include="..\manipulating_tables.cpp" />
+ <ClCompile Include="..\manipulating_parse_result.cpp" />
+ <ClCompile Include="..\manipulating_values.cpp" />
+ <ClCompile Include="..\parsing_arrays.cpp" />
+ <ClCompile Include="..\parsing_booleans.cpp" />
+ <ClCompile Include="..\parsing_comments.cpp" />
+ <ClCompile Include="..\parsing_dates_and_times.cpp" />
+ <ClCompile Include="..\parsing_floats.cpp" />
+ <ClCompile Include="..\parsing_integers.cpp" />
+ <ClCompile Include="..\parsing_key_value_pairs.cpp" />
+ <ClCompile Include="..\parsing_spec_example.cpp" />
+ <ClCompile Include="..\parsing_strings.cpp" />
+ <ClCompile Include="..\parsing_tables.cpp" />
+ <ClCompile Include="..\tests.cpp">
+ <PrecompiledHeader>Create</PrecompiledHeader>
+ </ClCompile>
+ <ClCompile Include="..\user_feedback.cpp" />
+ <ClCompile Include="..\using_iterators.cpp" />
+ <ClCompile Include="..\visit.cpp" />
+ <ClCompile Include="..\windows_compat.cpp" />
+ </ItemGroup>
+ <ItemGroup>
+ <Natvis Include="..\..\toml++.natvis" />
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="..\leakproof.hpp" />
+ <ClInclude Include="..\lib_catch2.hpp" />
+ <ClInclude Include="..\lib_tloptional.hpp" />
+ <ClInclude Include="..\settings.hpp" />
+ <ClInclude Include="..\tests.hpp" />
+ </ItemGroup>
+ <ItemGroup>
+ <None Include="..\cpp.hint" />
+ <None Include="..\meson.build" />
+ </ItemGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+</Project>
diff --git a/tomlplusplus/tests/vs/test_debug_x86.vcxproj b/tomlplusplus/tests/vs/test_debug_x86.vcxproj
new file mode 100644
index 0000000000..b6eb5c4fad
--- /dev/null
+++ b/tomlplusplus/tests/vs/test_debug_x86.vcxproj
@@ -0,0 +1,127 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup Label="ProjectConfigurations">
+ <ProjectConfiguration Include="Debug|Win32">
+ <Configuration>Debug</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ </ItemGroup>
+ <PropertyGroup Label="Globals">
+ <VCProjectVersion>16.0</VCProjectVersion>
+ <ProjectGuid>{CFBAF3E0-2F81-5178-964C-F419CD2F296D}</ProjectGuid>
+ <WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
+ <PreferredToolArchitecture>x64</PreferredToolArchitecture>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <UseDebugLibraries>true</UseDebugLibraries>
+ <PlatformToolset>v143</PlatformToolset>
+ <CharacterSet>MultiByte</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <UseDebugLibraries>false</UseDebugLibraries>
+ <PlatformToolset>v143</PlatformToolset>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ <CharacterSet>MultiByte</CharacterSet>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <ImportGroup Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props"
+ Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <Import Project="../../toml++.props" />
+ <ItemDefinitionGroup>
+ <ClCompile>
+ <AdditionalIncludeDirectories>..\tests;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <ExceptionHandling>Sync</ExceptionHandling>
+ <PrecompiledHeader>Use</PrecompiledHeader>
+ <PrecompiledHeaderFile>tests.hpp</PrecompiledHeaderFile>
+ <PreprocessorDefinitions>TOML_ENABLE_UNRELEASED_FEATURES=0;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <PreprocessorDefinitions>LEAK_TESTS=1;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'%(ExceptionHandling)'=='false'">_HAS_EXCEPTIONS=0;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'%(ExceptionHandling)'=='false'">SHOULD_HAVE_EXCEPTIONS=0;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'%(ExceptionHandling)'!='false'">SHOULD_HAVE_EXCEPTIONS=1;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <LanguageStandard>stdcpp17</LanguageStandard>
+ <MultiProcessorCompilation>true</MultiProcessorCompilation>
+ <WarningLevel>EnableAllWarnings</WarningLevel>
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4127</DisableSpecificWarnings> <!-- conditional expr is constant -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4324</DisableSpecificWarnings> <!-- structure was padded due to alignment specifier -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4464</DisableSpecificWarnings> <!-- relative include path contains '..' -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4505</DisableSpecificWarnings> <!-- unreferenced local function removed -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4514</DisableSpecificWarnings> <!-- unreferenced inline function has been removed -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4577</DisableSpecificWarnings> <!-- 'noexcept' used with no exception handling mode specified -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4582</DisableSpecificWarnings> <!-- constructor is not implicitly called -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4623</DisableSpecificWarnings> <!-- default constructor was implicitly defined as deleted -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4625</DisableSpecificWarnings> <!-- copy constructor was implicitly defined as deleted -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4626</DisableSpecificWarnings> <!-- assignment operator was implicitly defined as deleted -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4710</DisableSpecificWarnings> <!-- function not inlined -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4711</DisableSpecificWarnings> <!-- function selected for automatic expansion -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4738</DisableSpecificWarnings> <!-- storing 32-bit float result in memory -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4820</DisableSpecificWarnings> <!-- N bytes padding added -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4866</DisableSpecificWarnings> <!-- compiler may not enforce ltr eval in operator[] -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4868</DisableSpecificWarnings> <!-- compiler may not enforce ltr eval in initializer list -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4946</DisableSpecificWarnings> <!-- reinterpret_cast used between related classes -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);5026</DisableSpecificWarnings> <!-- move constructor was implicitly defined as deleted -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);5027</DisableSpecificWarnings> <!-- move assignment operator was implicitly defined as deleted -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);5039</DisableSpecificWarnings> <!-- potentially throwing function passed to 'extern "C"' -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);5045</DisableSpecificWarnings> <!-- Compiler will insert Spectre mitigation -->
+ </ClCompile>
+ </ItemDefinitionGroup>
+ <PropertyGroup>
+ <LocalDebuggerWorkingDirectory>$(ProjectDir)..\</LocalDebuggerWorkingDirectory>
+ </PropertyGroup>
+ <ItemGroup>
+ <ClCompile Include="..\at_path.cpp" />
+ <ClCompile Include="..\path.cpp" />
+ <ClCompile Include="..\conformance_burntsushi_invalid.cpp" />
+ <ClCompile Include="..\conformance_burntsushi_valid.cpp" />
+ <ClCompile Include="..\conformance_iarna_invalid.cpp" />
+ <ClCompile Include="..\conformance_iarna_valid.cpp" />
+ <ClCompile Include="..\for_each.cpp" />
+ <ClCompile Include="..\formatters.cpp" />
+ <ClCompile Include="..\impl_toml.cpp">
+ <PrecompiledHeader>NotUsing</PrecompiledHeader>
+ </ClCompile>
+ <ClCompile Include="..\main.cpp">
+ <PrecompiledHeader>NotUsing</PrecompiledHeader>
+ </ClCompile>
+ <ClCompile Include="..\manipulating_arrays.cpp" />
+ <ClCompile Include="..\manipulating_tables.cpp" />
+ <ClCompile Include="..\manipulating_parse_result.cpp" />
+ <ClCompile Include="..\manipulating_values.cpp" />
+ <ClCompile Include="..\parsing_arrays.cpp" />
+ <ClCompile Include="..\parsing_booleans.cpp" />
+ <ClCompile Include="..\parsing_comments.cpp" />
+ <ClCompile Include="..\parsing_dates_and_times.cpp" />
+ <ClCompile Include="..\parsing_floats.cpp" />
+ <ClCompile Include="..\parsing_integers.cpp" />
+ <ClCompile Include="..\parsing_key_value_pairs.cpp" />
+ <ClCompile Include="..\parsing_spec_example.cpp" />
+ <ClCompile Include="..\parsing_strings.cpp" />
+ <ClCompile Include="..\parsing_tables.cpp" />
+ <ClCompile Include="..\tests.cpp">
+ <PrecompiledHeader>Create</PrecompiledHeader>
+ </ClCompile>
+ <ClCompile Include="..\user_feedback.cpp" />
+ <ClCompile Include="..\using_iterators.cpp" />
+ <ClCompile Include="..\visit.cpp" />
+ <ClCompile Include="..\windows_compat.cpp" />
+ </ItemGroup>
+ <ItemGroup>
+ <Natvis Include="..\..\toml++.natvis" />
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="..\leakproof.hpp" />
+ <ClInclude Include="..\lib_catch2.hpp" />
+ <ClInclude Include="..\lib_tloptional.hpp" />
+ <ClInclude Include="..\settings.hpp" />
+ <ClInclude Include="..\tests.hpp" />
+ </ItemGroup>
+ <ItemGroup>
+ <None Include="..\cpp.hint" />
+ <None Include="..\meson.build" />
+ </ItemGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+</Project>
diff --git a/tomlplusplus/tests/vs/test_debug_x86_cpplatest.vcxproj b/tomlplusplus/tests/vs/test_debug_x86_cpplatest.vcxproj
new file mode 100644
index 0000000000..72506f22de
--- /dev/null
+++ b/tomlplusplus/tests/vs/test_debug_x86_cpplatest.vcxproj
@@ -0,0 +1,127 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup Label="ProjectConfigurations">
+ <ProjectConfiguration Include="Debug|Win32">
+ <Configuration>Debug</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ </ItemGroup>
+ <PropertyGroup Label="Globals">
+ <VCProjectVersion>16.0</VCProjectVersion>
+ <ProjectGuid>{AD9A5FC3-6B12-5B6F-86C0-AB2FBB8C7766}</ProjectGuid>
+ <WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
+ <PreferredToolArchitecture>x64</PreferredToolArchitecture>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <UseDebugLibraries>true</UseDebugLibraries>
+ <PlatformToolset>v143</PlatformToolset>
+ <CharacterSet>MultiByte</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <UseDebugLibraries>false</UseDebugLibraries>
+ <PlatformToolset>v143</PlatformToolset>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ <CharacterSet>MultiByte</CharacterSet>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <ImportGroup Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props"
+ Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <Import Project="../../toml++.props" />
+ <ItemDefinitionGroup>
+ <ClCompile>
+ <AdditionalIncludeDirectories>..\tests;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <ExceptionHandling>Sync</ExceptionHandling>
+ <PrecompiledHeader>Use</PrecompiledHeader>
+ <PrecompiledHeaderFile>tests.hpp</PrecompiledHeaderFile>
+ <PreprocessorDefinitions>TOML_ENABLE_UNRELEASED_FEATURES=0;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <PreprocessorDefinitions>LEAK_TESTS=1;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'%(ExceptionHandling)'=='false'">_HAS_EXCEPTIONS=0;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'%(ExceptionHandling)'=='false'">SHOULD_HAVE_EXCEPTIONS=0;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'%(ExceptionHandling)'!='false'">SHOULD_HAVE_EXCEPTIONS=1;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <LanguageStandard>stdcpplatest</LanguageStandard>
+ <MultiProcessorCompilation>true</MultiProcessorCompilation>
+ <WarningLevel>EnableAllWarnings</WarningLevel>
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4127</DisableSpecificWarnings> <!-- conditional expr is constant -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4324</DisableSpecificWarnings> <!-- structure was padded due to alignment specifier -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4464</DisableSpecificWarnings> <!-- relative include path contains '..' -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4505</DisableSpecificWarnings> <!-- unreferenced local function removed -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4514</DisableSpecificWarnings> <!-- unreferenced inline function has been removed -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4577</DisableSpecificWarnings> <!-- 'noexcept' used with no exception handling mode specified -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4582</DisableSpecificWarnings> <!-- constructor is not implicitly called -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4623</DisableSpecificWarnings> <!-- default constructor was implicitly defined as deleted -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4625</DisableSpecificWarnings> <!-- copy constructor was implicitly defined as deleted -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4626</DisableSpecificWarnings> <!-- assignment operator was implicitly defined as deleted -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4710</DisableSpecificWarnings> <!-- function not inlined -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4711</DisableSpecificWarnings> <!-- function selected for automatic expansion -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4738</DisableSpecificWarnings> <!-- storing 32-bit float result in memory -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4820</DisableSpecificWarnings> <!-- N bytes padding added -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4866</DisableSpecificWarnings> <!-- compiler may not enforce ltr eval in operator[] -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4868</DisableSpecificWarnings> <!-- compiler may not enforce ltr eval in initializer list -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4946</DisableSpecificWarnings> <!-- reinterpret_cast used between related classes -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);5026</DisableSpecificWarnings> <!-- move constructor was implicitly defined as deleted -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);5027</DisableSpecificWarnings> <!-- move assignment operator was implicitly defined as deleted -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);5039</DisableSpecificWarnings> <!-- potentially throwing function passed to 'extern "C"' -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);5045</DisableSpecificWarnings> <!-- Compiler will insert Spectre mitigation -->
+ </ClCompile>
+ </ItemDefinitionGroup>
+ <PropertyGroup>
+ <LocalDebuggerWorkingDirectory>$(ProjectDir)..\</LocalDebuggerWorkingDirectory>
+ </PropertyGroup>
+ <ItemGroup>
+ <ClCompile Include="..\at_path.cpp" />
+ <ClCompile Include="..\path.cpp" />
+ <ClCompile Include="..\conformance_burntsushi_invalid.cpp" />
+ <ClCompile Include="..\conformance_burntsushi_valid.cpp" />
+ <ClCompile Include="..\conformance_iarna_invalid.cpp" />
+ <ClCompile Include="..\conformance_iarna_valid.cpp" />
+ <ClCompile Include="..\for_each.cpp" />
+ <ClCompile Include="..\formatters.cpp" />
+ <ClCompile Include="..\impl_toml.cpp">
+ <PrecompiledHeader>NotUsing</PrecompiledHeader>
+ </ClCompile>
+ <ClCompile Include="..\main.cpp">
+ <PrecompiledHeader>NotUsing</PrecompiledHeader>
+ </ClCompile>
+ <ClCompile Include="..\manipulating_arrays.cpp" />
+ <ClCompile Include="..\manipulating_tables.cpp" />
+ <ClCompile Include="..\manipulating_parse_result.cpp" />
+ <ClCompile Include="..\manipulating_values.cpp" />
+ <ClCompile Include="..\parsing_arrays.cpp" />
+ <ClCompile Include="..\parsing_booleans.cpp" />
+ <ClCompile Include="..\parsing_comments.cpp" />
+ <ClCompile Include="..\parsing_dates_and_times.cpp" />
+ <ClCompile Include="..\parsing_floats.cpp" />
+ <ClCompile Include="..\parsing_integers.cpp" />
+ <ClCompile Include="..\parsing_key_value_pairs.cpp" />
+ <ClCompile Include="..\parsing_spec_example.cpp" />
+ <ClCompile Include="..\parsing_strings.cpp" />
+ <ClCompile Include="..\parsing_tables.cpp" />
+ <ClCompile Include="..\tests.cpp">
+ <PrecompiledHeader>Create</PrecompiledHeader>
+ </ClCompile>
+ <ClCompile Include="..\user_feedback.cpp" />
+ <ClCompile Include="..\using_iterators.cpp" />
+ <ClCompile Include="..\visit.cpp" />
+ <ClCompile Include="..\windows_compat.cpp" />
+ </ItemGroup>
+ <ItemGroup>
+ <Natvis Include="..\..\toml++.natvis" />
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="..\leakproof.hpp" />
+ <ClInclude Include="..\lib_catch2.hpp" />
+ <ClInclude Include="..\lib_tloptional.hpp" />
+ <ClInclude Include="..\settings.hpp" />
+ <ClInclude Include="..\tests.hpp" />
+ </ItemGroup>
+ <ItemGroup>
+ <None Include="..\cpp.hint" />
+ <None Include="..\meson.build" />
+ </ItemGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+</Project>
diff --git a/tomlplusplus/tests/vs/test_debug_x86_cpplatest_noexcept.vcxproj b/tomlplusplus/tests/vs/test_debug_x86_cpplatest_noexcept.vcxproj
new file mode 100644
index 0000000000..d3dfa36188
--- /dev/null
+++ b/tomlplusplus/tests/vs/test_debug_x86_cpplatest_noexcept.vcxproj
@@ -0,0 +1,127 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup Label="ProjectConfigurations">
+ <ProjectConfiguration Include="Debug|Win32">
+ <Configuration>Debug</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ </ItemGroup>
+ <PropertyGroup Label="Globals">
+ <VCProjectVersion>16.0</VCProjectVersion>
+ <ProjectGuid>{DC05B52F-D0ED-5F40-A5EC-92C4C1D77F98}</ProjectGuid>
+ <WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
+ <PreferredToolArchitecture>x64</PreferredToolArchitecture>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <UseDebugLibraries>true</UseDebugLibraries>
+ <PlatformToolset>v143</PlatformToolset>
+ <CharacterSet>MultiByte</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <UseDebugLibraries>false</UseDebugLibraries>
+ <PlatformToolset>v143</PlatformToolset>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ <CharacterSet>MultiByte</CharacterSet>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <ImportGroup Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props"
+ Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <Import Project="../../toml++.props" />
+ <ItemDefinitionGroup>
+ <ClCompile>
+ <AdditionalIncludeDirectories>..\tests;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <ExceptionHandling>false</ExceptionHandling>
+ <PrecompiledHeader>Use</PrecompiledHeader>
+ <PrecompiledHeaderFile>tests.hpp</PrecompiledHeaderFile>
+ <PreprocessorDefinitions>TOML_ENABLE_UNRELEASED_FEATURES=0;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <PreprocessorDefinitions>LEAK_TESTS=1;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'%(ExceptionHandling)'=='false'">_HAS_EXCEPTIONS=0;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'%(ExceptionHandling)'=='false'">SHOULD_HAVE_EXCEPTIONS=0;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'%(ExceptionHandling)'!='false'">SHOULD_HAVE_EXCEPTIONS=1;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <LanguageStandard>stdcpplatest</LanguageStandard>
+ <MultiProcessorCompilation>true</MultiProcessorCompilation>
+ <WarningLevel>EnableAllWarnings</WarningLevel>
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4127</DisableSpecificWarnings> <!-- conditional expr is constant -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4324</DisableSpecificWarnings> <!-- structure was padded due to alignment specifier -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4464</DisableSpecificWarnings> <!-- relative include path contains '..' -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4505</DisableSpecificWarnings> <!-- unreferenced local function removed -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4514</DisableSpecificWarnings> <!-- unreferenced inline function has been removed -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4577</DisableSpecificWarnings> <!-- 'noexcept' used with no exception handling mode specified -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4582</DisableSpecificWarnings> <!-- constructor is not implicitly called -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4623</DisableSpecificWarnings> <!-- default constructor was implicitly defined as deleted -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4625</DisableSpecificWarnings> <!-- copy constructor was implicitly defined as deleted -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4626</DisableSpecificWarnings> <!-- assignment operator was implicitly defined as deleted -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4710</DisableSpecificWarnings> <!-- function not inlined -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4711</DisableSpecificWarnings> <!-- function selected for automatic expansion -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4738</DisableSpecificWarnings> <!-- storing 32-bit float result in memory -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4820</DisableSpecificWarnings> <!-- N bytes padding added -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4866</DisableSpecificWarnings> <!-- compiler may not enforce ltr eval in operator[] -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4868</DisableSpecificWarnings> <!-- compiler may not enforce ltr eval in initializer list -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4946</DisableSpecificWarnings> <!-- reinterpret_cast used between related classes -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);5026</DisableSpecificWarnings> <!-- move constructor was implicitly defined as deleted -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);5027</DisableSpecificWarnings> <!-- move assignment operator was implicitly defined as deleted -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);5039</DisableSpecificWarnings> <!-- potentially throwing function passed to 'extern "C"' -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);5045</DisableSpecificWarnings> <!-- Compiler will insert Spectre mitigation -->
+ </ClCompile>
+ </ItemDefinitionGroup>
+ <PropertyGroup>
+ <LocalDebuggerWorkingDirectory>$(ProjectDir)..\</LocalDebuggerWorkingDirectory>
+ </PropertyGroup>
+ <ItemGroup>
+ <ClCompile Include="..\at_path.cpp" />
+ <ClCompile Include="..\path.cpp" />
+ <ClCompile Include="..\conformance_burntsushi_invalid.cpp" />
+ <ClCompile Include="..\conformance_burntsushi_valid.cpp" />
+ <ClCompile Include="..\conformance_iarna_invalid.cpp" />
+ <ClCompile Include="..\conformance_iarna_valid.cpp" />
+ <ClCompile Include="..\for_each.cpp" />
+ <ClCompile Include="..\formatters.cpp" />
+ <ClCompile Include="..\impl_toml.cpp">
+ <PrecompiledHeader>NotUsing</PrecompiledHeader>
+ </ClCompile>
+ <ClCompile Include="..\main.cpp">
+ <PrecompiledHeader>NotUsing</PrecompiledHeader>
+ </ClCompile>
+ <ClCompile Include="..\manipulating_arrays.cpp" />
+ <ClCompile Include="..\manipulating_tables.cpp" />
+ <ClCompile Include="..\manipulating_parse_result.cpp" />
+ <ClCompile Include="..\manipulating_values.cpp" />
+ <ClCompile Include="..\parsing_arrays.cpp" />
+ <ClCompile Include="..\parsing_booleans.cpp" />
+ <ClCompile Include="..\parsing_comments.cpp" />
+ <ClCompile Include="..\parsing_dates_and_times.cpp" />
+ <ClCompile Include="..\parsing_floats.cpp" />
+ <ClCompile Include="..\parsing_integers.cpp" />
+ <ClCompile Include="..\parsing_key_value_pairs.cpp" />
+ <ClCompile Include="..\parsing_spec_example.cpp" />
+ <ClCompile Include="..\parsing_strings.cpp" />
+ <ClCompile Include="..\parsing_tables.cpp" />
+ <ClCompile Include="..\tests.cpp">
+ <PrecompiledHeader>Create</PrecompiledHeader>
+ </ClCompile>
+ <ClCompile Include="..\user_feedback.cpp" />
+ <ClCompile Include="..\using_iterators.cpp" />
+ <ClCompile Include="..\visit.cpp" />
+ <ClCompile Include="..\windows_compat.cpp" />
+ </ItemGroup>
+ <ItemGroup>
+ <Natvis Include="..\..\toml++.natvis" />
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="..\leakproof.hpp" />
+ <ClInclude Include="..\lib_catch2.hpp" />
+ <ClInclude Include="..\lib_tloptional.hpp" />
+ <ClInclude Include="..\settings.hpp" />
+ <ClInclude Include="..\tests.hpp" />
+ </ItemGroup>
+ <ItemGroup>
+ <None Include="..\cpp.hint" />
+ <None Include="..\meson.build" />
+ </ItemGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+</Project>
diff --git a/tomlplusplus/tests/vs/test_debug_x86_cpplatest_noexcept_unrel.vcxproj b/tomlplusplus/tests/vs/test_debug_x86_cpplatest_noexcept_unrel.vcxproj
new file mode 100644
index 0000000000..4a433def0a
--- /dev/null
+++ b/tomlplusplus/tests/vs/test_debug_x86_cpplatest_noexcept_unrel.vcxproj
@@ -0,0 +1,127 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup Label="ProjectConfigurations">
+ <ProjectConfiguration Include="Debug|Win32">
+ <Configuration>Debug</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ </ItemGroup>
+ <PropertyGroup Label="Globals">
+ <VCProjectVersion>16.0</VCProjectVersion>
+ <ProjectGuid>{41DC0274-FFA8-5D94-AF8D-5677E3141095}</ProjectGuid>
+ <WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
+ <PreferredToolArchitecture>x64</PreferredToolArchitecture>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <UseDebugLibraries>true</UseDebugLibraries>
+ <PlatformToolset>v143</PlatformToolset>
+ <CharacterSet>MultiByte</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <UseDebugLibraries>false</UseDebugLibraries>
+ <PlatformToolset>v143</PlatformToolset>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ <CharacterSet>MultiByte</CharacterSet>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <ImportGroup Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props"
+ Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <Import Project="../../toml++.props" />
+ <ItemDefinitionGroup>
+ <ClCompile>
+ <AdditionalIncludeDirectories>..\tests;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <ExceptionHandling>false</ExceptionHandling>
+ <PrecompiledHeader>Use</PrecompiledHeader>
+ <PrecompiledHeaderFile>tests.hpp</PrecompiledHeaderFile>
+ <PreprocessorDefinitions>TOML_ENABLE_UNRELEASED_FEATURES=1;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <PreprocessorDefinitions>LEAK_TESTS=1;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'%(ExceptionHandling)'=='false'">_HAS_EXCEPTIONS=0;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'%(ExceptionHandling)'=='false'">SHOULD_HAVE_EXCEPTIONS=0;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'%(ExceptionHandling)'!='false'">SHOULD_HAVE_EXCEPTIONS=1;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <LanguageStandard>stdcpplatest</LanguageStandard>
+ <MultiProcessorCompilation>true</MultiProcessorCompilation>
+ <WarningLevel>EnableAllWarnings</WarningLevel>
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4127</DisableSpecificWarnings> <!-- conditional expr is constant -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4324</DisableSpecificWarnings> <!-- structure was padded due to alignment specifier -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4464</DisableSpecificWarnings> <!-- relative include path contains '..' -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4505</DisableSpecificWarnings> <!-- unreferenced local function removed -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4514</DisableSpecificWarnings> <!-- unreferenced inline function has been removed -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4577</DisableSpecificWarnings> <!-- 'noexcept' used with no exception handling mode specified -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4582</DisableSpecificWarnings> <!-- constructor is not implicitly called -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4623</DisableSpecificWarnings> <!-- default constructor was implicitly defined as deleted -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4625</DisableSpecificWarnings> <!-- copy constructor was implicitly defined as deleted -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4626</DisableSpecificWarnings> <!-- assignment operator was implicitly defined as deleted -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4710</DisableSpecificWarnings> <!-- function not inlined -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4711</DisableSpecificWarnings> <!-- function selected for automatic expansion -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4738</DisableSpecificWarnings> <!-- storing 32-bit float result in memory -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4820</DisableSpecificWarnings> <!-- N bytes padding added -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4866</DisableSpecificWarnings> <!-- compiler may not enforce ltr eval in operator[] -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4868</DisableSpecificWarnings> <!-- compiler may not enforce ltr eval in initializer list -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4946</DisableSpecificWarnings> <!-- reinterpret_cast used between related classes -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);5026</DisableSpecificWarnings> <!-- move constructor was implicitly defined as deleted -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);5027</DisableSpecificWarnings> <!-- move assignment operator was implicitly defined as deleted -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);5039</DisableSpecificWarnings> <!-- potentially throwing function passed to 'extern "C"' -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);5045</DisableSpecificWarnings> <!-- Compiler will insert Spectre mitigation -->
+ </ClCompile>
+ </ItemDefinitionGroup>
+ <PropertyGroup>
+ <LocalDebuggerWorkingDirectory>$(ProjectDir)..\</LocalDebuggerWorkingDirectory>
+ </PropertyGroup>
+ <ItemGroup>
+ <ClCompile Include="..\at_path.cpp" />
+ <ClCompile Include="..\path.cpp" />
+ <ClCompile Include="..\conformance_burntsushi_invalid.cpp" />
+ <ClCompile Include="..\conformance_burntsushi_valid.cpp" />
+ <ClCompile Include="..\conformance_iarna_invalid.cpp" />
+ <ClCompile Include="..\conformance_iarna_valid.cpp" />
+ <ClCompile Include="..\for_each.cpp" />
+ <ClCompile Include="..\formatters.cpp" />
+ <ClCompile Include="..\impl_toml.cpp">
+ <PrecompiledHeader>NotUsing</PrecompiledHeader>
+ </ClCompile>
+ <ClCompile Include="..\main.cpp">
+ <PrecompiledHeader>NotUsing</PrecompiledHeader>
+ </ClCompile>
+ <ClCompile Include="..\manipulating_arrays.cpp" />
+ <ClCompile Include="..\manipulating_tables.cpp" />
+ <ClCompile Include="..\manipulating_parse_result.cpp" />
+ <ClCompile Include="..\manipulating_values.cpp" />
+ <ClCompile Include="..\parsing_arrays.cpp" />
+ <ClCompile Include="..\parsing_booleans.cpp" />
+ <ClCompile Include="..\parsing_comments.cpp" />
+ <ClCompile Include="..\parsing_dates_and_times.cpp" />
+ <ClCompile Include="..\parsing_floats.cpp" />
+ <ClCompile Include="..\parsing_integers.cpp" />
+ <ClCompile Include="..\parsing_key_value_pairs.cpp" />
+ <ClCompile Include="..\parsing_spec_example.cpp" />
+ <ClCompile Include="..\parsing_strings.cpp" />
+ <ClCompile Include="..\parsing_tables.cpp" />
+ <ClCompile Include="..\tests.cpp">
+ <PrecompiledHeader>Create</PrecompiledHeader>
+ </ClCompile>
+ <ClCompile Include="..\user_feedback.cpp" />
+ <ClCompile Include="..\using_iterators.cpp" />
+ <ClCompile Include="..\visit.cpp" />
+ <ClCompile Include="..\windows_compat.cpp" />
+ </ItemGroup>
+ <ItemGroup>
+ <Natvis Include="..\..\toml++.natvis" />
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="..\leakproof.hpp" />
+ <ClInclude Include="..\lib_catch2.hpp" />
+ <ClInclude Include="..\lib_tloptional.hpp" />
+ <ClInclude Include="..\settings.hpp" />
+ <ClInclude Include="..\tests.hpp" />
+ </ItemGroup>
+ <ItemGroup>
+ <None Include="..\cpp.hint" />
+ <None Include="..\meson.build" />
+ </ItemGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+</Project>
diff --git a/tomlplusplus/tests/vs/test_debug_x86_cpplatest_unrel.vcxproj b/tomlplusplus/tests/vs/test_debug_x86_cpplatest_unrel.vcxproj
new file mode 100644
index 0000000000..69839eca1c
--- /dev/null
+++ b/tomlplusplus/tests/vs/test_debug_x86_cpplatest_unrel.vcxproj
@@ -0,0 +1,127 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup Label="ProjectConfigurations">
+ <ProjectConfiguration Include="Debug|Win32">
+ <Configuration>Debug</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ </ItemGroup>
+ <PropertyGroup Label="Globals">
+ <VCProjectVersion>16.0</VCProjectVersion>
+ <ProjectGuid>{C8B46DC3-994F-5A7C-98ED-3388BCE5D647}</ProjectGuid>
+ <WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
+ <PreferredToolArchitecture>x64</PreferredToolArchitecture>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <UseDebugLibraries>true</UseDebugLibraries>
+ <PlatformToolset>v143</PlatformToolset>
+ <CharacterSet>MultiByte</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <UseDebugLibraries>false</UseDebugLibraries>
+ <PlatformToolset>v143</PlatformToolset>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ <CharacterSet>MultiByte</CharacterSet>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <ImportGroup Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props"
+ Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <Import Project="../../toml++.props" />
+ <ItemDefinitionGroup>
+ <ClCompile>
+ <AdditionalIncludeDirectories>..\tests;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <ExceptionHandling>Sync</ExceptionHandling>
+ <PrecompiledHeader>Use</PrecompiledHeader>
+ <PrecompiledHeaderFile>tests.hpp</PrecompiledHeaderFile>
+ <PreprocessorDefinitions>TOML_ENABLE_UNRELEASED_FEATURES=1;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <PreprocessorDefinitions>LEAK_TESTS=1;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'%(ExceptionHandling)'=='false'">_HAS_EXCEPTIONS=0;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'%(ExceptionHandling)'=='false'">SHOULD_HAVE_EXCEPTIONS=0;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'%(ExceptionHandling)'!='false'">SHOULD_HAVE_EXCEPTIONS=1;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <LanguageStandard>stdcpplatest</LanguageStandard>
+ <MultiProcessorCompilation>true</MultiProcessorCompilation>
+ <WarningLevel>EnableAllWarnings</WarningLevel>
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4127</DisableSpecificWarnings> <!-- conditional expr is constant -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4324</DisableSpecificWarnings> <!-- structure was padded due to alignment specifier -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4464</DisableSpecificWarnings> <!-- relative include path contains '..' -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4505</DisableSpecificWarnings> <!-- unreferenced local function removed -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4514</DisableSpecificWarnings> <!-- unreferenced inline function has been removed -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4577</DisableSpecificWarnings> <!-- 'noexcept' used with no exception handling mode specified -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4582</DisableSpecificWarnings> <!-- constructor is not implicitly called -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4623</DisableSpecificWarnings> <!-- default constructor was implicitly defined as deleted -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4625</DisableSpecificWarnings> <!-- copy constructor was implicitly defined as deleted -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4626</DisableSpecificWarnings> <!-- assignment operator was implicitly defined as deleted -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4710</DisableSpecificWarnings> <!-- function not inlined -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4711</DisableSpecificWarnings> <!-- function selected for automatic expansion -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4738</DisableSpecificWarnings> <!-- storing 32-bit float result in memory -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4820</DisableSpecificWarnings> <!-- N bytes padding added -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4866</DisableSpecificWarnings> <!-- compiler may not enforce ltr eval in operator[] -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4868</DisableSpecificWarnings> <!-- compiler may not enforce ltr eval in initializer list -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4946</DisableSpecificWarnings> <!-- reinterpret_cast used between related classes -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);5026</DisableSpecificWarnings> <!-- move constructor was implicitly defined as deleted -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);5027</DisableSpecificWarnings> <!-- move assignment operator was implicitly defined as deleted -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);5039</DisableSpecificWarnings> <!-- potentially throwing function passed to 'extern "C"' -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);5045</DisableSpecificWarnings> <!-- Compiler will insert Spectre mitigation -->
+ </ClCompile>
+ </ItemDefinitionGroup>
+ <PropertyGroup>
+ <LocalDebuggerWorkingDirectory>$(ProjectDir)..\</LocalDebuggerWorkingDirectory>
+ </PropertyGroup>
+ <ItemGroup>
+ <ClCompile Include="..\at_path.cpp" />
+ <ClCompile Include="..\path.cpp" />
+ <ClCompile Include="..\conformance_burntsushi_invalid.cpp" />
+ <ClCompile Include="..\conformance_burntsushi_valid.cpp" />
+ <ClCompile Include="..\conformance_iarna_invalid.cpp" />
+ <ClCompile Include="..\conformance_iarna_valid.cpp" />
+ <ClCompile Include="..\for_each.cpp" />
+ <ClCompile Include="..\formatters.cpp" />
+ <ClCompile Include="..\impl_toml.cpp">
+ <PrecompiledHeader>NotUsing</PrecompiledHeader>
+ </ClCompile>
+ <ClCompile Include="..\main.cpp">
+ <PrecompiledHeader>NotUsing</PrecompiledHeader>
+ </ClCompile>
+ <ClCompile Include="..\manipulating_arrays.cpp" />
+ <ClCompile Include="..\manipulating_tables.cpp" />
+ <ClCompile Include="..\manipulating_parse_result.cpp" />
+ <ClCompile Include="..\manipulating_values.cpp" />
+ <ClCompile Include="..\parsing_arrays.cpp" />
+ <ClCompile Include="..\parsing_booleans.cpp" />
+ <ClCompile Include="..\parsing_comments.cpp" />
+ <ClCompile Include="..\parsing_dates_and_times.cpp" />
+ <ClCompile Include="..\parsing_floats.cpp" />
+ <ClCompile Include="..\parsing_integers.cpp" />
+ <ClCompile Include="..\parsing_key_value_pairs.cpp" />
+ <ClCompile Include="..\parsing_spec_example.cpp" />
+ <ClCompile Include="..\parsing_strings.cpp" />
+ <ClCompile Include="..\parsing_tables.cpp" />
+ <ClCompile Include="..\tests.cpp">
+ <PrecompiledHeader>Create</PrecompiledHeader>
+ </ClCompile>
+ <ClCompile Include="..\user_feedback.cpp" />
+ <ClCompile Include="..\using_iterators.cpp" />
+ <ClCompile Include="..\visit.cpp" />
+ <ClCompile Include="..\windows_compat.cpp" />
+ </ItemGroup>
+ <ItemGroup>
+ <Natvis Include="..\..\toml++.natvis" />
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="..\leakproof.hpp" />
+ <ClInclude Include="..\lib_catch2.hpp" />
+ <ClInclude Include="..\lib_tloptional.hpp" />
+ <ClInclude Include="..\settings.hpp" />
+ <ClInclude Include="..\tests.hpp" />
+ </ItemGroup>
+ <ItemGroup>
+ <None Include="..\cpp.hint" />
+ <None Include="..\meson.build" />
+ </ItemGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+</Project>
diff --git a/tomlplusplus/tests/vs/test_debug_x86_noexcept.vcxproj b/tomlplusplus/tests/vs/test_debug_x86_noexcept.vcxproj
new file mode 100644
index 0000000000..1d7098ba0f
--- /dev/null
+++ b/tomlplusplus/tests/vs/test_debug_x86_noexcept.vcxproj
@@ -0,0 +1,127 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup Label="ProjectConfigurations">
+ <ProjectConfiguration Include="Debug|Win32">
+ <Configuration>Debug</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ </ItemGroup>
+ <PropertyGroup Label="Globals">
+ <VCProjectVersion>16.0</VCProjectVersion>
+ <ProjectGuid>{F7375F00-0345-5F67-89C0-2B18412B40FB}</ProjectGuid>
+ <WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
+ <PreferredToolArchitecture>x64</PreferredToolArchitecture>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <UseDebugLibraries>true</UseDebugLibraries>
+ <PlatformToolset>v143</PlatformToolset>
+ <CharacterSet>MultiByte</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <UseDebugLibraries>false</UseDebugLibraries>
+ <PlatformToolset>v143</PlatformToolset>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ <CharacterSet>MultiByte</CharacterSet>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <ImportGroup Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props"
+ Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <Import Project="../../toml++.props" />
+ <ItemDefinitionGroup>
+ <ClCompile>
+ <AdditionalIncludeDirectories>..\tests;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <ExceptionHandling>false</ExceptionHandling>
+ <PrecompiledHeader>Use</PrecompiledHeader>
+ <PrecompiledHeaderFile>tests.hpp</PrecompiledHeaderFile>
+ <PreprocessorDefinitions>TOML_ENABLE_UNRELEASED_FEATURES=0;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <PreprocessorDefinitions>LEAK_TESTS=1;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'%(ExceptionHandling)'=='false'">_HAS_EXCEPTIONS=0;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'%(ExceptionHandling)'=='false'">SHOULD_HAVE_EXCEPTIONS=0;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'%(ExceptionHandling)'!='false'">SHOULD_HAVE_EXCEPTIONS=1;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <LanguageStandard>stdcpp17</LanguageStandard>
+ <MultiProcessorCompilation>true</MultiProcessorCompilation>
+ <WarningLevel>EnableAllWarnings</WarningLevel>
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4127</DisableSpecificWarnings> <!-- conditional expr is constant -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4324</DisableSpecificWarnings> <!-- structure was padded due to alignment specifier -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4464</DisableSpecificWarnings> <!-- relative include path contains '..' -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4505</DisableSpecificWarnings> <!-- unreferenced local function removed -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4514</DisableSpecificWarnings> <!-- unreferenced inline function has been removed -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4577</DisableSpecificWarnings> <!-- 'noexcept' used with no exception handling mode specified -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4582</DisableSpecificWarnings> <!-- constructor is not implicitly called -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4623</DisableSpecificWarnings> <!-- default constructor was implicitly defined as deleted -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4625</DisableSpecificWarnings> <!-- copy constructor was implicitly defined as deleted -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4626</DisableSpecificWarnings> <!-- assignment operator was implicitly defined as deleted -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4710</DisableSpecificWarnings> <!-- function not inlined -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4711</DisableSpecificWarnings> <!-- function selected for automatic expansion -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4738</DisableSpecificWarnings> <!-- storing 32-bit float result in memory -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4820</DisableSpecificWarnings> <!-- N bytes padding added -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4866</DisableSpecificWarnings> <!-- compiler may not enforce ltr eval in operator[] -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4868</DisableSpecificWarnings> <!-- compiler may not enforce ltr eval in initializer list -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4946</DisableSpecificWarnings> <!-- reinterpret_cast used between related classes -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);5026</DisableSpecificWarnings> <!-- move constructor was implicitly defined as deleted -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);5027</DisableSpecificWarnings> <!-- move assignment operator was implicitly defined as deleted -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);5039</DisableSpecificWarnings> <!-- potentially throwing function passed to 'extern "C"' -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);5045</DisableSpecificWarnings> <!-- Compiler will insert Spectre mitigation -->
+ </ClCompile>
+ </ItemDefinitionGroup>
+ <PropertyGroup>
+ <LocalDebuggerWorkingDirectory>$(ProjectDir)..\</LocalDebuggerWorkingDirectory>
+ </PropertyGroup>
+ <ItemGroup>
+ <ClCompile Include="..\at_path.cpp" />
+ <ClCompile Include="..\path.cpp" />
+ <ClCompile Include="..\conformance_burntsushi_invalid.cpp" />
+ <ClCompile Include="..\conformance_burntsushi_valid.cpp" />
+ <ClCompile Include="..\conformance_iarna_invalid.cpp" />
+ <ClCompile Include="..\conformance_iarna_valid.cpp" />
+ <ClCompile Include="..\for_each.cpp" />
+ <ClCompile Include="..\formatters.cpp" />
+ <ClCompile Include="..\impl_toml.cpp">
+ <PrecompiledHeader>NotUsing</PrecompiledHeader>
+ </ClCompile>
+ <ClCompile Include="..\main.cpp">
+ <PrecompiledHeader>NotUsing</PrecompiledHeader>
+ </ClCompile>
+ <ClCompile Include="..\manipulating_arrays.cpp" />
+ <ClCompile Include="..\manipulating_tables.cpp" />
+ <ClCompile Include="..\manipulating_parse_result.cpp" />
+ <ClCompile Include="..\manipulating_values.cpp" />
+ <ClCompile Include="..\parsing_arrays.cpp" />
+ <ClCompile Include="..\parsing_booleans.cpp" />
+ <ClCompile Include="..\parsing_comments.cpp" />
+ <ClCompile Include="..\parsing_dates_and_times.cpp" />
+ <ClCompile Include="..\parsing_floats.cpp" />
+ <ClCompile Include="..\parsing_integers.cpp" />
+ <ClCompile Include="..\parsing_key_value_pairs.cpp" />
+ <ClCompile Include="..\parsing_spec_example.cpp" />
+ <ClCompile Include="..\parsing_strings.cpp" />
+ <ClCompile Include="..\parsing_tables.cpp" />
+ <ClCompile Include="..\tests.cpp">
+ <PrecompiledHeader>Create</PrecompiledHeader>
+ </ClCompile>
+ <ClCompile Include="..\user_feedback.cpp" />
+ <ClCompile Include="..\using_iterators.cpp" />
+ <ClCompile Include="..\visit.cpp" />
+ <ClCompile Include="..\windows_compat.cpp" />
+ </ItemGroup>
+ <ItemGroup>
+ <Natvis Include="..\..\toml++.natvis" />
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="..\leakproof.hpp" />
+ <ClInclude Include="..\lib_catch2.hpp" />
+ <ClInclude Include="..\lib_tloptional.hpp" />
+ <ClInclude Include="..\settings.hpp" />
+ <ClInclude Include="..\tests.hpp" />
+ </ItemGroup>
+ <ItemGroup>
+ <None Include="..\cpp.hint" />
+ <None Include="..\meson.build" />
+ </ItemGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+</Project>
diff --git a/tomlplusplus/tests/vs/test_debug_x86_noexcept_unrel.vcxproj b/tomlplusplus/tests/vs/test_debug_x86_noexcept_unrel.vcxproj
new file mode 100644
index 0000000000..7f4fe51aa6
--- /dev/null
+++ b/tomlplusplus/tests/vs/test_debug_x86_noexcept_unrel.vcxproj
@@ -0,0 +1,127 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup Label="ProjectConfigurations">
+ <ProjectConfiguration Include="Debug|Win32">
+ <Configuration>Debug</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ </ItemGroup>
+ <PropertyGroup Label="Globals">
+ <VCProjectVersion>16.0</VCProjectVersion>
+ <ProjectGuid>{92AAC430-36B0-51E4-8E39-F3C579EDB331}</ProjectGuid>
+ <WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
+ <PreferredToolArchitecture>x64</PreferredToolArchitecture>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <UseDebugLibraries>true</UseDebugLibraries>
+ <PlatformToolset>v143</PlatformToolset>
+ <CharacterSet>MultiByte</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <UseDebugLibraries>false</UseDebugLibraries>
+ <PlatformToolset>v143</PlatformToolset>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ <CharacterSet>MultiByte</CharacterSet>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <ImportGroup Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props"
+ Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <Import Project="../../toml++.props" />
+ <ItemDefinitionGroup>
+ <ClCompile>
+ <AdditionalIncludeDirectories>..\tests;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <ExceptionHandling>false</ExceptionHandling>
+ <PrecompiledHeader>Use</PrecompiledHeader>
+ <PrecompiledHeaderFile>tests.hpp</PrecompiledHeaderFile>
+ <PreprocessorDefinitions>TOML_ENABLE_UNRELEASED_FEATURES=1;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <PreprocessorDefinitions>LEAK_TESTS=1;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'%(ExceptionHandling)'=='false'">_HAS_EXCEPTIONS=0;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'%(ExceptionHandling)'=='false'">SHOULD_HAVE_EXCEPTIONS=0;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'%(ExceptionHandling)'!='false'">SHOULD_HAVE_EXCEPTIONS=1;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <LanguageStandard>stdcpp17</LanguageStandard>
+ <MultiProcessorCompilation>true</MultiProcessorCompilation>
+ <WarningLevel>EnableAllWarnings</WarningLevel>
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4127</DisableSpecificWarnings> <!-- conditional expr is constant -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4324</DisableSpecificWarnings> <!-- structure was padded due to alignment specifier -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4464</DisableSpecificWarnings> <!-- relative include path contains '..' -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4505</DisableSpecificWarnings> <!-- unreferenced local function removed -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4514</DisableSpecificWarnings> <!-- unreferenced inline function has been removed -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4577</DisableSpecificWarnings> <!-- 'noexcept' used with no exception handling mode specified -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4582</DisableSpecificWarnings> <!-- constructor is not implicitly called -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4623</DisableSpecificWarnings> <!-- default constructor was implicitly defined as deleted -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4625</DisableSpecificWarnings> <!-- copy constructor was implicitly defined as deleted -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4626</DisableSpecificWarnings> <!-- assignment operator was implicitly defined as deleted -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4710</DisableSpecificWarnings> <!-- function not inlined -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4711</DisableSpecificWarnings> <!-- function selected for automatic expansion -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4738</DisableSpecificWarnings> <!-- storing 32-bit float result in memory -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4820</DisableSpecificWarnings> <!-- N bytes padding added -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4866</DisableSpecificWarnings> <!-- compiler may not enforce ltr eval in operator[] -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4868</DisableSpecificWarnings> <!-- compiler may not enforce ltr eval in initializer list -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4946</DisableSpecificWarnings> <!-- reinterpret_cast used between related classes -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);5026</DisableSpecificWarnings> <!-- move constructor was implicitly defined as deleted -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);5027</DisableSpecificWarnings> <!-- move assignment operator was implicitly defined as deleted -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);5039</DisableSpecificWarnings> <!-- potentially throwing function passed to 'extern "C"' -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);5045</DisableSpecificWarnings> <!-- Compiler will insert Spectre mitigation -->
+ </ClCompile>
+ </ItemDefinitionGroup>
+ <PropertyGroup>
+ <LocalDebuggerWorkingDirectory>$(ProjectDir)..\</LocalDebuggerWorkingDirectory>
+ </PropertyGroup>
+ <ItemGroup>
+ <ClCompile Include="..\at_path.cpp" />
+ <ClCompile Include="..\path.cpp" />
+ <ClCompile Include="..\conformance_burntsushi_invalid.cpp" />
+ <ClCompile Include="..\conformance_burntsushi_valid.cpp" />
+ <ClCompile Include="..\conformance_iarna_invalid.cpp" />
+ <ClCompile Include="..\conformance_iarna_valid.cpp" />
+ <ClCompile Include="..\for_each.cpp" />
+ <ClCompile Include="..\formatters.cpp" />
+ <ClCompile Include="..\impl_toml.cpp">
+ <PrecompiledHeader>NotUsing</PrecompiledHeader>
+ </ClCompile>
+ <ClCompile Include="..\main.cpp">
+ <PrecompiledHeader>NotUsing</PrecompiledHeader>
+ </ClCompile>
+ <ClCompile Include="..\manipulating_arrays.cpp" />
+ <ClCompile Include="..\manipulating_tables.cpp" />
+ <ClCompile Include="..\manipulating_parse_result.cpp" />
+ <ClCompile Include="..\manipulating_values.cpp" />
+ <ClCompile Include="..\parsing_arrays.cpp" />
+ <ClCompile Include="..\parsing_booleans.cpp" />
+ <ClCompile Include="..\parsing_comments.cpp" />
+ <ClCompile Include="..\parsing_dates_and_times.cpp" />
+ <ClCompile Include="..\parsing_floats.cpp" />
+ <ClCompile Include="..\parsing_integers.cpp" />
+ <ClCompile Include="..\parsing_key_value_pairs.cpp" />
+ <ClCompile Include="..\parsing_spec_example.cpp" />
+ <ClCompile Include="..\parsing_strings.cpp" />
+ <ClCompile Include="..\parsing_tables.cpp" />
+ <ClCompile Include="..\tests.cpp">
+ <PrecompiledHeader>Create</PrecompiledHeader>
+ </ClCompile>
+ <ClCompile Include="..\user_feedback.cpp" />
+ <ClCompile Include="..\using_iterators.cpp" />
+ <ClCompile Include="..\visit.cpp" />
+ <ClCompile Include="..\windows_compat.cpp" />
+ </ItemGroup>
+ <ItemGroup>
+ <Natvis Include="..\..\toml++.natvis" />
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="..\leakproof.hpp" />
+ <ClInclude Include="..\lib_catch2.hpp" />
+ <ClInclude Include="..\lib_tloptional.hpp" />
+ <ClInclude Include="..\settings.hpp" />
+ <ClInclude Include="..\tests.hpp" />
+ </ItemGroup>
+ <ItemGroup>
+ <None Include="..\cpp.hint" />
+ <None Include="..\meson.build" />
+ </ItemGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+</Project>
diff --git a/tomlplusplus/tests/vs/test_debug_x86_unrel.vcxproj b/tomlplusplus/tests/vs/test_debug_x86_unrel.vcxproj
new file mode 100644
index 0000000000..62edabce0d
--- /dev/null
+++ b/tomlplusplus/tests/vs/test_debug_x86_unrel.vcxproj
@@ -0,0 +1,127 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup Label="ProjectConfigurations">
+ <ProjectConfiguration Include="Debug|Win32">
+ <Configuration>Debug</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ </ItemGroup>
+ <PropertyGroup Label="Globals">
+ <VCProjectVersion>16.0</VCProjectVersion>
+ <ProjectGuid>{B1EAF133-1019-510F-A083-FC04774FF12E}</ProjectGuid>
+ <WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
+ <PreferredToolArchitecture>x64</PreferredToolArchitecture>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <UseDebugLibraries>true</UseDebugLibraries>
+ <PlatformToolset>v143</PlatformToolset>
+ <CharacterSet>MultiByte</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <UseDebugLibraries>false</UseDebugLibraries>
+ <PlatformToolset>v143</PlatformToolset>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ <CharacterSet>MultiByte</CharacterSet>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <ImportGroup Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props"
+ Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <Import Project="../../toml++.props" />
+ <ItemDefinitionGroup>
+ <ClCompile>
+ <AdditionalIncludeDirectories>..\tests;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <ExceptionHandling>Sync</ExceptionHandling>
+ <PrecompiledHeader>Use</PrecompiledHeader>
+ <PrecompiledHeaderFile>tests.hpp</PrecompiledHeaderFile>
+ <PreprocessorDefinitions>TOML_ENABLE_UNRELEASED_FEATURES=1;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <PreprocessorDefinitions>LEAK_TESTS=1;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'%(ExceptionHandling)'=='false'">_HAS_EXCEPTIONS=0;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'%(ExceptionHandling)'=='false'">SHOULD_HAVE_EXCEPTIONS=0;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'%(ExceptionHandling)'!='false'">SHOULD_HAVE_EXCEPTIONS=1;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <LanguageStandard>stdcpp17</LanguageStandard>
+ <MultiProcessorCompilation>true</MultiProcessorCompilation>
+ <WarningLevel>EnableAllWarnings</WarningLevel>
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4127</DisableSpecificWarnings> <!-- conditional expr is constant -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4324</DisableSpecificWarnings> <!-- structure was padded due to alignment specifier -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4464</DisableSpecificWarnings> <!-- relative include path contains '..' -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4505</DisableSpecificWarnings> <!-- unreferenced local function removed -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4514</DisableSpecificWarnings> <!-- unreferenced inline function has been removed -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4577</DisableSpecificWarnings> <!-- 'noexcept' used with no exception handling mode specified -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4582</DisableSpecificWarnings> <!-- constructor is not implicitly called -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4623</DisableSpecificWarnings> <!-- default constructor was implicitly defined as deleted -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4625</DisableSpecificWarnings> <!-- copy constructor was implicitly defined as deleted -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4626</DisableSpecificWarnings> <!-- assignment operator was implicitly defined as deleted -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4710</DisableSpecificWarnings> <!-- function not inlined -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4711</DisableSpecificWarnings> <!-- function selected for automatic expansion -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4738</DisableSpecificWarnings> <!-- storing 32-bit float result in memory -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4820</DisableSpecificWarnings> <!-- N bytes padding added -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4866</DisableSpecificWarnings> <!-- compiler may not enforce ltr eval in operator[] -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4868</DisableSpecificWarnings> <!-- compiler may not enforce ltr eval in initializer list -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4946</DisableSpecificWarnings> <!-- reinterpret_cast used between related classes -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);5026</DisableSpecificWarnings> <!-- move constructor was implicitly defined as deleted -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);5027</DisableSpecificWarnings> <!-- move assignment operator was implicitly defined as deleted -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);5039</DisableSpecificWarnings> <!-- potentially throwing function passed to 'extern "C"' -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);5045</DisableSpecificWarnings> <!-- Compiler will insert Spectre mitigation -->
+ </ClCompile>
+ </ItemDefinitionGroup>
+ <PropertyGroup>
+ <LocalDebuggerWorkingDirectory>$(ProjectDir)..\</LocalDebuggerWorkingDirectory>
+ </PropertyGroup>
+ <ItemGroup>
+ <ClCompile Include="..\at_path.cpp" />
+ <ClCompile Include="..\path.cpp" />
+ <ClCompile Include="..\conformance_burntsushi_invalid.cpp" />
+ <ClCompile Include="..\conformance_burntsushi_valid.cpp" />
+ <ClCompile Include="..\conformance_iarna_invalid.cpp" />
+ <ClCompile Include="..\conformance_iarna_valid.cpp" />
+ <ClCompile Include="..\for_each.cpp" />
+ <ClCompile Include="..\formatters.cpp" />
+ <ClCompile Include="..\impl_toml.cpp">
+ <PrecompiledHeader>NotUsing</PrecompiledHeader>
+ </ClCompile>
+ <ClCompile Include="..\main.cpp">
+ <PrecompiledHeader>NotUsing</PrecompiledHeader>
+ </ClCompile>
+ <ClCompile Include="..\manipulating_arrays.cpp" />
+ <ClCompile Include="..\manipulating_tables.cpp" />
+ <ClCompile Include="..\manipulating_parse_result.cpp" />
+ <ClCompile Include="..\manipulating_values.cpp" />
+ <ClCompile Include="..\parsing_arrays.cpp" />
+ <ClCompile Include="..\parsing_booleans.cpp" />
+ <ClCompile Include="..\parsing_comments.cpp" />
+ <ClCompile Include="..\parsing_dates_and_times.cpp" />
+ <ClCompile Include="..\parsing_floats.cpp" />
+ <ClCompile Include="..\parsing_integers.cpp" />
+ <ClCompile Include="..\parsing_key_value_pairs.cpp" />
+ <ClCompile Include="..\parsing_spec_example.cpp" />
+ <ClCompile Include="..\parsing_strings.cpp" />
+ <ClCompile Include="..\parsing_tables.cpp" />
+ <ClCompile Include="..\tests.cpp">
+ <PrecompiledHeader>Create</PrecompiledHeader>
+ </ClCompile>
+ <ClCompile Include="..\user_feedback.cpp" />
+ <ClCompile Include="..\using_iterators.cpp" />
+ <ClCompile Include="..\visit.cpp" />
+ <ClCompile Include="..\windows_compat.cpp" />
+ </ItemGroup>
+ <ItemGroup>
+ <Natvis Include="..\..\toml++.natvis" />
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="..\leakproof.hpp" />
+ <ClInclude Include="..\lib_catch2.hpp" />
+ <ClInclude Include="..\lib_tloptional.hpp" />
+ <ClInclude Include="..\settings.hpp" />
+ <ClInclude Include="..\tests.hpp" />
+ </ItemGroup>
+ <ItemGroup>
+ <None Include="..\cpp.hint" />
+ <None Include="..\meson.build" />
+ </ItemGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+</Project>
diff --git a/tomlplusplus/tests/vs/test_release_x64.vcxproj b/tomlplusplus/tests/vs/test_release_x64.vcxproj
new file mode 100644
index 0000000000..8836ba049d
--- /dev/null
+++ b/tomlplusplus/tests/vs/test_release_x64.vcxproj
@@ -0,0 +1,127 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup Label="ProjectConfigurations">
+ <ProjectConfiguration Include="Release|x64">
+ <Configuration>Release</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ </ItemGroup>
+ <PropertyGroup Label="Globals">
+ <VCProjectVersion>16.0</VCProjectVersion>
+ <ProjectGuid>{F70977E7-E735-5D5C-9043-CA792F1B9392}</ProjectGuid>
+ <WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
+ <PreferredToolArchitecture>x64</PreferredToolArchitecture>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <UseDebugLibraries>true</UseDebugLibraries>
+ <PlatformToolset>v143</PlatformToolset>
+ <CharacterSet>MultiByte</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <UseDebugLibraries>false</UseDebugLibraries>
+ <PlatformToolset>v143</PlatformToolset>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ <CharacterSet>MultiByte</CharacterSet>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <ImportGroup Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props"
+ Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <Import Project="../../toml++.props" />
+ <ItemDefinitionGroup>
+ <ClCompile>
+ <AdditionalIncludeDirectories>..\tests;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <ExceptionHandling>Sync</ExceptionHandling>
+ <PrecompiledHeader>Use</PrecompiledHeader>
+ <PrecompiledHeaderFile>tests.hpp</PrecompiledHeaderFile>
+ <PreprocessorDefinitions>TOML_ENABLE_UNRELEASED_FEATURES=0;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <PreprocessorDefinitions>LEAK_TESTS=1;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'%(ExceptionHandling)'=='false'">_HAS_EXCEPTIONS=0;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'%(ExceptionHandling)'=='false'">SHOULD_HAVE_EXCEPTIONS=0;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'%(ExceptionHandling)'!='false'">SHOULD_HAVE_EXCEPTIONS=1;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <LanguageStandard>stdcpp17</LanguageStandard>
+ <MultiProcessorCompilation>true</MultiProcessorCompilation>
+ <WarningLevel>EnableAllWarnings</WarningLevel>
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4127</DisableSpecificWarnings> <!-- conditional expr is constant -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4324</DisableSpecificWarnings> <!-- structure was padded due to alignment specifier -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4464</DisableSpecificWarnings> <!-- relative include path contains '..' -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4505</DisableSpecificWarnings> <!-- unreferenced local function removed -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4514</DisableSpecificWarnings> <!-- unreferenced inline function has been removed -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4577</DisableSpecificWarnings> <!-- 'noexcept' used with no exception handling mode specified -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4582</DisableSpecificWarnings> <!-- constructor is not implicitly called -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4623</DisableSpecificWarnings> <!-- default constructor was implicitly defined as deleted -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4625</DisableSpecificWarnings> <!-- copy constructor was implicitly defined as deleted -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4626</DisableSpecificWarnings> <!-- assignment operator was implicitly defined as deleted -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4710</DisableSpecificWarnings> <!-- function not inlined -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4711</DisableSpecificWarnings> <!-- function selected for automatic expansion -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4738</DisableSpecificWarnings> <!-- storing 32-bit float result in memory -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4820</DisableSpecificWarnings> <!-- N bytes padding added -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4866</DisableSpecificWarnings> <!-- compiler may not enforce ltr eval in operator[] -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4868</DisableSpecificWarnings> <!-- compiler may not enforce ltr eval in initializer list -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4946</DisableSpecificWarnings> <!-- reinterpret_cast used between related classes -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);5026</DisableSpecificWarnings> <!-- move constructor was implicitly defined as deleted -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);5027</DisableSpecificWarnings> <!-- move assignment operator was implicitly defined as deleted -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);5039</DisableSpecificWarnings> <!-- potentially throwing function passed to 'extern "C"' -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);5045</DisableSpecificWarnings> <!-- Compiler will insert Spectre mitigation -->
+ </ClCompile>
+ </ItemDefinitionGroup>
+ <PropertyGroup>
+ <LocalDebuggerWorkingDirectory>$(ProjectDir)..\</LocalDebuggerWorkingDirectory>
+ </PropertyGroup>
+ <ItemGroup>
+ <ClCompile Include="..\at_path.cpp" />
+ <ClCompile Include="..\path.cpp" />
+ <ClCompile Include="..\conformance_burntsushi_invalid.cpp" />
+ <ClCompile Include="..\conformance_burntsushi_valid.cpp" />
+ <ClCompile Include="..\conformance_iarna_invalid.cpp" />
+ <ClCompile Include="..\conformance_iarna_valid.cpp" />
+ <ClCompile Include="..\for_each.cpp" />
+ <ClCompile Include="..\formatters.cpp" />
+ <ClCompile Include="..\impl_toml.cpp">
+ <PrecompiledHeader>NotUsing</PrecompiledHeader>
+ </ClCompile>
+ <ClCompile Include="..\main.cpp">
+ <PrecompiledHeader>NotUsing</PrecompiledHeader>
+ </ClCompile>
+ <ClCompile Include="..\manipulating_arrays.cpp" />
+ <ClCompile Include="..\manipulating_tables.cpp" />
+ <ClCompile Include="..\manipulating_parse_result.cpp" />
+ <ClCompile Include="..\manipulating_values.cpp" />
+ <ClCompile Include="..\parsing_arrays.cpp" />
+ <ClCompile Include="..\parsing_booleans.cpp" />
+ <ClCompile Include="..\parsing_comments.cpp" />
+ <ClCompile Include="..\parsing_dates_and_times.cpp" />
+ <ClCompile Include="..\parsing_floats.cpp" />
+ <ClCompile Include="..\parsing_integers.cpp" />
+ <ClCompile Include="..\parsing_key_value_pairs.cpp" />
+ <ClCompile Include="..\parsing_spec_example.cpp" />
+ <ClCompile Include="..\parsing_strings.cpp" />
+ <ClCompile Include="..\parsing_tables.cpp" />
+ <ClCompile Include="..\tests.cpp">
+ <PrecompiledHeader>Create</PrecompiledHeader>
+ </ClCompile>
+ <ClCompile Include="..\user_feedback.cpp" />
+ <ClCompile Include="..\using_iterators.cpp" />
+ <ClCompile Include="..\visit.cpp" />
+ <ClCompile Include="..\windows_compat.cpp" />
+ </ItemGroup>
+ <ItemGroup>
+ <Natvis Include="..\..\toml++.natvis" />
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="..\leakproof.hpp" />
+ <ClInclude Include="..\lib_catch2.hpp" />
+ <ClInclude Include="..\lib_tloptional.hpp" />
+ <ClInclude Include="..\settings.hpp" />
+ <ClInclude Include="..\tests.hpp" />
+ </ItemGroup>
+ <ItemGroup>
+ <None Include="..\cpp.hint" />
+ <None Include="..\meson.build" />
+ </ItemGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+</Project>
diff --git a/tomlplusplus/tests/vs/test_release_x64_cpplatest.vcxproj b/tomlplusplus/tests/vs/test_release_x64_cpplatest.vcxproj
new file mode 100644
index 0000000000..7e5cbd061f
--- /dev/null
+++ b/tomlplusplus/tests/vs/test_release_x64_cpplatest.vcxproj
@@ -0,0 +1,127 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup Label="ProjectConfigurations">
+ <ProjectConfiguration Include="Release|x64">
+ <Configuration>Release</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ </ItemGroup>
+ <PropertyGroup Label="Globals">
+ <VCProjectVersion>16.0</VCProjectVersion>
+ <ProjectGuid>{413BDA52-0A9D-56B8-9AF3-A65019F42831}</ProjectGuid>
+ <WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
+ <PreferredToolArchitecture>x64</PreferredToolArchitecture>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <UseDebugLibraries>true</UseDebugLibraries>
+ <PlatformToolset>v143</PlatformToolset>
+ <CharacterSet>MultiByte</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <UseDebugLibraries>false</UseDebugLibraries>
+ <PlatformToolset>v143</PlatformToolset>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ <CharacterSet>MultiByte</CharacterSet>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <ImportGroup Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props"
+ Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <Import Project="../../toml++.props" />
+ <ItemDefinitionGroup>
+ <ClCompile>
+ <AdditionalIncludeDirectories>..\tests;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <ExceptionHandling>Sync</ExceptionHandling>
+ <PrecompiledHeader>Use</PrecompiledHeader>
+ <PrecompiledHeaderFile>tests.hpp</PrecompiledHeaderFile>
+ <PreprocessorDefinitions>TOML_ENABLE_UNRELEASED_FEATURES=0;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <PreprocessorDefinitions>LEAK_TESTS=1;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'%(ExceptionHandling)'=='false'">_HAS_EXCEPTIONS=0;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'%(ExceptionHandling)'=='false'">SHOULD_HAVE_EXCEPTIONS=0;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'%(ExceptionHandling)'!='false'">SHOULD_HAVE_EXCEPTIONS=1;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <LanguageStandard>stdcpplatest</LanguageStandard>
+ <MultiProcessorCompilation>true</MultiProcessorCompilation>
+ <WarningLevel>EnableAllWarnings</WarningLevel>
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4127</DisableSpecificWarnings> <!-- conditional expr is constant -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4324</DisableSpecificWarnings> <!-- structure was padded due to alignment specifier -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4464</DisableSpecificWarnings> <!-- relative include path contains '..' -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4505</DisableSpecificWarnings> <!-- unreferenced local function removed -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4514</DisableSpecificWarnings> <!-- unreferenced inline function has been removed -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4577</DisableSpecificWarnings> <!-- 'noexcept' used with no exception handling mode specified -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4582</DisableSpecificWarnings> <!-- constructor is not implicitly called -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4623</DisableSpecificWarnings> <!-- default constructor was implicitly defined as deleted -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4625</DisableSpecificWarnings> <!-- copy constructor was implicitly defined as deleted -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4626</DisableSpecificWarnings> <!-- assignment operator was implicitly defined as deleted -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4710</DisableSpecificWarnings> <!-- function not inlined -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4711</DisableSpecificWarnings> <!-- function selected for automatic expansion -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4738</DisableSpecificWarnings> <!-- storing 32-bit float result in memory -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4820</DisableSpecificWarnings> <!-- N bytes padding added -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4866</DisableSpecificWarnings> <!-- compiler may not enforce ltr eval in operator[] -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4868</DisableSpecificWarnings> <!-- compiler may not enforce ltr eval in initializer list -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4946</DisableSpecificWarnings> <!-- reinterpret_cast used between related classes -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);5026</DisableSpecificWarnings> <!-- move constructor was implicitly defined as deleted -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);5027</DisableSpecificWarnings> <!-- move assignment operator was implicitly defined as deleted -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);5039</DisableSpecificWarnings> <!-- potentially throwing function passed to 'extern "C"' -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);5045</DisableSpecificWarnings> <!-- Compiler will insert Spectre mitigation -->
+ </ClCompile>
+ </ItemDefinitionGroup>
+ <PropertyGroup>
+ <LocalDebuggerWorkingDirectory>$(ProjectDir)..\</LocalDebuggerWorkingDirectory>
+ </PropertyGroup>
+ <ItemGroup>
+ <ClCompile Include="..\at_path.cpp" />
+ <ClCompile Include="..\path.cpp" />
+ <ClCompile Include="..\conformance_burntsushi_invalid.cpp" />
+ <ClCompile Include="..\conformance_burntsushi_valid.cpp" />
+ <ClCompile Include="..\conformance_iarna_invalid.cpp" />
+ <ClCompile Include="..\conformance_iarna_valid.cpp" />
+ <ClCompile Include="..\for_each.cpp" />
+ <ClCompile Include="..\formatters.cpp" />
+ <ClCompile Include="..\impl_toml.cpp">
+ <PrecompiledHeader>NotUsing</PrecompiledHeader>
+ </ClCompile>
+ <ClCompile Include="..\main.cpp">
+ <PrecompiledHeader>NotUsing</PrecompiledHeader>
+ </ClCompile>
+ <ClCompile Include="..\manipulating_arrays.cpp" />
+ <ClCompile Include="..\manipulating_tables.cpp" />
+ <ClCompile Include="..\manipulating_parse_result.cpp" />
+ <ClCompile Include="..\manipulating_values.cpp" />
+ <ClCompile Include="..\parsing_arrays.cpp" />
+ <ClCompile Include="..\parsing_booleans.cpp" />
+ <ClCompile Include="..\parsing_comments.cpp" />
+ <ClCompile Include="..\parsing_dates_and_times.cpp" />
+ <ClCompile Include="..\parsing_floats.cpp" />
+ <ClCompile Include="..\parsing_integers.cpp" />
+ <ClCompile Include="..\parsing_key_value_pairs.cpp" />
+ <ClCompile Include="..\parsing_spec_example.cpp" />
+ <ClCompile Include="..\parsing_strings.cpp" />
+ <ClCompile Include="..\parsing_tables.cpp" />
+ <ClCompile Include="..\tests.cpp">
+ <PrecompiledHeader>Create</PrecompiledHeader>
+ </ClCompile>
+ <ClCompile Include="..\user_feedback.cpp" />
+ <ClCompile Include="..\using_iterators.cpp" />
+ <ClCompile Include="..\visit.cpp" />
+ <ClCompile Include="..\windows_compat.cpp" />
+ </ItemGroup>
+ <ItemGroup>
+ <Natvis Include="..\..\toml++.natvis" />
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="..\leakproof.hpp" />
+ <ClInclude Include="..\lib_catch2.hpp" />
+ <ClInclude Include="..\lib_tloptional.hpp" />
+ <ClInclude Include="..\settings.hpp" />
+ <ClInclude Include="..\tests.hpp" />
+ </ItemGroup>
+ <ItemGroup>
+ <None Include="..\cpp.hint" />
+ <None Include="..\meson.build" />
+ </ItemGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+</Project>
diff --git a/tomlplusplus/tests/vs/test_release_x64_cpplatest_noexcept.vcxproj b/tomlplusplus/tests/vs/test_release_x64_cpplatest_noexcept.vcxproj
new file mode 100644
index 0000000000..cff40b6cde
--- /dev/null
+++ b/tomlplusplus/tests/vs/test_release_x64_cpplatest_noexcept.vcxproj
@@ -0,0 +1,127 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup Label="ProjectConfigurations">
+ <ProjectConfiguration Include="Release|x64">
+ <Configuration>Release</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ </ItemGroup>
+ <PropertyGroup Label="Globals">
+ <VCProjectVersion>16.0</VCProjectVersion>
+ <ProjectGuid>{6F6D8031-4BA9-5F07-BE1F-190A2FC3CC9C}</ProjectGuid>
+ <WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
+ <PreferredToolArchitecture>x64</PreferredToolArchitecture>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <UseDebugLibraries>true</UseDebugLibraries>
+ <PlatformToolset>v143</PlatformToolset>
+ <CharacterSet>MultiByte</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <UseDebugLibraries>false</UseDebugLibraries>
+ <PlatformToolset>v143</PlatformToolset>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ <CharacterSet>MultiByte</CharacterSet>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <ImportGroup Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props"
+ Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <Import Project="../../toml++.props" />
+ <ItemDefinitionGroup>
+ <ClCompile>
+ <AdditionalIncludeDirectories>..\tests;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <ExceptionHandling>false</ExceptionHandling>
+ <PrecompiledHeader>Use</PrecompiledHeader>
+ <PrecompiledHeaderFile>tests.hpp</PrecompiledHeaderFile>
+ <PreprocessorDefinitions>TOML_ENABLE_UNRELEASED_FEATURES=0;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <PreprocessorDefinitions>LEAK_TESTS=1;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'%(ExceptionHandling)'=='false'">_HAS_EXCEPTIONS=0;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'%(ExceptionHandling)'=='false'">SHOULD_HAVE_EXCEPTIONS=0;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'%(ExceptionHandling)'!='false'">SHOULD_HAVE_EXCEPTIONS=1;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <LanguageStandard>stdcpplatest</LanguageStandard>
+ <MultiProcessorCompilation>true</MultiProcessorCompilation>
+ <WarningLevel>EnableAllWarnings</WarningLevel>
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4127</DisableSpecificWarnings> <!-- conditional expr is constant -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4324</DisableSpecificWarnings> <!-- structure was padded due to alignment specifier -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4464</DisableSpecificWarnings> <!-- relative include path contains '..' -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4505</DisableSpecificWarnings> <!-- unreferenced local function removed -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4514</DisableSpecificWarnings> <!-- unreferenced inline function has been removed -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4577</DisableSpecificWarnings> <!-- 'noexcept' used with no exception handling mode specified -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4582</DisableSpecificWarnings> <!-- constructor is not implicitly called -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4623</DisableSpecificWarnings> <!-- default constructor was implicitly defined as deleted -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4625</DisableSpecificWarnings> <!-- copy constructor was implicitly defined as deleted -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4626</DisableSpecificWarnings> <!-- assignment operator was implicitly defined as deleted -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4710</DisableSpecificWarnings> <!-- function not inlined -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4711</DisableSpecificWarnings> <!-- function selected for automatic expansion -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4738</DisableSpecificWarnings> <!-- storing 32-bit float result in memory -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4820</DisableSpecificWarnings> <!-- N bytes padding added -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4866</DisableSpecificWarnings> <!-- compiler may not enforce ltr eval in operator[] -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4868</DisableSpecificWarnings> <!-- compiler may not enforce ltr eval in initializer list -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4946</DisableSpecificWarnings> <!-- reinterpret_cast used between related classes -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);5026</DisableSpecificWarnings> <!-- move constructor was implicitly defined as deleted -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);5027</DisableSpecificWarnings> <!-- move assignment operator was implicitly defined as deleted -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);5039</DisableSpecificWarnings> <!-- potentially throwing function passed to 'extern "C"' -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);5045</DisableSpecificWarnings> <!-- Compiler will insert Spectre mitigation -->
+ </ClCompile>
+ </ItemDefinitionGroup>
+ <PropertyGroup>
+ <LocalDebuggerWorkingDirectory>$(ProjectDir)..\</LocalDebuggerWorkingDirectory>
+ </PropertyGroup>
+ <ItemGroup>
+ <ClCompile Include="..\at_path.cpp" />
+ <ClCompile Include="..\path.cpp" />
+ <ClCompile Include="..\conformance_burntsushi_invalid.cpp" />
+ <ClCompile Include="..\conformance_burntsushi_valid.cpp" />
+ <ClCompile Include="..\conformance_iarna_invalid.cpp" />
+ <ClCompile Include="..\conformance_iarna_valid.cpp" />
+ <ClCompile Include="..\for_each.cpp" />
+ <ClCompile Include="..\formatters.cpp" />
+ <ClCompile Include="..\impl_toml.cpp">
+ <PrecompiledHeader>NotUsing</PrecompiledHeader>
+ </ClCompile>
+ <ClCompile Include="..\main.cpp">
+ <PrecompiledHeader>NotUsing</PrecompiledHeader>
+ </ClCompile>
+ <ClCompile Include="..\manipulating_arrays.cpp" />
+ <ClCompile Include="..\manipulating_tables.cpp" />
+ <ClCompile Include="..\manipulating_parse_result.cpp" />
+ <ClCompile Include="..\manipulating_values.cpp" />
+ <ClCompile Include="..\parsing_arrays.cpp" />
+ <ClCompile Include="..\parsing_booleans.cpp" />
+ <ClCompile Include="..\parsing_comments.cpp" />
+ <ClCompile Include="..\parsing_dates_and_times.cpp" />
+ <ClCompile Include="..\parsing_floats.cpp" />
+ <ClCompile Include="..\parsing_integers.cpp" />
+ <ClCompile Include="..\parsing_key_value_pairs.cpp" />
+ <ClCompile Include="..\parsing_spec_example.cpp" />
+ <ClCompile Include="..\parsing_strings.cpp" />
+ <ClCompile Include="..\parsing_tables.cpp" />
+ <ClCompile Include="..\tests.cpp">
+ <PrecompiledHeader>Create</PrecompiledHeader>
+ </ClCompile>
+ <ClCompile Include="..\user_feedback.cpp" />
+ <ClCompile Include="..\using_iterators.cpp" />
+ <ClCompile Include="..\visit.cpp" />
+ <ClCompile Include="..\windows_compat.cpp" />
+ </ItemGroup>
+ <ItemGroup>
+ <Natvis Include="..\..\toml++.natvis" />
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="..\leakproof.hpp" />
+ <ClInclude Include="..\lib_catch2.hpp" />
+ <ClInclude Include="..\lib_tloptional.hpp" />
+ <ClInclude Include="..\settings.hpp" />
+ <ClInclude Include="..\tests.hpp" />
+ </ItemGroup>
+ <ItemGroup>
+ <None Include="..\cpp.hint" />
+ <None Include="..\meson.build" />
+ </ItemGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+</Project>
diff --git a/tomlplusplus/tests/vs/test_release_x64_cpplatest_noexcept_unrel.vcxproj b/tomlplusplus/tests/vs/test_release_x64_cpplatest_noexcept_unrel.vcxproj
new file mode 100644
index 0000000000..6e260d2ac3
--- /dev/null
+++ b/tomlplusplus/tests/vs/test_release_x64_cpplatest_noexcept_unrel.vcxproj
@@ -0,0 +1,127 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup Label="ProjectConfigurations">
+ <ProjectConfiguration Include="Release|x64">
+ <Configuration>Release</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ </ItemGroup>
+ <PropertyGroup Label="Globals">
+ <VCProjectVersion>16.0</VCProjectVersion>
+ <ProjectGuid>{18ADA45A-11DD-5649-8492-F726E6A82803}</ProjectGuid>
+ <WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
+ <PreferredToolArchitecture>x64</PreferredToolArchitecture>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <UseDebugLibraries>true</UseDebugLibraries>
+ <PlatformToolset>v143</PlatformToolset>
+ <CharacterSet>MultiByte</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <UseDebugLibraries>false</UseDebugLibraries>
+ <PlatformToolset>v143</PlatformToolset>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ <CharacterSet>MultiByte</CharacterSet>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <ImportGroup Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props"
+ Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <Import Project="../../toml++.props" />
+ <ItemDefinitionGroup>
+ <ClCompile>
+ <AdditionalIncludeDirectories>..\tests;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <ExceptionHandling>false</ExceptionHandling>
+ <PrecompiledHeader>Use</PrecompiledHeader>
+ <PrecompiledHeaderFile>tests.hpp</PrecompiledHeaderFile>
+ <PreprocessorDefinitions>TOML_ENABLE_UNRELEASED_FEATURES=1;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <PreprocessorDefinitions>LEAK_TESTS=1;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'%(ExceptionHandling)'=='false'">_HAS_EXCEPTIONS=0;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'%(ExceptionHandling)'=='false'">SHOULD_HAVE_EXCEPTIONS=0;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'%(ExceptionHandling)'!='false'">SHOULD_HAVE_EXCEPTIONS=1;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <LanguageStandard>stdcpplatest</LanguageStandard>
+ <MultiProcessorCompilation>true</MultiProcessorCompilation>
+ <WarningLevel>EnableAllWarnings</WarningLevel>
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4127</DisableSpecificWarnings> <!-- conditional expr is constant -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4324</DisableSpecificWarnings> <!-- structure was padded due to alignment specifier -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4464</DisableSpecificWarnings> <!-- relative include path contains '..' -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4505</DisableSpecificWarnings> <!-- unreferenced local function removed -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4514</DisableSpecificWarnings> <!-- unreferenced inline function has been removed -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4577</DisableSpecificWarnings> <!-- 'noexcept' used with no exception handling mode specified -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4582</DisableSpecificWarnings> <!-- constructor is not implicitly called -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4623</DisableSpecificWarnings> <!-- default constructor was implicitly defined as deleted -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4625</DisableSpecificWarnings> <!-- copy constructor was implicitly defined as deleted -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4626</DisableSpecificWarnings> <!-- assignment operator was implicitly defined as deleted -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4710</DisableSpecificWarnings> <!-- function not inlined -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4711</DisableSpecificWarnings> <!-- function selected for automatic expansion -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4738</DisableSpecificWarnings> <!-- storing 32-bit float result in memory -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4820</DisableSpecificWarnings> <!-- N bytes padding added -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4866</DisableSpecificWarnings> <!-- compiler may not enforce ltr eval in operator[] -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4868</DisableSpecificWarnings> <!-- compiler may not enforce ltr eval in initializer list -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4946</DisableSpecificWarnings> <!-- reinterpret_cast used between related classes -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);5026</DisableSpecificWarnings> <!-- move constructor was implicitly defined as deleted -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);5027</DisableSpecificWarnings> <!-- move assignment operator was implicitly defined as deleted -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);5039</DisableSpecificWarnings> <!-- potentially throwing function passed to 'extern "C"' -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);5045</DisableSpecificWarnings> <!-- Compiler will insert Spectre mitigation -->
+ </ClCompile>
+ </ItemDefinitionGroup>
+ <PropertyGroup>
+ <LocalDebuggerWorkingDirectory>$(ProjectDir)..\</LocalDebuggerWorkingDirectory>
+ </PropertyGroup>
+ <ItemGroup>
+ <ClCompile Include="..\at_path.cpp" />
+ <ClCompile Include="..\path.cpp" />
+ <ClCompile Include="..\conformance_burntsushi_invalid.cpp" />
+ <ClCompile Include="..\conformance_burntsushi_valid.cpp" />
+ <ClCompile Include="..\conformance_iarna_invalid.cpp" />
+ <ClCompile Include="..\conformance_iarna_valid.cpp" />
+ <ClCompile Include="..\for_each.cpp" />
+ <ClCompile Include="..\formatters.cpp" />
+ <ClCompile Include="..\impl_toml.cpp">
+ <PrecompiledHeader>NotUsing</PrecompiledHeader>
+ </ClCompile>
+ <ClCompile Include="..\main.cpp">
+ <PrecompiledHeader>NotUsing</PrecompiledHeader>
+ </ClCompile>
+ <ClCompile Include="..\manipulating_arrays.cpp" />
+ <ClCompile Include="..\manipulating_tables.cpp" />
+ <ClCompile Include="..\manipulating_parse_result.cpp" />
+ <ClCompile Include="..\manipulating_values.cpp" />
+ <ClCompile Include="..\parsing_arrays.cpp" />
+ <ClCompile Include="..\parsing_booleans.cpp" />
+ <ClCompile Include="..\parsing_comments.cpp" />
+ <ClCompile Include="..\parsing_dates_and_times.cpp" />
+ <ClCompile Include="..\parsing_floats.cpp" />
+ <ClCompile Include="..\parsing_integers.cpp" />
+ <ClCompile Include="..\parsing_key_value_pairs.cpp" />
+ <ClCompile Include="..\parsing_spec_example.cpp" />
+ <ClCompile Include="..\parsing_strings.cpp" />
+ <ClCompile Include="..\parsing_tables.cpp" />
+ <ClCompile Include="..\tests.cpp">
+ <PrecompiledHeader>Create</PrecompiledHeader>
+ </ClCompile>
+ <ClCompile Include="..\user_feedback.cpp" />
+ <ClCompile Include="..\using_iterators.cpp" />
+ <ClCompile Include="..\visit.cpp" />
+ <ClCompile Include="..\windows_compat.cpp" />
+ </ItemGroup>
+ <ItemGroup>
+ <Natvis Include="..\..\toml++.natvis" />
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="..\leakproof.hpp" />
+ <ClInclude Include="..\lib_catch2.hpp" />
+ <ClInclude Include="..\lib_tloptional.hpp" />
+ <ClInclude Include="..\settings.hpp" />
+ <ClInclude Include="..\tests.hpp" />
+ </ItemGroup>
+ <ItemGroup>
+ <None Include="..\cpp.hint" />
+ <None Include="..\meson.build" />
+ </ItemGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+</Project>
diff --git a/tomlplusplus/tests/vs/test_release_x64_cpplatest_unrel.vcxproj b/tomlplusplus/tests/vs/test_release_x64_cpplatest_unrel.vcxproj
new file mode 100644
index 0000000000..ee9312c2d4
--- /dev/null
+++ b/tomlplusplus/tests/vs/test_release_x64_cpplatest_unrel.vcxproj
@@ -0,0 +1,127 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup Label="ProjectConfigurations">
+ <ProjectConfiguration Include="Release|x64">
+ <Configuration>Release</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ </ItemGroup>
+ <PropertyGroup Label="Globals">
+ <VCProjectVersion>16.0</VCProjectVersion>
+ <ProjectGuid>{74813AFD-DB22-52FA-9108-0BADD4B0E161}</ProjectGuid>
+ <WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
+ <PreferredToolArchitecture>x64</PreferredToolArchitecture>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <UseDebugLibraries>true</UseDebugLibraries>
+ <PlatformToolset>v143</PlatformToolset>
+ <CharacterSet>MultiByte</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <UseDebugLibraries>false</UseDebugLibraries>
+ <PlatformToolset>v143</PlatformToolset>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ <CharacterSet>MultiByte</CharacterSet>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <ImportGroup Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props"
+ Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <Import Project="../../toml++.props" />
+ <ItemDefinitionGroup>
+ <ClCompile>
+ <AdditionalIncludeDirectories>..\tests;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <ExceptionHandling>Sync</ExceptionHandling>
+ <PrecompiledHeader>Use</PrecompiledHeader>
+ <PrecompiledHeaderFile>tests.hpp</PrecompiledHeaderFile>
+ <PreprocessorDefinitions>TOML_ENABLE_UNRELEASED_FEATURES=1;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <PreprocessorDefinitions>LEAK_TESTS=1;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'%(ExceptionHandling)'=='false'">_HAS_EXCEPTIONS=0;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'%(ExceptionHandling)'=='false'">SHOULD_HAVE_EXCEPTIONS=0;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'%(ExceptionHandling)'!='false'">SHOULD_HAVE_EXCEPTIONS=1;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <LanguageStandard>stdcpplatest</LanguageStandard>
+ <MultiProcessorCompilation>true</MultiProcessorCompilation>
+ <WarningLevel>EnableAllWarnings</WarningLevel>
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4127</DisableSpecificWarnings> <!-- conditional expr is constant -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4324</DisableSpecificWarnings> <!-- structure was padded due to alignment specifier -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4464</DisableSpecificWarnings> <!-- relative include path contains '..' -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4505</DisableSpecificWarnings> <!-- unreferenced local function removed -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4514</DisableSpecificWarnings> <!-- unreferenced inline function has been removed -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4577</DisableSpecificWarnings> <!-- 'noexcept' used with no exception handling mode specified -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4582</DisableSpecificWarnings> <!-- constructor is not implicitly called -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4623</DisableSpecificWarnings> <!-- default constructor was implicitly defined as deleted -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4625</DisableSpecificWarnings> <!-- copy constructor was implicitly defined as deleted -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4626</DisableSpecificWarnings> <!-- assignment operator was implicitly defined as deleted -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4710</DisableSpecificWarnings> <!-- function not inlined -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4711</DisableSpecificWarnings> <!-- function selected for automatic expansion -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4738</DisableSpecificWarnings> <!-- storing 32-bit float result in memory -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4820</DisableSpecificWarnings> <!-- N bytes padding added -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4866</DisableSpecificWarnings> <!-- compiler may not enforce ltr eval in operator[] -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4868</DisableSpecificWarnings> <!-- compiler may not enforce ltr eval in initializer list -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4946</DisableSpecificWarnings> <!-- reinterpret_cast used between related classes -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);5026</DisableSpecificWarnings> <!-- move constructor was implicitly defined as deleted -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);5027</DisableSpecificWarnings> <!-- move assignment operator was implicitly defined as deleted -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);5039</DisableSpecificWarnings> <!-- potentially throwing function passed to 'extern "C"' -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);5045</DisableSpecificWarnings> <!-- Compiler will insert Spectre mitigation -->
+ </ClCompile>
+ </ItemDefinitionGroup>
+ <PropertyGroup>
+ <LocalDebuggerWorkingDirectory>$(ProjectDir)..\</LocalDebuggerWorkingDirectory>
+ </PropertyGroup>
+ <ItemGroup>
+ <ClCompile Include="..\at_path.cpp" />
+ <ClCompile Include="..\path.cpp" />
+ <ClCompile Include="..\conformance_burntsushi_invalid.cpp" />
+ <ClCompile Include="..\conformance_burntsushi_valid.cpp" />
+ <ClCompile Include="..\conformance_iarna_invalid.cpp" />
+ <ClCompile Include="..\conformance_iarna_valid.cpp" />
+ <ClCompile Include="..\for_each.cpp" />
+ <ClCompile Include="..\formatters.cpp" />
+ <ClCompile Include="..\impl_toml.cpp">
+ <PrecompiledHeader>NotUsing</PrecompiledHeader>
+ </ClCompile>
+ <ClCompile Include="..\main.cpp">
+ <PrecompiledHeader>NotUsing</PrecompiledHeader>
+ </ClCompile>
+ <ClCompile Include="..\manipulating_arrays.cpp" />
+ <ClCompile Include="..\manipulating_tables.cpp" />
+ <ClCompile Include="..\manipulating_parse_result.cpp" />
+ <ClCompile Include="..\manipulating_values.cpp" />
+ <ClCompile Include="..\parsing_arrays.cpp" />
+ <ClCompile Include="..\parsing_booleans.cpp" />
+ <ClCompile Include="..\parsing_comments.cpp" />
+ <ClCompile Include="..\parsing_dates_and_times.cpp" />
+ <ClCompile Include="..\parsing_floats.cpp" />
+ <ClCompile Include="..\parsing_integers.cpp" />
+ <ClCompile Include="..\parsing_key_value_pairs.cpp" />
+ <ClCompile Include="..\parsing_spec_example.cpp" />
+ <ClCompile Include="..\parsing_strings.cpp" />
+ <ClCompile Include="..\parsing_tables.cpp" />
+ <ClCompile Include="..\tests.cpp">
+ <PrecompiledHeader>Create</PrecompiledHeader>
+ </ClCompile>
+ <ClCompile Include="..\user_feedback.cpp" />
+ <ClCompile Include="..\using_iterators.cpp" />
+ <ClCompile Include="..\visit.cpp" />
+ <ClCompile Include="..\windows_compat.cpp" />
+ </ItemGroup>
+ <ItemGroup>
+ <Natvis Include="..\..\toml++.natvis" />
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="..\leakproof.hpp" />
+ <ClInclude Include="..\lib_catch2.hpp" />
+ <ClInclude Include="..\lib_tloptional.hpp" />
+ <ClInclude Include="..\settings.hpp" />
+ <ClInclude Include="..\tests.hpp" />
+ </ItemGroup>
+ <ItemGroup>
+ <None Include="..\cpp.hint" />
+ <None Include="..\meson.build" />
+ </ItemGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+</Project>
diff --git a/tomlplusplus/tests/vs/test_release_x64_legacy_lambda.vcxproj b/tomlplusplus/tests/vs/test_release_x64_legacy_lambda.vcxproj
new file mode 100644
index 0000000000..e860101972
--- /dev/null
+++ b/tomlplusplus/tests/vs/test_release_x64_legacy_lambda.vcxproj
@@ -0,0 +1,128 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup Label="ProjectConfigurations">
+ <ProjectConfiguration Include="Release|x64">
+ <Configuration>Release</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ </ItemGroup>
+ <PropertyGroup Label="Globals">
+ <VCProjectVersion>16.0</VCProjectVersion>
+ <ProjectGuid>{D318404F-B9AB-4CFB-AEF1-92CE23369837}</ProjectGuid>
+ <WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
+ <PreferredToolArchitecture>x64</PreferredToolArchitecture>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <UseDebugLibraries>true</UseDebugLibraries>
+ <PlatformToolset>v143</PlatformToolset>
+ <CharacterSet>MultiByte</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <UseDebugLibraries>false</UseDebugLibraries>
+ <PlatformToolset>v143</PlatformToolset>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ <CharacterSet>MultiByte</CharacterSet>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <ImportGroup Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props"
+ Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <Import Project="../../toml++.props" />
+ <ItemDefinitionGroup>
+ <ClCompile>
+ <AdditionalIncludeDirectories>..\tests;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <ExceptionHandling>Sync</ExceptionHandling>
+ <PrecompiledHeader>Use</PrecompiledHeader>
+ <PrecompiledHeaderFile>tests.hpp</PrecompiledHeaderFile>
+ <PreprocessorDefinitions>TOML_ENABLE_UNRELEASED_FEATURES=0;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <PreprocessorDefinitions>LEAK_TESTS=1;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'%(ExceptionHandling)'=='false'">_HAS_EXCEPTIONS=0;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'%(ExceptionHandling)'=='false'">SHOULD_HAVE_EXCEPTIONS=0;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'%(ExceptionHandling)'!='false'">SHOULD_HAVE_EXCEPTIONS=1;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <LanguageStandard>stdcpp17</LanguageStandard>
+ <MultiProcessorCompilation>true</MultiProcessorCompilation>
+ <WarningLevel>EnableAllWarnings</WarningLevel>
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4127</DisableSpecificWarnings> <!-- conditional expr is constant -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4324</DisableSpecificWarnings> <!-- structure was padded due to alignment specifier -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4464</DisableSpecificWarnings> <!-- relative include path contains '..' -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4505</DisableSpecificWarnings> <!-- unreferenced local function removed -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4514</DisableSpecificWarnings> <!-- unreferenced inline function has been removed -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4577</DisableSpecificWarnings> <!-- 'noexcept' used with no exception handling mode specified -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4582</DisableSpecificWarnings> <!-- constructor is not implicitly called -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4623</DisableSpecificWarnings> <!-- default constructor was implicitly defined as deleted -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4625</DisableSpecificWarnings> <!-- copy constructor was implicitly defined as deleted -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4626</DisableSpecificWarnings> <!-- assignment operator was implicitly defined as deleted -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4710</DisableSpecificWarnings> <!-- function not inlined -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4711</DisableSpecificWarnings> <!-- function selected for automatic expansion -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4738</DisableSpecificWarnings> <!-- storing 32-bit float result in memory -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4820</DisableSpecificWarnings> <!-- N bytes padding added -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4866</DisableSpecificWarnings> <!-- compiler may not enforce ltr eval in operator[] -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4868</DisableSpecificWarnings> <!-- compiler may not enforce ltr eval in initializer list -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4946</DisableSpecificWarnings> <!-- reinterpret_cast used between related classes -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);5026</DisableSpecificWarnings> <!-- move constructor was implicitly defined as deleted -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);5027</DisableSpecificWarnings> <!-- move assignment operator was implicitly defined as deleted -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);5039</DisableSpecificWarnings> <!-- potentially throwing function passed to 'extern "C"' -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);5045</DisableSpecificWarnings> <!-- Compiler will insert Spectre mitigation -->
+ <ConformanceMode>Default</ConformanceMode> <!-- Default Conformance Mode implies using the legacy lambda processor -->
+ </ClCompile>
+ </ItemDefinitionGroup>
+ <PropertyGroup>
+ <LocalDebuggerWorkingDirectory>$(ProjectDir)..\</LocalDebuggerWorkingDirectory>
+ </PropertyGroup>
+ <ItemGroup>
+ <ClCompile Include="..\at_path.cpp" />
+ <ClCompile Include="..\path.cpp" />
+ <ClCompile Include="..\conformance_burntsushi_invalid.cpp" />
+ <ClCompile Include="..\conformance_burntsushi_valid.cpp" />
+ <ClCompile Include="..\conformance_iarna_invalid.cpp" />
+ <ClCompile Include="..\conformance_iarna_valid.cpp" />
+ <ClCompile Include="..\for_each.cpp" />
+ <ClCompile Include="..\formatters.cpp" />
+ <ClCompile Include="..\impl_toml.cpp">
+ <PrecompiledHeader>NotUsing</PrecompiledHeader>
+ </ClCompile>
+ <ClCompile Include="..\main.cpp">
+ <PrecompiledHeader>NotUsing</PrecompiledHeader>
+ </ClCompile>
+ <ClCompile Include="..\manipulating_arrays.cpp" />
+ <ClCompile Include="..\manipulating_tables.cpp" />
+ <ClCompile Include="..\manipulating_parse_result.cpp" />
+ <ClCompile Include="..\manipulating_values.cpp" />
+ <ClCompile Include="..\parsing_arrays.cpp" />
+ <ClCompile Include="..\parsing_booleans.cpp" />
+ <ClCompile Include="..\parsing_comments.cpp" />
+ <ClCompile Include="..\parsing_dates_and_times.cpp" />
+ <ClCompile Include="..\parsing_floats.cpp" />
+ <ClCompile Include="..\parsing_integers.cpp" />
+ <ClCompile Include="..\parsing_key_value_pairs.cpp" />
+ <ClCompile Include="..\parsing_spec_example.cpp" />
+ <ClCompile Include="..\parsing_strings.cpp" />
+ <ClCompile Include="..\parsing_tables.cpp" />
+ <ClCompile Include="..\tests.cpp">
+ <PrecompiledHeader>Create</PrecompiledHeader>
+ </ClCompile>
+ <ClCompile Include="..\user_feedback.cpp" />
+ <ClCompile Include="..\using_iterators.cpp" />
+ <ClCompile Include="..\visit.cpp" />
+ <ClCompile Include="..\windows_compat.cpp" />
+ </ItemGroup>
+ <ItemGroup>
+ <Natvis Include="..\..\toml++.natvis" />
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="..\leakproof.hpp" />
+ <ClInclude Include="..\lib_catch2.hpp" />
+ <ClInclude Include="..\lib_tloptional.hpp" />
+ <ClInclude Include="..\settings.hpp" />
+ <ClInclude Include="..\tests.hpp" />
+ </ItemGroup>
+ <ItemGroup>
+ <None Include="..\cpp.hint" />
+ <None Include="..\meson.build" />
+ </ItemGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+</Project>
diff --git a/tomlplusplus/tests/vs/test_release_x64_noexcept.vcxproj b/tomlplusplus/tests/vs/test_release_x64_noexcept.vcxproj
new file mode 100644
index 0000000000..6247285be8
--- /dev/null
+++ b/tomlplusplus/tests/vs/test_release_x64_noexcept.vcxproj
@@ -0,0 +1,127 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup Label="ProjectConfigurations">
+ <ProjectConfiguration Include="Release|x64">
+ <Configuration>Release</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ </ItemGroup>
+ <PropertyGroup Label="Globals">
+ <VCProjectVersion>16.0</VCProjectVersion>
+ <ProjectGuid>{B1B28D93-892C-59BF-9C6F-D813EC6438A0}</ProjectGuid>
+ <WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
+ <PreferredToolArchitecture>x64</PreferredToolArchitecture>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <UseDebugLibraries>true</UseDebugLibraries>
+ <PlatformToolset>v143</PlatformToolset>
+ <CharacterSet>MultiByte</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <UseDebugLibraries>false</UseDebugLibraries>
+ <PlatformToolset>v143</PlatformToolset>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ <CharacterSet>MultiByte</CharacterSet>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <ImportGroup Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props"
+ Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <Import Project="../../toml++.props" />
+ <ItemDefinitionGroup>
+ <ClCompile>
+ <AdditionalIncludeDirectories>..\tests;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <ExceptionHandling>false</ExceptionHandling>
+ <PrecompiledHeader>Use</PrecompiledHeader>
+ <PrecompiledHeaderFile>tests.hpp</PrecompiledHeaderFile>
+ <PreprocessorDefinitions>TOML_ENABLE_UNRELEASED_FEATURES=0;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <PreprocessorDefinitions>LEAK_TESTS=1;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'%(ExceptionHandling)'=='false'">_HAS_EXCEPTIONS=0;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'%(ExceptionHandling)'=='false'">SHOULD_HAVE_EXCEPTIONS=0;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'%(ExceptionHandling)'!='false'">SHOULD_HAVE_EXCEPTIONS=1;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <LanguageStandard>stdcpp17</LanguageStandard>
+ <MultiProcessorCompilation>true</MultiProcessorCompilation>
+ <WarningLevel>EnableAllWarnings</WarningLevel>
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4127</DisableSpecificWarnings> <!-- conditional expr is constant -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4324</DisableSpecificWarnings> <!-- structure was padded due to alignment specifier -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4464</DisableSpecificWarnings> <!-- relative include path contains '..' -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4505</DisableSpecificWarnings> <!-- unreferenced local function removed -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4514</DisableSpecificWarnings> <!-- unreferenced inline function has been removed -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4577</DisableSpecificWarnings> <!-- 'noexcept' used with no exception handling mode specified -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4582</DisableSpecificWarnings> <!-- constructor is not implicitly called -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4623</DisableSpecificWarnings> <!-- default constructor was implicitly defined as deleted -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4625</DisableSpecificWarnings> <!-- copy constructor was implicitly defined as deleted -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4626</DisableSpecificWarnings> <!-- assignment operator was implicitly defined as deleted -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4710</DisableSpecificWarnings> <!-- function not inlined -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4711</DisableSpecificWarnings> <!-- function selected for automatic expansion -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4738</DisableSpecificWarnings> <!-- storing 32-bit float result in memory -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4820</DisableSpecificWarnings> <!-- N bytes padding added -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4866</DisableSpecificWarnings> <!-- compiler may not enforce ltr eval in operator[] -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4868</DisableSpecificWarnings> <!-- compiler may not enforce ltr eval in initializer list -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4946</DisableSpecificWarnings> <!-- reinterpret_cast used between related classes -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);5026</DisableSpecificWarnings> <!-- move constructor was implicitly defined as deleted -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);5027</DisableSpecificWarnings> <!-- move assignment operator was implicitly defined as deleted -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);5039</DisableSpecificWarnings> <!-- potentially throwing function passed to 'extern "C"' -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);5045</DisableSpecificWarnings> <!-- Compiler will insert Spectre mitigation -->
+ </ClCompile>
+ </ItemDefinitionGroup>
+ <PropertyGroup>
+ <LocalDebuggerWorkingDirectory>$(ProjectDir)..\</LocalDebuggerWorkingDirectory>
+ </PropertyGroup>
+ <ItemGroup>
+ <ClCompile Include="..\at_path.cpp" />
+ <ClCompile Include="..\path.cpp" />
+ <ClCompile Include="..\conformance_burntsushi_invalid.cpp" />
+ <ClCompile Include="..\conformance_burntsushi_valid.cpp" />
+ <ClCompile Include="..\conformance_iarna_invalid.cpp" />
+ <ClCompile Include="..\conformance_iarna_valid.cpp" />
+ <ClCompile Include="..\for_each.cpp" />
+ <ClCompile Include="..\formatters.cpp" />
+ <ClCompile Include="..\impl_toml.cpp">
+ <PrecompiledHeader>NotUsing</PrecompiledHeader>
+ </ClCompile>
+ <ClCompile Include="..\main.cpp">
+ <PrecompiledHeader>NotUsing</PrecompiledHeader>
+ </ClCompile>
+ <ClCompile Include="..\manipulating_arrays.cpp" />
+ <ClCompile Include="..\manipulating_tables.cpp" />
+ <ClCompile Include="..\manipulating_parse_result.cpp" />
+ <ClCompile Include="..\manipulating_values.cpp" />
+ <ClCompile Include="..\parsing_arrays.cpp" />
+ <ClCompile Include="..\parsing_booleans.cpp" />
+ <ClCompile Include="..\parsing_comments.cpp" />
+ <ClCompile Include="..\parsing_dates_and_times.cpp" />
+ <ClCompile Include="..\parsing_floats.cpp" />
+ <ClCompile Include="..\parsing_integers.cpp" />
+ <ClCompile Include="..\parsing_key_value_pairs.cpp" />
+ <ClCompile Include="..\parsing_spec_example.cpp" />
+ <ClCompile Include="..\parsing_strings.cpp" />
+ <ClCompile Include="..\parsing_tables.cpp" />
+ <ClCompile Include="..\tests.cpp">
+ <PrecompiledHeader>Create</PrecompiledHeader>
+ </ClCompile>
+ <ClCompile Include="..\user_feedback.cpp" />
+ <ClCompile Include="..\using_iterators.cpp" />
+ <ClCompile Include="..\visit.cpp" />
+ <ClCompile Include="..\windows_compat.cpp" />
+ </ItemGroup>
+ <ItemGroup>
+ <Natvis Include="..\..\toml++.natvis" />
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="..\leakproof.hpp" />
+ <ClInclude Include="..\lib_catch2.hpp" />
+ <ClInclude Include="..\lib_tloptional.hpp" />
+ <ClInclude Include="..\settings.hpp" />
+ <ClInclude Include="..\tests.hpp" />
+ </ItemGroup>
+ <ItemGroup>
+ <None Include="..\cpp.hint" />
+ <None Include="..\meson.build" />
+ </ItemGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+</Project>
diff --git a/tomlplusplus/tests/vs/test_release_x64_noexcept_unrel.vcxproj b/tomlplusplus/tests/vs/test_release_x64_noexcept_unrel.vcxproj
new file mode 100644
index 0000000000..024f112e3a
--- /dev/null
+++ b/tomlplusplus/tests/vs/test_release_x64_noexcept_unrel.vcxproj
@@ -0,0 +1,127 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup Label="ProjectConfigurations">
+ <ProjectConfiguration Include="Release|x64">
+ <Configuration>Release</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ </ItemGroup>
+ <PropertyGroup Label="Globals">
+ <VCProjectVersion>16.0</VCProjectVersion>
+ <ProjectGuid>{6C3EA8CD-33CC-5775-ACC4-631FF5FE1E2C}</ProjectGuid>
+ <WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
+ <PreferredToolArchitecture>x64</PreferredToolArchitecture>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <UseDebugLibraries>true</UseDebugLibraries>
+ <PlatformToolset>v143</PlatformToolset>
+ <CharacterSet>MultiByte</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <UseDebugLibraries>false</UseDebugLibraries>
+ <PlatformToolset>v143</PlatformToolset>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ <CharacterSet>MultiByte</CharacterSet>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <ImportGroup Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props"
+ Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <Import Project="../../toml++.props" />
+ <ItemDefinitionGroup>
+ <ClCompile>
+ <AdditionalIncludeDirectories>..\tests;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <ExceptionHandling>false</ExceptionHandling>
+ <PrecompiledHeader>Use</PrecompiledHeader>
+ <PrecompiledHeaderFile>tests.hpp</PrecompiledHeaderFile>
+ <PreprocessorDefinitions>TOML_ENABLE_UNRELEASED_FEATURES=1;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <PreprocessorDefinitions>LEAK_TESTS=1;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'%(ExceptionHandling)'=='false'">_HAS_EXCEPTIONS=0;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'%(ExceptionHandling)'=='false'">SHOULD_HAVE_EXCEPTIONS=0;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'%(ExceptionHandling)'!='false'">SHOULD_HAVE_EXCEPTIONS=1;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <LanguageStandard>stdcpp17</LanguageStandard>
+ <MultiProcessorCompilation>true</MultiProcessorCompilation>
+ <WarningLevel>EnableAllWarnings</WarningLevel>
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4127</DisableSpecificWarnings> <!-- conditional expr is constant -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4324</DisableSpecificWarnings> <!-- structure was padded due to alignment specifier -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4464</DisableSpecificWarnings> <!-- relative include path contains '..' -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4505</DisableSpecificWarnings> <!-- unreferenced local function removed -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4514</DisableSpecificWarnings> <!-- unreferenced inline function has been removed -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4577</DisableSpecificWarnings> <!-- 'noexcept' used with no exception handling mode specified -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4582</DisableSpecificWarnings> <!-- constructor is not implicitly called -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4623</DisableSpecificWarnings> <!-- default constructor was implicitly defined as deleted -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4625</DisableSpecificWarnings> <!-- copy constructor was implicitly defined as deleted -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4626</DisableSpecificWarnings> <!-- assignment operator was implicitly defined as deleted -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4710</DisableSpecificWarnings> <!-- function not inlined -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4711</DisableSpecificWarnings> <!-- function selected for automatic expansion -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4738</DisableSpecificWarnings> <!-- storing 32-bit float result in memory -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4820</DisableSpecificWarnings> <!-- N bytes padding added -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4866</DisableSpecificWarnings> <!-- compiler may not enforce ltr eval in operator[] -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4868</DisableSpecificWarnings> <!-- compiler may not enforce ltr eval in initializer list -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4946</DisableSpecificWarnings> <!-- reinterpret_cast used between related classes -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);5026</DisableSpecificWarnings> <!-- move constructor was implicitly defined as deleted -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);5027</DisableSpecificWarnings> <!-- move assignment operator was implicitly defined as deleted -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);5039</DisableSpecificWarnings> <!-- potentially throwing function passed to 'extern "C"' -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);5045</DisableSpecificWarnings> <!-- Compiler will insert Spectre mitigation -->
+ </ClCompile>
+ </ItemDefinitionGroup>
+ <PropertyGroup>
+ <LocalDebuggerWorkingDirectory>$(ProjectDir)..\</LocalDebuggerWorkingDirectory>
+ </PropertyGroup>
+ <ItemGroup>
+ <ClCompile Include="..\at_path.cpp" />
+ <ClCompile Include="..\path.cpp" />
+ <ClCompile Include="..\conformance_burntsushi_invalid.cpp" />
+ <ClCompile Include="..\conformance_burntsushi_valid.cpp" />
+ <ClCompile Include="..\conformance_iarna_invalid.cpp" />
+ <ClCompile Include="..\conformance_iarna_valid.cpp" />
+ <ClCompile Include="..\for_each.cpp" />
+ <ClCompile Include="..\formatters.cpp" />
+ <ClCompile Include="..\impl_toml.cpp">
+ <PrecompiledHeader>NotUsing</PrecompiledHeader>
+ </ClCompile>
+ <ClCompile Include="..\main.cpp">
+ <PrecompiledHeader>NotUsing</PrecompiledHeader>
+ </ClCompile>
+ <ClCompile Include="..\manipulating_arrays.cpp" />
+ <ClCompile Include="..\manipulating_tables.cpp" />
+ <ClCompile Include="..\manipulating_parse_result.cpp" />
+ <ClCompile Include="..\manipulating_values.cpp" />
+ <ClCompile Include="..\parsing_arrays.cpp" />
+ <ClCompile Include="..\parsing_booleans.cpp" />
+ <ClCompile Include="..\parsing_comments.cpp" />
+ <ClCompile Include="..\parsing_dates_and_times.cpp" />
+ <ClCompile Include="..\parsing_floats.cpp" />
+ <ClCompile Include="..\parsing_integers.cpp" />
+ <ClCompile Include="..\parsing_key_value_pairs.cpp" />
+ <ClCompile Include="..\parsing_spec_example.cpp" />
+ <ClCompile Include="..\parsing_strings.cpp" />
+ <ClCompile Include="..\parsing_tables.cpp" />
+ <ClCompile Include="..\tests.cpp">
+ <PrecompiledHeader>Create</PrecompiledHeader>
+ </ClCompile>
+ <ClCompile Include="..\user_feedback.cpp" />
+ <ClCompile Include="..\using_iterators.cpp" />
+ <ClCompile Include="..\visit.cpp" />
+ <ClCompile Include="..\windows_compat.cpp" />
+ </ItemGroup>
+ <ItemGroup>
+ <Natvis Include="..\..\toml++.natvis" />
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="..\leakproof.hpp" />
+ <ClInclude Include="..\lib_catch2.hpp" />
+ <ClInclude Include="..\lib_tloptional.hpp" />
+ <ClInclude Include="..\settings.hpp" />
+ <ClInclude Include="..\tests.hpp" />
+ </ItemGroup>
+ <ItemGroup>
+ <None Include="..\cpp.hint" />
+ <None Include="..\meson.build" />
+ </ItemGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+</Project>
diff --git a/tomlplusplus/tests/vs/test_release_x64_unrel.vcxproj b/tomlplusplus/tests/vs/test_release_x64_unrel.vcxproj
new file mode 100644
index 0000000000..629c7ed02d
--- /dev/null
+++ b/tomlplusplus/tests/vs/test_release_x64_unrel.vcxproj
@@ -0,0 +1,127 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup Label="ProjectConfigurations">
+ <ProjectConfiguration Include="Release|x64">
+ <Configuration>Release</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ </ItemGroup>
+ <PropertyGroup Label="Globals">
+ <VCProjectVersion>16.0</VCProjectVersion>
+ <ProjectGuid>{B3779AEA-40D6-5F3C-BC86-98E4E577E09D}</ProjectGuid>
+ <WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
+ <PreferredToolArchitecture>x64</PreferredToolArchitecture>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <UseDebugLibraries>true</UseDebugLibraries>
+ <PlatformToolset>v143</PlatformToolset>
+ <CharacterSet>MultiByte</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <UseDebugLibraries>false</UseDebugLibraries>
+ <PlatformToolset>v143</PlatformToolset>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ <CharacterSet>MultiByte</CharacterSet>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <ImportGroup Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props"
+ Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <Import Project="../../toml++.props" />
+ <ItemDefinitionGroup>
+ <ClCompile>
+ <AdditionalIncludeDirectories>..\tests;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <ExceptionHandling>Sync</ExceptionHandling>
+ <PrecompiledHeader>Use</PrecompiledHeader>
+ <PrecompiledHeaderFile>tests.hpp</PrecompiledHeaderFile>
+ <PreprocessorDefinitions>TOML_ENABLE_UNRELEASED_FEATURES=1;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <PreprocessorDefinitions>LEAK_TESTS=1;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'%(ExceptionHandling)'=='false'">_HAS_EXCEPTIONS=0;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'%(ExceptionHandling)'=='false'">SHOULD_HAVE_EXCEPTIONS=0;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'%(ExceptionHandling)'!='false'">SHOULD_HAVE_EXCEPTIONS=1;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <LanguageStandard>stdcpp17</LanguageStandard>
+ <MultiProcessorCompilation>true</MultiProcessorCompilation>
+ <WarningLevel>EnableAllWarnings</WarningLevel>
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4127</DisableSpecificWarnings> <!-- conditional expr is constant -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4324</DisableSpecificWarnings> <!-- structure was padded due to alignment specifier -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4464</DisableSpecificWarnings> <!-- relative include path contains '..' -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4505</DisableSpecificWarnings> <!-- unreferenced local function removed -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4514</DisableSpecificWarnings> <!-- unreferenced inline function has been removed -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4577</DisableSpecificWarnings> <!-- 'noexcept' used with no exception handling mode specified -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4582</DisableSpecificWarnings> <!-- constructor is not implicitly called -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4623</DisableSpecificWarnings> <!-- default constructor was implicitly defined as deleted -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4625</DisableSpecificWarnings> <!-- copy constructor was implicitly defined as deleted -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4626</DisableSpecificWarnings> <!-- assignment operator was implicitly defined as deleted -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4710</DisableSpecificWarnings> <!-- function not inlined -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4711</DisableSpecificWarnings> <!-- function selected for automatic expansion -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4738</DisableSpecificWarnings> <!-- storing 32-bit float result in memory -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4820</DisableSpecificWarnings> <!-- N bytes padding added -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4866</DisableSpecificWarnings> <!-- compiler may not enforce ltr eval in operator[] -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4868</DisableSpecificWarnings> <!-- compiler may not enforce ltr eval in initializer list -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4946</DisableSpecificWarnings> <!-- reinterpret_cast used between related classes -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);5026</DisableSpecificWarnings> <!-- move constructor was implicitly defined as deleted -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);5027</DisableSpecificWarnings> <!-- move assignment operator was implicitly defined as deleted -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);5039</DisableSpecificWarnings> <!-- potentially throwing function passed to 'extern "C"' -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);5045</DisableSpecificWarnings> <!-- Compiler will insert Spectre mitigation -->
+ </ClCompile>
+ </ItemDefinitionGroup>
+ <PropertyGroup>
+ <LocalDebuggerWorkingDirectory>$(ProjectDir)..\</LocalDebuggerWorkingDirectory>
+ </PropertyGroup>
+ <ItemGroup>
+ <ClCompile Include="..\at_path.cpp" />
+ <ClCompile Include="..\path.cpp" />
+ <ClCompile Include="..\conformance_burntsushi_invalid.cpp" />
+ <ClCompile Include="..\conformance_burntsushi_valid.cpp" />
+ <ClCompile Include="..\conformance_iarna_invalid.cpp" />
+ <ClCompile Include="..\conformance_iarna_valid.cpp" />
+ <ClCompile Include="..\for_each.cpp" />
+ <ClCompile Include="..\formatters.cpp" />
+ <ClCompile Include="..\impl_toml.cpp">
+ <PrecompiledHeader>NotUsing</PrecompiledHeader>
+ </ClCompile>
+ <ClCompile Include="..\main.cpp">
+ <PrecompiledHeader>NotUsing</PrecompiledHeader>
+ </ClCompile>
+ <ClCompile Include="..\manipulating_arrays.cpp" />
+ <ClCompile Include="..\manipulating_tables.cpp" />
+ <ClCompile Include="..\manipulating_parse_result.cpp" />
+ <ClCompile Include="..\manipulating_values.cpp" />
+ <ClCompile Include="..\parsing_arrays.cpp" />
+ <ClCompile Include="..\parsing_booleans.cpp" />
+ <ClCompile Include="..\parsing_comments.cpp" />
+ <ClCompile Include="..\parsing_dates_and_times.cpp" />
+ <ClCompile Include="..\parsing_floats.cpp" />
+ <ClCompile Include="..\parsing_integers.cpp" />
+ <ClCompile Include="..\parsing_key_value_pairs.cpp" />
+ <ClCompile Include="..\parsing_spec_example.cpp" />
+ <ClCompile Include="..\parsing_strings.cpp" />
+ <ClCompile Include="..\parsing_tables.cpp" />
+ <ClCompile Include="..\tests.cpp">
+ <PrecompiledHeader>Create</PrecompiledHeader>
+ </ClCompile>
+ <ClCompile Include="..\user_feedback.cpp" />
+ <ClCompile Include="..\using_iterators.cpp" />
+ <ClCompile Include="..\visit.cpp" />
+ <ClCompile Include="..\windows_compat.cpp" />
+ </ItemGroup>
+ <ItemGroup>
+ <Natvis Include="..\..\toml++.natvis" />
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="..\leakproof.hpp" />
+ <ClInclude Include="..\lib_catch2.hpp" />
+ <ClInclude Include="..\lib_tloptional.hpp" />
+ <ClInclude Include="..\settings.hpp" />
+ <ClInclude Include="..\tests.hpp" />
+ </ItemGroup>
+ <ItemGroup>
+ <None Include="..\cpp.hint" />
+ <None Include="..\meson.build" />
+ </ItemGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+</Project>
diff --git a/tomlplusplus/tests/vs/test_release_x86.vcxproj b/tomlplusplus/tests/vs/test_release_x86.vcxproj
new file mode 100644
index 0000000000..1d23707af6
--- /dev/null
+++ b/tomlplusplus/tests/vs/test_release_x86.vcxproj
@@ -0,0 +1,127 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup Label="ProjectConfigurations">
+ <ProjectConfiguration Include="Release|Win32">
+ <Configuration>Release</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ </ItemGroup>
+ <PropertyGroup Label="Globals">
+ <VCProjectVersion>16.0</VCProjectVersion>
+ <ProjectGuid>{2D7D2E84-8861-529C-9C05-A1EE1FB84084}</ProjectGuid>
+ <WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
+ <PreferredToolArchitecture>x64</PreferredToolArchitecture>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <UseDebugLibraries>true</UseDebugLibraries>
+ <PlatformToolset>v143</PlatformToolset>
+ <CharacterSet>MultiByte</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <UseDebugLibraries>false</UseDebugLibraries>
+ <PlatformToolset>v143</PlatformToolset>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ <CharacterSet>MultiByte</CharacterSet>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <ImportGroup Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props"
+ Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <Import Project="../../toml++.props" />
+ <ItemDefinitionGroup>
+ <ClCompile>
+ <AdditionalIncludeDirectories>..\tests;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <ExceptionHandling>Sync</ExceptionHandling>
+ <PrecompiledHeader>Use</PrecompiledHeader>
+ <PrecompiledHeaderFile>tests.hpp</PrecompiledHeaderFile>
+ <PreprocessorDefinitions>TOML_ENABLE_UNRELEASED_FEATURES=0;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <PreprocessorDefinitions>LEAK_TESTS=1;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'%(ExceptionHandling)'=='false'">_HAS_EXCEPTIONS=0;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'%(ExceptionHandling)'=='false'">SHOULD_HAVE_EXCEPTIONS=0;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'%(ExceptionHandling)'!='false'">SHOULD_HAVE_EXCEPTIONS=1;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <LanguageStandard>stdcpp17</LanguageStandard>
+ <MultiProcessorCompilation>true</MultiProcessorCompilation>
+ <WarningLevel>EnableAllWarnings</WarningLevel>
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4127</DisableSpecificWarnings> <!-- conditional expr is constant -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4324</DisableSpecificWarnings> <!-- structure was padded due to alignment specifier -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4464</DisableSpecificWarnings> <!-- relative include path contains '..' -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4505</DisableSpecificWarnings> <!-- unreferenced local function removed -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4514</DisableSpecificWarnings> <!-- unreferenced inline function has been removed -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4577</DisableSpecificWarnings> <!-- 'noexcept' used with no exception handling mode specified -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4582</DisableSpecificWarnings> <!-- constructor is not implicitly called -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4623</DisableSpecificWarnings> <!-- default constructor was implicitly defined as deleted -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4625</DisableSpecificWarnings> <!-- copy constructor was implicitly defined as deleted -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4626</DisableSpecificWarnings> <!-- assignment operator was implicitly defined as deleted -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4710</DisableSpecificWarnings> <!-- function not inlined -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4711</DisableSpecificWarnings> <!-- function selected for automatic expansion -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4738</DisableSpecificWarnings> <!-- storing 32-bit float result in memory -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4820</DisableSpecificWarnings> <!-- N bytes padding added -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4866</DisableSpecificWarnings> <!-- compiler may not enforce ltr eval in operator[] -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4868</DisableSpecificWarnings> <!-- compiler may not enforce ltr eval in initializer list -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4946</DisableSpecificWarnings> <!-- reinterpret_cast used between related classes -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);5026</DisableSpecificWarnings> <!-- move constructor was implicitly defined as deleted -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);5027</DisableSpecificWarnings> <!-- move assignment operator was implicitly defined as deleted -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);5039</DisableSpecificWarnings> <!-- potentially throwing function passed to 'extern "C"' -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);5045</DisableSpecificWarnings> <!-- Compiler will insert Spectre mitigation -->
+ </ClCompile>
+ </ItemDefinitionGroup>
+ <PropertyGroup>
+ <LocalDebuggerWorkingDirectory>$(ProjectDir)..\</LocalDebuggerWorkingDirectory>
+ </PropertyGroup>
+ <ItemGroup>
+ <ClCompile Include="..\at_path.cpp" />
+ <ClCompile Include="..\path.cpp" />
+ <ClCompile Include="..\conformance_burntsushi_invalid.cpp" />
+ <ClCompile Include="..\conformance_burntsushi_valid.cpp" />
+ <ClCompile Include="..\conformance_iarna_invalid.cpp" />
+ <ClCompile Include="..\conformance_iarna_valid.cpp" />
+ <ClCompile Include="..\for_each.cpp" />
+ <ClCompile Include="..\formatters.cpp" />
+ <ClCompile Include="..\impl_toml.cpp">
+ <PrecompiledHeader>NotUsing</PrecompiledHeader>
+ </ClCompile>
+ <ClCompile Include="..\main.cpp">
+ <PrecompiledHeader>NotUsing</PrecompiledHeader>
+ </ClCompile>
+ <ClCompile Include="..\manipulating_arrays.cpp" />
+ <ClCompile Include="..\manipulating_tables.cpp" />
+ <ClCompile Include="..\manipulating_parse_result.cpp" />
+ <ClCompile Include="..\manipulating_values.cpp" />
+ <ClCompile Include="..\parsing_arrays.cpp" />
+ <ClCompile Include="..\parsing_booleans.cpp" />
+ <ClCompile Include="..\parsing_comments.cpp" />
+ <ClCompile Include="..\parsing_dates_and_times.cpp" />
+ <ClCompile Include="..\parsing_floats.cpp" />
+ <ClCompile Include="..\parsing_integers.cpp" />
+ <ClCompile Include="..\parsing_key_value_pairs.cpp" />
+ <ClCompile Include="..\parsing_spec_example.cpp" />
+ <ClCompile Include="..\parsing_strings.cpp" />
+ <ClCompile Include="..\parsing_tables.cpp" />
+ <ClCompile Include="..\tests.cpp">
+ <PrecompiledHeader>Create</PrecompiledHeader>
+ </ClCompile>
+ <ClCompile Include="..\user_feedback.cpp" />
+ <ClCompile Include="..\using_iterators.cpp" />
+ <ClCompile Include="..\visit.cpp" />
+ <ClCompile Include="..\windows_compat.cpp" />
+ </ItemGroup>
+ <ItemGroup>
+ <Natvis Include="..\..\toml++.natvis" />
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="..\leakproof.hpp" />
+ <ClInclude Include="..\lib_catch2.hpp" />
+ <ClInclude Include="..\lib_tloptional.hpp" />
+ <ClInclude Include="..\settings.hpp" />
+ <ClInclude Include="..\tests.hpp" />
+ </ItemGroup>
+ <ItemGroup>
+ <None Include="..\cpp.hint" />
+ <None Include="..\meson.build" />
+ </ItemGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+</Project>
diff --git a/tomlplusplus/tests/vs/test_release_x86_cpplatest.vcxproj b/tomlplusplus/tests/vs/test_release_x86_cpplatest.vcxproj
new file mode 100644
index 0000000000..8790e2d663
--- /dev/null
+++ b/tomlplusplus/tests/vs/test_release_x86_cpplatest.vcxproj
@@ -0,0 +1,127 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup Label="ProjectConfigurations">
+ <ProjectConfiguration Include="Release|Win32">
+ <Configuration>Release</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ </ItemGroup>
+ <PropertyGroup Label="Globals">
+ <VCProjectVersion>16.0</VCProjectVersion>
+ <ProjectGuid>{B98D8D10-4B7B-5AA8-84B5-87FE6AA80C10}</ProjectGuid>
+ <WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
+ <PreferredToolArchitecture>x64</PreferredToolArchitecture>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <UseDebugLibraries>true</UseDebugLibraries>
+ <PlatformToolset>v143</PlatformToolset>
+ <CharacterSet>MultiByte</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <UseDebugLibraries>false</UseDebugLibraries>
+ <PlatformToolset>v143</PlatformToolset>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ <CharacterSet>MultiByte</CharacterSet>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <ImportGroup Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props"
+ Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <Import Project="../../toml++.props" />
+ <ItemDefinitionGroup>
+ <ClCompile>
+ <AdditionalIncludeDirectories>..\tests;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <ExceptionHandling>Sync</ExceptionHandling>
+ <PrecompiledHeader>Use</PrecompiledHeader>
+ <PrecompiledHeaderFile>tests.hpp</PrecompiledHeaderFile>
+ <PreprocessorDefinitions>TOML_ENABLE_UNRELEASED_FEATURES=0;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <PreprocessorDefinitions>LEAK_TESTS=1;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'%(ExceptionHandling)'=='false'">_HAS_EXCEPTIONS=0;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'%(ExceptionHandling)'=='false'">SHOULD_HAVE_EXCEPTIONS=0;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'%(ExceptionHandling)'!='false'">SHOULD_HAVE_EXCEPTIONS=1;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <LanguageStandard>stdcpplatest</LanguageStandard>
+ <MultiProcessorCompilation>true</MultiProcessorCompilation>
+ <WarningLevel>EnableAllWarnings</WarningLevel>
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4127</DisableSpecificWarnings> <!-- conditional expr is constant -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4324</DisableSpecificWarnings> <!-- structure was padded due to alignment specifier -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4464</DisableSpecificWarnings> <!-- relative include path contains '..' -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4505</DisableSpecificWarnings> <!-- unreferenced local function removed -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4514</DisableSpecificWarnings> <!-- unreferenced inline function has been removed -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4577</DisableSpecificWarnings> <!-- 'noexcept' used with no exception handling mode specified -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4582</DisableSpecificWarnings> <!-- constructor is not implicitly called -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4623</DisableSpecificWarnings> <!-- default constructor was implicitly defined as deleted -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4625</DisableSpecificWarnings> <!-- copy constructor was implicitly defined as deleted -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4626</DisableSpecificWarnings> <!-- assignment operator was implicitly defined as deleted -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4710</DisableSpecificWarnings> <!-- function not inlined -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4711</DisableSpecificWarnings> <!-- function selected for automatic expansion -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4738</DisableSpecificWarnings> <!-- storing 32-bit float result in memory -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4820</DisableSpecificWarnings> <!-- N bytes padding added -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4866</DisableSpecificWarnings> <!-- compiler may not enforce ltr eval in operator[] -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4868</DisableSpecificWarnings> <!-- compiler may not enforce ltr eval in initializer list -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4946</DisableSpecificWarnings> <!-- reinterpret_cast used between related classes -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);5026</DisableSpecificWarnings> <!-- move constructor was implicitly defined as deleted -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);5027</DisableSpecificWarnings> <!-- move assignment operator was implicitly defined as deleted -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);5039</DisableSpecificWarnings> <!-- potentially throwing function passed to 'extern "C"' -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);5045</DisableSpecificWarnings> <!-- Compiler will insert Spectre mitigation -->
+ </ClCompile>
+ </ItemDefinitionGroup>
+ <PropertyGroup>
+ <LocalDebuggerWorkingDirectory>$(ProjectDir)..\</LocalDebuggerWorkingDirectory>
+ </PropertyGroup>
+ <ItemGroup>
+ <ClCompile Include="..\at_path.cpp" />
+ <ClCompile Include="..\path.cpp" />
+ <ClCompile Include="..\conformance_burntsushi_invalid.cpp" />
+ <ClCompile Include="..\conformance_burntsushi_valid.cpp" />
+ <ClCompile Include="..\conformance_iarna_invalid.cpp" />
+ <ClCompile Include="..\conformance_iarna_valid.cpp" />
+ <ClCompile Include="..\for_each.cpp" />
+ <ClCompile Include="..\formatters.cpp" />
+ <ClCompile Include="..\impl_toml.cpp">
+ <PrecompiledHeader>NotUsing</PrecompiledHeader>
+ </ClCompile>
+ <ClCompile Include="..\main.cpp">
+ <PrecompiledHeader>NotUsing</PrecompiledHeader>
+ </ClCompile>
+ <ClCompile Include="..\manipulating_arrays.cpp" />
+ <ClCompile Include="..\manipulating_tables.cpp" />
+ <ClCompile Include="..\manipulating_parse_result.cpp" />
+ <ClCompile Include="..\manipulating_values.cpp" />
+ <ClCompile Include="..\parsing_arrays.cpp" />
+ <ClCompile Include="..\parsing_booleans.cpp" />
+ <ClCompile Include="..\parsing_comments.cpp" />
+ <ClCompile Include="..\parsing_dates_and_times.cpp" />
+ <ClCompile Include="..\parsing_floats.cpp" />
+ <ClCompile Include="..\parsing_integers.cpp" />
+ <ClCompile Include="..\parsing_key_value_pairs.cpp" />
+ <ClCompile Include="..\parsing_spec_example.cpp" />
+ <ClCompile Include="..\parsing_strings.cpp" />
+ <ClCompile Include="..\parsing_tables.cpp" />
+ <ClCompile Include="..\tests.cpp">
+ <PrecompiledHeader>Create</PrecompiledHeader>
+ </ClCompile>
+ <ClCompile Include="..\user_feedback.cpp" />
+ <ClCompile Include="..\using_iterators.cpp" />
+ <ClCompile Include="..\visit.cpp" />
+ <ClCompile Include="..\windows_compat.cpp" />
+ </ItemGroup>
+ <ItemGroup>
+ <Natvis Include="..\..\toml++.natvis" />
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="..\leakproof.hpp" />
+ <ClInclude Include="..\lib_catch2.hpp" />
+ <ClInclude Include="..\lib_tloptional.hpp" />
+ <ClInclude Include="..\settings.hpp" />
+ <ClInclude Include="..\tests.hpp" />
+ </ItemGroup>
+ <ItemGroup>
+ <None Include="..\cpp.hint" />
+ <None Include="..\meson.build" />
+ </ItemGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+</Project>
diff --git a/tomlplusplus/tests/vs/test_release_x86_cpplatest_noexcept.vcxproj b/tomlplusplus/tests/vs/test_release_x86_cpplatest_noexcept.vcxproj
new file mode 100644
index 0000000000..b001d2f50f
--- /dev/null
+++ b/tomlplusplus/tests/vs/test_release_x86_cpplatest_noexcept.vcxproj
@@ -0,0 +1,127 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup Label="ProjectConfigurations">
+ <ProjectConfiguration Include="Release|Win32">
+ <Configuration>Release</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ </ItemGroup>
+ <PropertyGroup Label="Globals">
+ <VCProjectVersion>16.0</VCProjectVersion>
+ <ProjectGuid>{C9D50E23-65F2-5C1E-BE44-7327A9FFC637}</ProjectGuid>
+ <WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
+ <PreferredToolArchitecture>x64</PreferredToolArchitecture>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <UseDebugLibraries>true</UseDebugLibraries>
+ <PlatformToolset>v143</PlatformToolset>
+ <CharacterSet>MultiByte</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <UseDebugLibraries>false</UseDebugLibraries>
+ <PlatformToolset>v143</PlatformToolset>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ <CharacterSet>MultiByte</CharacterSet>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <ImportGroup Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props"
+ Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <Import Project="../../toml++.props" />
+ <ItemDefinitionGroup>
+ <ClCompile>
+ <AdditionalIncludeDirectories>..\tests;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <ExceptionHandling>false</ExceptionHandling>
+ <PrecompiledHeader>Use</PrecompiledHeader>
+ <PrecompiledHeaderFile>tests.hpp</PrecompiledHeaderFile>
+ <PreprocessorDefinitions>TOML_ENABLE_UNRELEASED_FEATURES=0;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <PreprocessorDefinitions>LEAK_TESTS=1;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'%(ExceptionHandling)'=='false'">_HAS_EXCEPTIONS=0;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'%(ExceptionHandling)'=='false'">SHOULD_HAVE_EXCEPTIONS=0;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'%(ExceptionHandling)'!='false'">SHOULD_HAVE_EXCEPTIONS=1;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <LanguageStandard>stdcpplatest</LanguageStandard>
+ <MultiProcessorCompilation>true</MultiProcessorCompilation>
+ <WarningLevel>EnableAllWarnings</WarningLevel>
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4127</DisableSpecificWarnings> <!-- conditional expr is constant -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4324</DisableSpecificWarnings> <!-- structure was padded due to alignment specifier -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4464</DisableSpecificWarnings> <!-- relative include path contains '..' -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4505</DisableSpecificWarnings> <!-- unreferenced local function removed -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4514</DisableSpecificWarnings> <!-- unreferenced inline function has been removed -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4577</DisableSpecificWarnings> <!-- 'noexcept' used with no exception handling mode specified -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4582</DisableSpecificWarnings> <!-- constructor is not implicitly called -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4623</DisableSpecificWarnings> <!-- default constructor was implicitly defined as deleted -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4625</DisableSpecificWarnings> <!-- copy constructor was implicitly defined as deleted -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4626</DisableSpecificWarnings> <!-- assignment operator was implicitly defined as deleted -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4710</DisableSpecificWarnings> <!-- function not inlined -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4711</DisableSpecificWarnings> <!-- function selected for automatic expansion -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4738</DisableSpecificWarnings> <!-- storing 32-bit float result in memory -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4820</DisableSpecificWarnings> <!-- N bytes padding added -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4866</DisableSpecificWarnings> <!-- compiler may not enforce ltr eval in operator[] -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4868</DisableSpecificWarnings> <!-- compiler may not enforce ltr eval in initializer list -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4946</DisableSpecificWarnings> <!-- reinterpret_cast used between related classes -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);5026</DisableSpecificWarnings> <!-- move constructor was implicitly defined as deleted -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);5027</DisableSpecificWarnings> <!-- move assignment operator was implicitly defined as deleted -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);5039</DisableSpecificWarnings> <!-- potentially throwing function passed to 'extern "C"' -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);5045</DisableSpecificWarnings> <!-- Compiler will insert Spectre mitigation -->
+ </ClCompile>
+ </ItemDefinitionGroup>
+ <PropertyGroup>
+ <LocalDebuggerWorkingDirectory>$(ProjectDir)..\</LocalDebuggerWorkingDirectory>
+ </PropertyGroup>
+ <ItemGroup>
+ <ClCompile Include="..\at_path.cpp" />
+ <ClCompile Include="..\path.cpp" />
+ <ClCompile Include="..\conformance_burntsushi_invalid.cpp" />
+ <ClCompile Include="..\conformance_burntsushi_valid.cpp" />
+ <ClCompile Include="..\conformance_iarna_invalid.cpp" />
+ <ClCompile Include="..\conformance_iarna_valid.cpp" />
+ <ClCompile Include="..\for_each.cpp" />
+ <ClCompile Include="..\formatters.cpp" />
+ <ClCompile Include="..\impl_toml.cpp">
+ <PrecompiledHeader>NotUsing</PrecompiledHeader>
+ </ClCompile>
+ <ClCompile Include="..\main.cpp">
+ <PrecompiledHeader>NotUsing</PrecompiledHeader>
+ </ClCompile>
+ <ClCompile Include="..\manipulating_arrays.cpp" />
+ <ClCompile Include="..\manipulating_tables.cpp" />
+ <ClCompile Include="..\manipulating_parse_result.cpp" />
+ <ClCompile Include="..\manipulating_values.cpp" />
+ <ClCompile Include="..\parsing_arrays.cpp" />
+ <ClCompile Include="..\parsing_booleans.cpp" />
+ <ClCompile Include="..\parsing_comments.cpp" />
+ <ClCompile Include="..\parsing_dates_and_times.cpp" />
+ <ClCompile Include="..\parsing_floats.cpp" />
+ <ClCompile Include="..\parsing_integers.cpp" />
+ <ClCompile Include="..\parsing_key_value_pairs.cpp" />
+ <ClCompile Include="..\parsing_spec_example.cpp" />
+ <ClCompile Include="..\parsing_strings.cpp" />
+ <ClCompile Include="..\parsing_tables.cpp" />
+ <ClCompile Include="..\tests.cpp">
+ <PrecompiledHeader>Create</PrecompiledHeader>
+ </ClCompile>
+ <ClCompile Include="..\user_feedback.cpp" />
+ <ClCompile Include="..\using_iterators.cpp" />
+ <ClCompile Include="..\visit.cpp" />
+ <ClCompile Include="..\windows_compat.cpp" />
+ </ItemGroup>
+ <ItemGroup>
+ <Natvis Include="..\..\toml++.natvis" />
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="..\leakproof.hpp" />
+ <ClInclude Include="..\lib_catch2.hpp" />
+ <ClInclude Include="..\lib_tloptional.hpp" />
+ <ClInclude Include="..\settings.hpp" />
+ <ClInclude Include="..\tests.hpp" />
+ </ItemGroup>
+ <ItemGroup>
+ <None Include="..\cpp.hint" />
+ <None Include="..\meson.build" />
+ </ItemGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+</Project>
diff --git a/tomlplusplus/tests/vs/test_release_x86_cpplatest_noexcept_unrel.vcxproj b/tomlplusplus/tests/vs/test_release_x86_cpplatest_noexcept_unrel.vcxproj
new file mode 100644
index 0000000000..93dfac1cd2
--- /dev/null
+++ b/tomlplusplus/tests/vs/test_release_x86_cpplatest_noexcept_unrel.vcxproj
@@ -0,0 +1,127 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup Label="ProjectConfigurations">
+ <ProjectConfiguration Include="Release|Win32">
+ <Configuration>Release</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ </ItemGroup>
+ <PropertyGroup Label="Globals">
+ <VCProjectVersion>16.0</VCProjectVersion>
+ <ProjectGuid>{082D6FBD-F01E-504B-9905-25937CCE7F9A}</ProjectGuid>
+ <WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
+ <PreferredToolArchitecture>x64</PreferredToolArchitecture>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <UseDebugLibraries>true</UseDebugLibraries>
+ <PlatformToolset>v143</PlatformToolset>
+ <CharacterSet>MultiByte</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <UseDebugLibraries>false</UseDebugLibraries>
+ <PlatformToolset>v143</PlatformToolset>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ <CharacterSet>MultiByte</CharacterSet>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <ImportGroup Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props"
+ Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <Import Project="../../toml++.props" />
+ <ItemDefinitionGroup>
+ <ClCompile>
+ <AdditionalIncludeDirectories>..\tests;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <ExceptionHandling>false</ExceptionHandling>
+ <PrecompiledHeader>Use</PrecompiledHeader>
+ <PrecompiledHeaderFile>tests.hpp</PrecompiledHeaderFile>
+ <PreprocessorDefinitions>TOML_ENABLE_UNRELEASED_FEATURES=1;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <PreprocessorDefinitions>LEAK_TESTS=1;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'%(ExceptionHandling)'=='false'">_HAS_EXCEPTIONS=0;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'%(ExceptionHandling)'=='false'">SHOULD_HAVE_EXCEPTIONS=0;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'%(ExceptionHandling)'!='false'">SHOULD_HAVE_EXCEPTIONS=1;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <LanguageStandard>stdcpplatest</LanguageStandard>
+ <MultiProcessorCompilation>true</MultiProcessorCompilation>
+ <WarningLevel>EnableAllWarnings</WarningLevel>
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4127</DisableSpecificWarnings> <!-- conditional expr is constant -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4324</DisableSpecificWarnings> <!-- structure was padded due to alignment specifier -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4464</DisableSpecificWarnings> <!-- relative include path contains '..' -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4505</DisableSpecificWarnings> <!-- unreferenced local function removed -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4514</DisableSpecificWarnings> <!-- unreferenced inline function has been removed -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4577</DisableSpecificWarnings> <!-- 'noexcept' used with no exception handling mode specified -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4582</DisableSpecificWarnings> <!-- constructor is not implicitly called -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4623</DisableSpecificWarnings> <!-- default constructor was implicitly defined as deleted -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4625</DisableSpecificWarnings> <!-- copy constructor was implicitly defined as deleted -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4626</DisableSpecificWarnings> <!-- assignment operator was implicitly defined as deleted -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4710</DisableSpecificWarnings> <!-- function not inlined -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4711</DisableSpecificWarnings> <!-- function selected for automatic expansion -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4738</DisableSpecificWarnings> <!-- storing 32-bit float result in memory -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4820</DisableSpecificWarnings> <!-- N bytes padding added -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4866</DisableSpecificWarnings> <!-- compiler may not enforce ltr eval in operator[] -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4868</DisableSpecificWarnings> <!-- compiler may not enforce ltr eval in initializer list -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4946</DisableSpecificWarnings> <!-- reinterpret_cast used between related classes -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);5026</DisableSpecificWarnings> <!-- move constructor was implicitly defined as deleted -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);5027</DisableSpecificWarnings> <!-- move assignment operator was implicitly defined as deleted -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);5039</DisableSpecificWarnings> <!-- potentially throwing function passed to 'extern "C"' -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);5045</DisableSpecificWarnings> <!-- Compiler will insert Spectre mitigation -->
+ </ClCompile>
+ </ItemDefinitionGroup>
+ <PropertyGroup>
+ <LocalDebuggerWorkingDirectory>$(ProjectDir)..\</LocalDebuggerWorkingDirectory>
+ </PropertyGroup>
+ <ItemGroup>
+ <ClCompile Include="..\at_path.cpp" />
+ <ClCompile Include="..\path.cpp" />
+ <ClCompile Include="..\conformance_burntsushi_invalid.cpp" />
+ <ClCompile Include="..\conformance_burntsushi_valid.cpp" />
+ <ClCompile Include="..\conformance_iarna_invalid.cpp" />
+ <ClCompile Include="..\conformance_iarna_valid.cpp" />
+ <ClCompile Include="..\for_each.cpp" />
+ <ClCompile Include="..\formatters.cpp" />
+ <ClCompile Include="..\impl_toml.cpp">
+ <PrecompiledHeader>NotUsing</PrecompiledHeader>
+ </ClCompile>
+ <ClCompile Include="..\main.cpp">
+ <PrecompiledHeader>NotUsing</PrecompiledHeader>
+ </ClCompile>
+ <ClCompile Include="..\manipulating_arrays.cpp" />
+ <ClCompile Include="..\manipulating_tables.cpp" />
+ <ClCompile Include="..\manipulating_parse_result.cpp" />
+ <ClCompile Include="..\manipulating_values.cpp" />
+ <ClCompile Include="..\parsing_arrays.cpp" />
+ <ClCompile Include="..\parsing_booleans.cpp" />
+ <ClCompile Include="..\parsing_comments.cpp" />
+ <ClCompile Include="..\parsing_dates_and_times.cpp" />
+ <ClCompile Include="..\parsing_floats.cpp" />
+ <ClCompile Include="..\parsing_integers.cpp" />
+ <ClCompile Include="..\parsing_key_value_pairs.cpp" />
+ <ClCompile Include="..\parsing_spec_example.cpp" />
+ <ClCompile Include="..\parsing_strings.cpp" />
+ <ClCompile Include="..\parsing_tables.cpp" />
+ <ClCompile Include="..\tests.cpp">
+ <PrecompiledHeader>Create</PrecompiledHeader>
+ </ClCompile>
+ <ClCompile Include="..\user_feedback.cpp" />
+ <ClCompile Include="..\using_iterators.cpp" />
+ <ClCompile Include="..\visit.cpp" />
+ <ClCompile Include="..\windows_compat.cpp" />
+ </ItemGroup>
+ <ItemGroup>
+ <Natvis Include="..\..\toml++.natvis" />
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="..\leakproof.hpp" />
+ <ClInclude Include="..\lib_catch2.hpp" />
+ <ClInclude Include="..\lib_tloptional.hpp" />
+ <ClInclude Include="..\settings.hpp" />
+ <ClInclude Include="..\tests.hpp" />
+ </ItemGroup>
+ <ItemGroup>
+ <None Include="..\cpp.hint" />
+ <None Include="..\meson.build" />
+ </ItemGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+</Project>
diff --git a/tomlplusplus/tests/vs/test_release_x86_cpplatest_unrel.vcxproj b/tomlplusplus/tests/vs/test_release_x86_cpplatest_unrel.vcxproj
new file mode 100644
index 0000000000..fb18b9f789
--- /dev/null
+++ b/tomlplusplus/tests/vs/test_release_x86_cpplatest_unrel.vcxproj
@@ -0,0 +1,127 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup Label="ProjectConfigurations">
+ <ProjectConfiguration Include="Release|Win32">
+ <Configuration>Release</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ </ItemGroup>
+ <PropertyGroup Label="Globals">
+ <VCProjectVersion>16.0</VCProjectVersion>
+ <ProjectGuid>{AD2F4862-1DC2-550B-AFEF-FF3D4D477323}</ProjectGuid>
+ <WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
+ <PreferredToolArchitecture>x64</PreferredToolArchitecture>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <UseDebugLibraries>true</UseDebugLibraries>
+ <PlatformToolset>v143</PlatformToolset>
+ <CharacterSet>MultiByte</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <UseDebugLibraries>false</UseDebugLibraries>
+ <PlatformToolset>v143</PlatformToolset>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ <CharacterSet>MultiByte</CharacterSet>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <ImportGroup Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props"
+ Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <Import Project="../../toml++.props" />
+ <ItemDefinitionGroup>
+ <ClCompile>
+ <AdditionalIncludeDirectories>..\tests;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <ExceptionHandling>Sync</ExceptionHandling>
+ <PrecompiledHeader>Use</PrecompiledHeader>
+ <PrecompiledHeaderFile>tests.hpp</PrecompiledHeaderFile>
+ <PreprocessorDefinitions>TOML_ENABLE_UNRELEASED_FEATURES=1;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <PreprocessorDefinitions>LEAK_TESTS=1;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'%(ExceptionHandling)'=='false'">_HAS_EXCEPTIONS=0;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'%(ExceptionHandling)'=='false'">SHOULD_HAVE_EXCEPTIONS=0;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'%(ExceptionHandling)'!='false'">SHOULD_HAVE_EXCEPTIONS=1;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <LanguageStandard>stdcpplatest</LanguageStandard>
+ <MultiProcessorCompilation>true</MultiProcessorCompilation>
+ <WarningLevel>EnableAllWarnings</WarningLevel>
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4127</DisableSpecificWarnings> <!-- conditional expr is constant -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4324</DisableSpecificWarnings> <!-- structure was padded due to alignment specifier -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4464</DisableSpecificWarnings> <!-- relative include path contains '..' -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4505</DisableSpecificWarnings> <!-- unreferenced local function removed -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4514</DisableSpecificWarnings> <!-- unreferenced inline function has been removed -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4577</DisableSpecificWarnings> <!-- 'noexcept' used with no exception handling mode specified -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4582</DisableSpecificWarnings> <!-- constructor is not implicitly called -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4623</DisableSpecificWarnings> <!-- default constructor was implicitly defined as deleted -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4625</DisableSpecificWarnings> <!-- copy constructor was implicitly defined as deleted -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4626</DisableSpecificWarnings> <!-- assignment operator was implicitly defined as deleted -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4710</DisableSpecificWarnings> <!-- function not inlined -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4711</DisableSpecificWarnings> <!-- function selected for automatic expansion -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4738</DisableSpecificWarnings> <!-- storing 32-bit float result in memory -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4820</DisableSpecificWarnings> <!-- N bytes padding added -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4866</DisableSpecificWarnings> <!-- compiler may not enforce ltr eval in operator[] -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4868</DisableSpecificWarnings> <!-- compiler may not enforce ltr eval in initializer list -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4946</DisableSpecificWarnings> <!-- reinterpret_cast used between related classes -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);5026</DisableSpecificWarnings> <!-- move constructor was implicitly defined as deleted -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);5027</DisableSpecificWarnings> <!-- move assignment operator was implicitly defined as deleted -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);5039</DisableSpecificWarnings> <!-- potentially throwing function passed to 'extern "C"' -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);5045</DisableSpecificWarnings> <!-- Compiler will insert Spectre mitigation -->
+ </ClCompile>
+ </ItemDefinitionGroup>
+ <PropertyGroup>
+ <LocalDebuggerWorkingDirectory>$(ProjectDir)..\</LocalDebuggerWorkingDirectory>
+ </PropertyGroup>
+ <ItemGroup>
+ <ClCompile Include="..\at_path.cpp" />
+ <ClCompile Include="..\path.cpp" />
+ <ClCompile Include="..\conformance_burntsushi_invalid.cpp" />
+ <ClCompile Include="..\conformance_burntsushi_valid.cpp" />
+ <ClCompile Include="..\conformance_iarna_invalid.cpp" />
+ <ClCompile Include="..\conformance_iarna_valid.cpp" />
+ <ClCompile Include="..\for_each.cpp" />
+ <ClCompile Include="..\formatters.cpp" />
+ <ClCompile Include="..\impl_toml.cpp">
+ <PrecompiledHeader>NotUsing</PrecompiledHeader>
+ </ClCompile>
+ <ClCompile Include="..\main.cpp">
+ <PrecompiledHeader>NotUsing</PrecompiledHeader>
+ </ClCompile>
+ <ClCompile Include="..\manipulating_arrays.cpp" />
+ <ClCompile Include="..\manipulating_tables.cpp" />
+ <ClCompile Include="..\manipulating_parse_result.cpp" />
+ <ClCompile Include="..\manipulating_values.cpp" />
+ <ClCompile Include="..\parsing_arrays.cpp" />
+ <ClCompile Include="..\parsing_booleans.cpp" />
+ <ClCompile Include="..\parsing_comments.cpp" />
+ <ClCompile Include="..\parsing_dates_and_times.cpp" />
+ <ClCompile Include="..\parsing_floats.cpp" />
+ <ClCompile Include="..\parsing_integers.cpp" />
+ <ClCompile Include="..\parsing_key_value_pairs.cpp" />
+ <ClCompile Include="..\parsing_spec_example.cpp" />
+ <ClCompile Include="..\parsing_strings.cpp" />
+ <ClCompile Include="..\parsing_tables.cpp" />
+ <ClCompile Include="..\tests.cpp">
+ <PrecompiledHeader>Create</PrecompiledHeader>
+ </ClCompile>
+ <ClCompile Include="..\user_feedback.cpp" />
+ <ClCompile Include="..\using_iterators.cpp" />
+ <ClCompile Include="..\visit.cpp" />
+ <ClCompile Include="..\windows_compat.cpp" />
+ </ItemGroup>
+ <ItemGroup>
+ <Natvis Include="..\..\toml++.natvis" />
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="..\leakproof.hpp" />
+ <ClInclude Include="..\lib_catch2.hpp" />
+ <ClInclude Include="..\lib_tloptional.hpp" />
+ <ClInclude Include="..\settings.hpp" />
+ <ClInclude Include="..\tests.hpp" />
+ </ItemGroup>
+ <ItemGroup>
+ <None Include="..\cpp.hint" />
+ <None Include="..\meson.build" />
+ </ItemGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+</Project>
diff --git a/tomlplusplus/tests/vs/test_release_x86_noexcept.vcxproj b/tomlplusplus/tests/vs/test_release_x86_noexcept.vcxproj
new file mode 100644
index 0000000000..291c77fd1b
--- /dev/null
+++ b/tomlplusplus/tests/vs/test_release_x86_noexcept.vcxproj
@@ -0,0 +1,127 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup Label="ProjectConfigurations">
+ <ProjectConfiguration Include="Release|Win32">
+ <Configuration>Release</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ </ItemGroup>
+ <PropertyGroup Label="Globals">
+ <VCProjectVersion>16.0</VCProjectVersion>
+ <ProjectGuid>{0D4D9D25-3F93-5C37-866E-F8B0AC23F851}</ProjectGuid>
+ <WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
+ <PreferredToolArchitecture>x64</PreferredToolArchitecture>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <UseDebugLibraries>true</UseDebugLibraries>
+ <PlatformToolset>v143</PlatformToolset>
+ <CharacterSet>MultiByte</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <UseDebugLibraries>false</UseDebugLibraries>
+ <PlatformToolset>v143</PlatformToolset>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ <CharacterSet>MultiByte</CharacterSet>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <ImportGroup Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props"
+ Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <Import Project="../../toml++.props" />
+ <ItemDefinitionGroup>
+ <ClCompile>
+ <AdditionalIncludeDirectories>..\tests;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <ExceptionHandling>false</ExceptionHandling>
+ <PrecompiledHeader>Use</PrecompiledHeader>
+ <PrecompiledHeaderFile>tests.hpp</PrecompiledHeaderFile>
+ <PreprocessorDefinitions>TOML_ENABLE_UNRELEASED_FEATURES=0;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <PreprocessorDefinitions>LEAK_TESTS=1;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'%(ExceptionHandling)'=='false'">_HAS_EXCEPTIONS=0;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'%(ExceptionHandling)'=='false'">SHOULD_HAVE_EXCEPTIONS=0;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'%(ExceptionHandling)'!='false'">SHOULD_HAVE_EXCEPTIONS=1;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <LanguageStandard>stdcpp17</LanguageStandard>
+ <MultiProcessorCompilation>true</MultiProcessorCompilation>
+ <WarningLevel>EnableAllWarnings</WarningLevel>
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4127</DisableSpecificWarnings> <!-- conditional expr is constant -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4324</DisableSpecificWarnings> <!-- structure was padded due to alignment specifier -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4464</DisableSpecificWarnings> <!-- relative include path contains '..' -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4505</DisableSpecificWarnings> <!-- unreferenced local function removed -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4514</DisableSpecificWarnings> <!-- unreferenced inline function has been removed -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4577</DisableSpecificWarnings> <!-- 'noexcept' used with no exception handling mode specified -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4582</DisableSpecificWarnings> <!-- constructor is not implicitly called -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4623</DisableSpecificWarnings> <!-- default constructor was implicitly defined as deleted -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4625</DisableSpecificWarnings> <!-- copy constructor was implicitly defined as deleted -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4626</DisableSpecificWarnings> <!-- assignment operator was implicitly defined as deleted -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4710</DisableSpecificWarnings> <!-- function not inlined -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4711</DisableSpecificWarnings> <!-- function selected for automatic expansion -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4738</DisableSpecificWarnings> <!-- storing 32-bit float result in memory -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4820</DisableSpecificWarnings> <!-- N bytes padding added -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4866</DisableSpecificWarnings> <!-- compiler may not enforce ltr eval in operator[] -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4868</DisableSpecificWarnings> <!-- compiler may not enforce ltr eval in initializer list -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4946</DisableSpecificWarnings> <!-- reinterpret_cast used between related classes -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);5026</DisableSpecificWarnings> <!-- move constructor was implicitly defined as deleted -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);5027</DisableSpecificWarnings> <!-- move assignment operator was implicitly defined as deleted -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);5039</DisableSpecificWarnings> <!-- potentially throwing function passed to 'extern "C"' -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);5045</DisableSpecificWarnings> <!-- Compiler will insert Spectre mitigation -->
+ </ClCompile>
+ </ItemDefinitionGroup>
+ <PropertyGroup>
+ <LocalDebuggerWorkingDirectory>$(ProjectDir)..\</LocalDebuggerWorkingDirectory>
+ </PropertyGroup>
+ <ItemGroup>
+ <ClCompile Include="..\at_path.cpp" />
+ <ClCompile Include="..\path.cpp" />
+ <ClCompile Include="..\conformance_burntsushi_invalid.cpp" />
+ <ClCompile Include="..\conformance_burntsushi_valid.cpp" />
+ <ClCompile Include="..\conformance_iarna_invalid.cpp" />
+ <ClCompile Include="..\conformance_iarna_valid.cpp" />
+ <ClCompile Include="..\for_each.cpp" />
+ <ClCompile Include="..\formatters.cpp" />
+ <ClCompile Include="..\impl_toml.cpp">
+ <PrecompiledHeader>NotUsing</PrecompiledHeader>
+ </ClCompile>
+ <ClCompile Include="..\main.cpp">
+ <PrecompiledHeader>NotUsing</PrecompiledHeader>
+ </ClCompile>
+ <ClCompile Include="..\manipulating_arrays.cpp" />
+ <ClCompile Include="..\manipulating_tables.cpp" />
+ <ClCompile Include="..\manipulating_parse_result.cpp" />
+ <ClCompile Include="..\manipulating_values.cpp" />
+ <ClCompile Include="..\parsing_arrays.cpp" />
+ <ClCompile Include="..\parsing_booleans.cpp" />
+ <ClCompile Include="..\parsing_comments.cpp" />
+ <ClCompile Include="..\parsing_dates_and_times.cpp" />
+ <ClCompile Include="..\parsing_floats.cpp" />
+ <ClCompile Include="..\parsing_integers.cpp" />
+ <ClCompile Include="..\parsing_key_value_pairs.cpp" />
+ <ClCompile Include="..\parsing_spec_example.cpp" />
+ <ClCompile Include="..\parsing_strings.cpp" />
+ <ClCompile Include="..\parsing_tables.cpp" />
+ <ClCompile Include="..\tests.cpp">
+ <PrecompiledHeader>Create</PrecompiledHeader>
+ </ClCompile>
+ <ClCompile Include="..\user_feedback.cpp" />
+ <ClCompile Include="..\using_iterators.cpp" />
+ <ClCompile Include="..\visit.cpp" />
+ <ClCompile Include="..\windows_compat.cpp" />
+ </ItemGroup>
+ <ItemGroup>
+ <Natvis Include="..\..\toml++.natvis" />
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="..\leakproof.hpp" />
+ <ClInclude Include="..\lib_catch2.hpp" />
+ <ClInclude Include="..\lib_tloptional.hpp" />
+ <ClInclude Include="..\settings.hpp" />
+ <ClInclude Include="..\tests.hpp" />
+ </ItemGroup>
+ <ItemGroup>
+ <None Include="..\cpp.hint" />
+ <None Include="..\meson.build" />
+ </ItemGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+</Project>
diff --git a/tomlplusplus/tests/vs/test_release_x86_noexcept_unrel.vcxproj b/tomlplusplus/tests/vs/test_release_x86_noexcept_unrel.vcxproj
new file mode 100644
index 0000000000..39ce1308bd
--- /dev/null
+++ b/tomlplusplus/tests/vs/test_release_x86_noexcept_unrel.vcxproj
@@ -0,0 +1,127 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup Label="ProjectConfigurations">
+ <ProjectConfiguration Include="Release|Win32">
+ <Configuration>Release</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ </ItemGroup>
+ <PropertyGroup Label="Globals">
+ <VCProjectVersion>16.0</VCProjectVersion>
+ <ProjectGuid>{151E9E68-E325-5B08-8722-257F2B083BAD}</ProjectGuid>
+ <WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
+ <PreferredToolArchitecture>x64</PreferredToolArchitecture>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <UseDebugLibraries>true</UseDebugLibraries>
+ <PlatformToolset>v143</PlatformToolset>
+ <CharacterSet>MultiByte</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <UseDebugLibraries>false</UseDebugLibraries>
+ <PlatformToolset>v143</PlatformToolset>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ <CharacterSet>MultiByte</CharacterSet>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <ImportGroup Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props"
+ Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <Import Project="../../toml++.props" />
+ <ItemDefinitionGroup>
+ <ClCompile>
+ <AdditionalIncludeDirectories>..\tests;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <ExceptionHandling>false</ExceptionHandling>
+ <PrecompiledHeader>Use</PrecompiledHeader>
+ <PrecompiledHeaderFile>tests.hpp</PrecompiledHeaderFile>
+ <PreprocessorDefinitions>TOML_ENABLE_UNRELEASED_FEATURES=1;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <PreprocessorDefinitions>LEAK_TESTS=1;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'%(ExceptionHandling)'=='false'">_HAS_EXCEPTIONS=0;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'%(ExceptionHandling)'=='false'">SHOULD_HAVE_EXCEPTIONS=0;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'%(ExceptionHandling)'!='false'">SHOULD_HAVE_EXCEPTIONS=1;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <LanguageStandard>stdcpp17</LanguageStandard>
+ <MultiProcessorCompilation>true</MultiProcessorCompilation>
+ <WarningLevel>EnableAllWarnings</WarningLevel>
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4127</DisableSpecificWarnings> <!-- conditional expr is constant -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4324</DisableSpecificWarnings> <!-- structure was padded due to alignment specifier -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4464</DisableSpecificWarnings> <!-- relative include path contains '..' -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4505</DisableSpecificWarnings> <!-- unreferenced local function removed -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4514</DisableSpecificWarnings> <!-- unreferenced inline function has been removed -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4577</DisableSpecificWarnings> <!-- 'noexcept' used with no exception handling mode specified -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4582</DisableSpecificWarnings> <!-- constructor is not implicitly called -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4623</DisableSpecificWarnings> <!-- default constructor was implicitly defined as deleted -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4625</DisableSpecificWarnings> <!-- copy constructor was implicitly defined as deleted -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4626</DisableSpecificWarnings> <!-- assignment operator was implicitly defined as deleted -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4710</DisableSpecificWarnings> <!-- function not inlined -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4711</DisableSpecificWarnings> <!-- function selected for automatic expansion -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4738</DisableSpecificWarnings> <!-- storing 32-bit float result in memory -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4820</DisableSpecificWarnings> <!-- N bytes padding added -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4866</DisableSpecificWarnings> <!-- compiler may not enforce ltr eval in operator[] -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4868</DisableSpecificWarnings> <!-- compiler may not enforce ltr eval in initializer list -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4946</DisableSpecificWarnings> <!-- reinterpret_cast used between related classes -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);5026</DisableSpecificWarnings> <!-- move constructor was implicitly defined as deleted -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);5027</DisableSpecificWarnings> <!-- move assignment operator was implicitly defined as deleted -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);5039</DisableSpecificWarnings> <!-- potentially throwing function passed to 'extern "C"' -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);5045</DisableSpecificWarnings> <!-- Compiler will insert Spectre mitigation -->
+ </ClCompile>
+ </ItemDefinitionGroup>
+ <PropertyGroup>
+ <LocalDebuggerWorkingDirectory>$(ProjectDir)..\</LocalDebuggerWorkingDirectory>
+ </PropertyGroup>
+ <ItemGroup>
+ <ClCompile Include="..\at_path.cpp" />
+ <ClCompile Include="..\path.cpp" />
+ <ClCompile Include="..\conformance_burntsushi_invalid.cpp" />
+ <ClCompile Include="..\conformance_burntsushi_valid.cpp" />
+ <ClCompile Include="..\conformance_iarna_invalid.cpp" />
+ <ClCompile Include="..\conformance_iarna_valid.cpp" />
+ <ClCompile Include="..\for_each.cpp" />
+ <ClCompile Include="..\formatters.cpp" />
+ <ClCompile Include="..\impl_toml.cpp">
+ <PrecompiledHeader>NotUsing</PrecompiledHeader>
+ </ClCompile>
+ <ClCompile Include="..\main.cpp">
+ <PrecompiledHeader>NotUsing</PrecompiledHeader>
+ </ClCompile>
+ <ClCompile Include="..\manipulating_arrays.cpp" />
+ <ClCompile Include="..\manipulating_tables.cpp" />
+ <ClCompile Include="..\manipulating_parse_result.cpp" />
+ <ClCompile Include="..\manipulating_values.cpp" />
+ <ClCompile Include="..\parsing_arrays.cpp" />
+ <ClCompile Include="..\parsing_booleans.cpp" />
+ <ClCompile Include="..\parsing_comments.cpp" />
+ <ClCompile Include="..\parsing_dates_and_times.cpp" />
+ <ClCompile Include="..\parsing_floats.cpp" />
+ <ClCompile Include="..\parsing_integers.cpp" />
+ <ClCompile Include="..\parsing_key_value_pairs.cpp" />
+ <ClCompile Include="..\parsing_spec_example.cpp" />
+ <ClCompile Include="..\parsing_strings.cpp" />
+ <ClCompile Include="..\parsing_tables.cpp" />
+ <ClCompile Include="..\tests.cpp">
+ <PrecompiledHeader>Create</PrecompiledHeader>
+ </ClCompile>
+ <ClCompile Include="..\user_feedback.cpp" />
+ <ClCompile Include="..\using_iterators.cpp" />
+ <ClCompile Include="..\visit.cpp" />
+ <ClCompile Include="..\windows_compat.cpp" />
+ </ItemGroup>
+ <ItemGroup>
+ <Natvis Include="..\..\toml++.natvis" />
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="..\leakproof.hpp" />
+ <ClInclude Include="..\lib_catch2.hpp" />
+ <ClInclude Include="..\lib_tloptional.hpp" />
+ <ClInclude Include="..\settings.hpp" />
+ <ClInclude Include="..\tests.hpp" />
+ </ItemGroup>
+ <ItemGroup>
+ <None Include="..\cpp.hint" />
+ <None Include="..\meson.build" />
+ </ItemGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+</Project>
diff --git a/tomlplusplus/tests/vs/test_release_x86_unrel.vcxproj b/tomlplusplus/tests/vs/test_release_x86_unrel.vcxproj
new file mode 100644
index 0000000000..cbdedd384b
--- /dev/null
+++ b/tomlplusplus/tests/vs/test_release_x86_unrel.vcxproj
@@ -0,0 +1,127 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup Label="ProjectConfigurations">
+ <ProjectConfiguration Include="Release|Win32">
+ <Configuration>Release</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ </ItemGroup>
+ <PropertyGroup Label="Globals">
+ <VCProjectVersion>16.0</VCProjectVersion>
+ <ProjectGuid>{B3077FF1-FC90-5C14-A69F-3524F62167B1}</ProjectGuid>
+ <WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
+ <PreferredToolArchitecture>x64</PreferredToolArchitecture>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <UseDebugLibraries>true</UseDebugLibraries>
+ <PlatformToolset>v143</PlatformToolset>
+ <CharacterSet>MultiByte</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <UseDebugLibraries>false</UseDebugLibraries>
+ <PlatformToolset>v143</PlatformToolset>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ <CharacterSet>MultiByte</CharacterSet>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <ImportGroup Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props"
+ Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <Import Project="../../toml++.props" />
+ <ItemDefinitionGroup>
+ <ClCompile>
+ <AdditionalIncludeDirectories>..\tests;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <ExceptionHandling>Sync</ExceptionHandling>
+ <PrecompiledHeader>Use</PrecompiledHeader>
+ <PrecompiledHeaderFile>tests.hpp</PrecompiledHeaderFile>
+ <PreprocessorDefinitions>TOML_ENABLE_UNRELEASED_FEATURES=1;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <PreprocessorDefinitions>LEAK_TESTS=1;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'%(ExceptionHandling)'=='false'">_HAS_EXCEPTIONS=0;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'%(ExceptionHandling)'=='false'">SHOULD_HAVE_EXCEPTIONS=0;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'%(ExceptionHandling)'!='false'">SHOULD_HAVE_EXCEPTIONS=1;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <LanguageStandard>stdcpp17</LanguageStandard>
+ <MultiProcessorCompilation>true</MultiProcessorCompilation>
+ <WarningLevel>EnableAllWarnings</WarningLevel>
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4127</DisableSpecificWarnings> <!-- conditional expr is constant -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4324</DisableSpecificWarnings> <!-- structure was padded due to alignment specifier -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4464</DisableSpecificWarnings> <!-- relative include path contains '..' -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4505</DisableSpecificWarnings> <!-- unreferenced local function removed -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4514</DisableSpecificWarnings> <!-- unreferenced inline function has been removed -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4577</DisableSpecificWarnings> <!-- 'noexcept' used with no exception handling mode specified -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4582</DisableSpecificWarnings> <!-- constructor is not implicitly called -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4623</DisableSpecificWarnings> <!-- default constructor was implicitly defined as deleted -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4625</DisableSpecificWarnings> <!-- copy constructor was implicitly defined as deleted -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4626</DisableSpecificWarnings> <!-- assignment operator was implicitly defined as deleted -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4710</DisableSpecificWarnings> <!-- function not inlined -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4711</DisableSpecificWarnings> <!-- function selected for automatic expansion -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4738</DisableSpecificWarnings> <!-- storing 32-bit float result in memory -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4820</DisableSpecificWarnings> <!-- N bytes padding added -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4866</DisableSpecificWarnings> <!-- compiler may not enforce ltr eval in operator[] -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4868</DisableSpecificWarnings> <!-- compiler may not enforce ltr eval in initializer list -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);4946</DisableSpecificWarnings> <!-- reinterpret_cast used between related classes -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);5026</DisableSpecificWarnings> <!-- move constructor was implicitly defined as deleted -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);5027</DisableSpecificWarnings> <!-- move assignment operator was implicitly defined as deleted -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);5039</DisableSpecificWarnings> <!-- potentially throwing function passed to 'extern "C"' -->
+ <DisableSpecificWarnings>%(DisableSpecificWarnings);5045</DisableSpecificWarnings> <!-- Compiler will insert Spectre mitigation -->
+ </ClCompile>
+ </ItemDefinitionGroup>
+ <PropertyGroup>
+ <LocalDebuggerWorkingDirectory>$(ProjectDir)..\</LocalDebuggerWorkingDirectory>
+ </PropertyGroup>
+ <ItemGroup>
+ <ClCompile Include="..\at_path.cpp" />
+ <ClCompile Include="..\path.cpp" />
+ <ClCompile Include="..\conformance_burntsushi_invalid.cpp" />
+ <ClCompile Include="..\conformance_burntsushi_valid.cpp" />
+ <ClCompile Include="..\conformance_iarna_invalid.cpp" />
+ <ClCompile Include="..\conformance_iarna_valid.cpp" />
+ <ClCompile Include="..\for_each.cpp" />
+ <ClCompile Include="..\formatters.cpp" />
+ <ClCompile Include="..\impl_toml.cpp">
+ <PrecompiledHeader>NotUsing</PrecompiledHeader>
+ </ClCompile>
+ <ClCompile Include="..\main.cpp">
+ <PrecompiledHeader>NotUsing</PrecompiledHeader>
+ </ClCompile>
+ <ClCompile Include="..\manipulating_arrays.cpp" />
+ <ClCompile Include="..\manipulating_tables.cpp" />
+ <ClCompile Include="..\manipulating_parse_result.cpp" />
+ <ClCompile Include="..\manipulating_values.cpp" />
+ <ClCompile Include="..\parsing_arrays.cpp" />
+ <ClCompile Include="..\parsing_booleans.cpp" />
+ <ClCompile Include="..\parsing_comments.cpp" />
+ <ClCompile Include="..\parsing_dates_and_times.cpp" />
+ <ClCompile Include="..\parsing_floats.cpp" />
+ <ClCompile Include="..\parsing_integers.cpp" />
+ <ClCompile Include="..\parsing_key_value_pairs.cpp" />
+ <ClCompile Include="..\parsing_spec_example.cpp" />
+ <ClCompile Include="..\parsing_strings.cpp" />
+ <ClCompile Include="..\parsing_tables.cpp" />
+ <ClCompile Include="..\tests.cpp">
+ <PrecompiledHeader>Create</PrecompiledHeader>
+ </ClCompile>
+ <ClCompile Include="..\user_feedback.cpp" />
+ <ClCompile Include="..\using_iterators.cpp" />
+ <ClCompile Include="..\visit.cpp" />
+ <ClCompile Include="..\windows_compat.cpp" />
+ </ItemGroup>
+ <ItemGroup>
+ <Natvis Include="..\..\toml++.natvis" />
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="..\leakproof.hpp" />
+ <ClInclude Include="..\lib_catch2.hpp" />
+ <ClInclude Include="..\lib_tloptional.hpp" />
+ <ClInclude Include="..\settings.hpp" />
+ <ClInclude Include="..\tests.hpp" />
+ </ItemGroup>
+ <ItemGroup>
+ <None Include="..\cpp.hint" />
+ <None Include="..\meson.build" />
+ </ItemGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+</Project>
diff --git a/tomlplusplus/tests/windows_compat.cpp b/tomlplusplus/tests/windows_compat.cpp
new file mode 100644
index 0000000000..1d234cf7a0
--- /dev/null
+++ b/tomlplusplus/tests/windows_compat.cpp
@@ -0,0 +1,97 @@
+// This file is a part of toml++ and is subject to the the terms of the MIT license.
+// Copyright (c) Mark Gillard <mark.gillard@outlook.com.au>
+// See https://github.com/marzer/tomlplusplus/blob/master/LICENSE for the full license text.
+// SPDX-License-Identifier: MIT
+
+#include "tests.hpp"
+
+#if TOML_ENABLE_WINDOWS_COMPAT
+
+TOML_DISABLE_WARNINGS;
+#include <windows.h>
+TOML_ENABLE_WARNINGS;
+
+TEST_CASE("windows compat")
+{
+ static constexpr auto toml_text = R"(
+ [library]
+ name = "toml++"
+ authors = ["Mark Gillard <mark.gillard@outlook.com.au>"]
+ free = true
+
+ [dependencies]
+ cpp = 17
+ )"sv;
+
+ auto res = toml::parse(toml_text, L"kek.toml");
+#if !TOML_EXCEPTIONS
+ REQUIRE(res.succeeded());
+#endif
+ table& tbl = res;
+
+ // source paths
+ REQUIRE(tbl.source().path != nullptr);
+ CHECK(*tbl.source().path == "kek.toml"sv);
+ CHECK(tbl.source().wide_path().has_value());
+ CHECK(tbl.source().wide_path().value() == L"kek.toml"sv);
+
+ // direct lookups from tables
+ REQUIRE(tbl.get("library") != nullptr);
+ CHECK(tbl.get("library") == tbl.get("library"sv));
+ CHECK(tbl.get("library") == tbl.get("library"s));
+ CHECK(tbl.get(L"library") != nullptr);
+ CHECK(tbl.get(L"library") == tbl.get(L"library"sv));
+ CHECK(tbl.get(L"library") == tbl.get(L"library"s));
+ CHECK(tbl.get(L"library") == tbl.get("library"));
+
+ // node-view lookups
+ CHECK(tbl[L"library"].node() != nullptr);
+ CHECK(tbl[L"library"].node() == tbl.get(L"library"));
+
+ // value queries
+ REQUIRE(tbl[L"library"][L"name"].as_string() != nullptr);
+ CHECK(tbl[L"library"][L"name"].value<std::wstring>() == L"toml++"s);
+ CHECK(tbl[L"library"][L"name"].value_or(L""sv) == L"toml++"s);
+ CHECK(tbl[L"library"][L"name"].value_or(L""s) == L"toml++"s);
+ CHECK(tbl[L"library"][L"name"].value_or(L"") == L"toml++"s);
+
+ // node-view comparisons
+ CHECK(tbl[L"library"][L"name"] == "toml++"sv);
+ CHECK(tbl[L"library"][L"name"] == "toml++"s);
+ CHECK(tbl[L"library"][L"name"] == "toml++");
+ CHECK(tbl[L"library"][L"name"] == L"toml++"sv);
+ CHECK(tbl[L"library"][L"name"] == L"toml++"s);
+ CHECK(tbl[L"library"][L"name"] == L"toml++");
+
+ // table manipulation
+ tbl.insert(L"foo", L"bar");
+ REQUIRE(tbl.contains("foo"));
+ REQUIRE(tbl.contains(L"foo"));
+ CHECK(tbl["foo"] == "bar");
+ tbl.insert_or_assign(L"foo", L"kek");
+ CHECK(tbl["foo"] == "kek");
+ tbl.erase(L"foo");
+ REQUIRE(!tbl.contains("foo"));
+ REQUIRE(!tbl.contains(L"foo"));
+
+ // windows types
+ CHECK(tbl[L"library"][L"free"].value<BOOL>() == 1);
+ CHECK(tbl[L"dependencies"][L"cpp"].value<BOOL>() == 17);
+ CHECK(tbl[L"dependencies"][L"cpp"].value<SHORT>() == 17);
+ CHECK(tbl[L"dependencies"][L"cpp"].value<INT>() == 17);
+ CHECK(tbl[L"dependencies"][L"cpp"].value<LONG>() == 17);
+ CHECK(tbl[L"dependencies"][L"cpp"].value<INT_PTR>() == 17);
+ CHECK(tbl[L"dependencies"][L"cpp"].value<LONG_PTR>() == 17);
+ CHECK(tbl[L"dependencies"][L"cpp"].value<USHORT>() == 17u);
+ CHECK(tbl[L"dependencies"][L"cpp"].value<UINT>() == 17u);
+ CHECK(tbl[L"dependencies"][L"cpp"].value<ULONG>() == 17u);
+ CHECK(tbl[L"dependencies"][L"cpp"].value<UINT_PTR>() == 17u);
+ CHECK(tbl[L"dependencies"][L"cpp"].value<ULONG_PTR>() == 17u);
+ CHECK(tbl[L"dependencies"][L"cpp"].value<WORD>() == 17u);
+ CHECK(tbl[L"dependencies"][L"cpp"].value<DWORD>() == 17u);
+ CHECK(tbl[L"dependencies"][L"cpp"].value<DWORD32>() == 17u);
+ CHECK(tbl[L"dependencies"][L"cpp"].value<DWORD64>() == 17u);
+ CHECK(tbl[L"dependencies"][L"cpp"].value<DWORDLONG>() == 17u);
+}
+
+#endif // TOML_ENABLE_WINDOWS_COMPAT