18#ifndef INCLUDE_WPI_JSON_HPP_
19#define INCLUDE_WPI_JSON_HPP_
24#include <initializer_list>
64#if defined(JSON_HAS_CPP_17)
66 #include <string_view>
101 friend class ::wpi::json_pointer;
105 template<
typename BasicJsonType,
typename InputType>
106 friend class ::wpi::detail::parser;
107 friend ::wpi::detail::serializer<basic_json>;
108 template<
typename BasicJsonType>
109 friend class ::wpi::detail::iter_impl;
110 template<
typename BasicJsonType,
typename CharType>
111 friend class ::wpi::detail::binary_writer;
112 template<
typename BasicJsonType,
typename InputType,
typename SAX>
113 friend class ::wpi::detail::binary_reader;
114 template<
typename BasicJsonType>
115 friend class ::wpi::detail::json_sax_dom_parser;
116 template<
typename BasicJsonType>
117 friend class ::wpi::detail::json_sax_dom_callback_parser;
125 using lexer = ::wpi::detail::lexer_base<basic_json>;
127 template<
typename InputAdapterType>
128 static ::wpi::detail::parser<basic_json, InputAdapterType> parser(
129 InputAdapterType adapter,
131 const bool allow_exceptions =
true,
132 const bool ignore_comments =
false
135 return ::wpi::detail::parser<basic_json, InputAdapterType>(std::move(adapter),
136 std::move(cb), allow_exceptions, ignore_comments);
140 using primitive_iterator_t = ::wpi::detail::primitive_iterator_t;
141 template<
typename BasicJsonType>
142 using internal_iterator = ::wpi::detail::internal_iterator<BasicJsonType>;
143 template<
typename BasicJsonType>
144 using iter_impl = ::wpi::detail::iter_impl<BasicJsonType>;
145 template<
typename Iterator>
146 using iteration_proxy = ::wpi::detail::iteration_proxy<Iterator>;
147 template<
typename Base>
using json_reverse_iterator = ::wpi::detail::json_reverse_iterator<Base>;
149 template<
typename CharType>
152 template<
typename InputType>
153 using binary_reader = ::wpi::detail::binary_reader<basic_json, InputType>;
154 template<
typename CharType>
using binary_writer = ::wpi::detail::binary_writer<basic_json, CharType>;
162 template<
typename T,
typename SFINAE>
219 using pointer =
typename std::allocator_traits<allocator_type>::pointer;
221 using const_pointer =
typename std::allocator_traits<allocator_type>::const_pointer;
249 result[
"copyright"] =
"(C) 2013-2022 Niels Lohmann";
250 result[
"name"] =
"JSON for Modern C++";
251 result[
"url"] =
"https://github.com/nlohmann/json";
252 result[
"version"][
"string"] =
261 result[
"platform"] =
"win32";
262#elif defined __linux__
263 result[
"platform"] =
"linux";
264#elif defined __APPLE__
265 result[
"platform"] =
"apple";
266#elif defined __unix__
267 result[
"platform"] =
"unix";
269 result[
"platform"] =
"unknown";
272#if defined(__ICC) || defined(__INTEL_COMPILER)
273 result[
"compiler"] = {{
"family",
"icc"}, {
"version", __INTEL_COMPILER}};
274#elif defined(__clang__)
275 result[
"compiler"] = {{
"family",
"clang"}, {
"version", __clang_version__}};
276#elif defined(__GNUC__) || defined(__GNUG__)
277 result[
"compiler"] = {{
"family",
"gcc"}, {
"version",
detail::concat(
283#elif defined(__HP_cc) || defined(__HP_aCC)
284 result[
"compiler"] =
"hp"
285#elif defined(__IBMCPP__)
286 result[
"compiler"] = {{
"family",
"ilecpp"}, {
"version", __IBMCPP__}};
287#elif defined(_MSC_VER)
288 result[
"compiler"] = {{
"family",
"msvc"}, {
"version", _MSC_VER}};
290 result[
"compiler"] = {{
"family",
"pgcpp"}, {
"version", __PGI}};
291#elif defined(__SUNPRO_CC)
292 result[
"compiler"] = {{
"family",
"sunpro"}, {
"version", __SUNPRO_CC}};
294 result[
"compiler"] = {{
"family",
"unknown"}, {
"version",
"unknown"}};
298#if defined(_MSVC_LANG)
300#elif defined(__cplusplus)
303 result[
"compiler"][
"c++"] =
"unknown";
322#if defined(JSON_HAS_CPP_14)
335 AllocatorType<std::pair<
const StringType,
340 using array_t = ArrayType<basic_json, AllocatorType<basic_json>>;
364 using binary_t = wpi::byte_container_with_subtype<BinaryType>;
375 template<
typename T,
typename... Args>
377 static T* create(Args&& ... args)
379 AllocatorType<T> alloc;
380 using AllocatorTraits = std::allocator_traits<AllocatorType<T>>;
382 auto deleter = [&](T * obj)
384 AllocatorTraits::deallocate(alloc, obj, 1);
386 std::unique_ptr<T,
decltype(deleter)> obj(AllocatorTraits::allocate(alloc, 1), deleter);
387 AllocatorTraits::construct(alloc, obj.get(), std::forward<Args>(args)...);
389 return obj.release();
442 json_value() =
default;
444 json_value(
boolean_t v) noexcept : boolean(v) {}
458 object = create<object_t>();
464 array = create<array_t>();
470 string = create<string_t>(
"");
476 binary = create<binary_t>();
558 std::vector<basic_json> stack;
563 stack.reserve(
array->size());
564 std::move(
array->begin(),
array->end(), std::back_inserter(stack));
568 stack.reserve(
object->size());
569 for (
auto&& it : *
object)
571 stack.push_back(std::move(it.second));
575 while (!stack.empty())
578 basic_json current_item(std::move(stack.back()));
583 if (current_item.is_array())
585 std::move(current_item.m_value.array->begin(), current_item.m_value.array->end(), std::back_inserter(stack));
587 current_item.m_value.array->clear();
589 else if (current_item.is_object())
591 for (
auto&& it : *current_item.m_value.object)
593 stack.push_back(std::move(it.second));
596 current_item.m_value.object->clear();
608 AllocatorType<object_t> alloc;
609 std::allocator_traits<
decltype(alloc)>::destroy(alloc,
object);
610 std::allocator_traits<
decltype(alloc)>::deallocate(alloc,
object, 1);
616 AllocatorType<array_t> alloc;
617 std::allocator_traits<
decltype(alloc)>::destroy(alloc, array);
618 std::allocator_traits<
decltype(alloc)>::deallocate(alloc, array, 1);
624 AllocatorType<string_t> alloc;
625 std::allocator_traits<
decltype(alloc)>::destroy(alloc,
string);
626 std::allocator_traits<
decltype(alloc)>::deallocate(alloc,
string, 1);
632 AllocatorType<binary_t> alloc;
633 std::allocator_traits<
decltype(alloc)>::destroy(alloc, binary);
634 std::allocator_traits<
decltype(alloc)>::deallocate(alloc, binary, 1);
671 void assert_invariant(
bool check_parents =
true) const noexcept
684 return j.m_parent ==
this;
689 static_cast<void>(check_parents);
699 for (
auto& element : *
m_value.array)
701 element.m_parent =
this;
708 for (
auto& element : *
m_value.object)
710 element.second.m_parent =
this;
729 iterator set_parents(
iterator it,
typename iterator::difference_type count_set_parents)
732 for (
typename iterator::difference_type i = 0; i < count_set_parents; ++i)
734 (it + i)->m_parent =
this;
737 static_cast<void>(count_set_parents);
742 reference set_parent(
reference j, std::size_t old_capacity =
static_cast<std::size_t
>(-1))
745 if (old_capacity !=
static_cast<std::size_t
>(-1))
759#ifdef JSON_HEDLEY_MSVC_VERSION
760#pragma warning(push )
761#pragma warning(disable : 4127)
768#ifdef JSON_HEDLEY_MSVC_VERSION
769#pragma warning( pop )
774 static_cast<void>(j);
775 static_cast<void>(old_capacity);
820 template <
typename CompatibleType,
826 std::forward<CompatibleType>(val))))
835 template <
typename BasicJsonType,
840 using other_boolean_t =
typename BasicJsonType::boolean_t;
841 using other_number_float_t =
typename BasicJsonType::number_float_t;
842 using other_number_integer_t =
typename BasicJsonType::number_integer_t;
843 using other_number_unsigned_t =
typename BasicJsonType::number_unsigned_t;
844 using other_string_t =
typename BasicJsonType::string_t;
845 using other_object_t =
typename BasicJsonType::object_t;
846 using other_array_t =
typename BasicJsonType::array_t;
847 using other_binary_t =
typename BasicJsonType::binary_t;
892 bool type_deduction =
true,
897 bool is_an_object = std::all_of(init.begin(), init.end(),
900 return element_ref->is_array() && element_ref->size() == 2 && (*element_ref)[0].is_string();
909 is_an_object =
false;
925 for (
auto& element_ref : init)
929 std::move(*((*element.m_value.array)[0].m_value.string)),
930 std::move((*element.m_value.array)[1]));
937 m_value.array = create<array_t>(init.begin(), init.end());
958 static basic_json binary(
const typename binary_t::container_type& init,
typename binary_t::subtype_type subtype)
962 res.m_value =
binary_t(init, subtype);
973 res.m_value = std::move(init);
980 static basic_json binary(
typename binary_t::container_type&& init,
typename binary_t::subtype_type subtype)
984 res.m_value =
binary_t(std::move(init), subtype);
1009 m_value.array = create<array_t>(cnt, val);
1016 template <
class InputIT,
typename std::enable_if <
1017 std::is_same<InputIT, typename basic_json_t::iterator>::value ||
1018 std::is_same<InputIT, typename basic_json_t::const_iterator>::value,
int >
::type = 0 >
1031 m_type =
first.m_object->m_type;
1043 || !last.m_it.primitive_iterator.is_end()))
1063 m_value.number_integer =
first.m_object->m_value.number_integer;
1069 m_value.number_unsigned =
first.m_object->m_value.number_unsigned;
1075 m_value.number_float =
first.m_object->m_value.number_float;
1093 m_value.object = create<object_t>(
first.m_it.object_iterator,
1094 last.m_it.object_iterator);
1100 m_value.array = create<array_t>(
first.m_it.array_iterator,
1101 last.m_it.array_iterator);
1126 template<
typename JsonRef,
1128 std::is_same<typename JsonRef::value_type, basic_json>>
::value,
int> = 0 >
1134 : m_type(other.m_type)
1137 other.assert_invariant();
1202 : m_type(std::move(other.m_type)),
1203 m_value(std::move(other.m_value))
1206 other.assert_invariant(
false);
1219 std::is_nothrow_move_constructible<value_t>::value&&
1220 std::is_nothrow_move_assignable<value_t>::value&&
1221 std::is_nothrow_move_constructible<json_value>::value&&
1222 std::is_nothrow_move_assignable<json_value>::value
1226 other.assert_invariant();
1229 swap(m_type, other.m_type);
1241 assert_invariant(
false);
1259 const char indent_char =
' ',
1260 const bool ensure_ascii =
false,
1268 s.dump(*
this,
true, ensure_ascii,
static_cast<unsigned int>(indent));
1272 s.dump(*
this,
false, ensure_ascii, 0);
1278 void dump(raw_ostream& os,
const int indent = -1,
1279 const char indent_char =
' ',
1280 const bool ensure_ascii =
false,
1281 const error_handler_t error_handler = error_handler_t::strict)
const {
1286 s.dump(*
this,
true, ensure_ascii,
static_cast<unsigned int>(indent));
1290 s.dump(*
this,
false, ensure_ascii, 0);
1438 constexpr const array_t* get_impl_ptr(
const array_t* )
const noexcept
1526 template<
typename ReferenceType,
typename ThisType>
1527 static ReferenceType get_ref_impl(ThisType& obj)
1547 template<
typename PointerType,
typename std::enable_if<
1548 std::is_pointer<PointerType>::value,
int>
::type = 0>
1549 auto get_ptr() noexcept -> decltype(
std::declval<basic_json_t&>().get_impl_ptr(
std::declval<PointerType>()))
1552 return get_impl_ptr(
static_cast<PointerType
>(
nullptr));
1557 template <
typename PointerType,
typename std::enable_if <
1558 std::is_pointer<PointerType>::value&&
1560 constexpr auto get_ptr() const noexcept -> decltype(
std::declval<const basic_json_t&>().get_impl_ptr(
std::declval<PointerType>()))
1563 return get_impl_ptr(
static_cast<PointerType
>(
nullptr));
1605 template <
typename ValueType,
1613 auto ret = ValueType();
1648 template <
typename ValueType,
1673 template <
typename BasicJsonType,
1696 template<
typename BasicJsonType,
1698 std::is_same<BasicJsonType, basic_json_t>::value,
1709 template<
typename PointerType,
1711 std::is_pointer<PointerType>::value,
1714 ->
decltype(std::declval<const basic_json_t&>().template get_ptr<PointerType>())
1717 return get_ptr<PointerType>();
1744 template <
typename ValueTypeCV,
typename ValueType = detail::uncvref_t<ValueTypeCV>>
1745#if defined(JSON_HAS_CPP_14)
1749 noexcept(
std::declval<const basic_json_t&>().template get_impl<ValueType>(
detail::priority_tag<4> {})))
1755 static_assert(!std::is_reference<ValueTypeCV>::value,
1756 "get() cannot be used with reference types, you might want to use get_ref()");
1787 template<
typename PointerType,
typename std::enable_if<
1788 std::is_pointer<PointerType>::value,
int>
::type = 0>
1789 auto get() noexcept -> decltype(
std::declval<basic_json_t&>().template
get_ptr<PointerType>())
1792 return get_ptr<PointerType>();
1797 template <
typename ValueType,
1802 ValueType &
get_to(ValueType& v)
const noexcept(
noexcept(
1811 template<
typename ValueType,
1822 typename T, std::size_t N,
1823 typename Array = T (&)[N],
1828 std::declval<const basic_json_t&>(), v)))
1836 template<
typename ReferenceType,
typename std::enable_if<
1837 std::is_reference<ReferenceType>::value,
int>
::type = 0>
1841 return get_ref_impl<ReferenceType>(*
this);
1846 template <
typename ReferenceType,
typename std::enable_if <
1847 std::is_reference<ReferenceType>::value&&
1852 return get_ref_impl<ReferenceType>(*
this);
1884 template <
typename ValueType,
typename std::enable_if <
1892#if defined(JSON_HAS_CPP_17) && (defined(__GNUC__) || (defined(_MSC_VER) && _MSC_VER >= 1910 && _MSC_VER <= 1914))
1895#if defined(JSON_HAS_CPP_17)
1903 return get<ValueType>();
1915 return *get_ptr<binary_t*>();
1927 return *get_ptr<const binary_t*>();
1950 return set_parent(
m_value.array->at(idx));
1973 return m_value.array->at(idx);
1997 auto it =
m_value.object->find(key);
1998 if (it ==
m_value.object->end())
2002 return set_parent(it->second);
2017 auto it =
m_value.object->find(std::forward<KeyType>(key));
2018 if (it ==
m_value.object->end())
2022 return set_parent(it->second);
2035 auto it =
m_value.object->find(key);
2036 if (it ==
m_value.object->end())
2055 auto it =
m_value.object->find(std::forward<KeyType>(key));
2056 if (it ==
m_value.object->end())
2071 m_value.array = create<array_t>();
2079 if (idx >=
m_value.array->size())
2083 const auto old_size =
m_value.array->size();
2084 const auto old_capacity =
m_value.array->capacity();
2086 m_value.array->resize(idx + 1);
2097 set_parents(begin() +
static_cast<typename iterator::difference_type
>(old_size),
static_cast<typename iterator::difference_type
>(idx + 1 - old_size));
2103 return m_value.array->operator[](idx);
2116 return m_value.array->operator[](idx);
2130 m_value.object = create<object_t>();
2137 auto result =
m_value.object->emplace(std::move(key),
nullptr);
2138 return set_parent(result.first->second);
2151 auto it =
m_value.object->find(key);
2161 template<
typename T>
2164 return operator[](
typename object_t::key_type(key));
2167 template<
typename T>
2170 return operator[](
typename object_t::key_type(key));
2183 m_value.object = create<object_t>();
2190 auto result =
m_value.object->emplace(std::forward<KeyType>(key),
nullptr);
2191 return set_parent(result.first->second);
2206 auto it =
m_value.object->find(std::forward<KeyType>(key));
2215 template<
typename KeyType>
2219 template<
typename ValueType>
2220 using value_return_type = std::conditional <
2230 && !std::is_same<value_t, detail::uncvref_t<ValueType>>
::value,
int > = 0 >
2231 ValueType
value(
const typename object_t::key_type& key,
const ValueType& default_value)
const
2237 const auto it =
find(key);
2240 return it->template get<ValueType>();
2243 return default_value;
2255 && !std::is_same<value_t, detail::uncvref_t<ValueType>>
::value,
int > = 0 >
2256 ReturnType
value(
const typename object_t::key_type& key, ValueType && default_value)
const
2262 const auto it =
find(key);
2265 return it->template get<ReturnType>();
2268 return std::forward<ValueType>(default_value);
2279 && is_comparable_with_object_key<KeyType>::value
2281 && !std::is_same<value_t, detail::uncvref_t<ValueType>>
::value,
int > = 0 >
2282 ValueType
value(KeyType && key,
const ValueType& default_value)
const
2288 const auto it =
find(std::forward<KeyType>(key));
2291 return it->template get<ValueType>();
2294 return default_value;
2306 && is_comparable_with_object_key<KeyType>::value
2308 && !std::is_same<value_t, detail::uncvref_t<ValueType>>
::value,
int > = 0 >
2309 ReturnType
value(KeyType && key, ValueType && default_value)
const
2315 const auto it =
find(std::forward<KeyType>(key));
2318 return it->template get<ReturnType>();
2321 return std::forward<ValueType>(default_value);
2331 && !std::is_same<value_t, detail::uncvref_t<ValueType>>
::value,
int > = 0 >
2340 return ptr.get_checked(
this).template get<ValueType>();
2344 return default_value;
2356 && !std::is_same<value_t, detail::uncvref_t<ValueType>>
::value,
int > = 0 >
2365 return ptr.get_checked(
this).template get<ReturnType>();
2369 return std::forward<ValueType>(default_value);
2379 && !std::is_same<value_t, detail::uncvref_t<ValueType>>
::value,
int > = 0 >
2381 ValueType
value(const ::wpi::json_pointer<BasicJsonType>&
ptr,
const ValueType& default_value)
const
2383 return value(
ptr.convert(), default_value);
2390 && !std::is_same<value_t, detail::uncvref_t<ValueType>>
::value,
int > = 0 >
2392 ReturnType
value(const ::wpi::json_pointer<BasicJsonType>&
ptr, ValueType && default_value)
const
2394 return value(
ptr.convert(), std::forward<ValueType>(default_value));
2432 std::is_same<IteratorType, typename basic_json_t::iterator>::value ||
2433 std::is_same<IteratorType, typename basic_json_t::const_iterator>::value,
int > = 0 >
2442 IteratorType result = end();
2460 AllocatorType<string_t> alloc;
2461 std::allocator_traits<
decltype(alloc)>::destroy(alloc,
m_value.string);
2462 std::allocator_traits<
decltype(alloc)>::deallocate(alloc,
m_value.string, 1);
2467 AllocatorType<binary_t> alloc;
2468 std::allocator_traits<
decltype(alloc)>::destroy(alloc,
m_value.binary);
2469 std::allocator_traits<
decltype(alloc)>::deallocate(alloc,
m_value.binary, 1);
2480 result.m_it.object_iterator =
m_value.object->erase(pos.m_it.object_iterator);
2486 result.m_it.array_iterator =
m_value.array->erase(pos.m_it.array_iterator);
2502 std::is_same<IteratorType, typename basic_json_t::iterator>::value ||
2503 std::is_same<IteratorType, typename basic_json_t::const_iterator>::value,
int > = 0 >
2512 IteratorType result = end();
2524 || !last.m_it.primitive_iterator.is_end()))
2531 AllocatorType<string_t> alloc;
2532 std::allocator_traits<
decltype(alloc)>::destroy(alloc,
m_value.string);
2533 std::allocator_traits<
decltype(alloc)>::deallocate(alloc,
m_value.string, 1);
2538 AllocatorType<binary_t> alloc;
2539 std::allocator_traits<
decltype(alloc)>::destroy(alloc,
m_value.binary);
2540 std::allocator_traits<
decltype(alloc)>::deallocate(alloc,
m_value.binary, 1);
2551 result.m_it.object_iterator =
m_value.object->erase(
first.m_it.object_iterator,
2552 last.m_it.object_iterator);
2558 result.m_it.array_iterator =
m_value.array->erase(
first.m_it.array_iterator,
2559 last.m_it.array_iterator);
2575 size_type erase_internal(KeyType && key)
2583 return m_value.object->erase(std::forward<KeyType>(key));
2588 size_type erase_internal(KeyType && key)
2596 const auto it =
m_value.object->find(std::forward<KeyType>(key));
2597 if (it !=
m_value.object->end())
2613 return erase_internal(key);
2622 return erase_internal(std::forward<KeyType>(key));
2659 auto result = end();
2663 result.m_it.object_iterator =
m_value.object->find(key);
2673 auto result = cend();
2677 result.m_it.object_iterator =
m_value.object->find(key);
2689 auto result = end();
2693 result.m_it.object_iterator =
m_value.object->find(std::forward<KeyType>(key));
2705 auto result = cend();
2709 result.m_it.object_iterator =
m_value.object->find(std::forward<KeyType>(key));
2730 return is_object() ?
m_value.object->count(std::forward<KeyType>(key)) : 0;
2735 bool contains(
const typename object_t::key_type& key)
const
2753 return ptr.contains(
this);
2756 template<typename BasicJsonType, detail::enable_if_t<detail::is_basic_json<BasicJsonType>::value,
int> = 0>
2758 bool contains(
const typename ::wpi::json_pointer<BasicJsonType>&
ptr)
const
2760 return ptr.contains(
this);
2890 iteration_proxy<iterator> items() noexcept
2892 return iteration_proxy<iterator>(*
this);
2897 iteration_proxy<const_iterator> items() const noexcept
2899 return iteration_proxy<const_iterator>(*
this);
2914 bool empty() const noexcept
2927 return m_value.array->empty();
2933 return m_value.object->empty();
2972 return m_value.object->size();
2999 return m_value.array->max_size();
3005 return m_value.object->max_size();
3036 void clear() noexcept
3114 const auto old_capacity =
m_value.array->capacity();
3115 m_value.array->push_back(std::move(val));
3116 set_parent(
m_value.array->back(), old_capacity);
3147 const auto old_capacity =
m_value.array->capacity();
3148 m_value.array->push_back(val);
3149 set_parent(
m_value.array->back(), old_capacity);
3179 auto res =
m_value.object->insert(val);
3180 set_parent(res.first->second);
3195 if (
is_object() && init.size() == 2 && (*init.begin())->is_string())
3197 basic_json&& key = init.begin()->moved_or_copied();
3198 push_back(
typename object_t::value_type(
3199 std::move(key.get_ref<
string_t&>()), (init.begin() + 1)->moved_or_copied()));
3217 template<
class... Args>
3235 const auto old_capacity =
m_value.array->capacity();
3236 m_value.array->emplace_back(std::forward<Args>(args)...);
3237 return set_parent(
m_value.array->back(), old_capacity);
3242 template<
class... Args>
3243 std::pair<iterator, bool>
emplace(Args&& ... args)
3260 auto res =
m_value.object->emplace(std::forward<Args>(args)...);
3261 set_parent(res.first->second);
3265 it.m_it.object_iterator = res.first;
3268 return {it, res.second};
3274 template<
typename... Args>
3280 auto insert_pos = std::distance(
m_value.array->begin(), pos.m_it.array_iterator);
3281 m_value.array->insert(pos.m_it.array_iterator, std::forward<Args>(args)...);
3282 result.m_it.array_iterator =
m_value.array->begin() + insert_pos;
3412 m_value.object->insert(
first.m_it.object_iterator, last.m_it.object_iterator);
3419 update(j.begin(), j.end(), merge_objects);
3430 m_value.object = create<object_t>();
3451 for (
auto it =
first; it != last; ++it)
3453 if (merge_objects && it.value().is_object())
3455 auto it2 =
m_value.object->find(it.key());
3456 if (it2 !=
m_value.object->end())
3458 it2->second.update(it.value(),
true);
3462 m_value.object->operator[](it.key()) = it.value();
3464 m_value.object->operator[](it.key()).m_parent =
this;
3472 std::is_nothrow_move_constructible<value_t>::value&&
3473 std::is_nothrow_move_assignable<value_t>::value&&
3474 std::is_nothrow_move_constructible<json_value>::value&&
3475 std::is_nothrow_move_assignable<json_value>::value
3482 other.set_parents();
3489 std::is_nothrow_move_constructible<value_t>::value&&
3490 std::is_nothrow_move_assignable<value_t>::value&&
3491 std::is_nothrow_move_constructible<json_value>::value&&
3492 std::is_nothrow_move_assignable<json_value>::value
3564 void swap(
typename binary_t::container_type& other)
3589#define JSON_IMPLEMENT_OPERATOR(op, null_result, unordered_result, default_result) \
3590 const auto lhs_type = lhs.type(); \
3591 const auto rhs_type = rhs.type(); \
3593 if (lhs_type == rhs_type) \
3597 case value_t::array: \
3598 return (*lhs.m_value.array) op (*rhs.m_value.array); \
3600 case value_t::object: \
3601 return (*lhs.m_value.object) op (*rhs.m_value.object); \
3603 case value_t::null: \
3604 return (null_result); \
3606 case value_t::string: \
3607 return (*lhs.m_value.string) op (*rhs.m_value.string); \
3609 case value_t::boolean: \
3610 return (lhs.m_value.boolean) op (rhs.m_value.boolean); \
3612 case value_t::number_integer: \
3613 return (lhs.m_value.number_integer) op (rhs.m_value.number_integer); \
3615 case value_t::number_unsigned: \
3616 return (lhs.m_value.number_unsigned) op (rhs.m_value.number_unsigned); \
3618 case value_t::number_float: \
3619 return (lhs.m_value.number_float) op (rhs.m_value.number_float); \
3621 case value_t::binary: \
3622 return (*lhs.m_value.binary) op (*rhs.m_value.binary); \
3624 case value_t::discarded: \
3626 return (unordered_result); \
3629 else if (lhs_type == value_t::number_integer && rhs_type == value_t::number_float) \
3631 return static_cast<number_float_t>(lhs.m_value.number_integer) op rhs.m_value.number_float; \
3633 else if (lhs_type == value_t::number_float && rhs_type == value_t::number_integer) \
3635 return lhs.m_value.number_float op static_cast<number_float_t>(rhs.m_value.number_integer); \
3637 else if (lhs_type == value_t::number_unsigned && rhs_type == value_t::number_float) \
3639 return static_cast<number_float_t>(lhs.m_value.number_unsigned) op rhs.m_value.number_float; \
3641 else if (lhs_type == value_t::number_float && rhs_type == value_t::number_unsigned) \
3643 return lhs.m_value.number_float op static_cast<number_float_t>(rhs.m_value.number_unsigned); \
3645 else if (lhs_type == value_t::number_unsigned && rhs_type == value_t::number_integer) \
3647 return static_cast<number_integer_t>(lhs.m_value.number_unsigned) op rhs.m_value.number_integer; \
3649 else if (lhs_type == value_t::number_integer && rhs_type == value_t::number_unsigned) \
3651 return lhs.m_value.number_integer op static_cast<number_integer_t>(rhs.m_value.number_unsigned); \
3653 else if(compares_unordered(lhs, rhs))\
3655 return (unordered_result);\
3658 return (default_result);
3673#if JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON
3684 return compares_unordered(*
this,
rhs,
inverse);
3688#if JSON_HAS_THREE_WAY_COMPARISON
3694#pragma GCC diagnostic push
3695#pragma GCC diagnostic ignored "-Wfloat-equal"
3700#pragma GCC diagnostic pop
3706 template<
typename ScalarType>
3707 requires std::is_scalar_v<ScalarType>
3717 if (compares_unordered(
rhs,
true))
3732 std::partial_ordering::equivalent,
3733 std::partial_ordering::unordered,
3734 lhs_type <=> rhs_type)
3739 template<
typename ScalarType>
3740 requires std::is_scalar_v<ScalarType>
3741 std::partial_ordering operator<=>(ScalarType
rhs)
const noexcept
3746#if JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON
3755 if (compares_unordered(
rhs,
true))
3759 return !(
rhs < *
this);
3764 template<
typename ScalarType>
3765 requires std::is_scalar_v<ScalarType>
3776 if (compares_unordered(
rhs,
true))
3780 return !(*
this <
rhs);
3785 template<
typename ScalarType>
3786 requires std::is_scalar_v<ScalarType>
3798#pragma GCC diagnostic push
3799#pragma GCC diagnostic ignored "-Wfloat-equal"
3803#pragma GCC diagnostic pop
3809 template<
typename ScalarType,
typename std::enable_if<
3810 std::is_scalar<ScalarType>::value,
int>
::type = 0>
3818 template<
typename ScalarType,
typename std::enable_if<
3819 std::is_scalar<ScalarType>::value,
int>
::type = 0>
3829 if (compares_unordered(lhs,
rhs,
true))
3833 return !(lhs ==
rhs);
3838 template<
typename ScalarType,
typename std::enable_if<
3839 std::is_scalar<ScalarType>::value,
int>
::type = 0>
3847 template<
typename ScalarType,
typename std::enable_if<
3848 std::is_scalar<ScalarType>::value,
int>
::type = 0>
3866 template<
typename ScalarType,
typename std::enable_if<
3867 std::is_scalar<ScalarType>::value,
int>
::type = 0>
3875 template<
typename ScalarType,
typename std::enable_if<
3876 std::is_scalar<ScalarType>::value,
int>
::type = 0>
3886 if (compares_unordered(lhs,
rhs,
true))
3890 return !(
rhs < lhs);
3895 template<
typename ScalarType,
typename std::enable_if<
3896 std::is_scalar<ScalarType>::value,
int>
::type = 0>
3904 template<
typename ScalarType,
typename std::enable_if<
3905 std::is_scalar<ScalarType>::value,
int>
::type = 0>
3916 if (compares_unordered(lhs,
rhs))
3920 return !(lhs <=
rhs);
3925 template<
typename ScalarType,
typename std::enable_if<
3926 std::is_scalar<ScalarType>::value,
int>
::type = 0>
3934 template<
typename ScalarType,
typename std::enable_if<
3935 std::is_scalar<ScalarType>::value,
int>
::type = 0>
3945 if (compares_unordered(lhs,
rhs,
true))
3949 return !(lhs <
rhs);
3954 template<
typename ScalarType,
typename std::enable_if<
3955 std::is_scalar<ScalarType>::value,
int>
::type = 0>
3963 template<
typename ScalarType,
typename std::enable_if<
3964 std::is_scalar<ScalarType>::value,
int>
::type = 0>
3971#undef JSON_IMPLEMENT_OPERATOR
3987 const bool pretty_print = o.width() > 0;
3988 const auto indentation = pretty_print ? o.width() : 0;
3995 s.dump(j, pretty_print,
false,
static_cast<unsigned int>(indentation));
4029 template<
typename InputType>
4033 const bool allow_exceptions =
true,
4034 const bool ignore_comments =
false)
4037 parser(
detail::input_adapter(std::forward<InputType>(i)), cb, allow_exceptions, ignore_comments).parse(
true, result);
4043 template<
typename IteratorType>
4048 const bool allow_exceptions =
true,
4049 const bool ignore_comments =
false)
4060 const bool allow_exceptions =
true,
4061 const bool ignore_comments =
false)
4064 parser(i.get(), cb, allow_exceptions, ignore_comments).parse(
true, result);
4070 template<
typename InputType>
4071 static bool accept(InputType&& i,
4072 const bool ignore_comments =
false)
4074 return parser(
detail::input_adapter(std::forward<InputType>(i)),
nullptr,
false, ignore_comments).accept(
true);
4079 template<
typename IteratorType>
4080 static bool accept(IteratorType
first, IteratorType last,
4081 const bool ignore_comments =
false)
4089 const bool ignore_comments =
false)
4091 return parser(i.get(),
nullptr,
false, ignore_comments).accept(
true);
4096 template <
typename InputType,
typename SAX>
4100 const
bool strict = true,
4101 const
bool ignore_comments = false)
4105 ? parser(std::move(ia),
nullptr,
true, ignore_comments).sax_parse(sax, strict)
4111 template<
class IteratorType,
class SAX>
4115 const
bool strict = true,
4116 const
bool ignore_comments = false)
4120 ? parser(std::move(ia),
nullptr,
true, ignore_comments).sax_parse(sax, strict)
4129 template <
typename SAX>
4134 const
bool strict = true,
4135 const
bool ignore_comments = false)
4140 ? parser(std::move(ia),
nullptr,
true, ignore_comments).sax_parse(sax, strict)
4229 std::vector<std::uint8_t> result;
4238 binary_writer<std::uint8_t>(o).write_cbor(j);
4245 binary_writer<char>(o).write_cbor(j);
4252 std::vector<std::uint8_t> result;
4261 binary_writer<std::uint8_t>(o).write_msgpack(j);
4268 binary_writer<char>(o).write_msgpack(j);
4274 const bool use_size =
false,
4275 const bool use_type =
false)
4277 std::vector<std::uint8_t> result;
4278 to_ubjson(j, result, use_size, use_type);
4285 const bool use_size =
false,
const bool use_type =
false)
4287 binary_writer<std::uint8_t>(o).write_ubjson(j, use_size, use_type);
4293 const bool use_size =
false,
const bool use_type =
false)
4295 binary_writer<char>(o).write_ubjson(j, use_size, use_type);
4301 const bool use_size =
false,
4302 const bool use_type =
false)
4304 std::vector<std::uint8_t> result;
4305 to_bjdata(j, result, use_size, use_type);
4312 const bool use_size =
false,
const bool use_type =
false)
4314 binary_writer<std::uint8_t>(o).write_ubjson(j, use_size, use_type,
true,
true);
4320 const bool use_size =
false,
const bool use_type =
false)
4322 binary_writer<char>(o).write_ubjson(j, use_size, use_type,
true,
true);
4329 std::vector<std::uint8_t> result;
4338 binary_writer<std::uint8_t>(o).write_bson(j);
4345 binary_writer<char>(o).write_bson(j);
4350 template<
typename InputType>
4353 const bool strict =
true,
4354 const bool allow_exceptions =
true,
4360 const bool res = binary_reader<decltype(ia)>(std::move(ia), input_format_t::cbor).sax_parse(input_format_t::cbor, &sdp, strict, tag_handler);
4366 template<
typename IteratorType>
4369 const bool strict =
true,
4370 const bool allow_exceptions =
true,
4376 const bool res = binary_reader<decltype(ia)>(std::move(ia), input_format_t::cbor).sax_parse(input_format_t::cbor, &sdp, strict, tag_handler);
4380 template<
typename T>
4384 const
bool strict = true,
4385 const
bool allow_exceptions = true,
4388 return from_cbor(
ptr,
ptr + len, strict, allow_exceptions, tag_handler);
4395 const
bool strict = true,
4396 const
bool allow_exceptions = true,
4403 const bool res = binary_reader<decltype(ia)>(std::move(ia), input_format_t::cbor).sax_parse(input_format_t::cbor, &sdp, strict, tag_handler);
4409 template<
typename InputType>
4412 const bool strict =
true,
4413 const bool allow_exceptions =
true)
4418 const bool res = binary_reader<decltype(ia)>(std::move(ia), input_format_t::msgpack).sax_parse(input_format_t::msgpack, &sdp, strict);
4424 template<
typename IteratorType>
4427 const bool strict =
true,
4428 const bool allow_exceptions =
true)
4433 const bool res = binary_reader<decltype(ia)>(std::move(ia), input_format_t::msgpack).sax_parse(input_format_t::msgpack, &sdp, strict);
4437 template<
typename T>
4441 const
bool strict = true,
4442 const
bool allow_exceptions = true)
4450 const
bool strict = true,
4451 const
bool allow_exceptions = true)
4457 const bool res = binary_reader<decltype(ia)>(std::move(ia), input_format_t::msgpack).sax_parse(input_format_t::msgpack, &sdp, strict);
4463 template<
typename InputType>
4466 const bool strict =
true,
4467 const bool allow_exceptions =
true)
4472 const bool res = binary_reader<decltype(ia)>(std::move(ia), input_format_t::ubjson).sax_parse(input_format_t::ubjson, &sdp, strict);
4478 template<
typename IteratorType>
4481 const bool strict =
true,
4482 const bool allow_exceptions =
true)
4487 const bool res = binary_reader<decltype(ia)>(std::move(ia), input_format_t::ubjson).sax_parse(input_format_t::ubjson, &sdp, strict);
4491 template<
typename T>
4495 const
bool strict = true,
4496 const
bool allow_exceptions = true)
4504 const
bool strict = true,
4505 const
bool allow_exceptions = true)
4511 const bool res = binary_reader<decltype(ia)>(std::move(ia), input_format_t::ubjson).sax_parse(input_format_t::ubjson, &sdp, strict);
4518 template<
typename InputType>
4521 const bool strict =
true,
4522 const bool allow_exceptions =
true)
4527 const bool res = binary_reader<decltype(ia)>(std::move(ia), input_format_t::bjdata).sax_parse(input_format_t::bjdata, &sdp, strict);
4533 template<
typename IteratorType>
4536 const bool strict =
true,
4537 const bool allow_exceptions =
true)
4542 const bool res = binary_reader<decltype(ia)>(std::move(ia), input_format_t::bjdata).sax_parse(input_format_t::bjdata, &sdp, strict);
4548 template<
typename InputType>
4551 const bool strict =
true,
4552 const bool allow_exceptions =
true)
4557 const bool res = binary_reader<decltype(ia)>(std::move(ia), input_format_t::bson).sax_parse(input_format_t::bson, &sdp, strict);
4563 template<
typename IteratorType>
4566 const bool strict =
true,
4567 const bool allow_exceptions =
true)
4572 const bool res = binary_reader<decltype(ia)>(std::move(ia), input_format_t::bson).sax_parse(input_format_t::bson, &sdp, strict);
4576 template<
typename T>
4580 const
bool strict = true,
4581 const
bool allow_exceptions = true)
4589 const
bool strict = true,
4590 const
bool allow_exceptions = true)
4596 const bool res = binary_reader<decltype(ia)>(std::move(ia), input_format_t::bson).sax_parse(input_format_t::bson, &sdp, strict);
4612 return ptr.get_unchecked(
this);
4615 template<typename BasicJsonType, detail::enable_if_t<detail::is_basic_json<BasicJsonType>::value,
int> = 0>
4619 return ptr.get_unchecked(
this);
4626 return ptr.get_unchecked(
this);
4629 template<typename BasicJsonType, detail::enable_if_t<detail::is_basic_json<BasicJsonType>::value,
int> = 0>
4633 return ptr.get_unchecked(
this);
4640 return ptr.get_checked(
this);
4643 template<typename BasicJsonType, detail::enable_if_t<detail::is_basic_json<BasicJsonType>::value,
int> = 0>
4647 return ptr.get_checked(
this);
4654 return ptr.get_checked(
this);
4657 template<typename BasicJsonType, detail::enable_if_t<detail::is_basic_json<BasicJsonType>::value,
int> = 0>
4661 return ptr.get_checked(
this);
4669 json_pointer::flatten(
"", *
this, result);
4677 return json_pointer::unflatten(*
this);
4691 void patch_inplace(
const basic_json& json_patch)
4695 enum class patch_operations {add, remove,
replace, move,
copy, test, invalid};
4697 const auto get_op = [](
const std::string & op)
4701 return patch_operations::add;
4705 return patch_operations::remove;
4707 if (op ==
"replace")
4709 return patch_operations::replace;
4713 return patch_operations::move;
4721 return patch_operations::test;
4724 return patch_operations::invalid;
4739 if (top_pointer !=
ptr)
4741 result.
at(top_pointer);
4745 const auto last_path =
ptr.back();
4750 switch (parent.m_type)
4756 parent[last_path] = val;
4762 if (last_path ==
"-")
4769 const auto idx = json_pointer::template array_index<basic_json_t>(last_path);
4799 const auto last_path =
ptr.back();
4807 auto it = parent.
find(last_path);
4820 parent.
erase(json_pointer::template array_index<basic_json_t>(last_path));
4831 for (
const auto& val : json_patch)
4834 const auto get_value = [&val](
const std::string & op,
4835 const std::string & member,
4839 auto it = val.
m_value.object->find(member);
4842 const auto error_msg = (op ==
"op") ?
"operation" :
detail::concat(
"operation '", op,
'\'');
4869 const auto op = get_value(
"op",
"op",
true).template get<std::string>();
4870 const auto path = get_value(op,
"path",
true).template get<std::string>();
4875 case patch_operations::add:
4877 operation_add(
ptr, get_value(
"add",
"value",
false));
4881 case patch_operations::remove:
4883 operation_remove(
ptr);
4887 case patch_operations::replace:
4890 result.
at(
ptr) = get_value(
"replace",
"value",
false);
4894 case patch_operations::move:
4896 const auto from_path = get_value(
"move",
"from",
true).template get<std::string>();
4906 operation_remove(from_ptr);
4907 operation_add(
ptr, v);
4913 const auto from_path = get_value(
"copy",
"from",
true).template get<std::string>();
4922 operation_add(
ptr, v);
4926 case patch_operations::test:
4928 bool success =
false;
4933 success = (result.
at(
ptr) == get_value(
"test",
"value",
false));
4949 case patch_operations::invalid:
4965 result.patch_inplace(json_patch);
4973 const std::string& path =
"")
4989 {
"op",
"replace"}, {
"path", path}, {
"value", target}
5000 while (i <
source.size() && i < target.size())
5004 result.
insert(result.end(), temp_diff.begin(), temp_diff.end());
5013 while (i <
source.size())
5026 while (i < target.size())
5032 {
"value", target[i]}
5043 for (
auto it =
source.cbegin(); it !=
source.cend(); ++it)
5048 if (target.
find(it.key()) != target.end())
5051 auto temp_diff =
diff(it.value(), target[it.key()], path_key);
5052 result.
insert(result.end(), temp_diff.begin(), temp_diff.end());
5059 {
"op",
"remove"}, {
"path", path_key}
5065 for (
auto it = target.cbegin(); it != target.cend(); ++it)
5073 {
"op",
"add"}, {
"path", path_key},
5074 {
"value", it.value()}
5095 {
"op",
"replace"}, {
"path", path}, {
"value", target}
5122 for (
auto it = apply_patch.begin(); it != apply_patch.end(); ++it)
5124 if (it.value().is_null())
5136 *
this = apply_patch;
5153inline namespace json_literals
5161 return wpi::json::parse(s, s + n);
5190 return wpi::detail::hash(j);
5205#if JSON_HAS_THREE_WAY_COMPARISON
5206 return std::is_lt(lhs <=> rhs);