Horizon
json.hpp
1 /*
2  __ _____ _____ _____
3  __| | __| | | | JSON for Modern C++
4 | | |__ | | | | | | version 3.9.1
5 |_____|_____|_____|_|___| https://github.com/nlohmann/json
6 
7 Licensed under the MIT License <http://opensource.org/licenses/MIT>.
8 SPDX-License-Identifier: MIT
9 Copyright (c) 2013-2019 Niels Lohmann <http://nlohmann.me>.
10 
11 Permission is hereby granted, free of charge, to any person obtaining a copy
12 of this software and associated documentation files (the "Software"), to deal
13 in the Software without restriction, including without limitation the rights
14 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
15 copies of the Software, and to permit persons to whom the Software is
16 furnished to do so, subject to the following conditions:
17 
18 The above copyright notice and this permission notice shall be included in all
19 copies or substantial portions of the Software.
20 
21 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
22 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
23 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
24 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
25 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
26 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
27 SOFTWARE.
28 */
29 
30 #ifndef INCLUDE_NLOHMANN_JSON_HPP_
31 #define INCLUDE_NLOHMANN_JSON_HPP_
32 
33 #define NLOHMANN_JSON_VERSION_MAJOR 3
34 #define NLOHMANN_JSON_VERSION_MINOR 9
35 #define NLOHMANN_JSON_VERSION_PATCH 1
36 
37 #include <algorithm> // all_of, find, for_each
38 #include <cstddef> // nullptr_t, ptrdiff_t, size_t
39 #include <functional> // hash, less
40 #include <initializer_list> // initializer_list
41 #include <iosfwd> // istream, ostream
42 #include <iterator> // random_access_iterator_tag
43 #include <memory> // unique_ptr
44 #include <numeric> // accumulate
45 #include <string> // string, stoi, to_string
46 #include <utility> // declval, forward, move, pair, swap
47 #include <vector> // vector
48 
49 #include <nlohmann/adl_serializer.hpp>
50 #include <nlohmann/byte_container_with_subtype.hpp>
51 #include <nlohmann/detail/conversions/from_json.hpp>
52 #include <nlohmann/detail/conversions/to_json.hpp>
53 #include <nlohmann/detail/exceptions.hpp>
54 #include <nlohmann/detail/hash.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>
74 #include <nlohmann/ordered_map.hpp>
75 
81 namespace nlohmann
82 {
83 
168 NLOHMANN_BASIC_JSON_TPL_DECLARATION
170 {
171  private:
172  template<detail::value_t> friend struct detail::external_constructor;
173  friend ::nlohmann::json_pointer<basic_json>;
174 
175  template<typename BasicJsonType, typename InputType>
176  friend class ::nlohmann::detail::parser;
177  friend ::nlohmann::detail::serializer<basic_json>;
178  template<typename BasicJsonType>
179  friend class ::nlohmann::detail::iter_impl;
180  template<typename BasicJsonType, typename CharType>
181  friend class ::nlohmann::detail::binary_writer;
182  template<typename BasicJsonType, typename InputType, typename SAX>
183  friend class ::nlohmann::detail::binary_reader;
184  template<typename BasicJsonType>
185  friend class ::nlohmann::detail::json_sax_dom_parser;
186  template<typename BasicJsonType>
187  friend class ::nlohmann::detail::json_sax_dom_callback_parser;
188 
190  using basic_json_t = NLOHMANN_BASIC_JSON_TPL;
191 
192  // convenience aliases for types residing in namespace detail;
194 
195  template<typename InputAdapterType>
196  static ::nlohmann::detail::parser<basic_json, InputAdapterType> parser(
197  InputAdapterType adapter,
198  detail::parser_callback_t<basic_json>cb = nullptr,
199  const bool allow_exceptions = true,
200  const bool ignore_comments = false
201  )
202  {
203  return ::nlohmann::detail::parser<basic_json, InputAdapterType>(std::move(adapter),
204  std::move(cb), allow_exceptions, ignore_comments);
205  }
206 
208  template<typename BasicJsonType>
210  template<typename BasicJsonType>
212  template<typename Iterator>
215 
216  template<typename CharType>
217  using output_adapter_t = ::nlohmann::detail::output_adapter_t<CharType>;
218 
219  template<typename InputType>
222 
224 
225  public:
226  using value_t = detail::value_t;
229  template<typename T, typename SFINAE>
230  using json_serializer = JSONSerializer<T, SFINAE>;
236  using initializer_list_t = std::initializer_list<detail::json_ref<basic_json>>;
237 
241 
243  // exceptions //
245 
249 
262 
264 
265 
267  // container types //
269 
274 
277 
281  using const_reference = const value_type&;
282 
284  using difference_type = std::ptrdiff_t;
286  using size_type = std::size_t;
287 
289  using allocator_type = AllocatorType<basic_json>;
290 
292  using pointer = typename std::allocator_traits<allocator_type>::pointer;
294  using const_pointer = typename std::allocator_traits<allocator_type>::const_pointer;
295 
304 
306 
307 
312  {
313  return allocator_type();
314  }
315 
342  JSON_HEDLEY_WARN_UNUSED_RESULT
343  static basic_json meta()
344  {
345  basic_json result;
346 
347  result["copyright"] = "(C) 2013-2020 Niels Lohmann";
348  result["name"] = "JSON for Modern C++";
349  result["url"] = "https://github.com/nlohmann/json";
350  result["version"]["string"] =
351  std::to_string(NLOHMANN_JSON_VERSION_MAJOR) + "." +
352  std::to_string(NLOHMANN_JSON_VERSION_MINOR) + "." +
353  std::to_string(NLOHMANN_JSON_VERSION_PATCH);
354  result["version"]["major"] = NLOHMANN_JSON_VERSION_MAJOR;
355  result["version"]["minor"] = NLOHMANN_JSON_VERSION_MINOR;
356  result["version"]["patch"] = NLOHMANN_JSON_VERSION_PATCH;
357 
358 #ifdef _WIN32
359  result["platform"] = "win32";
360 #elif defined __linux__
361  result["platform"] = "linux";
362 #elif defined __APPLE__
363  result["platform"] = "apple";
364 #elif defined __unix__
365  result["platform"] = "unix";
366 #else
367  result["platform"] = "unknown";
368 #endif
369 
370 #if defined(__ICC) || defined(__INTEL_COMPILER)
371  result["compiler"] = {{"family", "icc"}, {"version", __INTEL_COMPILER}};
372 #elif defined(__clang__)
373  result["compiler"] = {{"family", "clang"}, {"version", __clang_version__}};
374 #elif defined(__GNUC__) || defined(__GNUG__)
375  result["compiler"] = {{"family", "gcc"}, {"version", std::to_string(__GNUC__) + "." + std::to_string(__GNUC_MINOR__) + "." + std::to_string(__GNUC_PATCHLEVEL__)}};
376 #elif defined(__HP_cc) || defined(__HP_aCC)
377  result["compiler"] = "hp"
378 #elif defined(__IBMCPP__)
379  result["compiler"] = {{"family", "ilecpp"}, {"version", __IBMCPP__}};
380 #elif defined(_MSC_VER)
381  result["compiler"] = {{"family", "msvc"}, {"version", _MSC_VER}};
382 #elif defined(__PGI)
383  result["compiler"] = {{"family", "pgcpp"}, {"version", __PGI}};
384 #elif defined(__SUNPRO_CC)
385  result["compiler"] = {{"family", "sunpro"}, {"version", __SUNPRO_CC}};
386 #else
387  result["compiler"] = {{"family", "unknown"}, {"version", "unknown"}};
388 #endif
389 
390 #ifdef __cplusplus
391  result["compiler"]["c++"] = std::to_string(__cplusplus);
392 #else
393  result["compiler"]["c++"] = "unknown";
394 #endif
395  return result;
396  }
397 
398 
400  // JSON value data types //
402 
407 
408 #if defined(JSON_HAS_CPP_14)
409  // Use transparent comparator if possible, combined with perfect forwarding
410  // on find() and count() calls prevents unnecessary string construction.
411  using object_comparator_t = std::less<>;
412 #else
413  using object_comparator_t = std::less<StringType>;
414 #endif
415 
499  using object_t = ObjectType<StringType,
500  basic_json,
501  object_comparator_t,
502  AllocatorType<std::pair<const StringType,
503  basic_json>>>;
504 
549  using array_t = ArrayType<basic_json, AllocatorType<basic_json>>;
550 
602  using string_t = StringType;
603 
628  using boolean_t = BooleanType;
629 
700  using number_integer_t = NumberIntegerType;
701 
771  using number_unsigned_t = NumberUnsignedType;
772 
839  using number_float_t = NumberFloatType;
840 
912 
913  private:
914 
916  template<typename T, typename... Args>
917  JSON_HEDLEY_RETURNS_NON_NULL
918  static T* create(Args&& ... args)
919  {
920  AllocatorType<T> alloc;
921  using AllocatorTraits = std::allocator_traits<AllocatorType<T>>;
922 
923  auto deleter = [&](T * object)
924  {
925  AllocatorTraits::deallocate(alloc, object, 1);
926  };
927  std::unique_ptr<T, decltype(deleter)> object(AllocatorTraits::allocate(alloc, 1), deleter);
928  AllocatorTraits::construct(alloc, object.get(), std::forward<Args>(args)...);
929  JSON_ASSERT(object != nullptr);
930  return object.release();
931  }
932 
934  // JSON value storage //
936 
962  union json_value
963  {
965  object_t* object;
967  array_t* array;
969  string_t* string;
971  binary_t* binary;
973  boolean_t boolean;
975  number_integer_t number_integer;
977  number_unsigned_t number_unsigned;
979  number_float_t number_float;
980 
982  json_value() = default;
984  json_value(boolean_t v) noexcept : boolean(v) {}
986  json_value(number_integer_t v) noexcept : number_integer(v) {}
988  json_value(number_unsigned_t v) noexcept : number_unsigned(v) {}
990  json_value(number_float_t v) noexcept : number_float(v) {}
992  json_value(value_t t)
993  {
994  switch (t)
995  {
996  case value_t::object:
997  {
998  object = create<object_t>();
999  break;
1000  }
1001 
1002  case value_t::array:
1003  {
1004  array = create<array_t>();
1005  break;
1006  }
1007 
1008  case value_t::string:
1009  {
1010  string = create<string_t>("");
1011  break;
1012  }
1013 
1014  case value_t::binary:
1015  {
1016  binary = create<binary_t>();
1017  break;
1018  }
1019 
1020  case value_t::boolean:
1021  {
1022  boolean = boolean_t(false);
1023  break;
1024  }
1025 
1027  {
1029  break;
1030  }
1031 
1033  {
1035  break;
1036  }
1037 
1038  case value_t::number_float:
1039  {
1041  break;
1042  }
1043 
1044  case value_t::null:
1045  {
1046  object = nullptr; // silence warning, see #821
1047  break;
1048  }
1049 
1050  default:
1051  {
1052  object = nullptr; // silence warning, see #821
1053  if (JSON_HEDLEY_UNLIKELY(t == value_t::null))
1054  {
1055  JSON_THROW(other_error::create(500, "961c151d2e87f2686a955a9be24d316f1362bf21 3.9.1")); // LCOV_EXCL_LINE
1056  }
1057  break;
1058  }
1059  }
1060  }
1061 
1063  json_value(const string_t& value)
1064  {
1065  string = create<string_t>(value);
1066  }
1067 
1069  json_value(string_t&& value)
1070  {
1071  string = create<string_t>(std::move(value));
1072  }
1073 
1075  json_value(const object_t& value)
1076  {
1077  object = create<object_t>(value);
1078  }
1079 
1081  json_value(object_t&& value)
1082  {
1083  object = create<object_t>(std::move(value));
1084  }
1085 
1087  json_value(const array_t& value)
1088  {
1089  array = create<array_t>(value);
1090  }
1091 
1093  json_value(array_t&& value)
1094  {
1095  array = create<array_t>(std::move(value));
1096  }
1097 
1099  json_value(const typename binary_t::container_type& value)
1100  {
1101  binary = create<binary_t>(value);
1102  }
1103 
1105  json_value(typename binary_t::container_type&& value)
1106  {
1107  binary = create<binary_t>(std::move(value));
1108  }
1109 
1111  json_value(const binary_t& value)
1112  {
1113  binary = create<binary_t>(value);
1114  }
1115 
1117  json_value(binary_t&& value)
1118  {
1119  binary = create<binary_t>(std::move(value));
1120  }
1121 
1122  void destroy(value_t t) noexcept
1123  {
1124  // flatten the current json_value to a heap-allocated stack
1125  std::vector<basic_json> stack;
1126 
1127  // move the top-level items to stack
1128  if (t == value_t::array)
1129  {
1130  stack.reserve(array->size());
1131  std::move(array->begin(), array->end(), std::back_inserter(stack));
1132  }
1133  else if (t == value_t::object)
1134  {
1135  stack.reserve(object->size());
1136  for (auto&& it : *object)
1137  {
1138  stack.push_back(std::move(it.second));
1139  }
1140  }
1141 
1142  while (!stack.empty())
1143  {
1144  // move the last item to local variable to be processed
1145  basic_json current_item(std::move(stack.back()));
1146  stack.pop_back();
1147 
1148  // if current_item is array/object, move
1149  // its children to the stack to be processed later
1150  if (current_item.is_array())
1151  {
1152  std::move(current_item.m_value.array->begin(), current_item.m_value.array->end(),
1153  std::back_inserter(stack));
1154 
1155  current_item.m_value.array->clear();
1156  }
1157  else if (current_item.is_object())
1158  {
1159  for (auto&& it : *current_item.m_value.object)
1160  {
1161  stack.push_back(std::move(it.second));
1162  }
1163 
1164  current_item.m_value.object->clear();
1165  }
1166 
1167  // it's now safe that current_item get destructed
1168  // since it doesn't have any children
1169  }
1170 
1171  switch (t)
1172  {
1173  case value_t::object:
1174  {
1175  AllocatorType<object_t> alloc;
1176  std::allocator_traits<decltype(alloc)>::destroy(alloc, object);
1177  std::allocator_traits<decltype(alloc)>::deallocate(alloc, object, 1);
1178  break;
1179  }
1180 
1181  case value_t::array:
1182  {
1183  AllocatorType<array_t> alloc;
1184  std::allocator_traits<decltype(alloc)>::destroy(alloc, array);
1185  std::allocator_traits<decltype(alloc)>::deallocate(alloc, array, 1);
1186  break;
1187  }
1188 
1189  case value_t::string:
1190  {
1191  AllocatorType<string_t> alloc;
1192  std::allocator_traits<decltype(alloc)>::destroy(alloc, string);
1193  std::allocator_traits<decltype(alloc)>::deallocate(alloc, string, 1);
1194  break;
1195  }
1196 
1197  case value_t::binary:
1198  {
1199  AllocatorType<binary_t> alloc;
1200  std::allocator_traits<decltype(alloc)>::destroy(alloc, binary);
1201  std::allocator_traits<decltype(alloc)>::deallocate(alloc, binary, 1);
1202  break;
1203  }
1204 
1205  default:
1206  {
1207  break;
1208  }
1209  }
1210  }
1211  };
1212 
1222  void assert_invariant() const noexcept
1223  {
1224  JSON_ASSERT(m_type != value_t::object || m_value.object != nullptr);
1225  JSON_ASSERT(m_type != value_t::array || m_value.array != nullptr);
1226  JSON_ASSERT(m_type != value_t::string || m_value.string != nullptr);
1227  JSON_ASSERT(m_type != value_t::binary || m_value.binary != nullptr);
1228  }
1229 
1230  public:
1232  // JSON parser callback //
1234 
1251 
1301  using parser_callback_t = detail::parser_callback_t<basic_json>;
1302 
1304  // constructors //
1306 
1311 
1343  : m_type(v), m_value(v)
1344  {
1345  assert_invariant();
1346  }
1347 
1366  basic_json(std::nullptr_t = nullptr) noexcept
1367  : basic_json(value_t::null)
1368  {
1369  assert_invariant();
1370  }
1371 
1435  template < typename CompatibleType,
1436  typename U = detail::uncvref_t<CompatibleType>,
1437  detail::enable_if_t <
1439  basic_json(CompatibleType && val) noexcept(noexcept(
1440  JSONSerializer<U>::to_json(std::declval<basic_json_t&>(),
1441  std::forward<CompatibleType>(val))))
1442  {
1443  JSONSerializer<U>::to_json(*this, std::forward<CompatibleType>(val));
1444  assert_invariant();
1445  }
1446 
1473  template < typename BasicJsonType,
1474  detail::enable_if_t <
1475  detail::is_basic_json<BasicJsonType>::value&& !std::is_same<basic_json, BasicJsonType>::value, int > = 0 >
1476  basic_json(const BasicJsonType& val)
1477  {
1478  using other_boolean_t = typename BasicJsonType::boolean_t;
1479  using other_number_float_t = typename BasicJsonType::number_float_t;
1480  using other_number_integer_t = typename BasicJsonType::number_integer_t;
1481  using other_number_unsigned_t = typename BasicJsonType::number_unsigned_t;
1482  using other_string_t = typename BasicJsonType::string_t;
1483  using other_object_t = typename BasicJsonType::object_t;
1484  using other_array_t = typename BasicJsonType::array_t;
1485  using other_binary_t = typename BasicJsonType::binary_t;
1486 
1487  switch (val.type())
1488  {
1489  case value_t::boolean:
1490  JSONSerializer<other_boolean_t>::to_json(*this, val.template get<other_boolean_t>());
1491  break;
1492  case value_t::number_float:
1493  JSONSerializer<other_number_float_t>::to_json(*this, val.template get<other_number_float_t>());
1494  break;
1496  JSONSerializer<other_number_integer_t>::to_json(*this, val.template get<other_number_integer_t>());
1497  break;
1499  JSONSerializer<other_number_unsigned_t>::to_json(*this, val.template get<other_number_unsigned_t>());
1500  break;
1501  case value_t::string:
1502  JSONSerializer<other_string_t>::to_json(*this, val.template get_ref<const other_string_t&>());
1503  break;
1504  case value_t::object:
1505  JSONSerializer<other_object_t>::to_json(*this, val.template get_ref<const other_object_t&>());
1506  break;
1507  case value_t::array:
1508  JSONSerializer<other_array_t>::to_json(*this, val.template get_ref<const other_array_t&>());
1509  break;
1510  case value_t::binary:
1511  JSONSerializer<other_binary_t>::to_json(*this, val.template get_ref<const other_binary_t&>());
1512  break;
1513  case value_t::null:
1514  *this = nullptr;
1515  break;
1516  case value_t::discarded:
1517  m_type = value_t::discarded;
1518  break;
1519  default: // LCOV_EXCL_LINE
1520  JSON_ASSERT(false); // LCOV_EXCL_LINE
1521  }
1522  assert_invariant();
1523  }
1524 
1600  bool type_deduction = true,
1601  value_t manual_type = value_t::array)
1602  {
1603  // check if each element is an array with two elements whose first
1604  // element is a string
1605  bool is_an_object = std::all_of(init.begin(), init.end(),
1606  [](const detail::json_ref<basic_json>& element_ref)
1607  {
1608  return element_ref->is_array() && element_ref->size() == 2 && (*element_ref)[0].is_string();
1609  });
1610 
1611  // adjust type if type deduction is not wanted
1612  if (!type_deduction)
1613  {
1614  // if array is wanted, do not create an object though possible
1615  if (manual_type == value_t::array)
1616  {
1617  is_an_object = false;
1618  }
1619 
1620  // if object is wanted but impossible, throw an exception
1621  if (JSON_HEDLEY_UNLIKELY(manual_type == value_t::object && !is_an_object))
1622  {
1623  JSON_THROW(type_error::create(301, "cannot create object from initializer list"));
1624  }
1625  }
1626 
1627  if (is_an_object)
1628  {
1629  // the initializer list is a list of pairs -> create object
1630  m_type = value_t::object;
1631  m_value = value_t::object;
1632 
1633  std::for_each(init.begin(), init.end(), [this](const detail::json_ref<basic_json>& element_ref)
1634  {
1635  auto element = element_ref.moved_or_copied();
1636  m_value.object->emplace(
1637  std::move(*((*element.m_value.array)[0].m_value.string)),
1638  std::move((*element.m_value.array)[1]));
1639  });
1640  }
1641  else
1642  {
1643  // the initializer list describes an array -> create array
1644  m_type = value_t::array;
1645  m_value.array = create<array_t>(init.begin(), init.end());
1646  }
1647 
1648  assert_invariant();
1649  }
1650 
1678  JSON_HEDLEY_WARN_UNUSED_RESULT
1679  static basic_json binary(const typename binary_t::container_type& init)
1680  {
1681  auto res = basic_json();
1682  res.m_type = value_t::binary;
1683  res.m_value = init;
1684  return res;
1685  }
1686 
1715  JSON_HEDLEY_WARN_UNUSED_RESULT
1716  static basic_json binary(const typename binary_t::container_type& init, std::uint8_t subtype)
1717  {
1718  auto res = basic_json();
1719  res.m_type = value_t::binary;
1720  res.m_value = binary_t(init, subtype);
1721  return res;
1722  }
1723 
1725  JSON_HEDLEY_WARN_UNUSED_RESULT
1727  {
1728  auto res = basic_json();
1729  res.m_type = value_t::binary;
1730  res.m_value = std::move(init);
1731  return res;
1732  }
1733 
1735  JSON_HEDLEY_WARN_UNUSED_RESULT
1736  static basic_json binary(typename binary_t::container_type&& init, std::uint8_t subtype)
1737  {
1738  auto res = basic_json();
1739  res.m_type = value_t::binary;
1740  res.m_value = binary_t(std::move(init), subtype);
1741  return res;
1742  }
1743 
1781  JSON_HEDLEY_WARN_UNUSED_RESULT
1783  {
1784  return basic_json(init, false, value_t::array);
1785  }
1786 
1825  JSON_HEDLEY_WARN_UNUSED_RESULT
1827  {
1828  return basic_json(init, false, value_t::object);
1829  }
1830 
1854  : m_type(value_t::array)
1855  {
1856  m_value.array = create<array_t>(cnt, val);
1857  assert_invariant();
1858  }
1859 
1915  template < class InputIT, typename std::enable_if <
1916  std::is_same<InputIT, typename basic_json_t::iterator>::value ||
1917  std::is_same<InputIT, typename basic_json_t::const_iterator>::value, int >::type = 0 >
1918  basic_json(InputIT first, InputIT last)
1919  {
1920  JSON_ASSERT(first.m_object != nullptr);
1921  JSON_ASSERT(last.m_object != nullptr);
1922 
1923  // make sure iterator fits the current value
1924  if (JSON_HEDLEY_UNLIKELY(first.m_object != last.m_object))
1925  {
1926  JSON_THROW(invalid_iterator::create(201, "iterators are not compatible"));
1927  }
1928 
1929  // copy type from first iterator
1930  m_type = first.m_object->m_type;
1931 
1932  // check if iterator range is complete for primitive values
1933  switch (m_type)
1934  {
1935  case value_t::boolean:
1936  case value_t::number_float:
1939  case value_t::string:
1940  {
1941  if (JSON_HEDLEY_UNLIKELY(!first.m_it.primitive_iterator.is_begin()
1942  || !last.m_it.primitive_iterator.is_end()))
1943  {
1944  JSON_THROW(invalid_iterator::create(204, "iterators out of range"));
1945  }
1946  break;
1947  }
1948 
1949  default:
1950  break;
1951  }
1952 
1953  switch (m_type)
1954  {
1956  {
1957  m_value.number_integer = first.m_object->m_value.number_integer;
1958  break;
1959  }
1960 
1962  {
1963  m_value.number_unsigned = first.m_object->m_value.number_unsigned;
1964  break;
1965  }
1966 
1967  case value_t::number_float:
1968  {
1969  m_value.number_float = first.m_object->m_value.number_float;
1970  break;
1971  }
1972 
1973  case value_t::boolean:
1974  {
1975  m_value.boolean = first.m_object->m_value.boolean;
1976  break;
1977  }
1978 
1979  case value_t::string:
1980  {
1981  m_value = *first.m_object->m_value.string;
1982  break;
1983  }
1984 
1985  case value_t::object:
1986  {
1987  m_value.object = create<object_t>(first.m_it.object_iterator,
1988  last.m_it.object_iterator);
1989  break;
1990  }
1991 
1992  case value_t::array:
1993  {
1994  m_value.array = create<array_t>(first.m_it.array_iterator,
1995  last.m_it.array_iterator);
1996  break;
1997  }
1998 
1999  case value_t::binary:
2000  {
2001  m_value = *first.m_object->m_value.binary;
2002  break;
2003  }
2004 
2005  default:
2006  JSON_THROW(invalid_iterator::create(206, "cannot construct with iterators from " +
2007  std::string(first.m_object->type_name())));
2008  }
2009 
2010  assert_invariant();
2011  }
2012 
2013 
2015  // other constructors and destructor //
2017 
2018  template<typename JsonRef,
2019  detail::enable_if_t<detail::conjunction<detail::is_json_ref<JsonRef>,
2020  std::is_same<typename JsonRef::value_type, basic_json>>::value, int> = 0 >
2021  basic_json(const JsonRef& ref) : basic_json(ref.moved_or_copied()) {}
2022 
2048  basic_json(const basic_json& other)
2049  : m_type(other.m_type)
2050  {
2051  // check of passed value is valid
2052  other.assert_invariant();
2053 
2054  switch (m_type)
2055  {
2056  case value_t::object:
2057  {
2058  m_value = *other.m_value.object;
2059  break;
2060  }
2061 
2062  case value_t::array:
2063  {
2064  m_value = *other.m_value.array;
2065  break;
2066  }
2067 
2068  case value_t::string:
2069  {
2070  m_value = *other.m_value.string;
2071  break;
2072  }
2073 
2074  case value_t::boolean:
2075  {
2076  m_value = other.m_value.boolean;
2077  break;
2078  }
2079 
2081  {
2082  m_value = other.m_value.number_integer;
2083  break;
2084  }
2085 
2087  {
2088  m_value = other.m_value.number_unsigned;
2089  break;
2090  }
2091 
2092  case value_t::number_float:
2093  {
2094  m_value = other.m_value.number_float;
2095  break;
2096  }
2097 
2098  case value_t::binary:
2099  {
2100  m_value = *other.m_value.binary;
2101  break;
2102  }
2103 
2104  default:
2105  break;
2106  }
2107 
2108  assert_invariant();
2109  }
2110 
2137  basic_json(basic_json&& other) noexcept
2138  : m_type(std::move(other.m_type)),
2139  m_value(std::move(other.m_value))
2140  {
2141  // check that passed value is valid
2142  other.assert_invariant();
2143 
2144  // invalidate payload
2145  other.m_type = value_t::null;
2146  other.m_value = {};
2147 
2148  assert_invariant();
2149  }
2150 
2174  basic_json& operator=(basic_json other) noexcept (
2175  std::is_nothrow_move_constructible<value_t>::value&&
2176  std::is_nothrow_move_assignable<value_t>::value&&
2177  std::is_nothrow_move_constructible<json_value>::value&&
2178  std::is_nothrow_move_assignable<json_value>::value
2179  )
2180  {
2181  // check that passed value is valid
2182  other.assert_invariant();
2183 
2184  using std::swap;
2185  swap(m_type, other.m_type);
2186  swap(m_value, other.m_value);
2187 
2188  assert_invariant();
2189  return *this;
2190  }
2191 
2207  ~basic_json() noexcept
2208  {
2209  assert_invariant();
2210  m_value.destroy(m_type);
2211  }
2212 
2214 
2215  public:
2217  // object inspection //
2219 
2223 
2271  string_t dump(const int indent = -1,
2272  const char indent_char = ' ',
2273  const bool ensure_ascii = false,
2274  const error_handler_t error_handler = error_handler_t::strict) const
2275  {
2276  string_t result;
2277  serializer s(detail::output_adapter<char, string_t>(result), indent_char, error_handler);
2278 
2279  if (indent >= 0)
2280  {
2281  s.dump(*this, true, ensure_ascii, static_cast<unsigned int>(indent));
2282  }
2283  else
2284  {
2285  s.dump(*this, false, ensure_ascii, 0);
2286  }
2287 
2288  return result;
2289  }
2290 
2324  constexpr value_t type() const noexcept
2325  {
2326  return m_type;
2327  }
2328 
2355  constexpr bool is_primitive() const noexcept
2356  {
2357  return is_null() || is_string() || is_boolean() || is_number() || is_binary();
2358  }
2359 
2382  constexpr bool is_structured() const noexcept
2383  {
2384  return is_array() || is_object();
2385  }
2386 
2404  constexpr bool is_null() const noexcept
2405  {
2406  return m_type == value_t::null;
2407  }
2408 
2426  constexpr bool is_boolean() const noexcept
2427  {
2428  return m_type == value_t::boolean;
2429  }
2430 
2456  constexpr bool is_number() const noexcept
2457  {
2458  return is_number_integer() || is_number_float();
2459  }
2460 
2485  constexpr bool is_number_integer() const noexcept
2486  {
2487  return m_type == value_t::number_integer || m_type == value_t::number_unsigned;
2488  }
2489 
2513  constexpr bool is_number_unsigned() const noexcept
2514  {
2515  return m_type == value_t::number_unsigned;
2516  }
2517 
2541  constexpr bool is_number_float() const noexcept
2542  {
2543  return m_type == value_t::number_float;
2544  }
2545 
2563  constexpr bool is_object() const noexcept
2564  {
2565  return m_type == value_t::object;
2566  }
2567 
2585  constexpr bool is_array() const noexcept
2586  {
2587  return m_type == value_t::array;
2588  }
2589 
2607  constexpr bool is_string() const noexcept
2608  {
2609  return m_type == value_t::string;
2610  }
2611 
2629  constexpr bool is_binary() const noexcept
2630  {
2631  return m_type == value_t::binary;
2632  }
2633 
2656  constexpr bool is_discarded() const noexcept
2657  {
2658  return m_type == value_t::discarded;
2659  }
2660 
2682  constexpr operator value_t() const noexcept
2683  {
2684  return m_type;
2685  }
2686 
2688 
2689  private:
2691  // value access //
2693 
2695  boolean_t get_impl(boolean_t* /*unused*/) const
2696  {
2697  if (JSON_HEDLEY_LIKELY(is_boolean()))
2698  {
2699  return m_value.boolean;
2700  }
2701 
2702  JSON_THROW(type_error::create(302, "type must be boolean, but is " + std::string(type_name())));
2703  }
2704 
2706  object_t* get_impl_ptr(object_t* /*unused*/) noexcept
2707  {
2708  return is_object() ? m_value.object : nullptr;
2709  }
2710 
2712  constexpr const object_t* get_impl_ptr(const object_t* /*unused*/) const noexcept
2713  {
2714  return is_object() ? m_value.object : nullptr;
2715  }
2716 
2718  array_t* get_impl_ptr(array_t* /*unused*/) noexcept
2719  {
2720  return is_array() ? m_value.array : nullptr;
2721  }
2722 
2724  constexpr const array_t* get_impl_ptr(const array_t* /*unused*/) const noexcept
2725  {
2726  return is_array() ? m_value.array : nullptr;
2727  }
2728 
2730  string_t* get_impl_ptr(string_t* /*unused*/) noexcept
2731  {
2732  return is_string() ? m_value.string : nullptr;
2733  }
2734 
2736  constexpr const string_t* get_impl_ptr(const string_t* /*unused*/) const noexcept
2737  {
2738  return is_string() ? m_value.string : nullptr;
2739  }
2740 
2742  boolean_t* get_impl_ptr(boolean_t* /*unused*/) noexcept
2743  {
2744  return is_boolean() ? &m_value.boolean : nullptr;
2745  }
2746 
2748  constexpr const boolean_t* get_impl_ptr(const boolean_t* /*unused*/) const noexcept
2749  {
2750  return is_boolean() ? &m_value.boolean : nullptr;
2751  }
2752 
2754  number_integer_t* get_impl_ptr(number_integer_t* /*unused*/) noexcept
2755  {
2756  return is_number_integer() ? &m_value.number_integer : nullptr;
2757  }
2758 
2760  constexpr const number_integer_t* get_impl_ptr(const number_integer_t* /*unused*/) const noexcept
2761  {
2762  return is_number_integer() ? &m_value.number_integer : nullptr;
2763  }
2764 
2766  number_unsigned_t* get_impl_ptr(number_unsigned_t* /*unused*/) noexcept
2767  {
2768  return is_number_unsigned() ? &m_value.number_unsigned : nullptr;
2769  }
2770 
2772  constexpr const number_unsigned_t* get_impl_ptr(const number_unsigned_t* /*unused*/) const noexcept
2773  {
2774  return is_number_unsigned() ? &m_value.number_unsigned : nullptr;
2775  }
2776 
2778  number_float_t* get_impl_ptr(number_float_t* /*unused*/) noexcept
2779  {
2780  return is_number_float() ? &m_value.number_float : nullptr;
2781  }
2782 
2784  constexpr const number_float_t* get_impl_ptr(const number_float_t* /*unused*/) const noexcept
2785  {
2786  return is_number_float() ? &m_value.number_float : nullptr;
2787  }
2788 
2790  binary_t* get_impl_ptr(binary_t* /*unused*/) noexcept
2791  {
2792  return is_binary() ? m_value.binary : nullptr;
2793  }
2794 
2796  constexpr const binary_t* get_impl_ptr(const binary_t* /*unused*/) const noexcept
2797  {
2798  return is_binary() ? m_value.binary : nullptr;
2799  }
2800 
2812  template<typename ReferenceType, typename ThisType>
2813  static ReferenceType get_ref_impl(ThisType& obj)
2814  {
2815  // delegate the call to get_ptr<>()
2816  auto ptr = obj.template get_ptr<typename std::add_pointer<ReferenceType>::type>();
2817 
2818  if (JSON_HEDLEY_LIKELY(ptr != nullptr))
2819  {
2820  return *ptr;
2821  }
2822 
2823  JSON_THROW(type_error::create(303, "incompatible ReferenceType for get_ref, actual type is " + std::string(obj.type_name())));
2824  }
2825 
2826  public:
2830 
2845  template<typename BasicJsonType, detail::enable_if_t<
2846  std::is_same<typename std::remove_const<BasicJsonType>::type, basic_json_t>::value,
2847  int> = 0>
2848  basic_json get() const
2849  {
2850  return *this;
2851  }
2852 
2868  template < typename BasicJsonType, detail::enable_if_t <
2869  !std::is_same<BasicJsonType, basic_json>::value&&
2871  BasicJsonType get() const
2872  {
2873  return *this;
2874  }
2875 
2915  template < typename ValueTypeCV, typename ValueType = detail::uncvref_t<ValueTypeCV>,
2916  detail::enable_if_t <
2917  !detail::is_basic_json<ValueType>::value &&
2918  detail::has_from_json<basic_json_t, ValueType>::value &&
2919  !detail::has_non_default_from_json<basic_json_t, ValueType>::value,
2920  int > = 0 >
2921  ValueType get() const noexcept(noexcept(
2922  JSONSerializer<ValueType>::from_json(std::declval<const basic_json_t&>(), std::declval<ValueType&>())))
2923  {
2924  // we cannot static_assert on ValueTypeCV being non-const, because
2925  // there is support for get<const basic_json_t>(), which is why we
2926  // still need the uncvref
2927  static_assert(!std::is_reference<ValueTypeCV>::value,
2928  "get() cannot be used with reference types, you might want to use get_ref()");
2929  static_assert(std::is_default_constructible<ValueType>::value,
2930  "types must be DefaultConstructible when used with get()");
2931 
2932  ValueType ret;
2933  JSONSerializer<ValueType>::from_json(*this, ret);
2934  return ret;
2935  }
2936 
2968  template < typename ValueTypeCV, typename ValueType = detail::uncvref_t<ValueTypeCV>,
2969  detail::enable_if_t < !std::is_same<basic_json_t, ValueType>::value &&
2970  detail::has_non_default_from_json<basic_json_t, ValueType>::value,
2971  int > = 0 >
2972  ValueType get() const noexcept(noexcept(
2973  JSONSerializer<ValueType>::from_json(std::declval<const basic_json_t&>())))
2974  {
2975  static_assert(!std::is_reference<ValueTypeCV>::value,
2976  "get() cannot be used with reference types, you might want to use get_ref()");
2977  return JSONSerializer<ValueType>::from_json(*this);
2978  }
2979 
3013  template < typename ValueType,
3014  detail::enable_if_t <
3017  int > = 0 >
3018  ValueType & get_to(ValueType& v) const noexcept(noexcept(
3019  JSONSerializer<ValueType>::from_json(std::declval<const basic_json_t&>(), v)))
3020  {
3021  JSONSerializer<ValueType>::from_json(*this, v);
3022  return v;
3023  }
3024 
3025  // specialization to allow to call get_to with a basic_json value
3026  // see https://github.com/nlohmann/json/issues/2175
3027  template<typename ValueType,
3028  detail::enable_if_t <
3030  int> = 0>
3031  ValueType & get_to(ValueType& v) const
3032  {
3033  v = *this;
3034  return v;
3035  }
3036 
3037  template <
3038  typename T, std::size_t N,
3039  typename Array = T (&)[N],
3040  detail::enable_if_t <
3041  detail::has_from_json<basic_json_t, Array>::value, int > = 0 >
3042  Array get_to(T (&v)[N]) const
3043  noexcept(noexcept(JSONSerializer<Array>::from_json(
3044  std::declval<const basic_json_t&>(), v)))
3045  {
3046  JSONSerializer<Array>::from_json(*this, v);
3047  return v;
3048  }
3049 
3050 
3077  template<typename PointerType, typename std::enable_if<
3078  std::is_pointer<PointerType>::value, int>::type = 0>
3079  auto get_ptr() noexcept -> decltype(std::declval<basic_json_t&>().get_impl_ptr(std::declval<PointerType>()))
3080  {
3081  // delegate the call to get_impl_ptr<>()
3082  return get_impl_ptr(static_cast<PointerType>(nullptr));
3083  }
3084 
3089  template < typename PointerType, typename std::enable_if <
3090  std::is_pointer<PointerType>::value&&
3091  std::is_const<typename std::remove_pointer<PointerType>::type>::value, int >::type = 0 >
3092  constexpr auto get_ptr() const noexcept -> decltype(std::declval<const basic_json_t&>().get_impl_ptr(std::declval<PointerType>()))
3093  {
3094  // delegate the call to get_impl_ptr<>() const
3095  return get_impl_ptr(static_cast<PointerType>(nullptr));
3096  }
3097 
3125  template<typename PointerType, typename std::enable_if<
3126  std::is_pointer<PointerType>::value, int>::type = 0>
3127  auto get() noexcept -> decltype(std::declval<basic_json_t&>().template get_ptr<PointerType>())
3128  {
3129  // delegate the call to get_ptr
3130  return get_ptr<PointerType>();
3131  }
3132 
3137  template<typename PointerType, typename std::enable_if<
3138  std::is_pointer<PointerType>::value, int>::type = 0>
3139  constexpr auto get() const noexcept -> decltype(std::declval<const basic_json_t&>().template get_ptr<PointerType>())
3140  {
3141  // delegate the call to get_ptr
3142  return get_ptr<PointerType>();
3143  }
3144 
3171  template<typename ReferenceType, typename std::enable_if<
3172  std::is_reference<ReferenceType>::value, int>::type = 0>
3173  ReferenceType get_ref()
3174  {
3175  // delegate call to get_ref_impl
3176  return get_ref_impl<ReferenceType>(*this);
3177  }
3178 
3183  template < typename ReferenceType, typename std::enable_if <
3184  std::is_reference<ReferenceType>::value&&
3185  std::is_const<typename std::remove_reference<ReferenceType>::type>::value, int >::type = 0 >
3186  ReferenceType get_ref() const
3187  {
3188  // delegate call to get_ref_impl
3189  return get_ref_impl<ReferenceType>(*this);
3190  }
3191 
3221  template < typename ValueType, typename std::enable_if <
3222  !std::is_pointer<ValueType>::value&&
3223  !std::is_same<ValueType, detail::json_ref<basic_json>>::value&&
3224  !std::is_same<ValueType, typename string_t::value_type>::value&&
3226  && !std::is_same<ValueType, std::initializer_list<typename string_t::value_type>>::value
3227 #if defined(JSON_HAS_CPP_17) && (defined(__GNUC__) || (defined(_MSC_VER) && _MSC_VER >= 1910 && _MSC_VER <= 1914))
3228  && !std::is_same<ValueType, typename std::string_view>::value
3229 #endif
3230  && detail::is_detected<detail::get_template_function, const basic_json_t&, ValueType>::value
3231  , int >::type = 0 >
3232  JSON_EXPLICIT operator ValueType() const
3233  {
3234  // delegate the call to get<>() const
3235  return get<ValueType>();
3236  }
3237 
3248  {
3249  if (!is_binary())
3250  {
3251  JSON_THROW(type_error::create(302, "type must be binary, but is " + std::string(type_name())));
3252  }
3253 
3254  return *get_ptr<binary_t*>();
3255  }
3256 
3258  const binary_t& get_binary() const
3259  {
3260  if (!is_binary())
3261  {
3262  JSON_THROW(type_error::create(302, "type must be binary, but is " + std::string(type_name())));
3263  }
3264 
3265  return *get_ptr<const binary_t*>();
3266  }
3267 
3269 
3270 
3272  // element access //
3274 
3278 
3306  {
3307  // at only works for arrays
3308  if (JSON_HEDLEY_LIKELY(is_array()))
3309  {
3310  JSON_TRY
3311  {
3312  return m_value.array->at(idx);
3313  }
3314  JSON_CATCH (std::out_of_range&)
3315  {
3316  // create better exception explanation
3317  JSON_THROW(out_of_range::create(401, "array index " + std::to_string(idx) + " is out of range"));
3318  }
3319  }
3320  else
3321  {
3322  JSON_THROW(type_error::create(304, "cannot use at() with " + std::string(type_name())));
3323  }
3324  }
3325 
3353  {
3354  // at only works for arrays
3355  if (JSON_HEDLEY_LIKELY(is_array()))
3356  {
3357  JSON_TRY
3358  {
3359  return m_value.array->at(idx);
3360  }
3361  JSON_CATCH (std::out_of_range&)
3362  {
3363  // create better exception explanation
3364  JSON_THROW(out_of_range::create(401, "array index " + std::to_string(idx) + " is out of range"));
3365  }
3366  }
3367  else
3368  {
3369  JSON_THROW(type_error::create(304, "cannot use at() with " + std::string(type_name())));
3370  }
3371  }
3372 
3403  reference at(const typename object_t::key_type& key)
3404  {
3405  // at only works for objects
3406  if (JSON_HEDLEY_LIKELY(is_object()))
3407  {
3408  JSON_TRY
3409  {
3410  return m_value.object->at(key);
3411  }
3412  JSON_CATCH (std::out_of_range&)
3413  {
3414  // create better exception explanation
3415  JSON_THROW(out_of_range::create(403, "key '" + key + "' not found"));
3416  }
3417  }
3418  else
3419  {
3420  JSON_THROW(type_error::create(304, "cannot use at() with " + std::string(type_name())));
3421  }
3422  }
3423 
3454  const_reference at(const typename object_t::key_type& key) const
3455  {
3456  // at only works for objects
3457  if (JSON_HEDLEY_LIKELY(is_object()))
3458  {
3459  JSON_TRY
3460  {
3461  return m_value.object->at(key);
3462  }
3463  JSON_CATCH (std::out_of_range&)
3464  {
3465  // create better exception explanation
3466  JSON_THROW(out_of_range::create(403, "key '" + key + "' not found"));
3467  }
3468  }
3469  else
3470  {
3471  JSON_THROW(type_error::create(304, "cannot use at() with " + std::string(type_name())));
3472  }
3473  }
3474 
3501  {
3502  // implicitly convert null value to an empty array
3503  if (is_null())
3504  {
3505  m_type = value_t::array;
3506  m_value.array = create<array_t>();
3507  assert_invariant();
3508  }
3509 
3510  // operator[] only works for arrays
3511  if (JSON_HEDLEY_LIKELY(is_array()))
3512  {
3513  // fill up array with null values if given idx is outside range
3514  if (idx >= m_value.array->size())
3515  {
3516  m_value.array->insert(m_value.array->end(),
3517  idx - m_value.array->size() + 1,
3518  basic_json());
3519  }
3520 
3521  return m_value.array->operator[](idx);
3522  }
3523 
3524  JSON_THROW(type_error::create(305, "cannot use operator[] with a numeric argument with " + std::string(type_name())));
3525  }
3526 
3547  {
3548  // const operator[] only works for arrays
3549  if (JSON_HEDLEY_LIKELY(is_array()))
3550  {
3551  return m_value.array->operator[](idx);
3552  }
3553 
3554  JSON_THROW(type_error::create(305, "cannot use operator[] with a numeric argument with " + std::string(type_name())));
3555  }
3556 
3584  reference operator[](const typename object_t::key_type& key)
3585  {
3586  // implicitly convert null value to an empty object
3587  if (is_null())
3588  {
3589  m_type = value_t::object;
3590  m_value.object = create<object_t>();
3591  assert_invariant();
3592  }
3593 
3594  // operator[] only works for objects
3595  if (JSON_HEDLEY_LIKELY(is_object()))
3596  {
3597  return m_value.object->operator[](key);
3598  }
3599 
3600  JSON_THROW(type_error::create(305, "cannot use operator[] with a string argument with " + std::string(type_name())));
3601  }
3602 
3633  const_reference operator[](const typename object_t::key_type& key) const
3634  {
3635  // const operator[] only works for objects
3636  if (JSON_HEDLEY_LIKELY(is_object()))
3637  {
3638  JSON_ASSERT(m_value.object->find(key) != m_value.object->end());
3639  return m_value.object->find(key)->second;
3640  }
3641 
3642  JSON_THROW(type_error::create(305, "cannot use operator[] with a string argument with " + std::string(type_name())));
3643  }
3644 
3672  template<typename T>
3673  JSON_HEDLEY_NON_NULL(2)
3674  reference operator[](T* key)
3675  {
3676  // implicitly convert null to object
3677  if (is_null())
3678  {
3679  m_type = value_t::object;
3680  m_value = value_t::object;
3681  assert_invariant();
3682  }
3683 
3684  // at only works for objects
3685  if (JSON_HEDLEY_LIKELY(is_object()))
3686  {
3687  return m_value.object->operator[](key);
3688  }
3689 
3690  JSON_THROW(type_error::create(305, "cannot use operator[] with a string argument with " + std::string(type_name())));
3691  }
3692 
3723  template<typename T>
3724  JSON_HEDLEY_NON_NULL(2)
3725  const_reference operator[](T* key) const
3726  {
3727  // at only works for objects
3728  if (JSON_HEDLEY_LIKELY(is_object()))
3729  {
3730  JSON_ASSERT(m_value.object->find(key) != m_value.object->end());
3731  return m_value.object->find(key)->second;
3732  }
3733 
3734  JSON_THROW(type_error::create(305, "cannot use operator[] with a string argument with " + std::string(type_name())));
3735  }
3736 
3787  // using std::is_convertible in a std::enable_if will fail when using explicit conversions
3788  template < class ValueType, typename std::enable_if <
3790  && !std::is_same<value_t, ValueType>::value, int >::type = 0 >
3791  ValueType value(const typename object_t::key_type& key, const ValueType& default_value) const
3792  {
3793  // at only works for objects
3794  if (JSON_HEDLEY_LIKELY(is_object()))
3795  {
3796  // if key is found, return value and given default value otherwise
3797  const auto it = find(key);
3798  if (it != end())
3799  {
3800  return it->template get<ValueType>();
3801  }
3802 
3803  return default_value;
3804  }
3805 
3806  JSON_THROW(type_error::create(306, "cannot use value() with " + std::string(type_name())));
3807  }
3808 
3813  string_t value(const typename object_t::key_type& key, const char* default_value) const
3814  {
3815  return value(key, string_t(default_value));
3816  }
3817 
3861  template<class ValueType, typename std::enable_if<
3863  ValueType value(const json_pointer& ptr, const ValueType& default_value) const
3864  {
3865  // at only works for objects
3866  if (JSON_HEDLEY_LIKELY(is_object()))
3867  {
3868  // if pointer resolves a value, return it or use default value
3869  JSON_TRY
3870  {
3871  return ptr.get_checked(this).template get<ValueType>();
3872  }
3873  JSON_INTERNAL_CATCH (out_of_range&)
3874  {
3875  return default_value;
3876  }
3877  }
3878 
3879  JSON_THROW(type_error::create(306, "cannot use value() with " + std::string(type_name())));
3880  }
3881 
3886  JSON_HEDLEY_NON_NULL(3)
3887  string_t value(const json_pointer& ptr, const char* default_value) const
3888  {
3889  return value(ptr, string_t(default_value));
3890  }
3891 
3918  {
3919  return *begin();
3920  }
3921 
3926  {
3927  return *cbegin();
3928  }
3929 
3962  {
3963  auto tmp = end();
3964  --tmp;
3965  return *tmp;
3966  }
3967 
3972  {
3973  auto tmp = cend();
3974  --tmp;
3975  return *tmp;
3976  }
3977 
4024  template < class IteratorType, typename std::enable_if <
4025  std::is_same<IteratorType, typename basic_json_t::iterator>::value ||
4026  std::is_same<IteratorType, typename basic_json_t::const_iterator>::value, int >::type
4027  = 0 >
4028  IteratorType erase(IteratorType pos)
4029  {
4030  // make sure iterator fits the current value
4031  if (JSON_HEDLEY_UNLIKELY(this != pos.m_object))
4032  {
4033  JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value"));
4034  }
4035 
4036  IteratorType result = end();
4037 
4038  switch (m_type)
4039  {
4040  case value_t::boolean:
4041  case value_t::number_float:
4044  case value_t::string:
4045  case value_t::binary:
4046  {
4047  if (JSON_HEDLEY_UNLIKELY(!pos.m_it.primitive_iterator.is_begin()))
4048  {
4049  JSON_THROW(invalid_iterator::create(205, "iterator out of range"));
4050  }
4051 
4052  if (is_string())
4053  {
4054  AllocatorType<string_t> alloc;
4055  std::allocator_traits<decltype(alloc)>::destroy(alloc, m_value.string);
4056  std::allocator_traits<decltype(alloc)>::deallocate(alloc, m_value.string, 1);
4057  m_value.string = nullptr;
4058  }
4059  else if (is_binary())
4060  {
4061  AllocatorType<binary_t> alloc;
4062  std::allocator_traits<decltype(alloc)>::destroy(alloc, m_value.binary);
4063  std::allocator_traits<decltype(alloc)>::deallocate(alloc, m_value.binary, 1);
4064  m_value.binary = nullptr;
4065  }
4066 
4067  m_type = value_t::null;
4068  assert_invariant();
4069  break;
4070  }
4071 
4072  case value_t::object:
4073  {
4074  result.m_it.object_iterator = m_value.object->erase(pos.m_it.object_iterator);
4075  break;
4076  }
4077 
4078  case value_t::array:
4079  {
4080  result.m_it.array_iterator = m_value.array->erase(pos.m_it.array_iterator);
4081  break;
4082  }
4083 
4084  default:
4085  JSON_THROW(type_error::create(307, "cannot use erase() with " + std::string(type_name())));
4086  }
4087 
4088  return result;
4089  }
4090 
4137  template < class IteratorType, typename std::enable_if <
4138  std::is_same<IteratorType, typename basic_json_t::iterator>::value ||
4139  std::is_same<IteratorType, typename basic_json_t::const_iterator>::value, int >::type
4140  = 0 >
4141  IteratorType erase(IteratorType first, IteratorType last)
4142  {
4143  // make sure iterator fits the current value
4144  if (JSON_HEDLEY_UNLIKELY(this != first.m_object || this != last.m_object))
4145  {
4146  JSON_THROW(invalid_iterator::create(203, "iterators do not fit current value"));
4147  }
4148 
4149  IteratorType result = end();
4150 
4151  switch (m_type)
4152  {
4153  case value_t::boolean:
4154  case value_t::number_float:
4157  case value_t::string:
4158  case value_t::binary:
4159  {
4160  if (JSON_HEDLEY_LIKELY(!first.m_it.primitive_iterator.is_begin()
4161  || !last.m_it.primitive_iterator.is_end()))
4162  {
4163  JSON_THROW(invalid_iterator::create(204, "iterators out of range"));
4164  }
4165 
4166  if (is_string())
4167  {
4168  AllocatorType<string_t> alloc;
4169  std::allocator_traits<decltype(alloc)>::destroy(alloc, m_value.string);
4170  std::allocator_traits<decltype(alloc)>::deallocate(alloc, m_value.string, 1);
4171  m_value.string = nullptr;
4172  }
4173  else if (is_binary())
4174  {
4175  AllocatorType<binary_t> alloc;
4176  std::allocator_traits<decltype(alloc)>::destroy(alloc, m_value.binary);
4177  std::allocator_traits<decltype(alloc)>::deallocate(alloc, m_value.binary, 1);
4178  m_value.binary = nullptr;
4179  }
4180 
4181  m_type = value_t::null;
4182  assert_invariant();
4183  break;
4184  }
4185 
4186  case value_t::object:
4187  {
4188  result.m_it.object_iterator = m_value.object->erase(first.m_it.object_iterator,
4189  last.m_it.object_iterator);
4190  break;
4191  }
4192 
4193  case value_t::array:
4194  {
4195  result.m_it.array_iterator = m_value.array->erase(first.m_it.array_iterator,
4196  last.m_it.array_iterator);
4197  break;
4198  }
4199 
4200  default:
4201  JSON_THROW(type_error::create(307, "cannot use erase() with " + std::string(type_name())));
4202  }
4203 
4204  return result;
4205  }
4206 
4236  size_type erase(const typename object_t::key_type& key)
4237  {
4238  // this erase only works for objects
4239  if (JSON_HEDLEY_LIKELY(is_object()))
4240  {
4241  return m_value.object->erase(key);
4242  }
4243 
4244  JSON_THROW(type_error::create(307, "cannot use erase() with " + std::string(type_name())));
4245  }
4246 
4271  void erase(const size_type idx)
4272  {
4273  // this erase only works for arrays
4274  if (JSON_HEDLEY_LIKELY(is_array()))
4275  {
4276  if (JSON_HEDLEY_UNLIKELY(idx >= size()))
4277  {
4278  JSON_THROW(out_of_range::create(401, "array index " + std::to_string(idx) + " is out of range"));
4279  }
4280 
4281  m_value.array->erase(m_value.array->begin() + static_cast<difference_type>(idx));
4282  }
4283  else
4284  {
4285  JSON_THROW(type_error::create(307, "cannot use erase() with " + std::string(type_name())));
4286  }
4287  }
4288 
4290 
4291 
4293  // lookup //
4295 
4298 
4323  template<typename KeyT>
4324  iterator find(KeyT&& key)
4325  {
4326  auto result = end();
4327 
4328  if (is_object())
4329  {
4330  result.m_it.object_iterator = m_value.object->find(std::forward<KeyT>(key));
4331  }
4332 
4333  return result;
4334  }
4335 
4340  template<typename KeyT>
4341  const_iterator find(KeyT&& key) const
4342  {
4343  auto result = cend();
4344 
4345  if (is_object())
4346  {
4347  result.m_it.object_iterator = m_value.object->find(std::forward<KeyT>(key));
4348  }
4349 
4350  return result;
4351  }
4352 
4374  template<typename KeyT>
4375  size_type count(KeyT&& key) const
4376  {
4377  // return 0 for all nonobject types
4378  return is_object() ? m_value.object->count(std::forward<KeyT>(key)) : 0;
4379  }
4380 
4406  template < typename KeyT, typename std::enable_if <
4407  !std::is_same<typename std::decay<KeyT>::type, json_pointer>::value, int >::type = 0 >
4408  bool contains(KeyT && key) const
4409  {
4410  return is_object() && m_value.object->find(std::forward<KeyT>(key)) != m_value.object->end();
4411  }
4412 
4439  bool contains(const json_pointer& ptr) const
4440  {
4441  return ptr.contains(this);
4442  }
4443 
4445 
4446 
4448  // iterators //
4450 
4453 
4478  iterator begin() noexcept
4479  {
4480  iterator result(this);
4481  result.set_begin();
4482  return result;
4483  }
4484 
4488  const_iterator begin() const noexcept
4489  {
4490  return cbegin();
4491  }
4492 
4518  const_iterator cbegin() const noexcept
4519  {
4520  const_iterator result(this);
4521  result.set_begin();
4522  return result;
4523  }
4524 
4549  iterator end() noexcept
4550  {
4551  iterator result(this);
4552  result.set_end();
4553  return result;
4554  }
4555 
4559  const_iterator end() const noexcept
4560  {
4561  return cend();
4562  }
4563 
4589  const_iterator cend() const noexcept
4590  {
4591  const_iterator result(this);
4592  result.set_end();
4593  return result;
4594  }
4595 
4620  {
4621  return reverse_iterator(end());
4622  }
4623 
4628  {
4629  return crbegin();
4630  }
4631 
4657  {
4658  return reverse_iterator(begin());
4659  }
4660 
4664  const_reverse_iterator rend() const noexcept
4665  {
4666  return crend();
4667  }
4668 
4694  {
4695  return const_reverse_iterator(cend());
4696  }
4697 
4723  {
4724  return const_reverse_iterator(cbegin());
4725  }
4726 
4727  public:
4785  JSON_HEDLEY_DEPRECATED_FOR(3.1.0, items())
4787  {
4788  return ref.items();
4789  }
4790 
4794  JSON_HEDLEY_DEPRECATED_FOR(3.1.0, items())
4796  {
4797  return ref.items();
4798  }
4799 
4869  {
4870  return iteration_proxy<iterator>(*this);
4871  }
4872 
4877  {
4878  return iteration_proxy<const_iterator>(*this);
4879  }
4880 
4882 
4883 
4885  // capacity //
4887 
4890 
4933  bool empty() const noexcept
4934  {
4935  switch (m_type)
4936  {
4937  case value_t::null:
4938  {
4939  // null values are empty
4940  return true;
4941  }
4942 
4943  case value_t::array:
4944  {
4945  // delegate call to array_t::empty()
4946  return m_value.array->empty();
4947  }
4948 
4949  case value_t::object:
4950  {
4951  // delegate call to object_t::empty()
4952  return m_value.object->empty();
4953  }
4954 
4955  default:
4956  {
4957  // all other types are nonempty
4958  return false;
4959  }
4960  }
4961  }
4962 
5006  size_type size() const noexcept
5007  {
5008  switch (m_type)
5009  {
5010  case value_t::null:
5011  {
5012  // null values are empty
5013  return 0;
5014  }
5015 
5016  case value_t::array:
5017  {
5018  // delegate call to array_t::size()
5019  return m_value.array->size();
5020  }
5021 
5022  case value_t::object:
5023  {
5024  // delegate call to object_t::size()
5025  return m_value.object->size();
5026  }
5027 
5028  default:
5029  {
5030  // all other types have size 1
5031  return 1;
5032  }
5033  }
5034  }
5035 
5077  size_type max_size() const noexcept
5078  {
5079  switch (m_type)
5080  {
5081  case value_t::array:
5082  {
5083  // delegate call to array_t::max_size()
5084  return m_value.array->max_size();
5085  }
5086 
5087  case value_t::object:
5088  {
5089  // delegate call to object_t::max_size()
5090  return m_value.object->max_size();
5091  }
5092 
5093  default:
5094  {
5095  // all other types have max_size() == size()
5096  return size();
5097  }
5098  }
5099  }
5100 
5102 
5103 
5105  // modifiers //
5107 
5110 
5148  void clear() noexcept
5149  {
5150  switch (m_type)
5151  {
5153  {
5154  m_value.number_integer = 0;
5155  break;
5156  }
5157 
5159  {
5160  m_value.number_unsigned = 0;
5161  break;
5162  }
5163 
5164  case value_t::number_float:
5165  {
5166  m_value.number_float = 0.0;
5167  break;
5168  }
5169 
5170  case value_t::boolean:
5171  {
5172  m_value.boolean = false;
5173  break;
5174  }
5175 
5176  case value_t::string:
5177  {
5178  m_value.string->clear();
5179  break;
5180  }
5181 
5182  case value_t::binary:
5183  {
5184  m_value.binary->clear();
5185  break;
5186  }
5187 
5188  case value_t::array:
5189  {
5190  m_value.array->clear();
5191  break;
5192  }
5193 
5194  case value_t::object:
5195  {
5196  m_value.object->clear();
5197  break;
5198  }
5199 
5200  default:
5201  break;
5202  }
5203  }
5204 
5225  void push_back(basic_json&& val)
5226  {
5227  // push_back only works for null objects or arrays
5228  if (JSON_HEDLEY_UNLIKELY(!(is_null() || is_array())))
5229  {
5230  JSON_THROW(type_error::create(308, "cannot use push_back() with " + std::string(type_name())));
5231  }
5232 
5233  // transform null object into an array
5234  if (is_null())
5235  {
5236  m_type = value_t::array;
5237  m_value = value_t::array;
5238  assert_invariant();
5239  }
5240 
5241  // add element to array (move semantics)
5242  m_value.array->push_back(std::move(val));
5243  // if val is moved from, basic_json move constructor marks it null so we do not call the destructor
5244  }
5245 
5251  {
5252  push_back(std::move(val));
5253  return *this;
5254  }
5255 
5260  void push_back(const basic_json& val)
5261  {
5262  // push_back only works for null objects or arrays
5263  if (JSON_HEDLEY_UNLIKELY(!(is_null() || is_array())))
5264  {
5265  JSON_THROW(type_error::create(308, "cannot use push_back() with " + std::string(type_name())));
5266  }
5267 
5268  // transform null object into an array
5269  if (is_null())
5270  {
5271  m_type = value_t::array;
5272  m_value = value_t::array;
5273  assert_invariant();
5274  }
5275 
5276  // add element to array
5277  m_value.array->push_back(val);
5278  }
5279 
5285  {
5286  push_back(val);
5287  return *this;
5288  }
5289 
5310  void push_back(const typename object_t::value_type& val)
5311  {
5312  // push_back only works for null objects or objects
5313  if (JSON_HEDLEY_UNLIKELY(!(is_null() || is_object())))
5314  {
5315  JSON_THROW(type_error::create(308, "cannot use push_back() with " + std::string(type_name())));
5316  }
5317 
5318  // transform null object into an object
5319  if (is_null())
5320  {
5321  m_type = value_t::object;
5322  m_value = value_t::object;
5323  assert_invariant();
5324  }
5325 
5326  // add element to array
5327  m_value.object->insert(val);
5328  }
5329 
5334  reference operator+=(const typename object_t::value_type& val)
5335  {
5336  push_back(val);
5337  return *this;
5338  }
5339 
5366  {
5367  if (is_object() && init.size() == 2 && (*init.begin())->is_string())
5368  {
5369  basic_json&& key = init.begin()->moved_or_copied();
5370  push_back(typename object_t::value_type(
5371  std::move(key.get_ref<string_t&>()), (init.begin() + 1)->moved_or_copied()));
5372  }
5373  else
5374  {
5375  push_back(basic_json(init));
5376  }
5377  }
5378 
5384  {
5385  push_back(init);
5386  return *this;
5387  }
5388 
5412  template<class... Args>
5413  reference emplace_back(Args&& ... args)
5414  {
5415  // emplace_back only works for null objects or arrays
5416  if (JSON_HEDLEY_UNLIKELY(!(is_null() || is_array())))
5417  {
5418  JSON_THROW(type_error::create(311, "cannot use emplace_back() with " + std::string(type_name())));
5419  }
5420 
5421  // transform null object into an array
5422  if (is_null())
5423  {
5424  m_type = value_t::array;
5425  m_value = value_t::array;
5426  assert_invariant();
5427  }
5428 
5429  // add element to array (perfect forwarding)
5430 #ifdef JSON_HAS_CPP_17
5431  return m_value.array->emplace_back(std::forward<Args>(args)...);
5432 #else
5433  m_value.array->emplace_back(std::forward<Args>(args)...);
5434  return m_value.array->back();
5435 #endif
5436  }
5437 
5465  template<class... Args>
5466  std::pair<iterator, bool> emplace(Args&& ... args)
5467  {
5468  // emplace only works for null objects or arrays
5469  if (JSON_HEDLEY_UNLIKELY(!(is_null() || is_object())))
5470  {
5471  JSON_THROW(type_error::create(311, "cannot use emplace() with " + std::string(type_name())));
5472  }
5473 
5474  // transform null object into an object
5475  if (is_null())
5476  {
5477  m_type = value_t::object;
5478  m_value = value_t::object;
5479  assert_invariant();
5480  }
5481 
5482  // add element to array (perfect forwarding)
5483  auto res = m_value.object->emplace(std::forward<Args>(args)...);
5484  // create result iterator and set iterator to the result of emplace
5485  auto it = begin();
5486  it.m_it.object_iterator = res.first;
5487 
5488  // return pair of iterator and boolean
5489  return {it, res.second};
5490  }
5491 
5495  template<typename... Args>
5497  {
5498  iterator result(this);
5499  JSON_ASSERT(m_value.array != nullptr);
5500 
5501  auto insert_pos = std::distance(m_value.array->begin(), pos.m_it.array_iterator);
5502  m_value.array->insert(pos.m_it.array_iterator, std::forward<Args>(args)...);
5503  result.m_it.array_iterator = m_value.array->begin() + insert_pos;
5504 
5505  // This could have been written as:
5506  // result.m_it.array_iterator = m_value.array->insert(pos.m_it.array_iterator, cnt, val);
5507  // but the return value of insert is missing in GCC 4.8, so it is written this way instead.
5508 
5509  return result;
5510  }
5511 
5535  {
5536  // insert only works for arrays
5537  if (JSON_HEDLEY_LIKELY(is_array()))
5538  {
5539  // check if iterator pos fits to this JSON value
5540  if (JSON_HEDLEY_UNLIKELY(pos.m_object != this))
5541  {
5542  JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value"));
5543  }
5544 
5545  // insert to array and return iterator
5546  return insert_iterator(pos, val);
5547  }
5548 
5549  JSON_THROW(type_error::create(309, "cannot use insert() with " + std::string(type_name())));
5550  }
5551 
5557  {
5558  return insert(pos, val);
5559  }
5560 
5586  {
5587  // insert only works for arrays
5588  if (JSON_HEDLEY_LIKELY(is_array()))
5589  {
5590  // check if iterator pos fits to this JSON value
5591  if (JSON_HEDLEY_UNLIKELY(pos.m_object != this))
5592  {
5593  JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value"));
5594  }
5595 
5596  // insert to array and return iterator
5597  return insert_iterator(pos, cnt, val);
5598  }
5599 
5600  JSON_THROW(type_error::create(309, "cannot use insert() with " + std::string(type_name())));
5601  }
5602 
5634  {
5635  // insert only works for arrays
5636  if (JSON_HEDLEY_UNLIKELY(!is_array()))
5637  {
5638  JSON_THROW(type_error::create(309, "cannot use insert() with " + std::string(type_name())));
5639  }
5640 
5641  // check if iterator pos fits to this JSON value
5642  if (JSON_HEDLEY_UNLIKELY(pos.m_object != this))
5643  {
5644  JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value"));
5645  }
5646 
5647  // check if range iterators belong to the same JSON object
5648  if (JSON_HEDLEY_UNLIKELY(first.m_object != last.m_object))
5649  {
5650  JSON_THROW(invalid_iterator::create(210, "iterators do not fit"));
5651  }
5652 
5653  if (JSON_HEDLEY_UNLIKELY(first.m_object == this))
5654  {
5655  JSON_THROW(invalid_iterator::create(211, "passed iterators may not belong to container"));
5656  }
5657 
5658  // insert to array and return iterator
5659  return insert_iterator(pos, first.m_it.array_iterator, last.m_it.array_iterator);
5660  }
5661 
5687  {
5688  // insert only works for arrays
5689  if (JSON_HEDLEY_UNLIKELY(!is_array()))
5690  {
5691  JSON_THROW(type_error::create(309, "cannot use insert() with " + std::string(type_name())));
5692  }
5693 
5694  // check if iterator pos fits to this JSON value
5695  if (JSON_HEDLEY_UNLIKELY(pos.m_object != this))
5696  {
5697  JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value"));
5698  }
5699 
5700  // insert to array and return iterator
5701  return insert_iterator(pos, ilist.begin(), ilist.end());
5702  }
5703 
5728  {
5729  // insert only works for objects
5730  if (JSON_HEDLEY_UNLIKELY(!is_object()))
5731  {
5732  JSON_THROW(type_error::create(309, "cannot use insert() with " + std::string(type_name())));
5733  }
5734 
5735  // check if range iterators belong to the same JSON object
5736  if (JSON_HEDLEY_UNLIKELY(first.m_object != last.m_object))
5737  {
5738  JSON_THROW(invalid_iterator::create(210, "iterators do not fit"));
5739  }
5740 
5741  // passed iterators must belong to objects
5742  if (JSON_HEDLEY_UNLIKELY(!first.m_object->is_object()))
5743  {
5744  JSON_THROW(invalid_iterator::create(202, "iterators first and last must point to objects"));
5745  }
5746 
5747  m_value.object->insert(first.m_it.object_iterator, last.m_it.object_iterator);
5748  }
5749 
5770  {
5771  // implicitly convert null value to an empty object
5772  if (is_null())
5773  {
5774  m_type = value_t::object;
5775  m_value.object = create<object_t>();
5776  assert_invariant();
5777  }
5778 
5779  if (JSON_HEDLEY_UNLIKELY(!is_object()))
5780  {
5781  JSON_THROW(type_error::create(312, "cannot use update() with " + std::string(type_name())));
5782  }
5783  if (JSON_HEDLEY_UNLIKELY(!j.is_object()))
5784  {
5785  JSON_THROW(type_error::create(312, "cannot use update() with " + std::string(j.type_name())));
5786  }
5787 
5788  for (auto it = j.cbegin(); it != j.cend(); ++it)
5789  {
5790  m_value.object->operator[](it.key()) = it.value();
5791  }
5792  }
5793 
5821  {
5822  // implicitly convert null value to an empty object
5823  if (is_null())
5824  {
5825  m_type = value_t::object;
5826  m_value.object = create<object_t>();
5827  assert_invariant();
5828  }
5829 
5830  if (JSON_HEDLEY_UNLIKELY(!is_object()))
5831  {
5832  JSON_THROW(type_error::create(312, "cannot use update() with " + std::string(type_name())));
5833  }
5834 
5835  // check if range iterators belong to the same JSON object
5836  if (JSON_HEDLEY_UNLIKELY(first.m_object != last.m_object))
5837  {
5838  JSON_THROW(invalid_iterator::create(210, "iterators do not fit"));
5839  }
5840 
5841  // passed iterators must belong to objects
5842  if (JSON_HEDLEY_UNLIKELY(!first.m_object->is_object()
5843  || !last.m_object->is_object()))
5844  {
5845  JSON_THROW(invalid_iterator::create(202, "iterators first and last must point to objects"));
5846  }
5847 
5848  for (auto it = first; it != last; ++it)
5849  {
5850  m_value.object->operator[](it.key()) = it.value();
5851  }
5852  }
5853 
5871  void swap(reference other) noexcept (
5872  std::is_nothrow_move_constructible<value_t>::value&&
5873  std::is_nothrow_move_assignable<value_t>::value&&
5874  std::is_nothrow_move_constructible<json_value>::value&&
5875  std::is_nothrow_move_assignable<json_value>::value
5876  )
5877  {
5878  std::swap(m_type, other.m_type);
5879  std::swap(m_value, other.m_value);
5880  assert_invariant();
5881  }
5882 
5901  friend void swap(reference left, reference right) noexcept (
5902  std::is_nothrow_move_constructible<value_t>::value&&
5903  std::is_nothrow_move_assignable<value_t>::value&&
5904  std::is_nothrow_move_constructible<json_value>::value&&
5905  std::is_nothrow_move_assignable<json_value>::value
5906  )
5907  {
5908  left.swap(right);
5909  }
5910 
5931  void swap(array_t& other)
5932  {
5933  // swap only works for arrays
5934  if (JSON_HEDLEY_LIKELY(is_array()))
5935  {
5936  std::swap(*(m_value.array), other);
5937  }
5938  else
5939  {
5940  JSON_THROW(type_error::create(310, "cannot use swap() with " + std::string(type_name())));
5941  }
5942  }
5943 
5964  void swap(object_t& other)
5965  {
5966  // swap only works for objects
5967  if (JSON_HEDLEY_LIKELY(is_object()))
5968  {
5969  std::swap(*(m_value.object), other);
5970  }
5971  else
5972  {
5973  JSON_THROW(type_error::create(310, "cannot use swap() with " + std::string(type_name())));
5974  }
5975  }
5976 
5997  void swap(string_t& other)
5998  {
5999  // swap only works for strings
6000  if (JSON_HEDLEY_LIKELY(is_string()))
6001  {
6002  std::swap(*(m_value.string), other);
6003  }
6004  else
6005  {
6006  JSON_THROW(type_error::create(310, "cannot use swap() with " + std::string(type_name())));
6007  }
6008  }
6009 
6030  void swap(binary_t& other)
6031  {
6032  // swap only works for strings
6033  if (JSON_HEDLEY_LIKELY(is_binary()))
6034  {
6035  std::swap(*(m_value.binary), other);
6036  }
6037  else
6038  {
6039  JSON_THROW(type_error::create(310, "cannot use swap() with " + std::string(type_name())));
6040  }
6041  }
6042 
6044  void swap(typename binary_t::container_type& other)
6045  {
6046  // swap only works for strings
6047  if (JSON_HEDLEY_LIKELY(is_binary()))
6048  {
6049  std::swap(*(m_value.binary), other);
6050  }
6051  else
6052  {
6053  JSON_THROW(type_error::create(310, "cannot use swap() with " + std::string(type_name())));
6054  }
6055  }
6056 
6058 
6059  public:
6061  // lexicographical comparison operators //
6063 
6066 
6122  friend bool operator==(const_reference lhs, const_reference rhs) noexcept
6123  {
6124  const auto lhs_type = lhs.type();
6125  const auto rhs_type = rhs.type();
6126 
6127  if (lhs_type == rhs_type)
6128  {
6129  switch (lhs_type)
6130  {
6131  case value_t::array:
6132  return *lhs.m_value.array == *rhs.m_value.array;
6133 
6134  case value_t::object:
6135  return *lhs.m_value.object == *rhs.m_value.object;
6136 
6137  case value_t::null:
6138  return true;
6139 
6140  case value_t::string:
6141  return *lhs.m_value.string == *rhs.m_value.string;
6142 
6143  case value_t::boolean:
6144  return lhs.m_value.boolean == rhs.m_value.boolean;
6145 
6147  return lhs.m_value.number_integer == rhs.m_value.number_integer;
6148 
6150  return lhs.m_value.number_unsigned == rhs.m_value.number_unsigned;
6151 
6152  case value_t::number_float:
6153  return lhs.m_value.number_float == rhs.m_value.number_float;
6154 
6155  case value_t::binary:
6156  return *lhs.m_value.binary == *rhs.m_value.binary;
6157 
6158  default:
6159  return false;
6160  }
6161  }
6162  else if (lhs_type == value_t::number_integer && rhs_type == value_t::number_float)
6163  {
6164  return static_cast<number_float_t>(lhs.m_value.number_integer) == rhs.m_value.number_float;
6165  }
6166  else if (lhs_type == value_t::number_float && rhs_type == value_t::number_integer)
6167  {
6168  return lhs.m_value.number_float == static_cast<number_float_t>(rhs.m_value.number_integer);
6169  }
6170  else if (lhs_type == value_t::number_unsigned && rhs_type == value_t::number_float)
6171  {
6172  return static_cast<number_float_t>(lhs.m_value.number_unsigned) == rhs.m_value.number_float;
6173  }
6174  else if (lhs_type == value_t::number_float && rhs_type == value_t::number_unsigned)
6175  {
6176  return lhs.m_value.number_float == static_cast<number_float_t>(rhs.m_value.number_unsigned);
6177  }
6178  else if (lhs_type == value_t::number_unsigned && rhs_type == value_t::number_integer)
6179  {
6180  return static_cast<number_integer_t>(lhs.m_value.number_unsigned) == rhs.m_value.number_integer;
6181  }
6182  else if (lhs_type == value_t::number_integer && rhs_type == value_t::number_unsigned)
6183  {
6184  return lhs.m_value.number_integer == static_cast<number_integer_t>(rhs.m_value.number_unsigned);
6185  }
6186 
6187  return false;
6188  }
6189 
6194  template<typename ScalarType, typename std::enable_if<
6195  std::is_scalar<ScalarType>::value, int>::type = 0>
6196  friend bool operator==(const_reference lhs, const ScalarType rhs) noexcept
6197  {
6198  return lhs == basic_json(rhs);
6199  }
6200 
6205  template<typename ScalarType, typename std::enable_if<
6206  std::is_scalar<ScalarType>::value, int>::type = 0>
6207  friend bool operator==(const ScalarType lhs, const_reference rhs) noexcept
6208  {
6209  return basic_json(lhs) == rhs;
6210  }
6211 
6230  friend bool operator!=(const_reference lhs, const_reference rhs) noexcept
6231  {
6232  return !(lhs == rhs);
6233  }
6234 
6239  template<typename ScalarType, typename std::enable_if<
6240  std::is_scalar<ScalarType>::value, int>::type = 0>
6241  friend bool operator!=(const_reference lhs, const ScalarType rhs) noexcept
6242  {
6243  return lhs != basic_json(rhs);
6244  }
6245 
6250  template<typename ScalarType, typename std::enable_if<
6251  std::is_scalar<ScalarType>::value, int>::type = 0>
6252  friend bool operator!=(const ScalarType lhs, const_reference rhs) noexcept
6253  {
6254  return basic_json(lhs) != rhs;
6255  }
6256 
6283  friend bool operator<(const_reference lhs, const_reference rhs) noexcept
6284  {
6285  const auto lhs_type = lhs.type();
6286  const auto rhs_type = rhs.type();
6287 
6288  if (lhs_type == rhs_type)
6289  {
6290  switch (lhs_type)
6291  {
6292  case value_t::array:
6293  // note parentheses are necessary, see
6294  // https://github.com/nlohmann/json/issues/1530
6295  return (*lhs.m_value.array) < (*rhs.m_value.array);
6296 
6297  case value_t::object:
6298  return (*lhs.m_value.object) < (*rhs.m_value.object);
6299 
6300  case value_t::null:
6301  return false;
6302 
6303  case value_t::string:
6304  return (*lhs.m_value.string) < (*rhs.m_value.string);
6305 
6306  case value_t::boolean:
6307  return (lhs.m_value.boolean) < (rhs.m_value.boolean);
6308 
6310  return (lhs.m_value.number_integer) < (rhs.m_value.number_integer);
6311 
6313  return (lhs.m_value.number_unsigned) < (rhs.m_value.number_unsigned);
6314 
6315  case value_t::number_float:
6316  return (lhs.m_value.number_float) < (rhs.m_value.number_float);
6317 
6318  case value_t::binary:
6319  return (*lhs.m_value.binary) < (*rhs.m_value.binary);
6320 
6321  default:
6322  return false;
6323  }
6324  }
6325  else if (lhs_type == value_t::number_integer && rhs_type == value_t::number_float)
6326  {
6327  return static_cast<number_float_t>(lhs.m_value.number_integer) < rhs.m_value.number_float;
6328  }
6329  else if (lhs_type == value_t::number_float && rhs_type == value_t::number_integer)
6330  {
6331  return lhs.m_value.number_float < static_cast<number_float_t>(rhs.m_value.number_integer);
6332  }
6333  else if (lhs_type == value_t::number_unsigned && rhs_type == value_t::number_float)
6334  {
6335  return static_cast<number_float_t>(lhs.m_value.number_unsigned) < rhs.m_value.number_float;
6336  }
6337  else if (lhs_type == value_t::number_float && rhs_type == value_t::number_unsigned)
6338  {
6339  return lhs.m_value.number_float < static_cast<number_float_t>(rhs.m_value.number_unsigned);
6340  }
6341  else if (lhs_type == value_t::number_integer && rhs_type == value_t::number_unsigned)
6342  {
6343  return lhs.m_value.number_integer < static_cast<number_integer_t>(rhs.m_value.number_unsigned);
6344  }
6345  else if (lhs_type == value_t::number_unsigned && rhs_type == value_t::number_integer)
6346  {
6347  return static_cast<number_integer_t>(lhs.m_value.number_unsigned) < rhs.m_value.number_integer;
6348  }
6349 
6350  // We only reach this line if we cannot compare values. In that case,
6351  // we compare types. Note we have to call the operator explicitly,
6352  // because MSVC has problems otherwise.
6353  return operator<(lhs_type, rhs_type);
6354  }
6355 
6360  template<typename ScalarType, typename std::enable_if<
6361  std::is_scalar<ScalarType>::value, int>::type = 0>
6362  friend bool operator<(const_reference lhs, const ScalarType rhs) noexcept
6363  {
6364  return lhs < basic_json(rhs);
6365  }
6366 
6371  template<typename ScalarType, typename std::enable_if<
6372  std::is_scalar<ScalarType>::value, int>::type = 0>
6373  friend bool operator<(const ScalarType lhs, const_reference rhs) noexcept
6374  {
6375  return basic_json(lhs) < rhs;
6376  }
6377 
6397  friend bool operator<=(const_reference lhs, const_reference rhs) noexcept
6398  {
6399  return !(rhs < lhs);
6400  }
6401 
6406  template<typename ScalarType, typename std::enable_if<
6407  std::is_scalar<ScalarType>::value, int>::type = 0>
6408  friend bool operator<=(const_reference lhs, const ScalarType rhs) noexcept
6409  {
6410  return lhs <= basic_json(rhs);
6411  }
6412 
6417  template<typename ScalarType, typename std::enable_if<
6418  std::is_scalar<ScalarType>::value, int>::type = 0>
6419  friend bool operator<=(const ScalarType lhs, const_reference rhs) noexcept
6420  {
6421  return basic_json(lhs) <= rhs;
6422  }
6423 
6443  friend bool operator>(const_reference lhs, const_reference rhs) noexcept
6444  {
6445  return !(lhs <= rhs);
6446  }
6447 
6452  template<typename ScalarType, typename std::enable_if<
6453  std::is_scalar<ScalarType>::value, int>::type = 0>
6454  friend bool operator>(const_reference lhs, const ScalarType rhs) noexcept
6455  {
6456  return lhs > basic_json(rhs);
6457  }
6458 
6463  template<typename ScalarType, typename std::enable_if<
6464  std::is_scalar<ScalarType>::value, int>::type = 0>
6465  friend bool operator>(const ScalarType lhs, const_reference rhs) noexcept
6466  {
6467  return basic_json(lhs) > rhs;
6468  }
6469 
6489  friend bool operator>=(const_reference lhs, const_reference rhs) noexcept
6490  {
6491  return !(lhs < rhs);
6492  }
6493 
6498  template<typename ScalarType, typename std::enable_if<
6499  std::is_scalar<ScalarType>::value, int>::type = 0>
6500  friend bool operator>=(const_reference lhs, const ScalarType rhs) noexcept
6501  {
6502  return lhs >= basic_json(rhs);
6503  }
6504 
6509  template<typename ScalarType, typename std::enable_if<
6510  std::is_scalar<ScalarType>::value, int>::type = 0>
6511  friend bool operator>=(const ScalarType lhs, const_reference rhs) noexcept
6512  {
6513  return basic_json(lhs) >= rhs;
6514  }
6515 
6517 
6519  // serialization //
6521 
6524 
6556  friend std::ostream& operator<<(std::ostream& o, const basic_json& j)
6557  {
6558  // read width member and use it as indentation parameter if nonzero
6559  const bool pretty_print = o.width() > 0;
6560  const auto indentation = pretty_print ? o.width() : 0;
6561 
6562  // reset width to 0 for subsequent calls to this stream
6563  o.width(0);
6564 
6565  // do the actual serialization
6566  serializer s(detail::output_adapter<char>(o), o.fill());
6567  s.dump(j, pretty_print, false, static_cast<unsigned int>(indentation));
6568  return o;
6569  }
6570 
6579  JSON_HEDLEY_DEPRECATED_FOR(3.0.0, operator<<(std::ostream&, const basic_json&))
6580  friend std::ostream& operator>>(const basic_json& j, std::ostream& o)
6581  {
6582  return o << j;
6583  }
6584 
6586 
6587 
6589  // deserialization //
6591 
6594 
6646  template<typename InputType>
6647  JSON_HEDLEY_WARN_UNUSED_RESULT
6648  static basic_json parse(InputType&& i,
6649  const parser_callback_t cb = nullptr,
6650  const bool allow_exceptions = true,
6651  const bool ignore_comments = false)
6652  {
6653  basic_json result;
6654  parser(detail::input_adapter(std::forward<InputType>(i)), cb, allow_exceptions, ignore_comments).parse(true, result);
6655  return result;
6656  }
6657 
6684  template<typename IteratorType>
6685  JSON_HEDLEY_WARN_UNUSED_RESULT
6686  static basic_json parse(IteratorType first,
6687  IteratorType last,
6688  const parser_callback_t cb = nullptr,
6689  const bool allow_exceptions = true,
6690  const bool ignore_comments = false)
6691  {
6692  basic_json result;
6693  parser(detail::input_adapter(std::move(first), std::move(last)), cb, allow_exceptions, ignore_comments).parse(true, result);
6694  return result;
6695  }
6696 
6697  JSON_HEDLEY_WARN_UNUSED_RESULT
6698  JSON_HEDLEY_DEPRECATED_FOR(3.8.0, parse(ptr, ptr + len))
6700  const parser_callback_t cb = nullptr,
6701  const bool allow_exceptions = true,
6702  const bool ignore_comments = false)
6703  {
6704  basic_json result;
6705  parser(i.get(), cb, allow_exceptions, ignore_comments).parse(true, result);
6706  return result;
6707  }
6708 
6739  template<typename InputType>
6740  static bool accept(InputType&& i,
6741  const bool ignore_comments = false)
6742  {
6743  return parser(detail::input_adapter(std::forward<InputType>(i)), nullptr, false, ignore_comments).accept(true);
6744  }
6745 
6746  template<typename IteratorType>
6747  static bool accept(IteratorType first, IteratorType last,
6748  const bool ignore_comments = false)
6749  {
6750  return parser(detail::input_adapter(std::move(first), std::move(last)), nullptr, false, ignore_comments).accept(true);
6751  }
6752 
6753  JSON_HEDLEY_WARN_UNUSED_RESULT
6754  JSON_HEDLEY_DEPRECATED_FOR(3.8.0, accept(ptr, ptr + len))
6755  static bool accept(detail::span_input_adapter&& i,
6756  const bool ignore_comments = false)
6757  {
6758  return parser(i.get(), nullptr, false, ignore_comments).accept(true);
6759  }
6760 
6801  template <typename InputType, typename SAX>
6802  JSON_HEDLEY_NON_NULL(2)
6803  static bool sax_parse(InputType&& i, SAX* sax,
6805  const bool strict = true,
6806  const bool ignore_comments = false)
6807  {
6808  auto ia = detail::input_adapter(std::forward<InputType>(i));
6809  return format == input_format_t::json
6810  ? parser(std::move(ia), nullptr, true, ignore_comments).sax_parse(sax, strict)
6811  : detail::binary_reader<basic_json, decltype(ia), SAX>(std::move(ia)).sax_parse(format, sax, strict);
6812  }
6813 
6814  template<class IteratorType, class SAX>
6815  JSON_HEDLEY_NON_NULL(3)
6816  static bool sax_parse(IteratorType first, IteratorType last, SAX* sax,
6817  input_format_t format = input_format_t::json,
6818  const bool strict = true,
6819  const bool ignore_comments = false)
6820  {
6821  auto ia = detail::input_adapter(std::move(first), std::move(last));
6822  return format == input_format_t::json
6823  ? parser(std::move(ia), nullptr, true, ignore_comments).sax_parse(sax, strict)
6824  : detail::binary_reader<basic_json, decltype(ia), SAX>(std::move(ia)).sax_parse(format, sax, strict);
6825  }
6826 
6827  template <typename SAX>
6828  JSON_HEDLEY_DEPRECATED_FOR(3.8.0, sax_parse(ptr, ptr + len, ...))
6829  JSON_HEDLEY_NON_NULL(2)
6830  static bool sax_parse(detail::span_input_adapter&& i, SAX* sax,
6831  input_format_t format = input_format_t::json,
6832  const bool strict = true,
6833  const bool ignore_comments = false)
6834  {
6835  auto ia = i.get();
6836  return format == input_format_t::json
6837  ? parser(std::move(ia), nullptr, true, ignore_comments).sax_parse(sax, strict)
6838  : detail::binary_reader<basic_json, decltype(ia), SAX>(std::move(ia)).sax_parse(format, sax, strict);
6839  }
6840 
6849  JSON_HEDLEY_DEPRECATED_FOR(3.0.0, operator>>(std::istream&, basic_json&))
6850  friend std::istream& operator<<(basic_json& j, std::istream& i)
6851  {
6852  return operator>>(i, j);
6853  }
6854 
6880  friend std::istream& operator>>(std::istream& i, basic_json& j)
6881  {
6882  parser(detail::input_adapter(i)).parse(false, j);
6883  return i;
6884  }
6885 
6887 
6889  // convenience functions //
6891 
6923  JSON_HEDLEY_RETURNS_NON_NULL
6924  const char* type_name() const noexcept
6925  {
6926  {
6927  switch (m_type)
6928  {
6929  case value_t::null:
6930  return "null";
6931  case value_t::object:
6932  return "object";
6933  case value_t::array:
6934  return "array";
6935  case value_t::string:
6936  return "string";
6937  case value_t::boolean:
6938  return "boolean";
6939  case value_t::binary:
6940  return "binary";
6941  case value_t::discarded:
6942  return "discarded";
6943  default:
6944  return "number";
6945  }
6946  }
6947  }
6948 
6949 
6950  private:
6952  // member variables //
6954 
6956  value_t m_type = value_t::null;
6957 
6959  json_value m_value = {};
6960 
6962  // binary serialization/deserialization //
6964 
6967 
6968  public:
7063  static std::vector<uint8_t> to_cbor(const basic_json& j)
7064  {
7065  std::vector<uint8_t> result;
7066  to_cbor(j, result);
7067  return result;
7068  }
7069 
7070  static void to_cbor(const basic_json& j, detail::output_adapter<uint8_t> o)
7071  {
7072  binary_writer<uint8_t>(o).write_cbor(j);
7073  }
7074 
7075  static void to_cbor(const basic_json& j, detail::output_adapter<char> o)
7076  {
7077  binary_writer<char>(o).write_cbor(j);
7078  }
7079 
7158  static std::vector<uint8_t> to_msgpack(const basic_json& j)
7159  {
7160  std::vector<uint8_t> result;
7161  to_msgpack(j, result);
7162  return result;
7163  }
7164 
7165  static void to_msgpack(const basic_json& j, detail::output_adapter<uint8_t> o)
7166  {
7167  binary_writer<uint8_t>(o).write_msgpack(j);
7168  }
7169 
7170  static void to_msgpack(const basic_json& j, detail::output_adapter<char> o)
7171  {
7172  binary_writer<char>(o).write_msgpack(j);
7173  }
7174 
7261  static std::vector<uint8_t> to_ubjson(const basic_json& j,
7262  const bool use_size = false,
7263  const bool use_type = false)
7264  {
7265  std::vector<uint8_t> result;
7266  to_ubjson(j, result, use_size, use_type);
7267  return result;
7268  }
7269 
7270  static void to_ubjson(const basic_json& j, detail::output_adapter<uint8_t> o,
7271  const bool use_size = false, const bool use_type = false)
7272  {
7273  binary_writer<uint8_t>(o).write_ubjson(j, use_size, use_type);
7274  }
7275 
7276  static void to_ubjson(const basic_json& j, detail::output_adapter<char> o,
7277  const bool use_size = false, const bool use_type = false)
7278  {
7279  binary_writer<char>(o).write_ubjson(j, use_size, use_type);
7280  }
7281 
7282 
7339  static std::vector<uint8_t> to_bson(const basic_json& j)
7340  {
7341  std::vector<uint8_t> result;
7342  to_bson(j, result);
7343  return result;
7344  }
7345 
7355  {
7357  }
7358 
7363  {
7365  }
7366 
7367 
7470  template<typename InputType>
7471  JSON_HEDLEY_WARN_UNUSED_RESULT
7472  static basic_json from_cbor(InputType&& i,
7473  const bool strict = true,
7474  const bool allow_exceptions = true,
7475  const cbor_tag_handler_t tag_handler = cbor_tag_handler_t::error)
7476  {
7477  basic_json result;
7478  detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
7479  auto ia = detail::input_adapter(std::forward<InputType>(i));
7480  const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::cbor, &sdp, strict, tag_handler);
7481  return res ? result : basic_json(value_t::discarded);
7482  }
7483 
7487  template<typename IteratorType>
7488  JSON_HEDLEY_WARN_UNUSED_RESULT
7489  static basic_json from_cbor(IteratorType first, IteratorType last,
7490  const bool strict = true,
7491  const bool allow_exceptions = true,
7492  const cbor_tag_handler_t tag_handler = cbor_tag_handler_t::error)
7493  {
7494  basic_json result;
7495  detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
7496  auto ia = detail::input_adapter(std::move(first), std::move(last));
7497  const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::cbor, &sdp, strict, tag_handler);
7498  return res ? result : basic_json(value_t::discarded);
7499  }
7500 
7501  template<typename T>
7502  JSON_HEDLEY_WARN_UNUSED_RESULT
7503  JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_cbor(ptr, ptr + len))
7504  static basic_json from_cbor(const T* ptr, std::size_t len,
7505  const bool strict = true,
7506  const bool allow_exceptions = true,
7507  const cbor_tag_handler_t tag_handler = cbor_tag_handler_t::error)
7508  {
7509  return from_cbor(ptr, ptr + len, strict, allow_exceptions, tag_handler);
7510  }
7511 
7512 
7513  JSON_HEDLEY_WARN_UNUSED_RESULT
7514  JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_cbor(ptr, ptr + len))
7515  static basic_json from_cbor(detail::span_input_adapter&& i,
7516  const bool strict = true,
7517  const bool allow_exceptions = true,
7518  const cbor_tag_handler_t tag_handler = cbor_tag_handler_t::error)
7519  {
7520  basic_json result;
7521  detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
7522  auto ia = i.get();
7523  const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::cbor, &sdp, strict, tag_handler);
7524  return res ? result : basic_json(value_t::discarded);
7525  }
7526 
7613  template<typename InputType>
7614  JSON_HEDLEY_WARN_UNUSED_RESULT
7615  static basic_json from_msgpack(InputType&& i,
7616  const bool strict = true,
7617  const bool allow_exceptions = true)
7618  {
7619  basic_json result;
7620  detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
7621  auto ia = detail::input_adapter(std::forward<InputType>(i));
7622  const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::msgpack, &sdp, strict);
7623  return res ? result : basic_json(value_t::discarded);
7624  }
7625 
7629  template<typename IteratorType>
7630  JSON_HEDLEY_WARN_UNUSED_RESULT
7631  static basic_json from_msgpack(IteratorType first, IteratorType last,
7632  const bool strict = true,
7633  const bool allow_exceptions = true)
7634  {
7635  basic_json result;
7636  detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
7637  auto ia = detail::input_adapter(std::move(first), std::move(last));
7638  const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::msgpack, &sdp, strict);
7639  return res ? result : basic_json(value_t::discarded);
7640  }
7641 
7642 
7643  template<typename T>
7644  JSON_HEDLEY_WARN_UNUSED_RESULT
7645  JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_msgpack(ptr, ptr + len))
7646  static basic_json from_msgpack(const T* ptr, std::size_t len,
7647  const bool strict = true,
7648  const bool allow_exceptions = true)
7649  {
7650  return from_msgpack(ptr, ptr + len, strict, allow_exceptions);
7651  }
7652 
7653  JSON_HEDLEY_WARN_UNUSED_RESULT
7654  JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_msgpack(ptr, ptr + len))
7655  static basic_json from_msgpack(detail::span_input_adapter&& i,
7656  const bool strict = true,
7657  const bool allow_exceptions = true)
7658  {
7659  basic_json result;
7660  detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
7661  auto ia = i.get();
7662  const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::msgpack, &sdp, strict);
7663  return res ? result : basic_json(value_t::discarded);
7664  }
7665 
7666 
7729  template<typename InputType>
7730  JSON_HEDLEY_WARN_UNUSED_RESULT
7731  static basic_json from_ubjson(InputType&& i,
7732  const bool strict = true,
7733  const bool allow_exceptions = true)
7734  {
7735  basic_json result;
7736  detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
7737  auto ia = detail::input_adapter(std::forward<InputType>(i));
7738  const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::ubjson, &sdp, strict);
7739  return res ? result : basic_json(value_t::discarded);
7740  }
7741 
7745  template<typename IteratorType>
7746  JSON_HEDLEY_WARN_UNUSED_RESULT
7747  static basic_json from_ubjson(IteratorType first, IteratorType last,
7748  const bool strict = true,
7749  const bool allow_exceptions = true)
7750  {
7751  basic_json result;
7752  detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
7753  auto ia = detail::input_adapter(std::move(first), std::move(last));
7754  const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::ubjson, &sdp, strict);
7755  return res ? result : basic_json(value_t::discarded);
7756  }
7757 
7758  template<typename T>
7759  JSON_HEDLEY_WARN_UNUSED_RESULT
7760  JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_ubjson(ptr, ptr + len))
7761  static basic_json from_ubjson(const T* ptr, std::size_t len,
7762  const bool strict = true,
7763  const bool allow_exceptions = true)
7764  {
7765  return from_ubjson(ptr, ptr + len, strict, allow_exceptions);
7766  }
7767 
7768  JSON_HEDLEY_WARN_UNUSED_RESULT
7769  JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_ubjson(ptr, ptr + len))
7770  static basic_json from_ubjson(detail::span_input_adapter&& i,
7771  const bool strict = true,
7772  const bool allow_exceptions = true)
7773  {
7774  basic_json result;
7775  detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
7776  auto ia = i.get();
7777  const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::ubjson, &sdp, strict);
7778  return res ? result : basic_json(value_t::discarded);
7779  }
7780 
7781 
7842  template<typename InputType>
7843  JSON_HEDLEY_WARN_UNUSED_RESULT
7844  static basic_json from_bson(InputType&& i,
7845  const bool strict = true,
7846  const bool allow_exceptions = true)
7847  {
7848  basic_json result;
7849  detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
7850  auto ia = detail::input_adapter(std::forward<InputType>(i));
7851  const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::bson, &sdp, strict);
7852  return res ? result : basic_json(value_t::discarded);
7853  }
7854 
7858  template<typename IteratorType>
7859  JSON_HEDLEY_WARN_UNUSED_RESULT
7860  static basic_json from_bson(IteratorType first, IteratorType last,
7861  const bool strict = true,
7862  const bool allow_exceptions = true)
7863  {
7864  basic_json result;
7865  detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
7866  auto ia = detail::input_adapter(std::move(first), std::move(last));
7867  const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::bson, &sdp, strict);
7868  return res ? result : basic_json(value_t::discarded);
7869  }
7870 
7871  template<typename T>
7872  JSON_HEDLEY_WARN_UNUSED_RESULT
7873  JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_bson(ptr, ptr + len))
7874  static basic_json from_bson(const T* ptr, std::size_t len,
7875  const bool strict = true,
7876  const bool allow_exceptions = true)
7877  {
7878  return from_bson(ptr, ptr + len, strict, allow_exceptions);
7879  }
7880 
7881  JSON_HEDLEY_WARN_UNUSED_RESULT
7882  JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_bson(ptr, ptr + len))
7883  static basic_json from_bson(detail::span_input_adapter&& i,
7884  const bool strict = true,
7885  const bool allow_exceptions = true)
7886  {
7887  basic_json result;
7888  detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
7889  auto ia = i.get();
7890  const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::bson, &sdp, strict);
7891  return res ? result : basic_json(value_t::discarded);
7892  }
7894 
7896  // JSON Pointer support //
7898 
7901 
7936  {
7937  return ptr.get_unchecked(this);
7938  }
7939 
7964  {
7965  return ptr.get_unchecked(this);
7966  }
7967 
8007  {
8008  return ptr.get_checked(this);
8009  }
8010 
8049  const_reference at(const json_pointer& ptr) const
8050  {
8051  return ptr.get_checked(this);
8052  }
8053 
8077  {
8078  basic_json result(value_t::object);
8079  json_pointer::flatten("", *this, result);
8080  return result;
8081  }
8082 
8114  {
8115  return json_pointer::unflatten(*this);
8116  }
8117 
8119 
8121  // JSON Patch functions //
8123 
8126 
8174  basic_json patch(const basic_json& json_patch) const
8175  {
8176  // make a working copy to apply the patch to
8177  basic_json result = *this;
8178 
8179  // the valid JSON Patch operations
8180  enum class patch_operations {add, remove, replace, move, copy, test, invalid};
8181 
8182  const auto get_op = [](const std::string & op)
8183  {
8184  if (op == "add")
8185  {
8186  return patch_operations::add;
8187  }
8188  if (op == "remove")
8189  {
8190  return patch_operations::remove;
8191  }
8192  if (op == "replace")
8193  {
8194  return patch_operations::replace;
8195  }
8196  if (op == "move")
8197  {
8198  return patch_operations::move;
8199  }
8200  if (op == "copy")
8201  {
8202  return patch_operations::copy;
8203  }
8204  if (op == "test")
8205  {
8206  return patch_operations::test;
8207  }
8208 
8209  return patch_operations::invalid;
8210  };
8211 
8212  // wrapper for "add" operation; add value at ptr
8213  const auto operation_add = [&result](json_pointer & ptr, basic_json val)
8214  {
8215  // adding to the root of the target document means replacing it
8216  if (ptr.empty())
8217  {
8218  result = val;
8219  return;
8220  }
8221 
8222  // make sure the top element of the pointer exists
8223  json_pointer top_pointer = ptr.top();
8224  if (top_pointer != ptr)
8225  {
8226  result.at(top_pointer);
8227  }
8228 
8229  // get reference to parent of JSON pointer ptr
8230  const auto last_path = ptr.back();
8231  ptr.pop_back();
8232  basic_json& parent = result[ptr];
8233 
8234  switch (parent.m_type)
8235  {
8236  case value_t::null:
8237  case value_t::object:
8238  {
8239  // use operator[] to add value
8240  parent[last_path] = val;
8241  break;
8242  }
8243 
8244  case value_t::array:
8245  {
8246  if (last_path == "-")
8247  {
8248  // special case: append to back
8249  parent.push_back(val);
8250  }
8251  else
8252  {
8253  const auto idx = json_pointer::array_index(last_path);
8254  if (JSON_HEDLEY_UNLIKELY(idx > parent.size()))
8255  {
8256  // avoid undefined behavior
8257  JSON_THROW(out_of_range::create(401, "array index " + std::to_string(idx) + " is out of range"));
8258  }
8259 
8260  // default case: insert add offset
8261  parent.insert(parent.begin() + static_cast<difference_type>(idx), val);
8262  }
8263  break;
8264  }
8265 
8266  // if there exists a parent it cannot be primitive
8267  default: // LCOV_EXCL_LINE
8268  JSON_ASSERT(false); // LCOV_EXCL_LINE
8269  }
8270  };
8271 
8272  // wrapper for "remove" operation; remove value at ptr
8273  const auto operation_remove = [&result](json_pointer & ptr)
8274  {
8275  // get reference to parent of JSON pointer ptr
8276  const auto last_path = ptr.back();
8277  ptr.pop_back();
8278  basic_json& parent = result.at(ptr);
8279 
8280  // remove child
8281  if (parent.is_object())
8282  {
8283  // perform range check
8284  auto it = parent.find(last_path);
8285  if (JSON_HEDLEY_LIKELY(it != parent.end()))
8286  {
8287  parent.erase(it);
8288  }
8289  else
8290  {
8291  JSON_THROW(out_of_range::create(403, "key '" + last_path + "' not found"));
8292  }
8293  }
8294  else if (parent.is_array())
8295  {
8296  // note erase performs range check
8297  parent.erase(json_pointer::array_index(last_path));
8298  }
8299  };
8300 
8301  // type check: top level value must be an array
8302  if (JSON_HEDLEY_UNLIKELY(!json_patch.is_array()))
8303  {
8304  JSON_THROW(parse_error::create(104, 0, "JSON patch must be an array of objects"));
8305  }
8306 
8307  // iterate and apply the operations
8308  for (const auto& val : json_patch)
8309  {
8310  // wrapper to get a value for an operation
8311  const auto get_value = [&val](const std::string & op,
8312  const std::string & member,
8313  bool string_type) -> basic_json &
8314  {
8315  // find value
8316  auto it = val.m_value.object->find(member);
8317 
8318  // context-sensitive error message
8319  const auto error_msg = (op == "op") ? "operation" : "operation '" + op + "'";
8320 
8321  // check if desired value is present
8322  if (JSON_HEDLEY_UNLIKELY(it == val.m_value.object->end()))
8323  {
8324  JSON_THROW(parse_error::create(105, 0, error_msg + " must have member '" + member + "'"));
8325  }
8326 
8327  // check if result is of type string
8328  if (JSON_HEDLEY_UNLIKELY(string_type && !it->second.is_string()))
8329  {
8330  JSON_THROW(parse_error::create(105, 0, error_msg + " must have string member '" + member + "'"));
8331  }
8332 
8333  // no error: return value
8334  return it->second;
8335  };
8336 
8337  // type check: every element of the array must be an object
8338  if (JSON_HEDLEY_UNLIKELY(!val.is_object()))
8339  {
8340  JSON_THROW(parse_error::create(104, 0, "JSON patch must be an array of objects"));
8341  }
8342 
8343  // collect mandatory members
8344  const auto op = get_value("op", "op", true).template get<std::string>();
8345  const auto path = get_value(op, "path", true).template get<std::string>();
8346  json_pointer ptr(path);
8347 
8348  switch (get_op(op))
8349  {
8350  case patch_operations::add:
8351  {
8352  operation_add(ptr, get_value("add", "value", false));
8353  break;
8354  }
8355 
8356  case patch_operations::remove:
8357  {
8358  operation_remove(ptr);
8359  break;
8360  }
8361 
8362  case patch_operations::replace:
8363  {
8364  // the "path" location must exist - use at()
8365  result.at(ptr) = get_value("replace", "value", false);
8366  break;
8367  }
8368 
8369  case patch_operations::move:
8370  {
8371  const auto from_path = get_value("move", "from", true).template get<std::string>();
8372  json_pointer from_ptr(from_path);
8373 
8374  // the "from" location must exist - use at()
8375  basic_json v = result.at(from_ptr);
8376 
8377  // The move operation is functionally identical to a
8378  // "remove" operation on the "from" location, followed
8379  // immediately by an "add" operation at the target
8380  // location with the value that was just removed.
8381  operation_remove(from_ptr);
8382  operation_add(ptr, v);
8383  break;
8384  }
8385 
8386  case patch_operations::copy:
8387  {
8388  const auto from_path = get_value("copy", "from", true).template get<std::string>();
8389  const json_pointer from_ptr(from_path);
8390 
8391  // the "from" location must exist - use at()
8392  basic_json v = result.at(from_ptr);
8393 
8394  // The copy is functionally identical to an "add"
8395  // operation at the target location using the value
8396  // specified in the "from" member.
8397  operation_add(ptr, v);
8398  break;
8399  }
8400 
8401  case patch_operations::test:
8402  {
8403  bool success = false;
8404  JSON_TRY
8405  {
8406  // check if "value" matches the one at "path"
8407  // the "path" location must exist - use at()
8408  success = (result.at(ptr) == get_value("test", "value", false));
8409  }
8410  JSON_INTERNAL_CATCH (out_of_range&)
8411  {
8412  // ignore out of range errors: success remains false
8413  }
8414 
8415  // throw an exception if test fails
8416  if (JSON_HEDLEY_UNLIKELY(!success))
8417  {
8418  JSON_THROW(other_error::create(501, "unsuccessful: " + val.dump()));
8419  }
8420 
8421  break;
8422  }
8423 
8424  default:
8425  {
8426  // op must be "add", "remove", "replace", "move", "copy", or
8427  // "test"
8428  JSON_THROW(parse_error::create(105, 0, "operation value '" + op + "' is invalid"));
8429  }
8430  }
8431  }
8432 
8433  return result;
8434  }
8435 
8469  JSON_HEDLEY_WARN_UNUSED_RESULT
8470  static basic_json diff(const basic_json& source, const basic_json& target,
8471  const std::string& path = "")
8472  {
8473  // the patch
8474  basic_json result(value_t::array);
8475 
8476  // if the values are the same, return empty patch
8477  if (source == target)
8478  {
8479  return result;
8480  }
8481 
8482  if (source.type() != target.type())
8483  {
8484  // different types: replace value
8485  result.push_back(
8486  {
8487  {"op", "replace"}, {"path", path}, {"value", target}
8488  });
8489  return result;
8490  }
8491 
8492  switch (source.type())
8493  {
8494  case value_t::array:
8495  {
8496  // first pass: traverse common elements
8497  std::size_t i = 0;
8498  while (i < source.size() && i < target.size())
8499  {
8500  // recursive call to compare array values at index i
8501  auto temp_diff = diff(source[i], target[i], path + "/" + std::to_string(i));
8502  result.insert(result.end(), temp_diff.begin(), temp_diff.end());
8503  ++i;
8504  }
8505 
8506  // i now reached the end of at least one array
8507  // in a second pass, traverse the remaining elements
8508 
8509  // remove my remaining elements
8510  const auto end_index = static_cast<difference_type>(result.size());
8511  while (i < source.size())
8512  {
8513  // add operations in reverse order to avoid invalid
8514  // indices
8515  result.insert(result.begin() + end_index, object(
8516  {
8517  {"op", "remove"},
8518  {"path", path + "/" + std::to_string(i)}
8519  }));
8520  ++i;
8521  }
8522 
8523  // add other remaining elements
8524  while (i < target.size())
8525  {
8526  result.push_back(
8527  {
8528  {"op", "add"},
8529  {"path", path + "/-"},
8530  {"value", target[i]}
8531  });
8532  ++i;
8533  }
8534 
8535  break;
8536  }
8537 
8538  case value_t::object:
8539  {
8540  // first pass: traverse this object's elements
8541  for (auto it = source.cbegin(); it != source.cend(); ++it)
8542  {
8543  // escape the key name to be used in a JSON patch
8544  const auto key = json_pointer::escape(it.key());
8545 
8546  if (target.find(it.key()) != target.end())
8547  {
8548  // recursive call to compare object values at key it
8549  auto temp_diff = diff(it.value(), target[it.key()], path + "/" + key);
8550  result.insert(result.end(), temp_diff.begin(), temp_diff.end());
8551  }
8552  else
8553  {
8554  // found a key that is not in o -> remove it
8555  result.push_back(object(
8556  {
8557  {"op", "remove"}, {"path", path + "/" + key}
8558  }));
8559  }
8560  }
8561 
8562  // second pass: traverse other object's elements
8563  for (auto it = target.cbegin(); it != target.cend(); ++it)
8564  {
8565  if (source.find(it.key()) == source.end())
8566  {
8567  // found a key that is not in this -> add it
8568  const auto key = json_pointer::escape(it.key());
8569  result.push_back(
8570  {
8571  {"op", "add"}, {"path", path + "/" + key},
8572  {"value", it.value()}
8573  });
8574  }
8575  }
8576 
8577  break;
8578  }
8579 
8580  default:
8581  {
8582  // both primitive type: replace value
8583  result.push_back(
8584  {
8585  {"op", "replace"}, {"path", path}, {"value", target}
8586  });
8587  break;
8588  }
8589  }
8590 
8591  return result;
8592  }
8593 
8595 
8597  // JSON Merge Patch functions //
8599 
8602 
8645  void merge_patch(const basic_json& apply_patch)
8646  {
8647  if (apply_patch.is_object())
8648  {
8649  if (!is_object())
8650  {
8651  *this = object();
8652  }
8653  for (auto it = apply_patch.begin(); it != apply_patch.end(); ++it)
8654  {
8655  if (it.value().is_null())
8656  {
8657  erase(it.key());
8658  }
8659  else
8660  {
8661  operator[](it.key()).merge_patch(it.value());
8662  }
8663  }
8664  }
8665  else
8666  {
8667  *this = apply_patch;
8668  }
8669  }
8670 
8672 };
8673 
8683 NLOHMANN_BASIC_JSON_TPL_DECLARATION
8684 std::string to_string(const NLOHMANN_BASIC_JSON_TPL& j)
8685 {
8686  return j.dump();
8687 }
8688 } // namespace nlohmann
8689 
8691 // nonmember support //
8693 
8694 // specialization of std::swap, and std::hash
8695 namespace std
8696 {
8697 
8699 template<>
8700 struct hash<nlohmann::json>
8701 {
8707  std::size_t operator()(const nlohmann::json& j) const
8708  {
8709  return nlohmann::detail::hash(j);
8710  }
8711 };
8712 
8716 template<>
8718 {
8724  nlohmann::detail::value_t rhs) const noexcept
8725  {
8726  return nlohmann::detail::operator<(lhs, rhs);
8727  }
8728 };
8729 
8730 // C++20 prohibit function specialization in the std namespace.
8731 #ifndef JSON_HAS_CPP_20
8732 
8738 template<>
8739 inline void swap<nlohmann::json>(nlohmann::json& j1, nlohmann::json& j2) noexcept(
8740  is_nothrow_move_constructible<nlohmann::json>::value&&
8741  is_nothrow_move_assignable<nlohmann::json>::value
8742 )
8743 {
8744  j1.swap(j2);
8745 }
8746 
8747 #endif
8748 
8749 } // namespace std
8750 
8764 JSON_HEDLEY_NON_NULL(1)
8765 inline nlohmann::json operator "" _json(const char* s, std::size_t n)
8766 {
8767  return nlohmann::json::parse(s, s + n);
8768 }
8769 
8783 JSON_HEDLEY_NON_NULL(1)
8784 inline nlohmann::json::json_pointer operator "" _json_pointer(const char* s, std::size_t n)
8785 {
8786  return nlohmann::json::json_pointer(std::string(s, n));
8787 }
8788 
8789 #include <nlohmann/detail/macro_unscope.hpp>
8790 
8791 #endif // INCLUDE_NLOHMANN_JSON_HPP_
a class to store JSON values
Definition: json.hpp:170
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json binary(typename binary_t::container_type &&init, std::uint8_t subtype)
explicitly create a binary array (with subtype)
Definition: json.hpp:1736
constexpr auto get() const noexcept -> decltype(std::declval< const basic_json_t & >().template get_ptr< PointerType >())
get a pointer value (explicit)
Definition: json.hpp:3139
void insert(const_iterator first, const_iterator last)
inserts elements
Definition: json.hpp:5727
detail::parser_callback_t< basic_json > parser_callback_t
per-element parser callback type
Definition: json.hpp:1301
bool contains(KeyT &&key) const
check the existence of an element in a JSON object
Definition: json.hpp:4408
const_reverse_iterator crbegin() const noexcept
returns a const reverse iterator to the last element
Definition: json.hpp:4693
const_reference operator[](const json_pointer &ptr) const
access specified element via JSON Pointer
Definition: json.hpp:7963
basic_json get() const
get special-case overload
Definition: json.hpp:2848
reference operator[](const json_pointer &ptr)
access specified element via JSON Pointer
Definition: json.hpp:7935
ValueType value(const typename object_t::key_type &key, const ValueType &default_value) const
access specified object element with default value
Definition: json.hpp:3791
constexpr bool is_number_float() const noexcept
return whether value is a floating-point number
Definition: json.hpp:2541
NumberIntegerType number_integer_t
a type for a number (integer)
Definition: json.hpp:700
friend bool operator==(const_reference lhs, const_reference rhs) noexcept
comparison: equal
Definition: json.hpp:6122
friend bool operator>(const ScalarType lhs, const_reference rhs) noexcept
comparison: greater than
Definition: json.hpp:6465
static bool sax_parse(InputType &&i, SAX *sax, input_format_t format=input_format_t::json, const bool strict=true, const bool ignore_comments=false)
generate SAX events
Definition: json.hpp:6803
ReferenceType get_ref()
get a reference value (implicit)
Definition: json.hpp:3173
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json parse(InputType &&i, const parser_callback_t cb=nullptr, const bool allow_exceptions=true, const bool ignore_comments=false)
deserialize from a compatible input
Definition: json.hpp:6648
reference emplace_back(Args &&... args)
add an object to an array
Definition: json.hpp:5413
const_iterator find(KeyT &&key) const
find an element in a JSON object
Definition: json.hpp:4341
basic_json(const value_t v)
create an empty value with a given type
Definition: json.hpp:1342
basic_json & operator=(basic_json other) noexcept(std::is_nothrow_move_constructible< value_t >::value &&std::is_nothrow_move_assignable< value_t >::value &&std::is_nothrow_move_constructible< json_value >::value &&std::is_nothrow_move_assignable< json_value >::value)
copy assignment
Definition: json.hpp:2174
size_type max_size() const noexcept
returns the maximum possible number of elements
Definition: json.hpp:5077
basic_json(CompatibleType &&val) noexcept(noexcept(JSONSerializer< U >::to_json(std::declval< basic_json_t & >(), std::forward< CompatibleType >(val))))
create a JSON value
Definition: json.hpp:1439
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json diff(const basic_json &source, const basic_json &target, const std::string &path="")
creates a diff as a JSON patch
Definition: json.hpp:8470
void erase(const size_type idx)
remove element from a JSON array given an index
Definition: json.hpp:4271
const_reverse_iterator crend() const noexcept
returns a const reverse iterator to one before the first
Definition: json.hpp:4722
const_reference at(const typename object_t::key_type &key) const
access specified object element with bounds checking
Definition: json.hpp:3454
static iteration_proxy< iterator > iterator_wrapper(reference ref) noexcept
wrapper to access iterator member functions in range-based for
Definition: json.hpp:4786
reference at(const typename object_t::key_type &key)
access specified object element with bounds checking
Definition: json.hpp:3403
iterator begin() noexcept
returns an iterator to the first element
Definition: json.hpp:4478
basic_json(InputIT first, InputIT last)
construct a JSON container given an iterator range
Definition: json.hpp:1918
static std::vector< uint8_t > to_ubjson(const basic_json &j, const bool use_size=false, const bool use_type=false)
create a UBJSON serialization of a given JSON value
Definition: json.hpp:7261
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json array(initializer_list_t init={})
explicitly create an array from an initializer list
Definition: json.hpp:1782
const_reverse_iterator rend() const noexcept
returns a const reverse iterator to one before the first
Definition: json.hpp:4664
const_iterator cend() const noexcept
returns a const iterator to one past the last element
Definition: json.hpp:4589
reference back()
access the last element
Definition: json.hpp:3961
static bool accept(InputType &&i, const bool ignore_comments=false)
check if the input is valid JSON
Definition: json.hpp:6740
StringType string_t
a type for a string
Definition: json.hpp:602
size_type size() const noexcept
returns the number of elements
Definition: json.hpp:5006
void push_back(const basic_json &val)
add an object to an array
Definition: json.hpp:5260
friend std::ostream & operator>>(const basic_json &j, std::ostream &o)
serialize to stream
Definition: json.hpp:6580
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json meta()
returns version information on the library
Definition: json.hpp:343
ValueType value(const json_pointer &ptr, const ValueType &default_value) const
access specified object element via JSON Pointer with default value
Definition: json.hpp:3863
void update(const_reference j)
updates a JSON object from another object, overwriting existing keys
Definition: json.hpp:5769
std::size_t size_type
a type to represent container sizes
Definition: json.hpp:286
std::ptrdiff_t difference_type
a type to represent differences between iterators
Definition: json.hpp:284
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json binary(const typename binary_t::container_type &init)
explicitly create a binary array (without subtype)
Definition: json.hpp:1679
reference operator[](const typename object_t::key_type &key)
access specified object element
Definition: json.hpp:3584
reference operator+=(basic_json &&val)
add an object to an array
Definition: json.hpp:5250
basic_json(const BasicJsonType &val)
create a JSON value from an existing one
Definition: json.hpp:1476
typename std::allocator_traits< allocator_type >::const_pointer const_pointer
the type of an element const pointer
Definition: json.hpp:294
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json from_bson(IteratorType first, IteratorType last, const bool strict=true, const bool allow_exceptions=true)
Definition: json.hpp:7860
friend bool operator>(const_reference lhs, const ScalarType rhs) noexcept
comparison: greater than
Definition: json.hpp:6454
typename std::allocator_traits< allocator_type >::pointer pointer
the type of an element pointer
Definition: json.hpp:292
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json from_cbor(InputType &&i, const bool strict=true, const bool allow_exceptions=true, const cbor_tag_handler_t tag_handler=cbor_tag_handler_t::error)
create a JSON value from an input in CBOR format
Definition: json.hpp:7472
BooleanType boolean_t
a type for a boolean
Definition: json.hpp:628
void push_back(initializer_list_t init)
add an object to an object
Definition: json.hpp:5365
JSON_HEDLEY_RETURNS_NON_NULL const char * type_name() const noexcept
return the type as string
Definition: json.hpp:6924
string_t dump(const int indent=-1, const char indent_char=' ', const bool ensure_ascii=false, const error_handler_t error_handler=error_handler_t::strict) const
serialization
Definition: json.hpp:2271
IteratorType erase(IteratorType pos)
remove element given an iterator
Definition: json.hpp:4028
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json from_bson(InputType &&i, const bool strict=true, const bool allow_exceptions=true)
Create a JSON value from an input in BSON format.
Definition: json.hpp:7844
constexpr bool is_structured() const noexcept
return whether type is structured
Definition: json.hpp:2382
const_iterator begin() const noexcept
returns a const iterator to the first element
Definition: json.hpp:4488
iteration_proxy< const_iterator > items() const noexcept
helper to access iterator member functions in range-based for
Definition: json.hpp:4876
reference at(size_type idx)
access specified array element with bounds checking
Definition: json.hpp:3305
reference front()
access the first element
Definition: json.hpp:3917
constexpr bool is_primitive() const noexcept
return whether type is primitive
Definition: json.hpp:2355
constexpr bool is_number_unsigned() const noexcept
return whether value is an unsigned integer number
Definition: json.hpp:2513
detail::cbor_tag_handler_t cbor_tag_handler_t
how to treat CBOR tags
Definition: json.hpp:234
void swap(object_t &other)
exchanges the values
Definition: json.hpp:5964
constexpr bool is_object() const noexcept
return whether value is an object
Definition: json.hpp:2563
const_reference front() const
access the first element
Definition: json.hpp:3925
constexpr value_t type() const noexcept
return the type of the JSON value (explicit)
Definition: json.hpp:2324
NumberFloatType number_float_t
a type for a number (floating-point)
Definition: json.hpp:839
json_reverse_iterator< typename basic_json::iterator > reverse_iterator
a reverse iterator for a basic_json container
Definition: json.hpp:301
friend bool operator<=(const_reference lhs, const_reference rhs) noexcept
comparison: less than or equal
Definition: json.hpp:6397
bool empty() const noexcept
checks whether the container is empty.
Definition: json.hpp:4933
friend std::ostream & operator<<(std::ostream &o, const basic_json &j)
serialize to stream
Definition: json.hpp:6556
friend bool operator>=(const ScalarType lhs, const_reference rhs) noexcept
comparison: greater than or equal
Definition: json.hpp:6511
basic_json(const basic_json &other)
copy constructor
Definition: json.hpp:2048
~basic_json() noexcept
destructor
Definition: json.hpp:2207
BasicJsonType get() const
get special-case overload
Definition: json.hpp:2871
basic_json(basic_json &&other) noexcept
move constructor
Definition: json.hpp:2137
static void to_bson(const basic_json &j, detail::output_adapter< uint8_t > o)
Serializes the given JSON object j to BSON and forwards the corresponding BSON-representation to the ...
Definition: json.hpp:7354
friend bool operator>=(const_reference lhs, const ScalarType rhs) noexcept
comparison: greater than or equal
Definition: json.hpp:6500
friend bool operator!=(const_reference lhs, const_reference rhs) noexcept
comparison: not equal
Definition: json.hpp:6230
iterator insert(const_iterator pos, size_type cnt, const basic_json &val)
inserts elements
Definition: json.hpp:5585
void swap(typename binary_t::container_type &other)
Definition: json.hpp:6044
friend bool operator>=(const_reference lhs, const_reference rhs) noexcept
comparison: greater than or equal
Definition: json.hpp:6489
void swap(array_t &other)
exchanges the values
Definition: json.hpp:5931
friend bool operator<(const_reference lhs, const ScalarType rhs) noexcept
comparison: less than
Definition: json.hpp:6362
reverse_iterator rend() noexcept
returns an iterator to the reverse-end
Definition: json.hpp:4656
friend bool operator<=(const_reference lhs, const ScalarType rhs) noexcept
comparison: less than or equal
Definition: json.hpp:6408
ReferenceType get_ref() const
get a reference value (implicit)
Definition: json.hpp:3186
iterator insert(const_iterator pos, const_iterator first, const_iterator last)
inserts elements
Definition: json.hpp:5633
auto get() noexcept -> decltype(std::declval< basic_json_t & >().template get_ptr< PointerType >())
get a pointer value (explicit)
Definition: json.hpp:3127
const_reference at(const json_pointer &ptr) const
access specified element via JSON Pointer
Definition: json.hpp:8049
const_iterator end() const noexcept
returns a const iterator to one past the last element
Definition: json.hpp:4559
void merge_patch(const basic_json &apply_patch)
applies a JSON Merge Patch
Definition: json.hpp:8645
auto get_ptr() noexcept -> decltype(std::declval< basic_json_t & >().get_impl_ptr(std::declval< PointerType >()))
get a pointer value (implicit)
Definition: json.hpp:3079
iterator insert(const_iterator pos, initializer_list_t ilist)
inserts elements
Definition: json.hpp:5686
ArrayType< basic_json, AllocatorType< basic_json > > array_t
a type for an array
Definition: json.hpp:549
friend bool operator>(const_reference lhs, const_reference rhs) noexcept
comparison: greater than
Definition: json.hpp:6443
IteratorType erase(IteratorType first, IteratorType last)
remove elements given an iterator range
Definition: json.hpp:4141
ValueType get() const noexcept(noexcept(JSONSerializer< ValueType >::from_json(std::declval< const basic_json_t & >(), std::declval< ValueType & >())))
get a value (explicit)
Definition: json.hpp:2921
constexpr bool is_boolean() const noexcept
return whether value is a boolean
Definition: json.hpp:2426
iteration_proxy< iterator > items() noexcept
helper to access iterator member functions in range-based for
Definition: json.hpp:4868
iterator end() noexcept
returns an iterator to one past the last element
Definition: json.hpp:4549
void swap(reference other) noexcept(std::is_nothrow_move_constructible< value_t >::value &&std::is_nothrow_move_assignable< value_t >::value &&std::is_nothrow_move_constructible< json_value >::value &&std::is_nothrow_move_assignable< json_value >::value)
exchanges the values
Definition: json.hpp:5871
void clear() noexcept
clears the contents
Definition: json.hpp:5148
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json from_msgpack(IteratorType first, IteratorType last, const bool strict=true, const bool allow_exceptions=true)
Definition: json.hpp:7631
constexpr bool is_binary() const noexcept
return whether value is a binary array
Definition: json.hpp:2629
static std::vector< uint8_t > to_msgpack(const basic_json &j)
create a MessagePack serialization of a given JSON value
Definition: json.hpp:7158
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json object(initializer_list_t init={})
explicitly create an object from an initializer list
Definition: json.hpp:1826
iterator insert(const_iterator pos, basic_json &&val)
inserts element
Definition: json.hpp:5556
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json from_ubjson(IteratorType first, IteratorType last, const bool strict=true, const bool allow_exceptions=true)
Definition: json.hpp:7747
reference operator[](size_type idx)
access specified array element
Definition: json.hpp:3500
static void to_bson(const basic_json &j, detail::output_adapter< char > o)
Serializes the given JSON object j to BSON and forwards the corresponding BSON-representation to the ...
Definition: json.hpp:7362
void update(const_iterator first, const_iterator last)
updates a JSON object from another object, overwriting existing keys
Definition: json.hpp:5820
reference at(const json_pointer &ptr)
access specified element via JSON Pointer
Definition: json.hpp:8006
ValueType & get_to(ValueType &v) const noexcept(noexcept(JSONSerializer< ValueType >::from_json(std::declval< const basic_json_t & >(), v)))
get a value (explicit)
Definition: json.hpp:3018
void swap(binary_t &other)
exchanges the values
Definition: json.hpp:6030
static std::vector< uint8_t > to_bson(const basic_json &j)
Serializes the given JSON object j to BSON and returns a vector containing the corresponding BSON-rep...
Definition: json.hpp:7339
json_reverse_iterator< typename basic_json::const_iterator > const_reverse_iterator
a const reverse iterator for a basic_json container
Definition: json.hpp:303
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json from_ubjson(InputType &&i, const bool strict=true, const bool allow_exceptions=true)
create a JSON value from an input in UBJSON format
Definition: json.hpp:7731
::nlohmann::json_pointer< basic_json > json_pointer
JSON Pointer, see nlohmann::json_pointer.
Definition: json.hpp:228
const_reverse_iterator rbegin() const noexcept
returns a const reverse iterator to the last element
Definition: json.hpp:4627
binary_t & get_binary()
Definition: json.hpp:3247
void swap(string_t &other)
exchanges the values
Definition: json.hpp:5997
const_reference back() const
access the last element
Definition: json.hpp:3971
friend bool operator<(const_reference lhs, const_reference rhs) noexcept
comparison: less than
Definition: json.hpp:6283
friend std::istream & operator>>(std::istream &i, basic_json &j)
deserialize from stream
Definition: json.hpp:6880
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json binary(typename binary_t::container_type &&init)
explicitly create a binary array (without subtype)
Definition: json.hpp:1726
friend bool operator!=(const ScalarType lhs, const_reference rhs) noexcept
comparison: not equal
Definition: json.hpp:6252
constexpr bool is_string() const noexcept
return whether value is a string
Definition: json.hpp:2607
constexpr bool is_array() const noexcept
return whether value is an array
Definition: json.hpp:2585
iterator insert_iterator(const_iterator pos, Args &&... args)
Helper for insertion of an iterator.
Definition: json.hpp:5496
basic_json flatten() const
return flattened JSON value
Definition: json.hpp:8076
void push_back(basic_json &&val)
add an object to an array
Definition: json.hpp:5225
friend bool operator==(const_reference lhs, const ScalarType rhs) noexcept
comparison: equal
Definition: json.hpp:6196
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json from_cbor(IteratorType first, IteratorType last, const bool strict=true, const bool allow_exceptions=true, const cbor_tag_handler_t tag_handler=cbor_tag_handler_t::error)
Definition: json.hpp:7489
size_type count(KeyT &&key) const
returns the number of occurrences of a key in a JSON object
Definition: json.hpp:4375
const binary_t & get_binary() const
Definition: json.hpp:3258
constexpr bool is_number() const noexcept
return whether value is a number
Definition: json.hpp:2456
friend bool operator<(const ScalarType lhs, const_reference rhs) noexcept
comparison: less than
Definition: json.hpp:6373
std::pair< iterator, bool > emplace(Args &&... args)
add an object to an object if key does not exist
Definition: json.hpp:5466
reference operator+=(initializer_list_t init)
add an object to an object
Definition: json.hpp:5383
constexpr bool is_number_integer() const noexcept
return whether value is an integer number
Definition: json.hpp:2485
std::initializer_list< detail::json_ref< basic_json > > initializer_list_t
helper type for initializer lists of basic_json values
Definition: json.hpp:236
const_reference operator[](const typename object_t::key_type &key) const
read-only access specified object element
Definition: json.hpp:3633
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json binary(const typename binary_t::container_type &init, std::uint8_t subtype)
explicitly create a binary array (with subtype)
Definition: json.hpp:1716
iterator find(KeyT &&key)
find an element in a JSON object
Definition: json.hpp:4324
basic_json(std::nullptr_t=nullptr) noexcept
create a null object
Definition: json.hpp:1366
const_reference operator[](size_type idx) const
access specified array element
Definition: json.hpp:3546
AllocatorType< basic_json > allocator_type
the allocator type
Definition: json.hpp:289
nlohmann::byte_container_with_subtype< BinaryType > binary_t
a type for a packed binary type
Definition: json.hpp:910
void push_back(const typename object_t::value_type &val)
add an object to an object
Definition: json.hpp:5310
friend bool operator<=(const ScalarType lhs, const_reference rhs) noexcept
comparison: less than or equal
Definition: json.hpp:6419
ValueType get() const noexcept(noexcept(JSONSerializer< ValueType >::from_json(std::declval< const basic_json_t & >())))
get a value (explicit); special case
Definition: json.hpp:2972
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json parse(IteratorType first, IteratorType last, const parser_callback_t cb=nullptr, const bool allow_exceptions=true, const bool ignore_comments=false)
deserialize from a pair of character iterators
Definition: json.hpp:6686
static std::vector< uint8_t > to_cbor(const basic_json &j)
create a CBOR serialization of a given JSON value
Definition: json.hpp:7063
bool contains(const json_pointer &ptr) const
check the existence of an element in a JSON object given a JSON pointer
Definition: json.hpp:4439
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json from_msgpack(InputType &&i, const bool strict=true, const bool allow_exceptions=true)
create a JSON value from an input in MessagePack format
Definition: json.hpp:7615
basic_json patch(const basic_json &json_patch) const
applies a JSON patch
Definition: json.hpp:8174
string_t value(const typename object_t::key_type &key, const char *default_value) const
overload for a default value of type const char*
Definition: json.hpp:3813
basic_json unflatten() const
unflatten a previously flattened JSON value
Definition: json.hpp:8113
NumberUnsignedType number_unsigned_t
a type for a number (unsigned)
Definition: json.hpp:771
reference operator+=(const typename object_t::value_type &val)
add an object to an object
Definition: json.hpp:5334
const_iterator cbegin() const noexcept
returns a const iterator to the first element
Definition: json.hpp:4518
basic_json(initializer_list_t init, bool type_deduction=true, value_t manual_type=value_t::array)
create a container (array or object) from an initializer list
Definition: json.hpp:1599
const_reference at(size_type idx) const
access specified array element with bounds checking
Definition: json.hpp:3352
iterator insert(const_iterator pos, const basic_json &val)
inserts element
Definition: json.hpp:5534
constexpr bool is_discarded() const noexcept
return whether value is discarded
Definition: json.hpp:2656
constexpr bool is_null() const noexcept
return whether value is null
Definition: json.hpp:2404
friend void swap(reference left, reference right) noexcept(std::is_nothrow_move_constructible< value_t >::value &&std::is_nothrow_move_assignable< value_t >::value &&std::is_nothrow_move_constructible< json_value >::value &&std::is_nothrow_move_assignable< json_value >::value)
exchanges the values
Definition: json.hpp:5901
friend bool operator==(const ScalarType lhs, const_reference rhs) noexcept
comparison: equal
Definition: json.hpp:6207
ObjectType< StringType, basic_json, object_comparator_t, AllocatorType< std::pair< const StringType, basic_json > >> object_t
a type for an object
Definition: json.hpp:503
reference operator+=(const basic_json &val)
add an object to an array
Definition: json.hpp:5284
size_type erase(const typename object_t::key_type &key)
remove element from a JSON object given a key
Definition: json.hpp:4236
basic_json(size_type cnt, const basic_json &val)
construct an array with count copies of given value
Definition: json.hpp:1853
static allocator_type get_allocator()
returns the allocator associated with the container
Definition: json.hpp:311
constexpr auto get_ptr() const noexcept -> decltype(std::declval< const basic_json_t & >().get_impl_ptr(std::declval< PointerType >()))
get a pointer value (implicit)
Definition: json.hpp:3092
friend bool operator!=(const_reference lhs, const ScalarType rhs) noexcept
comparison: not equal
Definition: json.hpp:6241
reverse_iterator rbegin() noexcept
returns an iterator to the reverse-beginning
Definition: json.hpp:4619
an internal type for a backed binary type
Definition: byte_container_with_subtype.hpp:25
BinaryType container_type
the type of the underlying container
Definition: byte_container_with_subtype.hpp:28
deserialization of CBOR, MessagePack, and UBJSON values
Definition: binary_reader.hpp:57
bool sax_parse(const input_format_t format, json_sax_t *sax_, const bool strict=true, const cbor_tag_handler_t tag_handler=cbor_tag_handler_t::error)
Definition: binary_reader.hpp:94
serialization to CBOR and MessagePack values
Definition: binary_writer.hpp:28
void write_bson(const BasicJsonType &j)
Definition: binary_writer.hpp:48
general exception of the basic_json class
Definition: exceptions.hpp:47
exception indicating errors with iterators
Definition: exceptions.hpp:205
a template for a bidirectional iterator for the basic_json class This class implements a both iterato...
Definition: iter_impl.hpp:40
proxy class for the items() function
Definition: iteration_proxy.hpp:111
Definition: json_ref.hpp:14
a template for a reverse iterator class
Definition: json_reverse_iterator.hpp:35
SAX implementation to create a JSON value from SAX events.
Definition: json_sax.hpp:150
Definition: lexer.hpp:27
exception indicating other library errors
Definition: exceptions.hpp:344
exception indicating access out of the defined range
Definition: exceptions.hpp:306
Definition: output_adapters.hpp:103
exception indicating a parse error
Definition: exceptions.hpp:119
static parse_error create(int id_, const position_t &pos, const std::string &what_arg)
create a parse error exception
Definition: exceptions.hpp:130
Definition: primitive_iterator.hpp:20
Definition: serializer.hpp:41
void dump(const BasicJsonType &val, const bool pretty_print, const bool ensure_ascii, const unsigned int indent_step, const unsigned int current_indent=0)
internal implementation of the serialization function
Definition: serializer.hpp:96
Definition: input_adapters.hpp:427
exception indicating executing a member function with a wrong type
Definition: exceptions.hpp:259
JSON Pointer.
Definition: json_pointer.hpp:19
const std::string & back() const
return last reference token
Definition: json_pointer.hpp:270
void pop_back()
remove last reference token
Definition: json_pointer.hpp:246
bool empty() const noexcept
return whether pointer points to the root document
Definition: json_pointer.hpp:317
zip_uint8_t uint8_t
zip_uint8_t typedef.
Definition: zip.hpp:78
std::function< struct zip_source *(struct zip *)> source
Source creation for adding files.
Definition: zip.hpp:122
bool operator<(const value_t lhs, const value_t rhs) noexcept
comparison operator for JSON types
Definition: value_t.hpp:67
value_t
the JSON type enumeration
Definition: value_t.hpp:41
@ number_integer
number value (signed integer)
@ discarded
discarded by the parser callback function
@ binary
binary array (ordered collection of bytes)
@ object
object (unordered set of name/value pairs)
@ number_float
number value (floating-point)
@ number_unsigned
number value (unsigned integer)
@ array
array (ordered collection of values)
parse_event_t
Definition: parser.hpp:27
cbor_tag_handler_t
how to treat CBOR tags
Definition: binary_reader.hpp:30
@ error
throw a parse_error exception in case of a tag
error_handler_t
how to treat decoding errors
Definition: serializer.hpp:33
std::size_t hash(const BasicJsonType &j)
hash a JSON value
Definition: hash.hpp:30
std::shared_ptr< output_adapter_protocol< CharType > > output_adapter_t
a type to simplify interfaces
Definition: output_adapters.hpp:27
input_format_t
the supported input formats
Definition: input_adapters.hpp:23
namespace for Niels Lohmann
Definition: adl_serializer.hpp:9
NLOHMANN_BASIC_JSON_TPL_DECLARATION std::string to_string(const NLOHMANN_BASIC_JSON_TPL &j)
user-defined to_string function for JSON values
Definition: json.hpp:8684
Definition: to_json.hpp:25
Definition: type_traits.hpp:95
an iterator value
Definition: internal_iterator.hpp:16
BasicJsonType::array_t::iterator array_iterator
iterator for JSON arrays
Definition: internal_iterator.hpp:20
BasicJsonType::object_t::iterator object_iterator
iterator for JSON objects
Definition: internal_iterator.hpp:18
Definition: type_traits.hpp:38
Definition: type_traits.hpp:381
Definition: type_traits.hpp:103
SAX interface.
Definition: json_sax.hpp:24
std::size_t operator()(const nlohmann::json &j) const
return a hash value for a JSON object
Definition: json.hpp:8707
bool operator()(nlohmann::detail::value_t lhs, nlohmann::detail::value_t rhs) const noexcept
compare two value_t enum values
Definition: json.hpp:8723