Mark basic_json converting ctor JSON_EXPLICIT

Make JSON_USE_IMPLICIT_CONVERSIONS affect the basic_json converting
constructor.
This commit is contained in:
Florian Albrechtskirchinger 2022-06-04 10:41:35 +02:00
parent 84ced9bce4
commit 140943b18e
No known key found for this signature in database
GPG Key ID: 19618CE9B2D4BE6D
6 changed files with 88 additions and 7 deletions

View File

@ -937,7 +937,7 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
template < typename BasicJsonType, template < typename BasicJsonType,
detail::enable_if_t < detail::enable_if_t <
detail::is_basic_json<BasicJsonType>::value&& !std::is_same<basic_json, BasicJsonType>::value, int > = 0 > detail::is_basic_json<BasicJsonType>::value&& !std::is_same<basic_json, BasicJsonType>::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_boolean_t = typename BasicJsonType::boolean_t;
using other_number_float_t = typename BasicJsonType::number_float_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 > int > = 0 >
BasicJsonType get_impl(detail::priority_tag<2> /*unused*/) const BasicJsonType get_impl(detail::priority_tag<2> /*unused*/) const
{ {
return *this; return BasicJsonType(*this);
} }
/*! /*!

View File

@ -19303,7 +19303,7 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
template < typename BasicJsonType, template < typename BasicJsonType,
detail::enable_if_t < detail::enable_if_t <
detail::is_basic_json<BasicJsonType>::value&& !std::is_same<basic_json, BasicJsonType>::value, int > = 0 > detail::is_basic_json<BasicJsonType>::value&& !std::is_same<basic_json, BasicJsonType>::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_boolean_t = typename BasicJsonType::boolean_t;
using other_number_float_t = typename BasicJsonType::number_float_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 > int > = 0 >
BasicJsonType get_impl(detail::priority_tag<2> /*unused*/) const BasicJsonType get_impl(detail::priority_tag<2> /*unused*/) const
{ {
return *this; return BasicJsonType(*this);
} }
/*! /*!

View File

@ -343,7 +343,11 @@ TEST_CASE("alternative string type")
SECTION("json to alt_json") SECTION("json to alt_json")
{ {
json j("foo"); json j("foo");
#if JSON_USE_IMPLICIT_CONVERSIONS
alt_json aj = j; alt_json aj = j;
#else
alt_json aj = alt_json(j);
#endif
alt_string as = aj.dump(); alt_string as = aj.dump();
CHECK(j.is_string()); CHECK(j.is_string());
@ -354,7 +358,11 @@ TEST_CASE("alternative string type")
SECTION("alt_json to json") SECTION("alt_json to json")
{ {
alt_json aj("foo"); alt_json aj("foo");
#if JSON_USE_IMPLICIT_CONVERSIONS
json j = aj; json j = aj;
#else
json j = json(aj);
#endif
alt_string as = aj.dump(); alt_string as = aj.dump();
CHECK(aj.is_string()); CHECK(aj.is_string());
@ -368,7 +376,11 @@ TEST_CASE("alternative string type")
SECTION("json to alt_json") SECTION("json to alt_json")
{ {
json j{"foo"}; json j{"foo"};
#if JSON_USE_IMPLICIT_CONVERSIONS
alt_json aj = j; alt_json aj = j;
#else
alt_json aj = alt_json(j);
#endif
alt_string as = aj.dump(); alt_string as = aj.dump();
CHECK(j.is_array()); CHECK(j.is_array());
@ -379,7 +391,11 @@ TEST_CASE("alternative string type")
SECTION("alt_json to json") SECTION("alt_json to json")
{ {
alt_json aj{"foo"}; alt_json aj{"foo"};
#if JSON_USE_IMPLICIT_CONVERSIONS
json j = aj; json j = aj;
#else
json j = json(aj);
#endif
alt_string as = aj.dump(); alt_string as = aj.dump();
CHECK(aj.is_array()); CHECK(aj.is_array());
@ -393,7 +409,11 @@ TEST_CASE("alternative string type")
SECTION("json to alt_json") SECTION("json to alt_json")
{ {
json j{{"foo", {"bar", "baz"}}}; json j{{"foo", {"bar", "baz"}}};
#if JSON_USE_IMPLICIT_CONVERSIONS
alt_json aj = j; alt_json aj = j;
#else
alt_json aj = alt_json(j);
#endif
alt_string as = aj.dump(); alt_string as = aj.dump();
CHECK(j.is_object()); CHECK(j.is_object());
@ -404,7 +424,11 @@ TEST_CASE("alternative string type")
SECTION("alt_json to json") SECTION("alt_json to json")
{ {
alt_json aj{{"foo", {"bar", "baz"}}}; alt_json aj{{"foo", {"bar", "baz"}}};
#if JSON_USE_IMPLICIT_CONVERSIONS
json j = aj; json j = aj;
#else
json j = json(aj);
#endif
alt_string as = aj.dump(); alt_string as = aj.dump();
CHECK(aj.is_object()); CHECK(aj.is_object());
@ -418,7 +442,11 @@ TEST_CASE("alternative string type")
SECTION("json to alt_json") SECTION("json to alt_json")
{ {
auto j = json::binary({1, 2, 3, 4}, 128); auto j = json::binary({1, 2, 3, 4}, 128);
#if JSON_USE_IMPLICIT_CONVERSIONS
alt_json aj = j; alt_json aj = j;
#else
alt_json aj = alt_json(j);
#endif
alt_string as = aj.dump(); alt_string as = aj.dump();
CHECK(j.is_binary()); CHECK(j.is_binary());
@ -429,7 +457,11 @@ TEST_CASE("alternative string type")
SECTION("alt_json to json") SECTION("alt_json to json")
{ {
auto aj = alt_json::binary({1, 2, 3, 4}, 128); auto aj = alt_json::binary({1, 2, 3, 4}, 128);
#if JSON_USE_IMPLICIT_CONVERSIONS
json j = aj; json j = aj;
#else
json j = json(aj);
#endif
alt_string as = aj.dump(); alt_string as = aj.dump();
CHECK(aj.is_binary()); CHECK(aj.is_binary());

View File

@ -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") 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; 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") SECTION("issue #977 - Assigning between different json types")
@ -1496,7 +1500,11 @@ TEST_CASE("regression tests 1")
CHECK(lj.size() == 1); CHECK(lj.size() == 1);
CHECK(lj["x"] == 3); CHECK(lj["x"] == 3);
CHECK(ff.x == 3); CHECK(ff.x == 3);
#if JSON_USE_IMPLICIT_CONVERSIONS
nlohmann::json nj = lj; // This line works as expected nlohmann::json nj = lj; // This line works as expected
#else
nlohmann::json nj = nlohmann::json(lj); // This line works as expected
#endif
} }
} }

View File

@ -774,12 +774,12 @@ TEST_CASE("regression tests 2")
CHECK(test1.dump() == "{\"root\":{}}"); CHECK(test1.dump() == "{\"root\":{}}");
ordered_json test2; ordered_json test2;
test2[ordered_json::json_pointer(p)] = json::object(); test2[ordered_json::json_pointer(p)] = ordered_json::object();
CHECK(test2.dump() == "{\"root\":{}}"); CHECK(test2.dump() == "{\"root\":{}}");
// json::json_pointer and ordered_json::json_pointer are the same type; behave as above // json::json_pointer and ordered_json::json_pointer are the same type; behave as above
ordered_json test3; ordered_json test3;
test3[json::json_pointer(p)] = json::object(); test3[json::json_pointer(p)] = ordered_json::object();
CHECK(std::is_same<json::json_pointer::string_t, ordered_json::json_pointer::string_t>::value); CHECK(std::is_same<json::json_pointer::string_t, ordered_json::json_pointer::string_t>::value);
CHECK(test3.dump() == "{\"root\":{}}"); CHECK(test3.dump() == "{\"root\":{}}");
} }
@ -859,7 +859,8 @@ TEST_CASE("regression tests 2")
CHECK(td.str == "value"); 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") SECTION("issue #3312 - Parse to custom class from unordered_json breaks on G++11.2.0 with C++20")
{ {
// see test for #3171 // see test for #3171

View File

@ -713,14 +713,22 @@ TEST_CASE("different basic_json types conversions")
SECTION("null") SECTION("null")
{ {
json j; json j;
#if JSON_USE_IMPLICIT_CONVERSIONS
custom_json cj = j; custom_json cj = j;
#else
custom_json cj = custom_json(j);
#endif
CHECK(cj == nullptr); CHECK(cj == nullptr);
} }
SECTION("boolean") SECTION("boolean")
{ {
json j = true; json j = true;
#if JSON_USE_IMPLICIT_CONVERSIONS
custom_json cj = j; custom_json cj = j;
#else
custom_json cj = custom_json(j);
#endif
CHECK(cj == true); CHECK(cj == true);
} }
@ -728,49 +736,77 @@ TEST_CASE("different basic_json types conversions")
{ {
json j(json::value_t::discarded); json j(json::value_t::discarded);
custom_json cj; custom_json cj;
#if JSON_USE_IMPLICIT_CONVERSIONS
CHECK_NOTHROW(cj = j); CHECK_NOTHROW(cj = j);
#else
CHECK_NOTHROW(cj = custom_json(j));
#endif
CHECK(cj.type() == custom_json::value_t::discarded); CHECK(cj.type() == custom_json::value_t::discarded);
} }
SECTION("array") SECTION("array")
{ {
json j = {1, 2, 3}; json j = {1, 2, 3};
#if JSON_USE_IMPLICIT_CONVERSIONS
custom_json cj = j; custom_json cj = j;
#else
custom_json cj = custom_json(j);
#endif
CHECK((cj == std::vector<int> {1, 2, 3})); CHECK((cj == std::vector<int> {1, 2, 3}));
} }
SECTION("integer") SECTION("integer")
{ {
json j = 42; json j = 42;
#if JSON_USE_IMPLICIT_CONVERSIONS
custom_json cj = j; custom_json cj = j;
#else
custom_json cj = custom_json(j);
#endif
CHECK(cj == 42); CHECK(cj == 42);
} }
SECTION("float") SECTION("float")
{ {
json j = 42.0; json j = 42.0;
#if JSON_USE_IMPLICIT_CONVERSIONS
custom_json cj = j; custom_json cj = j;
#else
custom_json cj = custom_json(j);
#endif
CHECK(cj == 42.0); CHECK(cj == 42.0);
} }
SECTION("unsigned") SECTION("unsigned")
{ {
json j = 42u; json j = 42u;
#if JSON_USE_IMPLICIT_CONVERSIONS
custom_json cj = j; custom_json cj = j;
#else
custom_json cj = custom_json(j);
#endif
CHECK(cj == 42u); CHECK(cj == 42u);
} }
SECTION("string") SECTION("string")
{ {
json j = "forty-two"; json j = "forty-two";
#if JSON_USE_IMPLICIT_CONVERSIONS
custom_json cj = j; custom_json cj = j;
#else
custom_json cj = custom_json(j);
#endif
CHECK(cj == "forty-two"); CHECK(cj == "forty-two");
} }
SECTION("binary") SECTION("binary")
{ {
json j = json::binary({1, 2, 3}, 42); json j = json::binary({1, 2, 3}, 42);
#if JSON_USE_IMPLICIT_CONVERSIONS
custom_json cj = j; custom_json cj = j;
#else
custom_json cj = custom_json(j);
#endif
CHECK(cj.get_binary().subtype() == 42); CHECK(cj.get_binary().subtype() == 42);
std::vector<std::uint8_t> cv = cj.get_binary(); std::vector<std::uint8_t> cv = cj.get_binary();
std::vector<std::uint8_t> v = j.get_binary(); std::vector<std::uint8_t> v = j.get_binary();
@ -780,7 +816,11 @@ TEST_CASE("different basic_json types conversions")
SECTION("object") SECTION("object")
{ {
json j = {{"forty", "two"}}; json j = {{"forty", "two"}};
#if JSON_USE_IMPLICIT_CONVERSIONS
custom_json cj = j; custom_json cj = j;
#else
custom_json cj = custom_json(j);
#endif
auto m = j.get<std::map<std::string, std::string>>(); auto m = j.get<std::map<std::string, std::string>>();
CHECK(cj == m); CHECK(cj == m);
} }