Merge e15a17b437 into f7973f46d6
This commit is contained in:
commit
f7d5ba33f2
@ -45,7 +45,7 @@ inline void from_json(const BasicJsonType& j, typename std::nullptr_t& n)
|
||||
|
||||
// overloads for basic_json template parameters
|
||||
template < typename BasicJsonType, typename ArithmeticType,
|
||||
enable_if_t < std::is_arithmetic<ArithmeticType>::value&&
|
||||
enable_if_t < std::numeric_limits<ArithmeticType>::is_specialized&&
|
||||
!std::is_same<ArithmeticType, typename BasicJsonType::boolean_t>::value,
|
||||
int > = 0 >
|
||||
void get_arithmetic_value(const BasicJsonType& j, ArithmeticType& val)
|
||||
|
||||
@ -49,7 +49,7 @@ struct external_constructor<value_t::boolean>
|
||||
{
|
||||
j.m_value.destroy(j.m_type);
|
||||
j.m_type = value_t::boolean;
|
||||
j.m_value = b;
|
||||
new (&j.m_value) typename BasicJsonType::json_value(b);
|
||||
j.assert_invariant();
|
||||
}
|
||||
};
|
||||
@ -62,7 +62,7 @@ struct external_constructor<value_t::string>
|
||||
{
|
||||
j.m_value.destroy(j.m_type);
|
||||
j.m_type = value_t::string;
|
||||
j.m_value = s;
|
||||
new (&j.m_value) typename BasicJsonType::json_value(s);
|
||||
j.assert_invariant();
|
||||
}
|
||||
|
||||
@ -71,7 +71,7 @@ struct external_constructor<value_t::string>
|
||||
{
|
||||
j.m_value.destroy(j.m_type);
|
||||
j.m_type = value_t::string;
|
||||
j.m_value = std::move(s);
|
||||
new (&j.m_value) typename BasicJsonType::json_value(std::move(s));
|
||||
j.assert_invariant();
|
||||
}
|
||||
|
||||
@ -95,7 +95,7 @@ struct external_constructor<value_t::binary>
|
||||
{
|
||||
j.m_value.destroy(j.m_type);
|
||||
j.m_type = value_t::binary;
|
||||
j.m_value = typename BasicJsonType::binary_t(b);
|
||||
new (&j.m_value) typename BasicJsonType::json_value(typename BasicJsonType::binary_t(b));
|
||||
j.assert_invariant();
|
||||
}
|
||||
|
||||
@ -104,7 +104,7 @@ struct external_constructor<value_t::binary>
|
||||
{
|
||||
j.m_value.destroy(j.m_type);
|
||||
j.m_type = value_t::binary;
|
||||
j.m_value = typename BasicJsonType::binary_t(std::move(b));
|
||||
new (&j.m_value) typename BasicJsonType::json_value(typename BasicJsonType::binary_t(std::move(b)));
|
||||
j.assert_invariant();
|
||||
}
|
||||
};
|
||||
@ -117,7 +117,7 @@ struct external_constructor<value_t::number_float>
|
||||
{
|
||||
j.m_value.destroy(j.m_type);
|
||||
j.m_type = value_t::number_float;
|
||||
j.m_value = val;
|
||||
new (&j.m_value) typename BasicJsonType::json_value(val);
|
||||
j.assert_invariant();
|
||||
}
|
||||
};
|
||||
@ -130,7 +130,7 @@ struct external_constructor<value_t::number_unsigned>
|
||||
{
|
||||
j.m_value.destroy(j.m_type);
|
||||
j.m_type = value_t::number_unsigned;
|
||||
j.m_value = val;
|
||||
new (&j.m_value) typename BasicJsonType::json_value(val);
|
||||
j.assert_invariant();
|
||||
}
|
||||
};
|
||||
@ -143,7 +143,7 @@ struct external_constructor<value_t::number_integer>
|
||||
{
|
||||
j.m_value.destroy(j.m_type);
|
||||
j.m_type = value_t::number_integer;
|
||||
j.m_value = val;
|
||||
new (&j.m_value) typename BasicJsonType::json_value(val);
|
||||
j.assert_invariant();
|
||||
}
|
||||
};
|
||||
@ -156,7 +156,7 @@ struct external_constructor<value_t::array>
|
||||
{
|
||||
j.m_value.destroy(j.m_type);
|
||||
j.m_type = value_t::array;
|
||||
j.m_value = arr;
|
||||
new (&j.m_value) typename BasicJsonType::json_value(arr);
|
||||
j.set_parents();
|
||||
j.assert_invariant();
|
||||
}
|
||||
@ -166,7 +166,7 @@ struct external_constructor<value_t::array>
|
||||
{
|
||||
j.m_value.destroy(j.m_type);
|
||||
j.m_type = value_t::array;
|
||||
j.m_value = std::move(arr);
|
||||
new (&j.m_value) typename BasicJsonType::json_value(std::move(arr));
|
||||
j.set_parents();
|
||||
j.assert_invariant();
|
||||
}
|
||||
@ -191,7 +191,7 @@ struct external_constructor<value_t::array>
|
||||
{
|
||||
j.m_value.destroy(j.m_type);
|
||||
j.m_type = value_t::array;
|
||||
j.m_value = value_t::array;
|
||||
new (&j.m_value) typename BasicJsonType::json_value(value_t::array);
|
||||
j.m_value.array->reserve(arr.size());
|
||||
for (const bool x : arr)
|
||||
{
|
||||
@ -207,7 +207,7 @@ struct external_constructor<value_t::array>
|
||||
{
|
||||
j.m_value.destroy(j.m_type);
|
||||
j.m_type = value_t::array;
|
||||
j.m_value = value_t::array;
|
||||
new (&j.m_value) typename BasicJsonType::json_value(value_t::array);
|
||||
j.m_value.array->resize(arr.size());
|
||||
if (arr.size() > 0)
|
||||
{
|
||||
@ -226,7 +226,7 @@ struct external_constructor<value_t::object>
|
||||
{
|
||||
j.m_value.destroy(j.m_type);
|
||||
j.m_type = value_t::object;
|
||||
j.m_value = obj;
|
||||
new (&j.m_value) typename BasicJsonType::json_value(obj);
|
||||
j.set_parents();
|
||||
j.assert_invariant();
|
||||
}
|
||||
@ -236,7 +236,7 @@ struct external_constructor<value_t::object>
|
||||
{
|
||||
j.m_value.destroy(j.m_type);
|
||||
j.m_type = value_t::object;
|
||||
j.m_value = std::move(obj);
|
||||
new (&j.m_value) typename BasicJsonType:: json_value(std::move(obj));
|
||||
j.set_parents();
|
||||
j.assert_invariant();
|
||||
}
|
||||
|
||||
@ -1258,7 +1258,7 @@ scan_number_done:
|
||||
if (errno == 0)
|
||||
{
|
||||
value_unsigned = static_cast<number_unsigned_t>(x);
|
||||
if (value_unsigned == x)
|
||||
if (static_cast<long long>(value_unsigned) == x)
|
||||
{
|
||||
return token_type::value_unsigned;
|
||||
}
|
||||
@ -1274,7 +1274,7 @@ scan_number_done:
|
||||
if (errno == 0)
|
||||
{
|
||||
value_integer = static_cast<number_integer_t>(x);
|
||||
if (value_integer == x)
|
||||
if (static_cast<long long>(value_integer) == x)
|
||||
{
|
||||
return token_type::value_integer;
|
||||
}
|
||||
|
||||
@ -441,8 +441,8 @@ struct is_compatible_integer_type_impl : std::false_type {};
|
||||
template<typename RealIntegerType, typename CompatibleNumberIntegerType>
|
||||
struct is_compatible_integer_type_impl <
|
||||
RealIntegerType, CompatibleNumberIntegerType,
|
||||
enable_if_t < std::is_integral<RealIntegerType>::value&&
|
||||
std::is_integral<CompatibleNumberIntegerType>::value&&
|
||||
enable_if_t < std::numeric_limits<RealIntegerType>::is_integer&&
|
||||
std::numeric_limits<CompatibleNumberIntegerType>::is_integer&&
|
||||
!std::is_same<bool, CompatibleNumberIntegerType>::value >>
|
||||
{
|
||||
// is there an assert somewhere on overflows?
|
||||
|
||||
@ -684,13 +684,13 @@ class serializer
|
||||
}
|
||||
|
||||
// templates to avoid warnings about useless casts
|
||||
template <typename NumberType, enable_if_t<std::is_signed<NumberType>::value, int> = 0>
|
||||
template <typename NumberType, enable_if_t<std::numeric_limits<NumberType>::is_signed, int> = 0>
|
||||
bool is_negative_number(NumberType x)
|
||||
{
|
||||
return x < 0;
|
||||
return x < NumberType(0);
|
||||
}
|
||||
|
||||
template < typename NumberType, enable_if_t <std::is_unsigned<NumberType>::value, int > = 0 >
|
||||
template < typename NumberType, enable_if_t < !std::numeric_limits<NumberType>::is_signed, int > = 0 >
|
||||
bool is_negative_number(NumberType /*unused*/)
|
||||
{
|
||||
return false;
|
||||
@ -706,7 +706,7 @@ class serializer
|
||||
@tparam NumberType either @a number_integer_t or @a number_unsigned_t
|
||||
*/
|
||||
template < typename NumberType, detail::enable_if_t <
|
||||
std::is_integral<NumberType>::value ||
|
||||
std::numeric_limits<NumberType>::is_integer ||
|
||||
std::is_same<NumberType, number_unsigned_t>::value ||
|
||||
std::is_same<NumberType, number_integer_t>::value ||
|
||||
std::is_same<NumberType, binary_char_t>::value,
|
||||
@ -730,7 +730,7 @@ class serializer
|
||||
};
|
||||
|
||||
// special case for "0"
|
||||
if (x == 0)
|
||||
if (x == NumberType(0))
|
||||
{
|
||||
o->write_character('0');
|
||||
return;
|
||||
@ -766,15 +766,16 @@ class serializer
|
||||
|
||||
// Fast int2ascii implementation inspired by "Fastware" talk by Andrei Alexandrescu
|
||||
// See: https://www.youtube.com/watch?v=o4-CwDo2zpg
|
||||
while (abs_value >= 100)
|
||||
const NumberType hundred = 100;
|
||||
while (abs_value >= hundred)
|
||||
{
|
||||
const auto digits_index = static_cast<unsigned>((abs_value % 100));
|
||||
abs_value /= 100;
|
||||
const auto digits_index = static_cast<unsigned>((abs_value % hundred));
|
||||
abs_value /= hundred;
|
||||
*(--buffer_ptr) = digits_to_99[digits_index][1];
|
||||
*(--buffer_ptr) = digits_to_99[digits_index][0];
|
||||
}
|
||||
|
||||
if (abs_value >= 10)
|
||||
if (abs_value >= NumberType(10))
|
||||
{
|
||||
const auto digits_index = static_cast<unsigned>(abs_value);
|
||||
*(--buffer_ptr) = digits_to_99[digits_index][1];
|
||||
|
||||
@ -440,7 +440,7 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
||||
number_float_t number_float;
|
||||
|
||||
/// default constructor (for null values)
|
||||
json_value() = default;
|
||||
json_value() {};
|
||||
/// constructor for booleans
|
||||
json_value(boolean_t v) noexcept : boolean(v) {}
|
||||
/// constructor for numbers (integer)
|
||||
@ -551,6 +551,179 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
||||
/// constructor for rvalue binary arrays (internal type)
|
||||
json_value(binary_t&& value) : binary(create<binary_t>(std::move(value))) {}
|
||||
|
||||
/// User is responsible for calling `destroy` first to make this safe
|
||||
~json_value() {}
|
||||
|
||||
json_value& operator=(json_value&) = delete;
|
||||
|
||||
/// Copy from an existing value of type t
|
||||
json_value(value_t t, const json_value& v)
|
||||
{
|
||||
switch (t)
|
||||
{
|
||||
case value_t::object:
|
||||
{
|
||||
new (this) json_value(v.object);
|
||||
break;
|
||||
}
|
||||
case value_t::array:
|
||||
{
|
||||
new (this) json_value(v.array);
|
||||
break;
|
||||
}
|
||||
case value_t::string:
|
||||
{
|
||||
new (this) json_value(v.string);
|
||||
break;
|
||||
}
|
||||
case value_t::binary:
|
||||
{
|
||||
new (this) json_value(v.binary);
|
||||
break;
|
||||
}
|
||||
case value_t::boolean:
|
||||
{
|
||||
new (this) json_value(v.boolean);
|
||||
break;
|
||||
}
|
||||
case value_t::number_integer:
|
||||
{
|
||||
new (this) json_value(v.number_integer);
|
||||
break;
|
||||
}
|
||||
case value_t::number_unsigned:
|
||||
{
|
||||
new (this) json_value(v.number_unsigned);
|
||||
break;
|
||||
}
|
||||
case value_t::number_float:
|
||||
{
|
||||
new (this) json_value(v.number_float);
|
||||
break;
|
||||
}
|
||||
case value_t::discarded:
|
||||
case value_t::null:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/// Move from an existing value of type t
|
||||
json_value(value_t t, json_value&& v)
|
||||
{
|
||||
switch (t)
|
||||
{
|
||||
case value_t::object:
|
||||
{
|
||||
new (this) json_value(std::move(v.object));
|
||||
break;
|
||||
}
|
||||
case value_t::array:
|
||||
{
|
||||
new (this) json_value(std::move(v.array));
|
||||
break;
|
||||
}
|
||||
case value_t::string:
|
||||
{
|
||||
new (this) json_value(std::move(v.string));
|
||||
break;
|
||||
}
|
||||
case value_t::binary:
|
||||
{
|
||||
new (this) json_value(std::move(v.binary));
|
||||
break;
|
||||
}
|
||||
case value_t::boolean:
|
||||
{
|
||||
new (this) json_value(std::move(v.boolean));
|
||||
break;
|
||||
}
|
||||
case value_t::number_integer:
|
||||
{
|
||||
new (this) json_value(std::move(v.number_integer));
|
||||
break;
|
||||
}
|
||||
case value_t::number_unsigned:
|
||||
{
|
||||
new (this) json_value(std::move(v.number_unsigned));
|
||||
break;
|
||||
}
|
||||
case value_t::number_float:
|
||||
{
|
||||
new (this) json_value(std::move(v.number_float));
|
||||
break;
|
||||
}
|
||||
case value_t::discarded:
|
||||
case value_t::null:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
v.destroy(t);
|
||||
}
|
||||
|
||||
static void swap (value_t& t1, json_value& v1, value_t& t2, json_value& v2)
|
||||
{
|
||||
using std::swap;
|
||||
if (t1 == t2)
|
||||
{
|
||||
switch (t1)
|
||||
{
|
||||
case value_t::object:
|
||||
{
|
||||
swap(v1.object, v2.object);
|
||||
break;
|
||||
}
|
||||
case value_t::array:
|
||||
{
|
||||
swap(v1.array, v2.array);
|
||||
break;
|
||||
}
|
||||
case value_t::string:
|
||||
{
|
||||
swap(v1.string, v2.string);
|
||||
break;
|
||||
}
|
||||
case value_t::binary:
|
||||
{
|
||||
swap(v1.binary, v2.binary);
|
||||
break;
|
||||
}
|
||||
case value_t::boolean:
|
||||
{
|
||||
swap(v1.boolean, v2.boolean);
|
||||
break;
|
||||
}
|
||||
case value_t::number_integer:
|
||||
{
|
||||
swap(v1.number_integer, v2.number_integer);
|
||||
break;
|
||||
}
|
||||
case value_t::number_unsigned:
|
||||
{
|
||||
swap(v1.number_unsigned, v2.number_unsigned);
|
||||
break;
|
||||
}
|
||||
case value_t::number_float:
|
||||
{
|
||||
swap(v1.number_float, v2.number_float);
|
||||
break;
|
||||
}
|
||||
case value_t::discarded:
|
||||
case value_t::null:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
json_value tmp;
|
||||
new (&tmp) json_value(t1, std::move(v1));
|
||||
new (&v1) json_value(t2, std::move(v2));
|
||||
new (&v2) json_value(t1, std::move(tmp));
|
||||
swap(t1, t2);
|
||||
}
|
||||
}
|
||||
|
||||
void destroy(value_t t)
|
||||
{
|
||||
if (t == value_t::array || t == value_t::object)
|
||||
@ -636,11 +809,27 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
||||
break;
|
||||
}
|
||||
|
||||
case value_t::null:
|
||||
case value_t::boolean:
|
||||
{
|
||||
boolean.~boolean_t();
|
||||
break;
|
||||
}
|
||||
case value_t::number_integer:
|
||||
{
|
||||
number_integer.~number_integer_t();
|
||||
break;
|
||||
}
|
||||
case value_t::number_unsigned:
|
||||
{
|
||||
number_unsigned.~number_unsigned_t();
|
||||
break;
|
||||
}
|
||||
case value_t::number_float:
|
||||
{
|
||||
number_float.~number_float_t();
|
||||
break;
|
||||
}
|
||||
case value_t::null:
|
||||
case value_t::discarded:
|
||||
default:
|
||||
{
|
||||
@ -921,7 +1110,7 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
||||
{
|
||||
// the initializer list is a list of pairs -> create object
|
||||
m_type = value_t::object;
|
||||
m_value = value_t::object;
|
||||
new (&m_value) json_value (value_t::object);
|
||||
|
||||
for (auto& element_ref : init)
|
||||
{
|
||||
@ -949,7 +1138,7 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
||||
{
|
||||
auto res = basic_json();
|
||||
res.m_type = value_t::binary;
|
||||
res.m_value = init;
|
||||
new (&res.m_value) json_value(init);
|
||||
return res;
|
||||
}
|
||||
|
||||
@ -960,7 +1149,7 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
||||
{
|
||||
auto res = basic_json();
|
||||
res.m_type = value_t::binary;
|
||||
res.m_value = binary_t(init, subtype);
|
||||
new (&res.m_value) json_value(binary_t(init, subtype));
|
||||
return res;
|
||||
}
|
||||
|
||||
@ -971,7 +1160,7 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
||||
{
|
||||
auto res = basic_json();
|
||||
res.m_type = value_t::binary;
|
||||
res.m_value = std::move(init);
|
||||
new (&res.m_value) json_value(std::move(init));
|
||||
return res;
|
||||
}
|
||||
|
||||
@ -982,7 +1171,7 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
||||
{
|
||||
auto res = basic_json();
|
||||
res.m_type = value_t::binary;
|
||||
res.m_value = binary_t(std::move(init), subtype);
|
||||
new (&res.m_value) json_value(binary_t(std::move(init), subtype));
|
||||
return res;
|
||||
}
|
||||
|
||||
@ -1085,7 +1274,7 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
||||
|
||||
case value_t::string:
|
||||
{
|
||||
m_value = *first.m_object->m_value.string;
|
||||
new (&m_value) json_value(*first.m_object->m_value.string);
|
||||
break;
|
||||
}
|
||||
|
||||
@ -1105,7 +1294,7 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
||||
|
||||
case value_t::binary:
|
||||
{
|
||||
m_value = *first.m_object->m_value.binary;
|
||||
new (&m_value) json_value(*first.m_object->m_value.binary);
|
||||
break;
|
||||
}
|
||||
|
||||
@ -1141,49 +1330,50 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
||||
{
|
||||
case value_t::object:
|
||||
{
|
||||
m_value = *other.m_value.object;
|
||||
|
||||
new (&m_value) json_value(*other.m_value.object);
|
||||
break;
|
||||
}
|
||||
|
||||
case value_t::array:
|
||||
{
|
||||
m_value = *other.m_value.array;
|
||||
new (&m_value) json_value(*other.m_value.array);
|
||||
break;
|
||||
}
|
||||
|
||||
case value_t::string:
|
||||
{
|
||||
m_value = *other.m_value.string;
|
||||
new (&m_value) json_value(*other.m_value.string);
|
||||
break;
|
||||
}
|
||||
|
||||
case value_t::boolean:
|
||||
{
|
||||
m_value = other.m_value.boolean;
|
||||
new (&m_value) json_value(other.m_value.boolean);
|
||||
break;
|
||||
}
|
||||
|
||||
case value_t::number_integer:
|
||||
{
|
||||
m_value = other.m_value.number_integer;
|
||||
new (&m_value) json_value(other.m_value.number_integer);
|
||||
break;
|
||||
}
|
||||
|
||||
case value_t::number_unsigned:
|
||||
{
|
||||
m_value = other.m_value.number_unsigned;
|
||||
new (&m_value) json_value(other.m_value.number_unsigned);
|
||||
break;
|
||||
}
|
||||
|
||||
case value_t::number_float:
|
||||
{
|
||||
m_value = other.m_value.number_float;
|
||||
new (&m_value) json_value(other.m_value.number_float);
|
||||
break;
|
||||
}
|
||||
|
||||
case value_t::binary:
|
||||
{
|
||||
m_value = *other.m_value.binary;
|
||||
new (&m_value) json_value(*other.m_value.binary);
|
||||
break;
|
||||
}
|
||||
|
||||
@ -1201,14 +1391,13 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
||||
/// @sa https://json.nlohmann.me/api/basic_json/basic_json/
|
||||
basic_json(basic_json&& other) noexcept
|
||||
: m_type(std::move(other.m_type)),
|
||||
m_value(std::move(other.m_value))
|
||||
m_value(other.m_type, other.m_value)
|
||||
{
|
||||
// check that passed value is valid
|
||||
other.assert_invariant(false);
|
||||
|
||||
// invalidate payload
|
||||
other.m_type = value_t::null;
|
||||
other.m_value = {};
|
||||
|
||||
set_parents();
|
||||
assert_invariant();
|
||||
@ -1226,10 +1415,7 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
||||
// check that passed value is valid
|
||||
other.assert_invariant();
|
||||
|
||||
using std::swap;
|
||||
swap(m_type, other.m_type);
|
||||
swap(m_value, other.m_value);
|
||||
|
||||
json_value::swap(m_type, m_value, other.m_type, other.m_value);
|
||||
set_parents();
|
||||
assert_invariant();
|
||||
return *this;
|
||||
@ -3089,7 +3275,7 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
||||
if (is_null())
|
||||
{
|
||||
m_type = value_t::array;
|
||||
m_value = value_t::array;
|
||||
new (&m_value) json_value(value_t::array);
|
||||
assert_invariant();
|
||||
}
|
||||
|
||||
@ -3122,7 +3308,7 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
||||
if (is_null())
|
||||
{
|
||||
m_type = value_t::array;
|
||||
m_value = value_t::array;
|
||||
new (&m_value) json_value(value_t::array);
|
||||
assert_invariant();
|
||||
}
|
||||
|
||||
@ -3154,7 +3340,7 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
||||
if (is_null())
|
||||
{
|
||||
m_type = value_t::object;
|
||||
m_value = value_t::object;
|
||||
new (&m_value) json_value(value_t::object);
|
||||
assert_invariant();
|
||||
}
|
||||
|
||||
@ -3210,7 +3396,7 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
||||
if (is_null())
|
||||
{
|
||||
m_type = value_t::array;
|
||||
m_value = value_t::array;
|
||||
new (&m_value) json_value(value_t::array);
|
||||
assert_invariant();
|
||||
}
|
||||
|
||||
@ -3235,7 +3421,7 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
||||
if (is_null())
|
||||
{
|
||||
m_type = value_t::object;
|
||||
m_value = value_t::object;
|
||||
new (&m_value) json_value(value_t::object);
|
||||
assert_invariant();
|
||||
}
|
||||
|
||||
@ -3458,8 +3644,7 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
||||
std::is_nothrow_move_assignable<json_value>::value
|
||||
)
|
||||
{
|
||||
std::swap(m_type, other.m_type);
|
||||
std::swap(m_value, other.m_value);
|
||||
json_value::swap(m_type, m_value, other.m_type, other.m_value);
|
||||
|
||||
set_parents();
|
||||
other.set_parents();
|
||||
@ -4184,7 +4369,7 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
||||
value_t m_type = value_t::null;
|
||||
|
||||
/// the value of the current element
|
||||
json_value m_value = {};
|
||||
json_value m_value;
|
||||
|
||||
#if JSON_DIAGNOSTICS
|
||||
/// a pointer to a parent value (for debugging purposes)
|
||||
|
||||
@ -3837,8 +3837,8 @@ struct is_compatible_integer_type_impl : std::false_type {};
|
||||
template<typename RealIntegerType, typename CompatibleNumberIntegerType>
|
||||
struct is_compatible_integer_type_impl <
|
||||
RealIntegerType, CompatibleNumberIntegerType,
|
||||
enable_if_t < std::is_integral<RealIntegerType>::value&&
|
||||
std::is_integral<CompatibleNumberIntegerType>::value&&
|
||||
enable_if_t < std::numeric_limits<RealIntegerType>::is_integer&&
|
||||
std::numeric_limits<CompatibleNumberIntegerType>::is_integer&&
|
||||
!std::is_same<bool, CompatibleNumberIntegerType>::value >>
|
||||
{
|
||||
// is there an assert somewhere on overflows?
|
||||
@ -4601,7 +4601,7 @@ inline void from_json(const BasicJsonType& j, typename std::nullptr_t& n)
|
||||
|
||||
// overloads for basic_json template parameters
|
||||
template < typename BasicJsonType, typename ArithmeticType,
|
||||
enable_if_t < std::is_arithmetic<ArithmeticType>::value&&
|
||||
enable_if_t < std::numeric_limits<ArithmeticType>::is_specialized&&
|
||||
!std::is_same<ArithmeticType, typename BasicJsonType::boolean_t>::value,
|
||||
int > = 0 >
|
||||
void get_arithmetic_value(const BasicJsonType& j, ArithmeticType& val)
|
||||
@ -5355,7 +5355,7 @@ struct external_constructor<value_t::boolean>
|
||||
{
|
||||
j.m_value.destroy(j.m_type);
|
||||
j.m_type = value_t::boolean;
|
||||
j.m_value = b;
|
||||
new (&j.m_value) typename BasicJsonType::json_value(b);
|
||||
j.assert_invariant();
|
||||
}
|
||||
};
|
||||
@ -5368,7 +5368,7 @@ struct external_constructor<value_t::string>
|
||||
{
|
||||
j.m_value.destroy(j.m_type);
|
||||
j.m_type = value_t::string;
|
||||
j.m_value = s;
|
||||
new (&j.m_value) typename BasicJsonType::json_value(s);
|
||||
j.assert_invariant();
|
||||
}
|
||||
|
||||
@ -5377,7 +5377,7 @@ struct external_constructor<value_t::string>
|
||||
{
|
||||
j.m_value.destroy(j.m_type);
|
||||
j.m_type = value_t::string;
|
||||
j.m_value = std::move(s);
|
||||
new (&j.m_value) typename BasicJsonType::json_value(std::move(s));
|
||||
j.assert_invariant();
|
||||
}
|
||||
|
||||
@ -5401,7 +5401,7 @@ struct external_constructor<value_t::binary>
|
||||
{
|
||||
j.m_value.destroy(j.m_type);
|
||||
j.m_type = value_t::binary;
|
||||
j.m_value = typename BasicJsonType::binary_t(b);
|
||||
new (&j.m_value) typename BasicJsonType::json_value(typename BasicJsonType::binary_t(b));
|
||||
j.assert_invariant();
|
||||
}
|
||||
|
||||
@ -5410,7 +5410,7 @@ struct external_constructor<value_t::binary>
|
||||
{
|
||||
j.m_value.destroy(j.m_type);
|
||||
j.m_type = value_t::binary;
|
||||
j.m_value = typename BasicJsonType::binary_t(std::move(b));
|
||||
new (&j.m_value) typename BasicJsonType::json_value(typename BasicJsonType::binary_t(std::move(b)));
|
||||
j.assert_invariant();
|
||||
}
|
||||
};
|
||||
@ -5423,7 +5423,7 @@ struct external_constructor<value_t::number_float>
|
||||
{
|
||||
j.m_value.destroy(j.m_type);
|
||||
j.m_type = value_t::number_float;
|
||||
j.m_value = val;
|
||||
new (&j.m_value) typename BasicJsonType::json_value(val);
|
||||
j.assert_invariant();
|
||||
}
|
||||
};
|
||||
@ -5436,7 +5436,7 @@ struct external_constructor<value_t::number_unsigned>
|
||||
{
|
||||
j.m_value.destroy(j.m_type);
|
||||
j.m_type = value_t::number_unsigned;
|
||||
j.m_value = val;
|
||||
new (&j.m_value) typename BasicJsonType::json_value(val);
|
||||
j.assert_invariant();
|
||||
}
|
||||
};
|
||||
@ -5449,7 +5449,7 @@ struct external_constructor<value_t::number_integer>
|
||||
{
|
||||
j.m_value.destroy(j.m_type);
|
||||
j.m_type = value_t::number_integer;
|
||||
j.m_value = val;
|
||||
new (&j.m_value) typename BasicJsonType::json_value(val);
|
||||
j.assert_invariant();
|
||||
}
|
||||
};
|
||||
@ -5462,7 +5462,7 @@ struct external_constructor<value_t::array>
|
||||
{
|
||||
j.m_value.destroy(j.m_type);
|
||||
j.m_type = value_t::array;
|
||||
j.m_value = arr;
|
||||
new (&j.m_value) typename BasicJsonType::json_value(arr);
|
||||
j.set_parents();
|
||||
j.assert_invariant();
|
||||
}
|
||||
@ -5472,7 +5472,7 @@ struct external_constructor<value_t::array>
|
||||
{
|
||||
j.m_value.destroy(j.m_type);
|
||||
j.m_type = value_t::array;
|
||||
j.m_value = std::move(arr);
|
||||
new (&j.m_value) typename BasicJsonType::json_value(std::move(arr));
|
||||
j.set_parents();
|
||||
j.assert_invariant();
|
||||
}
|
||||
@ -5497,7 +5497,7 @@ struct external_constructor<value_t::array>
|
||||
{
|
||||
j.m_value.destroy(j.m_type);
|
||||
j.m_type = value_t::array;
|
||||
j.m_value = value_t::array;
|
||||
new (&j.m_value) typename BasicJsonType::json_value(value_t::array);
|
||||
j.m_value.array->reserve(arr.size());
|
||||
for (const bool x : arr)
|
||||
{
|
||||
@ -5513,7 +5513,7 @@ struct external_constructor<value_t::array>
|
||||
{
|
||||
j.m_value.destroy(j.m_type);
|
||||
j.m_type = value_t::array;
|
||||
j.m_value = value_t::array;
|
||||
new (&j.m_value) typename BasicJsonType::json_value(value_t::array);
|
||||
j.m_value.array->resize(arr.size());
|
||||
if (arr.size() > 0)
|
||||
{
|
||||
@ -5532,7 +5532,7 @@ struct external_constructor<value_t::object>
|
||||
{
|
||||
j.m_value.destroy(j.m_type);
|
||||
j.m_type = value_t::object;
|
||||
j.m_value = obj;
|
||||
new (&j.m_value) typename BasicJsonType::json_value(obj);
|
||||
j.set_parents();
|
||||
j.assert_invariant();
|
||||
}
|
||||
@ -5542,7 +5542,7 @@ struct external_constructor<value_t::object>
|
||||
{
|
||||
j.m_value.destroy(j.m_type);
|
||||
j.m_type = value_t::object;
|
||||
j.m_value = std::move(obj);
|
||||
new (&j.m_value) typename BasicJsonType:: json_value(std::move(obj));
|
||||
j.set_parents();
|
||||
j.assert_invariant();
|
||||
}
|
||||
@ -8559,7 +8559,7 @@ scan_number_done:
|
||||
if (errno == 0)
|
||||
{
|
||||
value_unsigned = static_cast<number_unsigned_t>(x);
|
||||
if (value_unsigned == x)
|
||||
if (static_cast<long long>(value_unsigned) == x)
|
||||
{
|
||||
return token_type::value_unsigned;
|
||||
}
|
||||
@ -8575,7 +8575,7 @@ scan_number_done:
|
||||
if (errno == 0)
|
||||
{
|
||||
value_integer = static_cast<number_integer_t>(x);
|
||||
if (value_integer == x)
|
||||
if (static_cast<long long>(value_integer) == x)
|
||||
{
|
||||
return token_type::value_integer;
|
||||
}
|
||||
@ -18568,13 +18568,13 @@ class serializer
|
||||
}
|
||||
|
||||
// templates to avoid warnings about useless casts
|
||||
template <typename NumberType, enable_if_t<std::is_signed<NumberType>::value, int> = 0>
|
||||
template <typename NumberType, enable_if_t<std::numeric_limits<NumberType>::is_signed, int> = 0>
|
||||
bool is_negative_number(NumberType x)
|
||||
{
|
||||
return x < 0;
|
||||
return x < NumberType(0);
|
||||
}
|
||||
|
||||
template < typename NumberType, enable_if_t <std::is_unsigned<NumberType>::value, int > = 0 >
|
||||
template < typename NumberType, enable_if_t < !std::numeric_limits<NumberType>::is_signed, int > = 0 >
|
||||
bool is_negative_number(NumberType /*unused*/)
|
||||
{
|
||||
return false;
|
||||
@ -18590,7 +18590,7 @@ class serializer
|
||||
@tparam NumberType either @a number_integer_t or @a number_unsigned_t
|
||||
*/
|
||||
template < typename NumberType, detail::enable_if_t <
|
||||
std::is_integral<NumberType>::value ||
|
||||
std::numeric_limits<NumberType>::is_integer ||
|
||||
std::is_same<NumberType, number_unsigned_t>::value ||
|
||||
std::is_same<NumberType, number_integer_t>::value ||
|
||||
std::is_same<NumberType, binary_char_t>::value,
|
||||
@ -18614,7 +18614,7 @@ class serializer
|
||||
};
|
||||
|
||||
// special case for "0"
|
||||
if (x == 0)
|
||||
if (x == NumberType(0))
|
||||
{
|
||||
o->write_character('0');
|
||||
return;
|
||||
@ -18650,15 +18650,16 @@ class serializer
|
||||
|
||||
// Fast int2ascii implementation inspired by "Fastware" talk by Andrei Alexandrescu
|
||||
// See: https://www.youtube.com/watch?v=o4-CwDo2zpg
|
||||
while (abs_value >= 100)
|
||||
const NumberType hundred = 100;
|
||||
while (abs_value >= hundred)
|
||||
{
|
||||
const auto digits_index = static_cast<unsigned>((abs_value % 100));
|
||||
abs_value /= 100;
|
||||
const auto digits_index = static_cast<unsigned>((abs_value % hundred));
|
||||
abs_value /= hundred;
|
||||
*(--buffer_ptr) = digits_to_99[digits_index][1];
|
||||
*(--buffer_ptr) = digits_to_99[digits_index][0];
|
||||
}
|
||||
|
||||
if (abs_value >= 10)
|
||||
if (abs_value >= NumberType(10))
|
||||
{
|
||||
const auto digits_index = static_cast<unsigned>(abs_value);
|
||||
*(--buffer_ptr) = digits_to_99[digits_index][1];
|
||||
@ -19618,7 +19619,7 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
||||
number_float_t number_float;
|
||||
|
||||
/// default constructor (for null values)
|
||||
json_value() = default;
|
||||
json_value() {};
|
||||
/// constructor for booleans
|
||||
json_value(boolean_t v) noexcept : boolean(v) {}
|
||||
/// constructor for numbers (integer)
|
||||
@ -19729,6 +19730,179 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
||||
/// constructor for rvalue binary arrays (internal type)
|
||||
json_value(binary_t&& value) : binary(create<binary_t>(std::move(value))) {}
|
||||
|
||||
/// User is responsible for calling `destroy` first to make this safe
|
||||
~json_value() {}
|
||||
|
||||
json_value& operator=(json_value&) = delete;
|
||||
|
||||
/// Copy from an existing value of type t
|
||||
json_value(value_t t, const json_value& v)
|
||||
{
|
||||
switch (t)
|
||||
{
|
||||
case value_t::object:
|
||||
{
|
||||
new (this) json_value(v.object);
|
||||
break;
|
||||
}
|
||||
case value_t::array:
|
||||
{
|
||||
new (this) json_value(v.array);
|
||||
break;
|
||||
}
|
||||
case value_t::string:
|
||||
{
|
||||
new (this) json_value(v.string);
|
||||
break;
|
||||
}
|
||||
case value_t::binary:
|
||||
{
|
||||
new (this) json_value(v.binary);
|
||||
break;
|
||||
}
|
||||
case value_t::boolean:
|
||||
{
|
||||
new (this) json_value(v.boolean);
|
||||
break;
|
||||
}
|
||||
case value_t::number_integer:
|
||||
{
|
||||
new (this) json_value(v.number_integer);
|
||||
break;
|
||||
}
|
||||
case value_t::number_unsigned:
|
||||
{
|
||||
new (this) json_value(v.number_unsigned);
|
||||
break;
|
||||
}
|
||||
case value_t::number_float:
|
||||
{
|
||||
new (this) json_value(v.number_float);
|
||||
break;
|
||||
}
|
||||
case value_t::discarded:
|
||||
case value_t::null:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/// Move from an existing value of type t
|
||||
json_value(value_t t, json_value&& v)
|
||||
{
|
||||
switch (t)
|
||||
{
|
||||
case value_t::object:
|
||||
{
|
||||
new (this) json_value(std::move(v.object));
|
||||
break;
|
||||
}
|
||||
case value_t::array:
|
||||
{
|
||||
new (this) json_value(std::move(v.array));
|
||||
break;
|
||||
}
|
||||
case value_t::string:
|
||||
{
|
||||
new (this) json_value(std::move(v.string));
|
||||
break;
|
||||
}
|
||||
case value_t::binary:
|
||||
{
|
||||
new (this) json_value(std::move(v.binary));
|
||||
break;
|
||||
}
|
||||
case value_t::boolean:
|
||||
{
|
||||
new (this) json_value(std::move(v.boolean));
|
||||
break;
|
||||
}
|
||||
case value_t::number_integer:
|
||||
{
|
||||
new (this) json_value(std::move(v.number_integer));
|
||||
break;
|
||||
}
|
||||
case value_t::number_unsigned:
|
||||
{
|
||||
new (this) json_value(std::move(v.number_unsigned));
|
||||
break;
|
||||
}
|
||||
case value_t::number_float:
|
||||
{
|
||||
new (this) json_value(std::move(v.number_float));
|
||||
break;
|
||||
}
|
||||
case value_t::discarded:
|
||||
case value_t::null:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
v.destroy(t);
|
||||
}
|
||||
|
||||
static void swap (value_t& t1, json_value& v1, value_t& t2, json_value& v2)
|
||||
{
|
||||
using std::swap;
|
||||
if (t1 == t2)
|
||||
{
|
||||
switch (t1)
|
||||
{
|
||||
case value_t::object:
|
||||
{
|
||||
swap(v1.object, v2.object);
|
||||
break;
|
||||
}
|
||||
case value_t::array:
|
||||
{
|
||||
swap(v1.array, v2.array);
|
||||
break;
|
||||
}
|
||||
case value_t::string:
|
||||
{
|
||||
swap(v1.string, v2.string);
|
||||
break;
|
||||
}
|
||||
case value_t::binary:
|
||||
{
|
||||
swap(v1.binary, v2.binary);
|
||||
break;
|
||||
}
|
||||
case value_t::boolean:
|
||||
{
|
||||
swap(v1.boolean, v2.boolean);
|
||||
break;
|
||||
}
|
||||
case value_t::number_integer:
|
||||
{
|
||||
swap(v1.number_integer, v2.number_integer);
|
||||
break;
|
||||
}
|
||||
case value_t::number_unsigned:
|
||||
{
|
||||
swap(v1.number_unsigned, v2.number_unsigned);
|
||||
break;
|
||||
}
|
||||
case value_t::number_float:
|
||||
{
|
||||
swap(v1.number_float, v2.number_float);
|
||||
break;
|
||||
}
|
||||
case value_t::discarded:
|
||||
case value_t::null:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
json_value tmp;
|
||||
new (&tmp) json_value(t1, std::move(v1));
|
||||
new (&v1) json_value(t2, std::move(v2));
|
||||
new (&v2) json_value(t1, std::move(tmp));
|
||||
swap(t1, t2);
|
||||
}
|
||||
}
|
||||
|
||||
void destroy(value_t t)
|
||||
{
|
||||
if (t == value_t::array || t == value_t::object)
|
||||
@ -19814,11 +19988,27 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
||||
break;
|
||||
}
|
||||
|
||||
case value_t::null:
|
||||
case value_t::boolean:
|
||||
{
|
||||
boolean.~boolean_t();
|
||||
break;
|
||||
}
|
||||
case value_t::number_integer:
|
||||
{
|
||||
number_integer.~number_integer_t();
|
||||
break;
|
||||
}
|
||||
case value_t::number_unsigned:
|
||||
{
|
||||
number_unsigned.~number_unsigned_t();
|
||||
break;
|
||||
}
|
||||
case value_t::number_float:
|
||||
{
|
||||
number_float.~number_float_t();
|
||||
break;
|
||||
}
|
||||
case value_t::null:
|
||||
case value_t::discarded:
|
||||
default:
|
||||
{
|
||||
@ -20099,7 +20289,7 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
||||
{
|
||||
// the initializer list is a list of pairs -> create object
|
||||
m_type = value_t::object;
|
||||
m_value = value_t::object;
|
||||
new (&m_value) json_value (value_t::object);
|
||||
|
||||
for (auto& element_ref : init)
|
||||
{
|
||||
@ -20127,7 +20317,7 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
||||
{
|
||||
auto res = basic_json();
|
||||
res.m_type = value_t::binary;
|
||||
res.m_value = init;
|
||||
new (&res.m_value) json_value(init);
|
||||
return res;
|
||||
}
|
||||
|
||||
@ -20138,7 +20328,7 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
||||
{
|
||||
auto res = basic_json();
|
||||
res.m_type = value_t::binary;
|
||||
res.m_value = binary_t(init, subtype);
|
||||
new (&res.m_value) json_value(binary_t(init, subtype));
|
||||
return res;
|
||||
}
|
||||
|
||||
@ -20149,7 +20339,7 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
||||
{
|
||||
auto res = basic_json();
|
||||
res.m_type = value_t::binary;
|
||||
res.m_value = std::move(init);
|
||||
new (&res.m_value) json_value(std::move(init));
|
||||
return res;
|
||||
}
|
||||
|
||||
@ -20160,7 +20350,7 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
||||
{
|
||||
auto res = basic_json();
|
||||
res.m_type = value_t::binary;
|
||||
res.m_value = binary_t(std::move(init), subtype);
|
||||
new (&res.m_value) json_value(binary_t(std::move(init), subtype));
|
||||
return res;
|
||||
}
|
||||
|
||||
@ -20263,7 +20453,7 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
||||
|
||||
case value_t::string:
|
||||
{
|
||||
m_value = *first.m_object->m_value.string;
|
||||
new (&m_value) json_value(*first.m_object->m_value.string);
|
||||
break;
|
||||
}
|
||||
|
||||
@ -20283,7 +20473,7 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
||||
|
||||
case value_t::binary:
|
||||
{
|
||||
m_value = *first.m_object->m_value.binary;
|
||||
new (&m_value) json_value(*first.m_object->m_value.binary);
|
||||
break;
|
||||
}
|
||||
|
||||
@ -20319,49 +20509,50 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
||||
{
|
||||
case value_t::object:
|
||||
{
|
||||
m_value = *other.m_value.object;
|
||||
|
||||
new (&m_value) json_value(*other.m_value.object);
|
||||
break;
|
||||
}
|
||||
|
||||
case value_t::array:
|
||||
{
|
||||
m_value = *other.m_value.array;
|
||||
new (&m_value) json_value(*other.m_value.array);
|
||||
break;
|
||||
}
|
||||
|
||||
case value_t::string:
|
||||
{
|
||||
m_value = *other.m_value.string;
|
||||
new (&m_value) json_value(*other.m_value.string);
|
||||
break;
|
||||
}
|
||||
|
||||
case value_t::boolean:
|
||||
{
|
||||
m_value = other.m_value.boolean;
|
||||
new (&m_value) json_value(other.m_value.boolean);
|
||||
break;
|
||||
}
|
||||
|
||||
case value_t::number_integer:
|
||||
{
|
||||
m_value = other.m_value.number_integer;
|
||||
new (&m_value) json_value(other.m_value.number_integer);
|
||||
break;
|
||||
}
|
||||
|
||||
case value_t::number_unsigned:
|
||||
{
|
||||
m_value = other.m_value.number_unsigned;
|
||||
new (&m_value) json_value(other.m_value.number_unsigned);
|
||||
break;
|
||||
}
|
||||
|
||||
case value_t::number_float:
|
||||
{
|
||||
m_value = other.m_value.number_float;
|
||||
new (&m_value) json_value(other.m_value.number_float);
|
||||
break;
|
||||
}
|
||||
|
||||
case value_t::binary:
|
||||
{
|
||||
m_value = *other.m_value.binary;
|
||||
new (&m_value) json_value(*other.m_value.binary);
|
||||
break;
|
||||
}
|
||||
|
||||
@ -20379,14 +20570,13 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
||||
/// @sa https://json.nlohmann.me/api/basic_json/basic_json/
|
||||
basic_json(basic_json&& other) noexcept
|
||||
: m_type(std::move(other.m_type)),
|
||||
m_value(std::move(other.m_value))
|
||||
m_value(other.m_type, other.m_value)
|
||||
{
|
||||
// check that passed value is valid
|
||||
other.assert_invariant(false);
|
||||
|
||||
// invalidate payload
|
||||
other.m_type = value_t::null;
|
||||
other.m_value = {};
|
||||
|
||||
set_parents();
|
||||
assert_invariant();
|
||||
@ -20404,10 +20594,7 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
||||
// check that passed value is valid
|
||||
other.assert_invariant();
|
||||
|
||||
using std::swap;
|
||||
swap(m_type, other.m_type);
|
||||
swap(m_value, other.m_value);
|
||||
|
||||
json_value::swap(m_type, m_value, other.m_type, other.m_value);
|
||||
set_parents();
|
||||
assert_invariant();
|
||||
return *this;
|
||||
@ -22267,7 +22454,7 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
||||
if (is_null())
|
||||
{
|
||||
m_type = value_t::array;
|
||||
m_value = value_t::array;
|
||||
new (&m_value) json_value(value_t::array);
|
||||
assert_invariant();
|
||||
}
|
||||
|
||||
@ -22300,7 +22487,7 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
||||
if (is_null())
|
||||
{
|
||||
m_type = value_t::array;
|
||||
m_value = value_t::array;
|
||||
new (&m_value) json_value(value_t::array);
|
||||
assert_invariant();
|
||||
}
|
||||
|
||||
@ -22332,7 +22519,7 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
||||
if (is_null())
|
||||
{
|
||||
m_type = value_t::object;
|
||||
m_value = value_t::object;
|
||||
new (&m_value) json_value(value_t::object);
|
||||
assert_invariant();
|
||||
}
|
||||
|
||||
@ -22388,7 +22575,7 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
||||
if (is_null())
|
||||
{
|
||||
m_type = value_t::array;
|
||||
m_value = value_t::array;
|
||||
new (&m_value) json_value(value_t::array);
|
||||
assert_invariant();
|
||||
}
|
||||
|
||||
@ -22413,7 +22600,7 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
||||
if (is_null())
|
||||
{
|
||||
m_type = value_t::object;
|
||||
m_value = value_t::object;
|
||||
new (&m_value) json_value(value_t::object);
|
||||
assert_invariant();
|
||||
}
|
||||
|
||||
@ -22636,8 +22823,7 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
||||
std::is_nothrow_move_assignable<json_value>::value
|
||||
)
|
||||
{
|
||||
std::swap(m_type, other.m_type);
|
||||
std::swap(m_value, other.m_value);
|
||||
json_value::swap(m_type, m_value, other.m_type, other.m_value);
|
||||
|
||||
set_parents();
|
||||
other.set_parents();
|
||||
@ -23362,7 +23548,7 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
||||
value_t m_type = value_t::null;
|
||||
|
||||
/// the value of the current element
|
||||
json_value m_value = {};
|
||||
json_value m_value;
|
||||
|
||||
#if JSON_DIAGNOSTICS
|
||||
/// a pointer to a parent value (for debugging purposes)
|
||||
|
||||
114
tests/src/unit-custom-integer.cpp
Normal file
114
tests/src/unit-custom-integer.cpp
Normal file
@ -0,0 +1,114 @@
|
||||
/*
|
||||
__ _____ _____ _____
|
||||
__| | __| | | | JSON for Modern C++ (test suite)
|
||||
| | |__ | | | | | | version 3.10.5
|
||||
|_____|_____|_____|_|___| https://github.com/nlohmann/json
|
||||
|
||||
Licensed under the MIT License <http://opensource.org/licenses/MIT>.
|
||||
SPDX-License-Identifier: MIT
|
||||
Copyright (c) 2013-2022 Niels Lohmann <http://nlohmann.me>.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "doctest_compatibility.h"
|
||||
|
||||
#include <nlohmann/json.hpp>
|
||||
using nlohmann::json;
|
||||
|
||||
/// A `int
|
||||
template<typename T>
|
||||
class heap_int
|
||||
{
|
||||
public:
|
||||
std::unique_ptr<T> val;
|
||||
operator T() const
|
||||
{
|
||||
return val == nullptr ? 0 : *val;
|
||||
}
|
||||
// operator double() const { return static_cast<T>(val); }
|
||||
heap_int() : val() {}
|
||||
heap_int(T val) : val(new T(val)) {}
|
||||
heap_int(heap_int&&) = default;
|
||||
heap_int(const heap_int& other) : val(new T(static_cast<T>(other))) {}
|
||||
|
||||
heap_int& operator=(const heap_int& other)
|
||||
{
|
||||
val = std::unique_ptr<T>(new T(static_cast<T>(other)));
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool operator==(const heap_int& other) const
|
||||
{
|
||||
return static_cast<T>(*this) == static_cast<T>(other);
|
||||
}
|
||||
bool operator<(const int& other) const
|
||||
{
|
||||
return static_cast<T>(*this) < other;
|
||||
}
|
||||
heap_int operator+(const heap_int& other) const
|
||||
{
|
||||
return static_cast<T>(*this) + static_cast<T>(other);
|
||||
}
|
||||
bool operator%(const heap_int& other) const
|
||||
{
|
||||
return static_cast<T>(*this) % static_cast<T>(other.val);
|
||||
}
|
||||
heap_int& operator/=(const heap_int& other)
|
||||
{
|
||||
if (val != nullptr)
|
||||
{
|
||||
*val /= static_cast<T>(other.val);
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
bool operator<(const heap_int& other) const
|
||||
{
|
||||
return static_cast<T>(*this) < static_cast<T>(other.val);
|
||||
}
|
||||
bool operator<=(const heap_int& other) const
|
||||
{
|
||||
return static_cast<T>(*this) <= static_cast<T>(other.val);
|
||||
}
|
||||
|
||||
friend void swap(heap_int& self, heap_int& other)
|
||||
{
|
||||
swap(self.val, other.val);
|
||||
}
|
||||
};
|
||||
|
||||
template<typename T> class std::numeric_limits<heap_int<T>>
|
||||
{
|
||||
public:
|
||||
static constexpr bool is_signed = std::numeric_limits<T>::is_signed;
|
||||
static constexpr bool is_integer = std::numeric_limits<T>::is_integer;
|
||||
static constexpr bool is_specialized = std::numeric_limits<T>::is_specialized;
|
||||
};
|
||||
|
||||
TEST_CASE("custom integer type")
|
||||
{
|
||||
using json = nlohmann::basic_json <
|
||||
std::map, std::vector, std::string, bool, heap_int<std::int64_t>, std::uint64_t, double, std::allocator >;
|
||||
// create a JSON value with different types
|
||||
std::string data = "[1,2,3,4]";
|
||||
json as_json = json::parse(data.begin(), data.end());
|
||||
heap_int<std::int64_t> i = as_json[2];
|
||||
heap_int<std::int64_t> three = 3;
|
||||
CHECK(i == three);
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user