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,
detail::enable_if_t <
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_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);
}
/*!

View File

@ -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<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_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);
}
/*!

View File

@ -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());

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")
{
#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
}
}

View File

@ -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<json::json_pointer::string_t, ordered_json::json_pointer::string_t>::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

View File

@ -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<int> {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<std::uint8_t> cv = cj.get_binary();
std::vector<std::uint8_t> 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<std::map<std::string, std::string>>();
CHECK(cj == m);
}