Prevent memory leak when exception is thrown in adl_serializer::to_json (#3901)

Co-authored-by: barcode <barcode@example.com>
This commit is contained in:
Raphael Grimm 2023-03-08 13:43:45 +01:00 committed by GitHub
parent fe4b66355c
commit bbe337c3a3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
15 changed files with 1321 additions and 1167 deletions

View File

@ -7,11 +7,11 @@ check_task:
- tar xfz cmake-3.20.2.tar.gz - tar xfz cmake-3.20.2.tar.gz
- cd cmake-3.20.2 - cd cmake-3.20.2
- ./configure - ./configure
- make cmake ctest -j10 - make cmake ctest -j4
- cd .. - cd ..
- mkdir build - mkdir build
- cd build - cd build
- ../cmake-3.20.2/bin/cmake .. -DJSON_FastTests=ON - ../cmake-3.20.2/bin/cmake .. -DJSON_FastTests=ON
- make -j10 - make -j4
- cd tests - cd tests
- ../../cmake-3.20.2/bin/ctest -j10 - ../../cmake-3.20.2/bin/ctest -j4

View File

@ -34,7 +34,7 @@ namespace detail
/* /*
* Note all external_constructor<>::construct functions need to call * Note all external_constructor<>::construct functions need to call
* j.m_value.destroy(j.m_type) to avoid a memory leak in case j contains an * j.m_data.m_value.destroy(j.m_data.m_type) to avoid a memory leak in case j contains an
* allocated value (e.g., a string). See bug issue * allocated value (e.g., a string). See bug issue
* https://github.com/nlohmann/json/issues/2865 for more information. * https://github.com/nlohmann/json/issues/2865 for more information.
*/ */
@ -47,9 +47,9 @@ struct external_constructor<value_t::boolean>
template<typename BasicJsonType> template<typename BasicJsonType>
static void construct(BasicJsonType& j, typename BasicJsonType::boolean_t b) noexcept static void construct(BasicJsonType& j, typename BasicJsonType::boolean_t b) noexcept
{ {
j.m_value.destroy(j.m_type); j.m_data.m_value.destroy(j.m_data.m_type);
j.m_type = value_t::boolean; j.m_data.m_type = value_t::boolean;
j.m_value = b; j.m_data.m_value = b;
j.assert_invariant(); j.assert_invariant();
} }
}; };
@ -60,18 +60,18 @@ struct external_constructor<value_t::string>
template<typename BasicJsonType> template<typename BasicJsonType>
static void construct(BasicJsonType& j, const typename BasicJsonType::string_t& s) static void construct(BasicJsonType& j, const typename BasicJsonType::string_t& s)
{ {
j.m_value.destroy(j.m_type); j.m_data.m_value.destroy(j.m_data.m_type);
j.m_type = value_t::string; j.m_data.m_type = value_t::string;
j.m_value = s; j.m_data.m_value = s;
j.assert_invariant(); j.assert_invariant();
} }
template<typename BasicJsonType> template<typename BasicJsonType>
static void construct(BasicJsonType& j, typename BasicJsonType::string_t&& s) static void construct(BasicJsonType& j, typename BasicJsonType::string_t&& s)
{ {
j.m_value.destroy(j.m_type); j.m_data.m_value.destroy(j.m_data.m_type);
j.m_type = value_t::string; j.m_data.m_type = value_t::string;
j.m_value = std::move(s); j.m_data.m_value = std::move(s);
j.assert_invariant(); j.assert_invariant();
} }
@ -80,9 +80,9 @@ struct external_constructor<value_t::string>
int > = 0 > int > = 0 >
static void construct(BasicJsonType& j, const CompatibleStringType& str) static void construct(BasicJsonType& j, const CompatibleStringType& str)
{ {
j.m_value.destroy(j.m_type); j.m_data.m_value.destroy(j.m_data.m_type);
j.m_type = value_t::string; j.m_data.m_type = value_t::string;
j.m_value.string = j.template create<typename BasicJsonType::string_t>(str); j.m_data.m_value.string = j.template create<typename BasicJsonType::string_t>(str);
j.assert_invariant(); j.assert_invariant();
} }
}; };
@ -93,18 +93,18 @@ struct external_constructor<value_t::binary>
template<typename BasicJsonType> template<typename BasicJsonType>
static void construct(BasicJsonType& j, const typename BasicJsonType::binary_t& b) static void construct(BasicJsonType& j, const typename BasicJsonType::binary_t& b)
{ {
j.m_value.destroy(j.m_type); j.m_data.m_value.destroy(j.m_data.m_type);
j.m_type = value_t::binary; j.m_data.m_type = value_t::binary;
j.m_value = typename BasicJsonType::binary_t(b); j.m_data.m_value = typename BasicJsonType::binary_t(b);
j.assert_invariant(); j.assert_invariant();
} }
template<typename BasicJsonType> template<typename BasicJsonType>
static void construct(BasicJsonType& j, typename BasicJsonType::binary_t&& b) static void construct(BasicJsonType& j, typename BasicJsonType::binary_t&& b)
{ {
j.m_value.destroy(j.m_type); j.m_data.m_value.destroy(j.m_data.m_type);
j.m_type = value_t::binary; j.m_data.m_type = value_t::binary;
j.m_value = typename BasicJsonType::binary_t(std::move(b)); j.m_data.m_value = typename BasicJsonType::binary_t(std::move(b));
j.assert_invariant(); j.assert_invariant();
} }
}; };
@ -115,9 +115,9 @@ struct external_constructor<value_t::number_float>
template<typename BasicJsonType> template<typename BasicJsonType>
static void construct(BasicJsonType& j, typename BasicJsonType::number_float_t val) noexcept static void construct(BasicJsonType& j, typename BasicJsonType::number_float_t val) noexcept
{ {
j.m_value.destroy(j.m_type); j.m_data.m_value.destroy(j.m_data.m_type);
j.m_type = value_t::number_float; j.m_data.m_type = value_t::number_float;
j.m_value = val; j.m_data.m_value = val;
j.assert_invariant(); j.assert_invariant();
} }
}; };
@ -128,9 +128,9 @@ struct external_constructor<value_t::number_unsigned>
template<typename BasicJsonType> template<typename BasicJsonType>
static void construct(BasicJsonType& j, typename BasicJsonType::number_unsigned_t val) noexcept static void construct(BasicJsonType& j, typename BasicJsonType::number_unsigned_t val) noexcept
{ {
j.m_value.destroy(j.m_type); j.m_data.m_value.destroy(j.m_data.m_type);
j.m_type = value_t::number_unsigned; j.m_data.m_type = value_t::number_unsigned;
j.m_value = val; j.m_data.m_value = val;
j.assert_invariant(); j.assert_invariant();
} }
}; };
@ -141,9 +141,9 @@ struct external_constructor<value_t::number_integer>
template<typename BasicJsonType> template<typename BasicJsonType>
static void construct(BasicJsonType& j, typename BasicJsonType::number_integer_t val) noexcept static void construct(BasicJsonType& j, typename BasicJsonType::number_integer_t val) noexcept
{ {
j.m_value.destroy(j.m_type); j.m_data.m_value.destroy(j.m_data.m_type);
j.m_type = value_t::number_integer; j.m_data.m_type = value_t::number_integer;
j.m_value = val; j.m_data.m_value = val;
j.assert_invariant(); j.assert_invariant();
} }
}; };
@ -154,9 +154,9 @@ struct external_constructor<value_t::array>
template<typename BasicJsonType> template<typename BasicJsonType>
static void construct(BasicJsonType& j, const typename BasicJsonType::array_t& arr) static void construct(BasicJsonType& j, const typename BasicJsonType::array_t& arr)
{ {
j.m_value.destroy(j.m_type); j.m_data.m_value.destroy(j.m_data.m_type);
j.m_type = value_t::array; j.m_data.m_type = value_t::array;
j.m_value = arr; j.m_data.m_value = arr;
j.set_parents(); j.set_parents();
j.assert_invariant(); j.assert_invariant();
} }
@ -164,9 +164,9 @@ struct external_constructor<value_t::array>
template<typename BasicJsonType> template<typename BasicJsonType>
static void construct(BasicJsonType& j, typename BasicJsonType::array_t&& arr) static void construct(BasicJsonType& j, typename BasicJsonType::array_t&& arr)
{ {
j.m_value.destroy(j.m_type); j.m_data.m_value.destroy(j.m_data.m_type);
j.m_type = value_t::array; j.m_data.m_type = value_t::array;
j.m_value = std::move(arr); j.m_data.m_value = std::move(arr);
j.set_parents(); j.set_parents();
j.assert_invariant(); j.assert_invariant();
} }
@ -179,9 +179,9 @@ struct external_constructor<value_t::array>
using std::begin; using std::begin;
using std::end; using std::end;
j.m_value.destroy(j.m_type); j.m_data.m_value.destroy(j.m_data.m_type);
j.m_type = value_t::array; j.m_data.m_type = value_t::array;
j.m_value.array = j.template create<typename BasicJsonType::array_t>(begin(arr), end(arr)); j.m_data.m_value.array = j.template create<typename BasicJsonType::array_t>(begin(arr), end(arr));
j.set_parents(); j.set_parents();
j.assert_invariant(); j.assert_invariant();
} }
@ -189,14 +189,14 @@ struct external_constructor<value_t::array>
template<typename BasicJsonType> template<typename BasicJsonType>
static void construct(BasicJsonType& j, const std::vector<bool>& arr) static void construct(BasicJsonType& j, const std::vector<bool>& arr)
{ {
j.m_value.destroy(j.m_type); j.m_data.m_value.destroy(j.m_data.m_type);
j.m_type = value_t::array; j.m_data.m_type = value_t::array;
j.m_value = value_t::array; j.m_data.m_value = value_t::array;
j.m_value.array->reserve(arr.size()); j.m_data.m_value.array->reserve(arr.size());
for (const bool x : arr) for (const bool x : arr)
{ {
j.m_value.array->push_back(x); j.m_data.m_value.array->push_back(x);
j.set_parent(j.m_value.array->back()); j.set_parent(j.m_data.m_value.array->back());
} }
j.assert_invariant(); j.assert_invariant();
} }
@ -205,13 +205,13 @@ struct external_constructor<value_t::array>
enable_if_t<std::is_convertible<T, BasicJsonType>::value, int> = 0> enable_if_t<std::is_convertible<T, BasicJsonType>::value, int> = 0>
static void construct(BasicJsonType& j, const std::valarray<T>& arr) static void construct(BasicJsonType& j, const std::valarray<T>& arr)
{ {
j.m_value.destroy(j.m_type); j.m_data.m_value.destroy(j.m_data.m_type);
j.m_type = value_t::array; j.m_data.m_type = value_t::array;
j.m_value = value_t::array; j.m_data.m_value = value_t::array;
j.m_value.array->resize(arr.size()); j.m_data.m_value.array->resize(arr.size());
if (arr.size() > 0) if (arr.size() > 0)
{ {
std::copy(std::begin(arr), std::end(arr), j.m_value.array->begin()); std::copy(std::begin(arr), std::end(arr), j.m_data.m_value.array->begin());
} }
j.set_parents(); j.set_parents();
j.assert_invariant(); j.assert_invariant();
@ -224,9 +224,9 @@ struct external_constructor<value_t::object>
template<typename BasicJsonType> template<typename BasicJsonType>
static void construct(BasicJsonType& j, const typename BasicJsonType::object_t& obj) static void construct(BasicJsonType& j, const typename BasicJsonType::object_t& obj)
{ {
j.m_value.destroy(j.m_type); j.m_data.m_value.destroy(j.m_data.m_type);
j.m_type = value_t::object; j.m_data.m_type = value_t::object;
j.m_value = obj; j.m_data.m_value = obj;
j.set_parents(); j.set_parents();
j.assert_invariant(); j.assert_invariant();
} }
@ -234,9 +234,9 @@ struct external_constructor<value_t::object>
template<typename BasicJsonType> template<typename BasicJsonType>
static void construct(BasicJsonType& j, typename BasicJsonType::object_t&& obj) static void construct(BasicJsonType& j, typename BasicJsonType::object_t&& obj)
{ {
j.m_value.destroy(j.m_type); j.m_data.m_value.destroy(j.m_data.m_type);
j.m_type = value_t::object; j.m_data.m_type = value_t::object;
j.m_value = std::move(obj); j.m_data.m_value = std::move(obj);
j.set_parents(); j.set_parents();
j.assert_invariant(); j.assert_invariant();
} }
@ -248,9 +248,9 @@ struct external_constructor<value_t::object>
using std::begin; using std::begin;
using std::end; using std::end;
j.m_value.destroy(j.m_type); j.m_data.m_value.destroy(j.m_data.m_type);
j.m_type = value_t::object; j.m_data.m_type = value_t::object;
j.m_value.object = j.template create<typename BasicJsonType::object_t>(begin(obj), end(obj)); j.m_data.m_value.object = j.template create<typename BasicJsonType::object_t>(begin(obj), end(obj));
j.set_parents(); j.set_parents();
j.assert_invariant(); j.assert_invariant();
} }

View File

