mirror of
https://github.com/nlohmann/json
synced 2024-11-09 14:10:07 +00:00
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:
parent
fe4b66355c
commit
bbe337c3a3
@ -7,11 +7,11 @@ check_task:
|
||||
- tar xfz cmake-3.20.2.tar.gz
|
||||
- cd cmake-3.20.2
|
||||
- ./configure
|
||||
- make cmake ctest -j10
|
||||
- make cmake ctest -j4
|
||||
- cd ..
|
||||
- mkdir build
|
||||
- cd build
|
||||
- ../cmake-3.20.2/bin/cmake .. -DJSON_FastTests=ON
|
||||
- make -j10
|
||||
- make -j4
|
||||
- cd tests
|
||||
- ../../cmake-3.20.2/bin/ctest -j10
|
||||
- ../../cmake-3.20.2/bin/ctest -j4
|
||||
|
@ -34,7 +34,7 @@ namespace detail
|
||||
|
||||
/*
|
||||
* 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
|
||||
* https://github.com/nlohmann/json/issues/2865 for more information.
|
||||
*/
|
||||
@ -47,9 +47,9 @@ struct external_constructor<value_t::boolean>
|
||||
template<typename BasicJsonType>
|
||||
static void construct(BasicJsonType& j, typename BasicJsonType::boolean_t b) noexcept
|
||||
{
|
||||
j.m_value.destroy(j.m_type);
|
||||
j.m_type = value_t::boolean;
|
||||
j.m_value = b;
|
||||
j.m_data.m_value.destroy(j.m_data.m_type);
|
||||
j.m_data.m_type = value_t::boolean;
|
||||
j.m_data.m_value = b;
|
||||
j.assert_invariant();
|
||||
}
|
||||
};
|
||||
@ -60,18 +60,18 @@ struct external_constructor<value_t::string>
|
||||
template<typename BasicJsonType>
|
||||
static void construct(BasicJsonType& j, const typename BasicJsonType::string_t& s)
|
||||
{
|
||||
j.m_value.destroy(j.m_type);
|
||||
j.m_type = value_t::string;
|
||||
j.m_value = s;
|
||||
j.m_data.m_value.destroy(j.m_data.m_type);
|
||||
j.m_data.m_type = value_t::string;
|
||||
j.m_data.m_value = s;
|
||||
j.assert_invariant();
|
||||
}
|
||||
|
||||
template<typename BasicJsonType>
|
||||
static void construct(BasicJsonType& j, typename BasicJsonType::string_t&& s)
|
||||
{
|
||||
j.m_value.destroy(j.m_type);
|
||||
j.m_type = value_t::string;
|
||||
j.m_value = std::move(s);
|
||||
j.m_data.m_value.destroy(j.m_data.m_type);
|
||||
j.m_data.m_type = value_t::string;
|
||||
j.m_data.m_value = std::move(s);
|
||||
j.assert_invariant();
|
||||
}
|
||||
|
||||
@ -80,9 +80,9 @@ struct external_constructor<value_t::string>
|
||||
int > = 0 >
|
||||
static void construct(BasicJsonType& j, const CompatibleStringType& str)
|
||||
{
|
||||
j.m_value.destroy(j.m_type);
|
||||
j.m_type = value_t::string;
|
||||
j.m_value.string = j.template create<typename BasicJsonType::string_t>(str);
|
||||
j.m_data.m_value.destroy(j.m_data.m_type);
|
||||
j.m_data.m_type = value_t::string;
|
||||
j.m_data.m_value.string = j.template create<typename BasicJsonType::string_t>(str);
|
||||
j.assert_invariant();
|
||||
}
|
||||
};
|
||||
@ -93,18 +93,18 @@ struct external_constructor<value_t::binary>
|
||||
template<typename BasicJsonType>
|
||||
static void construct(BasicJsonType& j, const typename BasicJsonType::binary_t& b)
|
||||
{
|
||||
j.m_value.destroy(j.m_type);
|
||||
j.m_type = value_t::binary;
|
||||
j.m_value = typename BasicJsonType::binary_t(b);
|
||||
j.m_data.m_value.destroy(j.m_data.m_type);
|
||||
j.m_data.m_type = value_t::binary;
|
||||
j.m_data.m_value = typename BasicJsonType::binary_t(b);
|
||||
j.assert_invariant();
|
||||
}
|
||||
|
||||
template<typename BasicJsonType>
|
||||
static void construct(BasicJsonType& j, typename BasicJsonType::binary_t&& b)
|
||||
{
|
||||
j.m_value.destroy(j.m_type);
|
||||
j.m_type = value_t::binary;
|
||||
j.m_value = typename BasicJsonType::binary_t(std::move(b));
|
||||
j.m_data.m_value.destroy(j.m_data.m_type);
|
||||
j.m_data.m_type = value_t::binary;
|
||||
j.m_data.m_value = typename BasicJsonType::binary_t(std::move(b));
|
||||
j.assert_invariant();
|
||||
}
|
||||
};
|
||||
@ -115,9 +115,9 @@ struct external_constructor<value_t::number_float>
|
||||
template<typename BasicJsonType>
|
||||
static void construct(BasicJsonType& j, typename BasicJsonType::number_float_t val) noexcept
|
||||
{
|
||||
j.m_value.destroy(j.m_type);
|
||||
j.m_type = value_t::number_float;
|
||||
j.m_value = val;
|
||||
j.m_data.m_value.destroy(j.m_data.m_type);
|
||||
j.m_data.m_type = value_t::number_float;
|
||||
j.m_data.m_value = val;
|
||||
j.assert_invariant();
|
||||
}
|
||||
};
|
||||
@ -128,9 +128,9 @@ struct external_constructor<value_t::number_unsigned>
|
||||
template<typename BasicJsonType>
|
||||
static void construct(BasicJsonType& j, typename BasicJsonType::number_unsigned_t val) noexcept
|
||||
{
|
||||
j.m_value.destroy(j.m_type);
|
||||
j.m_type = value_t::number_unsigned;
|
||||
j.m_value = val;
|
||||
j.m_data.m_value.destroy(j.m_data.m_type);
|
||||
j.m_data.m_type = value_t::number_unsigned;
|
||||
j.m_data.m_value = val;
|
||||
j.assert_invariant();
|
||||
}
|
||||
};
|
||||
@ -141,9 +141,9 @@ struct external_constructor<value_t::number_integer>
|
||||
template<typename BasicJsonType>
|
||||
static void construct(BasicJsonType& j, typename BasicJsonType::number_integer_t val) noexcept
|
||||
{
|
||||
j.m_value.destroy(j.m_type);
|
||||
j.m_type = value_t::number_integer;
|
||||
j.m_value = val;
|
||||
j.m_data.m_value.destroy(j.m_data.m_type);
|
||||
j.m_data.m_type = value_t::number_integer;
|
||||
j.m_data.m_value = val;
|
||||
j.assert_invariant();
|
||||
}
|
||||
};
|
||||
@ -154,9 +154,9 @@ struct external_constructor<value_t::array>
|
||||
template<typename BasicJsonType>
|
||||
static void construct(BasicJsonType& j, const typename BasicJsonType::array_t& arr)
|
||||
{
|
||||
j.m_value.destroy(j.m_type);
|
||||
j.m_type = value_t::array;
|
||||
j.m_value = arr;
|
||||
j.m_data.m_value.destroy(j.m_data.m_type);
|
||||
j.m_data.m_type = value_t::array;
|
||||
j.m_data.m_value = arr;
|
||||
j.set_parents();
|
||||
j.assert_invariant();
|
||||
}
|
||||
@ -164,9 +164,9 @@ struct external_constructor<value_t::array>
|
||||
template<typename BasicJsonType>
|
||||
static void construct(BasicJsonType& j, typename BasicJsonType::array_t&& arr)
|
||||
{
|
||||
j.m_value.destroy(j.m_type);
|
||||
j.m_type = value_t::array;
|
||||
j.m_value = std::move(arr);
|
||||
j.m_data.m_value.destroy(j.m_data.m_type);
|
||||
j.m_data.m_type = value_t::array;
|
||||
j.m_data.m_value = std::move(arr);
|
||||
j.set_parents();
|
||||
j.assert_invariant();
|
||||
}
|
||||
@ -179,9 +179,9 @@ struct external_constructor<value_t::array>
|
||||
using std::begin;
|
||||
using std::end;
|
||||
|
||||
j.m_value.destroy(j.m_type);
|
||||
j.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.destroy(j.m_data.m_type);
|
||||
j.m_data.m_type = value_t::array;
|
||||
j.m_data.m_value.array = j.template create<typename BasicJsonType::array_t>(begin(arr), end(arr));
|
||||
j.set_parents();
|
||||
j.assert_invariant();
|
||||
}
|
||||
@ -189,14 +189,14 @@ struct external_constructor<value_t::array>
|
||||
template<typename BasicJsonType>
|
||||
static void construct(BasicJsonType& j, const std::vector<bool>& arr)
|
||||
{
|
||||
j.m_value.destroy(j.m_type);
|
||||
j.m_type = value_t::array;
|
||||
j.m_value = value_t::array;
|
||||
j.m_value.array->reserve(arr.size());
|
||||
j.m_data.m_value.destroy(j.m_data.m_type);
|
||||
j.m_data.m_type = value_t::array;
|
||||
j.m_data.m_value = value_t::array;
|
||||
j.m_data.m_value.array->reserve(arr.size());
|
||||
for (const bool x : arr)
|
||||
{
|
||||
j.m_value.array->push_back(x);
|
||||
j.set_parent(j.m_value.array->back());
|
||||
j.m_data.m_value.array->push_back(x);
|
||||
j.set_parent(j.m_data.m_value.array->back());
|
||||
}
|
||||
j.assert_invariant();
|
||||
}
|
||||
@ -205,13 +205,13 @@ struct external_constructor<value_t::array>
|
||||
enable_if_t<std::is_convertible<T, BasicJsonType>::value, int> = 0>
|
||||
static void construct(BasicJsonType& j, const std::valarray<T>& arr)
|
||||
{
|
||||
j.m_value.destroy(j.m_type);
|
||||
j.m_type = value_t::array;
|
||||
j.m_value = value_t::array;
|
||||
j.m_value.array->resize(arr.size());
|
||||
j.m_data.m_value.destroy(j.m_data.m_type);
|
||||
j.m_data.m_type = value_t::array;
|
||||
j.m_data.m_value = value_t::array;
|
||||
j.m_data.m_value.array->resize(arr.size());
|
||||
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.assert_invariant();
|
||||
@ -224,9 +224,9 @@ struct external_constructor<value_t::object>
|
||||
template<typename BasicJsonType>
|
||||
static void construct(BasicJsonType& j, const typename BasicJsonType::object_t& obj)
|
||||
{
|
||||
j.m_value.destroy(j.m_type);
|
||||
j.m_type = value_t::object;
|
||||
j.m_value = obj;
|
||||
j.m_data.m_value.destroy(j.m_data.m_type);
|
||||
j.m_data.m_type = value_t::object;
|
||||
j.m_data.m_value = obj;
|
||||
j.set_parents();
|
||||
j.assert_invariant();
|
||||
}
|
||||
@ -234,9 +234,9 @@ struct external_constructor<value_t::object>
|
||||
template<typename BasicJsonType>
|
||||
static void construct(BasicJsonType& j, typename BasicJsonType::object_t&& obj)
|
||||
{
|
||||
j.m_value.destroy(j.m_type);
|
||||
j.m_type = value_t::object;
|
||||
j.m_value = std::move(obj);
|
||||
j.m_data.m_value.destroy(j.m_data.m_type);
|
||||
j.m_data.m_type = value_t::object;
|
||||
j.m_data.m_value = std::move(obj);
|
||||
j.set_parents();
|
||||
j.assert_invariant();
|
||||
}
|
||||
@ -248,9 +248,9 @@ struct external_constructor<value_t::object>
|
||||
using std::begin;
|
||||
using std::end;
|
||||
|
||||
j.m_value.destroy(j.m_type);
|
||||
j.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.destroy(j.m_data.m_type);
|
||||
j.m_data.m_type = value_t::object;
|
||||
j.m_data.m_value.object = j.template create<typename BasicJsonType::object_t>(begin(obj), end(obj));
|
||||
j.set_parents();
|
||||
j.assert_invariant();
|
||||
}
|
||||
|
@ -73,9 +73,9 @@ class exception : public std::exception
|
||||
{
|
||||
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 (¤t->m_parent->m_value.array->operator[](i) == current)
|
||||
if (¤t->m_parent->m_data.m_value.array->operator[](i) == current)
|
||||
{
|
||||
tokens.emplace_back(std::to_string(i));
|
||||
break;
|
||||
@ -86,7 +86,7 @@ class exception : public std::exception
|
||||
|
||||
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)
|
||||
{
|
||||
|
@ -244,7 +244,7 @@ class json_sax_dom_parser
|
||||
JSON_ASSERT(ref_stack.back()->is_object());
|
||||
|
||||
// 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;
|
||||
}
|
||||
|
||||
@ -319,8 +319,8 @@ class json_sax_dom_parser
|
||||
|
||||
if (ref_stack.back()->is_array())
|
||||
{
|
||||
ref_stack.back()->m_value.array->emplace_back(std::forward<Value>(v));
|
||||
return &(ref_stack.back()->m_value.array->back());
|
||||
ref_stack.back()->m_data.m_value.array->emplace_back(std::forward<Value>(v));
|
||||
return &(ref_stack.back()->m_data.m_value.array->back());
|
||||
}
|
||||
|
||||
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
|
||||
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;
|
||||
@ -524,7 +524,7 @@ class json_sax_dom_callback_parser
|
||||
// remove discarded value
|
||||
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;
|
||||
@ -607,8 +607,8 @@ class json_sax_dom_callback_parser
|
||||
// array
|
||||
if (ref_stack.back()->is_array())
|
||||
{
|
||||
ref_stack.back()->m_value.array->emplace_back(std::move(value));
|
||||
return {true, &(ref_stack.back()->m_value.array->back())};
|
||||
ref_stack.back()->m_data.m_value.array->emplace_back(std::move(value));
|
||||
return {true, &(ref_stack.back()->m_data.m_value.array->back())};
|
||||
}
|
||||
|
||||
// object
|
||||
|
@ -101,7 +101,7 @@ class iter_impl // NOLINT(cppcoreguidelines-special-member-functions,hicpp-speci
|
||||
{
|
||||
JSON_ASSERT(m_object != nullptr);
|
||||
|
||||
switch (m_object->m_type)
|
||||
switch (m_object->m_data.m_type)
|
||||
{
|
||||
case value_t::object:
|
||||
{
|
||||
@ -198,17 +198,17 @@ class iter_impl // NOLINT(cppcoreguidelines-special-member-functions,hicpp-speci
|
||||
{
|
||||
JSON_ASSERT(m_object != nullptr);
|
||||
|
||||
switch (m_object->m_type)
|
||||
switch (m_object->m_data.m_type)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
@ -242,17 +242,17 @@ class iter_impl // NOLINT(cppcoreguidelines-special-member-functions,hicpp-speci
|
||||
{
|
||||
JSON_ASSERT(m_object != nullptr);
|
||||
|
||||
switch (m_object->m_type)
|
||||
switch (m_object->m_data.m_type)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
@ -281,17 +281,17 @@ class iter_impl // NOLINT(cppcoreguidelines-special-member-functions,hicpp-speci
|
||||
{
|
||||
JSON_ASSERT(m_object != nullptr);
|
||||
|
||||
switch (m_object->m_type)
|
||||
switch (m_object->m_data.m_type)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
@ -325,17 +325,17 @@ class iter_impl // NOLINT(cppcoreguidelines-special-member-functions,hicpp-speci
|
||||
{
|
||||
JSON_ASSERT(m_object != nullptr);
|
||||
|
||||
switch (m_object->m_type)
|
||||
switch (m_object->m_data.m_type)
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
@ -378,7 +378,7 @@ class iter_impl // NOLINT(cppcoreguidelines-special-member-functions,hicpp-speci
|
||||
{
|
||||
JSON_ASSERT(m_object != nullptr);
|
||||
|
||||
switch (m_object->m_type)
|
||||
switch (m_object->m_data.m_type)
|
||||
{
|
||||
case value_t::object:
|
||||
{
|
||||
@ -429,7 +429,7 @@ class iter_impl // NOLINT(cppcoreguidelines-special-member-functions,hicpp-speci
|
||||
{
|
||||
JSON_ASSERT(m_object != nullptr);
|
||||
|
||||
switch (m_object->m_type)
|
||||
switch (m_object->m_data.m_type)
|
||||
{
|
||||
case value_t::object:
|
||||
{
|
||||
@ -476,7 +476,7 @@ class iter_impl // NOLINT(cppcoreguidelines-special-member-functions,hicpp-speci
|
||||
|
||||
JSON_ASSERT(m_object != nullptr);
|
||||
|
||||
switch (m_object->m_type)
|
||||
switch (m_object->m_data.m_type)
|
||||
{
|
||||
case value_t::object:
|
||||
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);
|
||||
|
||||
switch (m_object->m_type)
|
||||
switch (m_object->m_data.m_type)
|
||||
{
|
||||
case value_t::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);
|
||||
|
||||
switch (m_object->m_type)
|
||||
switch (m_object->m_data.m_type)
|
||||
{
|
||||
case value_t::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);
|
||||
|
||||
switch (m_object->m_type)
|
||||
switch (m_object->m_data.m_type)
|
||||
{
|
||||
case value_t::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);
|
||||
|
||||
switch (m_object->m_type)
|
||||
switch (m_object->m_data.m_type)
|
||||
{
|
||||
case value_t::object:
|
||||
JSON_THROW(invalid_iterator::create(208, "cannot use operator[] for object iterators", m_object));
|
||||
|
@ -386,7 +386,7 @@ class json_pointer
|
||||
if (reference_token == "-")
|
||||
{
|
||||
// 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
|
||||
{
|
||||
@ -438,7 +438,7 @@ class json_pointer
|
||||
{
|
||||
// "-" always fails the range check
|
||||
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));
|
||||
}
|
||||
|
||||
@ -495,7 +495,7 @@ class json_pointer
|
||||
if (JSON_HEDLEY_UNLIKELY(reference_token == "-"))
|
||||
{
|
||||
// "-" 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
|
||||
@ -545,7 +545,7 @@ class json_pointer
|
||||
{
|
||||
// "-" always fails the range check
|
||||
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));
|
||||
}
|
||||
|
||||
@ -740,7 +740,7 @@ class json_pointer
|
||||
{
|
||||
case detail::value_t::array:
|
||||
{
|
||||
if (value.m_value.array->empty())
|
||||
if (value.m_data.m_value.array->empty())
|
||||
{
|
||||
// flatten empty array as null
|
||||
result[reference_string] = nullptr;
|
||||
@ -748,10 +748,10 @@ class json_pointer
|
||||
else
|
||||
{
|
||||
// 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)),
|
||||
value.m_value.array->operator[](i), result);
|
||||
value.m_data.m_value.array->operator[](i), result);
|
||||
}
|
||||
}
|
||||
break;
|
||||
@ -759,7 +759,7 @@ class json_pointer
|
||||
|
||||
case detail::value_t::object:
|
||||
{
|
||||
if (value.m_value.object->empty())
|
||||
if (value.m_data.m_value.object->empty())
|
||||
{
|
||||
// flatten empty object as null
|
||||
result[reference_string] = nullptr;
|
||||
@ -767,7 +767,7 @@ class json_pointer
|
||||
else
|
||||
{
|
||||
// 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);
|
||||
}
|
||||
@ -814,7 +814,7 @@ class json_pointer
|
||||
BasicJsonType result;
|
||||
|
||||
// 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()))
|
||||
{
|
||||
|
@ -63,7 +63,7 @@ class binary_writer
|
||||
{
|
||||
case value_t::object:
|
||||
{
|
||||
write_bson_object(*j.m_value.object);
|
||||
write_bson_object(*j.m_data.m_value.object);
|
||||
break;
|
||||
}
|
||||
|
||||
@ -98,7 +98,7 @@ class binary_writer
|
||||
|
||||
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(0xF4));
|
||||
break;
|
||||
@ -106,42 +106,42 @@ class binary_writer
|
||||
|
||||
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
|
||||
// integers and unsigned integers. Therefore, we used the
|
||||
// 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));
|
||||
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));
|
||||
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));
|
||||
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
|
||||
{
|
||||
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
|
||||
{
|
||||
// The conversions below encode the sign in the first
|
||||
// byte, and the value is converted to a positive number.
|
||||
const auto positive_number = -1 - j.m_value.number_integer;
|
||||
if (j.m_value.number_integer >= -24)
|
||||
const auto positive_number = -1 - j.m_data.m_value.number_integer;
|
||||
if (j.m_data.m_value.number_integer >= -24)
|
||||
{
|
||||
write_number(static_cast<std::uint8_t>(0x20 + positive_number));
|
||||
}
|
||||
@ -171,52 +171,52 @@ class binary_writer
|
||||
|
||||
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));
|
||||
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));
|
||||
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));
|
||||
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
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
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
|
||||
oa->write_character(to_char_type(0xF9));
|
||||
oa->write_character(to_char_type(0x7E));
|
||||
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
|
||||
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));
|
||||
}
|
||||
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;
|
||||
}
|
||||
@ -224,7 +224,7 @@ class binary_writer
|
||||
case value_t::string:
|
||||
{
|
||||
// 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)
|
||||
{
|
||||
write_number(static_cast<std::uint8_t>(0x60 + N));
|
||||
@ -254,15 +254,15 @@ class binary_writer
|
||||
|
||||
// step 2: write the string
|
||||
oa->write_characters(
|
||||
reinterpret_cast<const CharType*>(j.m_value.string->c_str()),
|
||||
j.m_value.string->size());
|
||||
reinterpret_cast<const CharType*>(j.m_data.m_value.string->c_str()),
|
||||
j.m_data.m_value.string->size());
|
||||
break;
|
||||
}
|
||||
|
||||
case value_t::array:
|
||||
{
|
||||
// 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)
|
||||
{
|
||||
write_number(static_cast<std::uint8_t>(0x80 + N));
|
||||
@ -291,7 +291,7 @@ class binary_writer
|
||||
// LCOV_EXCL_STOP
|
||||
|
||||
// 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);
|
||||
}
|
||||
@ -300,32 +300,32 @@ class binary_writer
|
||||
|
||||
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>(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::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::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::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
|
||||
const auto N = j.m_value.binary->size();
|
||||
const auto N = j.m_data.m_value.binary->size();
|
||||
if (N <= 0x17)
|
||||
{
|
||||
write_number(static_cast<std::uint8_t>(0x40 + N));
|
||||
@ -355,7 +355,7 @@ class binary_writer
|
||||
|
||||
// step 2: write each element
|
||||
oa->write_characters(
|
||||
reinterpret_cast<const CharType*>(j.m_value.binary->data()),
|
||||
reinterpret_cast<const CharType*>(j.m_data.m_value.binary->data()),
|
||||
N);
|
||||
|
||||
break;
|
||||
@ -364,7 +364,7 @@ class binary_writer
|
||||
case value_t::object:
|
||||
{
|
||||
// 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)
|
||||
{
|
||||
write_number(static_cast<std::uint8_t>(0xA0 + N));
|
||||
@ -393,7 +393,7 @@ class binary_writer
|
||||
// LCOV_EXCL_STOP
|
||||
|
||||
// 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.second);
|
||||
@ -422,7 +422,7 @@ class binary_writer
|
||||
|
||||
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(0xC2));
|
||||
break;
|
||||
@ -430,75 +430,75 @@ class binary_writer
|
||||
|
||||
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
|
||||
// signed integers and unsigned integers. Therefore, we used
|
||||
// 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
|
||||
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
|
||||
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
|
||||
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
|
||||
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
|
||||
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
|
||||
{
|
||||
if (j.m_value.number_integer >= -32)
|
||||
if (j.m_data.m_value.number_integer >= -32)
|
||||
{
|
||||
// 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)() &&
|
||||
j.m_value.number_integer <= (std::numeric_limits<std::int8_t>::max)())
|
||||
else if (j.m_data.m_value.number_integer >= (std::numeric_limits<std::int8_t>::min)() &&
|
||||
j.m_data.m_value.number_integer <= (std::numeric_limits<std::int8_t>::max)())
|
||||
{
|
||||
// int 8
|
||||
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)() &&
|
||||
j.m_value.number_integer <= (std::numeric_limits<std::int16_t>::max)())
|
||||
else if (j.m_data.m_value.number_integer >= (std::numeric_limits<std::int16_t>::min)() &&
|
||||
j.m_data.m_value.number_integer <= (std::numeric_limits<std::int16_t>::max)())
|
||||
{
|
||||
// int 16
|
||||
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)() &&
|
||||
j.m_value.number_integer <= (std::numeric_limits<std::int32_t>::max)())
|
||||
else if (j.m_data.m_value.number_integer >= (std::numeric_limits<std::int32_t>::min)() &&
|
||||
j.m_data.m_value.number_integer <= (std::numeric_limits<std::int32_t>::max)())
|
||||
{
|
||||
// int 32
|
||||
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)() &&
|
||||
j.m_value.number_integer <= (std::numeric_limits<std::int64_t>::max)())
|
||||
else if (j.m_data.m_value.number_integer >= (std::numeric_limits<std::int64_t>::min)() &&
|
||||
j.m_data.m_value.number_integer <= (std::numeric_limits<std::int64_t>::max)())
|
||||
{
|
||||
// int 64
|
||||
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;
|
||||
@ -506,48 +506,48 @@ class binary_writer
|
||||
|
||||
case value_t::number_unsigned:
|
||||
{
|
||||
if (j.m_value.number_unsigned < 128)
|
||||
if (j.m_data.m_value.number_unsigned < 128)
|
||||
{
|
||||
// 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
|
||||
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
|
||||
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
|
||||
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
|
||||
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;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
case value_t::string:
|
||||
{
|
||||
// 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)
|
||||
{
|
||||
// fixstr
|
||||
@ -574,15 +574,15 @@ class binary_writer
|
||||
|
||||
// step 2: write the string
|
||||
oa->write_characters(
|
||||
reinterpret_cast<const CharType*>(j.m_value.string->c_str()),
|
||||
j.m_value.string->size());
|
||||
reinterpret_cast<const CharType*>(j.m_data.m_value.string->c_str()),
|
||||
j.m_data.m_value.string->size());
|
||||
break;
|
||||
}
|
||||
|
||||
case value_t::array:
|
||||
{
|
||||
// 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)
|
||||
{
|
||||
// fixarray
|
||||
@ -602,7 +602,7 @@ class binary_writer
|
||||
}
|
||||
|
||||
// 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);
|
||||
}
|
||||
@ -613,10 +613,10 @@ class binary_writer
|
||||
{
|
||||
// step 0: determine if the binary type has a set subtype to
|
||||
// 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
|
||||
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)())
|
||||
{
|
||||
std::uint8_t output_type{};
|
||||
@ -681,12 +681,12 @@ class binary_writer
|
||||
// step 1.5: if this is an ext type, write the subtype
|
||||
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
|
||||
oa->write_characters(
|
||||
reinterpret_cast<const CharType*>(j.m_value.binary->data()),
|
||||
reinterpret_cast<const CharType*>(j.m_data.m_value.binary->data()),
|
||||
N);
|
||||
|
||||
break;
|
||||
@ -695,7 +695,7 @@ class binary_writer
|
||||
case value_t::object:
|
||||
{
|
||||
// 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)
|
||||
{
|
||||
// fixmap
|
||||
@ -715,7 +715,7 @@ class binary_writer
|
||||
}
|
||||
|
||||
// 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.second);
|
||||
@ -755,7 +755,7 @@ class binary_writer
|
||||
{
|
||||
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('F'));
|
||||
}
|
||||
@ -764,19 +764,19 @@ class binary_writer
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
@ -786,10 +786,10 @@ class binary_writer
|
||||
{
|
||||
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(
|
||||
reinterpret_cast<const CharType*>(j.m_value.string->c_str()),
|
||||
j.m_value.string->size());
|
||||
reinterpret_cast<const CharType*>(j.m_data.m_value.string->c_str()),
|
||||
j.m_data.m_value.string->size());
|
||||
break;
|
||||
}
|
||||
|
||||
@ -801,7 +801,7 @@ class binary_writer
|
||||
}
|
||||
|
||||
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);
|
||||
const CharType first_prefix = ubjson_prefix(j.front(), use_bjdata);
|
||||
@ -824,10 +824,10 @@ class binary_writer
|
||||
if (use_count)
|
||||
{
|
||||
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);
|
||||
}
|
||||
@ -847,7 +847,7 @@ class binary_writer
|
||||
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);
|
||||
oa->write_character(to_char_type('$'));
|
||||
@ -857,21 +857,21 @@ class binary_writer
|
||||
if (use_count)
|
||||
{
|
||||
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)
|
||||
{
|
||||
oa->write_characters(
|
||||
reinterpret_cast<const CharType*>(j.m_value.binary->data()),
|
||||
j.m_value.binary->size());
|
||||
reinterpret_cast<const CharType*>(j.m_data.m_value.binary->data()),
|
||||
j.m_data.m_value.binary->size());
|
||||
}
|
||||
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(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:
|
||||
{
|
||||
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;
|
||||
}
|
||||
@ -899,7 +899,7 @@ class binary_writer
|
||||
}
|
||||
|
||||
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);
|
||||
const CharType first_prefix = ubjson_prefix(j.front(), use_bjdata);
|
||||
@ -922,10 +922,10 @@ class binary_writer
|
||||
if (use_count)
|
||||
{
|
||||
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);
|
||||
oa->write_characters(
|
||||
@ -1075,19 +1075,19 @@ class binary_writer
|
||||
void write_bson_unsigned(const string_t& name,
|
||||
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_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_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
|
||||
{
|
||||
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())
|
||||
{
|
||||
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:
|
||||
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:
|
||||
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:
|
||||
return header_size + 1ul;
|
||||
@ -1183,13 +1183,13 @@ class binary_writer
|
||||
return header_size + 8ul;
|
||||
|
||||
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:
|
||||
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:
|
||||
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:
|
||||
return header_size + 0ul;
|
||||
@ -1215,28 +1215,28 @@ class binary_writer
|
||||
switch (j.type())
|
||||
{
|
||||
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:
|
||||
return write_bson_array(name, *j.m_value.array);
|
||||
return write_bson_array(name, *j.m_data.m_value.array);
|
||||
|
||||
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:
|
||||
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:
|
||||
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:
|
||||
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:
|
||||
return write_bson_unsigned(name, j);
|
||||
|
||||
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:
|
||||
return write_bson_null(name);
|
||||
@ -1509,35 +1509,35 @@ class binary_writer
|
||||
return 'Z';
|
||||
|
||||
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:
|
||||
{
|
||||
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';
|
||||
}
|
||||
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';
|
||||
}
|
||||
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';
|
||||
}
|
||||
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';
|
||||
}
|
||||
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';
|
||||
}
|
||||
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';
|
||||
}
|
||||
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';
|
||||
}
|
||||
@ -1547,35 +1547,35 @@ class binary_writer
|
||||
|
||||
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';
|
||||
}
|
||||
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';
|
||||
}
|
||||
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';
|
||||
}
|
||||
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';
|
||||
}
|
||||
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';
|
||||
}
|
||||
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';
|
||||
}
|
||||
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';
|
||||
}
|
||||
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';
|
||||
}
|
||||
@ -1584,7 +1584,7 @@ class binary_writer
|
||||
}
|
||||
|
||||
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:
|
||||
return 'S';
|
||||
@ -1633,7 +1633,7 @@ class binary_writer
|
||||
std::size_t len = (value.at(key).empty() ? 0 : 1);
|
||||
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_";
|
||||
@ -1655,70 +1655,70 @@ class binary_writer
|
||||
{
|
||||
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')
|
||||
{
|
||||
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')
|
||||
{
|
||||
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')
|
||||
{
|
||||
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')
|
||||
{
|
||||
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')
|
||||
{
|
||||
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')
|
||||
{
|
||||
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')
|
||||
{
|
||||
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')
|
||||
{
|
||||
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')
|
||||
{
|
||||
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;
|
||||
|
@ -110,11 +110,11 @@ class serializer
|
||||
const unsigned int indent_step,
|
||||
const unsigned int current_indent = 0)
|
||||
{
|
||||
switch (val.m_type)
|
||||
switch (val.m_data.m_type)
|
||||
{
|
||||
case value_t::object:
|
||||
{
|
||||
if (val.m_value.object->empty())
|
||||
if (val.m_data.m_value.object->empty())
|
||||
{
|
||||
o->write_characters("{}", 2);
|
||||
return;
|
||||
@ -132,8 +132,8 @@ class serializer
|
||||
}
|
||||
|
||||
// first n-1 elements
|
||||
auto i = val.m_value.object->cbegin();
|
||||
for (std::size_t cnt = 0; cnt < val.m_value.object->size() - 1; ++cnt, ++i)
|
||||
auto i = val.m_data.m_value.object->cbegin();
|
||||
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_character('\"');
|
||||
@ -144,8 +144,8 @@ class serializer
|
||||
}
|
||||
|
||||
// last element
|
||||
JSON_ASSERT(i != val.m_value.object->cend());
|
||||
JSON_ASSERT(std::next(i) == val.m_value.object->cend());
|
||||
JSON_ASSERT(i != val.m_data.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_character('\"');
|
||||
dump_escaped(i->first, ensure_ascii);
|
||||
@ -161,8 +161,8 @@ class serializer
|
||||
o->write_character('{');
|
||||
|
||||
// first n-1 elements
|
||||
auto i = val.m_value.object->cbegin();
|
||||
for (std::size_t cnt = 0; cnt < val.m_value.object->size() - 1; ++cnt, ++i)
|
||||
auto i = val.m_data.m_value.object->cbegin();
|
||||
for (std::size_t cnt = 0; cnt < val.m_data.m_value.object->size() - 1; ++cnt, ++i)
|
||||
{
|
||||
o->write_character('\"');
|
||||
dump_escaped(i->first, ensure_ascii);
|
||||
@ -172,8 +172,8 @@ class serializer
|
||||
}
|
||||
|
||||
// last element
|
||||
JSON_ASSERT(i != val.m_value.object->cend());
|
||||
JSON_ASSERT(std::next(i) == val.m_value.object->cend());
|
||||
JSON_ASSERT(i != val.m_data.m_value.object->cend());
|
||||
JSON_ASSERT(std::next(i) == val.m_data.m_value.object->cend());
|
||||
o->write_character('\"');
|
||||
dump_escaped(i->first, ensure_ascii);
|
||||
o->write_characters("\":", 2);
|
||||
@ -187,7 +187,7 @@ class serializer
|
||||
|
||||
case value_t::array:
|
||||
{
|
||||
if (val.m_value.array->empty())
|
||||
if (val.m_data.m_value.array->empty())
|
||||
{
|
||||
o->write_characters("[]", 2);
|
||||
return;
|
||||
@ -205,8 +205,8 @@ class serializer
|
||||
}
|
||||
|
||||
// first n-1 elements
|
||||
for (auto i = val.m_value.array->cbegin();
|
||||
i != val.m_value.array->cend() - 1; ++i)
|
||||
for (auto i = val.m_data.m_value.array->cbegin();
|
||||
i != val.m_data.m_value.array->cend() - 1; ++i)
|
||||
{
|
||||
o->write_characters(indent_string.c_str(), new_indent);
|
||||
dump(*i, true, ensure_ascii, indent_step, new_indent);
|
||||
@ -214,9 +214,9 @@ class serializer
|
||||
}
|
||||
|
||||
// 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);
|
||||
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_characters(indent_string.c_str(), current_indent);
|
||||
@ -227,16 +227,16 @@ class serializer
|
||||
o->write_character('[');
|
||||
|
||||
// first n-1 elements
|
||||
for (auto i = val.m_value.array->cbegin();
|
||||
i != val.m_value.array->cend() - 1; ++i)
|
||||
for (auto i = val.m_data.m_value.array->cbegin();
|
||||
i != val.m_data.m_value.array->cend() - 1; ++i)
|
||||
{
|
||||
dump(*i, false, ensure_ascii, indent_step, current_indent);
|
||||
o->write_character(',');
|
||||
}
|
||||
|
||||
// last element
|
||||
JSON_ASSERT(!val.m_value.array->empty());
|
||||
dump(val.m_value.array->back(), false, ensure_ascii, indent_step, current_indent);
|
||||
JSON_ASSERT(!val.m_data.m_value.array->empty());
|
||||
dump(val.m_data.m_value.array->back(), false, ensure_ascii, indent_step, current_indent);
|
||||
|
||||
o->write_character(']');
|
||||
}
|
||||
@ -247,7 +247,7 @@ class serializer
|
||||
case value_t::string:
|
||||
{
|
||||
o->write_character('\"');
|
||||
dump_escaped(*val.m_value.string, ensure_ascii);
|
||||
dump_escaped(*val.m_data.m_value.string, ensure_ascii);
|
||||
o->write_character('\"');
|
||||
return;
|
||||
}
|
||||
@ -269,24 +269,24 @@ class serializer
|
||||
|
||||
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();
|
||||
i != val.m_value.binary->cend() - 1; ++i)
|
||||
for (auto i = val.m_data.m_value.binary->cbegin();
|
||||
i != val.m_data.m_value.binary->cend() - 1; ++i)
|
||||
{
|
||||
dump_integer(*i);
|
||||
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(indent_string.c_str(), new_indent);
|
||||
|
||||
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
|
||||
{
|
||||
@ -300,21 +300,21 @@ class serializer
|
||||
{
|
||||
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();
|
||||
i != val.m_value.binary->cend() - 1; ++i)
|
||||
for (auto i = val.m_data.m_value.binary->cbegin();
|
||||
i != val.m_data.m_value.binary->cend() - 1; ++i)
|
||||
{
|
||||
dump_integer(*i);
|
||||
o->write_character(',');
|
||||
}
|
||||
dump_integer(val.m_value.binary->back());
|
||||
dump_integer(val.m_data.m_value.binary->back());
|
||||
}
|
||||
|
||||
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('}');
|
||||
}
|
||||
else
|
||||
@ -327,7 +327,7 @@ class serializer
|
||||
|
||||
case value_t::boolean:
|
||||
{
|
||||
if (val.m_value.boolean)
|
||||
if (val.m_data.m_value.boolean)
|
||||
{
|
||||
o->write_characters("true", 4);
|
||||
}
|
||||
@ -340,19 +340,19 @@ class serializer
|
||||
|
||||
case value_t::number_integer:
|
||||
{
|
||||
dump_integer(val.m_value.number_integer);
|
||||
dump_integer(val.m_data.m_value.number_integer);
|
||||
return;
|
||||
}
|
||||
|
||||
case value_t::number_unsigned:
|
||||
{
|
||||
dump_integer(val.m_value.number_unsigned);
|
||||
dump_integer(val.m_data.m_value.number_unsigned);
|
||||
return;
|
||||
}
|
||||
|
||||
case value_t::number_float:
|
||||
{
|
||||
dump_float(val.m_value.number_float);
|
||||
dump_float(val.m_data.m_value.number_float);
|
||||
return;
|
||||
}
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -216,28 +216,28 @@ TEST_CASE("const_iterator class")
|
||||
{
|
||||
json const j({{"foo", "bar"}});
|
||||
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++;
|
||||
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")
|
||||
{
|
||||
json const j({1, 2, 3, 4});
|
||||
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++;
|
||||
CHECK((it.m_it.array_iterator != it.m_object->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->begin()));
|
||||
CHECK((it.m_it.array_iterator != it.m_object->m_data.m_value.array->end()));
|
||||
it++;
|
||||
CHECK((it.m_it.array_iterator != it.m_object->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->begin()));
|
||||
CHECK((it.m_it.array_iterator != it.m_object->m_data.m_value.array->end()));
|
||||
it++;
|
||||
CHECK((it.m_it.array_iterator != it.m_object->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->begin()));
|
||||
CHECK((it.m_it.array_iterator != it.m_object->m_data.m_value.array->end()));
|
||||
it++;
|
||||
CHECK((it.m_it.array_iterator != it.m_object->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->begin()));
|
||||
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_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;
|
||||
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")
|
||||
{
|
||||
json const j({1, 2, 3, 4});
|
||||
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;
|
||||
CHECK((it.m_it.array_iterator != it.m_object->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->begin()));
|
||||
CHECK((it.m_it.array_iterator != it.m_object->m_data.m_value.array->end()));
|
||||
++it;
|
||||
CHECK((it.m_it.array_iterator != it.m_object->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->begin()));
|
||||
CHECK((it.m_it.array_iterator != it.m_object->m_data.m_value.array->end()));
|
||||
++it;
|
||||
CHECK((it.m_it.array_iterator != it.m_object->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->begin()));
|
||||
CHECK((it.m_it.array_iterator != it.m_object->m_data.m_value.array->end()));
|
||||
++it;
|
||||
CHECK((it.m_it.array_iterator != it.m_object->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->begin()));
|
||||
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_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--;
|
||||
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")
|
||||
{
|
||||
json const j({1, 2, 3, 4});
|
||||
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--;
|
||||
CHECK((it.m_it.array_iterator != it.m_object->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->begin()));
|
||||
CHECK((it.m_it.array_iterator != it.m_object->m_data.m_value.array->end()));
|
||||
it--;
|
||||
CHECK((it.m_it.array_iterator != it.m_object->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->begin()));
|
||||
CHECK((it.m_it.array_iterator != it.m_object->m_data.m_value.array->end()));
|
||||
it--;
|
||||
CHECK((it.m_it.array_iterator != it.m_object->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->begin()));
|
||||
CHECK((it.m_it.array_iterator != it.m_object->m_data.m_value.array->end()));
|
||||
it--;
|
||||
CHECK((it.m_it.array_iterator == it.m_object->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->begin()));
|
||||
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_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;
|
||||
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")
|
||||
{
|
||||
json const j({1, 2, 3, 4});
|
||||
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;
|
||||
CHECK((it.m_it.array_iterator != it.m_object->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->begin()));
|
||||
CHECK((it.m_it.array_iterator != it.m_object->m_data.m_value.array->end()));
|
||||
--it;
|
||||
CHECK((it.m_it.array_iterator != it.m_object->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->begin()));
|
||||
CHECK((it.m_it.array_iterator != it.m_object->m_data.m_value.array->end()));
|
||||
--it;
|
||||
CHECK((it.m_it.array_iterator != it.m_object->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->begin()));
|
||||
CHECK((it.m_it.array_iterator != it.m_object->m_data.m_value.array->end()));
|
||||
--it;
|
||||
CHECK((it.m_it.array_iterator == it.m_object->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->begin()));
|
||||
CHECK((it.m_it.array_iterator != it.m_object->m_data.m_value.array->end()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -206,28 +206,28 @@ TEST_CASE("iterator class")
|
||||
{
|
||||
json j({{"foo", "bar"}});
|
||||
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++;
|
||||
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")
|
||||
{
|
||||
json j({1, 2, 3, 4});
|
||||
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++;
|
||||
CHECK((it.m_it.array_iterator != it.m_object->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->begin()));
|
||||
CHECK((it.m_it.array_iterator != it.m_object->m_data.m_value.array->end()));
|
||||
it++;
|
||||
CHECK((it.m_it.array_iterator != it.m_object->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->begin()));
|
||||
CHECK((it.m_it.array_iterator != it.m_object->m_data.m_value.array->end()));
|
||||
it++;
|
||||
CHECK((it.m_it.array_iterator != it.m_object->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->begin()));
|
||||
CHECK((it.m_it.array_iterator != it.m_object->m_data.m_value.array->end()));
|
||||
it++;
|
||||
CHECK((it.m_it.array_iterator != it.m_object->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->begin()));
|
||||
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::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;
|
||||
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")
|
||||
{
|
||||
json j({1, 2, 3, 4});
|
||||
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;
|
||||
CHECK((it.m_it.array_iterator != it.m_object->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->begin()));
|
||||
CHECK((it.m_it.array_iterator != it.m_object->m_data.m_value.array->end()));
|
||||
++it;
|
||||
CHECK((it.m_it.array_iterator != it.m_object->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->begin()));
|
||||
CHECK((it.m_it.array_iterator != it.m_object->m_data.m_value.array->end()));
|
||||
++it;
|
||||
CHECK((it.m_it.array_iterator != it.m_object->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->begin()));
|
||||
CHECK((it.m_it.array_iterator != it.m_object->m_data.m_value.array->end()));
|
||||
++it;
|
||||
CHECK((it.m_it.array_iterator != it.m_object->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->begin()));
|
||||
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::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--;
|
||||
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")
|
||||
{
|
||||
json j({1, 2, 3, 4});
|
||||
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--;
|
||||
CHECK((it.m_it.array_iterator != it.m_object->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->begin()));
|
||||
CHECK((it.m_it.array_iterator != it.m_object->m_data.m_value.array->end()));
|
||||
it--;
|
||||
CHECK((it.m_it.array_iterator != it.m_object->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->begin()));
|
||||
CHECK((it.m_it.array_iterator != it.m_object->m_data.m_value.array->end()));
|
||||
it--;
|
||||
CHECK((it.m_it.array_iterator != it.m_object->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->begin()));
|
||||
CHECK((it.m_it.array_iterator != it.m_object->m_data.m_value.array->end()));
|
||||
it--;
|
||||
CHECK((it.m_it.array_iterator == it.m_object->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->begin()));
|
||||
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::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;
|
||||
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")
|
||||
{
|
||||
json j({1, 2, 3, 4});
|
||||
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;
|
||||
CHECK((it.m_it.array_iterator != it.m_object->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->begin()));
|
||||
CHECK((it.m_it.array_iterator != it.m_object->m_data.m_value.array->end()));
|
||||
--it;
|
||||
CHECK((it.m_it.array_iterator != it.m_object->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->begin()));
|
||||
CHECK((it.m_it.array_iterator != it.m_object->m_data.m_value.array->end()));
|
||||
--it;
|
||||
CHECK((it.m_it.array_iterator != it.m_object->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->begin()));
|
||||
CHECK((it.m_it.array_iterator != it.m_object->m_data.m_value.array->end()));
|
||||
--it;
|
||||
CHECK((it.m_it.array_iterator == it.m_object->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->begin()));
|
||||
CHECK((it.m_it.array_iterator != it.m_object->m_data.m_value.array->end()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -872,7 +872,7 @@ TEST_CASE("constructors")
|
||||
float const n = 42.23f;
|
||||
json const j(n);
|
||||
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")
|
||||
@ -880,7 +880,7 @@ TEST_CASE("constructors")
|
||||
double const n = 42.23;
|
||||
json const j(n);
|
||||
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")
|
||||
@ -888,28 +888,28 @@ TEST_CASE("constructors")
|
||||
long double const n = 42.23L;
|
||||
json const j(n);
|
||||
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")
|
||||
{
|
||||
json const j(42.23);
|
||||
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")
|
||||
{
|
||||
json const j(42.23f);
|
||||
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")
|
||||
{
|
||||
json const j(42.23L);
|
||||
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));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1076,19 +1076,19 @@ TEST_CASE("value conversion")
|
||||
SECTION("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")
|
||||
{
|
||||
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")
|
||||
{
|
||||
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")
|
||||
@ -1126,19 +1126,19 @@ TEST_CASE("value conversion")
|
||||
SECTION("number_float_t")
|
||||
{
|
||||
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")
|
||||
{
|
||||
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")
|
||||
{
|
||||
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
|
||||
@ -1151,7 +1151,7 @@ TEST_CASE("value conversion")
|
||||
SECTION("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()")
|
||||
@ -1159,14 +1159,14 @@ TEST_CASE("value conversion")
|
||||
SECTION("non-const")
|
||||
{
|
||||
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")
|
||||
{
|
||||
const json j_const = j;
|
||||
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")
|
||||
{
|
||||
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
|
||||
|
86
tests/src/unit-no-mem-leak-on-adl-serialize.cpp
Normal file
86
tests/src/unit-no-mem-leak-on-adl-serialize.cpp
Normal 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
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user