From d90c26f9ac18f2d668c15f15eeae2769d903bbc6 Mon Sep 17 00:00:00 2001 From: ToruNiina Date: Fri, 16 Apr 2021 15:28:58 +0900 Subject: [PATCH 01/22] feat: add TOML11_PRESERVE_COMMENTS_BY_DEFAULT --- toml/comments.hpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/toml/comments.hpp b/toml/comments.hpp index 92fc8e1..b9ce806 100644 --- a/toml/comments.hpp +++ b/toml/comments.hpp @@ -10,6 +10,12 @@ #include #include +#ifdef TOML11_PRESERVE_COMMENTS_BY_DEFAULT +# define TOML11_DEFAULT_COMMENT_STRATEGY ::toml::preserve_comments +#else +# define TOML11_DEFAULT_COMMENT_STRATEGY ::toml::discard_comments +#endif + // This file provides mainly two classes, `preserve_comments` and `discard_comments`. // Those two are a container that have the same interface as `std::vector` // but bahaves in the opposite way. `preserve_comments` is just the same as From c40e0dbd3783405adea8168eb60b809f6a8b019a Mon Sep 17 00:00:00 2001 From: ToruNiina Date: Fri, 16 Apr 2021 15:29:24 +0900 Subject: [PATCH 02/22] feat: use comment macro everywhere --- toml/literal.hpp | 8 ++++---- toml/parser.hpp | 8 ++++---- toml/value.hpp | 3 ++- 3 files changed, 10 insertions(+), 9 deletions(-) diff --git a/toml/literal.hpp b/toml/literal.hpp index 0824f83..1d338b7 100644 --- a/toml/literal.hpp +++ b/toml/literal.hpp @@ -12,11 +12,11 @@ inline namespace toml_literals { // implementation -inline ::toml::basic_value<::toml::discard_comments, std::unordered_map, std::vector> +inline ::toml::basic_value literal_internal_impl(::toml::detail::location loc) { using value_type = ::toml::basic_value< - ::toml::discard_comments, std::unordered_map, std::vector>; + TOML11_DEFAULT_COMMENT_STRATEGY, std::unordered_map, std::vector>; // if there are some comments or empty lines, skip them. using skip_line = ::toml::detail::repeat, @@ -81,7 +81,7 @@ literal_internal_impl(::toml::detail::location loc) } -inline ::toml::basic_value<::toml::discard_comments, std::unordered_map, std::vector> +inline ::toml::basic_value operator"" _toml(const char* str, std::size_t len) { ::toml::detail::location loc( @@ -95,7 +95,7 @@ operator"" _toml(const char* str, std::size_t len) #if defined(__cpp_char8_t) && __cpp_char8_t >= 201811L // value of u8"" literal has been changed from char to char8_t and char8_t is // NOT compatible to char -inline ::toml::basic_value<::toml::discard_comments, std::unordered_map, std::vector> +inline ::toml::basic_value operator"" _toml(const char8_t* str, std::size_t len) { ::toml::detail::location loc( diff --git a/toml/parser.hpp b/toml/parser.hpp index c3df644..231df80 100644 --- a/toml/parser.hpp +++ b/toml/parser.hpp @@ -2076,7 +2076,7 @@ result parse_toml_file(location& loc) } // detail -template class Table = std::unordered_map, template class Array = std::vector> basic_value @@ -2127,7 +2127,7 @@ parse(std::istream& is, const std::string& fname = "unknown file") return data.unwrap(); } -template class Table = std::unordered_map, template class Array = std::vector> basic_value parse(const std::string& fname) @@ -2150,7 +2150,7 @@ basic_value parse(const std::string& fname) // // This function exactly matches to the invokation with c-string. // So this function is preferred than others and the ambiguity disappears. -template class Table = std::unordered_map, template class Array = std::vector> basic_value parse(const char* fname) @@ -2158,7 +2158,7 @@ basic_value parse(const char* fname) return parse(std::string(fname)); } -template class Table = std::unordered_map, template class Array = std::vector> basic_value parse(const std::filesystem::path& fpath) diff --git a/toml/value.hpp b/toml/value.hpp index e374c3b..f2e6c63 100644 --- a/toml/value.hpp +++ b/toml/value.hpp @@ -1739,7 +1739,8 @@ class basic_value }; // default toml::value and default array/table. -using value = basic_value; +// TOML11_DEFAULT_COMMENT_STRATEGY is defined in comments.hpp +using value = basic_value; using array = typename value::array_type; using table = typename value::table_type; From c4a803df50745598846490aeff0437c883b0be33 Mon Sep 17 00:00:00 2001 From: ToruNiina Date: Tue, 27 Apr 2021 13:05:03 +0900 Subject: [PATCH 03/22] test: add comment/no-comment cases to parse_array When we add a macro to change the default comment preservation scheme, some of the current tests that assume comments are discarded by defualt fails. To make it more robust, we need to explicitly specify the comment preservation scheme and add test cases for both of discard_ and preserve_comments. --- tests/test_parse_array.cpp | 184 +++++++++++++++++++++++++++++-------- 1 file changed, 144 insertions(+), 40 deletions(-) diff --git a/tests/test_parse_array.cpp b/tests/test_parse_array.cpp index 2723b89..a75a6f1 100644 --- a/tests/test_parse_array.cpp +++ b/tests/test_parse_array.cpp @@ -71,62 +71,153 @@ BOOST_AUTO_TEST_CASE(test_oneline_array_value) BOOST_AUTO_TEST_CASE(test_multiline_array) { - TOML11_TEST_PARSE_EQUAL(parse_array, "[\n#comment\n]", array()); + TOML11_TEST_PARSE_EQUAL(parse_array>, "[\n#comment\n]", typename basic_value< discard_comments>::array_type()); + TOML11_TEST_PARSE_EQUAL(parse_array>, "[\n#comment\n]", typename basic_value::array_type()); + { - array a(5); - a[0] = toml::value(3); a[1] = toml::value(1); a[2] = toml::value(4); - a[3] = toml::value(1); a[4] = toml::value(5); - TOML11_TEST_PARSE_EQUAL(parse_array, "[3,\n1,\n4,\n1,\n5]", a); + typename basic_value::array_type a(5); + a[0] = basic_value(3); + a[1] = basic_value(1); + a[2] = basic_value(4); + a[3] = basic_value(1); + a[4] = basic_value(5); + TOML11_TEST_PARSE_EQUAL(parse_array>, "[3,\n1,\n4,\n1,\n5]", a); } { - array a(3); - a[0] = toml::value("foo"); a[1] = toml::value("bar"); - a[2] = toml::value("baz"); - TOML11_TEST_PARSE_EQUAL(parse_array, "[\"foo\",\n\"bar\",\n\"baz\"]", a); + typename basic_value::array_type a(5); + a[0] = basic_value(3); + a[1] = basic_value(1); + a[2] = basic_value(4); + a[3] = basic_value(1); + a[4] = basic_value(5); + TOML11_TEST_PARSE_EQUAL(parse_array>, "[3,\n1,\n4,\n1,\n5]", a); } { - array a(5); - a[0] = toml::value(3); a[1] = toml::value(1); a[2] = toml::value(4); - a[3] = toml::value(1); a[4] = toml::value(5); - TOML11_TEST_PARSE_EQUAL(parse_array, "[3,#comment\n1,#comment\n4,#comment\n1,#comment\n5]", a); + typename basic_value::array_type a(5); + a[0] = basic_value(3); + a[1] = basic_value(1); + a[2] = basic_value(4); + a[3] = basic_value(1); + a[4] = basic_value(5); + TOML11_TEST_PARSE_EQUAL(parse_array>, "[3,#comment\n1,#comment\n4,#comment\n1,#comment\n5 #comment\n]", a); } { - array a(3); - a[0] = toml::value("foo"); a[1] = toml::value("b#r"); - a[2] = toml::value("b#z"); - TOML11_TEST_PARSE_EQUAL(parse_array, "[\"foo\",#comment\n\"b#r\",#comment\n\"b#z\"#comment\n]", a); + typename basic_value::array_type a(5); + a[0] = basic_value(3, {"comment"}); + a[1] = basic_value(1, {"comment"}); + a[2] = basic_value(4, {"comment"}); + a[3] = basic_value(1, {"comment"}); + a[4] = basic_value(5, {"comment"}); + TOML11_TEST_PARSE_EQUAL(parse_array>, "[3,#comment\n1,#comment\n4,#comment\n1,#comment\n5 #comment\n]", a); + } + + + { + typename basic_value::array_type a(3); + a[0] = basic_value("foo"); + a[1] = basic_value("bar"); + a[2] = basic_value("baz"); + TOML11_TEST_PARSE_EQUAL(parse_array>, "[\"foo\",\n\"bar\",\n\"baz\"]", a); + } + { + typename basic_value::array_type a(3); + a[0] = basic_value("foo"); + a[1] = basic_value("bar"); + a[2] = basic_value("baz"); + TOML11_TEST_PARSE_EQUAL(parse_array>, "[\"foo\",\n\"bar\",\n\"baz\"]", a); + } + + { + typename basic_value::array_type a(3); + a[0] = basic_value("foo"); + a[1] = basic_value("b#r"); + a[2] = basic_value("b#z"); + TOML11_TEST_PARSE_EQUAL(parse_array>, "[\"foo\",#comment\n\"b#r\",#comment\n\"b#z\"#comment\n]", a); + } + { + typename basic_value::array_type a(3); + a[0] = basic_value("foo", {"comment"}); + a[1] = basic_value("b#r", {"comment"}); + a[2] = basic_value("b#z", {"comment"}); + TOML11_TEST_PARSE_EQUAL(parse_array>, "[\"foo\",#comment\n\"b#r\",#comment\n\"b#z\"#comment\n]", a); } } BOOST_AUTO_TEST_CASE(test_multiline_array_value) { - TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "[\n#comment\n]", toml::value(array())); + TOML11_TEST_PARSE_EQUAL_VALUE(parse_value>, "[\n#comment\n]", basic_value< discard_comments>(typename basic_value< discard_comments>::array_type())); + TOML11_TEST_PARSE_EQUAL_VALUE(parse_value>, "[\n#comment\n]", basic_value(typename basic_value::array_type())); + { - array a(5); - a[0] = toml::value(3); a[1] = toml::value(1); a[2] = toml::value(4); - a[3] = toml::value(1); a[4] = toml::value(5); - TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "[3,\n1,\n4,\n1,\n5]", toml::value(a)); + typename basic_value::array_type a(5); + a[0] = basic_value(3); + a[1] = basic_value(1); + a[2] = basic_value(4); + a[3] = basic_value(1); + a[4] = basic_value(5); + TOML11_TEST_PARSE_EQUAL_VALUE(parse_value>, "[3,\n1,\n4,\n1,\n5]", basic_value(a)); } { - array a(3); - a[0] = toml::value("foo"); a[1] = toml::value("bar"); - a[2] = toml::value("baz"); - TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "[\"foo\",\n\"bar\",\n\"baz\"]", toml::value(a)); + typename basic_value::array_type a(5); + a[0] = basic_value(3); + a[1] = basic_value(1); + a[2] = basic_value(4); + a[3] = basic_value(1); + a[4] = basic_value(5); + TOML11_TEST_PARSE_EQUAL_VALUE(parse_value>, "[3,\n1,\n4,\n1,\n5]", basic_value(a)); } { - array a(5); - a[0] = toml::value(3); a[1] = toml::value(1); a[2] = toml::value(4); - a[3] = toml::value(1); a[4] = toml::value(5); - TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "[3,#comment\n1,#comment\n4,#comment\n1,#comment\n5]", toml::value(a)); + typename basic_value::array_type a(5); + a[0] = basic_value(3); + a[1] = basic_value(1); + a[2] = basic_value(4); + a[3] = basic_value(1); + a[4] = basic_value(5); + TOML11_TEST_PARSE_EQUAL_VALUE(parse_value>, "[3,#comment\n1,#comment\n4,#comment\n1,#comment\n5 #comment\n]", basic_value(a)); } { - array a(3); - a[0] = toml::value("foo"); a[1] = toml::value("b#r"); - a[2] = toml::value("b#z"); - TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "[\"foo\",#comment\n\"b#r\",#comment\n\"b#z\"#comment\n]", toml::value(a)); + typename basic_value::array_type a(5); + a[0] = basic_value(3, {"comment"}); + a[1] = basic_value(1, {"comment"}); + a[2] = basic_value(4, {"comment"}); + a[3] = basic_value(1, {"comment"}); + a[4] = basic_value(5, {"comment"}); + TOML11_TEST_PARSE_EQUAL_VALUE(parse_value>, "[3,#comment\n1,#comment\n4,#comment\n1,#comment\n5 #comment\n]", basic_value(a)); } + + + { + typename basic_value::array_type a(3); + a[0] = basic_value("foo"); + a[1] = basic_value("bar"); + a[2] = basic_value("baz"); + TOML11_TEST_PARSE_EQUAL_VALUE(parse_value>, "[\"foo\",\n\"bar\",\n\"baz\"]", basic_value(a)); + } + { + typename basic_value::array_type a(3); + a[0] = basic_value("foo"); + a[1] = basic_value("bar"); + a[2] = basic_value("baz"); + TOML11_TEST_PARSE_EQUAL_VALUE(parse_value>, "[\"foo\",\n\"bar\",\n\"baz\"]", basic_value(a)); + } + + { + typename basic_value::array_type a(3); + a[0] = basic_value("foo"); + a[1] = basic_value("b#r"); + a[2] = basic_value("b#z"); + TOML11_TEST_PARSE_EQUAL_VALUE(parse_value>, "[\"foo\",#comment\n\"b#r\",#comment\n\"b#z\"#comment\n]", basic_value(a)); + } + { + typename basic_value::array_type a(3); + a[0] = basic_value("foo", {"comment"}); + a[1] = basic_value("b#r", {"comment"}); + a[2] = basic_value("b#z", {"comment"}); + TOML11_TEST_PARSE_EQUAL_VALUE(parse_value>, "[\"foo\",#comment\n\"b#r\",#comment\n\"b#z\"#comment\n]", basic_value(a)); + } + } BOOST_AUTO_TEST_CASE(test_heterogeneous_array) @@ -176,14 +267,27 @@ BOOST_AUTO_TEST_CASE(test_heterogeneous_array) BOOST_AUTO_TEST_CASE(test_comments_after_comma) { { - array a; - a.push_back("foo"); - a.push_back("bar"); - a.push_back("baz"); - TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, + typename basic_value::array_type a(3); + a[0] = basic_value("foo"); + a[1] = basic_value("bar"); + a[2] = basic_value("baz"); + TOML11_TEST_PARSE_EQUAL_VALUE(parse_value>, "[ \"foo\" # comment\n" ", \"bar\" # comment\n" ", \"baz\" # comment\n" - "]", toml::value(a)); + "]", basic_value(a)); } + + { + typename basic_value::array_type a(3); + a[0] = basic_value("foo", {" comment"}); + a[1] = basic_value("bar", {" comment"}); + a[2] = basic_value("baz", {" comment"}); + TOML11_TEST_PARSE_EQUAL_VALUE(parse_value>, + "[ \"foo\" # comment\n" + ", \"bar\" # comment\n" + ", \"baz\" # comment\n" + "]", basic_value(a)); + } + } From 21ea4a348dc69f5f3cc4a930f27a5399360020c6 Mon Sep 17 00:00:00 2001 From: ToruNiina Date: Tue, 27 Apr 2021 13:12:37 +0900 Subject: [PATCH 04/22] test: explicitly specify template arguments toml::value is an alias of default parameters, so we need to avoid conflict of definitions between default and non-default parameters --- tests/test_find.cpp | 2 +- tests/test_find_or.cpp | 2 +- tests/test_get.cpp | 2 +- tests/test_get_or.cpp | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/test_find.cpp b/tests/test_find.cpp index 5582da8..238390c 100644 --- a/tests/test_find.cpp +++ b/tests/test_find.cpp @@ -19,7 +19,7 @@ #include using test_value_types = std::tuple< - toml::value, + toml::basic_value, toml::basic_value, toml::basic_value, toml::basic_value diff --git a/tests/test_find_or.cpp b/tests/test_find_or.cpp index 434f943..72e5450 100644 --- a/tests/test_find_or.cpp +++ b/tests/test_find_or.cpp @@ -17,7 +17,7 @@ #endif using test_value_types = std::tuple< - toml::value, + toml::basic_value, toml::basic_value, toml::basic_value, toml::basic_value diff --git a/tests/test_get.cpp b/tests/test_get.cpp index 0749fd4..9a795f2 100644 --- a/tests/test_get.cpp +++ b/tests/test_get.cpp @@ -17,7 +17,7 @@ #endif using test_value_types = std::tuple< - toml::value, + toml::basic_value, toml::basic_value, toml::basic_value, toml::basic_value diff --git a/tests/test_get_or.cpp b/tests/test_get_or.cpp index 82e4839..a709ae7 100644 --- a/tests/test_get_or.cpp +++ b/tests/test_get_or.cpp @@ -17,7 +17,7 @@ #endif using test_value_types = std::tuple< - toml::value, + toml::basic_value, toml::basic_value, toml::basic_value, toml::basic_value From b51ef5e869d9411d6c91255fd81c87219615309f Mon Sep 17 00:00:00 2001 From: ToruNiina Date: Tue, 27 Apr 2021 13:18:39 +0900 Subject: [PATCH 05/22] test: explicitly specify the comment preservation --- tests/test_serialize_file.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/test_serialize_file.cpp b/tests/test_serialize_file.cpp index b5c408e..7e1d8e1 100644 --- a/tests/test_serialize_file.cpp +++ b/tests/test_serialize_file.cpp @@ -127,8 +127,8 @@ BOOST_AUTO_TEST_CASE(test_example_with_comment_nocomment) BOOST_TEST(!has_comment_inside(serialized)); } { - const auto data_nocomment = toml::parse("toml/tests/example.toml"); - auto serialized = toml::parse("tmp1_com_nocomment.toml"); + const auto data_nocomment = toml::parse("toml/tests/example.toml"); + auto serialized = toml::parse("tmp1_com_nocomment.toml"); { auto& owner = toml::find(serialized, "owner"); auto& bio = toml::find(owner, "bio"); @@ -182,8 +182,8 @@ BOOST_AUTO_TEST_CASE(test_example_with_comment_map_dq_nocomment) BOOST_TEST(!has_comment_inside(serialized)); } { - const auto data_nocomment = toml::parse("toml/tests/example.toml"); - auto serialized = toml::parse("tmp1_com_map_dq_nocomment.toml"); + const auto data_nocomment = toml::parse("toml/tests/example.toml"); + auto serialized = toml::parse("tmp1_com_map_dq_nocomment.toml"); { auto& owner = toml::find(serialized, "owner"); auto& bio = toml::find(owner, "bio"); From beb665ba5813bae6d809a9e9ba0229d2baea7f43 Mon Sep 17 00:00:00 2001 From: ToruNiina Date: Tue, 27 Apr 2021 13:19:55 +0900 Subject: [PATCH 06/22] test: explicitly specify if comments are preserved --- tests/test_comments.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test_comments.cpp b/tests/test_comments.cpp index 7438cae..635783a 100644 --- a/tests/test_comments.cpp +++ b/tests/test_comments.cpp @@ -190,7 +190,7 @@ BOOST_AUTO_TEST_CASE(test_discard_comment) )"; std::istringstream iss(file); - const auto v = toml::parse(iss); + const auto v = toml::parse(iss); const auto& a = toml::find(v, "a"); const auto& b = toml::find(v, "b"); From 31b9b793123836b9b708cccc18e7fbd84e98d32f Mon Sep 17 00:00:00 2001 From: ToruNiina Date: Wed, 28 Apr 2021 15:12:04 +0900 Subject: [PATCH 07/22] ci: suppress clang-8 / c++20 because of gcc header --- .github/workflows/main.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 5a9a0b0..04ab80b 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -58,6 +58,7 @@ jobs: - {compiler: '5.0', standard: '20'} - {compiler: '6.0', standard: '20'} - {compiler: '7', standard: '20'} + - {compiler: '8', standard: '20'} steps: - name: Checkout uses: actions/checkout@v2 From 06e8b853ba3340859ab4fe4147b58d8f1d078775 Mon Sep 17 00:00:00 2001 From: ToruNiina Date: Tue, 4 May 2021 17:50:14 +0900 Subject: [PATCH 08/22] test: add Wshadow=local --- tests/CMakeLists.txt | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index a19c9b0..c1cd8bb 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -59,6 +59,7 @@ CHECK_CXX_COMPILER_FLAG("-Wuseless-cast" COMPILER_SUPPORTS_WUSELESS_CAST) CHECK_CXX_COMPILER_FLAG("-Wdouble-promotion" COMPILER_SUPPORTS_WDOUBLE_PROMOTION) CHECK_CXX_COMPILER_FLAG("-Wrange-loop-analysis" COMPILER_SUPPORTS_WRANGE_LOOP_ANALYSIS) CHECK_CXX_COMPILER_FLAG("-Wundef" COMPILER_SUPPORTS_WUNDEF) +CHECK_CXX_COMPILER_FLAG("-Wshadow=local" COMPILER_SUPPORTS_WSHADOW_LOCAL) if(COMPILER_SUPPORTS_WALL) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall") @@ -72,6 +73,9 @@ endif() if(COMPILER_SUPPORTS_WERROR) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Werror") endif() +if(COMPILER_SUPPORTS_WSHADOW_LOCAL) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wshadow=local") +endif() if(COMPILER_SUPPORTS_WSIGN_CONVERSION) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wsign-conversion") endif() From dce50142e6ad4940e1919e6301e6b14005b14ab6 Mon Sep 17 00:00:00 2001 From: ToruNiina Date: Mon, 10 May 2021 20:47:08 +0900 Subject: [PATCH 09/22] fix: avoid argname `key` to supress warning about shadowing --- toml/serializer.hpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/toml/serializer.hpp b/toml/serializer.hpp index 77aef58..b27abfd 100644 --- a/toml/serializer.hpp +++ b/toml/serializer.hpp @@ -26,19 +26,19 @@ namespace toml // a `"` and escaping some special character is boring. template std::basic_string -format_key(const std::basic_string& key) +format_key(const std::basic_string& k) { // check the key can be a bare (unquoted) key - detail::location loc(key, std::vector(key.begin(), key.end())); + detail::location loc(k, std::vector(k.begin(), k.end())); detail::lex_unquoted_key::invoke(loc); if(loc.iter() == loc.end()) { - return key; // all the tokens are consumed. the key is unquoted-key. + return k; // all the tokens are consumed. the key is unquoted-key. } //if it includes special characters, then format it in a "quoted" key. std::basic_string serialized("\""); - for(const char c : key) + for(const char c : k) { switch(c) { From 4acc563b28ee79fb64cb8cfb37379fd4e2e7c27b Mon Sep 17 00:00:00 2001 From: ToruNiina Date: Mon, 10 May 2021 20:48:27 +0900 Subject: [PATCH 10/22] feat: explicitly avoid -Wshadow=global in GCC --- toml/types.hpp | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/toml/types.hpp b/toml/types.hpp index 0818ebd..caf718b 100644 --- a/toml/types.hpp +++ b/toml/types.hpp @@ -38,6 +38,12 @@ using floating = double; // "float" is a keyward, cannot use it here. // using array = typename value::array_type; // using table = typename value::table_type; +// to avoid warnings about `value_t::integer` is "shadowing" toml::integer in +// GCC -Wshadow=global. +#if defined(__GNUC__) && !defined(__clang__) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wshadow=global" +#endif enum class value_t : std::uint8_t { empty = 0, @@ -52,6 +58,9 @@ enum class value_t : std::uint8_t array = 9, table = 10, }; +#if defined(__GNUC__) && !defined(__clang__) +#pragma GCC diagnostic pop +#endif template inline std::basic_ostream& @@ -147,4 +156,5 @@ template struct is_exact_toml_type } // detail } // toml + #endif// TOML11_TYPES_H From db0d9a024bc73b5e79819fef80743601cf753276 Mon Sep 17 00:00:00 2001 From: ToruNiina Date: Mon, 10 May 2021 20:49:41 +0900 Subject: [PATCH 11/22] test: add -Wshadow while compiling tests --- tests/CMakeLists.txt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index c1cd8bb..031bdac 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -59,7 +59,7 @@ CHECK_CXX_COMPILER_FLAG("-Wuseless-cast" COMPILER_SUPPORTS_WUSELESS_CAST) CHECK_CXX_COMPILER_FLAG("-Wdouble-promotion" COMPILER_SUPPORTS_WDOUBLE_PROMOTION) CHECK_CXX_COMPILER_FLAG("-Wrange-loop-analysis" COMPILER_SUPPORTS_WRANGE_LOOP_ANALYSIS) CHECK_CXX_COMPILER_FLAG("-Wundef" COMPILER_SUPPORTS_WUNDEF) -CHECK_CXX_COMPILER_FLAG("-Wshadow=local" COMPILER_SUPPORTS_WSHADOW_LOCAL) +CHECK_CXX_COMPILER_FLAG("-Wshadow" COMPILER_SUPPORTS_WSHADOW) if(COMPILER_SUPPORTS_WALL) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall") @@ -73,8 +73,8 @@ endif() if(COMPILER_SUPPORTS_WERROR) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Werror") endif() -if(COMPILER_SUPPORTS_WSHADOW_LOCAL) - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wshadow=local") +if(COMPILER_SUPPORTS_WSHADOW) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wshadow") endif() if(COMPILER_SUPPORTS_WSIGN_CONVERSION) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wsign-conversion") From cd60045014554e02a749555214e774d79c8d9a38 Mon Sep 17 00:00:00 2001 From: ToruNiina Date: Mon, 10 May 2021 21:51:51 +0900 Subject: [PATCH 12/22] fix: gcc 7 introduces wshadow variants --- toml/types.hpp | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/toml/types.hpp b/toml/types.hpp index caf718b..a292d09 100644 --- a/toml/types.hpp +++ b/toml/types.hpp @@ -41,8 +41,12 @@ using floating = double; // "float" is a keyward, cannot use it here. // to avoid warnings about `value_t::integer` is "shadowing" toml::integer in // GCC -Wshadow=global. #if defined(__GNUC__) && !defined(__clang__) -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wshadow=global" +# pragma GCC diagnostic push +# if 7 <= __GNUC__ +# pragma GCC diagnostic ignored "-Wshadow=global" +# else // gcc-6 or older +# pragma GCC diagnostic ignored "-Wshadow" +# endif #endif enum class value_t : std::uint8_t { @@ -59,7 +63,7 @@ enum class value_t : std::uint8_t table = 10, }; #if defined(__GNUC__) && !defined(__clang__) -#pragma GCC diagnostic pop +# pragma GCC diagnostic pop #endif template From b8291af42bb8dbde1625998cd04f8b2c51807fa4 Mon Sep 17 00:00:00 2001 From: ToruNiina Date: Mon, 10 May 2021 22:56:16 +0900 Subject: [PATCH 13/22] fix: rename func args to avoid -Wshadow in GCC 4.x --- toml/region.hpp | 20 ++++----- toml/value.hpp | 112 ++++++++++++++++++++++++------------------------ 2 files changed, 66 insertions(+), 66 deletions(-) diff --git a/toml/region.hpp b/toml/region.hpp index 37ba3a3..2e01e51 100644 --- a/toml/region.hpp +++ b/toml/region.hpp @@ -73,13 +73,13 @@ struct location final : public region_base using difference_type = typename const_iterator::difference_type; using source_ptr = std::shared_ptr>; - location(std::string name, std::vector cont) + location(std::string source_name, std::vector cont) : source_(std::make_shared>(std::move(cont))), - line_number_(1), source_name_(std::move(name)), iter_(source_->cbegin()) + line_number_(1), source_name_(std::move(source_name)), iter_(source_->cbegin()) {} - location(std::string name, const std::string& cont) + location(std::string source_name, const std::string& cont) : source_(std::make_shared>(cont.begin(), cont.end())), - line_number_(1), source_name_(std::move(name)), iter_(source_->cbegin()) + line_number_(1), source_name_(std::move(source_name)), iter_(source_->cbegin()) {} location(const location&) = default; @@ -343,9 +343,9 @@ struct region final : public region_base })) { // unwrap the first '#' by std::next. - auto str = make_string(std::next(comment_found), iter); - if(!str.empty() && str.back() == '\r') {str.pop_back();} - com.push_back(std::move(str)); + auto s = make_string(std::next(comment_found), iter); + if(!s.empty() && s.back() == '\r') {s.pop_back();} + com.push_back(std::move(s)); } else { @@ -396,9 +396,9 @@ struct region final : public region_base })) { // unwrap the first '#' by std::next. - auto str = make_string(std::next(comment_found), this->line_end()); - if(!str.empty() && str.back() == '\r') {str.pop_back();} - com.push_back(std::move(str)); + auto s = make_string(std::next(comment_found), this->line_end()); + if(!s.empty() && s.back() == '\r') {s.pop_back();} + com.push_back(std::move(s)); } } } diff --git a/toml/value.hpp b/toml/value.hpp index f2e6c63..ed8c76e 100644 --- a/toml/value.hpp +++ b/toml/value.hpp @@ -281,9 +281,9 @@ class basic_value // overwrite comments ---------------------------------------------------- - basic_value(const basic_value& v, std::vector comments) + basic_value(const basic_value& v, std::vector com) : type_(v.type()), region_info_(v.region_info_), - comments_(std::move(comments)) + comments_(std::move(com)) { switch(v.type()) { @@ -301,9 +301,9 @@ class basic_value } } - basic_value(basic_value&& v, std::vector comments) + basic_value(basic_value&& v, std::vector com) : type_(v.type()), region_info_(std::move(v.region_info_)), - comments_(std::move(comments)) + comments_(std::move(com)) { switch(this->type_) // here this->type_ is already initialized { @@ -359,9 +359,9 @@ class basic_value template class T, template class A> - basic_value(const basic_value& v, std::vector comments) + basic_value(const basic_value& v, std::vector com) : type_(v.type()), region_info_(v.region_info_), - comments_(std::move(comments)) + comments_(std::move(com)) { switch(v.type()) { @@ -443,10 +443,10 @@ class basic_value assigner(this->boolean_, b); return *this; } - basic_value(boolean b, std::vector comments) + basic_value(boolean b, std::vector com) : type_(value_t::boolean), region_info_(std::make_shared(region_base{})), - comments_(std::move(comments)) + comments_(std::move(com)) { assigner(this->boolean_, b); } @@ -478,10 +478,10 @@ class basic_value template, detail::negation>>::value, std::nullptr_t>::type = nullptr> - basic_value(T i, std::vector comments) + basic_value(T i, std::vector com) : type_(value_t::integer), region_info_(std::make_shared(region_base{})), - comments_(std::move(comments)) + comments_(std::move(com)) { assigner(this->integer_, static_cast(i)); } @@ -511,10 +511,10 @@ class basic_value template::value, std::nullptr_t>::type = nullptr> - basic_value(T f, std::vector comments) + basic_value(T f, std::vector com) : type_(value_t::floating), region_info_(std::make_shared(region_base{})), - comments_(std::move(comments)) + comments_(std::move(com)) { assigner(this->floating_, f); } @@ -535,10 +535,10 @@ class basic_value assigner(this->string_, s); return *this; } - basic_value(toml::string s, std::vector comments) + basic_value(toml::string s, std::vector com) : type_(value_t::string), region_info_(std::make_shared(region_base{})), - comments_(std::move(comments)) + comments_(std::move(com)) { assigner(this->string_, std::move(s)); } @@ -563,17 +563,17 @@ class basic_value { assigner(this->string_, toml::string(std::move(s), kind)); } - basic_value(std::string s, std::vector comments) + basic_value(std::string s, std::vector com) : type_(value_t::string), region_info_(std::make_shared(region_base{})), - comments_(std::move(comments)) + comments_(std::move(com)) { assigner(this->string_, toml::string(std::move(s))); } - basic_value(std::string s, string_t kind, std::vector comments) + basic_value(std::string s, string_t kind, std::vector com) : type_(value_t::string), region_info_(std::make_shared(region_base{})), - comments_(std::move(comments)) + comments_(std::move(com)) { assigner(this->string_, toml::string(std::move(s), kind)); } @@ -598,17 +598,17 @@ class basic_value { assigner(this->string_, toml::string(std::string(s), kind)); } - basic_value(const char* s, std::vector comments) + basic_value(const char* s, std::vector com) : type_(value_t::string), region_info_(std::make_shared(region_base{})), - comments_(std::move(comments)) + comments_(std::move(com)) { assigner(this->string_, toml::string(std::string(s))); } - basic_value(const char* s, string_t kind, std::vector comments) + basic_value(const char* s, string_t kind, std::vector com) : type_(value_t::string), region_info_(std::make_shared(region_base{})), - comments_(std::move(comments)) + comments_(std::move(com)) { assigner(this->string_, toml::string(std::string(s), kind)); } @@ -628,10 +628,10 @@ class basic_value assigner(this->string_, toml::string(s)); return *this; } - basic_value(std::string_view s, std::vector comments) + basic_value(std::string_view s, std::vector com) : type_(value_t::string), region_info_(std::make_shared(region_base{})), - comments_(std::move(comments)) + comments_(std::move(com)) { assigner(this->string_, toml::string(s)); } @@ -641,10 +641,10 @@ class basic_value { assigner(this->string_, toml::string(s, kind)); } - basic_value(std::string_view s, string_t kind, std::vector comments) + basic_value(std::string_view s, string_t kind, std::vector com) : type_(value_t::string), region_info_(std::make_shared(region_base{})), - comments_(std::move(comments)) + comments_(std::move(com)) { assigner(this->string_, toml::string(s, kind)); } @@ -666,10 +666,10 @@ class basic_value assigner(this->local_date_, ld); return *this; } - basic_value(const local_date& ld, std::vector comments) + basic_value(const local_date& ld, std::vector com) : type_(value_t::local_date), region_info_(std::make_shared(region_base{})), - comments_(std::move(comments)) + comments_(std::move(com)) { assigner(this->local_date_, ld); } @@ -682,10 +682,10 @@ class basic_value { assigner(this->local_time_, lt); } - basic_value(const local_time& lt, std::vector comments) + basic_value(const local_time& lt, std::vector com) : type_(value_t::local_time), region_info_(std::make_shared(region_base{})), - comments_(std::move(comments)) + comments_(std::move(com)) { assigner(this->local_time_, lt); } @@ -707,10 +707,10 @@ class basic_value } template basic_value(const std::chrono::duration& dur, - std::vector comments) + std::vector com) : type_(value_t::local_time), region_info_(std::make_shared(region_base{})), - comments_(std::move(comments)) + comments_(std::move(com)) { assigner(this->local_time_, local_time(dur)); } @@ -732,10 +732,10 @@ class basic_value { assigner(this->local_datetime_, ldt); } - basic_value(const local_datetime& ldt, std::vector comments) + basic_value(const local_datetime& ldt, std::vector com) : type_(value_t::local_datetime), region_info_(std::make_shared(region_base{})), - comments_(std::move(comments)) + comments_(std::move(com)) { assigner(this->local_datetime_, ldt); } @@ -756,10 +756,10 @@ class basic_value { assigner(this->offset_datetime_, odt); } - basic_value(const offset_datetime& odt, std::vector comments) + basic_value(const offset_datetime& odt, std::vector com) : type_(value_t::offset_datetime), region_info_(std::make_shared(region_base{})), - comments_(std::move(comments)) + comments_(std::move(com)) { assigner(this->offset_datetime_, odt); } @@ -778,10 +778,10 @@ class basic_value assigner(this->offset_datetime_, offset_datetime(tp)); } basic_value(const std::chrono::system_clock::time_point& tp, - std::vector comments) + std::vector com) : type_(value_t::offset_datetime), region_info_(std::make_shared(region_base{})), - comments_(std::move(comments)) + comments_(std::move(com)) { assigner(this->offset_datetime_, offset_datetime(tp)); } @@ -802,10 +802,10 @@ class basic_value { assigner(this->array_, ary); } - basic_value(const array_type& ary, std::vector comments) + basic_value(const array_type& ary, std::vector com) : type_(value_t::array), region_info_(std::make_shared(region_base{})), - comments_(std::move(comments)) + comments_(std::move(com)) { assigner(this->array_, ary); } @@ -833,10 +833,10 @@ class basic_value template::value, std::nullptr_t>::type = nullptr> - basic_value(std::initializer_list list, std::vector comments) + basic_value(std::initializer_list list, std::vector com) : type_(value_t::array), region_info_(std::make_shared(region_base{})), - comments_(std::move(comments)) + comments_(std::move(com)) { array_type ary(list.begin(), list.end()); assigner(this->array_, std::move(ary)); @@ -876,10 +876,10 @@ class basic_value detail::negation>, detail::is_container >::value, std::nullptr_t>::type = nullptr> - basic_value(const T& list, std::vector comments) + basic_value(const T& list, std::vector com) : type_(value_t::array), region_info_(std::make_shared(region_base{})), - comments_(std::move(comments)) + comments_(std::move(com)) { static_assert(std::is_convertible::value, "elements of a container should be convertible to toml::value"); @@ -915,10 +915,10 @@ class basic_value { assigner(this->table_, tab); } - basic_value(const table_type& tab, std::vector comments) + basic_value(const table_type& tab, std::vector com) : type_(value_t::table), region_info_(std::make_shared(region_base{})), - comments_(std::move(comments)) + comments_(std::move(com)) { assigner(this->table_, tab); } @@ -943,10 +943,10 @@ class basic_value } basic_value(std::initializer_list> list, - std::vector comments) + std::vector com) : type_(value_t::table), region_info_(std::make_shared(region_base{})), - comments_(std::move(comments)) + comments_(std::move(com)) { table_type tab; for(const auto& elem : list) {tab[elem.first] = elem.second;} @@ -982,10 +982,10 @@ class basic_value detail::negation>, detail::is_map >::value, std::nullptr_t>::type = nullptr> - basic_value(const Map& mp, std::vector comments) + basic_value(const Map& mp, std::vector com) : type_(value_t::table), region_info_(std::make_shared(region_base{})), - comments_(std::move(comments)) + comments_(std::move(com)) { table_type tab; for(const auto& elem : mp) {tab[elem.first] = elem.second;} @@ -1017,8 +1017,8 @@ class basic_value template::value, std::nullptr_t>::type = nullptr> - basic_value(const T& ud, std::vector comments) - : basic_value(ud.into_toml(), std::move(comments)) + basic_value(const T& ud, std::vector com) + : basic_value(ud.into_toml(), std::move(com)) {} template::value, std::nullptr_t>::type = nullptr> @@ -1033,8 +1033,8 @@ class basic_value template)> basic_value(const T& ud): basic_value(::toml::into::into_toml(ud)) {} template)> - basic_value(const T& ud, std::vector comments) - : basic_value(::toml::into::into_toml(ud), std::move(comments)) + basic_value(const T& ud, std::vector com) + : basic_value(::toml::into::into_toml(ud), std::move(com)) {} template)> basic_value& operator=(const T& ud) @@ -1134,10 +1134,10 @@ class basic_value template::value, std::nullptr_t>::type = nullptr> - basic_value(std::pair parse_result, std::vector comments) + basic_value(std::pair parse_result, std::vector com) : basic_value(std::move(parse_result.first), std::move(parse_result.second), - std::move(comments)) + std::move(com)) {} // type checking and casting ============================================ From 7e9028217516fd7cd41f0ad26fd4c2f4b55ad639 Mon Sep 17 00:00:00 2001 From: ToruNiina Date: Mon, 10 May 2021 23:00:30 +0900 Subject: [PATCH 14/22] fix: add region where -Wshadow is ignored on GCC 4 --- toml/types.hpp | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/toml/types.hpp b/toml/types.hpp index a292d09..7bf4b2e 100644 --- a/toml/types.hpp +++ b/toml/types.hpp @@ -21,6 +21,11 @@ class basic_value; using character = char; using key = std::string; +#if !defined(__clang__) && defined(__GNUC__) && __GNUC__ <= 4 +# pragma GCC diagnostic push +# pragma GCC diagnostic ignored "-Wshadow" +#endif + using boolean = bool; using integer = std::int64_t; using floating = double; // "float" is a keyward, cannot use it here. @@ -32,6 +37,10 @@ using floating = double; // "float" is a keyward, cannot use it here. // - local_date // - local_time +#if defined(__GNUC__) && !defined(__clang__) +# pragma GCC diagnostic pop +#endif + // default toml::value and default array/table. these are defined after defining // basic_value itself. // using value = basic_value; From b6e2c6e235b18fcf581ff376363b273e789050f4 Mon Sep 17 00:00:00 2001 From: ToruNiina Date: Fri, 14 May 2021 15:46:00 +0900 Subject: [PATCH 15/22] feat: add detail::has_specialization_from/into --- toml/traits.hpp | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/toml/traits.hpp b/toml/traits.hpp index eafa6af..209856d 100644 --- a/toml/traits.hpp +++ b/toml/traits.hpp @@ -2,6 +2,10 @@ // Distributed under the MIT License. #ifndef TOML11_TRAITS_HPP #define TOML11_TRAITS_HPP + +#include "from.hpp" +#include "into.hpp" + #include #include #include @@ -84,6 +88,22 @@ struct has_into_toml_method_impl static std::false_type check(...); }; +struct has_specialized_from_impl +{ + template + static std::false_type check(...); + template + static std::true_type check(std::nullptr_t, std::size_t S = sizeof(::toml::from)); +}; +struct has_specialized_into_impl +{ + template + static std::false_type check(...); + template + static std::true_type check(std::nullptr_t, std::size_t S = sizeof(::toml::into)); +}; + + /// Intel C++ compiler can not use decltype in parent class declaration, here /// is a hack to work around it. https://stackoverflow.com/a/23953090/4692076 #ifdef __INTEL_COMPILER @@ -114,6 +134,11 @@ template struct has_into_toml_method : decltype(has_into_toml_method_impl::check(nullptr)){}; +template +struct has_specialized_from : decltype(has_specialized_from_impl::check(nullptr)){}; +template +struct has_specialized_into : decltype(has_specialized_into_impl::check(nullptr)){}; + #ifdef __INTEL_COMPILER #undef decltype #endif From 72ee8caf09ba7a6d79827614611ddd20001cf4b0 Mon Sep 17 00:00:00 2001 From: ToruNiina Date: Fri, 14 May 2021 15:53:34 +0900 Subject: [PATCH 16/22] refactor: use has_specialized_from to check if toml::from exists for a specific T --- toml/get.hpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/toml/get.hpp b/toml/get.hpp index 5095caf..9a5a855 100644 --- a/toml/get.hpp +++ b/toml/get.hpp @@ -255,9 +255,9 @@ get(const basic_value&); // toml::from::from_toml(v) template class M, template class V, - std::size_t S = sizeof(::toml::from)> -T get(const basic_value&); + template class M, template class V> +detail::enable_if_t::value, T> +get(const basic_value&); // T(const toml::value&) and T is not toml::basic_value template& v) return ud; } template class M, template class V, - std::size_t> -T get(const basic_value& v) + template class M, template class V> +detail::enable_if_t::value, T> +get(const basic_value& v) { return ::toml::from::from_toml(v); } From e62259542662551b1a67bebc5823fda3373423c4 Mon Sep 17 00:00:00 2001 From: ToruNiina Date: Fri, 14 May 2021 16:01:43 +0900 Subject: [PATCH 17/22] fix: fix has_specialized_from/into to avoid ambiguity --- toml/traits.hpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/toml/traits.hpp b/toml/traits.hpp index 209856d..0064e37 100644 --- a/toml/traits.hpp +++ b/toml/traits.hpp @@ -92,15 +92,15 @@ struct has_specialized_from_impl { template static std::false_type check(...); - template - static std::true_type check(std::nullptr_t, std::size_t S = sizeof(::toml::from)); + template)> + static std::true_type check(::toml::from*); }; struct has_specialized_into_impl { template static std::false_type check(...); - template - static std::true_type check(std::nullptr_t, std::size_t S = sizeof(::toml::into)); + template)> + static std::true_type check(::toml::from*); }; From 0ac3919e084307e2c6be0d1a549830cfe19aed31 Mon Sep 17 00:00:00 2001 From: ToruNiina Date: Fri, 14 May 2021 16:05:54 +0900 Subject: [PATCH 18/22] feat: from and from_toml precede constructor constructor sometimes has `template ctor(const T&)` and it causes ambiguity. To avoid it, from and T.from_toml precedes any constructor. But, to check the ambiguity between from and from_toml, they do not precede each other. If anyone define both from and from_toml, it causes compilation error. --- toml/get.hpp | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/toml/get.hpp b/toml/get.hpp index 9a5a855..a766f4a 100644 --- a/toml/get.hpp +++ b/toml/get.hpp @@ -259,12 +259,15 @@ template::value, T> get(const basic_value&); -// T(const toml::value&) and T is not toml::basic_value +// T(const toml::value&) and T is not toml::basic_value, +// and it does not have `from` nor `from_toml`. template class M, template class V> detail::enable_if_t>, - std::is_constructible&> + std::is_constructible&>, + detail::negation>, + detail::negation> >::value, T> get(const basic_value&); @@ -450,8 +453,10 @@ get(const basic_value& v) template class M, template class V> detail::enable_if_t>, - std::is_constructible&> + detail::negation>, // T is not a toml::value + std::is_constructible&>, // T is constructible from toml::value + detail::negation>, // and T does not have T.from_toml(v); + detail::negation> // and T does not have toml::from{}; >::value, T> get(const basic_value& v) { From 07c1d10212720e22de499429d8254ddd0fb08d9d Mon Sep 17 00:00:00 2001 From: ToruNiina Date: Fri, 14 May 2021 16:16:23 +0900 Subject: [PATCH 19/22] ci: avoid clang-9 + C++20 because it lacks <=> And the operator<=> is used in the (GNU-) standard library implementation installed by default. Note: consider using libc++ library --- .github/workflows/main.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 04ab80b..874886b 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -59,6 +59,7 @@ jobs: - {compiler: '6.0', standard: '20'} - {compiler: '7', standard: '20'} - {compiler: '8', standard: '20'} + - {compiler: '9', standard: '20'} steps: - name: Checkout uses: actions/checkout@v2 From 798856946f0c58f8cc7272d0f63769e10d904d96 Mon Sep 17 00:00:00 2001 From: ToruNiina Date: Fri, 14 May 2021 18:19:44 +0900 Subject: [PATCH 20/22] ci: add new compilers gcc 10, 11, clang 11 --- .github/workflows/main.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 874886b..9f31914 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -8,7 +8,7 @@ jobs: strategy: matrix: # g++-4.8 and 4.9 are tested on Travis.CI. - compiler: ['g++-9', 'g++-8', 'g++-7', 'g++-6', 'g++-5'] + compiler: ['g++-11', 'g++-10', 'g++-9', 'g++-8', 'g++-7', 'g++-6', 'g++-5'] standard: ['11', '14', '17', '20'] exclude: - {compiler: 'g++-5', standard: '17'} @@ -47,7 +47,7 @@ jobs: runs-on: Ubuntu-18.04 strategy: matrix: - compiler: ['10', '9', '8', '7', '6.0', '5.0', '4.0', '3.9'] + compiler: ['11', '10', '9', '8', '7', '6.0', '5.0', '4.0', '3.9'] standard: ['11', '14', '17', '20'] exclude: - {compiler: '3.9', standard: '17'} From 287be5a5757676c44c73900542d76617acad439b Mon Sep 17 00:00:00 2001 From: ToruNiina Date: Fri, 14 May 2021 18:25:29 +0900 Subject: [PATCH 21/22] ci: clang11 is too new to install it without adding a new ppa --- .github/workflows/main.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 9f31914..2a20744 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -47,7 +47,7 @@ jobs: runs-on: Ubuntu-18.04 strategy: matrix: - compiler: ['11', '10', '9', '8', '7', '6.0', '5.0', '4.0', '3.9'] + compiler: ['10', '9', '8', '7', '6.0', '5.0', '4.0', '3.9'] standard: ['11', '14', '17', '20'] exclude: - {compiler: '3.9', standard: '17'} From 392a260db83e597d849d32b92dfd7ebc7606a5ee Mon Sep 17 00:00:00 2001 From: ToruNiina Date: Sat, 15 May 2021 00:24:51 +0900 Subject: [PATCH 22/22] doc: write about precedence --- README.md | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index d5bc1c8..5f5040f 100644 --- a/README.md +++ b/README.md @@ -1255,8 +1255,16 @@ struct from In this way, since the conversion function is defined outside of the class, you can add conversion between `toml::value` and classes defined in another library. -Note that you cannot implement both of the functions because the overload -resolution of `toml::get` will be ambiguous. +In some cases, a class has a templatized constructor that takes a template, `T`. +It confuses `toml::get/find` because it makes the class "constructible" from +`toml::value`. To avoid this problem, `toml::from` and `from_toml` always +precede constructor. It makes easier to implement conversion between +`toml::value` and types defined in other libraries because it skips constructor. + +But, importantly, you cannot define `toml::from` and `T.from_toml` at the same +time because it causes ambiguity in the overload resolution of `toml::get` and `toml::find`. + +So the precedence is `toml::from` == `T.from_toml()` > `T(toml::value)`. If you want to convert any versions of `toml::basic_value`, you need to templatize the conversion function as follows.