@ -73,9 +73,9 @@ class exception : public std::exception
{ {
case value_t::array: case value_t::array:
{ {
for (std::size_t i = 0; i < current->m_parent->m_value.array->size(); ++i) for (std::size_t i = 0; i < current->m_parent->m_data.m_value.array->size(); ++i)
{ {
if (&current->m_parent->m_value.array->operator[](i) == current) if (&current->m_parent->m_data.m_value.array->operator[](i) == current)
{ {
tokens.emplace_back(std::to_string(i)); tokens.emplace_back(std::to_string(i));
break; break;
@ -86,7 +86,7 @@ class exception : public std::exception
case value_t::object: case value_t::object:
{ {
for (const auto& element : *current->m_parent->m_value.object) for (const auto& element : *current->m_parent->m_data.m_value.object)
{ {
if (&element.second == current) if (&element.second == current)
{ {

View File

@ -244,7 +244,7 @@ class json_sax_dom_parser
JSON_ASSERT(ref_stack.back()->is_object()); JSON_ASSERT(ref_stack.back()->is_object());
// add null at given key and store the reference for later // add null at given key and store the reference for later
object_element = &(ref_stack.back()->m_value.object->operator[](val)); object_element = &(ref_stack.back()->m_data.m_value.object->operator[](val));
return true; return true;
} }
@ -319,8 +319,8 @@ class json_sax_dom_parser
if (ref_stack.back()->is_array()) if (ref_stack.back()->is_array())
{ {
ref_stack.back()->m_value.array->emplace_back(std::forward<Value>(v)); ref_stack.back()->m_data.m_value.array->emplace_back(std::forward<Value>(v));
return &(ref_stack.back()->m_value.array->back()); return &(ref_stack.back()->m_data.m_value.array->back());
} }
JSON_ASSERT(ref_stack.back()->is_object()); JSON_ASSERT(ref_stack.back()->is_object());
@ -439,7 +439,7 @@ class json_sax_dom_callback_parser
// add discarded value at given key and store the reference for later // add discarded value at given key and store the reference for later
if (keep && ref_stack.back()) if (keep && ref_stack.back())
{ {
object_element = &(ref_stack.back()->m_value.object->operator[](val) = discarded); object_element = &(ref_stack.back()->m_data.m_value.object->operator[](val) = discarded);
} }
return true; return true;
@ -524,7 +524,7 @@ class json_sax_dom_callback_parser
// remove discarded value // remove discarded value
if (!keep && !ref_stack.empty() && ref_stack.back()->is_array()) if (!keep && !ref_stack.empty() && ref_stack.back()->is_array())
{ {
ref_stack.back()->m_value.array->pop_back(); ref_stack.back()->m_data.m_value.array->pop_back();
} }
return true; return true;
@ -607,8 +607,8 @@ class json_sax_dom_callback_parser
// array // array
if (ref_stack.back()->is_array()) if (ref_stack.back()->is_array())
{ {
ref_stack.back()->m_value.array->emplace_back(std::move(value)); ref_stack.back()->m_data.m_value.array->emplace_back(std::move(value));
return {true, &(ref_stack.back()->m_value.array->back())}; return {true, &(ref_stack.back()->m_data.m_value.array->back())};
} }
// object // object

View File

@ -101,7 +101,7 @@ class iter_impl // NOLINT(cppcoreguidelines-special-member-functions,hicpp-speci
{ {
JSON_ASSERT(m_object != nullptr); JSON_ASSERT(m_object != nullptr);
switch (m_object->m_type) switch (m_object->m_data.m_type)
{ {
case value_t::object: case value_t::object:
{ {
@ -198,17 +198,17 @@ class iter_impl // NOLINT(cppcoreguidelines-special-member-functions,hicpp-speci
{ {
JSON_ASSERT(m_object != nullptr); JSON_ASSERT(m_object != nullptr);
switch (m_object->m_type) switch (m_object->m_data.m_type)
{ {
case value_t::object: case value_t::object:
{ {
m_it.object_iterator = m_object->m_value.object->begin(); m_it.object_iterator = m_object->m_data.m_value.object->begin();
break; break;
} }
case value_t::array: case value_t::array:
{ {
m_it.array_iterator = m_object->m_value.array->begin(); m_it.array_iterator = m_object->m_data.m_value.array->begin();
break; break;
} }
@ -242,17 +242,17 @@ class iter_impl // NOLINT(cppcoreguidelines-special-member-functions,hicpp-speci
{ {
JSON_ASSERT(m_object != nullptr); JSON_ASSERT(m_object != nullptr);
switch (m_object->m_type) switch (m_object->m_data.m_type)
{ {
case value_t::object: case value_t::object:
{ {
m_it.object_iterator = m_object->m_value.object->end(); m_it.object_iterator = m_object->m_data.m_value.object->end();
break; break;
} }
case value_t::array: case value_t::array:
{ {
m_it.array_iterator = m_object->m_value.array->end(); m_it.array_iterator = m_object->m_data.m_value.array->end();
break; break;
} }
@ -281,17 +281,17 @@ class iter_impl // NOLINT(cppcoreguidelines-special-member-functions,hicpp-speci
{ {
JSON_ASSERT(m_object != nullptr); JSON_ASSERT(m_object != nullptr);
switch (m_object->m_type) switch (m_object->m_data.m_type)
{ {
case value_t::object: case value_t::object:
{ {
JSON_ASSERT(m_it.object_iterator != m_object->m_value.object->end()); JSON_ASSERT(m_it.object_iterator != m_object->m_data.m_value.object->end());
return m_it.object_iterator->second; return m_it.object_iterator->second;
} }
case value_t::array: case value_t::array:
{ {
JSON_ASSERT(m_it.array_iterator != m_object->m_value.array->end()); JSON_ASSERT(m_it.array_iterator != m_object->m_data.m_value.array->end());
return *m_it.array_iterator; return *m_it.array_iterator;
} }
@ -325,17 +325,17 @@ class iter_impl // NOLINT(cppcoreguidelines-special-member-functions,hicpp-speci
{ {
JSON_ASSERT(m_object != nullptr); JSON_ASSERT(m_object != nullptr);
switch (m_object->m_type) switch (m_object->m_data.m_type)
{ {
case value_t::object: case value_t::object:
{ {
JSON_ASSERT(m_it.object_iterator != m_object->m_value.object->end()); JSON_ASSERT(m_it.object_iterator != m_object->m_data.m_value.object->end());
return &(m_it.object_iterator->second); return &(m_it.object_iterator->second);
} }
case value_t::array: case value_t::array:
{ {
JSON_ASSERT(m_it.array_iterator != m_object->m_value.array->end()); JSON_ASSERT(m_it.array_iterator != m_object->m_data.m_value.array->end());
return &*m_it.array_iterator; return &*m_it.array_iterator;
} }
@ -378,7 +378,7 @@ class iter_impl // NOLINT(cppcoreguidelines-special-member-functions,hicpp-speci
{ {
JSON_ASSERT(m_object != nullptr); JSON_ASSERT(m_object != nullptr);
switch (m_object->m_type) switch (m_object->m_data.m_type)
{ {
case value_t::object: case value_t::object:
{ {
@ -429,7 +429,7 @@ class iter_impl // NOLINT(cppcoreguidelines-special-member-functions,hicpp-speci
{ {
JSON_ASSERT(m_object != nullptr); JSON_ASSERT(m_object != nullptr);
switch (m_object->m_type) switch (m_object->m_data.m_type)
{ {
case value_t::object: case value_t::object:
{ {
@ -476,7 +476,7 @@ class iter_impl // NOLINT(cppcoreguidelines-special-member-functions,hicpp-speci
JSON_ASSERT(m_object != nullptr); JSON_ASSERT(m_object != nullptr);
switch (m_object->m_type) switch (m_object->m_data.m_type)
{ {
case value_t::object: case value_t::object:
return (m_it.object_iterator == other.m_it.object_iterator); return (m_it.object_iterator == other.m_it.object_iterator);
@ -521,7 +521,7 @@ class iter_impl // NOLINT(cppcoreguidelines-special-member-functions,hicpp-speci
JSON_ASSERT(m_object != nullptr); JSON_ASSERT(m_object != nullptr);
switch (m_object->m_type) switch (m_object->m_data.m_type)
{ {
case value_t::object: case value_t::object:
JSON_THROW(invalid_iterator::create(213, "cannot compare order of object iterators", m_object)); JSON_THROW(invalid_iterator::create(213, "cannot compare order of object iterators", m_object));
@ -577,7 +577,7 @@ class iter_impl // NOLINT(cppcoreguidelines-special-member-functions,hicpp-speci
{ {
JSON_ASSERT(m_object != nullptr); JSON_ASSERT(m_object != nullptr);
switch (m_object->m_type) switch (m_object->m_data.m_type)
{ {
case value_t::object: case value_t::object:
JSON_THROW(invalid_iterator::create(209, "cannot use offsets with object iterators", m_object)); JSON_THROW(invalid_iterator::create(209, "cannot use offsets with object iterators", m_object));
@ -656,7 +656,7 @@ class iter_impl // NOLINT(cppcoreguidelines-special-member-functions,hicpp-speci
{ {
JSON_ASSERT(m_object != nullptr); JSON_ASSERT(m_object != nullptr);
switch (m_object->m_type) switch (m_object->m_data.m_type)
{ {
case value_t::object: case value_t::object:
JSON_THROW(invalid_iterator::create(209, "cannot use offsets with object iterators", m_object)); JSON_THROW(invalid_iterator::create(209, "cannot use offsets with object iterators", m_object));
@ -685,7 +685,7 @@ class iter_impl // NOLINT(cppcoreguidelines-special-member-functions,hicpp-speci
{ {
JSON_ASSERT(m_object != nullptr); JSON_ASSERT(m_object != nullptr);
switch (m_object->m_type) switch (m_object->m_data.m_type)
{ {
case value_t::object: case value_t::object:
JSON_THROW(invalid_iterator::create(208, "cannot use operator[] for object iterators", m_object)); JSON_THROW(invalid_iterator::create(208, "cannot use operator[] for object iterators", m_object));

View File

@ -386,7 +386,7 @@ class json_pointer
if (reference_token == "-") if (reference_token == "-")
{ {
// explicitly treat "-" as index beyond the end // explicitly treat "-" as index beyond the end
ptr = &ptr->operator[](ptr->m_value.array->size()); ptr = &ptr->operator[](ptr->m_data.m_value.array->size());
} }
else else
{ {
@ -438,7 +438,7 @@ class json_pointer
{ {
// "-" always fails the range check // "-" always fails the range check
JSON_THROW(detail::out_of_range::create(402, detail::concat( JSON_THROW(detail::out_of_range::create(402, detail::concat(
"array index '-' (", std::to_string(ptr->m_value.array->size()), "array index '-' (", std::to_string(ptr->m_data.m_value.array->size()),
") is out of range"), ptr)); ") is out of range"), ptr));
} }
@ -495,7 +495,7 @@ class json_pointer
if (JSON_HEDLEY_UNLIKELY(reference_token == "-")) if (JSON_HEDLEY_UNLIKELY(reference_token == "-"))
{ {
// "-" cannot be used for const access // "-" cannot be used for const access
JSON_THROW(detail::out_of_range::create(402, detail::concat("array index '-' (", std::to_string(ptr->m_value.array->size()), ") is out of range"), ptr)); JSON_THROW(detail::out_of_range::create(402, detail::concat("array index '-' (", std::to_string(ptr->m_data.m_value.array->size()), ") is out of range"), ptr));
} }
// use unchecked array access // use unchecked array access
@ -545,7 +545,7 @@ class json_pointer
{ {
// "-" always fails the range check // "-" always fails the range check
JSON_THROW(detail::out_of_range::create(402, detail::concat( JSON_THROW(detail::out_of_range::create(402, detail::concat(
"array index '-' (", std::to_string(ptr->m_value.array->size()), "array index '-' (", std::to_string(ptr->m_data.m_value.array->size()),
") is out of range"), ptr)); ") is out of range"), ptr));
} }
@ -740,7 +740,7 @@ class json_pointer
{ {
case detail::value_t::array: case detail::value_t::array:
{ {
if (value.m_value.array->empty()) if (value.m_data.m_value.array->empty())
{ {
// flatten empty array as null // flatten empty array as null
result[reference_string] = nullptr; result[reference_string] = nullptr;
@ -748,10 +748,10 @@ class json_pointer
else else
{ {
// iterate array and use index as reference string // iterate array and use index as reference string
for (std::size_t i = 0; i < value.m_value.array->size(); ++i) for (std::size_t i = 0; i < value.m_data.m_value.array->size(); ++i)
{ {
flatten(detail::concat(reference_string, '/', std::to_string(i)), flatten(detail::concat(reference_string, '/', std::to_string(i)),
value.m_value.array->operator[](i), result); value.m_data.m_value.array->operator[](i), result);
} }
} }
break; break;
@ -759,7 +759,7 @@ class json_pointer
case detail::value_t::object: case detail::value_t::object:
{ {
if (value.m_value.object->empty()) if (value.m_data.m_value.object->empty())
{ {
// flatten empty object as null // flatten empty object as null
result[reference_string] = nullptr; result[reference_string] = nullptr;
@ -767,7 +767,7 @@ class json_pointer
else else
{ {
// iterate object and use keys as reference string // iterate object and use keys as reference string
for (const auto& element : *value.m_value.object) for (const auto& element : *value.m_data.m_value.object)
{ {
flatten(detail::concat(reference_string, '/', detail::escape(element.first)), element.second, result); flatten(detail::concat(reference_string, '/', detail::escape(element.first)), element.second, result);
} }
@ -814,7 +814,7 @@ class json_pointer
BasicJsonType result; BasicJsonType result;
// iterate the JSON object values // iterate the JSON object values
for (const auto& element : *value.m_value.object) for (const auto& element : *value.m_data.m_value.object)
{ {
if (JSON_HEDLEY_UNLIKELY(!element.second.is_primitive())) if (JSON_HEDLEY_UNLIKELY(!element.second.is_primitive()))
{ {

View File

@ -63,7 +63,7 @@ class binary_writer
{ {
case value_t::object: case value_t::object:
{ {
write_bson_object(*j.m_value.object); write_bson_object(*j.m_data.m_value.object);
break; break;
} }
@ -98,7 +98,7 @@ class binary_writer
case value_t::boolean: case value_t::boolean:
{ {
oa->write_character(j.m_value.boolean oa->write_character(j.m_data.m_value.boolean
? to_char_type(0xF5) ? to_char_type(0xF5)
: to_char_type(0xF4)); : to_char_type(0xF4));
break; break;
@ -106,42 +106,42 @@ class binary_writer
case value_t::number_integer: case value_t::number_integer:
{ {
if (j.m_value.number_integer >= 0) if (j.m_data.m_value.number_integer >= 0)
{ {
// CBOR does not differentiate between positive signed // CBOR does not differentiate between positive signed
// integers and unsigned integers. Therefore, we used the // integers and unsigned integers. Therefore, we used the
// code from the value_t::number_unsigned case here. // code from the value_t::number_unsigned case here.
if (j.m_value.number_integer <= 0x17) if (j.m_data.m_value.number_integer <= 0x17)
{ {
write_number(static_cast<std::uint8_t>(j.m_value.number_integer)); write_number(static_cast<std::uint8_t>(j.m_data.m_value.number_integer));
} }
else if (j.m_value.number_integer <= (std::numeric_limits<std::uint8_t>::max)()) else if (j.m_data.m_value.number_integer <= (std::numeric_limits<std::uint8_t>::max)())
{ {
oa->write_character(to_char_type(0x18)); oa->write_character(to_char_type(0x18));
write_number(static_cast<std::uint8_t>(j.m_value.number_integer)); write_number(static_cast<std::uint8_t>(j.m_data.m_value.number_integer));
} }
else if (j.m_value.number_integer <= (std::numeric_limits<std::uint16_t>::max)()) else if (j.m_data.m_value.number_integer <= (std::numeric_limits<std::uint16_t>::max)())
{ {
oa->write_character(to_char_type(0x19)); oa->write_character(to_char_type(0x19));
write_number(static_cast<std::uint16_t>(j.m_value.number_integer)); write_number(static_cast<std::uint16_t>(j.m_data.m_value.number_integer));
} }
else if (j.m_value.number_integer <= (std::numeric_limits<std::uint32_t>::max)()) else if (j.m_data.m_value.number_integer <= (std::numeric_limits<std::uint32_t>::max)())
{ {
oa->write_character(to_char_type(0x1A)); oa->write_character(to_char_type(0x1A));
write_number(static_cast<std::uint32_t>(j.m_value.number_integer)); write_number(static_cast<std::uint32_t>(j.m_data.m_value.number_integer));
} }
else else
{ {
oa->write_character(to_char_type(0x1B)); oa->write_character(to_char_type(0x1B));
write_number(static_cast<std::uint64_t>(j.m_value.number_integer)); write_number(static_cast<std::uint64_t>(j.m_data.m_value.number_integer));
} }
} }
else else
{ {
// The conversions below encode the sign in the first // The conversions below encode the sign in the first
// byte, and the value is converted to a positive number. // byte, and the value is converted to a positive number.
const auto positive_number = -1 - j.m_value.number_integer; const auto positive_number = -1 - j.m_data.m_value.number_integer;
if (j.m_value.number_integer >= -24) if (j.m_data.m_value.number_integer >= -24)
{ {
write_number(static_cast<std::uint8_t>(0x20 + positive_number)); write_number(static_cast<std::uint8_t>(0x20 + positive_number));
} }
@ -171,52 +171,52 @@ class binary_writer
case value_t::number_unsigned: case value_t::number_unsigned:
{ {
if (j.m_value.number_unsigned <= 0x17) if (j.m_data.m_value.number_unsigned <= 0x17)
{ {
write_number(static_cast<std::uint8_t>(j.m_value.number_unsigned)); write_number(static_cast<std::uint8_t>(j.m_data.m_value.number_unsigned));
} }
else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint8_t>::max)()) else if (j.m_data.m_value.number_unsigned <= (std::numeric_limits<std::uint8_t>::max)())
{ {
oa->write_character(to_char_type(0x18)); oa->write_character(to_char_type(0x18));
write_number(static_cast<std::uint8_t>(j.m_value.number_unsigned)); write_number(static_cast<std::uint8_t>(j.m_data.m_value.number_unsigned));
} }
else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint16_t>::max)()) else if (j.m_data.m_value.number_unsigned <= (std::numeric_limits<std::uint16_t>::max)())
{ {
oa->write_character(to_char_type(0x19)); oa->write_character(to_char_type(0x19));
write_number(static_cast<std::uint16_t>(j.m_value.number_unsigned)); write_number(static_cast<std::uint16_t>(j.m_data.m_value.number_unsigned));
} }
else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint32_t>::max)()) else if (j.m_data.m_value.number_unsigned <= (std::numeric_limits<std::uint32_t>::max)())
{ {
oa->write_character(to_char_type(0x1A)); oa->write_character(to_char_type(0x1A));
write_number(static_cast<std::uint32_t>(j.m_value.number_unsigned)); write_number(static_cast<std::uint32_t>(j.m_data.m_value.number_unsigned));
} }
else else
{ {
oa->write_character(to_char_type(0x1B)); oa->write_character(to_char_type(0x1B));
write_number(static_cast<std::uint64_t>(j.m_value.number_unsigned)); write_number(static_cast<std::uint64_t>(j.m_data.m_value.number_unsigned));
} }
break; break;
} }
case value_t::number_float: case value_t::number_float:
{ {
if (std::isnan(j.m_value.number_float)) if (std::isnan(j.m_data.m_value.number_float))
{ {
// NaN is 0xf97e00 in CBOR // NaN is 0xf97e00 in CBOR
oa->write_character(to_char_type(0xF9)); oa->write_character(to_char_type(0xF9));
oa->write_character(to_char_type(0x7E)); oa->write_character(to_char_type(0x7E));
oa->write_character(to_char_type(0x00)); oa->write_character(to_char_type(0x00));
} }
else if (std::isinf(j.m_value.number_float)) else if (std::isinf(j.m_data.m_value.number_float))
{ {
// Infinity is 0xf97c00, -Infinity is 0xf9fc00 // Infinity is 0xf97c00, -Infinity is 0xf9fc00
oa->write_character(to_char_type(0xf9)); oa->write_character(to_char_type(0xf9));
oa->write_character(j.m_value.number_float > 0 ? to_char_type(0x7C) : to_char_type(0xFC)); oa->write_character(j.m_data.m_value.number_float > 0 ? to_char_type(0x7C) : to_char_type(0xFC));
oa->write_character(to_char_type(0x00)); oa->write_character(to_char_type(0x00));
} }
else else
{ {
write_compact_float(j.m_value.number_float, detail::input_format_t::cbor); write_compact_float(j.m_data.m_value.number_float, detail::input_format_t::cbor);
} }
break; break;
} }
@ -224,7 +224,7 @@ class binary_writer
case value_t::string: case value_t::string:
{ {
// step 1: write control byte and the string length // step 1: write control byte and the string length
const auto N = j.m_value.string->size(); const auto N = j.m_data.m_value.string->size();
if (N <= 0x17) if (N <= 0x17)
{ {
write_number(static_cast<std::uint8_t>(0x60 + N)); write_number(static_cast<std::uint8_t>(0x60 + N));
@ -254,15 +254,15 @@ class binary_writer
// step 2: write the string // step 2: write the string
oa->write_characters( oa->write_characters(
reinterpret_cast<const CharType*>(j.m_value.string->c_str()), reinterpret_cast<const CharType*>(j.m_data.m_value.string->c_str()),
j.m_value.string->size()); j.m_data.m_value.string->size());
break; break;
} }
case value_t::array: case value_t::array:
{ {
// step 1: write control byte and the array size // step 1: write control byte and the array size
const auto N = j.m_value.array->size(); const auto N = j.m_data.m_value.array->size();
if (N <= 0x17) if (N <= 0x17)
{ {
write_number(static_cast<std::uint8_t>(0x80 + N)); write_number(static_cast<std::uint8_t>(0x80 + N));
@ -291,7 +291,7 @@ class binary_writer
// LCOV_EXCL_STOP // LCOV_EXCL_STOP
// step 2: write each element // step 2: write each element
for (const auto& el : *j.m_value.array) for (const auto& el : *j.m_data.m_value.array)
{ {
write_cbor(el); write_cbor(el);
} }
@ -300,32 +300,32 @@ class binary_writer
case value_t::binary: case value_t::binary:
{ {
if (j.m_value.binary->has_subtype()) if (j.m_data.m_value.binary->has_subtype())
{ {
if (j.m_value.binary->subtype() <= (std::numeric_limits<std::uint8_t>::max)()) if (j.m_data.m_value.binary->subtype() <= (std::numeric_limits<std::uint8_t>::max)())
{ {
write_number(static_cast<std::uint8_t>(0xd8)); write_number(static_cast<std::uint8_t>(0xd8));
write_number(static_cast<std::uint8_t>(j.m_value.binary->subtype())); write_number(static_cast<std::uint8_t>(j.m_data.m_value.binary->subtype()));
} }
else if (j.m_value.binary->subtype() <= (std::numeric_limits<std::uint16_t>::max)()) else if (j.m_data.m_value.binary->subtype() <= (std::numeric_limits<std::uint16_t>::max)())
{ {
write_number(static_cast<std::uint8_t>(0xd9)); write_number(static_cast<std::uint8_t>(0xd9));
write_number(static_cast<std::uint16_t>(j.m_value.binary->subtype())); write_number(static_cast<std::uint16_t>(j.m_data.m_value.binary->subtype()));
} }
else if (j.m_value.binary->subtype() <= (std::numeric_limits<std::uint32_t>::max)()) else if (j.m_data.m_value.binary->subtype() <= (std::numeric_limits<std::uint32_t>::max)())
{ {
write_number(static_cast<std::uint8_t>(0xda)); write_number(static_cast<std::uint8_t>(0xda));
write_number(static_cast<std::uint32_t>(j.m_value.binary->subtype())); write_number(static_cast<std::uint32_t>(j.m_data.m_value.binary->subtype()));
} }
else if (j.m_value.binary->subtype() <= (std::numeric_limits<std::uint64_t>::max)()) else if (j.m_data.m_value.binary->subtype() <= (std::numeric_limits<std::uint64_t>::max)())
{ {
write_number(static_cast<std::uint8_t>(0xdb)); write_number(static_cast<std::uint8_t>(0xdb));
write_number(static_cast<std::uint64_t>(j.m_value.binary->subtype())); write_number(static_cast<std::uint64_t>(j.m_data.m_value.binary->subtype()));
} }
} }
// step 1: write control byte and the binary array size // step 1: write control byte and the binary array size
const auto N = j.m_value.binary->size(); const auto N = j.m_data.m_value.binary->size();
if (N <= 0x17) if (N <= 0x17)
{ {
write_number(static_cast<std::uint8_t>(0x40 + N)); write_number(static_cast<std::uint8_t>(0x40 + N));
@ -355,7 +355,7 @@ class binary_writer
// step 2: write each element // step 2: write each element
oa->write_characters( oa->write_characters(
reinterpret_cast<const CharType*>(j.m_value.binary->data()), reinterpret_cast<const CharType*>(j.m_data.m_value.binary->data()),
N); N);
break; break;
@ -364,7 +364,7 @@ class binary_writer
case value_t::object: case value_t::object:
{ {
// step 1: write control byte and the object size // step 1: write control byte and the object size
const auto N = j.m_value.object->size(); const auto N = j.m_data.m_value.object->size();
if (N <= 0x17) if (N <= 0x17)
{ {
write_number(static_cast<std::uint8_t>(0xA0 + N)); write_number(static_cast<std::uint8_t>(0xA0 + N));
@ -393,7 +393,7 @@ class binary_writer
// LCOV_EXCL_STOP // LCOV_EXCL_STOP
// step 2: write each element // step 2: write each element
for (const auto& el : *j.m_value.object) for (const auto& el : *j.m_data.m_value.object)
{ {
write_cbor(el.first); write_cbor(el.first);
write_cbor(el.second); write_cbor(el.second);
@ -422,7 +422,7 @@ class binary_writer
case value_t::boolean: // true and false case value_t::boolean: // true and false
{ {
oa->write_character(j.m_value.boolean oa->write_character(j.m_data.m_value.boolean
? to_char_type(0xC3) ? to_char_type(0xC3)
: to_char_type(0xC2)); : to_char_type(0xC2));
break; break;
@ -430,75 +430,75 @@ class binary_writer
case value_t::number_integer: case value_t::number_integer:
{ {
if (j.m_value.number_integer >= 0) if (j.m_data.m_value.number_integer >= 0)
{ {
// MessagePack does not differentiate between positive // MessagePack does not differentiate between positive
// signed integers and unsigned integers. Therefore, we used // signed integers and unsigned integers. Therefore, we used
// the code from the value_t::number_unsigned case here. // the code from the value_t::number_unsigned case here.
if (j.m_value.number_unsigned < 128) if (j.m_data.m_value.number_unsigned < 128)
{ {
// positive fixnum // positive fixnum
write_number(static_cast<std::uint8_t>(j.m_value.number_integer)); write_number(static_cast<std::uint8_t>(j.m_data.m_value.number_integer));
} }
else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint8_t>::max)()) else if (j.m_data.m_value.number_unsigned <= (std::numeric_limits<std::uint8_t>::max)())
{ {
// uint 8 // uint 8
oa->write_character(to_char_type(0xCC)); oa->write_character(to_char_type(0xCC));
write_number(static_cast<std::uint8_t>(j.m_value.number_integer)); write_number(static_cast<std::uint8_t>(j.m_data.m_value.number_integer));
} }
else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint16_t>::max)()) else if (j.m_data.m_value.number_unsigned <= (std::numeric_limits<std::uint16_t>::max)())
{ {
// uint 16 // uint 16
oa->write_character(to_char_type(0xCD)); oa->write_character(to_char_type(0xCD));
write_number(static_cast<std::uint16_t>(j.m_value.number_integer)); write_number(static_cast<std::uint16_t>(j.m_data.m_value.number_integer));
} }
else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint32_t>::max)()) else if (j.m_data.m_value.number_unsigned <= (std::numeric_limits<std::uint32_t>::max)())
{ {
// uint 32 // uint 32
oa->write_character(to_char_type(0xCE)); oa->write_character(to_char_type(0xCE));
write_number(static_cast<std::uint32_t>(j.m_value.number_integer)); write_number(static_cast<std::uint32_t>(j.m_data.m_value.number_integer));
} }
else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint64_t>::max)()) else if (j.m_data.m_value.number_unsigned <= (std::numeric_limits<std::uint64_t>::max)())
{ {
// uint 64 // uint 64
oa->write_character(to_char_type(0xCF)); oa->write_character(to_char_type(0xCF));
write_number(static_cast<std::uint64_t>(j.m_value.number_integer)); write_number(static_cast<std::uint64_t>(j.m_data.m_value.number_integer));
} }
} }
else else
{ {
if (j.m_value.number_integer >= -32) if (j.m_data.m_value.number_integer >= -32)
{ {
// negative fixnum // negative fixnum
write_number(static_cast<std::int8_t>(j.m_value.number_integer)); write_number(static_cast<std::int8_t>(j.m_data.m_value.number_integer));
} }
else if (j.m_value.number_integer >= (std::numeric_limits<std::int8_t>::min)() && else if (j.m_data.m_value.number_integer >= (std::numeric_limits<std::int8_t>::min)() &&
j.m_value.number_integer <= (std::numeric_limits<std::int8_t>::max)()) j.m_data.m_value.number_integer <= (std::numeric_limits<std::int8_t>::max)())
{ {
// int 8 // int 8
oa->write_character(to_char_type(0xD0)); oa->write_character(to_char_type(0xD0));
write_number(static_cast<std::int8_t>(j.m_value.number_integer)); write_number(static_cast<std::int8_t>(j.m_data.m_value.number_integer));
} }
else if (j.m_value.number_integer >= (std::numeric_limits<std::int16_t>::min)() && else if (j.m_data.m_value.number_integer >= (std::numeric_limits<std::int16_t>::min)() &&
j.m_value.number_integer <= (std::numeric_limits<std::int16_t>::max)()) j.m_data.m_value.number_integer <= (std::numeric_limits<std::int16_t>::max)())
{ {
// int 16 // int 16
oa->write_character(to_char_type(0xD1)); oa->write_character(to_char_type(0xD1));
write_number(static_cast<std::int16_t>(j.m_value.number_integer)); write_number(static_cast<std::int16_t>(j.m_data.m_value.number_integer));
} }
else if (j.m_value.number_integer >= (std::numeric_limits<std::int32_t>::min)() && else if (j.m_data.m_value.number_integer >= (std::numeric_limits<std::int32_t>::min)() &&
j.m_value.number_integer <= (std::numeric_limits<std::int32_t>::max)()) j.m_data.m_value.number_integer <= (std::numeric_limits<std::int32_t>::max)())
{ {
// int 32 // int 32
oa->write_character(to_char_type(0xD2)); oa->write_character(to_char_type(0xD2));
write_number(static_cast<std::int32_t>(j.m_value.number_integer)); write_number(static_cast<std::int32_t>(j.m_data.m_value.number_integer));
} }
else if (j.m_value.number_integer >= (std::numeric_limits<std::int64_t>::min)() && else if (j.m_data.m_value.number_integer >= (std::numeric_limits<std::int64_t>::min)() &&
j.m_value.number_integer <= (std::numeric_limits<std::int64_t>::max)()) j.m_data.m_value.number_integer <= (std::numeric_limits<std::int64_t>::max)())
{ {
// int 64 // int 64
oa->write_character(to_char_type(0xD3)); oa->write_character(to_char_type(0xD3));
write_number(static_cast<std::int64_t>(j.m_value.number_integer)); write_number(static_cast<std::int64_t>(j.m_data.m_value.number_integer));
} }
} }
break; break;
@ -506,48 +506,48 @@ class binary_writer
case value_t::number_unsigned: case value_t::number_unsigned:
{ {
if (j.m_value.number_unsigned < 128) if (j.m_data.m_value.number_unsigned < 128)
{ {
// positive fixnum // positive fixnum
write_number(static_cast<std::uint8_t>(j.m_value.number_integer)); write_number(static_cast<std::uint8_t>(j.m_data.m_value.number_integer));
} }
else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint8_t>::max)()) else if (j.m_data.m_value.number_unsigned <= (std::numeric_limits<std::uint8_t>::max)())
{ {
// uint 8 // uint 8
oa->write_character(to_char_type(0xCC)); oa->write_character(to_char_type(0xCC));
write_number(static_cast<std::uint8_t>(j.m_value.number_integer)); write_number(static_cast<std::uint8_t>(j.m_data.m_value.number_integer));
} }
else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint16_t>::max)()) else if (j.m_data.m_value.number_unsigned <= (std::numeric_limits<std::uint16_t>::max)())
{ {
// uint 16 // uint 16
oa->write_character(to_char_type(0xCD)); oa->write_character(to_char_type(0xCD));
write_number(static_cast<std::uint16_t>(j.m_value.number_integer)); write_number(static_cast<std::uint16_t>(j.m_data.m_value.number_integer));
} }
else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint32_t>::max)()) else if (j.m_data.m_value.number_unsigned <= (std::numeric_limits<std::uint32_t>::max)())
{ {
// uint 32 // uint 32
oa->write_character(to_char_type(0xCE)); oa->write_character(to_char_type(0xCE));
write_number(static_cast<std::uint32_t>(j.m_value.number_integer)); write_number(static_cast<std::uint32_t>(j.m_data.m_value.number_integer));
} }
else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint64_t>::max)()) else if (j.m_data.m_value.number_unsigned <= (std::numeric_limits<std::uint64_t>::max)())
{ {
// uint 64 // uint 64
oa->write_character(to_char_type(0xCF)); oa->write_character(to_char_type(0xCF));
write_number(static_cast<std::uint64_t>(j.m_value.number_integer)); write_number(static_cast<std::uint64_t>(j.m_data.m_value.number_integer));
} }
break; break;
} }
case value_t::number_float: case value_t::number_float:
{ {
write_compact_float(j.m_value.number_float, detail::input_format_t::msgpack); write_compact_float(j.m_data.m_value.number_float, detail::input_format_t::msgpack);
break; break;
} }
case value_t::string: case value_t::string:
{ {
// step 1: write control byte and the string length // step 1: write control byte and the string length
const auto N = j.m_value.string->size(); const auto N = j.m_data.m_value.string->size();
if (N <= 31) if (N <= 31)
{ {
// fixstr // fixstr
@ -574,15 +574,15 @@ class binary_writer
// step 2: write the string // step 2: write the string
oa->write_characters( oa->write_characters(
reinterpret_cast<const CharType*>(j.m_value.string->c_str()), reinterpret_cast<const CharType*>(j.m_data.m_value.string->c_str()),
j.m_value.string->size()); j.m_data.m_value.string->size());
break; break;
} }
case value_t::array: case value_t::array:
{ {
// step 1: write control byte and the array size // step 1: write control byte and the array size
const auto N = j.m_value.array->size(); const auto N = j.m_data.m_value.array->size();
if (N <= 15) if (N <= 15)
{ {
// fixarray // fixarray
@ -602,7 +602,7 @@ class binary_writer
} }
// step 2: write each element // step 2: write each element
for (const auto& el : *j.m_value.array) for (const auto& el : *j.m_data.m_value.array)
{ {
write_msgpack(el); write_msgpack(el);
} }
@ -613,10 +613,10 @@ class binary_writer
{ {
// step 0: determine if the binary type has a set subtype to // step 0: determine if the binary type has a set subtype to
// determine whether or not to use the ext or fixext types // determine whether or not to use the ext or fixext types
const bool use_ext = j.m_value.binary->has_subtype(); const bool use_ext = j.m_data.m_value.binary->has_subtype();
// step 1: write control byte and the byte string length // step 1: write control byte and the byte string length
const auto N = j.m_value.binary->size(); const auto N = j.m_data.m_value.binary->size();
if (N <= (std::numeric_limits<std::uint8_t>::max)()) if (N <= (std::numeric_limits<std::uint8_t>::max)())
{ {
std::uint8_t output_type{}; std::uint8_t output_type{};
@ -681,12 +681,12 @@ class binary_writer
// step 1.5: if this is an ext type, write the subtype // step 1.5: if this is an ext type, write the subtype
if (use_ext) if (use_ext)
{ {
write_number(static_cast<std::int8_t>(j.m_value.binary->subtype())); write_number(static_cast<std::int8_t>(j.m_data.m_value.binary->subtype()));
} }
// step 2: write the byte string // step 2: write the byte string
oa->write_characters( oa->write_characters(
reinterpret_cast<const CharType*>(j.m_value.binary->data()), reinterpret_cast<const CharType*>(j.m_data.m_value.binary->data()),
N); N);
break; break;
@ -695,7 +695,7 @@ class binary_writer
case value_t::object: case value_t::object:
{ {
// step 1: write control byte and the object size // step 1: write control byte and the object size
const auto N = j.m_value.object->size(); const auto N = j.m_data.m_value.object->size();
if (N <= 15) if (N <= 15)
{ {
// fixmap // fixmap
@ -715,7 +715,7 @@ class binary_writer
} }
// step 2: write each element // step 2: write each element
for (const auto& el : *j.m_value.object) for (const auto& el : *j.m_data.m_value.object)
{ {
write_msgpack(el.first); write_msgpack(el.first);
write_msgpack(el.second); write_msgpack(el.second);
@ -755,7 +755,7 @@ class binary_writer
{ {
if (add_prefix) if (add_prefix)
{ {
oa->write_character(j.m_value.boolean oa->write_character(j.m_data.m_value.boolean
? to_char_type('T') ? to_char_type('T')
: to_char_type('F')); : to_char_type('F'));
} }
@ -764,19 +764,19 @@ class binary_writer
case value_t::number_integer: case value_t::number_integer:
{ {
write_number_with_ubjson_prefix(j.m_value.number_integer, add_prefix, use_bjdata); write_number_with_ubjson_prefix(j.m_data.m_value.number_integer, add_prefix, use_bjdata);
break; break;
} }
case value_t::number_unsigned: case value_t::number_unsigned:
{ {
write_number_with_ubjson_prefix(j.m_value.number_unsigned, add_prefix, use_bjdata); write_number_with_ubjson_prefix(j.m_data.m_value.number_unsigned, add_prefix, use_bjdata);
break; break;
} }
case value_t::number_float: case value_t::number_float:
{ {
write_number_with_ubjson_prefix(j.m_value.number_float, add_prefix, use_bjdata); write_number_with_ubjson_prefix(j.m_data.m_value.number_float, add_prefix, use_bjdata);
break; break;
} }
@ -786,10 +786,10 @@ class binary_writer
{ {
oa->write_character(to_char_type('S')); oa->write_character(to_char_type('S'));
} }
write_number_with_ubjson_prefix(j.m_value.string->size(), true, use_bjdata); write_number_with_ubjson_prefix(j.m_data.m_value.string->size(), true, use_bjdata);
oa->write_characters( oa->write_characters(
reinterpret_cast<const CharType*>(j.m_value.string->c_str()), reinterpret_cast<const CharType*>(j.m_data.m_value.string->c_str()),
j.m_value.string->size()); j.m_data.m_value.string->size());
break; break;
} }
@ -801,7 +801,7 @@ class binary_writer
} }
bool prefix_required = true; bool prefix_required = true;
if (use_type && !j.m_value.array->empty()) if (use_type && !j.m_data.m_value.array->empty())
{ {
JSON_ASSERT(use_count); JSON_ASSERT(use_count);
const CharType first_prefix = ubjson_prefix(j.front(), use_bjdata); const CharType first_prefix = ubjson_prefix(j.front(), use_bjdata);
@ -824,10 +824,10 @@ class binary_writer
if (use_count) if (use_count)
{ {
oa->write_character(to_char_type('#')); oa->write_character(to_char_type('#'));
write_number_with_ubjson_prefix(j.m_value.array->size(), true, use_bjdata); write_number_with_ubjson_prefix(j.m_data.m_value.array->size(), true, use_bjdata);
} }
for (const auto& el : *j.m_value.array) for (const auto& el : *j.m_data.m_value.array)
{ {
write_ubjson(el, use_count, use_type, prefix_required, use_bjdata); write_ubjson(el, use_count, use_type, prefix_required, use_bjdata);
} }
@ -847,7 +847,7 @@ class binary_writer
oa->write_character(to_char_type('[')); oa->write_character(to_char_type('['));
} }
if (use_type && !j.m_value.binary->empty()) if (use_type && !j.m_data.m_value.binary->empty())
{ {
JSON_ASSERT(use_count); JSON_ASSERT(use_count);
oa->write_character(to_char_type('$')); oa->write_character(to_char_type('$'));
@ -857,21 +857,21 @@ class binary_writer
if (use_count) if (use_count)
{ {
oa->write_character(to_char_type('#')); oa->write_character(to_char_type('#'));
write_number_with_ubjson_prefix(j.m_value.binary->size(), true, use_bjdata); write_number_with_ubjson_prefix(j.m_data.m_value.binary->size(), true, use_bjdata);
} }
if (use_type) if (use_type)
{ {
oa->write_characters( oa->write_characters(
reinterpret_cast<const CharType*>(j.m_value.binary->data()), reinterpret_cast<const CharType*>(j.m_data.m_value.binary->data()),
j.m_value.binary->size()); j.m_data.m_value.binary->size());
} }
else else
{ {
for (size_t i = 0; i < j.m_value.binary->size(); ++i) for (size_t i = 0; i < j.m_data.m_value.binary->size(); ++i)
{ {
oa->write_character(to_char_type('U')); oa->write_character(to_char_type('U'));
oa->write_character(j.m_value.binary->data()[i]); oa->write_character(j.m_data.m_value.binary->data()[i]);
} }
} }
@ -885,9 +885,9 @@ class binary_writer
case value_t::object: case value_t::object:
{ {
if (use_bjdata && j.m_value.object->size() == 3 && j.m_value.object->find("_ArrayType_") != j.m_value.object->end() && j.m_value.object->find("_ArraySize_") != j.m_value.object->end() && j.m_value.object->find("_ArrayData_") != j.m_value.object->end()) if (use_bjdata && j.m_data.m_value.object->size() == 3 && j.m_data.m_value.object->find("_ArrayType_") != j.m_data.m_value.object->end() && j.m_data.m_value.object->find("_ArraySize_") != j.m_data.m_value.object->end() && j.m_data.m_value.object->find("_ArrayData_") != j.m_data.m_value.object->end())
{ {
if (!write_bjdata_ndarray(*j.m_value.object, use_count, use_type)) // decode bjdata ndarray in the JData format (https://github.com/NeuroJSON/jdata) if (!write_bjdata_ndarray(*j.m_data.m_value.object, use_count, use_type)) // decode bjdata ndarray in the JData format (https://github.com/NeuroJSON/jdata)
{ {
break; break;
} }
@ -899,7 +899,7 @@ class binary_writer
} }
bool prefix_required = true; bool prefix_required = true;
if (use_type && !j.m_value.object->empty()) if (use_type && !j.m_data.m_value.object->empty())
{ {
JSON_ASSERT(use_count); JSON_ASSERT(use_count);
const CharType first_prefix = ubjson_prefix(j.front(), use_bjdata); const CharType first_prefix = ubjson_prefix(j.front(), use_bjdata);
@ -922,10 +922,10 @@ class binary_writer
if (use_count) if (use_count)
{ {
oa->write_character(to_char_type('#')); oa->write_character(to_char_type('#'));
write_number_with_ubjson_prefix(j.m_value.object->size(), true, use_bjdata); write_number_with_ubjson_prefix(j.m_data.m_value.object->size(), true, use_bjdata);
} }
for (const auto& el : *j.m_value.object) for (const auto& el : *j.m_data.m_value.object)
{ {
write_number_with_ubjson_prefix(el.first.size(), true, use_bjdata); write_number_with_ubjson_prefix(el.first.size(), true, use_bjdata);
oa->write_characters( oa->write_characters(
@ -1075,19 +1075,19 @@ class binary_writer
void write_bson_unsigned(const string_t& name, void write_bson_unsigned(const string_t& name,
const BasicJsonType& j) const BasicJsonType& j)
{ {
if (j.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::int32_t>::max)())) if (j.m_data.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::int32_t>::max)()))
{ {
write_bson_entry_header(name, 0x10 /* int32 */); write_bson_entry_header(name, 0x10 /* int32 */);
write_number<std::int32_t>(static_cast<std::int32_t>(j.m_value.number_unsigned), true); write_number<std::int32_t>(static_cast<std::int32_t>(j.m_data.m_value.number_unsigned), true);
} }
else if (j.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::int64_t>::max)())) else if (j.m_data.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::int64_t>::max)()))
{ {
write_bson_entry_header(name, 0x12 /* int64 */); write_bson_entry_header(name, 0x12 /* int64 */);
write_number<std::int64_t>(static_cast<std::int64_t>(j.m_value.number_unsigned), true); write_number<std::int64_t>(static_cast<std::int64_t>(j.m_data.m_value.number_unsigned), true);
} }
else else
{ {
JSON_THROW(out_of_range::create(407, concat("integer number ", std::to_string(j.m_value.number_unsigned), " cannot be represented by BSON as it does not fit int64"), &j)); JSON_THROW(out_of_range::create(407, concat("integer number ", std::to_string(j.m_data.m_value.number_unsigned), " cannot be represented by BSON as it does not fit int64"), &j));
} }
} }
@ -1168,13 +1168,13 @@ class binary_writer
switch (j.type()) switch (j.type())
{ {
case value_t::object: case value_t::object:
return header_size + calc_bson_object_size(*j.m_value.object); return header_size + calc_bson_object_size(*j.m_data.m_value.object);
case value_t::array: case value_t::array:
return header_size + calc_bson_array_size(*j.m_value.array); return header_size + calc_bson_array_size(*j.m_data.m_value.array);
case value_t::binary: case value_t::binary:
return header_size + calc_bson_binary_size(*j.m_value.binary); return header_size + calc_bson_binary_size(*j.m_data.m_value.binary);
case value_t::boolean: case value_t::boolean:
return header_size + 1ul; return header_size + 1ul;
@ -1183,13 +1183,13 @@ class binary_writer
return header_size + 8ul; return header_size + 8ul;
case value_t::number_integer: case value_t::number_integer:
return header_size + calc_bson_integer_size(j.m_value.number_integer); return header_size + calc_bson_integer_size(j.m_data.m_value.number_integer);
case value_t::number_unsigned: case value_t::number_unsigned:
return header_size + calc_bson_unsigned_size(j.m_value.number_unsigned); return header_size + calc_bson_unsigned_size(j.m_data.m_value.number_unsigned);
case value_t::string: case value_t::string:
return header_size + calc_bson_string_size(*j.m_value.string); return header_size + calc_bson_string_size(*j.m_data.m_value.string);
case value_t::null: case value_t::null:
return header_size + 0ul; return header_size + 0ul;
@ -1215,28 +1215,28 @@ class binary_writer
switch (j.type()) switch (j.type())
{ {
case value_t::object: case value_t::object:
return write_bson_object_entry(name, *j.m_value.object); return write_bson_object_entry(name, *j.m_data.m_value.object);
case value_t::array: case value_t::array:
return write_bson_array(name, *j.m_value.array); return write_bson_array(name, *j.m_data.m_value.array);
case value_t::binary: case value_t::binary:
return write_bson_binary(name, *j.m_value.binary); return write_bson_binary(name, *j.m_data.m_value.binary);
case value_t::boolean: case value_t::boolean:
return write_bson_boolean(name, j.m_value.boolean); return write_bson_boolean(name, j.m_data.m_value.boolean);
case value_t::number_float: case value_t::number_float:
return write_bson_double(name, j.m_value.number_float); return write_bson_double(name, j.m_data.m_value.number_float);
case value_t::number_integer: case value_t::number_integer:
return write_bson_integer(name, j.m_value.number_integer); return write_bson_integer(name, j.m_data.m_value.number_integer);
case value_t::number_unsigned: case value_t::number_unsigned:
return write_bson_unsigned(name, j); return write_bson_unsigned(name, j);
case value_t::string: case value_t::string:
return write_bson_string(name, *j.m_value.string); return write_bson_string(name, *j.m_data.m_value.string);
case value_t::null: case value_t::null:
return write_bson_null(name); return write_bson_null(name);
@ -1509,35 +1509,35 @@ class binary_writer
return 'Z'; return 'Z';
case value_t::boolean: case value_t::boolean:
return j.m_value.boolean ? 'T' : 'F'; return j.m_data.m_value.boolean ? 'T' : 'F';
case value_t::number_integer: case value_t::number_integer:
{ {
if ((std::numeric_limits<std::int8_t>::min)() <= j.m_value.number_integer && j.m_value.number_integer <= (std::numeric_limits<std::int8_t>::max)()) if ((std::numeric_limits<std::int8_t>::min)() <= j.m_data.m_value.number_integer && j.m_data.m_value.number_integer <= (std::numeric_limits<std::int8_t>::max)())
{ {
return 'i'; return 'i';
} }
if ((std::numeric_limits<std::uint8_t>::min)() <= j.m_value.number_integer && j.m_value.number_integer <= (std::numeric_limits<std::uint8_t>::max)()) if ((std::numeric_limits<std::uint8_t>::min)() <= j.m_data.m_value.number_integer && j.m_data.m_value.number_integer <= (std::numeric_limits<std::uint8_t>::max)())
{ {
return 'U'; return 'U';
} }
if ((std::numeric_limits<std::int16_t>::min)() <= j.m_value.number_integer && j.m_value.number_integer <= (std::numeric_limits<std::int16_t>::max)()) if ((std::numeric_limits<std::int16_t>::min)() <= j.m_data.m_value.number_integer && j.m_data.m_value.number_integer <= (std::numeric_limits<std::int16_t>::max)())
{ {
return 'I'; return 'I';
} }
if (use_bjdata && ((std::numeric_limits<std::uint16_t>::min)() <= j.m_value.number_integer && j.m_value.number_integer <= (std::numeric_limits<std::uint16_t>::max)())) if (use_bjdata && ((std::numeric_limits<std::uint16_t>::min)() <= j.m_data.m_value.number_integer && j.m_data.m_value.number_integer <= (std::numeric_limits<std::uint16_t>::max)()))
{ {
return 'u'; return 'u';
} }
if ((std::numeric_limits<std::int32_t>::min)() <= j.m_value.number_integer && j.m_value.number_integer <= (std::numeric_limits<std::int32_t>::max)()) if ((std::numeric_limits<std::int32_t>::min)() <= j.m_data.m_value.number_integer && j.m_data.m_value.number_integer <= (std::numeric_limits<std::int32_t>::max)())
{ {
return 'l'; return 'l';
} }
if (use_bjdata && ((std::numeric_limits<std::uint32_t>::min)() <= j.m_value.number_integer && j.m_value.number_integer <= (std::numeric_limits<std::uint32_t>::max)())) if (use_bjdata && ((std::numeric_limits<std::uint32_t>::min)() <= j.m_data.m_value.number_integer && j.m_data.m_value.number_integer <= (std::numeric_limits<std::uint32_t>::max)()))
{ {
return 'm'; return 'm';
} }
if ((std::numeric_limits<std::int64_t>::min)() <= j.m_value.number_integer && j.m_value.number_integer <= (std::numeric_limits<std::int64_t>::max)()) if ((std::numeric_limits<std::int64_t>::min)() <= j.m_data.m_value.number_integer && j.m_data.m_value.number_integer <= (std::numeric_limits<std::int64_t>::max)())
{ {
return 'L'; return 'L';
} }
@ -1547,35 +1547,35 @@ class binary_writer
case value_t::number_unsigned: case value_t::number_unsigned:
{ {
if (j.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::int8_t>::max)())) if (j.m_data.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::int8_t>::max)()))
{ {
return 'i'; return 'i';
} }
if (j.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::uint8_t>::max)())) if (j.m_data.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::uint8_t>::max)()))
{ {
return 'U'; return 'U';
} }
if (j.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::int16_t>::max)())) if (j.m_data.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::int16_t>::max)()))
{ {
return 'I'; return 'I';
} }
if (use_bjdata && j.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::uint16_t>::max)())) if (use_bjdata && j.m_data.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::uint16_t>::max)()))
{ {
return 'u'; return 'u';
} }
if (j.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::int32_t>::max)())) if (j.m_data.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::int32_t>::max)()))
{ {
return 'l'; return 'l';
} }
if (use_bjdata && j.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::uint32_t>::max)())) if (use_bjdata && j.m_data.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::uint32_t>::max)()))
{ {
return 'm'; return 'm';
} }
if (j.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::int64_t>::max)())) if (j.m_data.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::int64_t>::max)()))
{ {
return 'L'; return 'L';
} }
if (use_bjdata && j.m_value.number_unsigned <= (std::numeric_limits<std::uint64_t>::max)()) if (use_bjdata && j.m_data.m_value.number_unsigned <= (std::numeric_limits<std::uint64_t>::max)())
{ {
return 'M'; return 'M';
} }
@ -1584,7 +1584,7 @@ class binary_writer
} }
case value_t::number_float: case value_t::number_float:
return get_ubjson_float_prefix(j.m_value.number_float); return get_ubjson_float_prefix(j.m_data.m_value.number_float);
case value_t::string: case value_t::string:
return 'S'; return 'S';
@ -1633,7 +1633,7 @@ class binary_writer
std::size_t len = (value.at(key).empty() ? 0 : 1); std::size_t len = (value.at(key).empty() ? 0 : 1);
for (const auto& el : value.at(key)) for (const auto& el : value.at(key))
{ {
len *= static_cast<std::size_t>(el.m_value.number_unsigned); len *= static_cast<std::size_t>(el.m_data.m_value.number_unsigned);
} }
key = "_ArrayData_"; key = "_ArrayData_";
@ -1655,70 +1655,70 @@ class binary_writer
{ {
for (const auto& el : value.at(key)) for (const auto& el : value.at(key))
{ {
write_number(static_cast<std::uint8_t>(el.m_value.number_unsigned), true); write_number(static_cast<std::uint8_t>(el.m_data.m_value.number_unsigned), true);
} }
} }
else if (dtype == 'i') else if (dtype == 'i')
{ {
for (const auto& el : value.at(key)) for (const auto& el : value.at(key))
{ {
write_number(static_cast<std::int8_t>(el.m_value.number_integer), true); write_number(static_cast<std::int8_t>(el.m_data.m_value.number_integer), true);
} }
} }
else if (dtype == 'u') else if (dtype == 'u')
{ {
for (const auto& el : value.at(key)) for (const auto& el : value.at(key))
{ {
write_number(static_cast<std::uint16_t>(el.m_value.number_unsigned), true); write_number(static_cast<std::uint16_t>(el.m_data.m_value.number_unsigned), true);
} }
} }
else if (dtype == 'I') else if (dtype == 'I')
{ {
for (const auto& el : value.at(key)) for (const auto& el : value.at(key))
{ {
write_number(static_cast<std::int16_t>(el.m_value.number_integer), true); write_number(static_cast<std::int16_t>(el.m_data.m_value.number_integer), true);
} }
} }
else if (dtype == 'm') else if (dtype == 'm')
{ {
for (const auto& el : value.at(key)) for (const auto& el : value.at(key))
{ {
write_number(static_cast<std::uint32_t>(el.m_value.number_unsigned), true); write_number(static_cast<std::uint32_t>(el.m_data.m_value.number_unsigned), true);
} }
} }
else if (dtype == 'l') else if (dtype == 'l')
{ {
for (const auto& el : value.at(key)) for (const auto& el : value.at(key))
{ {
write_number(static_cast<std::int32_t>(el.m_value.number_integer), true); write_number(static_cast<std::int32_t>(el.m_data.m_value.number_integer), true);
} }
} }
else if (dtype == 'M') else if (dtype == 'M')
{ {
for (const auto& el : value.at(key)) for (const auto& el : value.at(key))
{ {
write_number(static_cast<std::uint64_t>(el.m_value.number_unsigned), true); write_number(static_cast<std::uint64_t>(el.m_data.m_value.number_unsigned), true);
} }
} }
else if (dtype == 'L') else if (dtype == 'L')
{ {
for (const auto& el : value.at(key)) for (const auto& el : value.at(key))
{ {
write_number(static_cast<std::int64_t>(el.m_value.number_integer), true); write_number(static_cast<std::int64_t>(el.m_data.m_value.number_integer), true);
} }
} }
else if (dtype == 'd') else if (dtype == 'd')
{ {
for (const auto& el : value.at(key)) for (const auto& el : value.at(key))
{ {
write_number(static_cast<float>(el.m_value.number_float), true); write_number(static_cast<float>(el.m_data.m_value.number_float), true);
} }
} }
else if (dtype == 'D') else if (dtype == 'D')
{ {
for (const auto& el : value.at(key)) for (const auto& el : value.at(key))
{ {
write_number(static_cast<double>(el.m_value.number_float), true); write_number(static_cast<double>(el.m_data.m_value.number_float), true);
} }
} }
return false; return false;

View File

@ -110,11 +110,11 @@ class serializer
const unsigned int indent_step, const unsigned int indent_step,
const unsigned int current_indent = 0) const unsigned int current_indent = 0)
{ {
switch (val.m_type) switch (val.m_data.m_type)
{ {
case value_t::object: case value_t::object:
{ {
if (val.m_value.object->empty()) if (val.m_data.m_value.object->empty())
{ {
o->write_characters("{}", 2); o->write_characters("{}", 2);
return; return;
@ -132,8 +132,8 @@ class serializer
} }
// first n-1 elements // first n-1 elements
auto i = val.m_value.object->cbegin(); auto i = val.m_data.m_value.object->cbegin();
for (std::size_t cnt = 0; cnt < val.m_value.object->size() - 1; ++cnt, ++i) for (std::size_t cnt = 0; cnt < val.m_data.m_value.object->size() - 1; ++cnt, ++i)
{ {
o->write_characters(indent_string.c_str(), new_indent); o->write_characters(indent_string.c_str(), new_indent);
o->write_character('\"'); o->write_character('\"');
@ -144,8 +144,8 @@ class serializer
} }
// last element // last element
JSON_ASSERT(i != val.m_value.object->cend()); JSON_ASSERT(i != val.m_data.m_value.object->cend());
JSON_ASSERT(std::next(i) == val.m_value.object->cend()); JSON_ASSERT(std::next(i) == val.m_data.m_value.object->cend());
o->write_characters(indent_string.c_str(), new_indent); o->write_characters(indent_string.c_str(), new_indent);
o->write_character('\"'); o->write_character('\"');
dump_escaped(i->first, ensure_ascii); dump_escaped(i->first, ensure_ascii);
@ -161,8 +161,8 @@ class serializer
o->write_character('{'); o->write_character('{');
// first n-1 elements // first n-1 elements
auto i = val.m_value.object->cbegin(); auto i = val.m_data.m_value.object->cbegin();
for (std::size_t cnt = 0; cnt < val.m_value.object->size() - 1; ++cnt, ++i) for (std::size_t cnt = 0; cnt < val.m_data.m_value.object->size() - 1; ++cnt, ++i)
{ {
o->write_character('\"'); o->write_character('\"');
dump_escaped(i->first, ensure_ascii); dump_escaped(i->first, ensure_ascii);
@ -172,8 +172,8 @@ class serializer
} }
// last element // last element
JSON_ASSERT(i != val.m_value.object->cend()); JSON_ASSERT(i != val.m_data.m_value.object->cend());
JSON_ASSERT(std::next(i) == val.m_value.object->cend()); JSON_ASSERT(std::next(i) == val.m_data.m_value.object->cend());
o->write_character('\"'); o->write_character('\"');
dump_escaped(i->first, ensure_ascii); dump_escaped(i->first, ensure_ascii);
o->write_characters("\":", 2); o->write_characters("\":", 2);
@ -187,7 +187,7 @@ class serializer
case value_t::array: case value_t::array:
{ {
if (val.m_value.array->empty()) if (val.m_data.m_value.array->empty())
{ {
o->write_characters("[]", 2); o->write_characters("[]", 2);
return; return;
@ -205,8 +205,8 @@ class serializer
} }
// first n-1 elements // first n-1 elements
for (auto i = val.m_value.array->cbegin(); for (auto i = val.m_data.m_value.array->cbegin();
i != val.m_value.array->cend() - 1; ++i) i != val.m_data.m_value.array->cend() - 1; ++i)
{ {
o->write_characters(indent_string.c_str(), new_indent); o->write_characters(indent_string.c_str(), new_indent);
dump(*i, true, ensure_ascii, indent_step, new_indent); dump(*i, true, ensure_ascii, indent_step, new_indent);
@ -214,9 +214,9 @@ class serializer
} }
// last element // last element
JSON_ASSERT(!val.m_value.array->empty()); JSON_ASSERT(!val.m_data.m_value.array->empty());
o->write_characters(indent_string.c_str(), new_indent); o->write_characters(indent_string.c_str(), new_indent);
dump(val.m_value.array->back(), true, ensure_ascii, indent_step, new_indent); dump(val.m_data.m_value.array->back(), true, ensure_ascii, indent_step, new_indent);
o->write_character('\n'); o->write_character('\n');
o->write_characters(indent_string.c_str(), current_indent); o->write_characters(indent_string.c_str(), current_indent);
@ -227,16 +227,16 @@ class serializer
o->write_character('['); o->write_character('[');
// first n-1 elements // first n-1 elements
for (auto i = val.m_value.array->cbegin(); for (auto i = val.m_data.m_value.array->cbegin();
i != val.m_value.array->cend() - 1; ++i) i != val.m_data.m_value.array->cend() - 1; ++i)
{ {
dump(*i, false, ensure_ascii, indent_step, current_indent); dump(*i, false, ensure_ascii, indent_step, current_indent);
o->write_character(','); o->write_character(',');
} }
// last element // last element
JSON_ASSERT(!val.m_value.array->empty()); JSON_ASSERT(!val.m_data.m_value.array->empty());
dump(val.m_value.array->back(), false, ensure_ascii, indent_step, current_indent); dump(val.m_data.m_value.array->back(), false, ensure_ascii, indent_step, current_indent);
o->write_character(']'); o->write_character(']');
} }
@ -247,7 +247,7 @@ class serializer
case value_t::string: case value_t::string:
{ {
o->write_character('\"'); o->write_character('\"');
dump_escaped(*val.m_value.string, ensure_ascii); dump_escaped(*val.m_data.m_value.string, ensure_ascii);
o->write_character('\"'); o->write_character('\"');
return; return;
} }
@ -269,24 +269,24 @@ class serializer
o->write_characters("\"bytes\": [", 10); o->write_characters("\"bytes\": [", 10);
if (!val.m_value.binary->empty()) if (!val.m_data.m_value.binary->empty())
{ {
for (auto i = val.m_value.binary->cbegin(); for (auto i = val.m_data.m_value.binary->cbegin();
i != val.m_value.binary->cend() - 1; ++i) i != val.m_data.m_value.binary->cend() - 1; ++i)
{ {
dump_integer(*i); dump_integer(*i);
o->write_characters(", ", 2); o->write_characters(", ", 2);
} }
dump_integer(val.m_value.binary->back()); dump_integer(val.m_data.m_value.binary->back());
} }
o->write_characters("],\n", 3); o->write_characters("],\n", 3);
o->write_characters(indent_string.c_str(), new_indent); o->write_characters(indent_string.c_str(), new_indent);
o->write_characters("\"subtype\": ", 11); o->write_characters("\"subtype\": ", 11);
if (val.m_value.binary->has_subtype()) if (val.m_data.m_value.binary->has_subtype())
{ {
dump_integer(val.m_value.binary->subtype()); dump_integer(val.m_data.m_value.binary->subtype());
} }
else else
{ {
@ -300,21 +300,21 @@ class serializer
{ {
o->write_characters("{\"bytes\":[", 10); o->write_characters("{\"bytes\":[", 10);
if (!val.m_value.binary->empty()) if (!val.m_data.m_value.binary->empty())
{ {
for (auto i = val.m_value.binary->cbegin(); for (auto i = val.m_data.m_value.binary->cbegin();
i != val.m_value.binary->cend() - 1; ++i) i != val.m_data.m_value.binary->cend() - 1; ++i)
{ {
dump_integer(*i); dump_integer(*i);
o->write_character(','); o->write_character(',');
} }
dump_integer(val.m_value.binary->back()); dump_integer(val.m_data.m_value.binary->back());
} }
o->write_characters("],\"subtype\":", 12); o->write_characters("],\"subtype\":", 12);
if (val.m_value.binary->has_subtype()) if (val.m_data.m_value.binary->has_subtype())
{ {
dump_integer(val.m_value.binary->subtype()); dump_integer(val.m_data.m_value.binary->subtype());
o->write_character('}'); o->write_character('}');
} }
else else
@ -327,7 +327,7 @@ class serializer
case value_t::boolean: case value_t::boolean:
{ {
if (val.m_value.boolean) if (val.m_data.m_value.boolean)
{ {
o->write_characters("true", 4); o->write_characters("true", 4);
} }
@ -340,19 +340,19 @@ class serializer
case value_t::number_integer: case value_t::number_integer:
{ {
dump_integer(val.m_value.number_integer); dump_integer(val.m_data.m_value.number_integer);
return; return;
} }
case value_t::number_unsigned: case value_t::number_unsigned:
{ {
dump_integer(val.m_value.number_unsigned); dump_integer(val.m_data.m_value.number_unsigned);
return; return;
} }
case value_t::number_float: case value_t::number_float:
{ {
dump_float(val.m_value.number_float); dump_float(val.m_data.m_value.number_float);
return; return;
} }

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -216,28 +216,28 @@ TEST_CASE("const_iterator class")
{ {
json const j({{"foo", "bar"}}); json const j({{"foo", "bar"}});
json::const_iterator it = j.cbegin(); json::const_iterator it = j.cbegin();
CHECK((it.m_it.object_iterator == it.m_object->m_value.object->begin())); CHECK((it.m_it.object_iterator == it.m_object->m_data.m_value.object->begin()));
it++; it++;
CHECK((it.m_it.object_iterator == it.m_object->m_value.object->end())); CHECK((it.m_it.object_iterator == it.m_object->m_data.m_value.object->end()));
} }
SECTION("array") SECTION("array")
{ {
json const j({1, 2, 3, 4}); json const j({1, 2, 3, 4});
json::const_iterator it = j.cbegin(); json::const_iterator it = j.cbegin();
CHECK((it.m_it.array_iterator == it.m_object->m_value.array->begin())); CHECK((it.m_it.array_iterator == it.m_object->m_data.m_value.array->begin()));
it++; it++;
CHECK((it.m_it.array_iterator != it.m_object->m_value.array->begin())); CHECK((it.m_it.array_iterator != it.m_object->m_data.m_value.array->begin()));
CHECK((it.m_it.array_iterator != it.m_object->m_value.array->end())); CHECK((it.m_it.array_iterator != it.m_object->m_data.m_value.array->end()));
it++; it++;
CHECK((it.m_it.array_iterator != it.m_object->m_value.array->begin())); CHECK((it.m_it.array_iterator != it.m_object->m_data.m_value.array->begin()));
CHECK((it.m_it.array_iterator != it.m_object->m_value.array->end())); CHECK((it.m_it.array_iterator != it.m_object->m_data.m_value.array->end()));
it++; it++;
CHECK((it.m_it.array_iterator != it.m_object->m_value.array->begin())); CHECK((it.m_it.array_iterator != it.m_object->m_data.m_value.array->begin()));
CHECK((it.m_it.array_iterator != it.m_object->m_value.array->end())); CHECK((it.m_it.array_iterator != it.m_object->m_data.m_value.array->end()));
it++; it++;
CHECK((it.m_it.array_iterator != it.m_object->m_value.array->begin())); CHECK((it.m_it.array_iterator != it.m_object->m_data.m_value.array->begin()));
CHECK((it.m_it.array_iterator == it.m_object->m_value.array->end())); CHECK((it.m_it.array_iterator == it.m_object->m_data.m_value.array->end()));
} }
} }
@ -267,28 +267,28 @@ TEST_CASE("const_iterator class")
{ {
json const j({{"foo", "bar"}}); json const j({{"foo", "bar"}});
json::const_iterator it = j.cbegin(); json::const_iterator it = j.cbegin();
CHECK((it.m_it.object_iterator == it.m_object->m_value.object->begin())); CHECK((it.m_it.object_iterator == it.m_object->m_data.m_value.object->begin()));
++it; ++it;
CHECK((it.m_it.object_iterator == it.m_object->m_value.object->end())); CHECK((it.m_it.object_iterator == it.m_object->m_data.m_value.object->end()));
} }
SECTION("array") SECTION("array")
{ {
json const j({1, 2, 3, 4}); json const j({1, 2, 3, 4});
json::const_iterator it = j.cbegin(); json::const_iterator it = j.cbegin();
CHECK((it.m_it.array_iterator == it.m_object->m_value.array->begin())); CHECK((it.m_it.array_iterator == it.m_object->m_data.m_value.array->begin()));
++it; ++it;
CHECK((it.m_it.array_iterator != it.m_object->m_value.array->begin())); CHECK((it.m_it.array_iterator != it.m_object->m_data.m_value.array->begin()));
CHECK((it.m_it.array_iterator != it.m_object->m_value.array->end())); CHECK((it.m_it.array_iterator != it.m_object->m_data.m_value.array->end()));
++it; ++it;
CHECK((it.m_it.array_iterator != it.m_object->m_value.array->begin())); CHECK((it.m_it.array_iterator != it.m_object->m_data.m_value.array->begin()));
CHECK((it.m_it.array_iterator != it.m_object->m_value.array->end())); CHECK((it.m_it.array_iterator != it.m_object->m_data.m_value.array->end()));
++it; ++it;
CHECK((it.m_it.array_iterator != it.m_object->m_value.array->begin())); CHECK((it.m_it.array_iterator != it.m_object->m_data.m_value.array->begin()));
CHECK((it.m_it.array_iterator != it.m_object->m_value.array->end())); CHECK((it.m_it.array_iterator != it.m_object->m_data.m_value.array->end()));
++it; ++it;
CHECK((it.m_it.array_iterator != it.m_object->m_value.array->begin())); CHECK((it.m_it.array_iterator != it.m_object->m_data.m_value.array->begin()));
CHECK((it.m_it.array_iterator == it.m_object->m_value.array->end())); CHECK((it.m_it.array_iterator == it.m_object->m_data.m_value.array->end()));
} }
} }
@ -316,28 +316,28 @@ TEST_CASE("const_iterator class")
{ {
json const j({{"foo", "bar"}}); json const j({{"foo", "bar"}});
json::const_iterator it = j.cend(); json::const_iterator it = j.cend();
CHECK((it.m_it.object_iterator == it.m_object->m_value.object->end())); CHECK((it.m_it.object_iterator == it.m_object->m_data.m_value.object->end()));
it--; it--;
CHECK((it.m_it.object_iterator == it.m_object->m_value.object->begin())); CHECK((it.m_it.object_iterator == it.m_object->m_data.m_value.object->begin()));
} }
SECTION("array") SECTION("array")
{ {
json const j({1, 2, 3, 4}); json const j({1, 2, 3, 4});
json::const_iterator it = j.cend(); json::const_iterator it = j.cend();
CHECK((it.m_it.array_iterator == it.m_object->m_value.array->end())); CHECK((it.m_it.array_iterator == it.m_object->m_data.m_value.array->end()));
it--; it--;
CHECK((it.m_it.array_iterator != it.m_object->m_value.array->begin())); CHECK((it.m_it.array_iterator != it.m_object->m_data.m_value.array->begin()));
CHECK((it.m_it.array_iterator != it.m_object->m_value.array->end())); CHECK((it.m_it.array_iterator != it.m_object->m_data.m_value.array->end()));
it--; it--;
CHECK((it.m_it.array_iterator != it.m_object->m_value.array->begin())); CHECK((it.m_it.array_iterator != it.m_object->m_data.m_value.array->begin()));
CHECK((it.m_it.array_iterator != it.m_object->m_value.array->end())); CHECK((it.m_it.array_iterator != it.m_object->m_data.m_value.array->end()));
it--; it--;
CHECK((it.m_it.array_iterator != it.m_object->m_value.array->begin())); CHECK((it.m_it.array_iterator != it.m_object->m_data.m_value.array->begin()));
CHECK((it.m_it.array_iterator != it.m_object->m_value.array->end())); CHECK((it.m_it.array_iterator != it.m_object->m_data.m_value.array->end()));
it--; it--;
CHECK((it.m_it.array_iterator == it.m_object->m_value.array->begin())); CHECK((it.m_it.array_iterator == it.m_object->m_data.m_value.array->begin()));
CHECK((it.m_it.array_iterator != it.m_object->m_value.array->end())); CHECK((it.m_it.array_iterator != it.m_object->m_data.m_value.array->end()));
} }
} }
@ -365,28 +365,28 @@ TEST_CASE("const_iterator class")
{ {
json const j({{"foo", "bar"}}); json const j({{"foo", "bar"}});
json::const_iterator it = j.cend(); json::const_iterator it = j.cend();
CHECK((it.m_it.object_iterator == it.m_object->m_value.object->end())); CHECK((it.m_it.object_iterator == it.m_object->m_data.m_value.object->end()));
--it; --it;
CHECK((it.m_it.object_iterator == it.m_object->m_value.object->begin())); CHECK((it.m_it.object_iterator == it.m_object->m_data.m_value.object->begin()));
} }
SECTION("array") SECTION("array")
{ {
json const j({1, 2, 3, 4}); json const j({1, 2, 3, 4});
json::const_iterator it = j.cend(); json::const_iterator it = j.cend();
CHECK((it.m_it.array_iterator == it.m_object->m_value.array->end())); CHECK((it.m_it.array_iterator == it.m_object->m_data.m_value.array->end()));
--it; --it;
CHECK((it.m_it.array_iterator != it.m_object->m_value.array->begin())); CHECK((it.m_it.array_iterator != it.m_object->m_data.m_value.array->begin()));
CHECK((it.m_it.array_iterator != it.m_object->m_value.array->end())); CHECK((it.m_it.array_iterator != it.m_object->m_data.m_value.array->end()));
--it; --it;
CHECK((it.m_it.array_iterator != it.m_object->m_value.array->begin())); CHECK((it.m_it.array_iterator != it.m_object->m_data.m_value.array->begin()));
CHECK((it.m_it.array_iterator != it.m_object->m_value.array->end())); CHECK((it.m_it.array_iterator != it.m_object->m_data.m_value.array->end()));
--it; --it;
CHECK((it.m_it.array_iterator != it.m_object->m_value.array->begin())); CHECK((it.m_it.array_iterator != it.m_object->m_data.m_value.array->begin()));
CHECK((it.m_it.array_iterator != it.m_object->m_value.array->end())); CHECK((it.m_it.array_iterator != it.m_object->m_data.m_value.array->end()));
--it; --it;
CHECK((it.m_it.array_iterator == it.m_object->m_value.array->begin())); CHECK((it.m_it.array_iterator == it.m_object->m_data.m_value.array->begin()));
CHECK((it.m_it.array_iterator != it.m_object->m_value.array->end())); CHECK((it.m_it.array_iterator != it.m_object->m_data.m_value.array->end()));
} }
} }
} }

View File

@ -206,28 +206,28 @@ TEST_CASE("iterator class")
{ {
json j({{"foo", "bar"}}); json j({{"foo", "bar"}});
json::iterator it = j.begin(); json::iterator it = j.begin();
CHECK((it.m_it.object_iterator == it.m_object->m_value.object->begin())); CHECK((it.m_it.object_iterator == it.m_object->m_data.m_value.object->begin()));
it++; it++;
CHECK((it.m_it.object_iterator == it.m_object->m_value.object->end())); CHECK((it.m_it.object_iterator == it.m_object->m_data.m_value.object->end()));
} }
SECTION("array") SECTION("array")
{ {
json j({1, 2, 3, 4}); json j({1, 2, 3, 4});
json::iterator it = j.begin(); json::iterator it = j.begin();
CHECK((it.m_it.array_iterator == it.m_object->m_value.array->begin())); CHECK((it.m_it.array_iterator == it.m_object->m_data.m_value.array->begin()));
it++; it++;
CHECK((it.m_it.array_iterator != it.m_object->m_value.array->begin())); CHECK((it.m_it.array_iterator != it.m_object->m_data.m_value.array->begin()));
CHECK((it.m_it.array_iterator != it.m_object->m_value.array->end())); CHECK((it.m_it.array_iterator != it.m_object->m_data.m_value.array->end()));
it++; it++;
CHECK((it.m_it.array_iterator != it.m_object->m_value.array->begin())); CHECK((it.m_it.array_iterator != it.m_object->m_data.m_value.array->begin()));
CHECK((it.m_it.array_iterator != it.m_object->m_value.array->end())); CHECK((it.m_it.array_iterator != it.m_object->m_data.m_value.array->end()));
it++; it++;
CHECK((it.m_it.array_iterator != it.m_object->m_value.array->begin())); CHECK((it.m_it.array_iterator != it.m_object->m_data.m_value.array->begin()));
CHECK((it.m_it.array_iterator != it.m_object->m_value.array->end())); CHECK((it.m_it.array_iterator != it.m_object->m_data.m_value.array->end()));
it++; it++;
CHECK((it.m_it.array_iterator != it.m_object->m_value.array->begin())); CHECK((it.m_it.array_iterator != it.m_object->m_data.m_value.array->begin()));
CHECK((it.m_it.array_iterator == it.m_object->m_value.array->end())); CHECK((it.m_it.array_iterator == it.m_object->m_data.m_value.array->end()));
} }
} }
@ -257,28 +257,28 @@ TEST_CASE("iterator class")
{ {
json j({{"foo", "bar"}}); json j({{"foo", "bar"}});
json::iterator it = j.begin(); json::iterator it = j.begin();
CHECK((it.m_it.object_iterator == it.m_object->m_value.object->begin())); CHECK((it.m_it.object_iterator == it.m_object->m_data.m_value.object->begin()));
++it; ++it;
CHECK((it.m_it.object_iterator == it.m_object->m_value.object->end())); CHECK((it.m_it.object_iterator == it.m_object->m_data.m_value.object->end()));
} }
SECTION("array") SECTION("array")
{ {
json j({1, 2, 3, 4}); json j({1, 2, 3, 4});
json::iterator it = j.begin(); json::iterator it = j.begin();
CHECK((it.m_it.array_iterator == it.m_object->m_value.array->begin())); CHECK((it.m_it.array_iterator == it.m_object->m_data.m_value.array->begin()));
++it; ++it;
CHECK((it.m_it.array_iterator != it.m_object->m_value.array->begin())); CHECK((it.m_it.array_iterator != it.m_object->m_data.m_value.array->begin()));
CHECK((it.m_it.array_iterator != it.m_object->m_value.array->end())); CHECK((it.m_it.array_iterator != it.m_object->m_data.m_value.array->end()));
++it; ++it;
CHECK((it.m_it.array_iterator != it.m_object->m_value.array->begin())); CHECK((it.m_it.array_iterator != it.m_object->m_data.m_value.array->begin()));
CHECK((it.m_it.array_iterator != it.m_object->m_value.array->end())); CHECK((it.m_it.array_iterator != it.m_object->m_data.m_value.array->end()));
++it; ++it;
CHECK((it.m_it.array_iterator != it.m_object->m_value.array->begin())); CHECK((it.m_it.array_iterator != it.m_object->m_data.m_value.array->begin()));
CHECK((it.m_it.array_iterator != it.m_object->m_value.array->end())); CHECK((it.m_it.array_iterator != it.m_object->m_data.m_value.array->end()));
++it; ++it;
CHECK((it.m_it.array_iterator != it.m_object->m_value.array->begin())); CHECK((it.m_it.array_iterator != it.m_object->m_data.m_value.array->begin()));
CHECK((it.m_it.array_iterator == it.m_object->m_value.array->end())); CHECK((it.m_it.array_iterator == it.m_object->m_data.m_value.array->end()));
} }
} }
@ -306,28 +306,28 @@ TEST_CASE("iterator class")
{ {
json j({{"foo", "bar"}}); json j({{"foo", "bar"}});
json::iterator it = j.end(); json::iterator it = j.end();
CHECK((it.m_it.object_iterator == it.m_object->m_value.object->end())); CHECK((it.m_it.object_iterator == it.m_object->m_data.m_value.object->end()));
it--; it--;
CHECK((it.m_it.object_iterator == it.m_object->m_value.object->begin())); CHECK((it.m_it.object_iterator == it.m_object->m_data.m_value.object->begin()));
} }
SECTION("array") SECTION("array")
{ {
json j({1, 2, 3, 4}); json j({1, 2, 3, 4});
json::iterator it = j.end(); json::iterator it = j.end();
CHECK((it.m_it.array_iterator == it.m_object->m_value.array->end())); CHECK((it.m_it.array_iterator == it.m_object->m_data.m_value.array->end()));
it--; it--;
CHECK((it.m_it.array_iterator != it.m_object->m_value.array->begin())); CHECK((it.m_it.array_iterator != it.m_object->m_data.m_value.array->begin()));
CHECK((it.m_it.array_iterator != it.m_object->m_value.array->end())); CHECK((it.m_it.array_iterator != it.m_object->m_data.m_value.array->end()));
it--; it--;
CHECK((it.m_it.array_iterator != it.m_object->m_value.array->begin())); CHECK((it.m_it.array_iterator != it.m_object->m_data.m_value.array->begin()));
CHECK((it.m_it.array_iterator != it.m_object->m_value.array->end())); CHECK((it.m_it.array_iterator != it.m_object->m_data.m_value.array->end()));
it--; it--;
CHECK((it.m_it.array_iterator != it.m_object->m_value.array->begin())); CHECK((it.m_it.array_iterator != it.m_object->m_data.m_value.array->begin()));
CHECK((it.m_it.array_iterator != it.m_object->m_value.array->end())); CHECK((it.m_it.array_iterator != it.m_object->m_data.m_value.array->end()));
it--; it--;
CHECK((it.m_it.array_iterator == it.m_object->m_value.array->begin())); CHECK((it.m_it.array_iterator == it.m_object->m_data.m_value.array->begin()));
CHECK((it.m_it.array_iterator != it.m_object->m_value.array->end())); CHECK((it.m_it.array_iterator != it.m_object->m_data.m_value.array->end()));
} }
} }
@ -355,28 +355,28 @@ TEST_CASE("iterator class")
{ {
json j({{"foo", "bar"}}); json j({{"foo", "bar"}});
json::iterator it = j.end(); json::iterator it = j.end();
CHECK((it.m_it.object_iterator == it.m_object->m_value.object->end())); CHECK((it.m_it.object_iterator == it.m_object->m_data.m_value.object->end()));
--it; --it;
CHECK((it.m_it.object_iterator == it.m_object->m_value.object->begin())); CHECK((it.m_it.object_iterator == it.m_object->m_data.m_value.object->begin()));
} }
SECTION("array") SECTION("array")
{ {
json j({1, 2, 3, 4}); json j({1, 2, 3, 4});
json::iterator it = j.end(); json::iterator it = j.end();
CHECK((it.m_it.array_iterator == it.m_object->m_value.array->end())); CHECK((it.m_it.array_iterator == it.m_object->m_data.m_value.array->end()));
--it; --it;
CHECK((it.m_it.array_iterator != it.m_object->m_value.array->begin())); CHECK((it.m_it.array_iterator != it.m_object->m_data.m_value.array->begin()));
CHECK((it.m_it.array_iterator != it.m_object->m_value.array->end())); CHECK((it.m_it.array_iterator != it.m_object->m_data.m_value.array->end()));
--it; --it;
CHECK((it.m_it.array_iterator != it.m_object->m_value.array->begin())); CHECK((it.m_it.array_iterator != it.m_object->m_data.m_value.array->begin()));
CHECK((it.m_it.array_iterator != it.m_object->m_value.array->end())); CHECK((it.m_it.array_iterator != it.m_object->m_data.m_value.array->end()));
--it; --it;
CHECK((it.m_it.array_iterator != it.m_object->m_value.array->begin())); CHECK((it.m_it.array_iterator != it.m_object->m_data.m_value.array->begin()));
CHECK((it.m_it.array_iterator != it.m_object->m_value.array->end())); CHECK((it.m_it.array_iterator != it.m_object->m_data.m_value.array->end()));
--it; --it;
CHECK((it.m_it.array_iterator == it.m_object->m_value.array->begin())); CHECK((it.m_it.array_iterator == it.m_object->m_data.m_value.array->begin()));
CHECK((it.m_it.array_iterator != it.m_object->m_value.array->end())); CHECK((it.m_it.array_iterator != it.m_object->m_data.m_value.array->end()));
} }
} }
} }

View File

@ -872,7 +872,7 @@ TEST_CASE("constructors")
float const n = 42.23f; float const n = 42.23f;
json const j(n); json const j(n);
CHECK(j.type() == json::value_t::number_float); CHECK(j.type() == json::value_t::number_float);
CHECK(j.m_value.number_float == Approx(j_reference.m_value.number_float)); CHECK(j.m_data.m_value.number_float == Approx(j_reference.m_data.m_value.number_float));
} }
SECTION("double") SECTION("double")
@ -880,7 +880,7 @@ TEST_CASE("constructors")
double const n = 42.23; double const n = 42.23;
json const j(n); json const j(n);
CHECK(j.type() == json::value_t::number_float); CHECK(j.type() == json::value_t::number_float);
CHECK(j.m_value.number_float == Approx(j_reference.m_value.number_float)); CHECK(j.m_data.m_value.number_float == Approx(j_reference.m_data.m_value.number_float));
} }
SECTION("long double") SECTION("long double")
@ -888,28 +888,28 @@ TEST_CASE("constructors")
long double const n = 42.23L; long double const n = 42.23L;
json const j(n); json const j(n);
CHECK(j.type() == json::value_t::number_float); CHECK(j.type() == json::value_t::number_float);
CHECK(j.m_value.number_float == Approx(j_reference.m_value.number_float)); CHECK(j.m_data.m_value.number_float == Approx(j_reference.m_data.m_value.number_float));
} }
SECTION("floating-point literal without suffix") SECTION("floating-point literal without suffix")
{ {
json const j(42.23); json const j(42.23);
CHECK(j.type() == json::value_t::number_float); CHECK(j.type() == json::value_t::number_float);
CHECK(j.m_value.number_float == Approx(j_reference.m_value.number_float)); CHECK(j.m_data.m_value.number_float == Approx(j_reference.m_data.m_value.number_float));
} }
SECTION("integer literal with f suffix") SECTION("integer literal with f suffix")
{ {
json const j(42.23f); json const j(42.23f);
CHECK(j.type() == json::value_t::number_float); CHECK(j.type() == json::value_t::number_float);
CHECK(j.m_value.number_float == Approx(j_reference.m_value.number_float)); CHECK(j.m_data.m_value.number_float == Approx(j_reference.m_data.m_value.number_float));
} }
SECTION("integer literal with l suffix") SECTION("integer literal with l suffix")
{ {
json const j(42.23L); json const j(42.23L);
CHECK(j.type() == json::value_t::number_float); CHECK(j.type() == json::value_t::number_float);
CHECK(j.m_value.number_float == Approx(j_reference.m_value.number_float)); CHECK(j.m_data.m_value.number_float == Approx(j_reference.m_data.m_value.number_float));
} }
} }

View File

@ -1076,19 +1076,19 @@ TEST_CASE("value conversion")
SECTION("number_float_t") SECTION("number_float_t")
{ {
auto n = j.get<json::number_float_t>(); auto n = j.get<json::number_float_t>();
CHECK(json(n).m_value.number_float == Approx(j.m_value.number_float)); CHECK(json(n).m_data.m_value.number_float == Approx(j.m_data.m_value.number_float));
} }
SECTION("float") SECTION("float")
{ {
auto n = j.get<float>(); auto n = j.get<float>();
CHECK(json(n).m_value.number_float == Approx(j.m_value.number_float)); CHECK(json(n).m_data.m_value.number_float == Approx(j.m_data.m_value.number_float));
} }
SECTION("double") SECTION("double")
{ {
auto n = j.get<double>(); auto n = j.get<double>();
CHECK(json(n).m_value.number_float == Approx(j.m_value.number_float)); CHECK(json(n).m_data.m_value.number_float == Approx(j.m_data.m_value.number_float));
} }
SECTION("exception in case of a non-string type") SECTION("exception in case of a non-string type")
@ -1126,19 +1126,19 @@ TEST_CASE("value conversion")
SECTION("number_float_t") SECTION("number_float_t")
{ {
json::number_float_t const n = j; json::number_float_t const n = j;
CHECK(json(n).m_value.number_float == Approx(j.m_value.number_float)); CHECK(json(n).m_data.m_value.number_float == Approx(j.m_data.m_value.number_float));
} }
SECTION("float") SECTION("float")
{ {
float const n = j; float const n = j;
CHECK(json(n).m_value.number_float == Approx(j.m_value.number_float)); CHECK(json(n).m_data.m_value.number_float == Approx(j.m_data.m_value.number_float));
} }
SECTION("double") SECTION("double")
{ {
double const n = j; double const n = j;
CHECK(json(n).m_value.number_float == Approx(j.m_value.number_float)); CHECK(json(n).m_data.m_value.number_float == Approx(j.m_data.m_value.number_float));
} }
} }
#endif #endif
@ -1151,7 +1151,7 @@ TEST_CASE("value conversion")
SECTION("binary_t") SECTION("binary_t")
{ {
json::binary_t const b = j.get<json::binary_t>(); json::binary_t const b = j.get<json::binary_t>();
CHECK(*json(b).m_value.binary == *j.m_value.binary); CHECK(*json(b).m_data.m_value.binary == *j.m_data.m_value.binary);
} }
SECTION("get_binary()") SECTION("get_binary()")
@ -1159,14 +1159,14 @@ TEST_CASE("value conversion")
SECTION("non-const") SECTION("non-const")
{ {
auto& b = j.get_binary(); auto& b = j.get_binary();
CHECK(*json(b).m_value.binary == *j.m_value.binary); CHECK(*json(b).m_data.m_value.binary == *j.m_data.m_value.binary);
} }
SECTION("non-const") SECTION("non-const")
{ {
const json j_const = j; const json j_const = j;
const auto& b = j_const.get_binary(); const auto& b = j_const.get_binary();
CHECK(*json(b).m_value.binary == *j.m_value.binary); CHECK(*json(b).m_data.m_value.binary == *j.m_data.m_value.binary);
} }
} }
@ -1258,7 +1258,7 @@ TEST_CASE("value conversion")
SECTION("binary_t") SECTION("binary_t")
{ {
json::binary_t const b = j; json::binary_t const b = j;
CHECK(*json(b).m_value.binary == *j.m_value.binary); CHECK(*json(b).m_data.m_value.binary == *j.m_data.m_value.binary);
} }
} }
#endif #endif

View File

@ -0,0 +1,86 @@
// __ _____ _____ _____
// __| | __| | | | JSON for Modern C++ (supporting code)
// | | |__ | | | | | | version 3.11.2
// |_____|_____|_____|_|___| https://github.com/nlohmann/json
//
// SPDX-FileCopyrightText: 2013-2022 Niels Lohmann <https://nlohmann.me>
// SPDX-License-Identifier: MIT
#include "doctest_compatibility.h"
#include <nlohmann/json.hpp>
#include <exception>
#include <iostream>
struct Foo
{
int a;
int b;
};
namespace nlohmann
{
template <>
struct adl_serializer<Foo>
{
static void to_json(json& j, Foo const& f)
{
switch (f.b)
{
case 0:
j["a"] = f.a;
break;
case 1:
j[0] = f.a;
break;
default:
j = "test";
}
if (f.a == 1)
{
throw std::runtime_error("b is invalid");
}
}
};
} // namespace nlohmann
TEST_CASE("check_for_mem_leak_on_adl_to_json-1")
{
try
{
const nlohmann::json j = Foo {1, 0};
std::cout << j.dump() << "\n";
}
catch (...)
{
// just ignore the exception in this POC
}
}
TEST_CASE("check_for_mem_leak_on_adl_to_json-2")
{
try
{
const nlohmann::json j = Foo {1, 1};
std::cout << j.dump() << "\n";
}
catch (...)
{
// just ignore the exception in this POC
}
}
TEST_CASE("check_for_mem_leak_on_adl_to_json-2")
{
try
{
const nlohmann::json j = Foo {1, 2};
std::cout << j.dump() << "\n";
}
catch (...)
{
// just ignore the exception in this POC
}
}