From f15d447522205cbdc253acde57028bb69fce14ff Mon Sep 17 00:00:00 2001 From: Niels Lohmann Date: Sat, 26 Dec 2020 14:55:19 +0100 Subject: [PATCH 01/14] :rotating_light: fix warnings --- include/nlohmann/detail/input/binary_reader.hpp | 2 +- single_include/nlohmann/json.hpp | 2 +- test/src/unit-class_lexer.cpp | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/include/nlohmann/detail/input/binary_reader.hpp b/include/nlohmann/detail/input/binary_reader.hpp index 6ae5882c7..6590470da 100644 --- a/include/nlohmann/detail/input/binary_reader.hpp +++ b/include/nlohmann/detail/input/binary_reader.hpp @@ -2340,7 +2340,7 @@ class binary_reader break; } result.push_back(static_cast(current)); - }; + } return success; } diff --git a/single_include/nlohmann/json.hpp b/single_include/nlohmann/json.hpp index 9e6f6012d..676905a01 100644 --- a/single_include/nlohmann/json.hpp +++ b/single_include/nlohmann/json.hpp @@ -10065,7 +10065,7 @@ class binary_reader break; } result.push_back(static_cast(current)); - }; + } return success; } diff --git a/test/src/unit-class_lexer.cpp b/test/src/unit-class_lexer.cpp index 1a4f8ed75..07d243a81 100644 --- a/test/src/unit-class_lexer.cpp +++ b/test/src/unit-class_lexer.cpp @@ -135,7 +135,7 @@ TEST_CASE("lexer class") // store scan() result const auto res = scan_string(s.c_str()); - CAPTURE(s); + CAPTURE(s) switch (c) { From dfedefb99369dabc86e307ba7edaeb4e9116720d Mon Sep 17 00:00:00 2001 From: Niels Lohmann Date: Sat, 26 Dec 2020 17:56:16 +0100 Subject: [PATCH 02/14] :rotating_light: fix warnings --- include/nlohmann/detail/hash.hpp | 2 ++ include/nlohmann/detail/input/binary_reader.hpp | 1 + .../nlohmann/detail/iterators/primitive_iterator.hpp | 2 ++ include/nlohmann/detail/meta/type_traits.hpp | 1 + include/nlohmann/thirdparty/hedley/hedley_undef.hpp | 2 ++ single_include/nlohmann/json.hpp | 10 ++++++++++ 6 files changed, 18 insertions(+) diff --git a/include/nlohmann/detail/hash.hpp b/include/nlohmann/detail/hash.hpp index d2d5d332d..c32d5535c 100644 --- a/include/nlohmann/detail/hash.hpp +++ b/include/nlohmann/detail/hash.hpp @@ -3,6 +3,8 @@ #include // size_t, uint8_t #include // hash +#include + namespace nlohmann { namespace detail diff --git a/include/nlohmann/detail/input/binary_reader.hpp b/include/nlohmann/detail/input/binary_reader.hpp index 6590470da..806e36030 100644 --- a/include/nlohmann/detail/input/binary_reader.hpp +++ b/include/nlohmann/detail/input/binary_reader.hpp @@ -11,6 +11,7 @@ #include // numeric_limits #include // char_traits, string #include // make_pair, move +#include // vector #include #include diff --git a/include/nlohmann/detail/iterators/primitive_iterator.hpp b/include/nlohmann/detail/iterators/primitive_iterator.hpp index 16dcc9f97..ae7471ef5 100644 --- a/include/nlohmann/detail/iterators/primitive_iterator.hpp +++ b/include/nlohmann/detail/iterators/primitive_iterator.hpp @@ -3,6 +3,8 @@ #include // ptrdiff_t #include // numeric_limits +#include + namespace nlohmann { namespace detail diff --git a/include/nlohmann/detail/meta/type_traits.hpp b/include/nlohmann/detail/meta/type_traits.hpp index 56c15a3f6..1706cbdc6 100644 --- a/include/nlohmann/detail/meta/type_traits.hpp +++ b/include/nlohmann/detail/meta/type_traits.hpp @@ -3,6 +3,7 @@ #include // numeric_limits #include // false_type, is_constructible, is_integral, is_same, true_type #include // declval +#include // tuple #include #include diff --git a/include/nlohmann/thirdparty/hedley/hedley_undef.hpp b/include/nlohmann/thirdparty/hedley/hedley_undef.hpp index 88ee044da..2f70f13c6 100644 --- a/include/nlohmann/thirdparty/hedley/hedley_undef.hpp +++ b/include/nlohmann/thirdparty/hedley/hedley_undef.hpp @@ -1,3 +1,5 @@ +#pragma once + #undef JSON_HEDLEY_ALWAYS_INLINE #undef JSON_HEDLEY_ARM_VERSION #undef JSON_HEDLEY_ARM_VERSION_CHECK diff --git a/single_include/nlohmann/json.hpp b/single_include/nlohmann/json.hpp index 676905a01..51fe8382b 100644 --- a/single_include/nlohmann/json.hpp +++ b/single_include/nlohmann/json.hpp @@ -2818,6 +2818,7 @@ constexpr T static_const::value; #include // numeric_limits #include // false_type, is_constructible, is_integral, is_same, true_type #include // declval +#include // tuple // #include @@ -4671,6 +4672,9 @@ class byte_container_with_subtype : public BinaryType #include // size_t, uint8_t #include // hash +// #include + + namespace nlohmann { namespace detail @@ -4799,6 +4803,7 @@ std::size_t hash(const BasicJsonType& j) #include // numeric_limits #include // char_traits, string #include // make_pair, move +#include // vector // #include @@ -10707,6 +10712,9 @@ class parser #include // ptrdiff_t #include // numeric_limits +// #include + + namespace nlohmann { namespace detail @@ -25410,6 +25418,8 @@ inline nlohmann::json::json_pointer operator "" _json_pointer(const char* s, std #undef JSON_EXPLICIT // #include + + #undef JSON_HEDLEY_ALWAYS_INLINE #undef JSON_HEDLEY_ARM_VERSION #undef JSON_HEDLEY_ARM_VERSION_CHECK From 5dd06714b13b375acdc987b9261679d0c331b9ed Mon Sep 17 00:00:00 2001 From: Niels Lohmann Date: Mon, 28 Dec 2020 11:31:21 +0100 Subject: [PATCH 03/14] :bug: allow parsing from std::byte containers #2546 --- include/nlohmann/detail/input/lexer.hpp | 6 +++--- single_include/nlohmann/json.hpp | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/include/nlohmann/detail/input/lexer.hpp b/include/nlohmann/detail/input/lexer.hpp index 0a9601352..eae82eaa3 100644 --- a/include/nlohmann/detail/input/lexer.hpp +++ b/include/nlohmann/detail/input/lexer.hpp @@ -1541,17 +1541,17 @@ scan_number_done: // literals case 't': { - std::array true_literal = {{'t', 'r', 'u', 'e'}}; + std::array true_literal = {{char_type('t'), char_type('r'), char_type('u'), char_type('e')}}; return scan_literal(true_literal.data(), true_literal.size(), token_type::literal_true); } case 'f': { - std::array false_literal = {{'f', 'a', 'l', 's', 'e'}}; + std::array false_literal = {{char_type('f'), char_type('a'), char_type('l'), char_type('s'), char_type('e')}}; return scan_literal(false_literal.data(), false_literal.size(), token_type::literal_false); } case 'n': { - std::array null_literal = {{'n', 'u', 'l', 'l'}}; + std::array null_literal = {{char_type('n'), char_type('u'), char_type('l'), char_type('l')}}; return scan_literal(null_literal.data(), null_literal.size(), token_type::literal_null); } diff --git a/single_include/nlohmann/json.hpp b/single_include/nlohmann/json.hpp index 51fe8382b..539ebc7ad 100644 --- a/single_include/nlohmann/json.hpp +++ b/single_include/nlohmann/json.hpp @@ -7511,17 +7511,17 @@ scan_number_done: // literals case 't': { - std::array true_literal = {{'t', 'r', 'u', 'e'}}; + std::array true_literal = {{char_type('t'), char_type('r'), char_type('u'), char_type('e')}}; return scan_literal(true_literal.data(), true_literal.size(), token_type::literal_true); } case 'f': { - std::array false_literal = {{'f', 'a', 'l', 's', 'e'}}; + std::array false_literal = {{char_type('f'), char_type('a'), char_type('l'), char_type('s'), char_type('e')}}; return scan_literal(false_literal.data(), false_literal.size(), token_type::literal_false); } case 'n': { - std::array null_literal = {{'n', 'u', 'l', 'l'}}; + std::array null_literal = {{char_type('n'), char_type('u'), char_type('l'), char_type('l')}}; return scan_literal(null_literal.data(), null_literal.size(), token_type::literal_null); } From 467f622c65daaabc71ca0572c2a9764d0a187197 Mon Sep 17 00:00:00 2001 From: Jaakko Moisio Date: Mon, 28 Dec 2020 22:20:37 +0100 Subject: [PATCH 04/14] Fix compilation of input_adapter(container) in edge cases This fixes a compilation issue with the library if trying to use containers that don't have non-member `begin()` and `end()` functions via ADL. This patch extends the `using std::begin` and `using std::end` declarations to also cover the return type deduction of the input_adapter() template specialization for containers. The previous implementation only enabled the detection of `std::begin()` and `std::end()` in the function body, making the specialization unusable for container types that only have member `begin()` and `end()` functions. It is not typical to have `using` declarations in the namespace scope in a header file. But a C++11 implementation can't rely on fully automatic return type deduction, and needs to rely on ADL enabled helper templates. To prevent the using declarations leaking, they are enclosed in another nested namespace. --- .../nlohmann/detail/input/input_adapters.hpp | 35 +++++++++++++---- single_include/nlohmann/json.hpp | 39 ++++++++++++++----- test/src/unit-user_defined_input.cpp | 27 ++++++++++++- 3 files changed, 84 insertions(+), 17 deletions(-) diff --git a/include/nlohmann/detail/input/input_adapters.hpp b/include/nlohmann/detail/input/input_adapters.hpp index 63921ca55..eed370fd2 100644 --- a/include/nlohmann/detail/input/input_adapters.hpp +++ b/include/nlohmann/detail/input/input_adapters.hpp @@ -371,14 +371,35 @@ typename iterator_input_adapter_factory::adapter_type input_adapte } // Convenience shorthand from container to iterator -template -auto input_adapter(const ContainerType& container) -> decltype(input_adapter(begin(container), end(container))) -{ - // Enable ADL - using std::begin; - using std::end; +// Enables ADL on begin(container) and end(container) +// Encloses the using declarations in namespace for not to leak them to outside scope - return input_adapter(begin(container), end(container)); +namespace container_input_adapter_factory_impl { + +using std::begin; +using std::end; + +template +struct container_input_adapter_factory {}; + +template +struct container_input_adapter_factory< ContainerType, + void_t()), end(std::declval()))> > +{ + using adapter_type = decltype(input_adapter(begin(std::declval()), end(std::declval()))); + + static adapter_type create(const ContainerType& container) + { + return input_adapter(begin(container), end(container)); + } +}; + +} + +template +typename container_input_adapter_factory_impl::container_input_adapter_factory::adapter_type input_adapter(const ContainerType& container) +{ + return container_input_adapter_factory_impl::container_input_adapter_factory::create(container); } // Special cases with fast paths diff --git a/single_include/nlohmann/json.hpp b/single_include/nlohmann/json.hpp index 51fe8382b..a919b8d6c 100644 --- a/single_include/nlohmann/json.hpp +++ b/single_include/nlohmann/json.hpp @@ -5183,14 +5183,35 @@ typename iterator_input_adapter_factory::adapter_type input_adapte } // Convenience shorthand from container to iterator -template -auto input_adapter(const ContainerType& container) -> decltype(input_adapter(begin(container), end(container))) -{ - // Enable ADL - using std::begin; - using std::end; +// Enables ADL on begin(container) and end(container) +// Encloses the using declarations in namespace for not to leak them to outside scope - return input_adapter(begin(container), end(container)); +namespace container_input_adapter_factory_impl { + +using std::begin; +using std::end; + +template +struct container_input_adapter_factory {}; + +template +struct container_input_adapter_factory< ContainerType, + void_t()), end(std::declval()))> > +{ + using adapter_type = decltype(input_adapter(begin(std::declval()), end(std::declval()))); + + static adapter_type create(const ContainerType& container) + { + return input_adapter(begin(container), end(container)); + } +}; + +} + +template +typename container_input_adapter_factory_impl::container_input_adapter_factory::adapter_type input_adapter(const ContainerType& container) +{ + return container_input_adapter_factory_impl::container_input_adapter_factory::create(container); } // Special cases with fast paths @@ -16801,7 +16822,7 @@ class basic_json detail::parser_callback_tcb = nullptr, const bool allow_exceptions = true, const bool ignore_comments = false - ) + ) { return ::nlohmann::detail::parser(std::move(adapter), std::move(cb), allow_exceptions, ignore_comments); @@ -25346,7 +25367,7 @@ template<> inline void swap(nlohmann::json& j1, nlohmann::json& j2) noexcept( is_nothrow_move_constructible::value&& is_nothrow_move_assignable::value - ) +) { j1.swap(j2); } diff --git a/test/src/unit-user_defined_input.cpp b/test/src/unit-user_defined_input.cpp index 5a1138b00..4b84e8e71 100644 --- a/test/src/unit-user_defined_input.cpp +++ b/test/src/unit-user_defined_input.cpp @@ -63,7 +63,7 @@ const char* end(const MyContainer& c) return c.data + strlen(c.data); } -TEST_CASE("Custom container") +TEST_CASE("Custom container non-member begin/end") { MyContainer data{"[1,2,3,4]"}; @@ -75,6 +75,31 @@ TEST_CASE("Custom container") } +TEST_CASE("Custom container member begin/end") +{ + struct MyContainer2 + { + const char* data; + + const char* begin() const + { + return data; + } + + const char* end() const + { + return data + strlen(data); + } + }; + + MyContainer2 data{"[1,2,3,4]"}; + json as_json = json::parse(data); + CHECK(as_json.at(0) == 1); + CHECK(as_json.at(1) == 2); + CHECK(as_json.at(2) == 3); + CHECK(as_json.at(3) == 4); +} + TEST_CASE("Custom iterator") { const char* raw_data = "[1,2,3,4]"; From 7b98df515f26058308f1ea5eedb6d1525cd12630 Mon Sep 17 00:00:00 2001 From: Niels Lohmann Date: Tue, 29 Dec 2020 14:48:18 +0100 Subject: [PATCH 05/14] :white_check_mark: add regression test --- .travis.yml | 10 ++++++++++ test/src/unit-regression2.cpp | 14 ++++++++++++++ 2 files changed, 24 insertions(+) diff --git a/.travis.yml b/.travis.yml index f48ee1fd6..c671e93f6 100644 --- a/.travis.yml +++ b/.travis.yml @@ -300,6 +300,16 @@ matrix: sources: ['ubuntu-toolchain-r-test', 'llvm-toolchain-trusty-7'] packages: ['g++-7', 'clang-7', 'ninja-build'] + - os: linux + compiler: clang + env: + - COMPILER=clang++-7 + - CXX_STANDARD=20 + addons: + apt: + sources: ['ubuntu-toolchain-r-test', 'llvm-toolchain-trusty-7'] + packages: ['g++-7', 'clang-7', 'ninja-build'] + ################ # build script # ################ diff --git a/test/src/unit-regression2.cpp b/test/src/unit-regression2.cpp index ca50cdd41..1171531f6 100644 --- a/test/src/unit-regression2.cpp +++ b/test/src/unit-regression2.cpp @@ -51,6 +51,10 @@ using nlohmann::json; #include #endif +#ifdef JSON_HAS_CPP_20 + #include +#endif + ///////////////////////////////////////////////////////////////////// // for #1021 ///////////////////////////////////////////////////////////////////// @@ -484,4 +488,14 @@ TEST_CASE("regression tests 2") json j = json::parse(ss, nullptr, true, true); CHECK(j.dump() == "{}"); } + +#ifdef JSON_HAS_CPP_20 + SECTION("issue #2546 - parsing containers of std::byte") + { + const char DATA[] = R"("Hello, world!")"; + const auto s = std::as_bytes(std::span(DATA)); + json j = json::parse(s); + CHECK(j.dump == "Hello, world!"); + } +#endif } From 433da313341430cf32b26f2bcdadbb67e9465ced Mon Sep 17 00:00:00 2001 From: Niels Lohmann Date: Tue, 29 Dec 2020 20:16:51 +0100 Subject: [PATCH 06/14] :alembic: try to use GCC 10 --- .github/workflows/ubuntu.yml | 8 ++++++ .travis.yml | 10 -------- .../nlohmann/detail/iterators/iter_impl.hpp | 25 ++++++++++++++++++- single_include/nlohmann/json.hpp | 25 ++++++++++++++++++- test/src/unit-class_parser.cpp | 2 +- test/src/unit-items.cpp | 8 ++++++ test/src/unit-regression1.cpp | 2 +- test/src/unit-udt.cpp | 14 +++++------ 8 files changed, 73 insertions(+), 21 deletions(-) diff --git a/.github/workflows/ubuntu.yml b/.github/workflows/ubuntu.yml index 1a47a885c..a4742e6a1 100644 --- a/.github/workflows/ubuntu.yml +++ b/.github/workflows/ubuntu.yml @@ -8,8 +8,16 @@ jobs: steps: - uses: actions/checkout@v1 + - name: install_gcc + run: | + sudo apt update + sudo apt install gcc-10 g++-10 + shell: bash - name: cmake run: cmake -S . -B build -D CMAKE_BUILD_TYPE=Debug -DJSON_BuildTests=On + env: + CC: gcc-10 + CXX: g++-10 - name: build run: cmake --build build --parallel 10 - name: test diff --git a/.travis.yml b/.travis.yml index c671e93f6..f48ee1fd6 100644 --- a/.travis.yml +++ b/.travis.yml @@ -300,16 +300,6 @@ matrix: sources: ['ubuntu-toolchain-r-test', 'llvm-toolchain-trusty-7'] packages: ['g++-7', 'clang-7', 'ninja-build'] - - os: linux - compiler: clang - env: - - COMPILER=clang++-7 - - CXX_STANDARD=20 - addons: - apt: - sources: ['ubuntu-toolchain-r-test', 'llvm-toolchain-trusty-7'] - packages: ['g++-7', 'clang-7', 'ninja-build'] - ################ # build script # ################ diff --git a/include/nlohmann/detail/iterators/iter_impl.hpp b/include/nlohmann/detail/iterators/iter_impl.hpp index b4faa88a5..6c65c6018 100644 --- a/include/nlohmann/detail/iterators/iter_impl.hpp +++ b/include/nlohmann/detail/iterators/iter_impl.hpp @@ -393,7 +393,30 @@ class iter_impl @brief comparison: equal @pre The iterator is initialized; i.e. `m_object != nullptr`. */ - bool operator==(const iter_impl& other) const + bool operator==(const iter_impl& other) const + { + // if objects are not the same, the comparison is undefined + if (JSON_HEDLEY_UNLIKELY(m_object != other.m_object)) + { + JSON_THROW(invalid_iterator::create(212, "cannot compare iterators of different containers")); + } + + JSON_ASSERT(m_object != nullptr); + + switch (m_object->m_type) + { + case value_t::object: + return (m_it.object_iterator == other.m_it.object_iterator); + + case value_t::array: + return (m_it.array_iterator == other.m_it.array_iterator); + + default: + return (m_it.primitive_iterator == other.m_it.primitive_iterator); + } + } + + bool operator==(const iter_impl::type>& other) const { // if objects are not the same, the comparison is undefined if (JSON_HEDLEY_UNLIKELY(m_object != other.m_object)) diff --git a/single_include/nlohmann/json.hpp b/single_include/nlohmann/json.hpp index 765eac810..ac0568ce9 100644 --- a/single_include/nlohmann/json.hpp +++ b/single_include/nlohmann/json.hpp @@ -11279,7 +11279,30 @@ class iter_impl @brief comparison: equal @pre The iterator is initialized; i.e. `m_object != nullptr`. */ - bool operator==(const iter_impl& other) const + bool operator==(const iter_impl& other) const + { + // if objects are not the same, the comparison is undefined + if (JSON_HEDLEY_UNLIKELY(m_object != other.m_object)) + { + JSON_THROW(invalid_iterator::create(212, "cannot compare iterators of different containers")); + } + + JSON_ASSERT(m_object != nullptr); + + switch (m_object->m_type) + { + case value_t::object: + return (m_it.object_iterator == other.m_it.object_iterator); + + case value_t::array: + return (m_it.array_iterator == other.m_it.array_iterator); + + default: + return (m_it.primitive_iterator == other.m_it.primitive_iterator); + } + } + + bool operator==(const iter_impl::type>& other) const { // if objects are not the same, the comparison is undefined if (JSON_HEDLEY_UNLIKELY(m_object != other.m_object)) diff --git a/test/src/unit-class_parser.cpp b/test/src/unit-class_parser.cpp index d0335c948..c612daabc 100644 --- a/test/src/unit-class_parser.cpp +++ b/test/src/unit-class_parser.cpp @@ -509,7 +509,7 @@ TEST_CASE("parser class") CHECK(parser_helper("\"€\"").get() == "€"); CHECK(parser_helper("\"🎈\"").get() == "🎈"); - CHECK(parser_helper("\"\\ud80c\\udc60\"").get() == u8"\U00013060"); + CHECK(parser_helper("\"\\ud80c\\udc60\"").get() == "\U00013060"); CHECK(parser_helper("\"\\ud83c\\udf1e\"").get() == "🌞"); } } diff --git a/test/src/unit-items.cpp b/test/src/unit-items.cpp index 10621ce7e..4caf76f23 100644 --- a/test/src/unit-items.cpp +++ b/test/src/unit-items.cpp @@ -1448,3 +1448,11 @@ TEST_CASE("items()") } } } + +#ifdef JSON_HAS_CPP_17 + #undef JSON_HAS_CPP_17 +#endif + +#ifdef JSON_HAS_CPP_14 + #undef JSON_HAS_CPP_14 +#endif diff --git a/test/src/unit-regression1.cpp b/test/src/unit-regression1.cpp index 9dcc75b09..f5520056f 100644 --- a/test/src/unit-regression1.cpp +++ b/test/src/unit-regression1.cpp @@ -400,7 +400,7 @@ TEST_CASE("regression tests 1") SECTION("issue #146 - character following a surrogate pair is skipped") { - CHECK(json::parse("\"\\ud80c\\udc60abc\"").get() == u8"\U00013060abc"); + CHECK(json::parse("\"\\ud80c\\udc60abc\"").get() == "\U00013060abc"); } SECTION("issue #171 - Cannot index by key of type static constexpr const char*") diff --git a/test/src/unit-udt.cpp b/test/src/unit-udt.cpp index 7f74ac5f8..b23765505 100644 --- a/test/src/unit-udt.cpp +++ b/test/src/unit-udt.cpp @@ -112,13 +112,13 @@ static void to_json(BasicJsonType& j, country c) switch (c) { case country::china: - j = u8"中华人民共和国"; + j = "中华人民共和国"; return; case country::france: j = "France"; return; case country::russia: - j = u8"Российская Федерация"; + j = "Российская Федерация"; return; default: break; @@ -201,9 +201,9 @@ static void from_json(const BasicJsonType& j, country& c) const auto str = j.template get(); static const std::map m = { - {u8"中华人民共和国", country::china}, + {"中华人民共和国", country::china}, {"France", country::france}, - {u8"Российская Федерация", country::russia} + {"Российская Федерация", country::russia} }; const auto it = m.find(str); @@ -248,7 +248,7 @@ TEST_CASE("basic usage" * doctest::test_suite("udt")) const udt::name n{"theo"}; const udt::country c{udt::country::france}; const udt::person sfinae_addict{a, n, c}; - const udt::person senior_programmer{{42}, {u8"王芳"}, udt::country::china}; + const udt::person senior_programmer{{42}, {"王芳"}, udt::country::china}; const udt::address addr{"Paris"}; const udt::contact cpp_programmer{sfinae_addict, addr}; const udt::contact_book book{{"C++"}, {cpp_programmer, {senior_programmer, addr}}}; @@ -265,14 +265,14 @@ TEST_CASE("basic usage" * doctest::test_suite("udt")) CHECK( json(book) == - u8R"({"name":"C++", "contacts" : [{"person" : {"age":23, "name":"theo", "country":"France"}, "address":"Paris"}, {"person" : {"age":42, "country":"中华人民共和国", "name":"王芳"}, "address":"Paris"}]})"_json); + R"({"name":"C++", "contacts" : [{"person" : {"age":23, "name":"theo", "country":"France"}, "address":"Paris"}, {"person" : {"age":42, "country":"中华人民共和国", "name":"王芳"}, "address":"Paris"}]})"_json); } SECTION("conversion from json via free-functions") { const auto big_json = - u8R"({"name":"C++", "contacts" : [{"person" : {"age":23, "name":"theo", "country":"France"}, "address":"Paris"}, {"person" : {"age":42, "country":"中华人民共和国", "name":"王芳"}, "address":"Paris"}]})"_json; + R"({"name":"C++", "contacts" : [{"person" : {"age":23, "name":"theo", "country":"France"}, "address":"Paris"}, {"person" : {"age":42, "country":"中华人民共和国", "name":"王芳"}, "address":"Paris"}]})"_json; SECTION("via explicit calls to get") { const auto parsed_book = big_json.get(); From ca51dc62f2a37be1a4f54a069850ffb80091a1e4 Mon Sep 17 00:00:00 2001 From: Niels Lohmann Date: Tue, 29 Dec 2020 20:21:43 +0100 Subject: [PATCH 07/14] :alembic: try to use Clang 10 --- .github/workflows/ubuntu.yml | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/.github/workflows/ubuntu.yml b/.github/workflows/ubuntu.yml index a4742e6a1..9792431ff 100644 --- a/.github/workflows/ubuntu.yml +++ b/.github/workflows/ubuntu.yml @@ -3,7 +3,7 @@ name: Ubuntu on: [push, pull_request] jobs: - build: + gcc_build: runs-on: ubuntu-latest steps: @@ -22,3 +22,23 @@ jobs: run: cmake --build build --parallel 10 - name: test run: cd build ; ctest -j 10 --output-on-failure + + clang_build: + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v1 + - name: install_gcc + run: | + sudo apt update + sudo apt install clang-10 + shell: bash + - name: cmake + run: cmake -S . -B build -D CMAKE_BUILD_TYPE=Debug -DJSON_BuildTests=On + env: + CC: clang-10 + CXX: clang++-10 + - name: build + run: cmake --build build --parallel 10 + - name: test + run: cd build ; ctest -j 10 --output-on-failure From 91d7aa571fbeb991813afd327ad005def52e7a0a Mon Sep 17 00:00:00 2001 From: Niels Lohmann Date: Tue, 29 Dec 2020 20:30:50 +0100 Subject: [PATCH 08/14] :alembic: add C++20 build --- .github/workflows/ubuntu.yml | 40 ++++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/.github/workflows/ubuntu.yml b/.github/workflows/ubuntu.yml index 9792431ff..58fdbd88f 100644 --- a/.github/workflows/ubuntu.yml +++ b/.github/workflows/ubuntu.yml @@ -42,3 +42,43 @@ jobs: run: cmake --build build --parallel 10 - name: test run: cd build ; ctest -j 10 --output-on-failure + + gcc_build_cxx20: + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v1 + - name: install_gcc + run: | + sudo apt update + sudo apt install gcc-10 g++-10 + shell: bash + - name: cmake + run: cmake -S . -B build -D CMAKE_BUILD_TYPE=Debug -DJSON_BuildTests=On -DCMAKE_CXX_STANDARD=20 -DCMAKE_CXX_STANDARD_REQUIRED=ON + env: + CC: gcc-10 + CXX: g++-10 + - name: build + run: cmake --build build --parallel 10 + - name: test + run: cd build ; ctest -j 10 --output-on-failure + + clang_build_cxx20: + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v1 + - name: install_gcc + run: | + sudo apt update + sudo apt install clang-10 + shell: bash + - name: cmake + run: cmake -S . -B build -D CMAKE_BUILD_TYPE=Debug -DJSON_BuildTests=On -DCMAKE_CXX_STANDARD=20 -DCMAKE_CXX_STANDARD_REQUIRED=ON + env: + CC: clang-10 + CXX: clang++-10 + - name: build + run: cmake --build build --parallel 10 + - name: test + run: cd build ; ctest -j 10 --output-on-failure From 77be4f6aaf2b72cf3f3ca16fce8abd3367bdc1e5 Mon Sep 17 00:00:00 2001 From: Niels Lohmann Date: Tue, 29 Dec 2020 20:32:07 +0100 Subject: [PATCH 09/14] :alembic: add C++20 build --- .github/workflows/ubuntu.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ubuntu.yml b/.github/workflows/ubuntu.yml index 58fdbd88f..711cf106d 100644 --- a/.github/workflows/ubuntu.yml +++ b/.github/workflows/ubuntu.yml @@ -54,7 +54,7 @@ jobs: sudo apt install gcc-10 g++-10 shell: bash - name: cmake - run: cmake -S . -B build -D CMAKE_BUILD_TYPE=Debug -DJSON_BuildTests=On -DCMAKE_CXX_STANDARD=20 -DCMAKE_CXX_STANDARD_REQUIRED=ON + run: cmake -S . -B build -D CMAKE_BUILD_TYPE=Debug -DJSON_BuildTests=On -DCMAKE_CXX_STANDARD=20 -DCMAKE_CXX_STANDARD_REQUIRED=ON env: CC: gcc-10 CXX: g++-10 From e4fc598466cffa49953f299c4de4a06f1c9a7392 Mon Sep 17 00:00:00 2001 From: Niels Lohmann Date: Tue, 29 Dec 2020 20:45:56 +0100 Subject: [PATCH 10/14] :alembic: add C++20 build --- .github/workflows/ubuntu.yml | 20 -------------------- test/src/unit-regression2.cpp | 2 +- 2 files changed, 1 insertion(+), 21 deletions(-) diff --git a/.github/workflows/ubuntu.yml b/.github/workflows/ubuntu.yml index 711cf106d..d6b654077 100644 --- a/.github/workflows/ubuntu.yml +++ b/.github/workflows/ubuntu.yml @@ -43,26 +43,6 @@ jobs: - name: test run: cd build ; ctest -j 10 --output-on-failure - gcc_build_cxx20: - runs-on: ubuntu-latest - - steps: - - uses: actions/checkout@v1 - - name: install_gcc - run: | - sudo apt update - sudo apt install gcc-10 g++-10 - shell: bash - - name: cmake - run: cmake -S . -B build -D CMAKE_BUILD_TYPE=Debug -DJSON_BuildTests=On -DCMAKE_CXX_STANDARD=20 -DCMAKE_CXX_STANDARD_REQUIRED=ON - env: - CC: gcc-10 - CXX: g++-10 - - name: build - run: cmake --build build --parallel 10 - - name: test - run: cd build ; ctest -j 10 --output-on-failure - clang_build_cxx20: runs-on: ubuntu-latest diff --git a/test/src/unit-regression2.cpp b/test/src/unit-regression2.cpp index 1171531f6..86320f039 100644 --- a/test/src/unit-regression2.cpp +++ b/test/src/unit-regression2.cpp @@ -495,7 +495,7 @@ TEST_CASE("regression tests 2") const char DATA[] = R"("Hello, world!")"; const auto s = std::as_bytes(std::span(DATA)); json j = json::parse(s); - CHECK(j.dump == "Hello, world!"); + CHECK(j.dump() == "Hello, world!"); } #endif } From 4402176df5e1aec1c77b19f973b4575c7e526dcd Mon Sep 17 00:00:00 2001 From: Niels Lohmann Date: Tue, 29 Dec 2020 20:52:57 +0100 Subject: [PATCH 11/14] :white_check_mark: add regression test --- test/src/unit-regression2.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/src/unit-regression2.cpp b/test/src/unit-regression2.cpp index 86320f039..1e8c4922a 100644 --- a/test/src/unit-regression2.cpp +++ b/test/src/unit-regression2.cpp @@ -495,7 +495,7 @@ TEST_CASE("regression tests 2") const char DATA[] = R"("Hello, world!")"; const auto s = std::as_bytes(std::span(DATA)); json j = json::parse(s); - CHECK(j.dump() == "Hello, world!"); + CHECK(j.dump() == "\"Hello, world!\""); } #endif } From c886646707b14e8919216e7d90d5ea6c9ffa6e2b Mon Sep 17 00:00:00 2001 From: Niels Lohmann Date: Tue, 29 Dec 2020 21:04:41 +0100 Subject: [PATCH 12/14] :rotating_light: fix warning --- test/src/unit-udt_macro.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/src/unit-udt_macro.cpp b/test/src/unit-udt_macro.cpp index b56a5d15e..a13ac006b 100644 --- a/test/src/unit-udt_macro.cpp +++ b/test/src/unit-udt_macro.cpp @@ -106,7 +106,7 @@ NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(person_without_private_data_2, age, name, met class person_with_private_alphabet { public: - bool operator==(const person_with_private_alphabet& other) + bool operator==(const person_with_private_alphabet& other) const { return a == other.a && b == other.b && @@ -169,7 +169,7 @@ class person_with_private_alphabet class person_with_public_alphabet { public: - bool operator==(const person_with_public_alphabet& other) + bool operator==(const person_with_public_alphabet& other) const { return a == other.a && b == other.b && From bdb2469c313cb8b83bfc0de9a1e789e93379ff00 Mon Sep 17 00:00:00 2001 From: Niels Lohmann Date: Tue, 29 Dec 2020 21:36:30 +0100 Subject: [PATCH 13/14] :rotating_light: fix warnings --- Makefile | 2 + .../nlohmann/detail/input/input_adapters.hpp | 19 ++-- .../nlohmann/detail/iterators/iter_impl.hpp | 63 +++++--------- single_include/nlohmann/json.hpp | 86 ++++++++----------- test/src/unit-conversions.cpp | 8 ++ 5 files changed, 76 insertions(+), 102 deletions(-) diff --git a/Makefile b/Makefile index 0b9aa8213..d3963f503 100644 --- a/Makefile +++ b/Makefile @@ -84,6 +84,7 @@ doctest: # -Wno-missing-prototypes: for NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE # -Wno-padded: padding is nothing to warn about # -Wno-range-loop-analysis: items tests "for(const auto i...)" +# -Wno-extra-semi-stmt: spurious warnings for semicolons after JSON_ASSERT() # -Wno-switch-enum -Wno-covered-switch-default: pedantic/contradicting warnings about switches # -Wno-weak-vtables: exception class is defined inline, but has virtual method pedantic_clang: @@ -100,6 +101,7 @@ pedantic_clang: -Wno-missing-prototypes \ -Wno-padded \ -Wno-range-loop-analysis \ + -Wno-extra-semi-stmt \ -Wno-switch-enum -Wno-covered-switch-default \ -Wno-weak-vtables" cmake -S . -B cmake-build-pedantic -GNinja -DCMAKE_BUILD_TYPE=Debug -DJSON_MultipleHeaders=ON -DJSON_BuildTests=On cmake --build cmake-build-pedantic diff --git a/include/nlohmann/detail/input/input_adapters.hpp b/include/nlohmann/detail/input/input_adapters.hpp index eed370fd2..a78a6ec96 100644 --- a/include/nlohmann/detail/input/input_adapters.hpp +++ b/include/nlohmann/detail/input/input_adapters.hpp @@ -374,7 +374,8 @@ typename iterator_input_adapter_factory::adapter_type input_adapte // Enables ADL on begin(container) and end(container) // Encloses the using declarations in namespace for not to leak them to outside scope -namespace container_input_adapter_factory_impl { +namespace container_input_adapter_factory_impl +{ using std::begin; using std::end; @@ -384,15 +385,15 @@ struct container_input_adapter_factory {}; template struct container_input_adapter_factory< ContainerType, - void_t()), end(std::declval()))> > -{ - using adapter_type = decltype(input_adapter(begin(std::declval()), end(std::declval()))); + void_t()), end(std::declval()))>> + { + using adapter_type = decltype(input_adapter(begin(std::declval()), end(std::declval()))); - static adapter_type create(const ContainerType& container) - { - return input_adapter(begin(container), end(container)); - } -}; + static adapter_type create(const ContainerType& container) +{ + return input_adapter(begin(container), end(container)); +} + }; } diff --git a/include/nlohmann/detail/iterators/iter_impl.hpp b/include/nlohmann/detail/iterators/iter_impl.hpp index 6c65c6018..67134166e 100644 --- a/include/nlohmann/detail/iterators/iter_impl.hpp +++ b/include/nlohmann/detail/iterators/iter_impl.hpp @@ -38,8 +38,10 @@ This class implements a both iterators (iterator and const_iterator) for the template class iter_impl { + /// the iterator with BasicJsonType of different const-ness + using other_iter_impl = iter_impl::value, typename std::remove_const::type, const BasicJsonType>::type>; /// allow basic_json to access private members - friend iter_impl::value, typename std::remove_const::type, const BasicJsonType>::type>; + friend other_iter_impl; friend BasicJsonType; friend iteration_proxy; friend iteration_proxy_value; @@ -390,33 +392,11 @@ class iter_impl } /*! - @brief comparison: equal + @brief comparison: equal @pre The iterator is initialized; i.e. `m_object != nullptr`. */ - bool operator==(const iter_impl& other) const - { - // if objects are not the same, the comparison is undefined - if (JSON_HEDLEY_UNLIKELY(m_object != other.m_object)) - { - JSON_THROW(invalid_iterator::create(212, "cannot compare iterators of different containers")); - } - - JSON_ASSERT(m_object != nullptr); - - switch (m_object->m_type) - { - case value_t::object: - return (m_it.object_iterator == other.m_it.object_iterator); - - case value_t::array: - return (m_it.array_iterator == other.m_it.array_iterator); - - default: - return (m_it.primitive_iterator == other.m_it.primitive_iterator); - } - } - - bool operator==(const iter_impl::type>& other) const + template < typename IterImpl, detail::enable_if_t < (std::is_same::value || std::is_same::value), std::nullptr_t > = nullptr > + bool operator==(const IterImpl& other) const { // if objects are not the same, the comparison is undefined if (JSON_HEDLEY_UNLIKELY(m_object != other.m_object)) @@ -440,16 +420,17 @@ class iter_impl } /*! - @brief comparison: not equal + @brief comparison: not equal @pre The iterator is initialized; i.e. `m_object != nullptr`. */ - bool operator!=(const iter_impl& other) const + template < typename IterImpl, detail::enable_if_t < (std::is_same::value || std::is_same::value), std::nullptr_t > = nullptr > + bool operator!=(const IterImpl& other) const { return !operator==(other); } /*! - @brief comparison: smaller + @brief comparison: smaller @pre The iterator is initialized; i.e. `m_object != nullptr`. */ bool operator<(const iter_impl& other) const @@ -476,7 +457,7 @@ class iter_impl } /*! - @brief comparison: less than or equal + @brief comparison: less than or equal @pre The iterator is initialized; i.e. `m_object != nullptr`. */ bool operator<=(const iter_impl& other) const @@ -485,7 +466,7 @@ class iter_impl } /*! - @brief comparison: greater than + @brief comparison: greater than @pre The iterator is initialized; i.e. `m_object != nullptr`. */ bool operator>(const iter_impl& other) const @@ -494,7 +475,7 @@ class iter_impl } /*! - @brief comparison: greater than or equal + @brief comparison: greater than or equal @pre The iterator is initialized; i.e. `m_object != nullptr`. */ bool operator>=(const iter_impl& other) const @@ -503,7 +484,7 @@ class iter_impl } /*! - @brief add to iterator + @brief add to iterator @pre The iterator is initialized; i.e. `m_object != nullptr`. */ iter_impl& operator+=(difference_type i) @@ -532,7 +513,7 @@ class iter_impl } /*! - @brief subtract from iterator + @brief subtract from iterator @pre The iterator is initialized; i.e. `m_object != nullptr`. */ iter_impl& operator-=(difference_type i) @@ -541,7 +522,7 @@ class iter_impl } /*! - @brief add to iterator + @brief add to iterator @pre The iterator is initialized; i.e. `m_object != nullptr`. */ iter_impl operator+(difference_type i) const @@ -552,7 +533,7 @@ class iter_impl } /*! - @brief addition of distance and iterator + @brief addition of distance and iterator @pre The iterator is initialized; i.e. `m_object != nullptr`. */ friend iter_impl operator+(difference_type i, const iter_impl& it) @@ -563,7 +544,7 @@ class iter_impl } /*! - @brief subtract from iterator + @brief subtract from iterator @pre The iterator is initialized; i.e. `m_object != nullptr`. */ iter_impl operator-(difference_type i) const @@ -574,7 +555,7 @@ class iter_impl } /*! - @brief return difference + @brief return difference @pre The iterator is initialized; i.e. `m_object != nullptr`. */ difference_type operator-(const iter_impl& other) const @@ -595,7 +576,7 @@ class iter_impl } /*! - @brief access to successor + @brief access to successor @pre The iterator is initialized; i.e. `m_object != nullptr`. */ reference operator[](difference_type n) const @@ -626,7 +607,7 @@ class iter_impl } /*! - @brief return the key of an object iterator + @brief return the key of an object iterator @pre The iterator is initialized; i.e. `m_object != nullptr`. */ const typename object_t::key_type& key() const @@ -642,7 +623,7 @@ class iter_impl } /*! - @brief return the value of an iterator + @brief return the value of an iterator @pre The iterator is initialized; i.e. `m_object != nullptr`. */ reference value() const diff --git a/single_include/nlohmann/json.hpp b/single_include/nlohmann/json.hpp index ac0568ce9..8b6344f92 100644 --- a/single_include/nlohmann/json.hpp +++ b/single_include/nlohmann/json.hpp @@ -5186,7 +5186,8 @@ typename iterator_input_adapter_factory::adapter_type input_adapte // Enables ADL on begin(container) and end(container) // Encloses the using declarations in namespace for not to leak them to outside scope -namespace container_input_adapter_factory_impl { +namespace container_input_adapter_factory_impl +{ using std::begin; using std::end; @@ -5196,15 +5197,15 @@ struct container_input_adapter_factory {}; template struct container_input_adapter_factory< ContainerType, - void_t()), end(std::declval()))> > -{ - using adapter_type = decltype(input_adapter(begin(std::declval()), end(std::declval()))); + void_t()), end(std::declval()))>> + { + using adapter_type = decltype(input_adapter(begin(std::declval()), end(std::declval()))); - static adapter_type create(const ContainerType& container) - { - return input_adapter(begin(container), end(container)); - } -}; + static adapter_type create(const ContainerType& container) +{ + return input_adapter(begin(container), end(container)); +} + }; } @@ -10924,8 +10925,10 @@ This class implements a both iterators (iterator and const_iterator) for the template class iter_impl { + /// the iterator with BasicJsonType of different const-ness + using other_iter_impl = iter_impl::value, typename std::remove_const::type, const BasicJsonType>::type>; /// allow basic_json to access private members - friend iter_impl::value, typename std::remove_const::type, const BasicJsonType>::type>; + friend other_iter_impl; friend BasicJsonType; friend iteration_proxy; friend iteration_proxy_value; @@ -11276,33 +11279,11 @@ class iter_impl } /*! - @brief comparison: equal + @brief comparison: equal @pre The iterator is initialized; i.e. `m_object != nullptr`. */ - bool operator==(const iter_impl& other) const - { - // if objects are not the same, the comparison is undefined - if (JSON_HEDLEY_UNLIKELY(m_object != other.m_object)) - { - JSON_THROW(invalid_iterator::create(212, "cannot compare iterators of different containers")); - } - - JSON_ASSERT(m_object != nullptr); - - switch (m_object->m_type) - { - case value_t::object: - return (m_it.object_iterator == other.m_it.object_iterator); - - case value_t::array: - return (m_it.array_iterator == other.m_it.array_iterator); - - default: - return (m_it.primitive_iterator == other.m_it.primitive_iterator); - } - } - - bool operator==(const iter_impl::type>& other) const + template < typename IterImpl, detail::enable_if_t < (std::is_same::value || std::is_same::value), std::nullptr_t > = nullptr > + bool operator==(const IterImpl& other) const { // if objects are not the same, the comparison is undefined if (JSON_HEDLEY_UNLIKELY(m_object != other.m_object)) @@ -11326,16 +11307,17 @@ class iter_impl } /*! - @brief comparison: not equal + @brief comparison: not equal @pre The iterator is initialized; i.e. `m_object != nullptr`. */ - bool operator!=(const iter_impl& other) const + template < typename IterImpl, detail::enable_if_t < (std::is_same::value || std::is_same::value), std::nullptr_t > = nullptr > + bool operator!=(const IterImpl& other) const { return !operator==(other); } /*! - @brief comparison: smaller + @brief comparison: smaller @pre The iterator is initialized; i.e. `m_object != nullptr`. */ bool operator<(const iter_impl& other) const @@ -11362,7 +11344,7 @@ class iter_impl } /*! - @brief comparison: less than or equal + @brief comparison: less than or equal @pre The iterator is initialized; i.e. `m_object != nullptr`. */ bool operator<=(const iter_impl& other) const @@ -11371,7 +11353,7 @@ class iter_impl } /*! - @brief comparison: greater than + @brief comparison: greater than @pre The iterator is initialized; i.e. `m_object != nullptr`. */ bool operator>(const iter_impl& other) const @@ -11380,7 +11362,7 @@ class iter_impl } /*! - @brief comparison: greater than or equal + @brief comparison: greater than or equal @pre The iterator is initialized; i.e. `m_object != nullptr`. */ bool operator>=(const iter_impl& other) const @@ -11389,7 +11371,7 @@ class iter_impl } /*! - @brief add to iterator + @brief add to iterator @pre The iterator is initialized; i.e. `m_object != nullptr`. */ iter_impl& operator+=(difference_type i) @@ -11418,7 +11400,7 @@ class iter_impl } /*! - @brief subtract from iterator + @brief subtract from iterator @pre The iterator is initialized; i.e. `m_object != nullptr`. */ iter_impl& operator-=(difference_type i) @@ -11427,7 +11409,7 @@ class iter_impl } /*! - @brief add to iterator + @brief add to iterator @pre The iterator is initialized; i.e. `m_object != nullptr`. */ iter_impl operator+(difference_type i) const @@ -11438,7 +11420,7 @@ class iter_impl } /*! - @brief addition of distance and iterator + @brief addition of distance and iterator @pre The iterator is initialized; i.e. `m_object != nullptr`. */ friend iter_impl operator+(difference_type i, const iter_impl& it) @@ -11449,7 +11431,7 @@ class iter_impl } /*! - @brief subtract from iterator + @brief subtract from iterator @pre The iterator is initialized; i.e. `m_object != nullptr`. */ iter_impl operator-(difference_type i) const @@ -11460,7 +11442,7 @@ class iter_impl } /*! - @brief return difference + @brief return difference @pre The iterator is initialized; i.e. `m_object != nullptr`. */ difference_type operator-(const iter_impl& other) const @@ -11481,7 +11463,7 @@ class iter_impl } /*! - @brief access to successor + @brief access to successor @pre The iterator is initialized; i.e. `m_object != nullptr`. */ reference operator[](difference_type n) const @@ -11512,7 +11494,7 @@ class iter_impl } /*! - @brief return the key of an object iterator + @brief return the key of an object iterator @pre The iterator is initialized; i.e. `m_object != nullptr`. */ const typename object_t::key_type& key() const @@ -11528,7 +11510,7 @@ class iter_impl } /*! - @brief return the value of an iterator + @brief return the value of an iterator @pre The iterator is initialized; i.e. `m_object != nullptr`. */ reference value() const @@ -16845,7 +16827,7 @@ class basic_json detail::parser_callback_tcb = nullptr, const bool allow_exceptions = true, const bool ignore_comments = false - ) + ) { return ::nlohmann::detail::parser(std::move(adapter), std::move(cb), allow_exceptions, ignore_comments); @@ -25390,7 +25372,7 @@ template<> inline void swap(nlohmann::json& j1, nlohmann::json& j2) noexcept( is_nothrow_move_constructible::value&& is_nothrow_move_assignable::value -) + ) { j1.swap(j2); } diff --git a/test/src/unit-conversions.cpp b/test/src/unit-conversions.cpp index 16c4f798e..7f59c63ec 100644 --- a/test/src/unit-conversions.cpp +++ b/test/src/unit-conversions.cpp @@ -1702,3 +1702,11 @@ TEST_CASE("JSON to enum mapping") CHECK(TS_INVALID == json("what?").get()); } } + +#ifdef JSON_HAS_CPP_17 + #undef JSON_HAS_CPP_17 +#endif + +#ifdef JSON_HAS_CPP_14 + #undef JSON_HAS_CPP_14 +#endif From fc7e181cbf38c041b875723a0194626e31c52430 Mon Sep 17 00:00:00 2001 From: Niels Lohmann Date: Tue, 29 Dec 2020 22:21:31 +0100 Subject: [PATCH 14/14] :alembic: fix string representation --- test/src/unit-class_parser.cpp | 2 +- test/src/unit-regression1.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/test/src/unit-class_parser.cpp b/test/src/unit-class_parser.cpp index c612daabc..2df07d6d4 100644 --- a/test/src/unit-class_parser.cpp +++ b/test/src/unit-class_parser.cpp @@ -509,7 +509,7 @@ TEST_CASE("parser class") CHECK(parser_helper("\"€\"").get() == "€"); CHECK(parser_helper("\"🎈\"").get() == "🎈"); - CHECK(parser_helper("\"\\ud80c\\udc60\"").get() == "\U00013060"); + CHECK(parser_helper("\"\\ud80c\\udc60\"").get() == "\xf0\x93\x81\xa0"); CHECK(parser_helper("\"\\ud83c\\udf1e\"").get() == "🌞"); } } diff --git a/test/src/unit-regression1.cpp b/test/src/unit-regression1.cpp index f5520056f..df660ddb4 100644 --- a/test/src/unit-regression1.cpp +++ b/test/src/unit-regression1.cpp @@ -400,7 +400,7 @@ TEST_CASE("regression tests 1") SECTION("issue #146 - character following a surrogate pair is skipped") { - CHECK(json::parse("\"\\ud80c\\udc60abc\"").get() == "\U00013060abc"); + CHECK(json::parse("\"\\ud80c\\udc60abc\"").get() == "\xf0\x93\x81\xa0\x61\x62\x63"); } SECTION("issue #171 - Cannot index by key of type static constexpr const char*")