diff --git a/include/nlohmann/json.hpp b/include/nlohmann/json.hpp index 61130a9d1..83971d680 100644 --- a/include/nlohmann/json.hpp +++ b/include/nlohmann/json.hpp @@ -937,7 +937,7 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec template < typename BasicJsonType, detail::enable_if_t < detail::is_basic_json::value&& !std::is_same::value, int > = 0 > - basic_json(const BasicJsonType& val) + JSON_EXPLICIT basic_json(const BasicJsonType& val) { using other_boolean_t = typename BasicJsonType::boolean_t; using other_number_float_t = typename BasicJsonType::number_float_t; @@ -1760,7 +1760,7 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec int > = 0 > BasicJsonType get_impl(detail::priority_tag<2> /*unused*/) const { - return *this; + return BasicJsonType(*this); } /*! diff --git a/single_include/nlohmann/json.hpp b/single_include/nlohmann/json.hpp index 0264c156c..5c6d6d6a4 100644 --- a/single_include/nlohmann/json.hpp +++ b/single_include/nlohmann/json.hpp @@ -19303,7 +19303,7 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec template < typename BasicJsonType, detail::enable_if_t < detail::is_basic_json::value&& !std::is_same::value, int > = 0 > - basic_json(const BasicJsonType& val) + JSON_EXPLICIT basic_json(const BasicJsonType& val) { using other_boolean_t = typename BasicJsonType::boolean_t; using other_number_float_t = typename BasicJsonType::number_float_t; @@ -20126,7 +20126,7 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec int > = 0 > BasicJsonType get_impl(detail::priority_tag<2> /*unused*/) const { - return *this; + return BasicJsonType(*this); } /*! diff --git a/tests/src/unit-alt-string.cpp b/tests/src/unit-alt-string.cpp index 6885c31d4..0e5d498b6 100644 --- a/tests/src/unit-alt-string.cpp +++ b/tests/src/unit-alt-string.cpp @@ -343,7 +343,11 @@ TEST_CASE("alternative string type") SECTION("json to alt_json") { json j("foo"); +#if JSON_USE_IMPLICIT_CONVERSIONS alt_json aj = j; +#else + alt_json aj = alt_json(j); +#endif alt_string as = aj.dump(); CHECK(j.is_string()); @@ -354,7 +358,11 @@ TEST_CASE("alternative string type") SECTION("alt_json to json") { alt_json aj("foo"); +#if JSON_USE_IMPLICIT_CONVERSIONS json j = aj; +#else + json j = json(aj); +#endif alt_string as = aj.dump(); CHECK(aj.is_string()); @@ -368,7 +376,11 @@ TEST_CASE("alternative string type") SECTION("json to alt_json") { json j{"foo"}; +#if JSON_USE_IMPLICIT_CONVERSIONS alt_json aj = j; +#else + alt_json aj = alt_json(j); +#endif alt_string as = aj.dump(); CHECK(j.is_array()); @@ -379,7 +391,11 @@ TEST_CASE("alternative string type") SECTION("alt_json to json") { alt_json aj{"foo"}; +#if JSON_USE_IMPLICIT_CONVERSIONS json j = aj; +#else + json j = json(aj); +#endif alt_string as = aj.dump(); CHECK(aj.is_array()); @@ -393,7 +409,11 @@ TEST_CASE("alternative string type") SECTION("json to alt_json") { json j{{"foo", {"bar", "baz"}}}; +#if JSON_USE_IMPLICIT_CONVERSIONS alt_json aj = j; +#else + alt_json aj = alt_json(j); +#endif alt_string as = aj.dump(); CHECK(j.is_object()); @@ -404,7 +424,11 @@ TEST_CASE("alternative string type") SECTION("alt_json to json") { alt_json aj{{"foo", {"bar", "baz"}}}; +#if JSON_USE_IMPLICIT_CONVERSIONS json j = aj; +#else + json j = json(aj); +#endif alt_string as = aj.dump(); CHECK(aj.is_object()); @@ -418,7 +442,11 @@ TEST_CASE("alternative string type") SECTION("json to alt_json") { auto j = json::binary({1, 2, 3, 4}, 128); +#if JSON_USE_IMPLICIT_CONVERSIONS alt_json aj = j; +#else + alt_json aj = alt_json(j); +#endif alt_string as = aj.dump(); CHECK(j.is_binary()); @@ -429,7 +457,11 @@ TEST_CASE("alternative string type") SECTION("alt_json to json") { auto aj = alt_json::binary({1, 2, 3, 4}, 128); +#if JSON_USE_IMPLICIT_CONVERSIONS json j = aj; +#else + json j = json(aj); +#endif alt_string as = aj.dump(); CHECK(aj.is_binary()); diff --git a/tests/src/unit-regression1.cpp b/tests/src/unit-regression1.cpp index e6dfaa1c5..b2a1b8827 100644 --- a/tests/src/unit-regression1.cpp +++ b/tests/src/unit-regression1.cpp @@ -1485,7 +1485,11 @@ TEST_CASE("regression tests 1") SECTION("issue #972 - Segmentation fault on G++ when trying to assign json string literal to custom json type") { +#if JSON_USE_IMPLICIT_CONVERSIONS my_json foo = R"([1, 2, 3])"_json; +#else + my_json foo = my_json(R"([1, 2, 3])"_json); +#endif } SECTION("issue #977 - Assigning between different json types") @@ -1496,7 +1500,11 @@ TEST_CASE("regression tests 1") CHECK(lj.size() == 1); CHECK(lj["x"] == 3); CHECK(ff.x == 3); +#if JSON_USE_IMPLICIT_CONVERSIONS nlohmann::json nj = lj; // This line works as expected +#else + nlohmann::json nj = nlohmann::json(lj); // This line works as expected +#endif } } diff --git a/tests/src/unit-regression2.cpp b/tests/src/unit-regression2.cpp index 3ee234eee..777f0f597 100644 --- a/tests/src/unit-regression2.cpp +++ b/tests/src/unit-regression2.cpp @@ -774,12 +774,12 @@ TEST_CASE("regression tests 2") CHECK(test1.dump() == "{\"root\":{}}"); ordered_json test2; - test2[ordered_json::json_pointer(p)] = json::object(); + test2[ordered_json::json_pointer(p)] = ordered_json::object(); CHECK(test2.dump() == "{\"root\":{}}"); // json::json_pointer and ordered_json::json_pointer are the same type; behave as above ordered_json test3; - test3[json::json_pointer(p)] = json::object(); + test3[json::json_pointer(p)] = ordered_json::object(); CHECK(std::is_same::value); CHECK(test3.dump() == "{\"root\":{}}"); } @@ -859,7 +859,8 @@ TEST_CASE("regression tests 2") CHECK(td.str == "value"); } -#ifdef JSON_HAS_CPP_20 + // this is no longer supported when implicit conversions are disabled +#if defined(JSON_HAS_CPP_20) && JSON_USE_IMPLICIT_CONVERSIONS SECTION("issue #3312 - Parse to custom class from unordered_json breaks on G++11.2.0 with C++20") { // see test for #3171 diff --git a/tests/src/unit-udt.cpp b/tests/src/unit-udt.cpp index a3f06210d..5d634d77b 100644 --- a/tests/src/unit-udt.cpp +++ b/tests/src/unit-udt.cpp @@ -713,14 +713,22 @@ TEST_CASE("different basic_json types conversions") SECTION("null") { json j; +#if JSON_USE_IMPLICIT_CONVERSIONS custom_json cj = j; +#else + custom_json cj = custom_json(j); +#endif CHECK(cj == nullptr); } SECTION("boolean") { json j = true; +#if JSON_USE_IMPLICIT_CONVERSIONS custom_json cj = j; +#else + custom_json cj = custom_json(j); +#endif CHECK(cj == true); } @@ -728,49 +736,77 @@ TEST_CASE("different basic_json types conversions") { json j(json::value_t::discarded); custom_json cj; +#if JSON_USE_IMPLICIT_CONVERSIONS CHECK_NOTHROW(cj = j); +#else + CHECK_NOTHROW(cj = custom_json(j)); +#endif CHECK(cj.type() == custom_json::value_t::discarded); } SECTION("array") { json j = {1, 2, 3}; +#if JSON_USE_IMPLICIT_CONVERSIONS custom_json cj = j; +#else + custom_json cj = custom_json(j); +#endif CHECK((cj == std::vector {1, 2, 3})); } SECTION("integer") { json j = 42; +#if JSON_USE_IMPLICIT_CONVERSIONS custom_json cj = j; +#else + custom_json cj = custom_json(j); +#endif CHECK(cj == 42); } SECTION("float") { json j = 42.0; +#if JSON_USE_IMPLICIT_CONVERSIONS custom_json cj = j; +#else + custom_json cj = custom_json(j); +#endif CHECK(cj == 42.0); } SECTION("unsigned") { json j = 42u; +#if JSON_USE_IMPLICIT_CONVERSIONS custom_json cj = j; +#else + custom_json cj = custom_json(j); +#endif CHECK(cj == 42u); } SECTION("string") { json j = "forty-two"; +#if JSON_USE_IMPLICIT_CONVERSIONS custom_json cj = j; +#else + custom_json cj = custom_json(j); +#endif CHECK(cj == "forty-two"); } SECTION("binary") { json j = json::binary({1, 2, 3}, 42); +#if JSON_USE_IMPLICIT_CONVERSIONS custom_json cj = j; +#else + custom_json cj = custom_json(j); +#endif CHECK(cj.get_binary().subtype() == 42); std::vector cv = cj.get_binary(); std::vector v = j.get_binary(); @@ -780,7 +816,11 @@ TEST_CASE("different basic_json types conversions") SECTION("object") { json j = {{"forty", "two"}}; +#if JSON_USE_IMPLICIT_CONVERSIONS custom_json cj = j; +#else + custom_json cj = custom_json(j); +#endif auto m = j.get>(); CHECK(cj == m); }