From 55670233ea1d0b2f0c766677b26b7d5aff78c3aa Mon Sep 17 00:00:00 2001 From: Niels Lohmann Date: Mon, 28 Sep 2026 18:59:28 +0200 Subject: [PATCH] Skip json reference tuple tests on clang < 4 and GCC < 5 ci_test_compilers_gcc_old (4.8) and ci_test_compilers_clang (3.4) could not compile the new tuple tests. Creating a std::tuple of basic_json references, e.g. std::forward_as_tuple(j), makes these compilers instantiate basic_json's conversion operator for libstdc++'s internal tuple bases, which fails hard. This happens with and without JSON_DISABLE_TUPLE_REFERENCE_CONVERSION, so it is a limitation of these compilers, not of the new option. Tested with the CI images: clang 3.4 to 3.9 and GCC 4.8 and 4.9 fail, clang 4, 5, and 6 and GCC 5 and 6 compile all cases. Skip only the checks that create such tuples; the is_constructible checks still run. Signed-off-by: Niels Lohmann --- .../unit-disable-tuple-reference-conversion.cpp | 14 ++++++++++++++ tests/src/unit-regression2.cpp | 10 ++++++++++ 2 files changed, 24 insertions(+) diff --git a/tests/src/unit-disable-tuple-reference-conversion.cpp b/tests/src/unit-disable-tuple-reference-conversion.cpp index 913bca9f1..6d978620b 100644 --- a/tests/src/unit-disable-tuple-reference-conversion.cpp +++ b/tests/src/unit-disable-tuple-reference-conversion.cpp @@ -26,6 +26,14 @@ using nlohmann::ordered_json; #include #include +// clang before 4 and GCC before 5 cannot create a std::tuple of basic_json +// references at all, with or without JSON_DISABLE_TUPLE_REFERENCE_CONVERSION: +// the tuple constructors make them instantiate basic_json's conversion operator +// for libstdc++'s internal tuple bases, which fails hard +#if (defined(__clang__) && __clang_major__ < 4) || (!defined(__clang__) && defined(__GNUC__) && __GNUC__ < 5) + #define SKIP_TESTS_FOR_JSON_REFERENCE_TUPLES +#endif + TEST_CASE("JSON_DISABLE_TUPLE_REFERENCE_CONVERSION") { SECTION("json is not constructible from a one-element tuple of a json reference") @@ -37,6 +45,7 @@ TEST_CASE("JSON_DISABLE_TUPLE_REFERENCE_CONVERSION") CHECK_FALSE(std::is_constructible>::value); } +#ifndef SKIP_TESTS_FOR_JSON_REFERENCE_TUPLES SECTION("issue #2226 - tuple from tuple keeps the reference") { json j = true; @@ -54,6 +63,7 @@ TEST_CASE("JSON_DISABLE_TUPLE_REFERENCE_CONVERSION") const std::tuple t2(std::forward_as_tuple(std::move(j2))); CHECK(std::get<0>(t2) == "text"); } +#endif SECTION("other tuple conversions are not affected") { @@ -64,16 +74,20 @@ TEST_CASE("JSON_DISABLE_TUPLE_REFERENCE_CONVERSION") // tuples with more than one element, even when holding references int i = 1; +#ifndef SKIP_TESTS_FOR_JSON_REFERENCE_TUPLES CHECK(json(std::forward_as_tuple(i, j)) == json::array({1, true})); CHECK(json(std::forward_as_tuple(j, j)) == json::array({true, true})); +#endif // one-element tuples holding references to other types std::string s = "text"; CHECK(json(std::forward_as_tuple(s)) == json::array({"text"})); CHECK(json(std::forward_as_tuple(i)) == json::array({1})); +#ifndef SKIP_TESTS_FOR_JSON_REFERENCE_TUPLES // a reference to a different basic_json specialization ordered_json oj = true; CHECK(json(std::forward_as_tuple(oj)) == json::array({true})); +#endif } } diff --git a/tests/src/unit-regression2.cpp b/tests/src/unit-regression2.cpp index 7db0e8e6e..6446f5f8c 100644 --- a/tests/src/unit-regression2.cpp +++ b/tests/src/unit-regression2.cpp @@ -23,6 +23,14 @@ #define SKIP_TESTS_FOR_TUPLE_REFERENCE_CONVERSION #endif +// clang before 4 and GCC before 5 cannot create a std::tuple of basic_json +// references at all, with or without JSON_DISABLE_TUPLE_REFERENCE_CONVERSION: +// the tuple constructors make them instantiate basic_json's conversion operator +// for libstdc++'s internal tuple bases, which fails hard +#if (defined(__clang__) && __clang_major__ < 4) || (!defined(__clang__) && defined(__GNUC__) && __GNUC__ < 5) + #define SKIP_TESTS_FOR_JSON_REFERENCE_TUPLES +#endif + #define JSON_TESTS_PRIVATE #include using json = nlohmann::json; @@ -556,7 +564,9 @@ TEST_CASE("regression tests 2") // this conversion (see unit-disable-tuple-reference-conversion.cpp) const json j = true; CHECK(std::is_constructible>::value); +#ifndef SKIP_TESTS_FOR_JSON_REFERENCE_TUPLES CHECK(json(std::forward_as_tuple(j)) == json::array({true})); +#endif } #endif