30 #ifndef INCLUDE_NLOHMANN_JSON_HPP_
31 #define INCLUDE_NLOHMANN_JSON_HPP_
33 #define NLOHMANN_JSON_VERSION_MAJOR 3
34 #define NLOHMANN_JSON_VERSION_MINOR 7
35 #define NLOHMANN_JSON_VERSION_PATCH 3
42 #include <initializer_list>
51 #include <nlohmann/adl_serializer.hpp>
52 #include <nlohmann/detail/conversions/from_json.hpp>
53 #include <nlohmann/detail/conversions/to_json.hpp>
54 #include <nlohmann/detail/exceptions.hpp>
55 #include <nlohmann/detail/input/binary_reader.hpp>
56 #include <nlohmann/detail/input/input_adapters.hpp>
57 #include <nlohmann/detail/input/lexer.hpp>
58 #include <nlohmann/detail/input/parser.hpp>
59 #include <nlohmann/detail/iterators/internal_iterator.hpp>
60 #include <nlohmann/detail/iterators/iter_impl.hpp>
61 #include <nlohmann/detail/iterators/iteration_proxy.hpp>
62 #include <nlohmann/detail/iterators/json_reverse_iterator.hpp>
63 #include <nlohmann/detail/iterators/primitive_iterator.hpp>
64 #include <nlohmann/detail/json_pointer.hpp>
65 #include <nlohmann/detail/json_ref.hpp>
66 #include <nlohmann/detail/macro_scope.hpp>
67 #include <nlohmann/detail/meta/cpp_future.hpp>
68 #include <nlohmann/detail/meta/type_traits.hpp>
69 #include <nlohmann/detail/output/binary_writer.hpp>
70 #include <nlohmann/detail/output/output_adapters.hpp>
71 #include <nlohmann/detail/output/serializer.hpp>
72 #include <nlohmann/detail/value_t.hpp>
73 #include <nlohmann/json_fwd.hpp>
164 NLOHMANN_BASIC_JSON_TPL_DECLARATION
168 template<detail::value_t>
friend struct detail::external_constructor;
169 friend ::nlohmann::json_pointer<basic_json>;
170 friend ::nlohmann::detail::parser<basic_json>;
171 friend ::nlohmann::detail::serializer<basic_json>;
172 template<
typename BasicJsonType>
173 friend class ::nlohmann::detail::iter_impl;
174 template<
typename BasicJsonType,
typename CharType>
175 friend class ::nlohmann::detail::binary_writer;
176 template<
typename BasicJsonType,
typename SAX>
177 friend class ::nlohmann::detail::binary_reader;
178 template<
typename BasicJsonType>
179 friend class ::nlohmann::detail::json_sax_dom_parser;
180 template<
typename BasicJsonType>
181 friend class ::nlohmann::detail::json_sax_dom_callback_parser;
184 using basic_json_t = NLOHMANN_BASIC_JSON_TPL;
191 template<
typename BasicJsonType>
193 template<
typename BasicJsonType>
195 template<
typename Iterator>
199 template<
typename CharType>
211 template<
typename T,
typename SFINAE>
212 using json_serializer = JSONSerializer<T, SFINAE>;
272 using pointer =
typename std::allocator_traits<allocator_type>::pointer;
274 using const_pointer =
typename std::allocator_traits<allocator_type>::const_pointer;
322 JSON_HEDLEY_WARN_UNUSED_RESULT
327 result[
"copyright"] =
"(C) 2013-2017 Niels Lohmann";
328 result[
"name"] =
"JSON for Modern C++";
329 result[
"url"] =
"https://github.com/nlohmann/json";
330 result[
"version"][
"string"] =
331 std::to_string(NLOHMANN_JSON_VERSION_MAJOR) +
"." +
332 std::to_string(NLOHMANN_JSON_VERSION_MINOR) +
"." +
333 std::to_string(NLOHMANN_JSON_VERSION_PATCH);
334 result[
"version"][
"major"] = NLOHMANN_JSON_VERSION_MAJOR;
335 result[
"version"][
"minor"] = NLOHMANN_JSON_VERSION_MINOR;
336 result[
"version"][
"patch"] = NLOHMANN_JSON_VERSION_PATCH;
339 result[
"platform"] =
"win32";
340 #elif defined __linux__
341 result[
"platform"] =
"linux";
342 #elif defined __APPLE__
343 result[
"platform"] =
"apple";
344 #elif defined __unix__
345 result[
"platform"] =
"unix";
347 result[
"platform"] =
"unknown";
350 #if defined(__ICC) || defined(__INTEL_COMPILER)
351 result[
"compiler"] = {{
"family",
"icc"}, {
"version", __INTEL_COMPILER}};
352 #elif defined(__clang__)
353 result[
"compiler"] = {{
"family",
"clang"}, {
"version", __clang_version__}};
354 #elif defined(__GNUC__) || defined(__GNUG__)
355 result[
"compiler"] = {{
"family",
"gcc"}, {
"version", std::to_string(__GNUC__) +
"." + std::to_string(__GNUC_MINOR__) +
"." + std::to_string(__GNUC_PATCHLEVEL__)}};
356 #elif defined(__HP_cc) || defined(__HP_aCC)
357 result[
"compiler"] =
"hp"
358 #elif defined(__IBMCPP__)
359 result[
"compiler"] = {{
"family",
"ilecpp"}, {
"version", __IBMCPP__}};
360 #elif defined(_MSC_VER)
361 result[
"compiler"] = {{
"family",
"msvc"}, {
"version", _MSC_VER}};
363 result[
"compiler"] = {{
"family",
"pgcpp"}, {
"version", __PGI}};
364 #elif defined(__SUNPRO_CC)
365 result[
"compiler"] = {{
"family",
"sunpro"}, {
"version", __SUNPRO_CC}};
367 result[
"compiler"] = {{
"family",
"unknown"}, {
"version",
"unknown"}};
371 result[
"compiler"][
"c++"] = std::to_string(__cplusplus);
373 result[
"compiler"][
"c++"] =
"unknown";
388 #if defined(JSON_HAS_CPP_14)
391 using object_comparator_t = std::less<>;
393 using object_comparator_t = std::less<StringType>;
482 AllocatorType<std::pair<
const StringType,
529 using array_t = ArrayType<basic_json, AllocatorType<basic_json>>;
826 template<
typename T,
typename... Args>
827 JSON_HEDLEY_RETURNS_NON_NULL
828 static T* create(Args&& ... args)
830 AllocatorType<T> alloc;
831 using AllocatorTraits = std::allocator_traits<AllocatorType<T>>;
833 auto deleter = [&](T *
object)
835 AllocatorTraits::deallocate(alloc,
object, 1);
837 std::unique_ptr<T, decltype(deleter)>
object(AllocatorTraits::allocate(alloc, 1), deleter);
838 AllocatorTraits::construct(alloc,
object.
get(), std::forward<Args>(args)...);
839 assert(
object !=
nullptr);
840 return object.release();
889 json_value() =
default;
891 json_value(
boolean_t v) noexcept : boolean(v) {}
899 json_value(value_t t)
905 object = create<object_t>();
911 array = create<array_t>();
917 string = create<string_t>(
"");
956 JSON_THROW(other_error::create(500,
"961c151d2e87f2686a955a9be24d316f1362bf21 3.7.3"));
966 string = create<string_t>(
value);
972 string = create<string_t>(std::move(
value));
978 object = create<object_t>(
value);
984 object = create<object_t>(std::move(
value));
999 void destroy(value_t t) noexcept
1002 std::vector<basic_json> stack;
1013 for (
auto&& it : *
object)
1015 stack.push_back(std::move(it.second));
1019 while (not stack.empty())
1022 basic_json current_item(std::move(stack.back()));
1027 if (current_item.is_array())
1029 std::move(current_item.m_value.array->begin(), current_item.m_value.array->end(),
1030 std::back_inserter(stack));
1032 current_item.m_value.array->clear();
1034 else if (current_item.is_object())
1036 for (
auto&& it : *current_item.m_value.object)
1038 stack.push_back(std::move(it.second));
1041 current_item.m_value.object->clear();
1052 AllocatorType<object_t> alloc;
1053 std::allocator_traits<decltype(alloc)>::destroy(alloc,
object);
1054 std::allocator_traits<decltype(alloc)>::deallocate(alloc,
object, 1);
1060 AllocatorType<array_t> alloc;
1061 std::allocator_traits<decltype(alloc)>::destroy(alloc,
array);
1062 std::allocator_traits<decltype(alloc)>::deallocate(alloc,
array, 1);
1068 AllocatorType<string_t> alloc;
1069 std::allocator_traits<decltype(alloc)>::destroy(alloc,
string);
1070 std::allocator_traits<decltype(alloc)>::deallocate(alloc,
string, 1);
1091 void assert_invariant() const noexcept
1210 : m_type(v), m_value(v)
1296 template <
typename CompatibleType,
1297 typename U = detail::uncvref_t<CompatibleType>,
1298 detail::enable_if_t<
1301 JSONSerializer<U>::to_json(std::declval<basic_json_t&>(),
1302 std::forward<CompatibleType>(val))))
1304 JSONSerializer<U>::to_json(*
this, std::forward<CompatibleType>(val));
1334 template <
typename BasicJsonType,
1335 detail::enable_if_t<
1339 using other_boolean_t =
typename BasicJsonType::boolean_t;
1340 using other_number_float_t =
typename BasicJsonType::number_float_t;
1341 using other_number_integer_t =
typename BasicJsonType::number_integer_t;
1342 using other_number_unsigned_t =
typename BasicJsonType::number_unsigned_t;
1343 using other_string_t =
typename BasicJsonType::string_t;
1344 using other_object_t =
typename BasicJsonType::object_t;
1345 using other_array_t =
typename BasicJsonType::array_t;
1350 JSONSerializer<other_boolean_t>::to_json(*
this, val.template get<other_boolean_t>());
1353 JSONSerializer<other_number_float_t>::to_json(*
this, val.template get<other_number_float_t>());
1356 JSONSerializer<other_number_integer_t>::to_json(*
this, val.template get<other_number_integer_t>());
1359 JSONSerializer<other_number_unsigned_t>::to_json(*
this, val.template get<other_number_unsigned_t>());
1362 JSONSerializer<other_string_t>::to_json(*
this, val.template get_ref<const other_string_t&>());
1365 JSONSerializer<other_object_t>::to_json(*
this, val.template get_ref<const other_object_t&>());
1368 JSONSerializer<other_array_t>::to_json(*
this, val.template get_ref<const other_array_t&>());
1457 bool type_deduction =
true,
1462 bool is_an_object = std::all_of(init.begin(), init.end(),
1465 return element_ref->is_array() and element_ref->size() == 2 and (*element_ref)[0].is_string();
1469 if (not type_deduction)
1474 is_an_object =
false;
1478 if (JSON_HEDLEY_UNLIKELY(manual_type ==
value_t::object and not is_an_object))
1480 JSON_THROW(type_error::create(301,
"cannot create object from initializer list"));
1492 auto element = element_ref.moved_or_copied();
1493 m_value.object->emplace(
1494 std::move(*((*element.m_value.array)[0].m_value.string)),
1495 std::move((*element.m_value.array)[1]));
1502 m_value.array = create<array_t>(init.begin(), init.end());
1545 JSON_HEDLEY_WARN_UNUSED_RESULT
1589 JSON_HEDLEY_WARN_UNUSED_RESULT
1620 m_value.array = create<array_t>(cnt, val);
1679 template<
class InputIT,
typename std::enable_if<
1680 std::is_same<InputIT, typename basic_json_t::iterator>::value or
1681 std::is_same<InputIT, typename basic_json_t::const_iterator>::value,
int>
::type = 0>
1684 assert(first.m_object !=
nullptr);
1685 assert(last.m_object !=
nullptr);
1688 if (JSON_HEDLEY_UNLIKELY(first.m_object != last.m_object))
1690 JSON_THROW(invalid_iterator::create(201,
"iterators are not compatible"));
1694 m_type = first.m_object->m_type;
1705 if (JSON_HEDLEY_UNLIKELY(not first.m_it.primitive_iterator.is_begin()
1706 or not last.m_it.primitive_iterator.is_end()))
1708 JSON_THROW(invalid_iterator::create(204,
"iterators out of range"));
1721 m_value.number_integer = first.m_object->m_value.number_integer;
1727 m_value.number_unsigned = first.m_object->m_value.number_unsigned;
1733 m_value.number_float = first.m_object->m_value.number_float;
1739 m_value.boolean = first.m_object->m_value.boolean;
1745 m_value = *first.m_object->m_value.string;
1751 m_value.object = create<object_t>(first.m_it.object_iterator,
1752 last.m_it.object_iterator);
1758 m_value.array = create<array_t>(first.m_it.array_iterator,
1759 last.m_it.array_iterator);
1764 JSON_THROW(invalid_iterator::create(206,
"cannot construct with iterators from " +
1765 std::string(first.m_object->type_name())));
1807 : m_type(other.m_type)
1810 other.assert_invariant();
1816 m_value = *other.m_value.object;
1822 m_value = *other.m_value.array;
1828 m_value = *other.m_value.string;
1834 m_value = other.m_value.boolean;
1840 m_value = other.m_value.number_integer;
1846 m_value = other.m_value.number_unsigned;
1852 m_value = other.m_value.number_float;
1890 : m_type(std::move(other.m_type)),
1891 m_value(std::move(other.m_value))
1894 other.assert_invariant();
1927 std::is_nothrow_move_constructible<value_t>::value and
1928 std::is_nothrow_move_assignable<value_t>::value and
1929 std::is_nothrow_move_constructible<json_value>::value and
1930 std::is_nothrow_move_assignable<json_value>::value
1934 other.assert_invariant();
1937 swap(m_type, other.m_type);
1938 swap(m_value, other.m_value);
1962 m_value.destroy(m_type);
2018 const char indent_char =
' ',
2019 const bool ensure_ascii =
false,
2027 s.
dump(*
this,
true, ensure_ascii,
static_cast<unsigned int>(indent));
2031 s.
dump(*
this,
false, ensure_ascii, 0);
2421 return m_value.boolean;
2424 JSON_THROW(type_error::create(302,
"type must be boolean, but is " + std::string(
type_name())));
2430 return is_object() ? m_value.object :
nullptr;
2436 return is_object() ? m_value.object :
nullptr;
2442 return is_array() ? m_value.array :
nullptr;
2446 constexpr
const array_t* get_impl_ptr(
const array_t* )
const noexcept
2448 return is_array() ? m_value.array :
nullptr;
2454 return is_string() ? m_value.string :
nullptr;
2460 return is_string() ? m_value.string :
nullptr;
2466 return is_boolean() ? &m_value.boolean :
nullptr;
2472 return is_boolean() ? &m_value.boolean :
nullptr;
2522 template<
typename ReferenceType,
typename ThisType>
2523 static ReferenceType get_ref_impl(ThisType& obj)
2526 auto ptr = obj.template get_ptr<typename std::add_pointer<ReferenceType>::type>();
2528 if (JSON_HEDLEY_LIKELY(ptr !=
nullptr))
2533 JSON_THROW(type_error::create(303,
"incompatible ReferenceType for get_ref, actual type is " + std::string(obj.type_name())));
2555 template<
typename BasicJsonType, detail::enable_if_t<
2556 std::is_same<typename std::remove_const<BasicJsonType>::type, basic_json_t>
::value,
2578 template<
typename BasicJsonType, detail::enable_if_t<
2579 not std::is_same<BasicJsonType, basic_json>::value and
2625 template<
typename ValueTypeCV,
typename ValueType = detail::uncvref_t<ValueTypeCV>,
2626 detail::enable_if_t <
2627 not detail::is_basic_json<ValueType>::value and
2628 detail::has_from_json<basic_json_t, ValueType>::value and
2629 not detail::has_non_default_from_json<basic_json_t, ValueType>::value,
2631 ValueType
get() const noexcept(noexcept(
2632 JSONSerializer<ValueType>::from_json(std::declval<const basic_json_t&>(), std::declval<ValueType&>())))
2637 static_assert(not std::is_reference<ValueTypeCV>::value,
2638 "get() cannot be used with reference types, you might want to use get_ref()");
2639 static_assert(std::is_default_constructible<ValueType>::value,
2640 "types must be DefaultConstructible when used with get()");
2643 JSONSerializer<ValueType>::from_json(*
this, ret);
2678 template<
typename ValueTypeCV,
typename ValueType = detail::uncvref_t<ValueTypeCV>,
2679 detail::enable_if_t<not std::is_same<basic_json_t, ValueType>::value and
2680 detail::has_non_default_from_json<basic_json_t, ValueType>::value,
2682 ValueType
get() const noexcept(noexcept(
2683 JSONSerializer<ValueType>::from_json(std::declval<const basic_json_t&>())))
2685 static_assert(not std::is_reference<ValueTypeCV>::value,
2686 "get() cannot be used with reference types, you might want to use get_ref()");
2687 return JSONSerializer<ValueType>::from_json(*
this);
2723 template<
typename ValueType,
2724 detail::enable_if_t <
2728 ValueType &
get_to(ValueType& v)
const noexcept(noexcept(
2729 JSONSerializer<ValueType>::from_json(std::declval<const basic_json_t&>(), v)))
2731 JSONSerializer<ValueType>::from_json(*
this, v);
2736 typename T, std::size_t N,
2737 typename Array = T (&)[N],
2738 detail::enable_if_t <
2740 Array
get_to(T (&v)[N])
const
2741 noexcept(noexcept(JSONSerializer<Array>::from_json(
2742 std::declval<const basic_json_t&>(), v)))
2744 JSONSerializer<Array>::from_json(*
this, v);
2775 template<
typename PointerType,
typename std::enable_if<
2776 std::is_pointer<PointerType>::value,
int>
::type = 0>
2777 auto get_ptr() noexcept -> decltype(std::declval<basic_json_t&>().get_impl_ptr(std::declval<PointerType>()))
2780 return get_impl_ptr(
static_cast<PointerType
>(
nullptr));
2787 template<
typename PointerType,
typename std::enable_if<
2788 std::is_pointer<PointerType>::value and
2789 std::is_const<typename std::remove_pointer<PointerType>::type>
::value,
int>
::type = 0>
2790 constexpr
auto get_ptr() const noexcept -> decltype(std::declval<const basic_json_t&>().get_impl_ptr(std::declval<PointerType>()))
2793 return get_impl_ptr(
static_cast<PointerType
>(
nullptr));
2823 template<
typename PointerType,
typename std::enable_if<
2824 std::is_pointer<PointerType>::value,
int>
::type = 0>
2825 auto get() noexcept -> decltype(std::declval<basic_json_t&>().template
get_ptr<PointerType>())
2828 return get_ptr<PointerType>();
2835 template<
typename PointerType,
typename std::enable_if<
2836 std::is_pointer<PointerType>::value,
int>
::type = 0>
2837 constexpr
auto get() const noexcept -> decltype(std::declval<const basic_json_t&>().template
get_ptr<PointerType>())
2840 return get_ptr<PointerType>();
2869 template<
typename ReferenceType,
typename std::enable_if<
2870 std::is_reference<ReferenceType>::value,
int>
::type = 0>
2874 return get_ref_impl<ReferenceType>(*
this);
2881 template<
typename ReferenceType,
typename std::enable_if<
2882 std::is_reference<ReferenceType>::value and
2883 std::is_const<typename std::remove_reference<ReferenceType>::type>
::value,
int>
::type = 0>
2887 return get_ref_impl<ReferenceType>(*
this);
2919 template <
typename ValueType,
typename std::enable_if <
2920 not std::is_pointer<ValueType>::value and
2921 not std::is_same<ValueType, detail::json_ref<basic_json>>
::value and
2922 not std::is_same<ValueType, typename string_t::value_type>::value and
2925 #ifndef _MSC_VER // fix for issue #167 operator<< ambiguity under VS2015
2926 and not std::is_same<ValueType, std::initializer_list<typename string_t::value_type>>
::value
2927 #if defined(JSON_HAS_CPP_17) && (defined(__GNUC__) || (defined(_MSC_VER) and _MSC_VER <= 1914))
2928 and not std::is_same<ValueType, typename std::string_view>::value
2931 and detail::is_detected<detail::get_template_function, const basic_json_t&, ValueType>::value
2933 operator ValueType()
const
2936 return get<ValueType>();
2979 if (JSON_HEDLEY_LIKELY(
is_array()))
2983 return m_value.array->at(idx);
2985 JSON_CATCH (std::out_of_range&)
2988 JSON_THROW(out_of_range::create(401,
"array index " + std::to_string(idx) +
" is out of range"));
2993 JSON_THROW(type_error::create(304,
"cannot use at() with " + std::string(
type_name())));
3026 if (JSON_HEDLEY_LIKELY(
is_array()))
3030 return m_value.array->at(idx);
3032 JSON_CATCH (std::out_of_range&)
3035 JSON_THROW(out_of_range::create(401,
"array index " + std::to_string(idx) +
" is out of range"));
3040 JSON_THROW(type_error::create(304,
"cannot use at() with " + std::string(
type_name())));
3081 return m_value.object->at(key);
3083 JSON_CATCH (std::out_of_range&)
3086 JSON_THROW(out_of_range::create(403,
"key '" + key +
"' not found"));
3091 JSON_THROW(type_error::create(304,
"cannot use at() with " + std::string(
type_name())));
3132 return m_value.object->at(key);
3134 JSON_CATCH (std::out_of_range&)
3137 JSON_THROW(out_of_range::create(403,
"key '" + key +
"' not found"));
3142 JSON_THROW(type_error::create(304,
"cannot use at() with " + std::string(
type_name())));
3177 m_value.array = create<array_t>();
3182 if (JSON_HEDLEY_LIKELY(
is_array()))
3185 if (idx >= m_value.array->size())
3187 m_value.array->insert(m_value.array->end(),
3188 idx - m_value.array->size() + 1,
3192 return m_value.array->operator[](idx);
3195 JSON_THROW(type_error::create(305,
"cannot use operator[] with a numeric argument with " + std::string(
type_name())));
3220 if (JSON_HEDLEY_LIKELY(
is_array()))
3222 return m_value.array->operator[](idx);
3225 JSON_THROW(type_error::create(305,
"cannot use operator[] with a numeric argument with " + std::string(
type_name())));
3261 m_value.object = create<object_t>();
3268 return m_value.object->operator[](key);
3271 JSON_THROW(type_error::create(305,
"cannot use operator[] with a string argument with " + std::string(
type_name())));
3309 assert(m_value.object->find(key) != m_value.object->end());
3310 return m_value.object->find(key)->second;
3313 JSON_THROW(type_error::create(305,
"cannot use operator[] with a string argument with " + std::string(
type_name())));
3343 template<
typename T>
3344 JSON_HEDLEY_NON_NULL(2)
3358 return m_value.object->operator[](key);
3361 JSON_THROW(type_error::create(305,
"cannot use operator[] with a string argument with " + std::string(
type_name())));
3394 template<
typename T>
3395 JSON_HEDLEY_NON_NULL(2)
3401 assert(m_value.object->find(key) != m_value.object->end());
3402 return m_value.object->find(key)->second;
3405 JSON_THROW(type_error::create(305,
"cannot use operator[] with a string argument with " + std::string(
type_name())));
3458 template<
class ValueType,
typename std::enable_if<
3459 std::is_convertible<basic_json_t, ValueType>::value,
int>
::type = 0>
3460 ValueType
value(
const typename object_t::key_type& key,
const ValueType& default_value)
const
3466 const auto it =
find(key);
3472 return default_value;
3475 JSON_THROW(type_error::create(306,
"cannot use value() with " + std::string(
type_name())));
3482 string_t value(
const typename object_t::key_type& key,
const char* default_value)
const
3530 template<
class ValueType,
typename std::enable_if<
3531 std::is_convertible<basic_json_t, ValueType>::value,
int>
::type = 0>
3540 return ptr.get_checked(
this);
3544 return default_value;
3548 JSON_THROW(type_error::create(306,
"cannot use value() with " + std::string(
type_name())));
3555 JSON_HEDLEY_NON_NULL(3)
3693 template<
class IteratorType,
typename std::enable_if<
3694 std::is_same<IteratorType, typename basic_json_t::iterator>::value or
3695 std::is_same<IteratorType, typename basic_json_t::const_iterator>::value,
int>
::type
3700 if (JSON_HEDLEY_UNLIKELY(
this != pos.m_object))
3702 JSON_THROW(invalid_iterator::create(202,
"iterator does not fit current value"));
3705 IteratorType result =
end();
3715 if (JSON_HEDLEY_UNLIKELY(not pos.m_it.primitive_iterator.is_begin()))
3717 JSON_THROW(invalid_iterator::create(205,
"iterator out of range"));
3722 AllocatorType<string_t> alloc;
3723 std::allocator_traits<decltype(alloc)>::destroy(alloc, m_value.string);
3724 std::allocator_traits<decltype(alloc)>::deallocate(alloc, m_value.string, 1);
3725 m_value.string =
nullptr;
3735 result.m_it.object_iterator = m_value.object->erase(pos.m_it.object_iterator);
3741 result.m_it.array_iterator = m_value.array->erase(pos.m_it.array_iterator);
3746 JSON_THROW(type_error::create(307,
"cannot use erase() with " + std::string(
type_name())));
3798 template<
class IteratorType,
typename std::enable_if<
3799 std::is_same<IteratorType, typename basic_json_t::iterator>::value or
3800 std::is_same<IteratorType, typename basic_json_t::const_iterator>::value,
int>
::type
3802 IteratorType
erase(IteratorType first, IteratorType last)
3805 if (JSON_HEDLEY_UNLIKELY(
this != first.m_object or
this != last.m_object))
3807 JSON_THROW(invalid_iterator::create(203,
"iterators do not fit current value"));
3810 IteratorType result =
end();
3820 if (JSON_HEDLEY_LIKELY(not first.m_it.primitive_iterator.is_begin()
3821 or not last.m_it.primitive_iterator.is_end()))
3823 JSON_THROW(invalid_iterator::create(204,
"iterators out of range"));
3828 AllocatorType<string_t> alloc;
3829 std::allocator_traits<decltype(alloc)>::destroy(alloc, m_value.string);
3830 std::allocator_traits<decltype(alloc)>::deallocate(alloc, m_value.string, 1);
3831 m_value.string =
nullptr;
3841 result.m_it.object_iterator = m_value.object->erase(first.m_it.object_iterator,
3842 last.m_it.object_iterator);
3848 result.m_it.array_iterator = m_value.array->erase(first.m_it.array_iterator,
3849 last.m_it.array_iterator);
3854 JSON_THROW(type_error::create(307,
"cannot use erase() with " + std::string(
type_name())));
3894 return m_value.object->erase(key);
3897 JSON_THROW(type_error::create(307,
"cannot use erase() with " + std::string(
type_name())));
3927 if (JSON_HEDLEY_LIKELY(
is_array()))
3929 if (JSON_HEDLEY_UNLIKELY(idx >=
size()))
3931 JSON_THROW(out_of_range::create(401,
"array index " + std::to_string(idx) +
" is out of range"));
3934 m_value.array->erase(m_value.array->begin() +
static_cast<difference_type>(idx));
3938 JSON_THROW(type_error::create(307,
"cannot use erase() with " + std::string(
type_name())));
3976 template<
typename KeyT>
3979 auto result =
end();
3983 result.m_it.object_iterator = m_value.object->find(std::forward<KeyT>(key));
3993 template<
typename KeyT>
3996 auto result =
cend();
4000 result.m_it.object_iterator = m_value.object->find(std::forward<KeyT>(key));
4027 template<
typename KeyT>
4031 return is_object() ? m_value.object->count(std::forward<KeyT>(key)) : 0;
4059 template<
typename KeyT,
typename std::enable_if<
4063 return is_object() and m_value.object->find(std::forward<KeyT>(key)) != m_value.object->end();
4094 return ptr.contains(
this);
4438 JSON_HEDLEY_DEPRECATED(3.1.0)
4447 JSON_HEDLEY_DEPRECATED(3.1.0)
4593 return m_value.array->empty();
4599 return m_value.object->empty();
4665 return m_value.array->size();
4671 return m_value.object->size();
4729 return m_value.array->max_size();
4735 return m_value.object->max_size();
4798 m_value.number_integer = 0;
4804 m_value.number_unsigned = 0;
4810 m_value.number_float = 0.0;
4816 m_value.boolean =
false;
4822 m_value.string->clear();
4828 m_value.array->clear();
4834 m_value.object->clear();
4868 JSON_THROW(type_error::create(308,
"cannot use push_back() with " + std::string(
type_name())));
4880 m_value.array->push_back(std::move(val));
4905 JSON_THROW(type_error::create(308,
"cannot use push_back() with " + std::string(
type_name())));
4917 m_value.array->push_back(val);
4955 JSON_THROW(type_error::create(308,
"cannot use push_back() with " + std::string(
type_name())));
4967 m_value.object->insert(val);
5007 if (
is_object() and init.size() == 2 and (*init.begin())->is_string())
5010 push_back(
typename object_t::value_type(
5011 std::move(key.get_ref<
string_t&>()), (init.begin() + 1)->moved_or_copied()));
5052 template<
class... Args>
5058 JSON_THROW(type_error::create(311,
"cannot use emplace_back() with " + std::string(
type_name())));
5070 #ifdef JSON_HAS_CPP_17
5071 return m_value.array->emplace_back(std::forward<Args>(args)...);
5073 m_value.array->emplace_back(std::forward<Args>(args)...);
5074 return m_value.array->back();
5105 template<
class... Args>
5106 std::pair<iterator, bool>
emplace(Args&& ... args)
5111 JSON_THROW(type_error::create(311,
"cannot use emplace() with " + std::string(
type_name())));
5123 auto res = m_value.object->emplace(std::forward<Args>(args)...);
5126 it.m_it.object_iterator = res.first;
5129 return {it, res.second};
5135 template<
typename... Args>
5139 assert(m_value.array !=
nullptr);
5141 auto insert_pos = std::distance(m_value.array->begin(), pos.m_it.
array_iterator);
5142 m_value.array->insert(pos.m_it.
array_iterator, std::forward<Args>(args)...);
5143 result.m_it.
array_iterator = m_value.array->begin() + insert_pos;
5177 if (JSON_HEDLEY_LIKELY(
is_array()))
5180 if (JSON_HEDLEY_UNLIKELY(pos.m_object !=
this))
5182 JSON_THROW(invalid_iterator::create(202,
"iterator does not fit current value"));
5189 JSON_THROW(type_error::create(309,
"cannot use insert() with " + std::string(
type_name())));
5228 if (JSON_HEDLEY_LIKELY(
is_array()))
5231 if (JSON_HEDLEY_UNLIKELY(pos.m_object !=
this))
5233 JSON_THROW(invalid_iterator::create(202,
"iterator does not fit current value"));
5240 JSON_THROW(type_error::create(309,
"cannot use insert() with " + std::string(
type_name())));
5276 if (JSON_HEDLEY_UNLIKELY(not
is_array()))
5278 JSON_THROW(type_error::create(309,
"cannot use insert() with " + std::string(
type_name())));
5282 if (JSON_HEDLEY_UNLIKELY(pos.m_object !=
this))
5284 JSON_THROW(invalid_iterator::create(202,
"iterator does not fit current value"));
5288 if (JSON_HEDLEY_UNLIKELY(first.m_object != last.m_object))
5290 JSON_THROW(invalid_iterator::create(210,
"iterators do not fit"));
5293 if (JSON_HEDLEY_UNLIKELY(first.m_object ==
this))
5295 JSON_THROW(invalid_iterator::create(211,
"passed iterators may not belong to container"));
5329 if (JSON_HEDLEY_UNLIKELY(not
is_array()))
5331 JSON_THROW(type_error::create(309,
"cannot use insert() with " + std::string(
type_name())));
5335 if (JSON_HEDLEY_UNLIKELY(pos.m_object !=
this))
5337 JSON_THROW(invalid_iterator::create(202,
"iterator does not fit current value"));
5370 if (JSON_HEDLEY_UNLIKELY(not
is_object()))
5372 JSON_THROW(type_error::create(309,
"cannot use insert() with " + std::string(
type_name())));
5376 if (JSON_HEDLEY_UNLIKELY(first.m_object != last.m_object))
5378 JSON_THROW(invalid_iterator::create(210,
"iterators do not fit"));
5382 if (JSON_HEDLEY_UNLIKELY(not first.m_object->is_object()))
5384 JSON_THROW(invalid_iterator::create(202,
"iterators first and last must point to objects"));
5415 m_value.object = create<object_t>();
5419 if (JSON_HEDLEY_UNLIKELY(not
is_object()))
5421 JSON_THROW(type_error::create(312,
"cannot use update() with " + std::string(
type_name())));
5423 if (JSON_HEDLEY_UNLIKELY(not j.is_object()))
5425 JSON_THROW(type_error::create(312,
"cannot use update() with " + std::string(j.type_name())));
5428 for (
auto it = j.cbegin(); it != j.cend(); ++it)
5430 m_value.object->operator[](it.key()) = it.value();
5466 m_value.object = create<object_t>();
5470 if (JSON_HEDLEY_UNLIKELY(not
is_object()))
5472 JSON_THROW(type_error::create(312,
"cannot use update() with " + std::string(
type_name())));
5476 if (JSON_HEDLEY_UNLIKELY(first.m_object != last.m_object))
5478 JSON_THROW(invalid_iterator::create(210,
"iterators do not fit"));
5482 if (JSON_HEDLEY_UNLIKELY(not first.m_object->is_object()
5483 or not last.m_object->is_object()))
5485 JSON_THROW(invalid_iterator::create(202,
"iterators first and last must point to objects"));
5488 for (
auto it = first; it != last; ++it)
5490 m_value.object->operator[](it.key()) = it.value();
5512 std::is_nothrow_move_constructible<value_t>::value and
5513 std::is_nothrow_move_assignable<value_t>::value and
5514 std::is_nothrow_move_constructible<json_value>::value and
5515 std::is_nothrow_move_assignable<json_value>::value
5518 std::swap(m_type, other.m_type);
5519 std::swap(m_value, other.m_value);
5546 if (JSON_HEDLEY_LIKELY(
is_array()))
5548 std::swap(*(m_value.array), other);
5552 JSON_THROW(type_error::create(310,
"cannot use swap() with " + std::string(
type_name())));
5581 std::swap(*(m_value.object), other);
5585 JSON_THROW(type_error::create(310,
"cannot use swap() with " + std::string(
type_name())));
5614 std::swap(*(m_value.string), other);
5618 JSON_THROW(type_error::create(310,
"cannot use swap() with " + std::string(
type_name())));
5673 const auto lhs_type = lhs.type();
5674 const auto rhs_type = rhs.type();
5676 if (lhs_type == rhs_type)
5681 return *lhs.m_value.array == *rhs.m_value.array;
5684 return *lhs.m_value.object == *rhs.m_value.object;
5690 return *lhs.m_value.string == *rhs.m_value.string;
5693 return lhs.m_value.boolean == rhs.m_value.boolean;
5696 return lhs.m_value.number_integer == rhs.m_value.number_integer;
5699 return lhs.m_value.number_unsigned == rhs.m_value.number_unsigned;
5702 return lhs.m_value.number_float == rhs.m_value.number_float;
5710 return static_cast<number_float_t>(lhs.m_value.number_integer) == rhs.m_value.number_float;
5714 return lhs.m_value.number_float ==
static_cast<number_float_t>(rhs.m_value.number_integer);
5718 return static_cast<number_float_t>(lhs.m_value.number_unsigned) == rhs.m_value.number_float;
5722 return lhs.m_value.number_float ==
static_cast<number_float_t>(rhs.m_value.number_unsigned);
5726 return static_cast<number_integer_t>(lhs.m_value.number_unsigned) == rhs.m_value.number_integer;
5730 return lhs.m_value.number_integer ==
static_cast<number_integer_t>(rhs.m_value.number_unsigned);
5740 template<
typename ScalarType,
typename std::enable_if<
5741 std::is_scalar<ScalarType>::value,
int>
::type = 0>
5751 template<
typename ScalarType,
typename std::enable_if<
5752 std::is_scalar<ScalarType>::value,
int>
::type = 0>
5778 return not (lhs == rhs);
5785 template<
typename ScalarType,
typename std::enable_if<
5786 std::is_scalar<ScalarType>::value,
int>
::type = 0>
5796 template<
typename ScalarType,
typename std::enable_if<
5797 std::is_scalar<ScalarType>::value,
int>
::type = 0>
5831 const auto lhs_type = lhs.type();
5832 const auto rhs_type = rhs.type();
5834 if (lhs_type == rhs_type)
5841 return (*lhs.m_value.array) < (*rhs.m_value.array);
5844 return (*lhs.m_value.object) < (*rhs.m_value.object);
5850 return (*lhs.m_value.string) < (*rhs.m_value.string);
5853 return (lhs.m_value.boolean) < (rhs.m_value.boolean);
5856 return (lhs.m_value.number_integer) < (rhs.m_value.number_integer);
5859 return (lhs.m_value.number_unsigned) < (rhs.m_value.number_unsigned);
5862 return (lhs.m_value.number_float) < (rhs.m_value.number_float);
5870 return static_cast<number_float_t>(lhs.m_value.number_integer) < rhs.m_value.number_float;
5874 return lhs.m_value.number_float <
static_cast<number_float_t>(rhs.m_value.number_integer);
5878 return static_cast<number_float_t>(lhs.m_value.number_unsigned) < rhs.m_value.number_float;
5882 return lhs.m_value.number_float <
static_cast<number_float_t>(rhs.m_value.number_unsigned);
5886 return lhs.m_value.number_integer <
static_cast<number_integer_t>(rhs.m_value.number_unsigned);
5890 return static_cast<number_integer_t>(lhs.m_value.number_unsigned) < rhs.m_value.number_integer;
5903 template<
typename ScalarType,
typename std::enable_if<
5904 std::is_scalar<ScalarType>::value,
int>
::type = 0>
5914 template<
typename ScalarType,
typename std::enable_if<
5915 std::is_scalar<ScalarType>::value,
int>
::type = 0>
5942 return not (rhs < lhs);
5949 template<
typename ScalarType,
typename std::enable_if<
5950 std::is_scalar<ScalarType>::value,
int>
::type = 0>
5960 template<
typename ScalarType,
typename std::enable_if<
5961 std::is_scalar<ScalarType>::value,
int>
::type = 0>
5988 return not (lhs <= rhs);
5995 template<
typename ScalarType,
typename std::enable_if<
5996 std::is_scalar<ScalarType>::value,
int>
::type = 0>
6006 template<
typename ScalarType,
typename std::enable_if<
6007 std::is_scalar<ScalarType>::value,
int>
::type = 0>
6034 return not (lhs < rhs);
6041 template<
typename ScalarType,
typename std::enable_if<
6042 std::is_scalar<ScalarType>::value,
int>
::type = 0>
6052 template<
typename ScalarType,
typename std::enable_if<
6053 std::is_scalar<ScalarType>::value,
int>
::type = 0>
6102 const bool pretty_print = o.width() > 0;
6103 const auto indentation = pretty_print ? o.width() : 0;
6110 s.
dump(j, pretty_print,
false,
static_cast<unsigned int>(indentation));
6122 JSON_HEDLEY_DEPRECATED(3.0.0)
6123 friend std::ostream& operator>>(const
basic_json& j, std::ostream& o)
6201 JSON_HEDLEY_WARN_UNUSED_RESULT
6204 const bool allow_exceptions =
true)
6207 parser(i, cb, allow_exceptions).
parse(
true, result);
6213 return parser(i).accept(
true);
6269 template <
typename SAX>
6270 JSON_HEDLEY_NON_NULL(2)
6273 const
bool strict = true)
6276 return format == input_format_t::json
6277 ?
parser(std::move(i)).sax_parse(sax, strict)
6330 template<
class IteratorType,
typename std::enable_if<
6332 std::random_access_iterator_tag,
6333 typename std::iterator_traits<IteratorType>::iterator_category>
::value,
int>
::type = 0>
6336 const bool allow_exceptions =
true)
6343 template<
class IteratorType,
typename std::enable_if<
6345 std::random_access_iterator_tag,
6346 typename std::iterator_traits<IteratorType>::iterator_category>
::value,
int>
::type = 0>
6347 static bool accept(IteratorType first, IteratorType last)
6352 template<
class IteratorType,
class SAX,
typename std::enable_if<
6354 std::random_access_iterator_tag,
6355 typename std::iterator_traits<IteratorType>::iterator_category>
::value,
int>
::type = 0>
6356 JSON_HEDLEY_NON_NULL(3)
6357 static
bool sax_parse(IteratorType first, IteratorType last, SAX* sax)
6359 return parser(detail::input_adapter(first, last)).sax_parse(sax);
6370 JSON_HEDLEY_DEPRECATED(3.0.0)
6443 JSON_HEDLEY_RETURNS_NON_NULL
6477 json_value m_value = {};
6577 std::vector<uint8_t> result;
6584 binary_writer<uint8_t>(o).write_cbor(j);
6589 binary_writer<char>(o).write_cbor(j);
6673 std::vector<uint8_t> result;
6680 binary_writer<uint8_t>(o).write_msgpack(j);
6685 binary_writer<char>(o).write_msgpack(j);
6769 const bool use_size =
false,
6770 const bool use_type =
false)
6772 std::vector<uint8_t> result;
6773 to_ubjson(j, result, use_size, use_type);
6778 const bool use_size =
false,
const bool use_type =
false)
6780 binary_writer<uint8_t>(o).write_ubjson(j, use_size, use_type);
6784 const bool use_size =
false,
const bool use_type =
false)
6786 binary_writer<char>(o).write_ubjson(j, use_size, use_type);
6847 std::vector<uint8_t> result;
6973 JSON_HEDLEY_WARN_UNUSED_RESULT
6975 const bool strict =
true,
6976 const bool allow_exceptions =
true)
6987 template<
typename A1,
typename A2,
6988 detail::enable_if_t<std::is_constructible<detail::input_adapter, A1, A2>::value,
int> = 0>
6989 JSON_HEDLEY_WARN_UNUSED_RESULT
6991 const bool strict =
true,
6992 const bool allow_exceptions =
true)
7082 JSON_HEDLEY_WARN_UNUSED_RESULT
7084 const bool strict =
true,
7085 const bool allow_exceptions =
true)
7096 template<
typename A1,
typename A2,
7097 detail::enable_if_t<std::is_constructible<detail::input_adapter, A1, A2>::value,
int> = 0>
7098 JSON_HEDLEY_WARN_UNUSED_RESULT
7100 const bool strict =
true,
7101 const bool allow_exceptions =
true)
7170 JSON_HEDLEY_WARN_UNUSED_RESULT
7172 const bool strict =
true,
7173 const bool allow_exceptions =
true)
7184 template<
typename A1,
typename A2,
7185 detail::enable_if_t<std::is_constructible<detail::input_adapter, A1, A2>::value,
int> = 0>
7186 JSON_HEDLEY_WARN_UNUSED_RESULT
7188 const bool strict =
true,
7189 const bool allow_exceptions =
true)
7257 JSON_HEDLEY_WARN_UNUSED_RESULT
7259 const bool strict =
true,
7260 const bool allow_exceptions =
true)
7271 template<
typename A1,
typename A2,
7272 detail::enable_if_t<std::is_constructible<detail::input_adapter, A1, A2>::value,
int> = 0>
7273 JSON_HEDLEY_WARN_UNUSED_RESULT
7275 const bool strict =
true,
7276 const bool allow_exceptions =
true)
7330 return ptr.get_unchecked(
this);
7358 return ptr.get_unchecked(
this);
7401 return ptr.get_checked(
this);
7444 return ptr.get_checked(
this);
7472 json_pointer::flatten(
"", *
this, result);
7508 return json_pointer::unflatten(*
this);
7573 enum class patch_operations {add, remove, replace, move, copy, test, invalid};
7575 const auto get_op = [](
const std::string & op)
7579 return patch_operations::add;
7583 return patch_operations::remove;
7585 if (op ==
"replace")
7587 return patch_operations::replace;
7591 return patch_operations::move;
7595 return patch_operations::copy;
7599 return patch_operations::test;
7602 return patch_operations::invalid;
7617 if (top_pointer != ptr)
7619 result.at(top_pointer);
7623 const auto last_path = ptr.
back();
7627 switch (parent.m_type)
7633 parent[last_path] = val;
7639 if (last_path ==
"-")
7642 parent.push_back(val);
7646 const auto idx = json_pointer::array_index(last_path);
7647 if (JSON_HEDLEY_UNLIKELY(
static_cast<size_type>(idx) > parent.size()))
7650 JSON_THROW(out_of_range::create(401,
"array index " + std::to_string(idx) +
" is out of range"));
7654 parent.insert(parent.begin() +
static_cast<difference_type>(idx), val);
7666 const auto operation_remove = [&result](
json_pointer & ptr)
7669 const auto last_path = ptr.
back();
7674 if (parent.is_object())
7677 auto it = parent.find(last_path);
7678 if (JSON_HEDLEY_LIKELY(it != parent.end()))
7684 JSON_THROW(out_of_range::create(403,
"key '" + last_path +
"' not found"));
7687 else if (parent.is_array())
7690 parent.erase(
static_cast<size_type>(json_pointer::array_index(last_path)));
7695 if (JSON_HEDLEY_UNLIKELY(not json_patch.is_array()))
7701 for (
const auto& val : json_patch)
7704 const auto get_value = [&val](
const std::string & op,
7705 const std::string & member,
7709 auto it = val.m_value.object->find(member);
7712 const auto error_msg = (op ==
"op") ?
"operation" :
"operation '" + op +
"'";
7715 if (JSON_HEDLEY_UNLIKELY(it == val.m_value.object->end()))
7717 JSON_THROW(
parse_error::create(105, 0, error_msg +
" must have member '" + member +
"'"));
7721 if (JSON_HEDLEY_UNLIKELY(string_type and not it->second.is_string()))
7723 JSON_THROW(
parse_error::create(105, 0, error_msg +
" must have string member '" + member +
"'"));
7731 if (JSON_HEDLEY_UNLIKELY(not val.is_object()))
7737 const std::string op = get_value(
"op",
"op",
true);
7738 const std::string path = get_value(op,
"path",
true);
7743 case patch_operations::add:
7745 operation_add(ptr, get_value(
"add",
"value",
false));
7749 case patch_operations::remove:
7751 operation_remove(ptr);
7755 case patch_operations::replace:
7758 result.at(ptr) = get_value(
"replace",
"value",
false);
7762 case patch_operations::move:
7764 const std::string from_path = get_value(
"move",
"from",
true);
7774 operation_remove(from_ptr);
7775 operation_add(ptr, v);
7779 case patch_operations::copy:
7781 const std::string from_path = get_value(
"copy",
"from",
true);
7790 operation_add(ptr, v);
7794 case patch_operations::test:
7796 bool success =
false;
7801 success = (result.at(ptr) == get_value(
"test",
"value",
false));
7809 if (JSON_HEDLEY_UNLIKELY(not success))
7811 JSON_THROW(other_error::create(501,
"unsuccessful: " + val.dump()));
7862 JSON_HEDLEY_WARN_UNUSED_RESULT
7864 const std::string& path =
"")
7875 if (
source.type() != target.type())
7880 {
"op",
"replace"}, {
"path", path}, {
"value", target}
7891 while (i <
source.size() and i < target.size())
7894 auto temp_diff =
diff(
source[i], target[i], path +
"/" + std::to_string(i));
7895 result.insert(result.end(), temp_diff.begin(), temp_diff.end());
7904 while (i <
source.size())
7908 result.insert(result.begin() + end_index,
object(
7911 {
"path", path +
"/" + std::to_string(i)}
7917 while (i < target.size())
7922 {
"path", path +
"/" + std::to_string(i)},
7923 {
"value", target[i]}
7934 for (
auto it =
source.cbegin(); it !=
source.cend(); ++it)
7937 const auto key = json_pointer::escape(it.key());
7939 if (target.find(it.key()) != target.end())
7942 auto temp_diff =
diff(it.value(), target[it.key()], path +
"/" + key);
7943 result.insert(result.end(), temp_diff.begin(), temp_diff.end());
7948 result.push_back(
object(
7950 {
"op",
"remove"}, {
"path", path +
"/" + key}
7956 for (
auto it = target.cbegin(); it != target.cend(); ++it)
7961 const auto key = json_pointer::escape(it.key());
7964 {
"op",
"add"}, {
"path", path +
"/" + key},
7965 {
"value", it.value()}
7978 {
"op",
"replace"}, {
"path", path}, {
"value", target}
8040 if (apply_patch.is_object())
8046 for (
auto it = apply_patch.begin(); it != apply_patch.end(); ++it)
8048 if (it.value().is_null())
8060 *
this = apply_patch;
8076 NLOHMANN_BASIC_JSON_TPL_DECLARATION
8077 std::string
to_string(
const NLOHMANN_BASIC_JSON_TPL& j)
8103 const auto& h = hash<nlohmann::json::string_t>();
8132 is_nothrow_move_constructible<nlohmann::json>::value and
8133 is_nothrow_move_assignable<nlohmann::json>::value
8154 JSON_HEDLEY_NON_NULL(1)
8155 inline
nlohmann::
json operator "" _json(const
char* s, std::
size_t n)
8173 JSON_HEDLEY_NON_NULL(1)
8174 inline
nlohmann::
json::json_pointer operator "" _json_pointer(const
char* s, std::
size_t n)
8179 #include <nlohmann/detail/macro_unscope.hpp>
8181 #endif // INCLUDE_NLOHMANN_JSON_HPP_