o-du/phy
Intel O-RAN/X-RAN Generated Doxygen Documentation
json.hpp
Go to the documentation of this file.
1 /*
2  __ _____ _____ _____
3  __| | __| | | | JSON for Modern C++
4 | | |__ | | | | | | version 2.1.1
5 |_____|_____|_____|_|___| https://github.com/nlohmann/json
6 
7 Licensed under the MIT License <http://opensource.org/licenses/MIT>.
8 Copyright (c) 2013-2017 Niels Lohmann <http://nlohmann.me>.
9 
10 Permission is hereby granted, free of charge, to any person obtaining a copy
11 of this software and associated documentation files (the "Software"), to deal
12 in the Software without restriction, including without limitation the rights
13 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
14 copies of the Software, and to permit persons to whom the Software is
15 furnished to do so, subject to the following conditions:
16 
17 The above copyright notice and this permission notice shall be included in all
18 copies or substantial portions of the Software.
19 
20 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
23 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
24 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
25 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
26 SOFTWARE.
27 */
28 
29 #ifndef NLOHMANN_JSON_HPP
30 #define NLOHMANN_JSON_HPP
31 
32 #include <algorithm> // all_of, copy, fill, find, for_each, none_of, remove, reverse, transform
33 #include <array> // array
34 #include <cassert> // assert
35 #include <cctype> // isdigit
36 #include <ciso646> // and, not, or
37 #include <cmath> // isfinite, labs, ldexp, signbit
38 #include <cstddef> // nullptr_t, ptrdiff_t, size_t
39 #include <cstdint> // int64_t, uint64_t
40 #include <cstdlib> // abort, strtod, strtof, strtold, strtoul, strtoll, strtoull
41 #include <cstring> // strlen
42 #include <forward_list> // forward_list
43 #include <functional> // function, hash, less
44 #include <initializer_list> // initializer_list
45 #include <iomanip> // setw
46 #include <iostream> // istream, ostream
47 #include <iterator> // advance, begin, back_inserter, bidirectional_iterator_tag, distance, end, inserter, iterator, iterator_traits, next, random_access_iterator_tag, reverse_iterator
48 #include <limits> // numeric_limits
49 #include <locale> // locale
50 #include <map> // map
51 #include <memory> // addressof, allocator, allocator_traits, unique_ptr
52 #include <numeric> // accumulate
53 #include <sstream> // stringstream
54 #include <stdexcept> // domain_error, invalid_argument, out_of_range
55 #include <string> // getline, stoi, string, to_string
56 #include <type_traits> // add_pointer, conditional, decay, enable_if, false_type, integral_constant, is_arithmetic, is_base_of, is_const, is_constructible, is_convertible, is_default_constructible, is_enum, is_floating_point, is_integral, is_nothrow_move_assignable, is_nothrow_move_constructible, is_pointer, is_reference, is_same, is_scalar, is_signed, remove_const, remove_cv, remove_pointer, remove_reference, true_type, underlying_type
57 #include <utility> // declval, forward, make_pair, move, pair, swap
58 #include <vector> // vector
59 
60 // allow for portable deprecation warnings
61 #if defined(__clang__) || defined(__GNUC__) || defined(__GNUG__)
62  #define JSON_DEPRECATED __attribute__((deprecated))
63 #elif defined(_MSC_VER)
64  #define JSON_DEPRECATED __declspec(deprecated)
65 #else
66  #define JSON_DEPRECATED
67 #endif
68 
69 // allow to disable exceptions
70 #if not defined(JSON_NOEXCEPTION) || defined(__EXCEPTIONS)
71  #define JSON_THROW(exception) throw exception
72  #define JSON_TRY try
73  #define JSON_CATCH(exception) catch(exception)
74 #else
75  #define JSON_THROW(exception) std::abort()
76  #define JSON_TRY if(true)
77  #define JSON_CATCH(exception) if(false)
78 #endif
79 
85 namespace nlohmann
86 {
87 
96 namespace detail
97 {
99 // JSON type enumeration //
101 
126 enum class value_t : uint8_t
127 {
128  null,
129  object,
130  array,
131  string,
132  boolean,
135  number_float,
136  discarded
137 };
138 
148 inline bool operator<(const value_t lhs, const value_t rhs) noexcept
149 {
150  static constexpr std::array<uint8_t, 8> order = {{
151  0, // null
152  3, // object
153  4, // array
154  5, // string
155  1, // boolean
156  2, // integer
157  2, // unsigned
158  2, // float
159  }
160  };
161 
162  // discarded values are not comparable
163  if (lhs == value_t::discarded or rhs == value_t::discarded)
164  {
165  return false;
166  }
167 
168  return order[static_cast<std::size_t>(lhs)] <
169  order[static_cast<std::size_t>(rhs)];
170 }
171 
172 
174 // helpers //
176 
177 // alias templates to reduce boilerplate
178 template<bool B, typename T = void>
179 using enable_if_t = typename std::enable_if<B, T>::type;
180 
181 template<typename T>
182 using uncvref_t = typename std::remove_cv<typename std::remove_reference<T>::type>::type;
183 
184 // taken from http://stackoverflow.com/a/26936864/266378
185 template<typename T>
186 using is_unscoped_enum =
187  std::integral_constant<bool, std::is_convertible<T, int>::value and
188  std::is_enum<T>::value>;
189 
190 /*
191 Implementation of two C++17 constructs: conjunction, negation. This is needed
192 to avoid evaluating all the traits in a condition
193 
194 For example: not std::is_same<void, T>::value and has_value_type<T>::value
195 will not compile when T = void (on MSVC at least). Whereas
196 conjunction<negation<std::is_same<void, T>>, has_value_type<T>>::value will
197 stop evaluating if negation<...>::value == false
198 
199 Please note that those constructs must be used with caution, since symbols can
200 become very long quickly (which can slow down compilation and cause MSVC
201 internal compiler errors). Only use it when you have to (see example ahead).
202 */
203 template<class...> struct conjunction : std::true_type {};
204 template<class B1> struct conjunction<B1> : B1 {};
205 template<class B1, class... Bn>
206 struct conjunction<B1, Bn...> : std::conditional<bool(B1::value), conjunction<Bn...>, B1>::type {};
207 
208 template<class B> struct negation : std::integral_constant < bool, !B::value > {};
209 
210 // dispatch utility (taken from ranges-v3)
211 template<unsigned N> struct priority_tag : priority_tag < N - 1 > {};
212 template<> struct priority_tag<0> {};
213 
214 
216 // constructors //
218 
219 template<value_t> struct external_constructor;
220 
221 template<>
223 {
224  template<typename BasicJsonType>
225  static void construct(BasicJsonType& j, typename BasicJsonType::boolean_t b) noexcept
226  {
227  j.m_type = value_t::boolean;
228  j.m_value = b;
229  j.assert_invariant();
230  }
231 };
232 
233 template<>
235 {
236  template<typename BasicJsonType>
237  static void construct(BasicJsonType& j, const typename BasicJsonType::string_t& s)
238  {
239  j.m_type = value_t::string;
240  j.m_value = s;
241  j.assert_invariant();
242  }
243 };
244 
245 template<>
247 {
248  template<typename BasicJsonType>
249  static void construct(BasicJsonType& j, typename BasicJsonType::number_float_t val) noexcept
250  {
251  // replace infinity and NAN by null
252  if (not std::isfinite(val))
253  {
254  j = BasicJsonType{};
255  }
256  else
257  {
258  j.m_type = value_t::number_float;
259  j.m_value = val;
260  }
261  j.assert_invariant();
262  }
263 };
264 
265 template<>
267 {
268  template<typename BasicJsonType>
269  static void construct(BasicJsonType& j, typename BasicJsonType::number_unsigned_t val) noexcept
270  {
271  j.m_type = value_t::number_unsigned;
272  j.m_value = val;
273  j.assert_invariant();
274  }
275 };
276 
277 template<>
279 {
280  template<typename BasicJsonType>
281  static void construct(BasicJsonType& j, typename BasicJsonType::number_integer_t val) noexcept
282  {
283  j.m_type = value_t::number_integer;
284  j.m_value = val;
285  j.assert_invariant();
286  }
287 };
288 
289 template<>
291 {
292  template<typename BasicJsonType>
293  static void construct(BasicJsonType& j, const typename BasicJsonType::array_t& arr)
294  {
295  j.m_type = value_t::array;
296  j.m_value = arr;
297  j.assert_invariant();
298  }
299 
300  template<typename BasicJsonType, typename CompatibleArrayType,
301  enable_if_t<not std::is_same<CompatibleArrayType,
302  typename BasicJsonType::array_t>::value,
303  int> = 0>
304  static void construct(BasicJsonType& j, const CompatibleArrayType& arr)
305  {
306  using std::begin;
307  using std::end;
308  j.m_type = value_t::array;
309  j.m_value.array = j.template create<typename BasicJsonType::array_t>(begin(arr), end(arr));
310  j.assert_invariant();
311  }
312 };
313 
314 template<>
316 {
317  template<typename BasicJsonType>
318  static void construct(BasicJsonType& j, const typename BasicJsonType::object_t& obj)
319  {
320  j.m_type = value_t::object;
321  j.m_value = obj;
322  j.assert_invariant();
323  }
324 
325  template<typename BasicJsonType, typename CompatibleObjectType,
326  enable_if_t<not std::is_same<CompatibleObjectType,
327  typename BasicJsonType::object_t>::value,
328  int> = 0>
329  static void construct(BasicJsonType& j, const CompatibleObjectType& obj)
330  {
331  using std::begin;
332  using std::end;
333 
334  j.m_type = value_t::object;
335  j.m_value.object = j.template create<typename BasicJsonType::object_t>(begin(obj), end(obj));
336  j.assert_invariant();
337  }
338 };
339 
340 
342 // has_/is_ functions //
344 
355 #define NLOHMANN_JSON_HAS_HELPER(type) \
356  template<typename T> struct has_##type { \
357  private: \
358  template<typename U, typename = typename U::type> \
359  static int detect(U &&); \
360  static void detect(...); \
361  public: \
362  static constexpr bool value = \
363  std::is_integral<decltype(detect(std::declval<T>()))>::value; \
364  }
365 
366 NLOHMANN_JSON_HAS_HELPER(mapped_type);
367 NLOHMANN_JSON_HAS_HELPER(key_type);
368 NLOHMANN_JSON_HAS_HELPER(value_type);
369 NLOHMANN_JSON_HAS_HELPER(iterator);
370 
371 #undef NLOHMANN_JSON_HAS_HELPER
372 
373 
374 template<bool B, class RealType, class CompatibleObjectType>
375 struct is_compatible_object_type_impl : std::false_type {};
376 
377 template<class RealType, class CompatibleObjectType>
378 struct is_compatible_object_type_impl<true, RealType, CompatibleObjectType>
379 {
380  static constexpr auto value =
381  std::is_constructible<typename RealType::key_type,
382  typename CompatibleObjectType::key_type>::value and
383  std::is_constructible<typename RealType::mapped_type,
384  typename CompatibleObjectType::mapped_type>::value;
385 };
386 
387 template<class BasicJsonType, class CompatibleObjectType>
389 {
390  static auto constexpr value = is_compatible_object_type_impl <
392  has_mapped_type<CompatibleObjectType>,
393  has_key_type<CompatibleObjectType>>::value,
394  typename BasicJsonType::object_t, CompatibleObjectType >::value;
395 };
396 
397 template<typename BasicJsonType, typename T>
399 {
400  static auto constexpr value = std::is_same<T, typename BasicJsonType::iterator>::value or
401  std::is_same<T, typename BasicJsonType::const_iterator>::value or
402  std::is_same<T, typename BasicJsonType::reverse_iterator>::value or
403  std::is_same<T, typename BasicJsonType::const_reverse_iterator>::value or
404  std::is_same<T, typename BasicJsonType::json_pointer>::value;
405 };
406 
407 template<class BasicJsonType, class CompatibleArrayType>
409 {
410  static auto constexpr value =
413  BasicJsonType, CompatibleArrayType>>,
414  negation<std::is_constructible<typename BasicJsonType::string_t,
415  CompatibleArrayType>>,
417  has_value_type<CompatibleArrayType>,
418  has_iterator<CompatibleArrayType>>::value;
419 };
420 
421 template<bool, typename, typename>
422 struct is_compatible_integer_type_impl : std::false_type {};
423 
424 template<typename RealIntegerType, typename CompatibleNumberIntegerType>
425 struct is_compatible_integer_type_impl<true, RealIntegerType, CompatibleNumberIntegerType>
426 {
427  // is there an assert somewhere on overflows?
428  using RealLimits = std::numeric_limits<RealIntegerType>;
429  using CompatibleLimits = std::numeric_limits<CompatibleNumberIntegerType>;
430 
431  static constexpr auto value =
432  std::is_constructible<RealIntegerType,
433  CompatibleNumberIntegerType>::value and
434  CompatibleLimits::is_integer and
435  RealLimits::is_signed == CompatibleLimits::is_signed;
436 };
437 
438 template<typename RealIntegerType, typename CompatibleNumberIntegerType>
440 {
441  static constexpr auto value =
443  std::is_integral<CompatibleNumberIntegerType>::value and
444  not std::is_same<bool, CompatibleNumberIntegerType>::value,
445  RealIntegerType, CompatibleNumberIntegerType > ::value;
446 };
447 
448 
449 // trait checking if JSONSerializer<T>::from_json(json const&, udt&) exists
450 template<typename BasicJsonType, typename T>
452 {
453  private:
454  // also check the return type of from_json
456  std::declval<BasicJsonType>(), std::declval<T&>()))>::value>>
457  static int detect(U&&);
458  static void detect(...);
459 
460  public:
461  static constexpr bool value = std::is_integral<decltype(
462  detect(std::declval<typename BasicJsonType::template json_serializer<T, void > >()))>::value;
463 };
464 
465 // This trait checks if JSONSerializer<T>::from_json(json const&) exists
466 // this overload is used for non-default-constructible user-defined-types
467 template<typename BasicJsonType, typename T>
469 {
470  private:
471  template <
472  typename U,
473  typename = enable_if_t<std::is_same<
474  T, decltype(uncvref_t<U>::from_json(std::declval<BasicJsonType>()))>::value >>
475  static int detect(U&&);
476  static void detect(...);
477 
478  public:
479  static constexpr bool value = std::is_integral<decltype(detect(
480  std::declval<typename BasicJsonType::template json_serializer<T, void> >()))>::value;
481 };
482 
483 // This trait checks if BasicJsonType::json_serializer<T>::to_json exists
484 template<typename BasicJsonType, typename T>
486 {
487  private:
489  std::declval<BasicJsonType&>(), std::declval<T>()))>
490  static int detect(U&&);
491  static void detect(...);
492 
493  public:
494  static constexpr bool value = std::is_integral<decltype(detect(
495  std::declval<typename BasicJsonType::template json_serializer<T, void> >()))>::value;
496 };
497 
498 
500 // to_json //
502 
503 template<typename BasicJsonType, typename T, enable_if_t<
504  std::is_same<T, typename BasicJsonType::boolean_t>::value, int> = 0>
505 void to_json(BasicJsonType& j, T b) noexcept
506 {
508 }
509 
510 template<typename BasicJsonType, typename CompatibleString,
511  enable_if_t<std::is_constructible<typename BasicJsonType::string_t,
512  CompatibleString>::value, int> = 0>
513 void to_json(BasicJsonType& j, const CompatibleString& s)
514 {
516 }
517 
518 template<typename BasicJsonType, typename FloatType,
520 void to_json(BasicJsonType& j, FloatType val) noexcept
521 {
522  external_constructor<value_t::number_float>::construct(j, static_cast<typename BasicJsonType::number_float_t>(val));
523 }
524 
525 template <
526  typename BasicJsonType, typename CompatibleNumberUnsignedType,
527  enable_if_t<is_compatible_integer_type<typename BasicJsonType::number_unsigned_t,
528  CompatibleNumberUnsignedType>::value, int> = 0 >
529 void to_json(BasicJsonType& j, CompatibleNumberUnsignedType val) noexcept
530 {
531  external_constructor<value_t::number_unsigned>::construct(j, static_cast<typename BasicJsonType::number_unsigned_t>(val));
532 }
533 
534 template <
535  typename BasicJsonType, typename CompatibleNumberIntegerType,
536  enable_if_t<is_compatible_integer_type<typename BasicJsonType::number_integer_t,
537  CompatibleNumberIntegerType>::value, int> = 0 >
538 void to_json(BasicJsonType& j, CompatibleNumberIntegerType val) noexcept
539 {
540  external_constructor<value_t::number_integer>::construct(j, static_cast<typename BasicJsonType::number_integer_t>(val));
541 }
542 
543 template<typename BasicJsonType, typename UnscopedEnumType,
545 void to_json(BasicJsonType& j, UnscopedEnumType e) noexcept
546 {
548 }
549 
550 template <
551  typename BasicJsonType, typename CompatibleArrayType,
552  enable_if_t <
554  std::is_same<typename BasicJsonType::array_t, CompatibleArrayType>::value,
555  int > = 0 >
556 void to_json(BasicJsonType& j, const CompatibleArrayType& arr)
557 {
559 }
560 
561 template <
562  typename BasicJsonType, typename CompatibleObjectType,
564  int> = 0 >
565 void to_json(BasicJsonType& j, const CompatibleObjectType& arr)
566 {
568 }
569 
570 
572 // from_json //
574 
575 // overloads for basic_json template parameters
576 template<typename BasicJsonType, typename ArithmeticType,
578  not std::is_same<ArithmeticType,
579  typename BasicJsonType::boolean_t>::value,
580  int> = 0>
581 void get_arithmetic_value(const BasicJsonType& j, ArithmeticType& val)
582 {
583  switch (static_cast<value_t>(j))
584  {
586  {
587  val = static_cast<ArithmeticType>(
588  *j.template get_ptr<const typename BasicJsonType::number_unsigned_t*>());
589  break;
590  }
592  {
593  val = static_cast<ArithmeticType>(
594  *j.template get_ptr<const typename BasicJsonType::number_integer_t*>());
595  break;
596  }
598  {
599  val = static_cast<ArithmeticType>(
600  *j.template get_ptr<const typename BasicJsonType::number_float_t*>());
601  break;
602  }
603  default:
604  {
605  JSON_THROW(
606  std::domain_error("type must be number, but is " + j.type_name()));
607  }
608  }
609 }
610 
611 template<typename BasicJsonType>
612 void from_json(const BasicJsonType& j, typename BasicJsonType::boolean_t& b)
613 {
614  if (not j.is_boolean())
615  {
616  JSON_THROW(std::domain_error("type must be boolean, but is " + j.type_name()));
617  }
618  b = *j.template get_ptr<const typename BasicJsonType::boolean_t*>();
619 }
620 
621 template<typename BasicJsonType>
622 void from_json(const BasicJsonType& j, typename BasicJsonType::string_t& s)
623 {
624  if (not j.is_string())
625  {
626  JSON_THROW(std::domain_error("type must be string, but is " + j.type_name()));
627  }
628  s = *j.template get_ptr<const typename BasicJsonType::string_t*>();
629 }
630 
631 template<typename BasicJsonType>
632 void from_json(const BasicJsonType& j, typename BasicJsonType::number_float_t& val)
633 {
634  get_arithmetic_value(j, val);
635 }
636 
637 template<typename BasicJsonType>
638 void from_json(const BasicJsonType& j, typename BasicJsonType::number_unsigned_t& val)
639 {
640  get_arithmetic_value(j, val);
641 }
642 
643 template<typename BasicJsonType>
644 void from_json(const BasicJsonType& j, typename BasicJsonType::number_integer_t& val)
645 {
646  get_arithmetic_value(j, val);
647 }
648 
649 template<typename BasicJsonType, typename UnscopedEnumType,
650  enable_if_t<is_unscoped_enum<UnscopedEnumType>::value, int> = 0>
651 void from_json(const BasicJsonType& j, UnscopedEnumType& e)
652 {
653  typename std::underlying_type<UnscopedEnumType>::type val;
654  get_arithmetic_value(j, val);
655  e = static_cast<UnscopedEnumType>(val);
656 }
657 
658 template<typename BasicJsonType>
659 void from_json(const BasicJsonType& j, typename BasicJsonType::array_t& arr)
660 {
661  if (not j.is_array())
662  {
663  JSON_THROW(std::domain_error("type must be array, but is " + j.type_name()));
664  }
665  arr = *j.template get_ptr<const typename BasicJsonType::array_t*>();
666 }
667 
668 // forward_list doesn't have an insert method
669 template<typename BasicJsonType, typename T, typename Allocator>
670 void from_json(const BasicJsonType& j, std::forward_list<T, Allocator>& l)
671 {
672  // do not perform the check when user wants to retrieve jsons
673  // (except when it's null.. ?)
674  if (j.is_null())
675  {
676  JSON_THROW(std::domain_error("type must be array, but is " + j.type_name()));
677  }
678  if (not std::is_same<T, BasicJsonType>::value)
679  {
680  if (not j.is_array())
681  {
682  JSON_THROW(std::domain_error("type must be array, but is " + j.type_name()));
683  }
684  }
685  for (auto it = j.rbegin(), end = j.rend(); it != end; ++it)
686  {
687  l.push_front(it->template get<T>());
688  }
689 }
690 
691 template<typename BasicJsonType, typename CompatibleArrayType>
692 void from_json_array_impl(const BasicJsonType& j, CompatibleArrayType& arr, priority_tag<0>)
693 {
694  using std::begin;
695  using std::end;
696 
697  std::transform(j.begin(), j.end(),
698  std::inserter(arr, end(arr)), [](const BasicJsonType & i)
699  {
700  // get<BasicJsonType>() returns *this, this won't call a from_json
701  // method when value_type is BasicJsonType
702  return i.template get<typename CompatibleArrayType::value_type>();
703  });
704 }
705 
706 template<typename BasicJsonType, typename CompatibleArrayType>
707 auto from_json_array_impl(const BasicJsonType& j, CompatibleArrayType& arr, priority_tag<1>)
708 -> decltype(
709  arr.reserve(std::declval<typename CompatibleArrayType::size_type>()),
710  void())
711 {
712  using std::begin;
713  using std::end;
714 
715  arr.reserve(j.size());
716  std::transform(
717  j.begin(), j.end(), std::inserter(arr, end(arr)), [](const BasicJsonType & i)
718  {
719  // get<BasicJsonType>() returns *this, this won't call a from_json
720  // method when value_type is BasicJsonType
721  return i.template get<typename CompatibleArrayType::value_type>();
722  });
723 }
724 
725 template<typename BasicJsonType, typename CompatibleArrayType,
727  not std::is_same<typename BasicJsonType::array_t, CompatibleArrayType>::value, int> = 0>
728 void from_json(const BasicJsonType& j, CompatibleArrayType& arr)
729 {
730  if (j.is_null())
731  {
732  JSON_THROW(std::domain_error("type must be array, but is " + j.type_name()));
733  }
734 
735  // when T == BasicJsonType, do not check if value_t is correct
736  if (not std::is_same<typename CompatibleArrayType::value_type, BasicJsonType>::value)
737  {
738  if (not j.is_array())
739  {
740  JSON_THROW(std::domain_error("type must be array, but is " + j.type_name()));
741  }
742  }
744 }
745 
746 template<typename BasicJsonType, typename CompatibleObjectType,
747  enable_if_t<is_compatible_object_type<BasicJsonType, CompatibleObjectType>::value, int> = 0>
748 void from_json(const BasicJsonType& j, CompatibleObjectType& obj)
749 {
750  if (not j.is_object())
751  {
752  JSON_THROW(std::domain_error("type must be object, but is " + j.type_name()));
753  }
754 
755  auto inner_object = j.template get_ptr<const typename BasicJsonType::object_t*>();
756  using std::begin;
757  using std::end;
758  // we could avoid the assignment, but this might require a for loop, which
759  // might be less efficient than the container constructor for some
760  // containers (would it?)
761  obj = CompatibleObjectType(begin(*inner_object), end(*inner_object));
762 }
763 
764 // overload for arithmetic types, not chosen for basic_json template arguments
765 // (BooleanType, etc..); note: Is it really necessary to provide explicit
766 // overloads for boolean_t etc. in case of a custom BooleanType which is not
767 // an arithmetic type?
768 template<typename BasicJsonType, typename ArithmeticType,
769  enable_if_t <
770  std::is_arithmetic<ArithmeticType>::value and
771  not std::is_same<ArithmeticType, typename BasicJsonType::number_unsigned_t>::value and
772  not std::is_same<ArithmeticType, typename BasicJsonType::number_integer_t>::value and
773  not std::is_same<ArithmeticType, typename BasicJsonType::number_float_t>::value and
774  not std::is_same<ArithmeticType, typename BasicJsonType::boolean_t>::value,
775  int> = 0>
776 void from_json(const BasicJsonType& j, ArithmeticType& val)
777 {
778  switch (static_cast<value_t>(j))
779  {
781  {
782  val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_unsigned_t*>());
783  break;
784  }
786  {
787  val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_integer_t*>());
788  break;
789  }
791  {
792  val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_float_t*>());
793  break;
794  }
795  case value_t::boolean:
796  {
797  val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::boolean_t*>());
798  break;
799  }
800  default:
801  {
802  JSON_THROW(std::domain_error("type must be number, but is " + j.type_name()));
803  }
804  }
805 }
806 
808 {
809  private:
810  template<typename BasicJsonType, typename T>
811  auto call(BasicJsonType& j, T&& val, priority_tag<1>) const noexcept(noexcept(to_json(j, std::forward<T>(val))))
812  -> decltype(to_json(j, std::forward<T>(val)), void())
813  {
814  return to_json(j, std::forward<T>(val));
815  }
816 
817  template<typename BasicJsonType, typename T>
818  void call(BasicJsonType&, T&&, priority_tag<0>) const noexcept
819  {
820  static_assert(sizeof(BasicJsonType) == 0,
821  "could not find to_json() method in T's namespace");
822  }
823 
824  public:
825  template<typename BasicJsonType, typename T>
826  void operator()(BasicJsonType& j, T&& val) const
827  noexcept(noexcept(std::declval<to_json_fn>().call(j, std::forward<T>(val), priority_tag<1> {})))
828  {
829  return call(j, std::forward<T>(val), priority_tag<1> {});
830  }
831 };
832 
834 {
835  private:
836  template<typename BasicJsonType, typename T>
837  auto call(const BasicJsonType& j, T& val, priority_tag<1>) const
838  noexcept(noexcept(from_json(j, val)))
839  -> decltype(from_json(j, val), void())
840  {
841  return from_json(j, val);
842  }
843 
844  template<typename BasicJsonType, typename T>
845  void call(const BasicJsonType&, T&, priority_tag<0>) const noexcept
846  {
847  static_assert(sizeof(BasicJsonType) == 0,
848  "could not find from_json() method in T's namespace");
849  }
850 
851  public:
852  template<typename BasicJsonType, typename T>
853  void operator()(const BasicJsonType& j, T& val) const
854  noexcept(noexcept(std::declval<from_json_fn>().call(j, val, priority_tag<1> {})))
855  {
856  return call(j, val, priority_tag<1> {});
857  }
858 };
859 
860 // taken from ranges-v3
861 template<typename T>
863 {
864  static constexpr T value{};
865 };
866 
867 template<typename T>
868 constexpr T static_const<T>::value;
869 } // namespace detail
870 
871 
873 namespace
874 {
877 }
878 
879 
887 template<typename = void, typename = void>
889 {
899  template<typename BasicJsonType, typename ValueType>
900  static void from_json(BasicJsonType&& j, ValueType& val) noexcept(
901  noexcept(::nlohmann::from_json(std::forward<BasicJsonType>(j), val)))
902  {
903  ::nlohmann::from_json(std::forward<BasicJsonType>(j), val);
904  }
905 
915  template<typename BasicJsonType, typename ValueType>
916  static void to_json(BasicJsonType& j, ValueType&& val) noexcept(
917  noexcept(::nlohmann::to_json(j, std::forward<ValueType>(val))))
918  {
919  ::nlohmann::to_json(j, std::forward<ValueType>(val));
920  }
921 };
922 
923 
1005 template <
1006  template<typename U, typename V, typename... Args> class ObjectType = std::map,
1007  template<typename U, typename... Args> class ArrayType = std::vector,
1008  class StringType = std::string,
1009  class BooleanType = bool,
1010  class NumberIntegerType = std::int64_t,
1011  class NumberUnsignedType = std::uint64_t,
1012  class NumberFloatType = double,
1013  template<typename U> class AllocatorType = std::allocator,
1014  template<typename T, typename SFINAE = void> class JSONSerializer = adl_serializer
1015  >
1017 {
1018  private:
1019  template<detail::value_t> friend struct detail::external_constructor;
1021  using basic_json_t = basic_json<ObjectType, ArrayType, StringType,
1022  BooleanType, NumberIntegerType, NumberUnsignedType, NumberFloatType,
1023  AllocatorType, JSONSerializer>;
1024 
1025  public:
1027  // forward declarations
1028  template<typename U> class iter_impl;
1029  template<typename Base> class json_reverse_iterator;
1030  class json_pointer;
1031  template<typename T, typename SFINAE>
1032  using json_serializer = JSONSerializer<T, SFINAE>;
1033 
1035  // container types //
1037 
1042 
1045 
1049  using const_reference = const value_type&;
1050 
1052  using difference_type = std::ptrdiff_t;
1054  using size_type = std::size_t;
1055 
1057  using allocator_type = AllocatorType<basic_json>;
1058 
1060  using pointer = typename std::allocator_traits<allocator_type>::pointer;
1062  using const_pointer = typename std::allocator_traits<allocator_type>::const_pointer;
1063 
1072 
1074 
1075 
1080  {
1081  return allocator_type();
1082  }
1083 
1107  static basic_json meta()
1108  {
1109  basic_json result;
1110 
1111  result["copyright"] = "(C) 2013-2017 Niels Lohmann";
1112  result["name"] = "JSON for Modern C++";
1113  result["url"] = "https://github.com/nlohmann/json";
1114  result["version"] =
1115  {
1116  {"string", "2.1.1"},
1117  {"major", 2},
1118  {"minor", 1},
1119  {"patch", 1}
1120  };
1121 
1122 #ifdef _WIN32
1123  result["platform"] = "win32";
1124 #elif defined __linux__
1125  result["platform"] = "linux";
1126 #elif defined __APPLE__
1127  result["platform"] = "apple";
1128 #elif defined __unix__
1129  result["platform"] = "unix";
1130 #else
1131  result["platform"] = "unknown";
1132 #endif
1133 
1134 #if defined(__clang__)
1135  result["compiler"] = {{"family", "clang"}, {"version", __clang_version__}};
1136 #elif defined(__ICC) || defined(__INTEL_COMPILER)
1137  result["compiler"] = {{"family", "icc"}, {"version", __INTEL_COMPILER}};
1138 #elif defined(__GNUC__) || defined(__GNUG__)
1139  result["compiler"] = {{"family", "gcc"}, {"version", std::to_string(__GNUC__) + "." + std::to_string(__GNUC_MINOR__) + "." + std::to_string(__GNUC_PATCHLEVEL__)}};
1140 #elif defined(__HP_cc) || defined(__HP_aCC)
1141  result["compiler"] = "hp"
1142 #elif defined(__IBMCPP__)
1143  result["compiler"] = {{"family", "ilecpp"}, {"version", __IBMCPP__}};
1144 #elif defined(_MSC_VER)
1145  result["compiler"] = {{"family", "msvc"}, {"version", _MSC_VER}};
1146 #elif defined(__PGI)
1147  result["compiler"] = {{"family", "pgcpp"}, {"version", __PGI}};
1148 #elif defined(__SUNPRO_CC)
1149  result["compiler"] = {{"family", "sunpro"}, {"version", __SUNPRO_CC}};
1150 #else
1151  result["compiler"] = {{"family", "unknown"}, {"version", "unknown"}};
1152 #endif
1153 
1154 #ifdef __cplusplus
1155  result["compiler"]["c++"] = std::to_string(__cplusplus);
1156 #else
1157  result["compiler"]["c++"] = "unknown";
1158 #endif
1159  return result;
1160  }
1161 
1162 
1164  // JSON value data types //
1166 
1171 
1255  using object_t = ObjectType<StringType,
1256  basic_json,
1257  std::less<StringType>,
1258  AllocatorType<std::pair<const StringType,
1259  basic_json>>>;
1260 
1305  using array_t = ArrayType<basic_json, AllocatorType<basic_json>>;
1306 
1358  using string_t = StringType;
1359 
1384  using boolean_t = BooleanType;
1385 
1456  using number_integer_t = NumberIntegerType;
1457 
1527  using number_unsigned_t = NumberUnsignedType;
1528 
1595  using number_float_t = NumberFloatType;
1596 
1598 
1599  private:
1600 
1602  template<typename T, typename... Args>
1603  static T* create(Args&& ... args)
1604  {
1605  AllocatorType<T> alloc;
1606  auto deleter = [&](T * object)
1607  {
1608  alloc.deallocate(object, 1);
1609  };
1610  std::unique_ptr<T, decltype(deleter)> object(alloc.allocate(1), deleter);
1611  alloc.construct(object.get(), std::forward<Args>(args)...);
1612  assert(object != nullptr);
1613  return object.release();
1614  }
1615 
1617  // JSON value storage //
1619 
1644  union json_value
1645  {
1647  object_t* object;
1649  array_t* array;
1651  string_t* string;
1660 
1662  json_value() = default;
1664  json_value(boolean_t v) noexcept : boolean(v) {}
1666  json_value(number_integer_t v) noexcept : number_integer(v) {}
1668  json_value(number_unsigned_t v) noexcept : number_unsigned(v) {}
1670  json_value(number_float_t v) noexcept : number_float(v) {}
1672  json_value(value_t t)
1673  {
1674  switch (t)
1675  {
1676  case value_t::object:
1677  {
1678  object = create<object_t>();
1679  break;
1680  }
1681 
1682  case value_t::array:
1683  {
1684  array = create<array_t>();
1685  break;
1686  }
1687 
1688  case value_t::string:
1689  {
1690  string = create<string_t>("");
1691  break;
1692  }
1693 
1694  case value_t::boolean:
1695  {
1696  boolean = boolean_t(false);
1697  break;
1698  }
1699 
1701  {
1702  number_integer = number_integer_t(0);
1703  break;
1704  }
1705 
1707  {
1708  number_unsigned = number_unsigned_t(0);
1709  break;
1710  }
1711 
1712  case value_t::number_float:
1713  {
1714  number_float = number_float_t(0.0);
1715  break;
1716  }
1717 
1718  case value_t::null:
1719  {
1720  break;
1721  }
1722 
1723  default:
1724  {
1725  if (t == value_t::null)
1726  {
1727  JSON_THROW(std::domain_error("961c151d2e87f2686a955a9be24d316f1362bf21 2.1.1")); // LCOV_EXCL_LINE
1728  }
1729  break;
1730  }
1731  }
1732  }
1733 
1735  json_value(const string_t& value)
1736  {
1737  string = create<string_t>(value);
1738  }
1739 
1741  json_value(const object_t& value)
1742  {
1743  object = create<object_t>(value);
1744  }
1745 
1747  json_value(const array_t& value)
1748  {
1749  array = create<array_t>(value);
1750  }
1751  };
1752 
1762  void assert_invariant() const
1763  {
1764  assert(m_type != value_t::object or m_value.object != nullptr);
1765  assert(m_type != value_t::array or m_value.array != nullptr);
1766  assert(m_type != value_t::string or m_value.string != nullptr);
1767  }
1768 
1769  public:
1771  // JSON parser callback //
1773 
1784  enum class parse_event_t : uint8_t
1785  {
1787  object_start,
1789  object_end,
1791  array_start,
1793  array_end,
1795  key,
1797  value
1798  };
1799 
1852  using parser_callback_t = std::function<bool(int depth,
1853  parse_event_t event,
1854  basic_json& parsed)>;
1855 
1856 
1858  // constructors //
1860 
1865 
1894  : m_type(value_type), m_value(value_type)
1895  {
1896  assert_invariant();
1897  }
1898 
1917  basic_json(std::nullptr_t = nullptr) noexcept
1918  : basic_json(value_t::null)
1919  {
1920  assert_invariant();
1921  }
1922 
1976  template<typename CompatibleType, typename U = detail::uncvref_t<CompatibleType>,
1977  detail::enable_if_t<not std::is_base_of<std::istream, U>::value and
1978  not std::is_same<U, basic_json_t>::value and
1979  not detail::is_basic_json_nested_type<
1980  basic_json_t, U>::value and
1981  detail::has_to_json<basic_json, U>::value,
1982  int> = 0>
1983  basic_json(CompatibleType && val) noexcept(noexcept(JSONSerializer<U>::to_json(
1984  std::declval<basic_json_t&>(), std::forward<CompatibleType>(val))))
1985  {
1986  JSONSerializer<U>::to_json(*this, std::forward<CompatibleType>(val));
1987  assert_invariant();
1988  }
1989 
2059  basic_json(std::initializer_list<basic_json> init,
2060  bool type_deduction = true,
2061  value_t manual_type = value_t::array)
2062  {
2063  // check if each element is an array with two elements whose first
2064  // element is a string
2065  bool is_an_object = std::all_of(init.begin(), init.end(),
2066  [](const basic_json & element)
2067  {
2068  return element.is_array() and element.size() == 2 and element[0].is_string();
2069  });
2070 
2071  // adjust type if type deduction is not wanted
2072  if (not type_deduction)
2073  {
2074  // if array is wanted, do not create an object though possible
2075  if (manual_type == value_t::array)
2076  {
2077  is_an_object = false;
2078  }
2079 
2080  // if object is wanted but impossible, throw an exception
2081  if (manual_type == value_t::object and not is_an_object)
2082  {
2083  JSON_THROW(std::domain_error("cannot create object from initializer list"));
2084  }
2085  }
2086 
2087  if (is_an_object)
2088  {
2089  // the initializer list is a list of pairs -> create object
2090  m_type = value_t::object;
2091  m_value = value_t::object;
2092 
2093  std::for_each(init.begin(), init.end(), [this](const basic_json & element)
2094  {
2095  m_value.object->emplace(*(element[0].m_value.string), element[1]);
2096  });
2097  }
2098  else
2099  {
2100  // the initializer list describes an array -> create array
2101  m_type = value_t::array;
2102  m_value.array = create<array_t>(init);
2103  }
2104 
2105  assert_invariant();
2106  }
2107 
2142  static basic_json array(std::initializer_list<basic_json> init =
2143  std::initializer_list<basic_json>())
2144  {
2145  return basic_json(init, false, value_t::array);
2146  }
2147 
2182  static basic_json object(std::initializer_list<basic_json> init =
2183  std::initializer_list<basic_json>())
2184  {
2185  return basic_json(init, false, value_t::object);
2186  }
2187 
2207  : m_type(value_t::array)
2208  {
2209  m_value.array = create<array_t>(cnt, val);
2210  assert_invariant();
2211  }
2212 
2250  template<class InputIT, typename std::enable_if<
2251  std::is_same<InputIT, typename basic_json_t::iterator>::value or
2252  std::is_same<InputIT, typename basic_json_t::const_iterator>::value, int>::type = 0>
2253  basic_json(InputIT first, InputIT last)
2254  {
2255  assert(first.m_object != nullptr);
2256  assert(last.m_object != nullptr);
2257 
2258  // make sure iterator fits the current value
2259  if (first.m_object != last.m_object)
2260  {
2261  JSON_THROW(std::domain_error("iterators are not compatible"));
2262  }
2263 
2264  // copy type from first iterator
2265  m_type = first.m_object->m_type;
2266 
2267  // check if iterator range is complete for primitive values
2268  switch (m_type)
2269  {
2270  case value_t::boolean:
2271  case value_t::number_float:
2274  case value_t::string:
2275  {
2276  if (not first.m_it.primitive_iterator.is_begin() or not last.m_it.primitive_iterator.is_end())
2277  {
2278  JSON_THROW(std::out_of_range("iterators out of range"));
2279  }
2280  break;
2281  }
2282 
2283  default:
2284  {
2285  break;
2286  }
2287  }
2288 
2289  switch (m_type)
2290  {
2292  {
2293  m_value.number_integer = first.m_object->m_value.number_integer;
2294  break;
2295  }
2296 
2298  {
2299  m_value.number_unsigned = first.m_object->m_value.number_unsigned;
2300  break;
2301  }
2302 
2303  case value_t::number_float:
2304  {
2305  m_value.number_float = first.m_object->m_value.number_float;
2306  break;
2307  }
2308 
2309  case value_t::boolean:
2310  {
2311  m_value.boolean = first.m_object->m_value.boolean;
2312  break;
2313  }
2314 
2315  case value_t::string:
2316  {
2317  m_value = *first.m_object->m_value.string;
2318  break;
2319  }
2320 
2321  case value_t::object:
2322  {
2323  m_value.object = create<object_t>(first.m_it.object_iterator,
2324  last.m_it.object_iterator);
2325  break;
2326  }
2327 
2328  case value_t::array:
2329  {
2330  m_value.array = create<array_t>(first.m_it.array_iterator,
2331  last.m_it.array_iterator);
2332  break;
2333  }
2334 
2335  default:
2336  {
2337  JSON_THROW(std::domain_error("cannot use construct with iterators from " + first.m_object->type_name()));
2338  }
2339  }
2340 
2341  assert_invariant();
2342  }
2343 
2373  explicit basic_json(std::istream& i, const parser_callback_t cb = nullptr)
2374  {
2375  *this = parser(i, cb).parse();
2376  assert_invariant();
2377  }
2378 
2380  // other constructors and destructor //
2382 
2405  basic_json(const basic_json& other)
2406  : m_type(other.m_type)
2407  {
2408  // check of passed value is valid
2409  other.assert_invariant();
2410 
2411  switch (m_type)
2412  {
2413  case value_t::object:
2414  {
2415  m_value = *other.m_value.object;
2416  break;
2417  }
2418 
2419  case value_t::array:
2420  {
2421  m_value = *other.m_value.array;
2422  break;
2423  }
2424 
2425  case value_t::string:
2426  {
2427  m_value = *other.m_value.string;
2428  break;
2429  }
2430 
2431  case value_t::boolean:
2432  {
2433  m_value = other.m_value.boolean;
2434  break;
2435  }
2436 
2438  {
2439  m_value = other.m_value.number_integer;
2440  break;
2441  }
2442 
2444  {
2445  m_value = other.m_value.number_unsigned;
2446  break;
2447  }
2448 
2449  case value_t::number_float:
2450  {
2451  m_value = other.m_value.number_float;
2452  break;
2453  }
2454 
2455  default:
2456  {
2457  break;
2458  }
2459  }
2460 
2461  assert_invariant();
2462  }
2463 
2482  basic_json(basic_json&& other) noexcept
2483  : m_type(std::move(other.m_type)),
2484  m_value(std::move(other.m_value))
2485  {
2486  // check that passed value is valid
2487  other.assert_invariant();
2488 
2489  // invalidate payload
2490  other.m_type = value_t::null;
2491  other.m_value = {};
2492 
2493  assert_invariant();
2494  }
2495 
2519  reference& operator=(basic_json other) noexcept (
2520  std::is_nothrow_move_constructible<value_t>::value and
2521  std::is_nothrow_move_assignable<value_t>::value and
2522  std::is_nothrow_move_constructible<json_value>::value and
2523  std::is_nothrow_move_assignable<json_value>::value
2524  )
2525  {
2526  // check that passed value is valid
2527  other.assert_invariant();
2528 
2529  using std::swap;
2530  swap(m_type, other.m_type);
2531  swap(m_value, other.m_value);
2532 
2533  assert_invariant();
2534  return *this;
2535  }
2536 
2553  {
2554  assert_invariant();
2555 
2556  switch (m_type)
2557  {
2558  case value_t::object:
2559  {
2560  AllocatorType<object_t> alloc;
2561  alloc.destroy(m_value.object);
2562  alloc.deallocate(m_value.object, 1);
2563  break;
2564  }
2565 
2566  case value_t::array:
2567  {
2568  AllocatorType<array_t> alloc;
2569  alloc.destroy(m_value.array);
2570  alloc.deallocate(m_value.array, 1);
2571  break;
2572  }
2573 
2574  case value_t::string:
2575  {
2576  AllocatorType<string_t> alloc;
2577  alloc.destroy(m_value.string);
2578  alloc.deallocate(m_value.string, 1);
2579  break;
2580  }
2581 
2582  default:
2583  {
2584  // all other types need no specific destructor
2585  break;
2586  }
2587  }
2588  }
2589 
2591 
2592  public:
2594  // object inspection //
2596 
2600 
2624  string_t dump(const int indent = -1) const
2625  {
2626  std::stringstream ss;
2627 
2628  if (indent >= 0)
2629  {
2630  dump(ss, true, static_cast<unsigned int>(indent));
2631  }
2632  else
2633  {
2634  dump(ss, false, 0);
2635  }
2636 
2637  return ss.str();
2638  }
2639 
2658  constexpr value_t type() const noexcept
2659  {
2660  return m_type;
2661  }
2662 
2688  constexpr bool is_primitive() const noexcept
2689  {
2690  return is_null() or is_string() or is_boolean() or is_number();
2691  }
2692 
2715  constexpr bool is_structured() const noexcept
2716  {
2717  return is_array() or is_object();
2718  }
2719 
2737  constexpr bool is_null() const noexcept
2738  {
2739  return m_type == value_t::null;
2740  }
2741 
2759  constexpr bool is_boolean() const noexcept
2760  {
2761  return m_type == value_t::boolean;
2762  }
2763 
2789  constexpr bool is_number() const noexcept
2790  {
2791  return is_number_integer() or is_number_float();
2792  }
2793 
2818  constexpr bool is_number_integer() const noexcept
2819  {
2820  return m_type == value_t::number_integer or m_type == value_t::number_unsigned;
2821  }
2822 
2846  constexpr bool is_number_unsigned() const noexcept
2847  {
2848  return m_type == value_t::number_unsigned;
2849  }
2850 
2874  constexpr bool is_number_float() const noexcept
2875  {
2876  return m_type == value_t::number_float;
2877  }
2878 
2896  constexpr bool is_object() const noexcept
2897  {
2898  return m_type == value_t::object;
2899  }
2900 
2918  constexpr bool is_array() const noexcept
2919  {
2920  return m_type == value_t::array;
2921  }
2922 
2940  constexpr bool is_string() const noexcept
2941  {
2942  return m_type == value_t::string;
2943  }
2944 
2967  constexpr bool is_discarded() const noexcept
2968  {
2969  return m_type == value_t::discarded;
2970  }
2971 
2990  constexpr operator value_t() const noexcept
2991  {
2992  return m_type;
2993  }
2994 
2996 
2997  private:
2999  // value access //
3001 
3003  boolean_t get_impl(boolean_t* /*unused*/) const
3004  {
3005  if (is_boolean())
3006  {
3007  return m_value.boolean;
3008  }
3009 
3010  JSON_THROW(std::domain_error("type must be boolean, but is " + type_name()));
3011  }
3012 
3014  object_t* get_impl_ptr(object_t* /*unused*/) noexcept
3015  {
3016  return is_object() ? m_value.object : nullptr;
3017  }
3018 
3020  constexpr const object_t* get_impl_ptr(const object_t* /*unused*/) const noexcept
3021  {
3022  return is_object() ? m_value.object : nullptr;
3023  }
3024 
3026  array_t* get_impl_ptr(array_t* /*unused*/) noexcept
3027  {
3028  return is_array() ? m_value.array : nullptr;
3029  }
3030 
3032  constexpr const array_t* get_impl_ptr(const array_t* /*unused*/) const noexcept
3033  {
3034  return is_array() ? m_value.array : nullptr;
3035  }
3036 
3038  string_t* get_impl_ptr(string_t* /*unused*/) noexcept
3039  {
3040  return is_string() ? m_value.string : nullptr;
3041  }
3042 
3044  constexpr const string_t* get_impl_ptr(const string_t* /*unused*/) const noexcept
3045  {
3046  return is_string() ? m_value.string : nullptr;
3047  }
3048 
3050  boolean_t* get_impl_ptr(boolean_t* /*unused*/) noexcept
3051  {
3052  return is_boolean() ? &m_value.boolean : nullptr;
3053  }
3054 
3056  constexpr const boolean_t* get_impl_ptr(const boolean_t* /*unused*/) const noexcept
3057  {
3058  return is_boolean() ? &m_value.boolean : nullptr;
3059  }
3060 
3062  number_integer_t* get_impl_ptr(number_integer_t* /*unused*/) noexcept
3063  {
3064  return is_number_integer() ? &m_value.number_integer : nullptr;
3065  }
3066 
3068  constexpr const number_integer_t* get_impl_ptr(const number_integer_t* /*unused*/) const noexcept
3069  {
3070  return is_number_integer() ? &m_value.number_integer : nullptr;
3071  }
3072 
3074  number_unsigned_t* get_impl_ptr(number_unsigned_t* /*unused*/) noexcept
3075  {
3076  return is_number_unsigned() ? &m_value.number_unsigned : nullptr;
3077  }
3078 
3080  constexpr const number_unsigned_t* get_impl_ptr(const number_unsigned_t* /*unused*/) const noexcept
3081  {
3082  return is_number_unsigned() ? &m_value.number_unsigned : nullptr;
3083  }
3084 
3086  number_float_t* get_impl_ptr(number_float_t* /*unused*/) noexcept
3087  {
3088  return is_number_float() ? &m_value.number_float : nullptr;
3089  }
3090 
3092  constexpr const number_float_t* get_impl_ptr(const number_float_t* /*unused*/) const noexcept
3093  {
3094  return is_number_float() ? &m_value.number_float : nullptr;
3095  }
3096 
3108  template<typename ReferenceType, typename ThisType>
3109  static ReferenceType get_ref_impl(ThisType& obj)
3110  {
3111  // helper type
3112  using PointerType = typename std::add_pointer<ReferenceType>::type;
3113 
3114  // delegate the call to get_ptr<>()
3115  auto ptr = obj.template get_ptr<PointerType>();
3116 
3117  if (ptr != nullptr)
3118  {
3119  return *ptr;
3120  }
3121 
3122  JSON_THROW(std::domain_error("incompatible ReferenceType for get_ref, actual type is " +
3123  obj.type_name()));
3124  }
3125 
3126  public:
3130 
3145  template <
3146  typename BasicJsonType,
3148  basic_json_t>::value,
3149  int> = 0 >
3150  basic_json get() const
3151  {
3152  return *this;
3153  }
3154 
3194  template <
3195  typename ValueTypeCV,
3196  typename ValueType = detail::uncvref_t<ValueTypeCV>,
3198  not std::is_same<basic_json_t, ValueType>::value and
3201  int > = 0 >
3202  ValueType get() const noexcept(noexcept(
3203  JSONSerializer<ValueType>::from_json(std::declval<const basic_json_t&>(), std::declval<ValueType&>())))
3204  {
3205  // we cannot static_assert on ValueTypeCV being non-const, because
3206  // there is support for get<const basic_json_t>(), which is why we
3207  // still need the uncvref
3208  static_assert(not std::is_reference<ValueTypeCV>::value,
3209  "get() cannot be used with reference types, you might want to use get_ref()");
3210  static_assert(std::is_default_constructible<ValueType>::value,
3211  "types must be DefaultConstructible when used with get()");
3212 
3213  ValueType ret;
3215  return ret;
3216  }
3217 
3249  template <
3250  typename ValueTypeCV,
3251  typename ValueType = detail::uncvref_t<ValueTypeCV>,
3254  ValueType>::value, int> = 0 >
3255  ValueType get() const noexcept(noexcept(
3256  JSONSerializer<ValueTypeCV>::from_json(std::declval<const basic_json_t&>())))
3257  {
3258  static_assert(not std::is_reference<ValueTypeCV>::value,
3259  "get() cannot be used with reference types, you might want to use get_ref()");
3261  }
3262 
3290  template<typename PointerType, typename std::enable_if<
3291  std::is_pointer<PointerType>::value, int>::type = 0>
3292  PointerType get() noexcept
3293  {
3294  // delegate the call to get_ptr
3295  return get_ptr<PointerType>();
3296  }
3297 
3302  template<typename PointerType, typename std::enable_if<
3303  std::is_pointer<PointerType>::value, int>::type = 0>
3304  constexpr const PointerType get() const noexcept
3305  {
3306  // delegate the call to get_ptr
3307  return get_ptr<PointerType>();
3308  }
3309 
3336  template<typename PointerType, typename std::enable_if<
3337  std::is_pointer<PointerType>::value, int>::type = 0>
3338  PointerType get_ptr() noexcept
3339  {
3340  // get the type of the PointerType (remove pointer and const)
3341  using pointee_t = typename std::remove_const<typename
3342  std::remove_pointer<typename
3343  std::remove_const<PointerType>::type>::type>::type;
3344  // make sure the type matches the allowed types
3345  static_assert(
3346  std::is_same<object_t, pointee_t>::value
3347  or std::is_same<array_t, pointee_t>::value
3348  or std::is_same<string_t, pointee_t>::value
3349  or std::is_same<boolean_t, pointee_t>::value
3350  or std::is_same<number_integer_t, pointee_t>::value
3351  or std::is_same<number_unsigned_t, pointee_t>::value
3352  or std::is_same<number_float_t, pointee_t>::value
3353  , "incompatible pointer type");
3354 
3355  // delegate the call to get_impl_ptr<>()
3356  return get_impl_ptr(static_cast<PointerType>(nullptr));
3357  }
3358 
3363  template<typename PointerType, typename std::enable_if<
3364  std::is_pointer<PointerType>::value and
3365  std::is_const<typename std::remove_pointer<PointerType>::type>::value, int>::type = 0>
3366  constexpr const PointerType get_ptr() const noexcept
3367  {
3368  // get the type of the PointerType (remove pointer and const)
3369  using pointee_t = typename std::remove_const<typename
3370  std::remove_pointer<typename
3371  std::remove_const<PointerType>::type>::type>::type;
3372  // make sure the type matches the allowed types
3373  static_assert(
3374  std::is_same<object_t, pointee_t>::value
3375  or std::is_same<array_t, pointee_t>::value
3376  or std::is_same<string_t, pointee_t>::value
3377  or std::is_same<boolean_t, pointee_t>::value
3378  or std::is_same<number_integer_t, pointee_t>::value
3379  or std::is_same<number_unsigned_t, pointee_t>::value
3380  or std::is_same<number_float_t, pointee_t>::value
3381  , "incompatible pointer type");
3382 
3383  // delegate the call to get_impl_ptr<>() const
3384  return get_impl_ptr(static_cast<const PointerType>(nullptr));
3385  }
3386 
3413  template<typename ReferenceType, typename std::enable_if<
3414  std::is_reference<ReferenceType>::value, int>::type = 0>
3415  ReferenceType get_ref()
3416  {
3417  // delegate call to get_ref_impl
3418  return get_ref_impl<ReferenceType>(*this);
3419  }
3420 
3425  template<typename ReferenceType, typename std::enable_if<
3426  std::is_reference<ReferenceType>::value and
3427  std::is_const<typename std::remove_reference<ReferenceType>::type>::value, int>::type = 0>
3428  ReferenceType get_ref() const
3429  {
3430  // delegate call to get_ref_impl
3431  return get_ref_impl<ReferenceType>(*this);
3432  }
3433 
3462  template < typename ValueType, typename std::enable_if <
3463  not std::is_pointer<ValueType>::value and
3464  not std::is_same<ValueType, typename string_t::value_type>::value
3465 #ifndef _MSC_VER // fix for issue #167 operator<< ambiguity under VS2015
3466  and not std::is_same<ValueType, std::initializer_list<typename string_t::value_type>>::value
3467 #endif
3468  , int >::type = 0 >
3469  operator ValueType() const
3470  {
3471  // delegate the call to get<>() const
3472  return get<ValueType>();
3473  }
3474 
3476 
3477 
3479  // element access //
3481 
3485 
3509  {
3510  // at only works for arrays
3511  if (is_array())
3512  {
3513  JSON_TRY
3514  {
3515  return m_value.array->at(idx);
3516  }
3517  JSON_CATCH (std::out_of_range&)
3518  {
3519  // create better exception explanation
3520  JSON_THROW(std::out_of_range("array index " + std::to_string(idx) + " is out of range"));
3521  }
3522  }
3523  else
3524  {
3525  JSON_THROW(std::domain_error("cannot use at() with " + type_name()));
3526  }
3527  }
3528 
3552  {
3553  // at only works for arrays
3554  if (is_array())
3555  {
3556  JSON_TRY
3557  {
3558  return m_value.array->at(idx);
3559  }
3560  JSON_CATCH (std::out_of_range&)
3561  {
3562  // create better exception explanation
3563  JSON_THROW(std::out_of_range("array index " + std::to_string(idx) + " is out of range"));
3564  }
3565  }
3566  else
3567  {
3568  JSON_THROW(std::domain_error("cannot use at() with " + type_name()));
3569  }
3570  }
3571 
3598  reference at(const typename object_t::key_type& key)
3599  {
3600  // at only works for objects
3601  if (is_object())
3602  {
3603  JSON_TRY
3604  {
3605  return m_value.object->at(key);
3606  }
3607  JSON_CATCH (std::out_of_range&)
3608  {
3609  // create better exception explanation
3610  JSON_THROW(std::out_of_range("key '" + key + "' not found"));
3611  }
3612  }
3613  else
3614  {
3615  JSON_THROW(std::domain_error("cannot use at() with " + type_name()));
3616  }
3617  }
3618 
3645  const_reference at(const typename object_t::key_type& key) const
3646  {
3647  // at only works for objects
3648  if (is_object())
3649  {
3650  JSON_TRY
3651  {
3652  return m_value.object->at(key);
3653  }
3654  JSON_CATCH (std::out_of_range&)
3655  {
3656  // create better exception explanation
3657  JSON_THROW(std::out_of_range("key '" + key + "' not found"));
3658  }
3659  }
3660  else
3661  {
3662  JSON_THROW(std::domain_error("cannot use at() with " + type_name()));
3663  }
3664  }
3665 
3692  {
3693  // implicitly convert null value to an empty array
3694  if (is_null())
3695  {
3696  m_type = value_t::array;
3697  m_value.array = create<array_t>();
3698  assert_invariant();
3699  }
3700 
3701  // operator[] only works for arrays
3702  if (is_array())
3703  {
3704  // fill up array with null values if given idx is outside range
3705  if (idx >= m_value.array->size())
3706  {
3707  m_value.array->insert(m_value.array->end(),
3708  idx - m_value.array->size() + 1,
3709  basic_json());
3710  }
3711 
3712  return m_value.array->operator[](idx);
3713  }
3714 
3715  JSON_THROW(std::domain_error("cannot use operator[] with " + type_name()));
3716  }
3717 
3738  {
3739  // const operator[] only works for arrays
3740  if (is_array())
3741  {
3742  return m_value.array->operator[](idx);
3743  }
3744 
3745  JSON_THROW(std::domain_error("cannot use operator[] with " + type_name()));
3746  }
3747 
3775  reference operator[](const typename object_t::key_type& key)
3776  {
3777  // implicitly convert null value to an empty object
3778  if (is_null())
3779  {
3780  m_type = value_t::object;
3781  m_value.object = create<object_t>();
3782  assert_invariant();
3783  }
3784 
3785  // operator[] only works for objects
3786  if (is_object())
3787  {
3788  return m_value.object->operator[](key);
3789  }
3790 
3791  JSON_THROW(std::domain_error("cannot use operator[] with " + type_name()));
3792  }
3793 
3824  const_reference operator[](const typename object_t::key_type& key) const
3825  {
3826  // const operator[] only works for objects
3827  if (is_object())
3828  {
3829  assert(m_value.object->find(key) != m_value.object->end());
3830  return m_value.object->find(key)->second;
3831  }
3832 
3833  JSON_THROW(std::domain_error("cannot use operator[] with " + type_name()));
3834  }
3835 
3863  template<typename T, std::size_t n>
3864  reference operator[](T * (&key)[n])
3865  {
3866  return operator[](static_cast<const T>(key));
3867  }
3868 
3898  template<typename T, std::size_t n>
3899  const_reference operator[](T * (&key)[n]) const
3900  {
3901  return operator[](static_cast<const T>(key));
3902  }
3903 
3931  template<typename T>
3933  {
3934  // implicitly convert null to object
3935  if (is_null())
3936  {
3937  m_type = value_t::object;
3938  m_value = value_t::object;
3939  assert_invariant();
3940  }
3941 
3942  // at only works for objects
3943  if (is_object())
3944  {
3945  return m_value.object->operator[](key);
3946  }
3947 
3948  JSON_THROW(std::domain_error("cannot use operator[] with " + type_name()));
3949  }
3950 
3981  template<typename T>
3983  {
3984  // at only works for objects
3985  if (is_object())
3986  {
3987  assert(m_value.object->find(key) != m_value.object->end());
3988  return m_value.object->find(key)->second;
3989  }
3990 
3991  JSON_THROW(std::domain_error("cannot use operator[] with " + type_name()));
3992  }
3993 
4042  template<class ValueType, typename std::enable_if<
4043  std::is_convertible<basic_json_t, ValueType>::value, int>::type = 0>
4044  ValueType value(const typename object_t::key_type& key, ValueType default_value) const
4045  {
4046  // at only works for objects
4047  if (is_object())
4048  {
4049  // if key is found, return value and given default value otherwise
4050  const auto it = find(key);
4051  if (it != end())
4052  {
4053  return *it;
4054  }
4055 
4056  return default_value;
4057  }
4058  else
4059  {
4060  JSON_THROW(std::domain_error("cannot use value() with " + type_name()));
4061  }
4062  }
4063 
4068  string_t value(const typename object_t::key_type& key, const char* default_value) const
4069  {
4070  return value(key, string_t(default_value));
4071  }
4072 
4114  template<class ValueType, typename std::enable_if<
4115  std::is_convertible<basic_json_t, ValueType>::value, int>::type = 0>
4116  ValueType value(const json_pointer& ptr, ValueType default_value) const
4117  {
4118  // at only works for objects
4119  if (is_object())
4120  {
4121  // if pointer resolves a value, return it or use default value
4122  JSON_TRY
4123  {
4124  return ptr.get_checked(this);
4125  }
4126  JSON_CATCH (std::out_of_range&)
4127  {
4128  return default_value;
4129  }
4130  }
4131 
4132  JSON_THROW(std::domain_error("cannot use value() with " + type_name()));
4133  }
4134 
4139  string_t value(const json_pointer& ptr, const char* default_value) const
4140  {
4141  return value(ptr, string_t(default_value));
4142  }
4143 
4170  {
4171  return *begin();
4172  }
4173 
4178  {
4179  return *cbegin();
4180  }
4181 
4213  {
4214  auto tmp = end();
4215  --tmp;
4216  return *tmp;
4217  }
4218 
4223  {
4224  auto tmp = cend();
4225  --tmp;
4226  return *tmp;
4227  }
4228 
4274  template<class IteratorType, typename std::enable_if<
4275  std::is_same<IteratorType, typename basic_json_t::iterator>::value or
4276  std::is_same<IteratorType, typename basic_json_t::const_iterator>::value, int>::type
4277  = 0>
4278  IteratorType erase(IteratorType pos)
4279  {
4280  // make sure iterator fits the current value
4281  if (this != pos.m_object)
4282  {
4283  JSON_THROW(std::domain_error("iterator does not fit current value"));
4284  }
4285 
4286  IteratorType result = end();
4287 
4288  switch (m_type)
4289  {
4290  case value_t::boolean:
4291  case value_t::number_float:
4294  case value_t::string:
4295  {
4296  if (not pos.m_it.primitive_iterator.is_begin())
4297  {
4298  JSON_THROW(std::out_of_range("iterator out of range"));
4299  }
4300 
4301  if (is_string())
4302  {
4303  AllocatorType<string_t> alloc;
4304  alloc.destroy(m_value.string);
4305  alloc.deallocate(m_value.string, 1);
4306  m_value.string = nullptr;
4307  }
4308 
4309  m_type = value_t::null;
4310  assert_invariant();
4311  break;
4312  }
4313 
4314  case value_t::object:
4315  {
4316  result.m_it.object_iterator = m_value.object->erase(pos.m_it.object_iterator);
4317  break;
4318  }
4319 
4320  case value_t::array:
4321  {
4322  result.m_it.array_iterator = m_value.array->erase(pos.m_it.array_iterator);
4323  break;
4324  }
4325 
4326  default:
4327  {
4328  JSON_THROW(std::domain_error("cannot use erase() with " + type_name()));
4329  }
4330  }
4331 
4332  return result;
4333  }
4334 
4381  template<class IteratorType, typename std::enable_if<
4382  std::is_same<IteratorType, typename basic_json_t::iterator>::value or
4383  std::is_same<IteratorType, typename basic_json_t::const_iterator>::value, int>::type
4384  = 0>
4385  IteratorType erase(IteratorType first, IteratorType last)
4386  {
4387  // make sure iterator fits the current value
4388  if (this != first.m_object or this != last.m_object)
4389  {
4390  JSON_THROW(std::domain_error("iterators do not fit current value"));
4391  }
4392 
4393  IteratorType result = end();
4394 
4395  switch (m_type)
4396  {
4397  case value_t::boolean:
4398  case value_t::number_float:
4401  case value_t::string:
4402  {
4403  if (not first.m_it.primitive_iterator.is_begin() or not last.m_it.primitive_iterator.is_end())
4404  {
4405  JSON_THROW(std::out_of_range("iterators out of range"));
4406  }
4407 
4408  if (is_string())
4409  {
4410  AllocatorType<string_t> alloc;
4411  alloc.destroy(m_value.string);
4412  alloc.deallocate(m_value.string, 1);
4413  m_value.string = nullptr;
4414  }
4415 
4416  m_type = value_t::null;
4417  assert_invariant();
4418  break;
4419  }
4420 
4421  case value_t::object:
4422  {
4423  result.m_it.object_iterator = m_value.object->erase(first.m_it.object_iterator,
4424  last.m_it.object_iterator);
4425  break;
4426  }
4427 
4428  case value_t::array:
4429  {
4430  result.m_it.array_iterator = m_value.array->erase(first.m_it.array_iterator,
4431  last.m_it.array_iterator);
4432  break;
4433  }
4434 
4435  default:
4436  {
4437  JSON_THROW(std::domain_error("cannot use erase() with " + type_name()));
4438  }
4439  }
4440 
4441  return result;
4442  }
4443 
4473  size_type erase(const typename object_t::key_type& key)
4474  {
4475  // this erase only works for objects
4476  if (is_object())
4477  {
4478  return m_value.object->erase(key);
4479  }
4480 
4481  JSON_THROW(std::domain_error("cannot use erase() with " + type_name()));
4482  }
4483 
4508  void erase(const size_type idx)
4509  {
4510  // this erase only works for arrays
4511  if (is_array())
4512  {
4513  if (idx >= size())
4514  {
4515  JSON_THROW(std::out_of_range("array index " + std::to_string(idx) + " is out of range"));
4516  }
4517 
4518  m_value.array->erase(m_value.array->begin() + static_cast<difference_type>(idx));
4519  }
4520  else
4521  {
4522  JSON_THROW(std::domain_error("cannot use erase() with " + type_name()));
4523  }
4524  }
4525 
4527 
4528 
4530  // lookup //
4532 
4535 
4558  iterator find(typename object_t::key_type key)
4559  {
4560  auto result = end();
4561 
4562  if (is_object())
4563  {
4564  result.m_it.object_iterator = m_value.object->find(key);
4565  }
4566 
4567  return result;
4568  }
4569 
4574  const_iterator find(typename object_t::key_type key) const
4575  {
4576  auto result = cend();
4577 
4578  if (is_object())
4579  {
4580  result.m_it.object_iterator = m_value.object->find(key);
4581  }
4582 
4583  return result;
4584  }
4585 
4607  size_type count(typename object_t::key_type key) const
4608  {
4609  // return 0 for all nonobject types
4610  return is_object() ? m_value.object->count(key) : 0;
4611  }
4612 
4614 
4615 
4617  // iterators //
4619 
4622 
4647  iterator begin() noexcept
4648  {
4649  iterator result(this);
4650  result.set_begin();
4651  return result;
4652  }
4653 
4657  const_iterator begin() const noexcept
4658  {
4659  return cbegin();
4660  }
4661 
4687  const_iterator cbegin() const noexcept
4688  {
4689  const_iterator result(this);
4690  result.set_begin();
4691  return result;
4692  }
4693 
4718  iterator end() noexcept
4719  {
4720  iterator result(this);
4721  result.set_end();
4722  return result;
4723  }
4724 
4728  const_iterator end() const noexcept
4729  {
4730  return cend();
4731  }
4732 
4758  const_iterator cend() const noexcept
4759  {
4760  const_iterator result(this);
4761  result.set_end();
4762  return result;
4763  }
4764 
4789  {
4790  return reverse_iterator(end());
4791  }
4792 
4797  {
4798  return crbegin();
4799  }
4800 
4826  {
4827  return reverse_iterator(begin());
4828  }
4829 
4833  const_reverse_iterator rend() const noexcept
4834  {
4835  return crend();
4836  }
4837 
4863  {
4864  return const_reverse_iterator(cend());
4865  }
4866 
4892  {
4893  return const_reverse_iterator(cbegin());
4894  }
4895 
4896  private:
4897  // forward declaration
4898  template<typename IteratorType> class iteration_proxy;
4899 
4900  public:
4912  static iteration_proxy<iterator> iterator_wrapper(reference cont)
4913  {
4914  return iteration_proxy<iterator>(cont);
4915  }
4916 
4920  static iteration_proxy<const_iterator> iterator_wrapper(const_reference cont)
4921  {
4922  return iteration_proxy<const_iterator>(cont);
4923  }
4924 
4926 
4927 
4929  // capacity //
4931 
4934 
4972  bool empty() const noexcept
4973  {
4974  switch (m_type)
4975  {
4976  case value_t::null:
4977  {
4978  // null values are empty
4979  return true;
4980  }
4981 
4982  case value_t::array:
4983  {
4984  // delegate call to array_t::empty()
4985  return m_value.array->empty();
4986  }
4987 
4988  case value_t::object:
4989  {
4990  // delegate call to object_t::empty()
4991  return m_value.object->empty();
4992  }
4993 
4994  default:
4995  {
4996  // all other types are nonempty
4997  return false;
4998  }
4999  }
5000  }
5001 
5040  size_type size() const noexcept
5041  {
5042  switch (m_type)
5043  {
5044  case value_t::null:
5045  {
5046  // null values are empty
5047  return 0;
5048  }
5049 
5050  case value_t::array:
5051  {
5052  // delegate call to array_t::size()
5053  return m_value.array->size();
5054  }
5055 
5056  case value_t::object:
5057  {
5058  // delegate call to object_t::size()
5059  return m_value.object->size();
5060  }
5061 
5062  default:
5063  {
5064  // all other types have size 1
5065  return 1;
5066  }
5067  }
5068  }
5069 
5106  size_type max_size() const noexcept
5107  {
5108  switch (m_type)
5109  {
5110  case value_t::array:
5111  {
5112  // delegate call to array_t::max_size()
5113  return m_value.array->max_size();
5114  }
5115 
5116  case value_t::object:
5117  {
5118  // delegate call to object_t::max_size()
5119  return m_value.object->max_size();
5120  }
5121 
5122  default:
5123  {
5124  // all other types have max_size() == size()
5125  return size();
5126  }
5127  }
5128  }
5129 
5131 
5132 
5134  // modifiers //
5136 
5139 
5162  void clear() noexcept
5163  {
5164  switch (m_type)
5165  {
5167  {
5168  m_value.number_integer = 0;
5169  break;
5170  }
5171 
5173  {
5174  m_value.number_unsigned = 0;
5175  break;
5176  }
5177 
5178  case value_t::number_float:
5179  {
5180  m_value.number_float = 0.0;
5181  break;
5182  }
5183 
5184  case value_t::boolean:
5185  {
5186  m_value.boolean = false;
5187  break;
5188  }
5189 
5190  case value_t::string:
5191  {
5192  m_value.string->clear();
5193  break;
5194  }
5195 
5196  case value_t::array:
5197  {
5198  m_value.array->clear();
5199  break;
5200  }
5201 
5202  case value_t::object:
5203  {
5204  m_value.object->clear();
5205  break;
5206  }
5207 
5208  default:
5209  {
5210  break;
5211  }
5212  }
5213  }
5214 
5235  void push_back(basic_json&& val)
5236  {
5237  // push_back only works for null objects or arrays
5238  if (not(is_null() or is_array()))
5239  {
5240  JSON_THROW(std::domain_error("cannot use push_back() with " + type_name()));
5241  }
5242 
5243  // transform null object into an array
5244  if (is_null())
5245  {
5246  m_type = value_t::array;
5247  m_value = value_t::array;
5248  assert_invariant();
5249  }
5250 
5251  // add element to array (move semantics)
5252  m_value.array->push_back(std::move(val));
5253  // invalidate object
5254  val.m_type = value_t::null;
5255  }
5256 
5262  {
5263  push_back(std::move(val));
5264  return *this;
5265  }
5266 
5271  void push_back(const basic_json& val)
5272  {
5273  // push_back only works for null objects or arrays
5274  if (not(is_null() or is_array()))
5275  {
5276  JSON_THROW(std::domain_error("cannot use push_back() with " + type_name()));
5277  }
5278 
5279  // transform null object into an array
5280  if (is_null())
5281  {
5282  m_type = value_t::array;
5283  m_value = value_t::array;
5284  assert_invariant();
5285  }
5286 
5287  // add element to array
5288  m_value.array->push_back(val);
5289  }
5290 
5296  {
5297  push_back(val);
5298  return *this;
5299  }
5300 
5321  void push_back(const typename object_t::value_type& val)
5322  {
5323  // push_back only works for null objects or objects
5324  if (not(is_null() or is_object()))
5325  {
5326  JSON_THROW(std::domain_error("cannot use push_back() with " + type_name()));
5327  }
5328 
5329  // transform null object into an object
5330  if (is_null())
5331  {
5332  m_type = value_t::object;
5333  m_value = value_t::object;
5334  assert_invariant();
5335  }
5336 
5337  // add element to array
5338  m_value.object->insert(val);
5339  }
5340 
5345  reference operator+=(const typename object_t::value_type& val)
5346  {
5347  push_back(val);
5348  return *this;
5349  }
5350 
5376  void push_back(std::initializer_list<basic_json> init)
5377  {
5378  if (is_object() and init.size() == 2 and init.begin()->is_string())
5379  {
5380  const string_t key = *init.begin();
5381  push_back(typename object_t::value_type(key, *(init.begin() + 1)));
5382  }
5383  else
5384  {
5385  push_back(basic_json(init));
5386  }
5387  }
5388 
5393  reference operator+=(std::initializer_list<basic_json> init)
5394  {
5395  push_back(init);
5396  return *this;
5397  }
5398 
5420  template<class... Args>
5421  void emplace_back(Args&& ... args)
5422  {
5423  // emplace_back only works for null objects or arrays
5424  if (not(is_null() or is_array()))
5425  {
5426  JSON_THROW(std::domain_error("cannot use emplace_back() with " + type_name()));
5427  }
5428 
5429  // transform null object into an array
5430  if (is_null())
5431  {
5432  m_type = value_t::array;
5433  m_value = value_t::array;
5434  assert_invariant();
5435  }
5436 
5437  // add element to array (perfect forwarding)
5438  m_value.array->emplace_back(std::forward<Args>(args)...);
5439  }
5440 
5468  template<class... Args>
5469  std::pair<iterator, bool> emplace(Args&& ... args)
5470  {
5471  // emplace only works for null objects or arrays
5472  if (not(is_null() or is_object()))
5473  {
5474  JSON_THROW(std::domain_error("cannot use emplace() with " + type_name()));
5475  }
5476 
5477  // transform null object into an object
5478  if (is_null())
5479  {
5480  m_type = value_t::object;
5481  m_value = value_t::object;
5482  assert_invariant();
5483  }
5484 
5485  // add element to array (perfect forwarding)
5486  auto res = m_value.object->emplace(std::forward<Args>(args)...);
5487  // create result iterator and set iterator to the result of emplace
5488  auto it = begin();
5489  it.m_it.object_iterator = res.first;
5490 
5491  // return pair of iterator and boolean
5492  return {it, res.second};
5493  }
5494 
5518  {
5519  // insert only works for arrays
5520  if (is_array())
5521  {
5522  // check if iterator pos fits to this JSON value
5523  if (pos.m_object != this)
5524  {
5525  JSON_THROW(std::domain_error("iterator does not fit current value"));
5526  }
5527 
5528  // insert to array and return iterator
5529  iterator result(this);
5530  result.m_it.array_iterator = m_value.array->insert(pos.m_it.array_iterator, val);
5531  return result;
5532  }
5533 
5534  JSON_THROW(std::domain_error("cannot use insert() with " + type_name()));
5535  }
5536 
5542  {
5543  return insert(pos, val);
5544  }
5545 
5571  {
5572  // insert only works for arrays
5573  if (is_array())
5574  {
5575  // check if iterator pos fits to this JSON value
5576  if (pos.m_object != this)
5577  {
5578  JSON_THROW(std::domain_error("iterator does not fit current value"));
5579  }
5580 
5581  // insert to array and return iterator
5582  iterator result(this);
5583  result.m_it.array_iterator = m_value.array->insert(pos.m_it.array_iterator, cnt, val);
5584  return result;
5585  }
5586 
5587  JSON_THROW(std::domain_error("cannot use insert() with " + type_name()));
5588  }
5589 
5621  {
5622  // insert only works for arrays
5623  if (not is_array())
5624  {
5625  JSON_THROW(std::domain_error("cannot use insert() with " + type_name()));
5626  }
5627 
5628  // check if iterator pos fits to this JSON value
5629  if (pos.m_object != this)
5630  {
5631  JSON_THROW(std::domain_error("iterator does not fit current value"));
5632  }
5633 
5634  // check if range iterators belong to the same JSON object
5635  if (first.m_object != last.m_object)
5636  {
5637  JSON_THROW(std::domain_error("iterators do not fit"));
5638  }
5639 
5640  if (first.m_object == this or last.m_object == this)
5641  {
5642  JSON_THROW(std::domain_error("passed iterators may not belong to container"));
5643  }
5644 
5645  // insert to array and return iterator
5646  iterator result(this);
5647  result.m_it.array_iterator = m_value.array->insert(
5648  pos.m_it.array_iterator,
5649  first.m_it.array_iterator,
5650  last.m_it.array_iterator);
5651  return result;
5652  }
5653 
5678  iterator insert(const_iterator pos, std::initializer_list<basic_json> ilist)
5679  {
5680  // insert only works for arrays
5681  if (not is_array())
5682  {
5683  JSON_THROW(std::domain_error("cannot use insert() with " + type_name()));
5684  }
5685 
5686  // check if iterator pos fits to this JSON value
5687  if (pos.m_object != this)
5688  {
5689  JSON_THROW(std::domain_error("iterator does not fit current value"));
5690  }
5691 
5692  // insert to array and return iterator
5693  iterator result(this);
5694  result.m_it.array_iterator = m_value.array->insert(pos.m_it.array_iterator, ilist);
5695  return result;
5696  }
5697 
5715  void swap(reference other) noexcept (
5716  std::is_nothrow_move_constructible<value_t>::value and
5717  std::is_nothrow_move_assignable<value_t>::value and
5718  std::is_nothrow_move_constructible<json_value>::value and
5719  std::is_nothrow_move_assignable<json_value>::value
5720  )
5721  {
5722  std::swap(m_type, other.m_type);
5723  std::swap(m_value, other.m_value);
5724  assert_invariant();
5725  }
5726 
5747  void swap(array_t& other)
5748  {
5749  // swap only works for arrays
5750  if (is_array())
5751  {
5752  std::swap(*(m_value.array), other);
5753  }
5754  else
5755  {
5756  JSON_THROW(std::domain_error("cannot use swap() with " + type_name()));
5757  }
5758  }
5759 
5780  void swap(object_t& other)
5781  {
5782  // swap only works for objects
5783  if (is_object())
5784  {
5785  std::swap(*(m_value.object), other);
5786  }
5787  else
5788  {
5789  JSON_THROW(std::domain_error("cannot use swap() with " + type_name()));
5790  }
5791  }
5792 
5813  void swap(string_t& other)
5814  {
5815  // swap only works for strings
5816  if (is_string())
5817  {
5818  std::swap(*(m_value.string), other);
5819  }
5820  else
5821  {
5822  JSON_THROW(std::domain_error("cannot use swap() with " + type_name()));
5823  }
5824  }
5825 
5827 
5828  public:
5830  // lexicographical comparison operators //
5832 
5835 
5859  friend bool operator==(const_reference lhs, const_reference rhs) noexcept
5860  {
5861  const auto lhs_type = lhs.type();
5862  const auto rhs_type = rhs.type();
5863 
5864  if (lhs_type == rhs_type)
5865  {
5866  switch (lhs_type)
5867  {
5868  case value_t::array:
5869  {
5870  return *lhs.m_value.array == *rhs.m_value.array;
5871  }
5872  case value_t::object:
5873  {
5874  return *lhs.m_value.object == *rhs.m_value.object;
5875  }
5876  case value_t::null:
5877  {
5878  return true;
5879  }
5880  case value_t::string:
5881  {
5882  return *lhs.m_value.string == *rhs.m_value.string;
5883  }
5884  case value_t::boolean:
5885  {
5886  return lhs.m_value.boolean == rhs.m_value.boolean;
5887  }
5889  {
5890  return lhs.m_value.number_integer == rhs.m_value.number_integer;
5891  }
5893  {
5894  return lhs.m_value.number_unsigned == rhs.m_value.number_unsigned;
5895  }
5896  case value_t::number_float:
5897  {
5898  return lhs.m_value.number_float == rhs.m_value.number_float;
5899  }
5900  default:
5901  {
5902  return false;
5903  }
5904  }
5905  }
5906  else if (lhs_type == value_t::number_integer and rhs_type == value_t::number_float)
5907  {
5908  return static_cast<number_float_t>(lhs.m_value.number_integer) == rhs.m_value.number_float;
5909  }
5910  else if (lhs_type == value_t::number_float and rhs_type == value_t::number_integer)
5911  {
5912  return lhs.m_value.number_float == static_cast<number_float_t>(rhs.m_value.number_integer);
5913  }
5914  else if (lhs_type == value_t::number_unsigned and rhs_type == value_t::number_float)
5915  {
5916  return static_cast<number_float_t>(lhs.m_value.number_unsigned) == rhs.m_value.number_float;
5917  }
5918  else if (lhs_type == value_t::number_float and rhs_type == value_t::number_unsigned)
5919  {
5920  return lhs.m_value.number_float == static_cast<number_float_t>(rhs.m_value.number_unsigned);
5921  }
5922  else if (lhs_type == value_t::number_unsigned and rhs_type == value_t::number_integer)
5923  {
5924  return static_cast<number_integer_t>(lhs.m_value.number_unsigned) == rhs.m_value.number_integer;
5925  }
5926  else if (lhs_type == value_t::number_integer and rhs_type == value_t::number_unsigned)
5927  {
5928  return lhs.m_value.number_integer == static_cast<number_integer_t>(rhs.m_value.number_unsigned);
5929  }
5930 
5931  return false;
5932  }
5933 
5938  template<typename ScalarType, typename std::enable_if<
5939  std::is_scalar<ScalarType>::value, int>::type = 0>
5940  friend bool operator==(const_reference lhs, const ScalarType rhs) noexcept
5941  {
5942  return (lhs == basic_json(rhs));
5943  }
5944 
5949  template<typename ScalarType, typename std::enable_if<
5950  std::is_scalar<ScalarType>::value, int>::type = 0>
5951  friend bool operator==(const ScalarType lhs, const_reference rhs) noexcept
5952  {
5953  return (basic_json(lhs) == rhs);
5954  }
5955 
5972  friend bool operator!=(const_reference lhs, const_reference rhs) noexcept
5973  {
5974  return not (lhs == rhs);
5975  }
5976 
5981  template<typename ScalarType, typename std::enable_if<
5982  std::is_scalar<ScalarType>::value, int>::type = 0>
5983  friend bool operator!=(const_reference lhs, const ScalarType rhs) noexcept
5984  {
5985  return (lhs != basic_json(rhs));
5986  }
5987 
5992  template<typename ScalarType, typename std::enable_if<
5993  std::is_scalar<ScalarType>::value, int>::type = 0>
5994  friend bool operator!=(const ScalarType lhs, const_reference rhs) noexcept
5995  {
5996  return (basic_json(lhs) != rhs);
5997  }
5998 
6023  friend bool operator<(const_reference lhs, const_reference rhs) noexcept
6024  {
6025  const auto lhs_type = lhs.type();
6026  const auto rhs_type = rhs.type();
6027 
6028  if (lhs_type == rhs_type)
6029  {
6030  switch (lhs_type)
6031  {
6032  case value_t::array:
6033  {
6034  return *lhs.m_value.array < *rhs.m_value.array;
6035  }
6036  case value_t::object:
6037  {
6038  return *lhs.m_value.object < *rhs.m_value.object;
6039  }
6040  case value_t::null:
6041  {
6042  return false;
6043  }
6044  case value_t::string:
6045  {
6046  return *lhs.m_value.string < *rhs.m_value.string;
6047  }
6048  case value_t::boolean:
6049  {
6050  return lhs.m_value.boolean < rhs.m_value.boolean;
6051  }
6053  {
6054  return lhs.m_value.number_integer < rhs.m_value.number_integer;
6055  }
6057  {
6058  return lhs.m_value.number_unsigned < rhs.m_value.number_unsigned;
6059  }
6060  case value_t::number_float:
6061  {
6062  return lhs.m_value.number_float < rhs.m_value.number_float;
6063  }
6064  default:
6065  {
6066  return false;
6067  }
6068  }
6069  }
6070  else if (lhs_type == value_t::number_integer and rhs_type == value_t::number_float)
6071  {
6072  return static_cast<number_float_t>(lhs.m_value.number_integer) < rhs.m_value.number_float;
6073  }
6074  else if (lhs_type == value_t::number_float and rhs_type == value_t::number_integer)
6075  {
6076  return lhs.m_value.number_float < static_cast<number_float_t>(rhs.m_value.number_integer);
6077  }
6078  else if (lhs_type == value_t::number_unsigned and rhs_type == value_t::number_float)
6079  {
6080  return static_cast<number_float_t>(lhs.m_value.number_unsigned) < rhs.m_value.number_float;
6081  }
6082  else if (lhs_type == value_t::number_float and rhs_type == value_t::number_unsigned)
6083  {
6084  return lhs.m_value.number_float < static_cast<number_float_t>(rhs.m_value.number_unsigned);
6085  }
6086  else if (lhs_type == value_t::number_integer and rhs_type == value_t::number_unsigned)
6087  {
6088  return lhs.m_value.number_integer < static_cast<number_integer_t>(rhs.m_value.number_unsigned);
6089  }
6090  else if (lhs_type == value_t::number_unsigned and rhs_type == value_t::number_integer)
6091  {
6092  return static_cast<number_integer_t>(lhs.m_value.number_unsigned) < rhs.m_value.number_integer;
6093  }
6094 
6095  // We only reach this line if we cannot compare values. In that case,
6096  // we compare types. Note we have to call the operator explicitly,
6097  // because MSVC has problems otherwise.
6098  return operator<(lhs_type, rhs_type);
6099  }
6100 
6118  friend bool operator<=(const_reference lhs, const_reference rhs) noexcept
6119  {
6120  return not (rhs < lhs);
6121  }
6122 
6140  friend bool operator>(const_reference lhs, const_reference rhs) noexcept
6141  {
6142  return not (lhs <= rhs);
6143  }
6144 
6162  friend bool operator>=(const_reference lhs, const_reference rhs) noexcept
6163  {
6164  return not (lhs < rhs);
6165  }
6166 
6168 
6169 
6171  // serialization //
6173 
6176 
6199  friend std::ostream& operator<<(std::ostream& o, const basic_json& j)
6200  {
6201  // read width member and use it as indentation parameter if nonzero
6202  const bool pretty_print = (o.width() > 0);
6203  const auto indentation = (pretty_print ? o.width() : 0);
6204 
6205  // reset width to 0 for subsequent calls to this stream
6206  o.width(0);
6207 
6208  // do the actual serialization
6209  j.dump(o, pretty_print, static_cast<unsigned int>(indentation));
6210 
6211  return o;
6212  }
6213 
6218  friend std::ostream& operator>>(const basic_json& j, std::ostream& o)
6219  {
6220  return o << j;
6221  }
6222 
6224 
6225 
6227  // deserialization //
6229 
6232 
6260  template<class T, std::size_t N>
6261  static basic_json parse(T (&array)[N],
6262  const parser_callback_t cb = nullptr)
6263  {
6264  // delegate the call to the iterator-range parse overload
6265  return parse(std::begin(array), std::end(array), cb);
6266  }
6267 
6295  template<typename CharT, typename std::enable_if<
6296  std::is_pointer<CharT>::value and
6297  std::is_integral<typename std::remove_pointer<CharT>::type>::value and
6298  sizeof(typename std::remove_pointer<CharT>::type) == 1, int>::type = 0>
6299  static basic_json parse(const CharT s,
6300  const parser_callback_t cb = nullptr)
6301  {
6302  return parser(reinterpret_cast<const char*>(s), cb).parse();
6303  }
6304 
6329  static basic_json parse(std::istream& i,
6330  const parser_callback_t cb = nullptr)
6331  {
6332  return parser(i, cb).parse();
6333  }
6334 
6338  static basic_json parse(std::istream&& i,
6339  const parser_callback_t cb = nullptr)
6340  {
6341  return parser(i, cb).parse();
6342  }
6343 
6385  template<class IteratorType, typename std::enable_if<
6386  std::is_base_of<
6387  std::random_access_iterator_tag,
6388  typename std::iterator_traits<IteratorType>::iterator_category>::value, int>::type = 0>
6389  static basic_json parse(IteratorType first, IteratorType last,
6390  const parser_callback_t cb = nullptr)
6391  {
6392  // assertion to check that the iterator range is indeed contiguous,
6393  // see http://stackoverflow.com/a/35008842/266378 for more discussion
6394  assert(std::accumulate(first, last, std::pair<bool, int>(true, 0),
6395  [&first](std::pair<bool, int> res, decltype(*first) val)
6396  {
6397  res.first &= (val == *(std::next(std::addressof(*first), res.second++)));
6398  return res;
6399  }).first);
6400 
6401  // assertion to check that each element is 1 byte long
6402  static_assert(sizeof(typename std::iterator_traits<IteratorType>::value_type) == 1,
6403  "each element in the iterator range must have the size of 1 byte");
6404 
6405  // if iterator range is empty, create a parser with an empty string
6406  // to generate "unexpected EOF" error message
6407  if (std::distance(first, last) <= 0)
6408  {
6409  return parser("").parse();
6410  }
6411 
6412  return parser(first, last, cb).parse();
6413  }
6414 
6455  template<class ContiguousContainer, typename std::enable_if<
6456  not std::is_pointer<ContiguousContainer>::value and
6457  std::is_base_of<
6458  std::random_access_iterator_tag,
6459  typename std::iterator_traits<decltype(std::begin(std::declval<ContiguousContainer const>()))>::iterator_category>::value
6460  , int>::type = 0>
6461  static basic_json parse(const ContiguousContainer& c,
6462  const parser_callback_t cb = nullptr)
6463  {
6464  // delegate the call to the iterator-range parse overload
6465  return parse(std::begin(c), std::end(c), cb);
6466  }
6467 
6491  friend std::istream& operator<<(basic_json& j, std::istream& i)
6492  {
6493  j = parser(i).parse();
6494  return i;
6495  }
6496 
6501  friend std::istream& operator>>(std::istream& i, basic_json& j)
6502  {
6503  j = parser(i).parse();
6504  return i;
6505  }
6506 
6508 
6510  // binary serialization/deserialization //
6512 
6515 
6516  private:
6522  template<typename T>
6523  static void add_to_vector(std::vector<uint8_t>& vec, size_t bytes, const T number)
6524  {
6525  assert(bytes == 1 or bytes == 2 or bytes == 4 or bytes == 8);
6526 
6527  switch (bytes)
6528  {
6529  case 8:
6530  {
6531  vec.push_back(static_cast<uint8_t>((static_cast<uint64_t>(number) >> 070) & 0xff));
6532  vec.push_back(static_cast<uint8_t>((static_cast<uint64_t>(number) >> 060) & 0xff));
6533  vec.push_back(static_cast<uint8_t>((static_cast<uint64_t>(number) >> 050) & 0xff));
6534  vec.push_back(static_cast<uint8_t>((static_cast<uint64_t>(number) >> 040) & 0xff));
6535  vec.push_back(static_cast<uint8_t>((number >> 030) & 0xff));
6536  vec.push_back(static_cast<uint8_t>((number >> 020) & 0xff));
6537  vec.push_back(static_cast<uint8_t>((number >> 010) & 0xff));
6538  vec.push_back(static_cast<uint8_t>(number & 0xff));
6539  break;
6540  }
6541 
6542  case 4:
6543  {
6544  vec.push_back(static_cast<uint8_t>((number >> 030) & 0xff));
6545  vec.push_back(static_cast<uint8_t>((number >> 020) & 0xff));
6546  vec.push_back(static_cast<uint8_t>((number >> 010) & 0xff));
6547  vec.push_back(static_cast<uint8_t>(number & 0xff));
6548  break;
6549  }
6550 
6551  case 2:
6552  {
6553  vec.push_back(static_cast<uint8_t>((number >> 010) & 0xff));
6554  vec.push_back(static_cast<uint8_t>(number & 0xff));
6555  break;
6556  }
6557 
6558  case 1:
6559  {
6560  vec.push_back(static_cast<uint8_t>(number & 0xff));
6561  break;
6562  }
6563  }
6564  }
6565 
6602  template<typename T>
6603  static T get_from_vector(const std::vector<uint8_t>& vec, const size_t current_index)
6604  {
6605  if (current_index + sizeof(T) + 1 > vec.size())
6606  {
6607  JSON_THROW(std::out_of_range("cannot read " + std::to_string(sizeof(T)) + " bytes from vector"));
6608  }
6609 
6610  T result;
6611  auto* ptr = reinterpret_cast<uint8_t*>(&result);
6612  for (size_t i = 0; i < sizeof(T); ++i)
6613  {
6614  *ptr++ = vec[current_index + sizeof(T) - i];
6615  }
6616  return result;
6617  }
6618 
6629  static void to_msgpack_internal(const basic_json& j, std::vector<uint8_t>& v)
6630  {
6631  switch (j.type())
6632  {
6633  case value_t::null:
6634  {
6635  // nil
6636  v.push_back(0xc0);
6637  break;
6638  }
6639 
6640  case value_t::boolean:
6641  {
6642  // true and false
6643  v.push_back(j.m_value.boolean ? 0xc3 : 0xc2);
6644  break;
6645  }
6646 
6648  {
6649  if (j.m_value.number_integer >= 0)
6650  {
6651  // MessagePack does not differentiate between positive
6652  // signed integers and unsigned integers. Therefore, we
6653  // used the code from the value_t::number_unsigned case
6654  // here.
6655  if (j.m_value.number_unsigned < 128)
6656  {
6657  // positive fixnum
6658  add_to_vector(v, 1, j.m_value.number_unsigned);
6659  }
6660  else if (j.m_value.number_unsigned <= std::numeric_limits<uint8_t>::max())
6661  {
6662  // uint 8
6663  v.push_back(0xcc);
6664  add_to_vector(v, 1, j.m_value.number_unsigned);
6665  }
6666  else if (j.m_value.number_unsigned <= std::numeric_limits<uint16_t>::max())
6667  {
6668  // uint 16
6669  v.push_back(0xcd);
6670  add_to_vector(v, 2, j.m_value.number_unsigned);
6671  }
6672  else if (j.m_value.number_unsigned <= std::numeric_limits<uint32_t>::max())
6673  {
6674  // uint 32
6675  v.push_back(0xce);
6676  add_to_vector(v, 4, j.m_value.number_unsigned);
6677  }
6678  else if (j.m_value.number_unsigned <= std::numeric_limits<uint64_t>::max())
6679  {
6680  // uint 64
6681  v.push_back(0xcf);
6682  add_to_vector(v, 8, j.m_value.number_unsigned);
6683  }
6684  }
6685  else
6686  {
6687  if (j.m_value.number_integer >= -32)
6688  {
6689  // negative fixnum
6690  add_to_vector(v, 1, j.m_value.number_integer);
6691  }
6692  else if (j.m_value.number_integer >= std::numeric_limits<int8_t>::min() and j.m_value.number_integer <= std::numeric_limits<int8_t>::max())
6693  {
6694  // int 8
6695  v.push_back(0xd0);
6696  add_to_vector(v, 1, j.m_value.number_integer);
6697  }
6698  else if (j.m_value.number_integer >= std::numeric_limits<int16_t>::min() and j.m_value.number_integer <= std::numeric_limits<int16_t>::max())
6699  {
6700  // int 16
6701  v.push_back(0xd1);
6702  add_to_vector(v, 2, j.m_value.number_integer);
6703  }
6704  else if (j.m_value.number_integer >= std::numeric_limits<int32_t>::min() and j.m_value.number_integer <= std::numeric_limits<int32_t>::max())
6705  {
6706  // int 32
6707  v.push_back(0xd2);
6708  add_to_vector(v, 4, j.m_value.number_integer);
6709  }
6710  else if (j.m_value.number_integer >= std::numeric_limits<int64_t>::min() and j.m_value.number_integer <= std::numeric_limits<int64_t>::max())
6711  {
6712  // int 64
6713  v.push_back(0xd3);
6714  add_to_vector(v, 8, j.m_value.number_integer);
6715  }
6716  }
6717  break;
6718  }
6719 
6721  {
6722  if (j.m_value.number_unsigned < 128)
6723  {
6724  // positive fixnum
6725  add_to_vector(v, 1, j.m_value.number_unsigned);
6726  }
6727  else if (j.m_value.number_unsigned <= std::numeric_limits<uint8_t>::max())
6728  {
6729  // uint 8
6730  v.push_back(0xcc);
6731  add_to_vector(v, 1, j.m_value.number_unsigned);
6732  }
6733  else if (j.m_value.number_unsigned <= std::numeric_limits<uint16_t>::max())
6734  {
6735  // uint 16
6736  v.push_back(0xcd);
6737  add_to_vector(v, 2, j.m_value.number_unsigned);
6738  }
6739  else if (j.m_value.number_unsigned <= std::numeric_limits<uint32_t>::max())
6740  {
6741  // uint 32
6742  v.push_back(0xce);
6743  add_to_vector(v, 4, j.m_value.number_unsigned);
6744  }
6745  else if (j.m_value.number_unsigned <= std::numeric_limits<uint64_t>::max())
6746  {
6747  // uint 64
6748  v.push_back(0xcf);
6749  add_to_vector(v, 8, j.m_value.number_unsigned);
6750  }
6751  break;
6752  }
6753 
6754  case value_t::number_float:
6755  {
6756  // float 64
6757  v.push_back(0xcb);
6758  const auto* helper = reinterpret_cast<const uint8_t*>(&(j.m_value.number_float));
6759  for (size_t i = 0; i < 8; ++i)
6760  {
6761  v.push_back(helper[7 - i]);
6762  }
6763  break;
6764  }
6765 
6766  case value_t::string:
6767  {
6768  const auto N = j.m_value.string->size();
6769  if (N <= 31)
6770  {
6771  // fixstr
6772  v.push_back(static_cast<uint8_t>(0xa0 | N));
6773  }
6774  else if (N <= 255)
6775  {
6776  // str 8
6777  v.push_back(0xd9);
6778  add_to_vector(v, 1, N);
6779  }
6780  else if (N <= 65535)
6781  {
6782  // str 16
6783  v.push_back(0xda);
6784  add_to_vector(v, 2, N);
6785  }
6786  else if (N <= 4294967295)
6787  {
6788  // str 32
6789  v.push_back(0xdb);
6790  add_to_vector(v, 4, N);
6791  }
6792 
6793  // append string
6794  std::copy(j.m_value.string->begin(), j.m_value.string->end(),
6795  std::back_inserter(v));
6796  break;
6797  }
6798 
6799  case value_t::array:
6800  {
6801  const auto N = j.m_value.array->size();
6802  if (N <= 15)
6803  {
6804  // fixarray
6805  v.push_back(static_cast<uint8_t>(0x90 | N));
6806  }
6807  else if (N <= 0xffff)
6808  {
6809  // array 16
6810  v.push_back(0xdc);
6811  add_to_vector(v, 2, N);
6812  }
6813  else if (N <= 0xffffffff)
6814  {
6815  // array 32
6816  v.push_back(0xdd);
6817  add_to_vector(v, 4, N);
6818  }
6819 
6820  // append each element
6821  for (const auto& el : *j.m_value.array)
6822  {
6823  to_msgpack_internal(el, v);
6824  }
6825  break;
6826  }
6827 
6828  case value_t::object:
6829  {
6830  const auto N = j.m_value.object->size();
6831  if (N <= 15)
6832  {
6833  // fixmap
6834  v.push_back(static_cast<uint8_t>(0x80 | (N & 0xf)));
6835  }
6836  else if (N <= 65535)
6837  {
6838  // map 16
6839  v.push_back(0xde);
6840  add_to_vector(v, 2, N);
6841  }
6842  else if (N <= 4294967295)
6843  {
6844  // map 32
6845  v.push_back(0xdf);
6846  add_to_vector(v, 4, N);
6847  }
6848 
6849  // append each element
6850  for (const auto& el : *j.m_value.object)
6851  {
6852  to_msgpack_internal(el.first, v);
6853  to_msgpack_internal(el.second, v);
6854  }
6855  break;
6856  }
6857 
6858  default:
6859  {
6860  break;
6861  }
6862  }
6863  }
6864 
6875  static void to_cbor_internal(const basic_json& j, std::vector<uint8_t>& v)
6876  {
6877  switch (j.type())
6878  {
6879  case value_t::null:
6880  {
6881  v.push_back(0xf6);
6882  break;
6883  }
6884 
6885  case value_t::boolean:
6886  {
6887  v.push_back(j.m_value.boolean ? 0xf5 : 0xf4);
6888  break;
6889  }
6890 
6892  {
6893  if (j.m_value.number_integer >= 0)
6894  {
6895  // CBOR does not differentiate between positive signed
6896  // integers and unsigned integers. Therefore, we used the
6897  // code from the value_t::number_unsigned case here.
6898  if (j.m_value.number_integer <= 0x17)
6899  {
6900  add_to_vector(v, 1, j.m_value.number_integer);
6901  }
6902  else if (j.m_value.number_integer <= std::numeric_limits<uint8_t>::max())
6903  {
6904  v.push_back(0x18);
6905  // one-byte uint8_t
6906  add_to_vector(v, 1, j.m_value.number_integer);
6907  }
6908  else if (j.m_value.number_integer <= std::numeric_limits<uint16_t>::max())
6909  {
6910  v.push_back(0x19);
6911  // two-byte uint16_t
6912  add_to_vector(v, 2, j.m_value.number_integer);
6913  }
6914  else if (j.m_value.number_integer <= std::numeric_limits<uint32_t>::max())
6915  {
6916  v.push_back(0x1a);
6917  // four-byte uint32_t
6918  add_to_vector(v, 4, j.m_value.number_integer);
6919  }
6920  else
6921  {
6922  v.push_back(0x1b);
6923  // eight-byte uint64_t
6924  add_to_vector(v, 8, j.m_value.number_integer);
6925  }
6926  }
6927  else
6928  {
6929  // The conversions below encode the sign in the first
6930  // byte, and the value is converted to a positive number.
6931  const auto positive_number = -1 - j.m_value.number_integer;
6932  if (j.m_value.number_integer >= -24)
6933  {
6934  v.push_back(static_cast<uint8_t>(0x20 + positive_number));
6935  }
6936  else if (positive_number <= std::numeric_limits<uint8_t>::max())
6937  {
6938  // int 8
6939  v.push_back(0x38);
6940  add_to_vector(v, 1, positive_number);
6941  }
6942  else if (positive_number <= std::numeric_limits<uint16_t>::max())
6943  {
6944  // int 16
6945  v.push_back(0x39);
6946  add_to_vector(v, 2, positive_number);
6947  }
6948  else if (positive_number <= std::numeric_limits<uint32_t>::max())
6949  {
6950  // int 32
6951  v.push_back(0x3a);
6952  add_to_vector(v, 4, positive_number);
6953  }
6954  else
6955  {
6956  // int 64
6957  v.push_back(0x3b);
6958  add_to_vector(v, 8, positive_number);
6959  }
6960  }
6961  break;
6962  }
6963 
6965  {
6966  if (j.m_value.number_unsigned <= 0x17)
6967  {
6968  v.push_back(static_cast<uint8_t>(j.m_value.number_unsigned));
6969  }
6970  else if (j.m_value.number_unsigned <= 0xff)
6971  {
6972  v.push_back(0x18);
6973  // one-byte uint8_t
6974  add_to_vector(v, 1, j.m_value.number_unsigned);
6975  }
6976  else if (j.m_value.number_unsigned <= 0xffff)
6977  {
6978  v.push_back(0x19);
6979  // two-byte uint16_t
6980  add_to_vector(v, 2, j.m_value.number_unsigned);
6981  }
6982  else if (j.m_value.number_unsigned <= 0xffffffff)
6983  {
6984  v.push_back(0x1a);
6985  // four-byte uint32_t
6986  add_to_vector(v, 4, j.m_value.number_unsigned);
6987  }
6988  else if (j.m_value.number_unsigned <= 0xffffffffffffffff)
6989  {
6990  v.push_back(0x1b);
6991  // eight-byte uint64_t
6992  add_to_vector(v, 8, j.m_value.number_unsigned);
6993  }
6994  break;
6995  }
6996 
6997  case value_t::number_float:
6998  {
6999  // Double-Precision Float
7000  v.push_back(0xfb);
7001  const auto* helper = reinterpret_cast<const uint8_t*>(&(j.m_value.number_float));
7002  for (size_t i = 0; i < 8; ++i)
7003  {
7004  v.push_back(helper[7 - i]);
7005  }
7006  break;
7007  }
7008 
7009  case value_t::string:
7010  {
7011  const auto N = j.m_value.string->size();
7012  if (N <= 0x17)
7013  {
7014  v.push_back(0x60 + static_cast<uint8_t>(N)); // 1 byte for string + size
7015  }
7016  else if (N <= 0xff)
7017  {
7018  v.push_back(0x78); // one-byte uint8_t for N
7019  add_to_vector(v, 1, N);
7020  }
7021  else if (N <= 0xffff)
7022  {
7023  v.push_back(0x79); // two-byte uint16_t for N
7024  add_to_vector(v, 2, N);
7025  }
7026  else if (N <= 0xffffffff)
7027  {
7028  v.push_back(0x7a); // four-byte uint32_t for N
7029  add_to_vector(v, 4, N);
7030  }
7031  // LCOV_EXCL_START
7032  else if (N <= 0xffffffffffffffff)
7033  {
7034  v.push_back(0x7b); // eight-byte uint64_t for N
7035  add_to_vector(v, 8, N);
7036  }
7037  // LCOV_EXCL_STOP
7038 
7039  // append string
7040  std::copy(j.m_value.string->begin(), j.m_value.string->end(),
7041  std::back_inserter(v));
7042  break;
7043  }
7044 
7045  case value_t::array:
7046  {
7047  const auto N = j.m_value.array->size();
7048  if (N <= 0x17)
7049  {
7050  v.push_back(0x80 + static_cast<uint8_t>(N)); // 1 byte for array + size
7051  }
7052  else if (N <= 0xff)
7053  {
7054  v.push_back(0x98); // one-byte uint8_t for N
7055  add_to_vector(v, 1, N);
7056  }
7057  else if (N <= 0xffff)
7058  {
7059  v.push_back(0x99); // two-byte uint16_t for N
7060  add_to_vector(v, 2, N);
7061  }
7062  else if (N <= 0xffffffff)
7063  {
7064  v.push_back(0x9a); // four-byte uint32_t for N
7065  add_to_vector(v, 4, N);
7066  }
7067  // LCOV_EXCL_START
7068  else if (N <= 0xffffffffffffffff)
7069  {
7070  v.push_back(0x9b); // eight-byte uint64_t for N
7071  add_to_vector(v, 8, N);
7072  }
7073  // LCOV_EXCL_STOP
7074 
7075  // append each element
7076  for (const auto& el : *j.m_value.array)
7077  {
7078  to_cbor_internal(el, v);
7079  }
7080  break;
7081  }
7082 
7083  case value_t::object:
7084  {
7085  const auto N = j.m_value.object->size();
7086  if (N <= 0x17)
7087  {
7088  v.push_back(0xa0 + static_cast<uint8_t>(N)); // 1 byte for object + size
7089  }
7090  else if (N <= 0xff)
7091  {
7092  v.push_back(0xb8);
7093  add_to_vector(v, 1, N); // one-byte uint8_t for N
7094  }
7095  else if (N <= 0xffff)
7096  {
7097  v.push_back(0xb9);
7098  add_to_vector(v, 2, N); // two-byte uint16_t for N
7099  }
7100  else if (N <= 0xffffffff)
7101  {
7102  v.push_back(0xba);
7103  add_to_vector(v, 4, N); // four-byte uint32_t for N
7104  }
7105  // LCOV_EXCL_START
7106  else if (N <= 0xffffffffffffffff)
7107  {
7108  v.push_back(0xbb);
7109  add_to_vector(v, 8, N); // eight-byte uint64_t for N
7110  }
7111  // LCOV_EXCL_STOP
7112 
7113  // append each element
7114  for (const auto& el : *j.m_value.object)
7115  {
7116  to_cbor_internal(el.first, v);
7117  to_cbor_internal(el.second, v);
7118  }
7119  break;
7120  }
7121 
7122  default:
7123  {
7124  break;
7125  }
7126  }
7127  }
7128 
7129 
7130  /*
7131  @brief checks if given lengths do not exceed the size of a given vector
7132 
7133  To secure the access to the byte vector during CBOR/MessagePack
7134  deserialization, bytes are copied from the vector into buffers. This
7135  function checks if the number of bytes to copy (@a len) does not exceed
7136  the size @s size of the vector. Additionally, an @a offset is given from
7137  where to start reading the bytes.
7138 
7139  This function checks whether reading the bytes is safe; that is, offset is
7140  a valid index in the vector, offset+len
7141 
7142  @param[in] size size of the byte vector
7143  @param[in] len number of bytes to read
7144  @param[in] offset offset where to start reading
7145 
7146  vec: x x x x x X X X X X
7147  ^ ^ ^
7148  0 offset len
7149 
7150  @throws out_of_range if `len > v.size()`
7151  */
7152  static void check_length(const size_t size, const size_t len, const size_t offset)
7153  {
7154  // simple case: requested length is greater than the vector's length
7155  if (len > size or offset > size)
7156  {
7157  JSON_THROW(std::out_of_range("len out of range"));
7158  }
7159 
7160  // second case: adding offset would result in overflow
7161  if ((size > (std::numeric_limits<size_t>::max() - offset)))
7162  {
7163  JSON_THROW(std::out_of_range("len+offset out of range"));
7164  }
7165 
7166  // last case: reading past the end of the vector
7167  if (len + offset > size)
7168  {
7169  JSON_THROW(std::out_of_range("len+offset out of range"));
7170  }
7171  }
7172 
7187  static basic_json from_msgpack_internal(const std::vector<uint8_t>& v, size_t& idx)
7188  {
7189  // make sure reading 1 byte is safe
7190  check_length(v.size(), 1, idx);
7191 
7192  // store and increment index
7193  const size_t current_idx = idx++;
7194 
7195  if (v[current_idx] <= 0xbf)
7196  {
7197  if (v[current_idx] <= 0x7f) // positive fixint
7198  {
7199  return v[current_idx];
7200  }
7201  if (v[current_idx] <= 0x8f) // fixmap
7202  {
7203  basic_json result = value_t::object;
7204  const size_t len = v[current_idx] & 0x0f;
7205  for (size_t i = 0; i < len; ++i)
7206  {
7207  std::string key = from_msgpack_internal(v, idx);
7208  result[key] = from_msgpack_internal(v, idx);
7209  }
7210  return result;
7211  }
7212  else if (v[current_idx] <= 0x9f) // fixarray
7213  {
7214  basic_json result = value_t::array;
7215  const size_t len = v[current_idx] & 0x0f;
7216  for (size_t i = 0; i < len; ++i)
7217  {
7218  result.push_back(from_msgpack_internal(v, idx));
7219  }
7220  return result;
7221  }
7222  else // fixstr
7223  {
7224  const size_t len = v[current_idx] & 0x1f;
7225  const size_t offset = current_idx + 1;
7226  idx += len; // skip content bytes
7227  check_length(v.size(), len, offset);
7228  return std::string(reinterpret_cast<const char*>(v.data()) + offset, len);
7229  }
7230  }
7231  else if (v[current_idx] >= 0xe0) // negative fixint
7232  {
7233  return static_cast<int8_t>(v[current_idx]);
7234  }
7235  else
7236  {
7237  switch (v[current_idx])
7238  {
7239  case 0xc0: // nil
7240  {
7241  return value_t::null;
7242  }
7243 
7244  case 0xc2: // false
7245  {
7246  return false;
7247  }
7248 
7249  case 0xc3: // true
7250  {
7251  return true;
7252  }
7253 
7254  case 0xca: // float 32
7255  {
7256  // copy bytes in reverse order into the double variable
7257  float res;
7258  for (size_t byte = 0; byte < sizeof(float); ++byte)
7259  {
7260  reinterpret_cast<uint8_t*>(&res)[sizeof(float) - byte - 1] = v.at(current_idx + 1 + byte);
7261  }
7262  idx += sizeof(float); // skip content bytes
7263  return res;
7264  }
7265 
7266  case 0xcb: // float 64
7267  {
7268  // copy bytes in reverse order into the double variable
7269  double res;
7270  for (size_t byte = 0; byte < sizeof(double); ++byte)
7271  {
7272  reinterpret_cast<uint8_t*>(&res)[sizeof(double) - byte - 1] = v.at(current_idx + 1 + byte);
7273  }
7274  idx += sizeof(double); // skip content bytes
7275  return res;
7276  }
7277 
7278  case 0xcc: // uint 8
7279  {
7280  idx += 1; // skip content byte
7281  return get_from_vector<uint8_t>(v, current_idx);
7282  }
7283 
7284  case 0xcd: // uint 16
7285  {
7286  idx += 2; // skip 2 content bytes
7287  return get_from_vector<uint16_t>(v, current_idx);
7288  }
7289 
7290  case 0xce: // uint 32
7291  {
7292  idx += 4; // skip 4 content bytes
7293  return get_from_vector<uint32_t>(v, current_idx);
7294  }
7295 
7296  case 0xcf: // uint 64
7297  {
7298  idx += 8; // skip 8 content bytes
7299  return get_from_vector<uint64_t>(v, current_idx);
7300  }
7301 
7302  case 0xd0: // int 8
7303  {
7304  idx += 1; // skip content byte
7305  return get_from_vector<int8_t>(v, current_idx);
7306  }
7307 
7308  case 0xd1: // int 16
7309  {
7310  idx += 2; // skip 2 content bytes
7311  return get_from_vector<int16_t>(v, current_idx);
7312  }
7313 
7314  case 0xd2: // int 32
7315  {
7316  idx += 4; // skip 4 content bytes
7317  return get_from_vector<int32_t>(v, current_idx);
7318  }
7319 
7320  case 0xd3: // int 64
7321  {
7322  idx += 8; // skip 8 content bytes
7323  return get_from_vector<int64_t>(v, current_idx);
7324  }
7325 
7326  case 0xd9: // str 8
7327  {
7328  const auto len = static_cast<size_t>(get_from_vector<uint8_t>(v, current_idx));
7329  const size_t offset = current_idx + 2;
7330  idx += len + 1; // skip size byte + content bytes
7331  check_length(v.size(), len, offset);
7332  return std::string(reinterpret_cast<const char*>(v.data()) + offset, len);
7333  }
7334 
7335  case 0xda: // str 16
7336  {
7337  const auto len = static_cast<size_t>(get_from_vector<uint16_t>(v, current_idx));
7338  const size_t offset = current_idx + 3;
7339  idx += len + 2; // skip 2 size bytes + content bytes
7340  check_length(v.size(), len, offset);
7341  return std::string(reinterpret_cast<const char*>(v.data()) + offset, len);
7342  }
7343 
7344  case 0xdb: // str 32
7345  {
7346  const auto len = static_cast<size_t>(get_from_vector<uint32_t>(v, current_idx));
7347  const size_t offset = current_idx + 5;
7348  idx += len + 4; // skip 4 size bytes + content bytes
7349  check_length(v.size(), len, offset);
7350  return std::string(reinterpret_cast<const char*>(v.data()) + offset, len);
7351  }
7352 
7353  case 0xdc: // array 16
7354  {
7355  basic_json result = value_t::array;
7356  const auto len = static_cast<size_t>(get_from_vector<uint16_t>(v, current_idx));
7357  idx += 2; // skip 2 size bytes
7358  for (size_t i = 0; i < len; ++i)
7359  {
7360  result.push_back(from_msgpack_internal(v, idx));
7361  }
7362  return result;
7363  }
7364 
7365  case 0xdd: // array 32
7366  {
7367  basic_json result = value_t::array;
7368  const auto len = static_cast<size_t>(get_from_vector<uint32_t>(v, current_idx));
7369  idx += 4; // skip 4 size bytes
7370  for (size_t i = 0; i < len; ++i)
7371  {
7372  result.push_back(from_msgpack_internal(v, idx));
7373  }
7374  return result;
7375  }
7376 
7377  case 0xde: // map 16
7378  {
7379  basic_json result = value_t::object;
7380  const auto len = static_cast<size_t>(get_from_vector<uint16_t>(v, current_idx));
7381  idx += 2; // skip 2 size bytes
7382  for (size_t i = 0; i < len; ++i)
7383  {
7384  std::string key = from_msgpack_internal(v, idx);
7385  result[key] = from_msgpack_internal(v, idx);
7386  }
7387  return result;
7388  }
7389 
7390  case 0xdf: // map 32
7391  {
7392  basic_json result = value_t::object;
7393  const auto len = static_cast<size_t>(get_from_vector<uint32_t>(v, current_idx));
7394  idx += 4; // skip 4 size bytes
7395  for (size_t i = 0; i < len; ++i)
7396  {
7397  std::string key = from_msgpack_internal(v, idx);
7398  result[key] = from_msgpack_internal(v, idx);
7399  }
7400  return result;
7401  }
7402 
7403  default:
7404  {
7405  JSON_THROW(std::invalid_argument("error parsing a msgpack @ " + std::to_string(current_idx) + ": " + std::to_string(static_cast<int>(v[current_idx]))));
7406  }
7407  }
7408  }
7409  }
7410 
7425  static basic_json from_cbor_internal(const std::vector<uint8_t>& v, size_t& idx)
7426  {
7427  // store and increment index
7428  const size_t current_idx = idx++;
7429 
7430  switch (v.at(current_idx))
7431  {
7432  // Integer 0x00..0x17 (0..23)
7433  case 0x00:
7434  case 0x01:
7435  case 0x02:
7436  case 0x03:
7437  case 0x04:
7438  case 0x05:
7439  case 0x06:
7440  case 0x07:
7441  case 0x08:
7442  case 0x09:
7443  case 0x0a:
7444  case 0x0b:
7445  case 0x0c:
7446  case 0x0d:
7447  case 0x0e:
7448  case 0x0f:
7449  case 0x10:
7450  case 0x11:
7451  case 0x12:
7452  case 0x13:
7453  case 0x14:
7454  case 0x15:
7455  case 0x16:
7456  case 0x17:
7457  {
7458  return v[current_idx];
7459  }
7460 
7461  case 0x18: // Unsigned integer (one-byte uint8_t follows)
7462  {
7463  idx += 1; // skip content byte
7464  return get_from_vector<uint8_t>(v, current_idx);
7465  }
7466 
7467  case 0x19: // Unsigned integer (two-byte uint16_t follows)
7468  {
7469  idx += 2; // skip 2 content bytes
7470  return get_from_vector<uint16_t>(v, current_idx);
7471  }
7472 
7473  case 0x1a: // Unsigned integer (four-byte uint32_t follows)
7474  {
7475  idx += 4; // skip 4 content bytes
7476  return get_from_vector<uint32_t>(v, current_idx);
7477  }
7478 
7479  case 0x1b: // Unsigned integer (eight-byte uint64_t follows)
7480  {
7481  idx += 8; // skip 8 content bytes
7482  return get_from_vector<uint64_t>(v, current_idx);
7483  }
7484 
7485  // Negative integer -1-0x00..-1-0x17 (-1..-24)
7486  case 0x20:
7487  case 0x21:
7488  case 0x22:
7489  case 0x23:
7490  case 0x24:
7491  case 0x25:
7492  case 0x26:
7493  case 0x27:
7494  case 0x28:
7495  case 0x29:
7496  case 0x2a:
7497  case 0x2b:
7498  case 0x2c:
7499  case 0x2d:
7500  case 0x2e:
7501  case 0x2f:
7502  case 0x30:
7503  case 0x31:
7504  case 0x32:
7505  case 0x33:
7506  case 0x34:
7507  case 0x35:
7508  case 0x36:
7509  case 0x37:
7510  {
7511  return static_cast<int8_t>(0x20 - 1 - v[current_idx]);
7512  }
7513 
7514  case 0x38: // Negative integer (one-byte uint8_t follows)
7515  {
7516  idx += 1; // skip content byte
7517  // must be uint8_t !
7518  return static_cast<number_integer_t>(-1) - get_from_vector<uint8_t>(v, current_idx);
7519  }
7520 
7521  case 0x39: // Negative integer -1-n (two-byte uint16_t follows)
7522  {
7523  idx += 2; // skip 2 content bytes
7524  return static_cast<number_integer_t>(-1) - get_from_vector<uint16_t>(v, current_idx);
7525  }
7526 
7527  case 0x3a: // Negative integer -1-n (four-byte uint32_t follows)
7528  {
7529  idx += 4; // skip 4 content bytes
7530  return static_cast<number_integer_t>(-1) - get_from_vector<uint32_t>(v, current_idx);
7531  }
7532 
7533  case 0x3b: // Negative integer -1-n (eight-byte uint64_t follows)
7534  {
7535  idx += 8; // skip 8 content bytes
7536  return static_cast<number_integer_t>(-1) - static_cast<number_integer_t>(get_from_vector<uint64_t>(v, current_idx));
7537  }
7538 
7539  // UTF-8 string (0x00..0x17 bytes follow)
7540  case 0x60:
7541  case 0x61:
7542  case 0x62:
7543  case 0x63:
7544  case 0x64:
7545  case 0x65:
7546  case 0x66:
7547  case 0x67:
7548  case 0x68:
7549  case 0x69:
7550  case 0x6a:
7551  case 0x6b:
7552  case 0x6c:
7553  case 0x6d:
7554  case 0x6e:
7555  case 0x6f:
7556  case 0x70:
7557  case 0x71:
7558  case 0x72:
7559  case 0x73:
7560  case 0x74:
7561  case 0x75:
7562  case 0x76:
7563  case 0x77:
7564  {
7565  const auto len = static_cast<size_t>(v[current_idx] - 0x60);
7566  const size_t offset = current_idx + 1;
7567  idx += len; // skip content bytes
7568  check_length(v.size(), len, offset);
7569  return std::string(reinterpret_cast<const char*>(v.data()) + offset, len);
7570  }
7571 
7572  case 0x78: // UTF-8 string (one-byte uint8_t for n follows)
7573  {
7574  const auto len = static_cast<size_t>(get_from_vector<uint8_t>(v, current_idx));
7575  const size_t offset = current_idx + 2;
7576  idx += len + 1; // skip size byte + content bytes
7577  check_length(v.size(), len, offset);
7578  return std::string(reinterpret_cast<const char*>(v.data()) + offset, len);
7579  }
7580 
7581  case 0x79: // UTF-8 string (two-byte uint16_t for n follow)
7582  {
7583  const auto len = static_cast<size_t>(get_from_vector<uint16_t>(v, current_idx));
7584  const size_t offset = current_idx + 3;
7585  idx += len + 2; // skip 2 size bytes + content bytes
7586  check_length(v.size(), len, offset);
7587  return std::string(reinterpret_cast<const char*>(v.data()) + offset, len);
7588  }
7589 
7590  case 0x7a: // UTF-8 string (four-byte uint32_t for n follow)
7591  {
7592  const auto len = static_cast<size_t>(get_from_vector<uint32_t>(v, current_idx));
7593  const size_t offset = current_idx + 5;
7594  idx += len + 4; // skip 4 size bytes + content bytes
7595  check_length(v.size(), len, offset);
7596  return std::string(reinterpret_cast<const char*>(v.data()) + offset, len);
7597  }
7598 
7599  case 0x7b: // UTF-8 string (eight-byte uint64_t for n follow)
7600  {
7601  const auto len = static_cast<size_t>(get_from_vector<uint64_t>(v, current_idx));
7602  const size_t offset = current_idx + 9;
7603  idx += len + 8; // skip 8 size bytes + content bytes
7604  check_length(v.size(), len, offset);
7605  return std::string(reinterpret_cast<const char*>(v.data()) + offset, len);
7606  }
7607 
7608  case 0x7f: // UTF-8 string (indefinite length)
7609  {
7610  std::string result;
7611  while (v.at(idx) != 0xff)
7612  {
7613  string_t s = from_cbor_internal(v, idx);
7614  result += s;
7615  }
7616  // skip break byte (0xFF)
7617  idx += 1;
7618  return result;
7619  }
7620 
7621  // array (0x00..0x17 data items follow)
7622  case 0x80:
7623  case 0x81:
7624  case 0x82:
7625  case 0x83:
7626  case 0x84:
7627  case 0x85:
7628  case 0x86:
7629  case 0x87:
7630  case 0x88:
7631  case 0x89:
7632  case 0x8a:
7633  case 0x8b:
7634  case 0x8c:
7635  case 0x8d:
7636  case 0x8e:
7637  case 0x8f:
7638  case 0x90:
7639  case 0x91:
7640  case 0x92:
7641  case 0x93:
7642  case 0x94:
7643  case 0x95:
7644  case 0x96:
7645  case 0x97:
7646  {
7647  basic_json result = value_t::array;
7648  const auto len = static_cast<size_t>(v[current_idx] - 0x80);
7649  for (size_t i = 0; i < len; ++i)
7650  {
7651  result.push_back(from_cbor_internal(v, idx));
7652  }
7653  return result;
7654  }
7655 
7656  case 0x98: // array (one-byte uint8_t for n follows)
7657  {
7658  basic_json result = value_t::array;
7659  const auto len = static_cast<size_t>(get_from_vector<uint8_t>(v, current_idx));
7660  idx += 1; // skip 1 size byte
7661  for (size_t i = 0; i < len; ++i)
7662  {
7663  result.push_back(from_cbor_internal(v, idx));
7664  }
7665  return result;
7666  }
7667 
7668  case 0x99: // array (two-byte uint16_t for n follow)
7669  {
7670  basic_json result = value_t::array;
7671  const auto len = static_cast<size_t>(get_from_vector<uint16_t>(v, current_idx));
7672  idx += 2; // skip 4 size bytes
7673  for (size_t i = 0; i < len; ++i)
7674  {
7675  result.push_back(from_cbor_internal(v, idx));
7676  }
7677  return result;
7678  }
7679 
7680  case 0x9a: // array (four-byte uint32_t for n follow)
7681  {
7682  basic_json result = value_t::array;
7683  const auto len = static_cast<size_t>(get_from_vector<uint32_t>(v, current_idx));
7684  idx += 4; // skip 4 size bytes
7685  for (size_t i = 0; i < len; ++i)
7686  {
7687  result.push_back(from_cbor_internal(v, idx));
7688  }
7689  return result;
7690  }
7691 
7692  case 0x9b: // array (eight-byte uint64_t for n follow)
7693  {
7694  basic_json result = value_t::array;
7695  const auto len = static_cast<size_t>(get_from_vector<uint64_t>(v, current_idx));
7696  idx += 8; // skip 8 size bytes
7697  for (size_t i = 0; i < len; ++i)
7698  {
7699  result.push_back(from_cbor_internal(v, idx));
7700  }
7701  return result;
7702  }
7703 
7704  case 0x9f: // array (indefinite length)
7705  {
7706  basic_json result = value_t::array;
7707  while (v.at(idx) != 0xff)
7708  {
7709  result.push_back(from_cbor_internal(v, idx));
7710  }
7711  // skip break byte (0xFF)
7712  idx += 1;
7713  return result;
7714  }
7715 
7716  // map (0x00..0x17 pairs of data items follow)
7717  case 0xa0:
7718  case 0xa1:
7719  case 0xa2:
7720  case 0xa3:
7721  case 0xa4:
7722  case 0xa5:
7723  case 0xa6:
7724  case 0xa7:
7725  case 0xa8:
7726  case 0xa9:
7727  case 0xaa:
7728  case 0xab:
7729  case 0xac:
7730  case 0xad:
7731  case 0xae:
7732  case 0xaf:
7733  case 0xb0:
7734  case 0xb1:
7735  case 0xb2:
7736  case 0xb3:
7737  case 0xb4:
7738  case 0xb5:
7739  case 0xb6:
7740  case 0xb7:
7741  {
7742  basic_json result = value_t::object;
7743  const auto len = static_cast<size_t>(v[current_idx] - 0xa0);
7744  for (size_t i = 0; i < len; ++i)
7745  {
7746  std::string key = from_cbor_internal(v, idx);
7747  result[key] = from_cbor_internal(v, idx);
7748  }
7749  return result;
7750  }
7751 
7752  case 0xb8: // map (one-byte uint8_t for n follows)
7753  {
7754  basic_json result = value_t::object;
7755  const auto len = static_cast<size_t>(get_from_vector<uint8_t>(v, current_idx));
7756  idx += 1; // skip 1 size byte
7757  for (size_t i = 0; i < len; ++i)
7758  {
7759  std::string key = from_cbor_internal(v, idx);
7760  result[key] = from_cbor_internal(v, idx);
7761  }
7762  return result;
7763  }
7764 
7765  case 0xb9: // map (two-byte uint16_t for n follow)
7766  {
7767  basic_json result = value_t::object;
7768  const auto len = static_cast<size_t>(get_from_vector<uint16_t>(v, current_idx));
7769  idx += 2; // skip 2 size bytes
7770  for (size_t i = 0; i < len; ++i)
7771  {
7772  std::string key = from_cbor_internal(v, idx);
7773  result[key] = from_cbor_internal(v, idx);
7774  }
7775  return result;
7776  }
7777 
7778  case 0xba: // map (four-byte uint32_t for n follow)
7779  {
7780  basic_json result = value_t::object;
7781  const auto len = static_cast<size_t>(get_from_vector<uint32_t>(v, current_idx));
7782  idx += 4; // skip 4 size bytes
7783  for (size_t i = 0; i < len; ++i)
7784  {
7785  std::string key = from_cbor_internal(v, idx);
7786  result[key] = from_cbor_internal(v, idx);
7787  }
7788  return result;
7789  }
7790 
7791  case 0xbb: // map (eight-byte uint64_t for n follow)
7792  {
7793  basic_json result = value_t::object;
7794  const auto len = static_cast<size_t>(get_from_vector<uint64_t>(v, current_idx));
7795  idx += 8; // skip 8 size bytes
7796  for (size_t i = 0; i < len; ++i)
7797  {
7798  std::string key = from_cbor_internal(v, idx);
7799  result[key] = from_cbor_internal(v, idx);
7800  }
7801  return result;
7802  }
7803 
7804  case 0xbf: // map (indefinite length)
7805  {
7806  basic_json result = value_t::object;
7807  while (v.at(idx) != 0xff)
7808  {
7809  std::string key = from_cbor_internal(v, idx);
7810  result[key] = from_cbor_internal(v, idx);
7811  }
7812  // skip break byte (0xFF)
7813  idx += 1;
7814  return result;
7815  }
7816 
7817  case 0xf4: // false
7818  {
7819  return false;
7820  }
7821 
7822  case 0xf5: // true
7823  {
7824  return true;
7825  }
7826 
7827  case 0xf6: // null
7828  {
7829  return value_t::null;
7830  }
7831 
7832  case 0xf9: // Half-Precision Float (two-byte IEEE 754)
7833  {
7834  idx += 2; // skip two content bytes
7835 
7836  // code from RFC 7049, Appendix D, Figure 3:
7837  // As half-precision floating-point numbers were only added to
7838  // IEEE 754 in 2008, today's programming platforms often still
7839  // only have limited support for them. It is very easy to
7840  // include at least decoding support for them even without such
7841  // support. An example of a small decoder for half-precision
7842  // floating-point numbers in the C language is shown in Fig. 3.
7843  const int half = (v.at(current_idx + 1) << 8) + v.at(current_idx + 2);
7844  const int exp = (half >> 10) & 0x1f;
7845  const int mant = half & 0x3ff;
7846  double val;
7847  if (exp == 0)
7848  {
7849  val = std::ldexp(mant, -24);
7850  }
7851  else if (exp != 31)
7852  {
7853  val = std::ldexp(mant + 1024, exp - 25);
7854  }
7855  else
7856  {
7857  val = mant == 0
7858  ? std::numeric_limits<double>::infinity()
7859  : std::numeric_limits<double>::quiet_NaN();
7860  }
7861  return (half & 0x8000) != 0 ? -val : val;
7862  }
7863 
7864  case 0xfa: // Single-Precision Float (four-byte IEEE 754)
7865  {
7866  // copy bytes in reverse order into the float variable
7867  float res;
7868  for (size_t byte = 0; byte < sizeof(float); ++byte)
7869  {
7870  reinterpret_cast<uint8_t*>(&res)[sizeof(float) - byte - 1] = v.at(current_idx + 1 + byte);
7871  }
7872  idx += sizeof(float); // skip content bytes
7873  return res;
7874  }
7875 
7876  case 0xfb: // Double-Precision Float (eight-byte IEEE 754)
7877  {
7878  // copy bytes in reverse order into the double variable
7879  double res;
7880  for (size_t byte = 0; byte < sizeof(double); ++byte)
7881  {
7882  reinterpret_cast<uint8_t*>(&res)[sizeof(double) - byte - 1] = v.at(current_idx + 1 + byte);
7883  }
7884  idx += sizeof(double); // skip content bytes
7885  return res;
7886  }
7887 
7888  default: // anything else (0xFF is handled inside the other types)
7889  {
7890  JSON_THROW(std::invalid_argument("error parsing a CBOR @ " + std::to_string(current_idx) + ": " + std::to_string(static_cast<int>(v[current_idx]))));
7891  }
7892  }
7893  }
7894 
7895  public:
7918  static std::vector<uint8_t> to_msgpack(const basic_json& j)
7919  {
7920  std::vector<uint8_t> result;
7921  to_msgpack_internal(j, result);
7922  return result;
7923  }
7924 
7951  static basic_json from_msgpack(const std::vector<uint8_t>& v,
7952  const size_t start_index = 0)
7953  {
7954  size_t i = start_index;
7955  return from_msgpack_internal(v, i);
7956  }
7957 
7981  static std::vector<uint8_t> to_cbor(const basic_json& j)
7982  {
7983  std::vector<uint8_t> result;
7984  to_cbor_internal(j, result);
7985  return result;
7986  }
7987 
8014  static basic_json from_cbor(const std::vector<uint8_t>& v,
8015  const size_t start_index = 0)
8016  {
8017  size_t i = start_index;
8018  return from_cbor_internal(v, i);
8019  }
8020 
8022 
8024  // convenience functions //
8026 
8043  {
8044  {
8045  switch (m_type)
8046  {
8047  case value_t::null:
8048  return "null";
8049  case value_t::object:
8050  return "object";
8051  case value_t::array:
8052  return "array";
8053  case value_t::string:
8054  return "string";
8055  case value_t::boolean:
8056  return "boolean";
8057  case value_t::discarded:
8058  return "discarded";
8059  default:
8060  return "number";
8061  }
8062  }
8063  }
8064 
8065  private:
8074  static std::size_t extra_space(const string_t& s) noexcept
8075  {
8076  return std::accumulate(s.begin(), s.end(), size_t{},
8077  [](size_t res, typename string_t::value_type c)
8078  {
8079  switch (c)
8080  {
8081  case '"':
8082  case '\\':
8083  case '\b':
8084  case '\f':
8085  case '\n':
8086  case '\r':
8087  case '\t':
8088  {
8089  // from c (1 byte) to \x (2 bytes)
8090  return res + 1;
8091  }
8092 
8093  default:
8094  {
8095  if (c >= 0x00 and c <= 0x1f)
8096  {
8097  // from c (1 byte) to \uxxxx (6 bytes)
8098  return res + 5;
8099  }
8100 
8101  return res;
8102  }
8103  }
8104  });
8105  }
8106 
8120  static string_t escape_string(const string_t& s)
8121  {
8122  const auto space = extra_space(s);
8123  if (space == 0)
8124  {
8125  return s;
8126  }
8127 
8128  // create a result string of necessary size
8129  string_t result(s.size() + space, '\\');
8130  std::size_t pos = 0;
8131 
8132  for (const auto& c : s)
8133  {
8134  switch (c)
8135  {
8136  // quotation mark (0x22)
8137  case '"':
8138  {
8139  result[pos + 1] = '"';
8140  pos += 2;
8141  break;
8142  }
8143 
8144  // reverse solidus (0x5c)
8145  case '\\':
8146  {
8147  // nothing to change
8148  pos += 2;
8149  break;
8150  }
8151 
8152  // backspace (0x08)
8153  case '\b':
8154  {
8155  result[pos + 1] = 'b';
8156  pos += 2;
8157  break;
8158  }
8159 
8160  // formfeed (0x0c)
8161  case '\f':
8162  {
8163  result[pos + 1] = 'f';
8164  pos += 2;
8165  break;
8166  }
8167 
8168  // newline (0x0a)
8169  case '\n':
8170  {
8171  result[pos + 1] = 'n';
8172  pos += 2;
8173  break;
8174  }
8175 
8176  // carriage return (0x0d)
8177  case '\r':
8178  {
8179  result[pos + 1] = 'r';
8180  pos += 2;
8181  break;
8182  }
8183 
8184  // horizontal tab (0x09)
8185  case '\t':
8186  {
8187  result[pos + 1] = 't';
8188  pos += 2;
8189  break;
8190  }
8191 
8192  default:
8193  {
8194  if (c >= 0x00 and c <= 0x1f)
8195  {
8196  // convert a number 0..15 to its hex representation
8197  // (0..f)
8198  static const char hexify[16] =
8199  {
8200  '0', '1', '2', '3', '4', '5', '6', '7',
8201  '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'
8202  };
8203 
8204  // print character c as \uxxxx
8205  for (const char m :
8206  { 'u', '0', '0', hexify[c >> 4], hexify[c & 0x0f]
8207  })
8208  {
8209  result[++pos] = m;
8210  }
8211 
8212  ++pos;
8213  }
8214  else
8215  {
8216  // all other characters are added as-is
8217  result[pos++] = c;
8218  }
8219  break;
8220  }
8221  }
8222  }
8223 
8224  return result;
8225  }
8226 
8227 
8231  struct numtostr
8232  {
8233  public:
8234  template<typename NumberType>
8235  numtostr(NumberType value)
8236  {
8237  x_write(value, std::is_integral<NumberType>());
8238  }
8239 
8240  const char* c_str() const
8241  {
8242  return m_buf.data();
8243  }
8244 
8245  private:
8247  std::array < char, 64 > m_buf{{}};
8248 
8249  template<typename NumberType>
8250  void x_write(NumberType x, /*is_integral=*/std::true_type)
8251  {
8252  // special case for "0"
8253  if (x == 0)
8254  {
8255  m_buf[0] = '0';
8256  return;
8257  }
8258 
8259  const bool is_negative = x < 0;
8260  size_t i = 0;
8261 
8262  // spare 1 byte for '\0'
8263  while (x != 0 and i < m_buf.size() - 1)
8264  {
8265  const auto digit = std::labs(static_cast<long>(x % 10));
8266  m_buf[i++] = static_cast<char>('0' + digit);
8267  x /= 10;
8268  }
8269 
8270  // make sure the number has been processed completely
8271  assert(x == 0);
8272 
8273  if (is_negative)
8274  {
8275  // make sure there is capacity for the '-'
8276  assert(i < m_buf.size() - 2);
8277  m_buf[i++] = '-';
8278  }
8279 
8280  std::reverse(m_buf.begin(), m_buf.begin() + i);
8281  }
8282 
8283  template<typename NumberType>
8284  void x_write(NumberType x, /*is_integral=*/std::false_type)
8285  {
8286  // special case for 0.0 and -0.0
8287  if (x == 0)
8288  {
8289  size_t i = 0;
8290  if (std::signbit(x))
8291  {
8292  m_buf[i++] = '-';
8293  }
8294  m_buf[i++] = '0';
8295  m_buf[i++] = '.';
8296  m_buf[i] = '0';
8297  return;
8298  }
8299 
8300  // get number of digits for a text -> float -> text round-trip
8301  static constexpr auto d = std::numeric_limits<NumberType>::digits10;
8302 
8303  // the actual conversion
8304  const auto written_bytes = snprintf(m_buf.data(), m_buf.size(), "%.*g", d, (double)x);
8305 
8306  // negative value indicates an error
8307  assert(written_bytes > 0);
8308  // check if buffer was large enough
8309  assert(static_cast<size_t>(written_bytes) < m_buf.size());
8310 
8311  // read information from locale
8312  const auto loc = localeconv();
8313  assert(loc != nullptr);
8314  const char thousands_sep = !loc->thousands_sep ? '\0'
8315  : loc->thousands_sep[0];
8316 
8317  const char decimal_point = !loc->decimal_point ? '\0'
8318  : loc->decimal_point[0];
8319 
8320  // erase thousands separator
8321  if (thousands_sep != '\0')
8322  {
8323  const auto end = std::remove(m_buf.begin(), m_buf.begin() + written_bytes, thousands_sep);
8324  std::fill(end, m_buf.end(), '\0');
8325  }
8326 
8327  // convert decimal point to '.'
8328  if (decimal_point != '\0' and decimal_point != '.')
8329  {
8330  for (auto& c : m_buf)
8331  {
8332  if (c == decimal_point)
8333  {
8334  c = '.';
8335  break;
8336  }
8337  }
8338  }
8339 
8340  // determine if need to append ".0"
8341  size_t i = 0;
8342  bool value_is_int_like = true;
8343  for (i = 0; i < m_buf.size(); ++i)
8344  {
8345  // break when end of number is reached
8346  if (m_buf[i] == '\0')
8347  {
8348  break;
8349  }
8350 
8351  // check if we find non-int character
8352  value_is_int_like = value_is_int_like and m_buf[i] != '.' and
8353  m_buf[i] != 'e' and m_buf[i] != 'E';
8354  }
8355 
8356  if (value_is_int_like)
8357  {
8358  // there must be 2 bytes left for ".0"
8359  assert((i + 2) < m_buf.size());
8360  // we write to the end of the number
8361  assert(m_buf[i] == '\0');
8362  assert(m_buf[i - 1] != '\0');
8363 
8364  // add ".0"
8365  m_buf[i] = '.';
8366  m_buf[i + 1] = '0';
8367 
8368  // the resulting string is properly terminated
8369  assert(m_buf[i + 2] == '\0');
8370  }
8371  }
8372  };
8373 
8374 
8392  void dump(std::ostream& o,
8393  const bool pretty_print,
8394  const unsigned int indent_step,
8395  const unsigned int current_indent = 0) const
8396  {
8397  // variable to hold indentation for recursive calls
8398  unsigned int new_indent = current_indent;
8399 
8400  switch (m_type)
8401  {
8402  case value_t::object:
8403  {
8404  if (m_value.object->empty())
8405  {
8406  o << "{}";
8407  return;
8408  }
8409 
8410  o << "{";
8411 
8412  // increase indentation
8413  if (pretty_print)
8414  {
8415  new_indent += indent_step;
8416  o << "\n";
8417  }
8418 
8419  for (auto i = m_value.object->cbegin(); i != m_value.object->cend(); ++i)
8420  {
8421  if (i != m_value.object->cbegin())
8422  {
8423  o << (pretty_print ? ",\n" : ",");
8424  }
8425  o << string_t(new_indent, ' ') << "\""
8426  << escape_string(i->first) << "\":"
8427  << (pretty_print ? " " : "");
8428  i->second.dump(o, pretty_print, indent_step, new_indent);
8429  }
8430 
8431  // decrease indentation
8432  if (pretty_print)
8433  {
8434  new_indent -= indent_step;
8435  o << "\n";
8436  }
8437 
8438  o << string_t(new_indent, ' ') + "}";
8439  return;
8440  }
8441 
8442  case value_t::array:
8443  {
8444  if (m_value.array->empty())
8445  {
8446  o << "[]";
8447  return;
8448  }
8449 
8450  o << "[";
8451 
8452  // increase indentation
8453  if (pretty_print)
8454  {
8455  new_indent += indent_step;
8456  o << "\n";
8457  }
8458 
8459  for (auto i = m_value.array->cbegin(); i != m_value.array->cend(); ++i)
8460  {
8461  if (i != m_value.array->cbegin())
8462  {
8463  o << (pretty_print ? ",\n" : ",");
8464  }
8465  o << string_t(new_indent, ' ');
8466  i->dump(o, pretty_print, indent_step, new_indent);
8467  }
8468 
8469  // decrease indentation
8470  if (pretty_print)
8471  {
8472  new_indent -= indent_step;
8473  o << "\n";
8474  }
8475 
8476  o << string_t(new_indent, ' ') << "]";
8477  return;
8478  }
8479 
8480  case value_t::string:
8481  {
8482  o << string_t("\"") << escape_string(*m_value.string) << "\"";
8483  return;
8484  }
8485 
8486  case value_t::boolean:
8487  {
8488  o << (m_value.boolean ? "true" : "false");
8489  return;
8490  }
8491 
8493  {
8494  o << numtostr(m_value.number_integer).c_str();
8495  return;
8496  }
8497 
8499  {
8500  o << numtostr(m_value.number_unsigned).c_str();
8501  return;
8502  }
8503 
8504  case value_t::number_float:
8505  {
8506  o << numtostr(m_value.number_float).c_str();
8507  return;
8508  }
8509 
8510  case value_t::discarded:
8511  {
8512  o << "<discarded>";
8513  return;
8514  }
8515 
8516  case value_t::null:
8517  {
8518  o << "null";
8519  return;
8520  }
8521  }
8522  }
8523 
8524  private:
8526  // member variables //
8528 
8530  value_t m_type = value_t::null;
8531 
8533  json_value m_value = {};
8534 
8535 
8536  private:
8538  // iterators //
8540 
8550  class primitive_iterator_t
8551  {
8552  public:
8553 
8554  difference_type get_value() const noexcept
8555  {
8556  return m_it;
8557  }
8559  void set_begin() noexcept
8560  {
8561  m_it = begin_value;
8562  }
8563 
8565  void set_end() noexcept
8566  {
8567  m_it = end_value;
8568  }
8569 
8571  constexpr bool is_begin() const noexcept
8572  {
8573  return (m_it == begin_value);
8574  }
8575 
8577  constexpr bool is_end() const noexcept
8578  {
8579  return (m_it == end_value);
8580  }
8581 
8582  friend constexpr bool operator==(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept
8583  {
8584  return lhs.m_it == rhs.m_it;
8585  }
8586 
8587  friend constexpr bool operator!=(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept
8588  {
8589  return !(lhs == rhs);
8590  }
8591 
8592  friend constexpr bool operator<(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept
8593  {
8594  return lhs.m_it < rhs.m_it;
8595  }
8596 
8597  friend constexpr bool operator<=(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept
8598  {
8599  return lhs.m_it <= rhs.m_it;
8600  }
8601 
8602  friend constexpr bool operator>(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept
8603  {
8604  return lhs.m_it > rhs.m_it;
8605  }
8606 
8607  friend constexpr bool operator>=(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept
8608  {
8609  return lhs.m_it >= rhs.m_it;
8610  }
8611 
8612  primitive_iterator_t operator+(difference_type i)
8613  {
8614  auto result = *this;
8615  result += i;
8616  return result;
8617  }
8618 
8619  friend constexpr difference_type operator-(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept
8620  {
8621  return lhs.m_it - rhs.m_it;
8622  }
8623 
8624  friend std::ostream& operator<<(std::ostream& os, primitive_iterator_t it)
8625  {
8626  return os << it.m_it;
8627  }
8628 
8629  primitive_iterator_t& operator++()
8630  {
8631  ++m_it;
8632  return *this;
8633  }
8634 
8635  primitive_iterator_t operator++(int)
8636  {
8637  auto result = *this;
8638  m_it++;
8639  return result;
8640  }
8641 
8642  primitive_iterator_t& operator--()
8643  {
8644  --m_it;
8645  return *this;
8646  }
8647 
8648  primitive_iterator_t operator--(int)
8649  {
8650  auto result = *this;
8651  m_it--;
8652  return result;
8653  }
8654 
8655  primitive_iterator_t& operator+=(difference_type n)
8656  {
8657  m_it += n;
8658  return *this;
8659  }
8660 
8661  primitive_iterator_t& operator-=(difference_type n)
8662  {
8663  m_it -= n;
8664  return *this;
8665  }
8666 
8667  private:
8668  static constexpr difference_type begin_value = 0;
8669  static constexpr difference_type end_value = begin_value + 1;
8670 
8672  difference_type m_it = std::numeric_limits<std::ptrdiff_t>::denorm_min();
8673  };
8674 
8682  struct internal_iterator
8683  {
8685  typename object_t::iterator object_iterator;
8687  typename array_t::iterator array_iterator;
8689  primitive_iterator_t primitive_iterator;
8690 
8692  internal_iterator() noexcept
8693  : object_iterator(), array_iterator(), primitive_iterator()
8694  {}
8695  };
8696 
8698  template<typename IteratorType>
8699  class iteration_proxy
8700  {
8701  private:
8703  class iteration_proxy_internal
8704  {
8705  private:
8707  IteratorType anchor;
8709  size_t array_index = 0;
8710 
8711  public:
8712  explicit iteration_proxy_internal(IteratorType it) noexcept
8713  : anchor(it)
8714  {}
8715 
8717  iteration_proxy_internal& operator*()
8718  {
8719  return *this;
8720  }
8721 
8723  iteration_proxy_internal& operator++()
8724  {
8725  ++anchor;
8726  ++array_index;
8727 
8728  return *this;
8729  }
8730 
8732  bool operator!= (const iteration_proxy_internal& o) const
8733  {
8734  return anchor != o.anchor;
8735  }
8736 
8738  typename basic_json::string_t key() const
8739  {
8740  assert(anchor.m_object != nullptr);
8741 
8742  switch (anchor.m_object->type())
8743  {
8744  // use integer array index as key
8745  case value_t::array:
8746  {
8747  return std::to_string(array_index);
8748  }
8749 
8750  // use key from the object
8751  case value_t::object:
8752  {
8753  return anchor.key();
8754  }
8755 
8756  // use an empty key for all primitive types
8757  default:
8758  {
8759  return "";
8760  }
8761  }
8762  }
8763 
8765  typename IteratorType::reference value() const
8766  {
8767  return anchor.value();
8768  }
8769  };
8770 
8772  typename IteratorType::reference container;
8773 
8774  public:
8776  explicit iteration_proxy(typename IteratorType::reference cont)
8777  : container(cont)
8778  {}
8779 
8781  iteration_proxy_internal begin() noexcept
8782  {
8783  return iteration_proxy_internal(container.begin());
8784  }
8785 
8787  iteration_proxy_internal end() noexcept
8788  {
8789  return iteration_proxy_internal(container.end());
8790  }
8791  };
8792 
8793  public:
8813  template<typename U>
8814  class iter_impl : public std::iterator<std::random_access_iterator_tag, U>
8815  {
8817  friend class basic_json;
8818 
8819  // make sure U is basic_json or const basic_json
8820  static_assert(std::is_same<U, basic_json>::value
8821  or std::is_same<U, const basic_json>::value,
8822  "iter_impl only accepts (const) basic_json");
8823 
8824  public:
8830  using pointer = typename std::conditional<std::is_const<U>::value,
8831  typename basic_json::const_pointer,
8832  typename basic_json::pointer>::type;
8834  using reference = typename std::conditional<std::is_const<U>::value,
8835  typename basic_json::const_reference,
8836  typename basic_json::reference>::type;
8838  using iterator_category = std::bidirectional_iterator_tag;
8839 
8841  iter_impl() = default;
8842 
8849  explicit iter_impl(pointer object) noexcept
8850  : m_object(object)
8851  {
8852  assert(m_object != nullptr);
8853 
8854  switch (m_object->m_type)
8855  {
8857  {
8858  m_it.object_iterator = typename object_t::iterator();
8859  break;
8860  }
8861 
8863  {
8864  m_it.array_iterator = typename array_t::iterator();
8865  break;
8866  }
8867 
8868  default:
8869  {
8870  m_it.primitive_iterator = primitive_iterator_t();
8871  break;
8872  }
8873  }
8874  }
8875 
8876  /*
8877  Use operator `const_iterator` instead of `const_iterator(const iterator&
8878  other) noexcept` to avoid two class definitions for @ref iterator and
8879  @ref const_iterator.
8880 
8881  This function is only called if this class is an @ref iterator. If this
8882  class is a @ref const_iterator this function is not called.
8883  */
8884  operator const_iterator() const
8885  {
8886  const_iterator ret;
8887 
8888  if (m_object)
8889  {
8890  ret.m_object = m_object;
8891  ret.m_it = m_it;
8892  }
8893 
8894  return ret;
8895  }
8896 
8902  iter_impl(const iter_impl& other) noexcept
8903  : m_object(other.m_object), m_it(other.m_it)
8904  {}
8905 
8911  iter_impl& operator=(iter_impl other) noexcept(
8912  std::is_nothrow_move_constructible<pointer>::value and
8913  std::is_nothrow_move_assignable<pointer>::value and
8914  std::is_nothrow_move_constructible<internal_iterator>::value and
8915  std::is_nothrow_move_assignable<internal_iterator>::value
8916  )
8917  {
8918  std::swap(m_object, other.m_object);
8919  std::swap(m_it, other.m_it);
8920  return *this;
8921  }
8922 
8923  private:
8928  void set_begin() noexcept
8929  {
8930  assert(m_object != nullptr);
8931 
8932  switch (m_object->m_type)
8933  {
8935  {
8936  m_it.object_iterator = m_object->m_value.object->begin();
8937  break;
8938  }
8939 
8941  {
8942  m_it.array_iterator = m_object->m_value.array->begin();
8943  break;
8944  }
8945 
8946  case basic_json::value_t::null:
8947  {
8948  // set to end so begin()==end() is true: null is empty
8949  m_it.primitive_iterator.set_end();
8950  break;
8951  }
8952 
8953  default:
8954  {
8955  m_it.primitive_iterator.set_begin();
8956  break;
8957  }
8958  }
8959  }
8960 
8965  void set_end() noexcept
8966  {
8967  assert(m_object != nullptr);
8968 
8969  switch (m_object->m_type)
8970  {
8972  {
8973  m_it.object_iterator = m_object->m_value.object->end();
8974  break;
8975  }
8976 
8978  {
8979  m_it.array_iterator = m_object->m_value.array->end();
8980  break;
8981  }
8982 
8983  default:
8984  {
8985  m_it.primitive_iterator.set_end();
8986  break;
8987  }
8988  }
8989  }
8990 
8991  public:
8997  {
8998  assert(m_object != nullptr);
8999 
9000  switch (m_object->m_type)
9001  {
9003  {
9004  assert(m_it.object_iterator != m_object->m_value.object->end());
9005  return m_it.object_iterator->second;
9006  }
9007 
9009  {
9010  assert(m_it.array_iterator != m_object->m_value.array->end());
9011  return *m_it.array_iterator;
9012  }
9013 
9014  case basic_json::value_t::null:
9015  {
9016  JSON_THROW(std::out_of_range("cannot get value"));
9017  }
9018 
9019  default:
9020  {
9021  if (m_it.primitive_iterator.is_begin())
9022  {
9023  return *m_object;
9024  }
9025 
9026  JSON_THROW(std::out_of_range("cannot get value"));
9027  }
9028  }
9029  }
9030 
9036  {
9037  assert(m_object != nullptr);
9038 
9039  switch (m_object->m_type)
9040  {
9042  {
9043  assert(m_it.object_iterator != m_object->m_value.object->end());
9044  return &(m_it.object_iterator->second);
9045  }
9046 
9048  {
9049  assert(m_it.array_iterator != m_object->m_value.array->end());
9050  return &*m_it.array_iterator;
9051  }
9052 
9053  default:
9054  {
9055  if (m_it.primitive_iterator.is_begin())
9056  {
9057  return m_object;
9058  }
9059 
9060  JSON_THROW(std::out_of_range("cannot get value"));
9061  }
9062  }
9063  }
9064 
9070  {
9071  auto result = *this;
9072  ++(*this);
9073  return result;
9074  }
9075 
9081  {
9082  assert(m_object != nullptr);
9083 
9084  switch (m_object->m_type)
9085  {
9087  {
9088  std::advance(m_it.object_iterator, 1);
9089  break;
9090  }
9091 
9093  {
9094  std::advance(m_it.array_iterator, 1);
9095  break;
9096  }
9097 
9098  default:
9099  {
9100  ++m_it.primitive_iterator;
9101  break;
9102  }
9103  }
9104 
9105  return *this;
9106  }
9107 
9113  {
9114  auto result = *this;
9115  --(*this);
9116  return result;
9117  }
9118 
9124  {
9125  assert(m_object != nullptr);
9126 
9127  switch (m_object->m_type)
9128  {
9130  {
9131  std::advance(m_it.object_iterator, -1);
9132  break;
9133  }
9134 
9136  {
9137  std::advance(m_it.array_iterator, -1);
9138  break;
9139  }
9140 
9141  default:
9142  {
9143  --m_it.primitive_iterator;
9144  break;
9145  }
9146  }
9147 
9148  return *this;
9149  }
9150 
9155  bool operator==(const iter_impl& other) const
9156  {
9157  // if objects are not the same, the comparison is undefined
9158  if (m_object != other.m_object)
9159  {
9160  JSON_THROW(std::domain_error("cannot compare iterators of different containers"));
9161  }
9162 
9163  assert(m_object != nullptr);
9164 
9165  switch (m_object->m_type)
9166  {
9168  {
9169  return (m_it.object_iterator == other.m_it.object_iterator);
9170  }
9171 
9173  {
9174  return (m_it.array_iterator == other.m_it.array_iterator);
9175  }
9176 
9177  default:
9178  {
9179  return (m_it.primitive_iterator == other.m_it.primitive_iterator);
9180  }
9181  }
9182  }
9183 
9188  bool operator!=(const iter_impl& other) const
9189  {
9190  return not operator==(other);
9191  }
9192 
9197  bool operator<(const iter_impl& other) const
9198  {
9199  // if objects are not the same, the comparison is undefined
9200  if (m_object != other.m_object)
9201  {
9202  JSON_THROW(std::domain_error("cannot compare iterators of different containers"));
9203  }
9204 
9205  assert(m_object != nullptr);
9206 
9207  switch (m_object->m_type)
9208  {
9210  {
9211  JSON_THROW(std::domain_error("cannot compare order of object iterators"));
9212  }
9213 
9215  {
9216  return (m_it.array_iterator < other.m_it.array_iterator);
9217  }
9218 
9219  default:
9220  {
9221  return (m_it.primitive_iterator < other.m_it.primitive_iterator);
9222  }
9223  }
9224  }
9225 
9230  bool operator<=(const iter_impl& other) const
9231  {
9232  return not other.operator < (*this);
9233  }
9234 
9239  bool operator>(const iter_impl& other) const
9240  {
9241  return not operator<=(other);
9242  }
9243 
9248  bool operator>=(const iter_impl& other) const
9249  {
9250  return not operator<(other);
9251  }
9252 
9258  {
9259  assert(m_object != nullptr);
9260 
9261  switch (m_object->m_type)
9262  {
9264  {
9265  JSON_THROW(std::domain_error("cannot use offsets with object iterators"));
9266  }
9267 
9269  {
9270  std::advance(m_it.array_iterator, i);
9271  break;
9272  }
9273 
9274  default:
9275  {
9276  m_it.primitive_iterator += i;
9277  break;
9278  }
9279  }
9280 
9281  return *this;
9282  }
9283 
9289  {
9290  return operator+=(-i);
9291  }
9292 
9298  {
9299  auto result = *this;
9300  result += i;
9301  return result;
9302  }
9303 
9309  {
9310  auto result = *this;
9311  result -= i;
9312  return result;
9313  }
9314 
9320  {
9321  assert(m_object != nullptr);
9322 
9323  switch (m_object->m_type)
9324  {
9326  {
9327  JSON_THROW(std::domain_error("cannot use offsets with object iterators"));
9328  }
9329 
9331  {
9332  return m_it.array_iterator - other.m_it.array_iterator;
9333  }
9334 
9335  default:
9336  {
9337  return m_it.primitive_iterator - other.m_it.primitive_iterator;
9338  }
9339  }
9340  }
9341 
9347  {
9348  assert(m_object != nullptr);
9349 
9350  switch (m_object->m_type)
9351  {
9353  {
9354  JSON_THROW(std::domain_error("cannot use operator[] for object iterators"));
9355  }
9356 
9358  {
9359  return *std::next(m_it.array_iterator, n);
9360  }
9361 
9362  case basic_json::value_t::null:
9363  {
9364  JSON_THROW(std::out_of_range("cannot get value"));
9365  }
9366 
9367  default:
9368  {
9369  if (m_it.primitive_iterator.get_value() == -n)
9370  {
9371  return *m_object;
9372  }
9373 
9374  JSON_THROW(std::out_of_range("cannot get value"));
9375  }
9376  }
9377  }
9378 
9383  typename object_t::key_type key() const
9384  {
9385  assert(m_object != nullptr);
9386 
9387  if (m_object->is_object())
9388  {
9389  return m_it.object_iterator->first;
9390  }
9391 
9392  JSON_THROW(std::domain_error("cannot use key() for non-object iterators"));
9393  }
9394 
9400  {
9401  return operator*();
9402  }
9403 
9404  private:
9406  pointer m_object = nullptr;
9408  internal_iterator m_it = internal_iterator();
9409  };
9410 
9428  template<typename Base>
9429  class json_reverse_iterator : public std::reverse_iterator<Base>
9430  {
9431  public:
9433  using base_iterator = std::reverse_iterator<Base>;
9435  using reference = typename Base::reference;
9436 
9438  json_reverse_iterator(const typename base_iterator::iterator_type& it) noexcept
9439  : base_iterator(it)
9440  {}
9441 
9444  : base_iterator(it)
9445  {}
9446 
9449  {
9450  return base_iterator::operator++(1);
9451  }
9452 
9455  {
9456  base_iterator::operator++();
9457  return *this;
9458  }
9459 
9462  {
9463  return base_iterator::operator--(1);
9464  }
9465 
9468  {
9469  base_iterator::operator--();
9470  return *this;
9471  }
9472 
9475  {
9476  base_iterator::operator+=(i);
9477  return *this;
9478  }
9479 
9482  {
9483  auto result = *this;
9484  result += i;
9485  return result;
9486  }
9487 
9490  {
9491  auto result = *this;
9492  result -= i;
9493  return result;
9494  }
9495 
9498  {
9499  return this->base() - other.base();
9500  }
9501 
9504  {
9505  return *(this->operator+(n));
9506  }
9507 
9509  typename object_t::key_type key() const
9510  {
9511  auto it = --this->base();
9512  return it.key();
9513  }
9514 
9517  {
9518  auto it = --this->base();
9519  return it.operator * ();
9520  }
9521  };
9522 
9523 
9524  private:
9526  // lexer and parser //
9528 
9536  class lexer
9537  {
9538  public:
9540  enum class token_type
9541  {
9542  uninitialized,
9543  literal_true,
9544  literal_false,
9545  literal_null,
9546  value_string,
9547  value_unsigned,
9548  value_integer,
9549  value_float,
9550  begin_array,
9551  begin_object,
9552  end_array,
9553  end_object,
9554  name_separator,
9555  value_separator,
9556  parse_error,
9557  end_of_input
9558  };
9559 
9561  using lexer_char_t = unsigned char;
9562 
9564  lexer(const lexer_char_t* buff, const size_t len) noexcept
9565  : m_content(buff)
9566  {
9567  assert(m_content != nullptr);
9568  m_start = m_cursor = m_content;
9569  m_limit = m_content + len;
9570  }
9571 
9573  explicit lexer(std::istream& s)
9574  : m_stream(&s), m_line_buffer()
9575  {
9576  // immediately abort if stream is erroneous
9577  if (s.fail())
9578  {
9579  JSON_THROW(std::invalid_argument("stream error"));
9580  }
9581 
9582  // fill buffer
9583  fill_line_buffer();
9584 
9585  // skip UTF-8 byte-order mark
9586  if (m_line_buffer.size() >= 3 and m_line_buffer.substr(0, 3) == "\xEF\xBB\xBF")
9587  {
9588  m_line_buffer[0] = ' ';
9589  m_line_buffer[1] = ' ';
9590  m_line_buffer[2] = ' ';
9591  }
9592  }
9593 
9594  // switch off unwanted functions (due to pointer members)
9595  lexer() = delete;
9596  lexer(const lexer&) = delete;
9597  lexer operator=(const lexer&) = delete;
9598 
9622  static string_t to_unicode(const std::size_t codepoint1,
9623  const std::size_t codepoint2 = 0)
9624  {
9625  // calculate the code point from the given code points
9626  std::size_t codepoint = codepoint1;
9627 
9628  // check if codepoint1 is a high surrogate
9629  if (codepoint1 >= 0xD800 and codepoint1 <= 0xDBFF)
9630  {
9631  // check if codepoint2 is a low surrogate
9632  if (codepoint2 >= 0xDC00 and codepoint2 <= 0xDFFF)
9633  {
9634  codepoint =
9635  // high surrogate occupies the most significant 22 bits
9636  (codepoint1 << 10)
9637  // low surrogate occupies the least significant 15 bits
9638  + codepoint2
9639  // there is still the 0xD800, 0xDC00 and 0x10000 noise
9640  // in the result so we have to subtract with:
9641  // (0xD800 << 10) + DC00 - 0x10000 = 0x35FDC00
9642  - 0x35FDC00;
9643  }
9644  else
9645  {
9646  JSON_THROW(std::invalid_argument("missing or wrong low surrogate"));
9647  }
9648  }
9649 
9650  string_t result;
9651 
9652  if (codepoint < 0x80)
9653  {
9654  // 1-byte characters: 0xxxxxxx (ASCII)
9655  result.append(1, static_cast<typename string_t::value_type>(codepoint));
9656  }
9657  else if (codepoint <= 0x7ff)
9658  {
9659  // 2-byte characters: 110xxxxx 10xxxxxx
9660  result.append(1, static_cast<typename string_t::value_type>(0xC0 | ((codepoint >> 6) & 0x1F)));
9661  result.append(1, static_cast<typename string_t::value_type>(0x80 | (codepoint & 0x3F)));
9662  }
9663  else if (codepoint <= 0xffff)
9664  {
9665  // 3-byte characters: 1110xxxx 10xxxxxx 10xxxxxx
9666  result.append(1, static_cast<typename string_t::value_type>(0xE0 | ((codepoint >> 12) & 0x0F)));
9667  result.append(1, static_cast<typename string_t::value_type>(0x80 | ((codepoint >> 6) & 0x3F)));
9668  result.append(1, static_cast<typename string_t::value_type>(0x80 | (codepoint & 0x3F)));
9669  }
9670  else if (codepoint <= 0x10ffff)
9671  {
9672  // 4-byte characters: 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
9673  result.append(1, static_cast<typename string_t::value_type>(0xF0 | ((codepoint >> 18) & 0x07)));
9674  result.append(1, static_cast<typename string_t::value_type>(0x80 | ((codepoint >> 12) & 0x3F)));
9675  result.append(1, static_cast<typename string_t::value_type>(0x80 | ((codepoint >> 6) & 0x3F)));
9676  result.append(1, static_cast<typename string_t::value_type>(0x80 | (codepoint & 0x3F)));
9677  }
9678  else
9679  {
9680  JSON_THROW(std::out_of_range("code points above 0x10FFFF are invalid"));
9681  }
9682 
9683  return result;
9684  }
9685 
9687  static std::string token_type_name(const token_type t)
9688  {
9689  switch (t)
9690  {
9691  case token_type::uninitialized:
9692  return "<uninitialized>";
9693  case token_type::literal_true:
9694  return "true literal";
9695  case token_type::literal_false:
9696  return "false literal";
9697  case token_type::literal_null:
9698  return "null literal";
9699  case token_type::value_string:
9700  return "string literal";
9701  case lexer::token_type::value_unsigned:
9702  case lexer::token_type::value_integer:
9703  case lexer::token_type::value_float:
9704  return "number literal";
9705  case token_type::begin_array:
9706  return "'['";
9707  case token_type::begin_object:
9708  return "'{'";
9709  case token_type::end_array:
9710  return "']'";
9711  case token_type::end_object:
9712  return "'}'";
9713  case token_type::name_separator:
9714  return "':'";
9715  case token_type::value_separator:
9716  return "','";
9717  case token_type::parse_error:
9718  return "<parse error>";
9719  case token_type::end_of_input:
9720  return "end of input";
9721  default:
9722  {
9723  // catch non-enum values
9724  return "unknown token"; // LCOV_EXCL_LINE
9725  }
9726  }
9727  }
9728 
9750  token_type scan()
9751  {
9752  while (true)
9753  {
9754  // pointer for backtracking information
9755  m_marker = nullptr;
9756 
9757  // remember the begin of the token
9758  m_start = m_cursor;
9759  assert(m_start != nullptr);
9760 
9761 
9762  {
9763  lexer_char_t yych;
9764  unsigned int yyaccept = 0;
9765  static const unsigned char yybm[] =
9766  {
9767  0, 0, 0, 0, 0, 0, 0, 0,
9768  0, 32, 32, 0, 0, 32, 0, 0,
9769  0, 0, 0, 0, 0, 0, 0, 0,
9770  0, 0, 0, 0, 0, 0, 0, 0,
9771  160, 128, 0, 128, 128, 128, 128, 128,
9772  128, 128, 128, 128, 128, 128, 128, 128,
9773  192, 192, 192, 192, 192, 192, 192, 192,
9774  192, 192, 128, 128, 128, 128, 128, 128,
9775  128, 128, 128, 128, 128, 128, 128, 128,
9776  128, 128, 128, 128, 128, 128, 128, 128,
9777  128, 128, 128, 128, 128, 128, 128, 128,
9778  128, 128, 128, 128, 0, 128, 128, 128,
9779  128, 128, 128, 128, 128, 128, 128, 128,
9780  128, 128, 128, 128, 128, 128, 128, 128,
9781  128, 128, 128, 128, 128, 128, 128, 128,
9782  128, 128, 128, 128, 128, 128, 128, 128,
9783  0, 0, 0, 0, 0, 0, 0, 0,
9784  0, 0, 0, 0, 0, 0, 0, 0,
9785  0, 0, 0, 0, 0, 0, 0, 0,
9786  0, 0, 0, 0, 0, 0, 0, 0,
9787  0, 0, 0, 0, 0, 0, 0, 0,
9788  0, 0, 0, 0, 0, 0, 0, 0,
9789  0, 0, 0, 0, 0, 0, 0, 0,
9790  0, 0, 0, 0, 0, 0, 0, 0,
9791  0, 0, 0, 0, 0, 0, 0, 0,
9792  0, 0, 0, 0, 0, 0, 0, 0,
9793  0, 0, 0, 0, 0, 0, 0, 0,
9794  0, 0, 0, 0, 0, 0, 0, 0,
9795  0, 0, 0, 0, 0, 0, 0, 0,
9796  0, 0, 0, 0, 0, 0, 0, 0,
9797  0, 0, 0, 0, 0, 0, 0, 0,
9798  0, 0, 0, 0, 0, 0, 0, 0,
9799  };
9800  if ((m_limit - m_cursor) < 5)
9801  {
9802  fill_line_buffer(5); // LCOV_EXCL_LINE
9803  }
9804  yych = *m_cursor;
9805  if (yybm[0 + yych] & 32)
9806  {
9807  goto basic_json_parser_6;
9808  }
9809  if (yych <= '[')
9810  {
9811  if (yych <= '-')
9812  {
9813  if (yych <= '"')
9814  {
9815  if (yych <= 0x00)
9816  {
9817  goto basic_json_parser_2;
9818  }
9819  if (yych <= '!')
9820  {
9821  goto basic_json_parser_4;
9822  }
9823  goto basic_json_parser_9;
9824  }
9825  else
9826  {
9827  if (yych <= '+')
9828  {
9829  goto basic_json_parser_4;
9830  }
9831  if (yych <= ',')
9832  {
9833  goto basic_json_parser_10;
9834  }
9835  goto basic_json_parser_12;
9836  }
9837  }
9838  else
9839  {
9840  if (yych <= '9')
9841  {
9842  if (yych <= '/')
9843  {
9844  goto basic_json_parser_4;
9845  }
9846  if (yych <= '0')
9847  {
9848  goto basic_json_parser_13;
9849  }
9850  goto basic_json_parser_15;
9851  }
9852  else
9853  {
9854  if (yych <= ':')
9855  {
9856  goto basic_json_parser_17;
9857  }
9858  if (yych <= 'Z')
9859  {
9860  goto basic_json_parser_4;
9861  }
9862  goto basic_json_parser_19;
9863  }
9864  }
9865  }
9866  else
9867  {
9868  if (yych <= 'n')
9869  {
9870  if (yych <= 'e')
9871  {
9872  if (yych == ']')
9873  {
9874  goto basic_json_parser_21;
9875  }
9876  goto basic_json_parser_4;
9877  }
9878  else
9879  {
9880  if (yych <= 'f')
9881  {
9882  goto basic_json_parser_23;
9883  }
9884  if (yych <= 'm')
9885  {
9886  goto basic_json_parser_4;
9887  }
9888  goto basic_json_parser_24;
9889  }
9890  }
9891  else
9892  {
9893  if (yych <= 'z')
9894  {
9895  if (yych == 't')
9896  {
9897  goto basic_json_parser_25;
9898  }
9899  goto basic_json_parser_4;
9900  }
9901  else
9902  {
9903  if (yych <= '{')
9904  {
9905  goto basic_json_parser_26;
9906  }
9907  if (yych == '}')
9908  {
9909  goto basic_json_parser_28;
9910  }
9911  goto basic_json_parser_4;
9912  }
9913  }
9914  }
9915 basic_json_parser_2:
9916  ++m_cursor;
9917  {
9918  last_token_type = token_type::end_of_input;
9919  break;
9920  }
9921 basic_json_parser_4:
9922  ++m_cursor;
9923 basic_json_parser_5:
9924  {
9925  last_token_type = token_type::parse_error;
9926  break;
9927  }
9928 basic_json_parser_6:
9929  ++m_cursor;
9930  if (m_limit <= m_cursor)
9931  {
9932  fill_line_buffer(1); // LCOV_EXCL_LINE
9933  }
9934  yych = *m_cursor;
9935  if (yybm[0 + yych] & 32)
9936  {
9937  goto basic_json_parser_6;
9938  }
9939  {
9940  continue;
9941  }
9942 basic_json_parser_9:
9943  yyaccept = 0;
9944  yych = *(m_marker = ++m_cursor);
9945  if (yych <= 0x1F)
9946  {
9947  goto basic_json_parser_5;
9948  }
9949  if (yych <= 0x7F)
9950  {
9951  goto basic_json_parser_31;
9952  }
9953  if (yych <= 0xC1)
9954  {
9955  goto basic_json_parser_5;
9956  }
9957  if (yych <= 0xF4)
9958  {
9959  goto basic_json_parser_31;
9960  }
9961  goto basic_json_parser_5;
9962 basic_json_parser_10:
9963  ++m_cursor;
9964  {
9965  last_token_type = token_type::value_separator;
9966  break;
9967  }
9968 basic_json_parser_12:
9969  yych = *++m_cursor;
9970  if (yych <= '/')
9971  {
9972  goto basic_json_parser_5;
9973  }
9974  if (yych <= '0')
9975  {
9976  goto basic_json_parser_43;
9977  }
9978  if (yych <= '9')
9979  {
9980  goto basic_json_parser_45;
9981  }
9982  goto basic_json_parser_5;
9983 basic_json_parser_13:
9984  yyaccept = 1;
9985  yych = *(m_marker = ++m_cursor);
9986  if (yych <= '9')
9987  {
9988  if (yych == '.')
9989  {
9990  goto basic_json_parser_47;
9991  }
9992  if (yych >= '0')
9993  {
9994  goto basic_json_parser_48;
9995  }
9996  }
9997  else
9998  {
9999  if (yych <= 'E')
10000  {
10001  if (yych >= 'E')
10002  {
10003  goto basic_json_parser_51;
10004  }
10005  }
10006  else
10007  {
10008  if (yych == 'e')
10009  {
10010  goto basic_json_parser_51;
10011  }
10012  }
10013  }
10014 basic_json_parser_14:
10015  {
10016  last_token_type = token_type::value_unsigned;
10017  break;
10018  }
10019 basic_json_parser_15:
10020  yyaccept = 1;
10021  m_marker = ++m_cursor;
10022  if ((m_limit - m_cursor) < 3)
10023  {
10024  fill_line_buffer(3); // LCOV_EXCL_LINE
10025  }
10026  yych = *m_cursor;
10027  if (yybm[0 + yych] & 64)
10028  {
10029  goto basic_json_parser_15;
10030  }
10031  if (yych <= 'D')
10032  {
10033  if (yych == '.')
10034  {
10035  goto basic_json_parser_47;
10036  }
10037  goto basic_json_parser_14;
10038  }
10039  else
10040  {
10041  if (yych <= 'E')
10042  {
10043  goto basic_json_parser_51;
10044  }
10045  if (yych == 'e')
10046  {
10047  goto basic_json_parser_51;
10048  }
10049  goto basic_json_parser_14;
10050  }
10051 basic_json_parser_17:
10052  ++m_cursor;
10053  {
10054  last_token_type = token_type::name_separator;
10055  break;
10056  }
10057 basic_json_parser_19:
10058  ++m_cursor;
10059  {
10060  last_token_type = token_type::begin_array;
10061  break;
10062  }
10063 basic_json_parser_21:
10064  ++m_cursor;
10065  {
10066  last_token_type = token_type::end_array;
10067  break;
10068  }
10069 basic_json_parser_23:
10070  yyaccept = 0;
10071  yych = *(m_marker = ++m_cursor);
10072  if (yych == 'a')
10073  {
10074  goto basic_json_parser_52;
10075  }
10076  goto basic_json_parser_5;
10077 basic_json_parser_24:
10078  yyaccept = 0;
10079  yych = *(m_marker = ++m_cursor);
10080  if (yych == 'u')
10081  {
10082  goto basic_json_parser_53;
10083  }
10084  goto basic_json_parser_5;
10085 basic_json_parser_25:
10086  yyaccept = 0;
10087  yych = *(m_marker = ++m_cursor);
10088  if (yych == 'r')
10089  {
10090  goto basic_json_parser_54;
10091  }
10092  goto basic_json_parser_5;
10093 basic_json_parser_26:
10094  ++m_cursor;
10095  {
10096  last_token_type = token_type::begin_object;
10097  break;
10098  }
10099 basic_json_parser_28:
10100  ++m_cursor;
10101  {
10102  last_token_type = token_type::end_object;
10103  break;
10104  }
10105 basic_json_parser_30:
10106  ++m_cursor;
10107  if (m_limit <= m_cursor)
10108  {
10109  fill_line_buffer(1); // LCOV_EXCL_LINE
10110  }
10111  yych = *m_cursor;
10112 basic_json_parser_31:
10113  if (yybm[0 + yych] & 128)
10114  {
10115  goto basic_json_parser_30;
10116  }
10117  if (yych <= 0xE0)
10118  {
10119  if (yych <= '\\')
10120  {
10121  if (yych <= 0x1F)
10122  {
10123  goto basic_json_parser_32;
10124  }
10125  if (yych <= '"')
10126  {
10127  goto basic_json_parser_33;
10128  }
10129  goto basic_json_parser_35;
10130  }
10131  else
10132  {
10133  if (yych <= 0xC1)
10134  {
10135  goto basic_json_parser_32;
10136  }
10137  if (yych <= 0xDF)
10138  {
10139  goto basic_json_parser_36;
10140  }
10141  goto basic_json_parser_37;
10142  }
10143  }
10144  else
10145  {
10146  if (yych <= 0xEF)
10147  {
10148  if (yych == 0xED)
10149  {
10150  goto basic_json_parser_39;
10151  }
10152  goto basic_json_parser_38;
10153  }
10154  else
10155  {
10156  if (yych <= 0xF0)
10157  {
10158  goto basic_json_parser_40;
10159  }
10160  if (yych <= 0xF3)
10161  {
10162  goto basic_json_parser_41;
10163  }
10164  if (yych <= 0xF4)
10165  {
10166  goto basic_json_parser_42;
10167  }
10168  }
10169  }
10170 basic_json_parser_32:
10171  m_cursor = m_marker;
10172  if (yyaccept <= 1)
10173  {
10174  if (yyaccept == 0)
10175  {
10176  goto basic_json_parser_5;
10177  }
10178  else
10179  {
10180  goto basic_json_parser_14;
10181  }
10182  }
10183  else
10184  {
10185  if (yyaccept == 2)
10186  {
10187  goto basic_json_parser_44;
10188  }
10189  else
10190  {
10191  goto basic_json_parser_58;
10192  }
10193  }
10194 basic_json_parser_33:
10195  ++m_cursor;
10196  {
10197  last_token_type = token_type::value_string;
10198  break;
10199  }
10200 basic_json_parser_35:
10201  ++m_cursor;
10202  if (m_limit <= m_cursor)
10203  {
10204  fill_line_buffer(1); // LCOV_EXCL_LINE
10205  }
10206  yych = *m_cursor;
10207  if (yych <= 'e')
10208  {
10209  if (yych <= '/')
10210  {
10211  if (yych == '"')
10212  {
10213  goto basic_json_parser_30;
10214  }
10215  if (yych <= '.')
10216  {
10217  goto basic_json_parser_32;
10218  }
10219  goto basic_json_parser_30;
10220  }
10221  else
10222  {
10223  if (yych <= '\\')
10224  {
10225  if (yych <= '[')
10226  {
10227  goto basic_json_parser_32;
10228  }
10229  goto basic_json_parser_30;
10230  }
10231  else
10232  {
10233  if (yych == 'b')
10234  {
10235  goto basic_json_parser_30;
10236  }
10237  goto basic_json_parser_32;
10238  }
10239  }
10240  }
10241  else
10242  {
10243  if (yych <= 'q')
10244  {
10245  if (yych <= 'f')
10246  {
10247  goto basic_json_parser_30;
10248  }
10249  if (yych == 'n')
10250  {
10251  goto basic_json_parser_30;
10252  }
10253  goto basic_json_parser_32;
10254  }
10255  else
10256  {
10257  if (yych <= 's')
10258  {
10259  if (yych <= 'r')
10260  {
10261  goto basic_json_parser_30;
10262  }
10263  goto basic_json_parser_32;
10264  }
10265  else
10266  {
10267  if (yych <= 't')
10268  {
10269  goto basic_json_parser_30;
10270  }
10271  if (yych <= 'u')
10272  {
10273  goto basic_json_parser_55;
10274  }
10275  goto basic_json_parser_32;
10276  }
10277  }
10278  }
10279 basic_json_parser_36:
10280  ++m_cursor;
10281  if (m_limit <= m_cursor)
10282  {
10283  fill_line_buffer(1); // LCOV_EXCL_LINE
10284  }
10285  yych = *m_cursor;
10286  if (yych <= 0x7F)
10287  {
10288  goto basic_json_parser_32;
10289  }
10290  if (yych <= 0xBF)
10291  {
10292  goto basic_json_parser_30;
10293  }
10294  goto basic_json_parser_32;
10295 basic_json_parser_37:
10296  ++m_cursor;
10297  if (m_limit <= m_cursor)
10298  {
10299  fill_line_buffer(1); // LCOV_EXCL_LINE
10300  }
10301  yych = *m_cursor;
10302  if (yych <= 0x9F)
10303  {
10304  goto basic_json_parser_32;
10305  }
10306  if (yych <= 0xBF)
10307  {
10308  goto basic_json_parser_36;
10309  }
10310  goto basic_json_parser_32;
10311 basic_json_parser_38:
10312  ++m_cursor;
10313  if (m_limit <= m_cursor)
10314  {
10315  fill_line_buffer(1); // LCOV_EXCL_LINE
10316  }
10317  yych = *m_cursor;
10318  if (yych <= 0x7F)
10319  {
10320  goto basic_json_parser_32;
10321  }
10322  if (yych <= 0xBF)
10323  {
10324  goto basic_json_parser_36;
10325  }
10326  goto basic_json_parser_32;
10327 basic_json_parser_39:
10328  ++m_cursor;
10329  if (m_limit <= m_cursor)
10330  {
10331  fill_line_buffer(1); // LCOV_EXCL_LINE
10332  }
10333  yych = *m_cursor;
10334  if (yych <= 0x7F)
10335  {
10336  goto basic_json_parser_32;
10337  }
10338  if (yych <= 0x9F)
10339  {
10340  goto basic_json_parser_36;
10341  }
10342  goto basic_json_parser_32;
10343 basic_json_parser_40:
10344  ++m_cursor;
10345  if (m_limit <= m_cursor)
10346  {
10347  fill_line_buffer(1); // LCOV_EXCL_LINE
10348  }
10349  yych = *m_cursor;
10350  if (yych <= 0x8F)
10351  {
10352  goto basic_json_parser_32;
10353  }
10354  if (yych <= 0xBF)
10355  {
10356  goto basic_json_parser_38;
10357  }
10358  goto basic_json_parser_32;
10359 basic_json_parser_41:
10360  ++m_cursor;
10361  if (m_limit <= m_cursor)
10362  {
10363  fill_line_buffer(1); // LCOV_EXCL_LINE
10364  }
10365  yych = *m_cursor;
10366  if (yych <= 0x7F)
10367  {
10368  goto basic_json_parser_32;
10369  }
10370  if (yych <= 0xBF)
10371  {
10372  goto basic_json_parser_38;
10373  }
10374  goto basic_json_parser_32;
10375 basic_json_parser_42:
10376  ++m_cursor;
10377  if (m_limit <= m_cursor)
10378  {
10379  fill_line_buffer(1); // LCOV_EXCL_LINE
10380  }
10381  yych = *m_cursor;
10382  if (yych <= 0x7F)
10383  {
10384  goto basic_json_parser_32;
10385  }
10386  if (yych <= 0x8F)
10387  {
10388  goto basic_json_parser_38;
10389  }
10390  goto basic_json_parser_32;
10391 basic_json_parser_43:
10392  yyaccept = 2;
10393  yych = *(m_marker = ++m_cursor);
10394  if (yych <= '9')
10395  {
10396  if (yych == '.')
10397  {
10398  goto basic_json_parser_47;
10399  }
10400  if (yych >= '0')
10401  {
10402  goto basic_json_parser_48;
10403  }
10404  }
10405  else
10406  {
10407  if (yych <= 'E')
10408  {
10409  if (yych >= 'E')
10410  {
10411  goto basic_json_parser_51;
10412  }
10413  }
10414  else
10415  {
10416  if (yych == 'e')
10417  {
10418  goto basic_json_parser_51;
10419  }
10420  }
10421  }
10422 basic_json_parser_44:
10423  {
10424  last_token_type = token_type::value_integer;
10425  break;
10426  }
10427 basic_json_parser_45:
10428  yyaccept = 2;
10429  m_marker = ++m_cursor;
10430  if ((m_limit - m_cursor) < 3)
10431  {
10432  fill_line_buffer(3); // LCOV_EXCL_LINE
10433  }
10434  yych = *m_cursor;
10435  if (yych <= '9')
10436  {
10437  if (yych == '.')
10438  {
10439  goto basic_json_parser_47;
10440  }
10441  if (yych <= '/')
10442  {
10443  goto basic_json_parser_44;
10444  }
10445  goto basic_json_parser_45;
10446  }
10447  else
10448  {
10449  if (yych <= 'E')
10450  {
10451  if (yych <= 'D')
10452  {
10453  goto basic_json_parser_44;
10454  }
10455  goto basic_json_parser_51;
10456  }
10457  else
10458  {
10459  if (yych == 'e')
10460  {
10461  goto basic_json_parser_51;
10462  }
10463  goto basic_json_parser_44;
10464  }
10465  }
10466 basic_json_parser_47:
10467  yych = *++m_cursor;
10468  if (yych <= '/')
10469  {
10470  goto basic_json_parser_32;
10471  }
10472  if (yych <= '9')
10473  {
10474  goto basic_json_parser_56;
10475  }
10476  goto basic_json_parser_32;
10477 basic_json_parser_48:
10478  ++m_cursor;
10479  if (m_limit <= m_cursor)
10480  {
10481  fill_line_buffer(1); // LCOV_EXCL_LINE
10482  }
10483  yych = *m_cursor;
10484  if (yych <= '/')
10485  {
10486  goto basic_json_parser_50;
10487  }
10488  if (yych <= '9')
10489  {
10490  goto basic_json_parser_48;
10491  }
10492 basic_json_parser_50:
10493  {
10494  last_token_type = token_type::parse_error;
10495  break;
10496  }
10497 basic_json_parser_51:
10498  yych = *++m_cursor;
10499  if (yych <= ',')
10500  {
10501  if (yych == '+')
10502  {
10503  goto basic_json_parser_59;
10504  }
10505  goto basic_json_parser_32;
10506  }
10507  else
10508  {
10509  if (yych <= '-')
10510  {
10511  goto basic_json_parser_59;
10512  }
10513  if (yych <= '/')
10514  {
10515  goto basic_json_parser_32;
10516  }
10517  if (yych <= '9')
10518  {
10519  goto basic_json_parser_60;
10520  }
10521  goto basic_json_parser_32;
10522  }
10523 basic_json_parser_52:
10524  yych = *++m_cursor;
10525  if (yych == 'l')
10526  {
10527  goto basic_json_parser_62;
10528  }
10529  goto basic_json_parser_32;
10530 basic_json_parser_53:
10531  yych = *++m_cursor;
10532  if (yych == 'l')
10533  {
10534  goto basic_json_parser_63;
10535  }
10536  goto basic_json_parser_32;
10537 basic_json_parser_54:
10538  yych = *++m_cursor;
10539  if (yych == 'u')
10540  {
10541  goto basic_json_parser_64;
10542  }
10543  goto basic_json_parser_32;
10544 basic_json_parser_55:
10545  ++m_cursor;
10546  if (m_limit <= m_cursor)
10547  {
10548  fill_line_buffer(1); // LCOV_EXCL_LINE
10549  }
10550  yych = *m_cursor;
10551  if (yych <= '@')
10552  {
10553  if (yych <= '/')
10554  {
10555  goto basic_json_parser_32;
10556  }
10557  if (yych <= '9')
10558  {
10559  goto basic_json_parser_65;
10560  }
10561  goto basic_json_parser_32;
10562  }
10563  else
10564  {
10565  if (yych <= 'F')
10566  {
10567  goto basic_json_parser_65;
10568  }
10569  if (yych <= '`')
10570  {
10571  goto basic_json_parser_32;
10572  }
10573  if (yych <= 'f')
10574  {
10575  goto basic_json_parser_65;
10576  }
10577  goto basic_json_parser_32;
10578  }
10579 basic_json_parser_56:
10580  yyaccept = 3;
10581  m_marker = ++m_cursor;
10582  if ((m_limit - m_cursor) < 3)
10583  {
10584  fill_line_buffer(3); // LCOV_EXCL_LINE
10585  }
10586  yych = *m_cursor;
10587  if (yych <= 'D')
10588  {
10589  if (yych <= '/')
10590  {
10591  goto basic_json_parser_58;
10592  }
10593  if (yych <= '9')
10594  {
10595  goto basic_json_parser_56;
10596  }
10597  }
10598  else
10599  {
10600  if (yych <= 'E')
10601  {
10602  goto basic_json_parser_51;
10603  }
10604  if (yych == 'e')
10605  {
10606  goto basic_json_parser_51;
10607  }
10608  }
10609 basic_json_parser_58:
10610  {
10611  last_token_type = token_type::value_float;
10612  break;
10613  }
10614 basic_json_parser_59:
10615  yych = *++m_cursor;
10616  if (yych <= '/')
10617  {
10618  goto basic_json_parser_32;
10619  }
10620  if (yych >= ':')
10621  {
10622  goto basic_json_parser_32;
10623  }
10624 basic_json_parser_60:
10625  ++m_cursor;
10626  if (m_limit <= m_cursor)
10627  {
10628  fill_line_buffer(1); // LCOV_EXCL_LINE
10629  }
10630  yych = *m_cursor;
10631  if (yych <= '/')
10632  {
10633  goto basic_json_parser_58;
10634  }
10635  if (yych <= '9')
10636  {
10637  goto basic_json_parser_60;
10638  }
10639  goto basic_json_parser_58;
10640 basic_json_parser_62:
10641  yych = *++m_cursor;
10642  if (yych == 's')
10643  {
10644  goto basic_json_parser_66;
10645  }
10646  goto basic_json_parser_32;
10647 basic_json_parser_63:
10648  yych = *++m_cursor;
10649  if (yych == 'l')
10650  {
10651  goto basic_json_parser_67;
10652  }
10653  goto basic_json_parser_32;
10654 basic_json_parser_64:
10655  yych = *++m_cursor;
10656  if (yych == 'e')
10657  {
10658  goto basic_json_parser_69;
10659  }
10660  goto basic_json_parser_32;
10661 basic_json_parser_65:
10662  ++m_cursor;
10663  if (m_limit <= m_cursor)
10664  {
10665  fill_line_buffer(1); // LCOV_EXCL_LINE
10666  }
10667  yych = *m_cursor;
10668  if (yych <= '@')
10669  {
10670  if (yych <= '/')
10671  {
10672  goto basic_json_parser_32;
10673  }
10674  if (yych <= '9')
10675  {
10676  goto basic_json_parser_71;
10677  }
10678  goto basic_json_parser_32;
10679  }
10680  else
10681  {
10682  if (yych <= 'F')
10683  {
10684  goto basic_json_parser_71;
10685  }
10686  if (yych <= '`')
10687  {
10688  goto basic_json_parser_32;
10689  }
10690  if (yych <= 'f')
10691  {
10692  goto basic_json_parser_71;
10693  }
10694  goto basic_json_parser_32;
10695  }
10696 basic_json_parser_66:
10697  yych = *++m_cursor;
10698  if (yych == 'e')
10699  {
10700  goto basic_json_parser_72;
10701  }
10702  goto basic_json_parser_32;
10703 basic_json_parser_67:
10704  ++m_cursor;
10705  {
10706  last_token_type = token_type::literal_null;
10707  break;
10708  }
10709 basic_json_parser_69:
10710  ++m_cursor;
10711  {
10712  last_token_type = token_type::literal_true;
10713  break;
10714  }
10715 basic_json_parser_71:
10716  ++m_cursor;
10717  if (m_limit <= m_cursor)
10718  {
10719  fill_line_buffer(1); // LCOV_EXCL_LINE
10720  }
10721  yych = *m_cursor;
10722  if (yych <= '@')
10723  {
10724  if (yych <= '/')
10725  {
10726  goto basic_json_parser_32;
10727  }
10728  if (yych <= '9')
10729  {
10730  goto basic_json_parser_74;
10731  }
10732  goto basic_json_parser_32;
10733  }
10734  else
10735  {
10736  if (yych <= 'F')
10737  {
10738  goto basic_json_parser_74;
10739  }
10740  if (yych <= '`')
10741  {
10742  goto basic_json_parser_32;
10743  }
10744  if (yych <= 'f')
10745  {
10746  goto basic_json_parser_74;
10747  }
10748  goto basic_json_parser_32;
10749  }
10750 basic_json_parser_72:
10751  ++m_cursor;
10752  {
10753  last_token_type = token_type::literal_false;
10754  break;
10755  }
10756 basic_json_parser_74:
10757  ++m_cursor;
10758  if (m_limit <= m_cursor)
10759  {
10760  fill_line_buffer(1); // LCOV_EXCL_LINE
10761  }
10762  yych = *m_cursor;
10763  if (yych <= '@')
10764  {
10765  if (yych <= '/')
10766  {
10767  goto basic_json_parser_32;
10768  }
10769  if (yych <= '9')
10770  {
10771  goto basic_json_parser_30;
10772  }
10773  goto basic_json_parser_32;
10774  }
10775  else
10776  {
10777  if (yych <= 'F')
10778  {
10779  goto basic_json_parser_30;
10780  }
10781  if (yych <= '`')
10782  {
10783  goto basic_json_parser_32;
10784  }
10785  if (yych <= 'f')
10786  {
10787  goto basic_json_parser_30;
10788  }
10789  goto basic_json_parser_32;
10790  }
10791  }
10792 
10793  }
10794 
10795  return last_token_type;
10796  }
10797 
10826  void fill_line_buffer(size_t n = 0)
10827  {
10828  // if line buffer is used, m_content points to its data
10829  assert(m_line_buffer.empty()
10830  or m_content == reinterpret_cast<const lexer_char_t*>(m_line_buffer.data()));
10831 
10832  // if line buffer is used, m_limit is set past the end of its data
10833  assert(m_line_buffer.empty()
10834  or m_limit == m_content + m_line_buffer.size());
10835 
10836  // pointer relationships
10837  assert(m_content <= m_start);
10838  assert(m_start <= m_cursor);
10839  assert(m_cursor <= m_limit);
10840  assert(m_marker == nullptr or m_marker <= m_limit);
10841 
10842  // number of processed characters (p)
10843  const auto num_processed_chars = static_cast<size_t>(m_start - m_content);
10844  // offset for m_marker wrt. to m_start
10845  const auto offset_marker = (m_marker == nullptr) ? 0 : m_marker - m_start;
10846  // number of unprocessed characters (u)
10847  const auto offset_cursor = m_cursor - m_start;
10848 
10849  // no stream is used or end of file is reached
10850  if (m_stream == nullptr or m_stream->eof())
10851  {
10852  // m_start may or may not be pointing into m_line_buffer at
10853  // this point. We trust the standard library to do the right
10854  // thing. See http://stackoverflow.com/q/28142011/266378
10855  m_line_buffer.assign(m_start, m_limit);
10856 
10857  // append n characters to make sure that there is sufficient
10858  // space between m_cursor and m_limit
10859  m_line_buffer.append(1, '\x00');
10860  if (n > 0)
10861  {
10862  m_line_buffer.append(n - 1, '\x01');
10863  }
10864  }
10865  else
10866  {
10867  // delete processed characters from line buffer
10868  m_line_buffer.erase(0, num_processed_chars);
10869  // read next line from input stream
10870  m_line_buffer_tmp.clear();
10871  std::getline(*m_stream, m_line_buffer_tmp, '\n');
10872 
10873  // add line with newline symbol to the line buffer
10874  m_line_buffer += m_line_buffer_tmp;
10875  m_line_buffer.push_back('\n');
10876  }
10877 
10878  // set pointers
10879  m_content = reinterpret_cast<const lexer_char_t*>(m_line_buffer.data());
10880  assert(m_content != nullptr);
10881  m_start = m_content;
10882  m_marker = m_start + offset_marker;
10883  m_cursor = m_start + offset_cursor;
10884  m_limit = m_start + m_line_buffer.size();
10885  }
10886 
10888  string_t get_token_string() const
10889  {
10890  assert(m_start != nullptr);
10891  return string_t(reinterpret_cast<typename string_t::const_pointer>(m_start),
10892  static_cast<size_t>(m_cursor - m_start));
10893  }
10894 
10952  string_t get_string() const
10953  {
10954  assert(m_cursor - m_start >= 2);
10955 
10956  string_t result;
10957  result.reserve(static_cast<size_t>(m_cursor - m_start - 2));
10958 
10959  // iterate the result between the quotes
10960  for (const lexer_char_t* i = m_start + 1; i < m_cursor - 1; ++i)
10961  {
10962  // find next escape character
10963  auto e = std::find(i, m_cursor - 1, '\\');
10964  if (e != i)
10965  {
10966  // see https://github.com/nlohmann/json/issues/365#issuecomment-262874705
10967  for (auto k = i; k < e; k++)
10968  {
10969  result.push_back(static_cast<typename string_t::value_type>(*k));
10970  }
10971  i = e - 1; // -1 because of ++i
10972  }
10973  else
10974  {
10975  // processing escaped character
10976  // read next character
10977  ++i;
10978 
10979  switch (*i)
10980  {
10981  // the default escapes
10982  case 't':
10983  {
10984  result += "\t";
10985  break;
10986  }
10987  case 'b':
10988  {
10989  result += "\b";
10990  break;
10991  }
10992  case 'f':
10993  {
10994  result += "\f";
10995  break;
10996  }
10997  case 'n':
10998  {
10999  result += "\n";
11000  break;
11001  }
11002  case 'r':
11003  {
11004  result += "\r";
11005  break;
11006  }
11007  case '\\':
11008  {
11009  result += "\\";
11010  break;
11011  }
11012  case '/':
11013  {
11014  result += "/";
11015  break;
11016  }
11017  case '"':
11018  {
11019  result += "\"";
11020  break;
11021  }
11022 
11023  // unicode
11024  case 'u':
11025  {
11026  // get code xxxx from uxxxx
11027  auto codepoint = std::strtoul(std::string(reinterpret_cast<typename string_t::const_pointer>(i + 1),
11028  4).c_str(), nullptr, 16);
11029 
11030  // check if codepoint is a high surrogate
11031  if (codepoint >= 0xD800 and codepoint <= 0xDBFF)
11032  {
11033  // make sure there is a subsequent unicode
11034  if ((i + 6 >= m_limit) or * (i + 5) != '\\' or * (i + 6) != 'u')
11035  {
11036  JSON_THROW(std::invalid_argument("missing low surrogate"));
11037  }
11038 
11039  // get code yyyy from uxxxx\uyyyy
11040  auto codepoint2 = std::strtoul(std::string(reinterpret_cast<typename string_t::const_pointer>
11041  (i + 7), 4).c_str(), nullptr, 16);
11042  result += to_unicode(codepoint, codepoint2);
11043  // skip the next 10 characters (xxxx\uyyyy)
11044  i += 10;
11045  }
11046  else if (codepoint >= 0xDC00 and codepoint <= 0xDFFF)
11047  {
11048  // we found a lone low surrogate
11049  JSON_THROW(std::invalid_argument("missing high surrogate"));
11050  }
11051  else
11052  {
11053  // add unicode character(s)
11054  result += to_unicode(codepoint);
11055  // skip the next four characters (xxxx)
11056  i += 4;
11057  }
11058  break;
11059  }
11060  }
11061  }
11062  }
11063 
11064  return result;
11065  }
11066 
11067 
11077  struct strtonum
11078  {
11079  public:
11080  strtonum(const char* start, const char* end)
11081  : m_start(start), m_end(end)
11082  {}
11083 
11090  template<typename T, typename = typename std::enable_if<std::is_arithmetic<T>::value>::type>
11091  bool to(T& val) const
11092  {
11093  return parse(val, std::is_integral<T>());
11094  }
11095 
11096  private:
11097  const char* const m_start = nullptr;
11098  const char* const m_end = nullptr;
11099 
11100  // floating-point conversion
11101 
11102  // overloaded wrappers for strtod/strtof/strtold
11103  // that will be called from parse<floating_point_t>
11104  static void strtof(float& f, const char* str, char** endptr)
11105  {
11106  f = std::strtof(str, endptr);
11107  }
11108 
11109  static void strtof(double& f, const char* str, char** endptr)
11110  {
11111  f = std::strtod(str, endptr);
11112  }
11113 
11114  static void strtof(long double& f, const char* str, char** endptr)
11115  {
11116  f = std::strtold(str, endptr);
11117  }
11118 
11119  template<typename T>
11120  bool parse(T& value, /*is_integral=*/std::false_type) const
11121  {
11122  // replace decimal separator with locale-specific version,
11123  // when necessary; data will point to either the original
11124  // string, or buf, or tempstr containing the fixed string.
11125  std::string tempstr;
11126  std::array<char, 64> buf;
11127  const size_t len = static_cast<size_t>(m_end - m_start);
11128 
11129  // lexer will reject empty numbers
11130  assert(len > 0);
11131 
11132  // since dealing with strtod family of functions, we're
11133  // getting the decimal point char from the C locale facilities
11134  // instead of C++'s numpunct facet of the current std::locale
11135  const auto loc = localeconv();
11136  assert(loc != nullptr);
11137  const char decimal_point_char = (loc->decimal_point == nullptr) ? '.' : loc->decimal_point[0];
11138 
11139  const char* data = m_start;
11140 
11141  if (decimal_point_char != '.')
11142  {
11143  const size_t ds_pos = static_cast<size_t>(std::find(m_start, m_end, '.') - m_start);
11144 
11145  if (ds_pos != len)
11146  {
11147  // copy the data into the local buffer or tempstr, if
11148  // buffer is too small; replace decimal separator, and
11149  // update data to point to the modified bytes
11150  if ((len + 1) < buf.size())
11151  {
11152  std::copy(m_start, m_end, buf.begin());
11153  buf[len] = 0;
11154  buf[ds_pos] = decimal_point_char;
11155  data = buf.data();
11156  }
11157  else
11158  {
11159  tempstr.assign(m_start, m_end);
11160  tempstr[ds_pos] = decimal_point_char;
11161  data = tempstr.c_str();
11162  }
11163  }
11164  }
11165 
11166  char* endptr = nullptr;
11167  value = 0;
11168  // this calls appropriate overload depending on T
11169  strtof(value, data, &endptr);
11170 
11171  // parsing was successful iff strtof parsed exactly the number
11172  // of characters determined by the lexer (len)
11173  const bool ok = (endptr == (data + len));
11174 
11175  if (ok and (value == static_cast<T>(0.0)) and (*data == '-'))
11176  {
11177  // some implementations forget to negate the zero
11178  value = -0.0;
11179  }
11180 
11181  return ok;
11182  }
11183 
11184  // integral conversion
11185 
11186  signed long long parse_integral(char** endptr, /*is_signed*/std::true_type) const
11187  {
11188  return std::strtoll(m_start, endptr, 10);
11189  }
11190 
11191  unsigned long long parse_integral(char** endptr, /*is_signed*/std::false_type) const
11192  {
11193  return std::strtoull(m_start, endptr, 10);
11194  }
11195 
11196  template<typename T>
11197  bool parse(T& value, /*is_integral=*/std::true_type) const
11198  {
11199  char* endptr = nullptr;
11200  errno = 0; // these are thread-local
11201  const auto x = parse_integral(&endptr, std::is_signed<T>());
11202 
11203  // called right overload?
11204  static_assert(std::is_signed<T>() == std::is_signed<decltype(x)>(), "");
11205 
11206  value = static_cast<T>(x);
11207 
11208  return (x == static_cast<decltype(x)>(value)) // x fits into destination T
11209  and (x < 0) == (value < 0) // preserved sign
11210  //and ((x != 0) or is_integral()) // strto[u]ll did nto fail
11211  and (errno == 0) // strto[u]ll did not overflow
11212  and (m_start < m_end) // token was not empty
11213  and (endptr == m_end); // parsed entire token exactly
11214  }
11215  };
11216 
11236  bool get_number(basic_json& result, const token_type token) const
11237  {
11238  assert(m_start != nullptr);
11239  assert(m_start < m_cursor);
11240  assert((token == token_type::value_unsigned) or
11241  (token == token_type::value_integer) or
11242  (token == token_type::value_float));
11243 
11244  strtonum num_converter(reinterpret_cast<const char*>(m_start),
11245  reinterpret_cast<const char*>(m_cursor));
11246 
11247  switch (token)
11248  {
11249  case lexer::token_type::value_unsigned:
11250  {
11251  number_unsigned_t val;
11252  if (num_converter.to(val))
11253  {
11254  // parsing successful
11255  result.m_type = value_t::number_unsigned;
11256  result.m_value = val;
11257  return true;
11258  }
11259  break;
11260  }
11261 
11262  case lexer::token_type::value_integer:
11263  {
11264  number_integer_t val;
11265  if (num_converter.to(val))
11266  {
11267  // parsing successful
11268  result.m_type = value_t::number_integer;
11269  result.m_value = val;
11270  return true;
11271  }
11272  break;
11273  }
11274 
11275  default:
11276  {
11277  break;
11278  }
11279  }
11280 
11281  // parse float (either explicitly or because a previous conversion
11282  // failed)
11283  number_float_t val;
11284  if (num_converter.to(val))
11285  {
11286  // parsing successful
11287  result.m_type = value_t::number_float;
11288  result.m_value = val;
11289 
11290  // replace infinity and NAN by null
11291  if (not std::isfinite(result.m_value.number_float))
11292  {
11293  result.m_type = value_t::null;
11294  result.m_value = basic_json::json_value();
11295  }
11296 
11297  return true;
11298  }
11299 
11300  // couldn't parse number in any format
11301  return false;
11302  }
11303 
11304  private:
11306  std::istream* m_stream = nullptr;
11308  string_t m_line_buffer {};
11310  string_t m_line_buffer_tmp {};
11312  const lexer_char_t* m_content = nullptr;
11314  const lexer_char_t* m_start = nullptr;
11316  const lexer_char_t* m_marker = nullptr;
11318  const lexer_char_t* m_cursor = nullptr;
11320  const lexer_char_t* m_limit = nullptr;
11322  token_type last_token_type = token_type::end_of_input;
11323  };
11324 
11330  class parser
11331  {
11332  public:
11334  parser(const char* buff, const parser_callback_t cb = nullptr)
11335  : callback(cb),
11336  m_lexer(reinterpret_cast<const typename lexer::lexer_char_t*>(buff), std::strlen(buff))
11337  {}
11338 
11340  parser(std::istream& is, const parser_callback_t cb = nullptr)
11341  : callback(cb), m_lexer(is)
11342  {}
11343 
11345  template<class IteratorType, typename std::enable_if<
11346  std::is_same<typename std::iterator_traits<IteratorType>::iterator_category, std::random_access_iterator_tag>::value
11347  , int>::type
11348  = 0>
11349  parser(IteratorType first, IteratorType last, const parser_callback_t cb = nullptr)
11350  : callback(cb),
11351  m_lexer(reinterpret_cast<const typename lexer::lexer_char_t*>(&(*first)),
11352  static_cast<size_t>(std::distance(first, last)))
11353  {}
11354 
11356  basic_json parse()
11357  {
11358  // read first token
11359  get_token();
11360 
11361  basic_json result = parse_internal(true);
11362  result.assert_invariant();
11363 
11364  expect(lexer::token_type::end_of_input);
11365 
11366  // return parser result and replace it with null in case the
11367  // top-level value was discarded by the callback function
11368  return result.is_discarded() ? basic_json() : std::move(result);
11369  }
11370 
11371  private:
11373  basic_json parse_internal(bool keep)
11374  {
11375  auto result = basic_json(value_t::discarded);
11376 
11377  switch (last_token)
11378  {
11379  case lexer::token_type::begin_object:
11380  {
11381  if (keep and (not callback
11382  or ((keep = callback(depth++, parse_event_t::object_start, result)) != 0)))
11383  {
11384  // explicitly set result to object to cope with {}
11385  result.m_type = value_t::object;
11386  result.m_value = value_t::object;
11387  }
11388 
11389  // read next token
11390  get_token();
11391 
11392  // closing } -> we are done
11393  if (last_token == lexer::token_type::end_object)
11394  {
11395  get_token();
11396  if (keep and callback and not callback(--depth, parse_event_t::object_end, result))
11397  {
11398  result = basic_json(value_t::discarded);
11399  }
11400  return result;
11401  }
11402 
11403  // no comma is expected here
11404  unexpect(lexer::token_type::value_separator);
11405 
11406  // otherwise: parse key-value pairs
11407  do
11408  {
11409  // ugly, but could be fixed with loop reorganization
11410  if (last_token == lexer::token_type::value_separator)
11411  {
11412  get_token();
11413  }
11414 
11415  // store key
11416  expect(lexer::token_type::value_string);
11417  const auto key = m_lexer.get_string();
11418 
11419  bool keep_tag = false;
11420  if (keep)
11421  {
11422  if (callback)
11423  {
11424  basic_json k(key);
11425  keep_tag = callback(depth, parse_event_t::key, k);
11426  }
11427  else
11428  {
11429  keep_tag = true;
11430  }
11431  }
11432 
11433  // parse separator (:)
11434  get_token();
11435  expect(lexer::token_type::name_separator);
11436 
11437  // parse and add value
11438  get_token();
11439  auto value = parse_internal(keep);
11440  if (keep and keep_tag and not value.is_discarded())
11441  {
11442  result[key] = std::move(value);
11443  }
11444  }
11445  while (last_token == lexer::token_type::value_separator);
11446 
11447  // closing }
11448  expect(lexer::token_type::end_object);
11449  get_token();
11450  if (keep and callback and not callback(--depth, parse_event_t::object_end, result))
11451  {
11452  result = basic_json(value_t::discarded);
11453  }
11454 
11455  return result;
11456  }
11457 
11458  case lexer::token_type::begin_array:
11459  {
11460  if (keep and (not callback
11461  or ((keep = callback(depth++, parse_event_t::array_start, result)) != 0)))
11462  {
11463  // explicitly set result to object to cope with []
11464  result.m_type = value_t::array;
11465  result.m_value = value_t::array;
11466  }
11467 
11468  // read next token
11469  get_token();
11470 
11471  // closing ] -> we are done
11472  if (last_token == lexer::token_type::end_array)
11473  {
11474  get_token();
11475  if (callback and not callback(--depth, parse_event_t::array_end, result))
11476  {
11477  result = basic_json(value_t::discarded);
11478  }
11479  return result;
11480  }
11481 
11482  // no comma is expected here
11483  unexpect(lexer::token_type::value_separator);
11484 
11485  // otherwise: parse values
11486  do
11487  {
11488  // ugly, but could be fixed with loop reorganization
11489  if (last_token == lexer::token_type::value_separator)
11490  {
11491  get_token();
11492  }
11493 
11494  // parse value
11495  auto value = parse_internal(keep);
11496  if (keep and not value.is_discarded())
11497  {
11498  result.push_back(std::move(value));
11499  }
11500  }
11501  while (last_token == lexer::token_type::value_separator);
11502 
11503  // closing ]
11504  expect(lexer::token_type::end_array);
11505  get_token();
11506  if (keep and callback and not callback(--depth, parse_event_t::array_end, result))
11507  {
11508  result = basic_json(value_t::discarded);
11509  }
11510 
11511  return result;
11512  }
11513 
11514  case lexer::token_type::literal_null:
11515  {
11516  get_token();
11517  result.m_type = value_t::null;
11518  break;
11519  }
11520 
11521  case lexer::token_type::value_string:
11522  {
11523  const auto s = m_lexer.get_string();
11524  get_token();
11525  result = basic_json(s);
11526  break;
11527  }
11528 
11529  case lexer::token_type::literal_true:
11530  {
11531  get_token();
11532  result.m_type = value_t::boolean;
11533  result.m_value = true;
11534  break;
11535  }
11536 
11537  case lexer::token_type::literal_false:
11538  {
11539  get_token();
11540  result.m_type = value_t::boolean;
11541  result.m_value = false;
11542  break;
11543  }
11544 
11545  case lexer::token_type::value_unsigned:
11546  case lexer::token_type::value_integer:
11547  case lexer::token_type::value_float:
11548  {
11549  m_lexer.get_number(result, last_token);
11550  get_token();
11551  break;
11552  }
11553 
11554  default:
11555  {
11556  // the last token was unexpected
11557  unexpect(last_token);
11558  }
11559  }
11560 
11561  if (keep and callback and not callback(depth, parse_event_t::value, result))
11562  {
11563  result = basic_json(value_t::discarded);
11564  }
11565  return result;
11566  }
11567 
11569  typename lexer::token_type get_token()
11570  {
11571  last_token = m_lexer.scan();
11572  return last_token;
11573  }
11574 
11575  void expect(typename lexer::token_type t) const
11576  {
11577  if (t != last_token)
11578  {
11579  std::string error_msg = "parse error - unexpected ";
11580  error_msg += (last_token == lexer::token_type::parse_error ? ("'" + m_lexer.get_token_string() +
11581  "'") :
11582  lexer::token_type_name(last_token));
11583  error_msg += "; expected " + lexer::token_type_name(t);
11584  JSON_THROW(std::invalid_argument(error_msg));
11585  }
11586  }
11587 
11588  void unexpect(typename lexer::token_type t) const
11589  {
11590  if (t == last_token)
11591  {
11592  std::string error_msg = "parse error - unexpected ";
11593  error_msg += (last_token == lexer::token_type::parse_error ? ("'" + m_lexer.get_token_string() +
11594  "'") :
11595  lexer::token_type_name(last_token));
11596  JSON_THROW(std::invalid_argument(error_msg));
11597  }
11598  }
11599 
11600  private:
11602  int depth = 0;
11604  const parser_callback_t callback = nullptr;
11606  typename lexer::token_type last_token = lexer::token_type::uninitialized;
11608  lexer m_lexer;
11609  };
11610 
11611  public:
11624  {
11626  friend class basic_json;
11627 
11628  public:
11651  explicit json_pointer(const std::string& s = "")
11652  : reference_tokens(split(s))
11653  {}
11654 
11670  std::string to_string() const noexcept
11671  {
11672  return std::accumulate(reference_tokens.begin(),
11673  reference_tokens.end(), std::string{},
11674  [](const std::string & a, const std::string & b)
11675  {
11676  return a + "/" + escape(b);
11677  });
11678  }
11679 
11681  operator std::string() const
11682  {
11683  return to_string();
11684  }
11685 
11686  private:
11688  std::string pop_back()
11689  {
11690  if (is_root())
11691  {
11692  JSON_THROW(std::domain_error("JSON pointer has no parent"));
11693  }
11694 
11695  auto last = reference_tokens.back();
11696  reference_tokens.pop_back();
11697  return last;
11698  }
11699 
11701  bool is_root() const
11702  {
11703  return reference_tokens.empty();
11704  }
11705 
11706  json_pointer top() const
11707  {
11708  if (is_root())
11709  {
11710  JSON_THROW(std::domain_error("JSON pointer has no parent"));
11711  }
11712 
11713  json_pointer result = *this;
11714  result.reference_tokens = {reference_tokens[0]};
11715  return result;
11716  }
11717 
11723  reference get_and_create(reference j) const
11724  {
11725  pointer result = &j;
11726 
11727  // in case no reference tokens exist, return a reference to the
11728  // JSON value j which will be overwritten by a primitive value
11729  for (const auto& reference_token : reference_tokens)
11730  {
11731  switch (result->m_type)
11732  {
11733  case value_t::null:
11734  {
11735  if (reference_token == "0")
11736  {
11737  // start a new array if reference token is 0
11738  result = &result->operator[](0);
11739  }
11740  else
11741  {
11742  // start a new object otherwise
11743  result = &result->operator[](reference_token);
11744  }
11745  break;
11746  }
11747 
11748  case value_t::object:
11749  {
11750  // create an entry in the object
11751  result = &result->operator[](reference_token);
11752  break;
11753  }
11754 
11755  case value_t::array:
11756  {
11757  // create an entry in the array
11758  result = &result->operator[](static_cast<size_type>(std::stoi(reference_token)));
11759  break;
11760  }
11761 
11762  /*
11763  The following code is only reached if there exists a
11764  reference token _and_ the current value is primitive. In
11765  this case, we have an error situation, because primitive
11766  values may only occur as single value; that is, with an
11767  empty list of reference tokens.
11768  */
11769  default:
11770  {
11771  JSON_THROW(std::domain_error("invalid value to unflatten"));
11772  }
11773  }
11774  }
11775 
11776  return *result;
11777  }
11778 
11798  reference get_unchecked(pointer ptr) const
11799  {
11800  for (const auto& reference_token : reference_tokens)
11801  {
11802  // convert null values to arrays or objects before continuing
11803  if (ptr->m_type == value_t::null)
11804  {
11805  // check if reference token is a number
11806  const bool nums = std::all_of(reference_token.begin(),
11807  reference_token.end(),
11808  [](const char x)
11809  {
11810  return std::isdigit(x);
11811  });
11812 
11813  // change value to array for numbers or "-" or to object
11814  // otherwise
11815  if (nums or reference_token == "-")
11816  {
11817  *ptr = value_t::array;
11818  }
11819  else
11820  {
11821  *ptr = value_t::object;
11822  }
11823  }
11824 
11825  switch (ptr->m_type)
11826  {
11827  case value_t::object:
11828  {
11829  // use unchecked object access
11830  ptr = &ptr->operator[](reference_token);
11831  break;
11832  }
11833 
11834  case value_t::array:
11835  {
11836  // error condition (cf. RFC 6901, Sect. 4)
11837  if (reference_token.size() > 1 and reference_token[0] == '0')
11838  {
11839  JSON_THROW(std::domain_error("array index must not begin with '0'"));
11840  }
11841 
11842  if (reference_token == "-")
11843  {
11844  // explicitly treat "-" as index beyond the end
11845  ptr = &ptr->operator[](ptr->m_value.array->size());
11846  }
11847  else
11848  {
11849  // convert array index to number; unchecked access
11850  ptr = &ptr->operator[](static_cast<size_type>(std::stoi(reference_token)));
11851  }
11852  break;
11853  }
11854 
11855  default:
11856  {
11857  JSON_THROW(std::out_of_range("unresolved reference token '" + reference_token + "'"));
11858  }
11859  }
11860  }
11861 
11862  return *ptr;
11863  }
11864 
11865  reference get_checked(pointer ptr) const
11866  {
11867  for (const auto& reference_token : reference_tokens)
11868  {
11869  switch (ptr->m_type)
11870  {
11871  case value_t::object:
11872  {
11873  // note: at performs range check
11874  ptr = &ptr->at(reference_token);
11875  break;
11876  }
11877 
11878  case value_t::array:
11879  {
11880  if (reference_token == "-")
11881  {
11882  // "-" always fails the range check
11883  JSON_THROW(std::out_of_range("array index '-' (" +
11884  std::to_string(ptr->m_value.array->size()) +
11885  ") is out of range"));
11886  }
11887 
11888  // error condition (cf. RFC 6901, Sect. 4)
11889  if (reference_token.size() > 1 and reference_token[0] == '0')
11890  {
11891  JSON_THROW(std::domain_error("array index must not begin with '0'"));
11892  }
11893 
11894  // note: at performs range check
11895  ptr = &ptr->at(static_cast<size_type>(std::stoi(reference_token)));
11896  break;
11897  }
11898 
11899  default:
11900  {
11901  JSON_THROW(std::out_of_range("unresolved reference token '" + reference_token + "'"));
11902  }
11903  }
11904  }
11905 
11906  return *ptr;
11907  }
11908 
11917  const_reference get_unchecked(const_pointer ptr) const
11918  {
11919  for (const auto& reference_token : reference_tokens)
11920  {
11921  switch (ptr->m_type)
11922  {
11923  case value_t::object:
11924  {
11925  // use unchecked object access
11926  ptr = &ptr->operator[](reference_token);
11927  break;
11928  }
11929 
11930  case value_t::array:
11931  {
11932  if (reference_token == "-")
11933  {
11934  // "-" cannot be used for const access
11935  JSON_THROW(std::out_of_range("array index '-' (" +
11936  std::to_string(ptr->m_value.array->size()) +
11937  ") is out of range"));
11938  }
11939 
11940  // error condition (cf. RFC 6901, Sect. 4)
11941  if (reference_token.size() > 1 and reference_token[0] == '0')
11942  {
11943  JSON_THROW(std::domain_error("array index must not begin with '0'"));
11944  }
11945 
11946  // use unchecked array access
11947  ptr = &ptr->operator[](static_cast<size_type>(std::stoi(reference_token)));
11948  break;
11949  }
11950 
11951  default:
11952  {
11953  JSON_THROW(std::out_of_range("unresolved reference token '" + reference_token + "'"));
11954  }
11955  }
11956  }
11957 
11958  return *ptr;
11959  }
11960 
11961  const_reference get_checked(const_pointer ptr) const
11962  {
11963  for (const auto& reference_token : reference_tokens)
11964  {
11965  switch (ptr->m_type)
11966  {
11967  case value_t::object:
11968  {
11969  // note: at performs range check
11970  ptr = &ptr->at(reference_token);
11971  break;
11972  }
11973 
11974  case value_t::array:
11975  {
11976  if (reference_token == "-")
11977  {
11978  // "-" always fails the range check
11979  JSON_THROW(std::out_of_range("array index '-' (" +
11980  std::to_string(ptr->m_value.array->size()) +
11981  ") is out of range"));
11982  }
11983 
11984  // error condition (cf. RFC 6901, Sect. 4)
11985  if (reference_token.size() > 1 and reference_token[0] == '0')
11986  {
11987  JSON_THROW(std::domain_error("array index must not begin with '0'"));
11988  }
11989 
11990  // note: at performs range check
11991  ptr = &ptr->at(static_cast<size_type>(std::stoi(reference_token)));
11992  break;
11993  }
11994 
11995  default:
11996  {
11997  JSON_THROW(std::out_of_range("unresolved reference token '" + reference_token + "'"));
11998  }
11999  }
12000  }
12001 
12002  return *ptr;
12003  }
12004 
12006  static std::vector<std::string> split(const std::string& reference_string)
12007  {
12008  std::vector<std::string> result;
12009 
12010  // special case: empty reference string -> no reference tokens
12011  if (reference_string.empty())
12012  {
12013  return result;
12014  }
12015 
12016  // check if nonempty reference string begins with slash
12017  if (reference_string[0] != '/')
12018  {
12019  JSON_THROW(std::domain_error("JSON pointer must be empty or begin with '/'"));
12020  }
12021 
12022  // extract the reference tokens:
12023  // - slash: position of the last read slash (or end of string)
12024  // - start: position after the previous slash
12025  for (
12026  // search for the first slash after the first character
12027  size_t slash = reference_string.find_first_of('/', 1),
12028  // set the beginning of the first reference token
12029  start = 1;
12030  // we can stop if start == string::npos+1 = 0
12031  start != 0;
12032  // set the beginning of the next reference token
12033  // (will eventually be 0 if slash == std::string::npos)
12034  start = slash + 1,
12035  // find next slash
12036  slash = reference_string.find_first_of('/', start))
12037  {
12038  // use the text between the beginning of the reference token
12039  // (start) and the last slash (slash).
12040  auto reference_token = reference_string.substr(start, slash - start);
12041 
12042  // check reference tokens are properly escaped
12043  for (size_t pos = reference_token.find_first_of('~');
12044  pos != std::string::npos;
12045  pos = reference_token.find_first_of('~', pos + 1))
12046  {
12047  assert(reference_token[pos] == '~');
12048 
12049  // ~ must be followed by 0 or 1
12050  if (pos == reference_token.size() - 1 or
12051  (reference_token[pos + 1] != '0' and
12052  reference_token[pos + 1] != '1'))
12053  {
12054  JSON_THROW(std::domain_error("escape error: '~' must be followed with '0' or '1'"));
12055  }
12056  }
12057 
12058  // finally, store the reference token
12059  unescape(reference_token);
12060  result.push_back(reference_token);
12061  }
12062 
12063  return result;
12064  }
12065 
12066  private:
12079  static void replace_substring(std::string& s,
12080  const std::string& f,
12081  const std::string& t)
12082  {
12083  assert(not f.empty());
12084 
12085  for (
12086  size_t pos = s.find(f); // find first occurrence of f
12087  pos != std::string::npos; // make sure f was found
12088  s.replace(pos, f.size(), t), // replace with t
12089  pos = s.find(f, pos + t.size()) // find next occurrence of f
12090  );
12091  }
12092 
12094  static std::string escape(std::string s)
12095  {
12096  // escape "~"" to "~0" and "/" to "~1"
12097  replace_substring(s, "~", "~0");
12098  replace_substring(s, "/", "~1");
12099  return s;
12100  }
12101 
12103  static void unescape(std::string& s)
12104  {
12105  // first transform any occurrence of the sequence '~1' to '/'
12106  replace_substring(s, "~1", "/");
12107  // then transform any occurrence of the sequence '~0' to '~'
12108  replace_substring(s, "~0", "~");
12109  }
12110 
12118  static void flatten(const std::string& reference_string,
12119  const basic_json& value,
12120  basic_json& result)
12121  {
12122  switch (value.m_type)
12123  {
12124  case value_t::array:
12125  {
12126  if (value.m_value.array->empty())
12127  {
12128  // flatten empty array as null
12129  result[reference_string] = nullptr;
12130  }
12131  else
12132  {
12133  // iterate array and use index as reference string
12134  for (size_t i = 0; i < value.m_value.array->size(); ++i)
12135  {
12136  flatten(reference_string + "/" + std::to_string(i),
12137  value.m_value.array->operator[](i), result);
12138  }
12139  }
12140  break;
12141  }
12142 
12143  case value_t::object:
12144  {
12145  if (value.m_value.object->empty())
12146  {
12147  // flatten empty object as null
12148  result[reference_string] = nullptr;
12149  }
12150  else
12151  {
12152  // iterate object and use keys as reference string
12153  for (const auto& element : *value.m_value.object)
12154  {
12155  flatten(reference_string + "/" + escape(element.first),
12156  element.second, result);
12157  }
12158  }
12159  break;
12160  }
12161 
12162  default:
12163  {
12164  // add primitive value with its reference string
12165  result[reference_string] = value;
12166  break;
12167  }
12168  }
12169  }
12170 
12176  static basic_json unflatten(const basic_json& value)
12177  {
12178  if (not value.is_object())
12179  {
12180  JSON_THROW(std::domain_error("only objects can be unflattened"));
12181  }
12182 
12183  basic_json result;
12184 
12185  // iterate the JSON object values
12186  for (const auto& element : *value.m_value.object)
12187  {
12188  if (not element.second.is_primitive())
12189  {
12190  JSON_THROW(std::domain_error("values in object must be primitive"));
12191  }
12192 
12193  // assign value to reference pointed to by JSON pointer; Note
12194  // that if the JSON pointer is "" (i.e., points to the whole
12195  // value), function get_and_create returns a reference to
12196  // result itself. An assignment will then create a primitive
12197  // value.
12198  json_pointer(element.first).get_and_create(result) = element.second;
12199  }
12200 
12201  return result;
12202  }
12203 
12204  private:
12205  friend bool operator==(json_pointer const& lhs,
12206  json_pointer const& rhs) noexcept
12207  {
12208  return lhs.reference_tokens == rhs.reference_tokens;
12209  }
12210 
12211  friend bool operator!=(json_pointer const& lhs,
12212  json_pointer const& rhs) noexcept
12213  {
12214  return !(lhs == rhs);
12215  }
12216 
12218  std::vector<std::string> reference_tokens {};
12219  };
12220 
12222  // JSON Pointer support //
12224 
12227 
12262  {
12263  return ptr.get_unchecked(this);
12264  }
12265 
12289  {
12290  return ptr.get_unchecked(this);
12291  }
12292 
12314  {
12315  return ptr.get_checked(this);
12316  }
12317 
12338  const_reference at(const json_pointer& ptr) const
12339  {
12340  return ptr.get_checked(this);
12341  }
12342 
12366  {
12367  basic_json result(value_t::object);
12368  json_pointer::flatten("", *this, result);
12369  return result;
12370  }
12371 
12400  {
12401  return json_pointer::unflatten(*this);
12402  }
12403 
12405 
12407  // JSON Patch functions //
12409 
12412 
12449  basic_json patch(const basic_json& json_patch) const
12450  {
12451  // make a working copy to apply the patch to
12452  basic_json result = *this;
12453 
12454  // the valid JSON Patch operations
12455  enum class patch_operations {add, remove, replace, move, copy, test, invalid};
12456 
12457  const auto get_op = [](const std::string op)
12458  {
12459  if (op == "add")
12460  {
12461  return patch_operations::add;
12462  }
12463  if (op == "remove")
12464  {
12465  return patch_operations::remove;
12466  }
12467  if (op == "replace")
12468  {
12469  return patch_operations::replace;
12470  }
12471  if (op == "move")
12472  {
12473  return patch_operations::move;
12474  }
12475  if (op == "copy")
12476  {
12477  return patch_operations::copy;
12478  }
12479  if (op == "test")
12480  {
12481  return patch_operations::test;
12482  }
12483 
12484  return patch_operations::invalid;
12485  };
12486 
12487  // wrapper for "add" operation; add value at ptr
12488  const auto operation_add = [&result](json_pointer & ptr, basic_json val)
12489  {
12490  // adding to the root of the target document means replacing it
12491  if (ptr.is_root())
12492  {
12493  result = val;
12494  }
12495  else
12496  {
12497  // make sure the top element of the pointer exists
12498  json_pointer top_pointer = ptr.top();
12499  if (top_pointer != ptr)
12500  {
12501  result.at(top_pointer);
12502  }
12503 
12504  // get reference to parent of JSON pointer ptr
12505  const auto last_path = ptr.pop_back();
12506  basic_json& parent = result[ptr];
12507 
12508  switch (parent.m_type)
12509  {
12510  case value_t::null:
12511  case value_t::object:
12512  {
12513  // use operator[] to add value
12514  parent[last_path] = val;
12515  break;
12516  }
12517 
12518  case value_t::array:
12519  {
12520  if (last_path == "-")
12521  {
12522  // special case: append to back
12523  parent.push_back(val);
12524  }
12525  else
12526  {
12527  const auto idx = std::stoi(last_path);
12528  if (static_cast<size_type>(idx) > parent.size())
12529  {
12530  // avoid undefined behavior
12531  JSON_THROW(std::out_of_range("array index " + std::to_string(idx) + " is out of range"));
12532  }
12533  else
12534  {
12535  // default case: insert add offset
12536  parent.insert(parent.begin() + static_cast<difference_type>(idx), val);
12537  }
12538  }
12539  break;
12540  }
12541 
12542  default:
12543  {
12544  // if there exists a parent it cannot be primitive
12545  assert(false); // LCOV_EXCL_LINE
12546  }
12547  }
12548  }
12549  };
12550 
12551  // wrapper for "remove" operation; remove value at ptr
12552  const auto operation_remove = [&result](json_pointer & ptr)
12553  {
12554  // get reference to parent of JSON pointer ptr
12555  const auto last_path = ptr.pop_back();
12556  basic_json& parent = result.at(ptr);
12557 
12558  // remove child
12559  if (parent.is_object())
12560  {
12561  // perform range check
12562  auto it = parent.find(last_path);
12563  if (it != parent.end())
12564  {
12565  parent.erase(it);
12566  }
12567  else
12568  {
12569  JSON_THROW(std::out_of_range("key '" + last_path + "' not found"));
12570  }
12571  }
12572  else if (parent.is_array())
12573  {
12574  // note erase performs range check
12575  parent.erase(static_cast<size_type>(std::stoi(last_path)));
12576  }
12577  };
12578 
12579  // type check
12580  if (not json_patch.is_array())
12581  {
12582  // a JSON patch must be an array of objects
12583  JSON_THROW(std::invalid_argument("JSON patch must be an array of objects"));
12584  }
12585 
12586  // iterate and apply the operations
12587  for (const auto& val : json_patch)
12588  {
12589  // wrapper to get a value for an operation
12590  const auto get_value = [&val](const std::string & op,
12591  const std::string & member,
12592  bool string_type) -> basic_json&
12593  {
12594  // find value
12595  auto it = val.m_value.object->find(member);
12596 
12597  // context-sensitive error message
12598  const auto error_msg = (op == "op") ? "operation" : "operation '" + op + "'";
12599 
12600  // check if desired value is present
12601  if (it == val.m_value.object->end())
12602  {
12603  JSON_THROW(std::invalid_argument(error_msg + " must have member '" + member + "'"));
12604  }
12605 
12606  // check if result is of type string
12607  if (string_type and not it->second.is_string())
12608  {
12609  JSON_THROW(std::invalid_argument(error_msg + " must have string member '" + member + "'"));
12610  }
12611 
12612  // no error: return value
12613  return it->second;
12614  };
12615 
12616  // type check
12617  if (not val.is_object())
12618  {
12619  JSON_THROW(std::invalid_argument("JSON patch must be an array of objects"));
12620  }
12621 
12622  // collect mandatory members
12623  const std::string op = get_value("op", "op", true);
12624  const std::string path = get_value(op, "path", true);
12625  json_pointer ptr(path);
12626 
12627  switch (get_op(op))
12628  {
12629  case patch_operations::add:
12630  {
12631  operation_add(ptr, get_value("add", "value", false));
12632  break;
12633  }
12634 
12635  case patch_operations::remove:
12636  {
12637  operation_remove(ptr);
12638  break;
12639  }
12640 
12641  case patch_operations::replace:
12642  {
12643  // the "path" location must exist - use at()
12644  result.at(ptr) = get_value("replace", "value", false);
12645  break;
12646  }
12647 
12648  case patch_operations::move:
12649  {
12650  const std::string from_path = get_value("move", "from", true);
12651  json_pointer from_ptr(from_path);
12652 
12653  // the "from" location must exist - use at()
12654  basic_json v = result.at(from_ptr);
12655 
12656  // The move operation is functionally identical to a
12657  // "remove" operation on the "from" location, followed
12658  // immediately by an "add" operation at the target
12659  // location with the value that was just removed.
12660  operation_remove(from_ptr);
12661  operation_add(ptr, v);
12662  break;
12663  }
12664 
12665  case patch_operations::copy:
12666  {
12667  const std::string from_path = get_value("copy", "from", true);;
12668  const json_pointer from_ptr(from_path);
12669 
12670  // the "from" location must exist - use at()
12671  result[ptr] = result.at(from_ptr);
12672  break;
12673  }
12674 
12675  case patch_operations::test:
12676  {
12677  bool success = false;
12678  JSON_TRY
12679  {
12680  // check if "value" matches the one at "path"
12681  // the "path" location must exist - use at()
12682  success = (result.at(ptr) == get_value("test", "value", false));
12683  }
12684  JSON_CATCH (std::out_of_range&)
12685  {
12686  // ignore out of range errors: success remains false
12687  }
12688 
12689  // throw an exception if test fails
12690  if (not success)
12691  {
12692  JSON_THROW(std::domain_error("unsuccessful: " + val.dump()));
12693  }
12694 
12695  break;
12696  }
12697 
12698  case patch_operations::invalid:
12699  {
12700  // op must be "add", "remove", "replace", "move", "copy", or
12701  // "test"
12702  JSON_THROW(std::invalid_argument("operation value '" + op + "' is invalid"));
12703  }
12704  }
12705  }
12706 
12707  return result;
12708  }
12709 
12742  static basic_json diff(const basic_json& source,
12743  const basic_json& target,
12744  const std::string& path = "")
12745  {
12746  // the patch
12747  basic_json result(value_t::array);
12748 
12749  // if the values are the same, return empty patch
12750  if (source == target)
12751  {
12752  return result;
12753  }
12754 
12755  if (source.type() != target.type())
12756  {
12757  // different types: replace value
12758  result.push_back(
12759  {
12760  {"op", "replace"},
12761  {"path", path},
12762  {"value", target}
12763  });
12764  }
12765  else
12766  {
12767  switch (source.type())
12768  {
12769  case value_t::array:
12770  {
12771  // first pass: traverse common elements
12772  size_t i = 0;
12773  while (i < source.size() and i < target.size())
12774  {
12775  // recursive call to compare array values at index i
12776  auto temp_diff = diff(source[i], target[i], path + "/" + std::to_string(i));
12777  result.insert(result.end(), temp_diff.begin(), temp_diff.end());
12778  ++i;
12779  }
12780 
12781  // i now reached the end of at least one array
12782  // in a second pass, traverse the remaining elements
12783 
12784  // remove my remaining elements
12785  const auto end_index = static_cast<difference_type>(result.size());
12786  while (i < source.size())
12787  {
12788  // add operations in reverse order to avoid invalid
12789  // indices
12790  result.insert(result.begin() + end_index, object(
12791  {
12792  {"op", "remove"},
12793  {"path", path + "/" + std::to_string(i)}
12794  }));
12795  ++i;
12796  }
12797 
12798  // add other remaining elements
12799  while (i < target.size())
12800  {
12801  result.push_back(
12802  {
12803  {"op", "add"},
12804  {"path", path + "/" + std::to_string(i)},
12805  {"value", target[i]}
12806  });
12807  ++i;
12808  }
12809 
12810  break;
12811  }
12812 
12813  case value_t::object:
12814  {
12815  // first pass: traverse this object's elements
12816  for (auto it = source.begin(); it != source.end(); ++it)
12817  {
12818  // escape the key name to be used in a JSON patch
12819  const auto key = json_pointer::escape(it.key());
12820 
12821  if (target.find(it.key()) != target.end())
12822  {
12823  // recursive call to compare object values at key it
12824  auto temp_diff = diff(it.value(), target[it.key()], path + "/" + key);
12825  result.insert(result.end(), temp_diff.begin(), temp_diff.end());
12826  }
12827  else
12828  {
12829  // found a key that is not in o -> remove it
12830  result.push_back(object(
12831  {
12832  {"op", "remove"},
12833  {"path", path + "/" + key}
12834  }));
12835  }
12836  }
12837 
12838  // second pass: traverse other object's elements
12839  for (auto it = target.begin(); it != target.end(); ++it)
12840  {
12841  if (source.find(it.key()) == source.end())
12842  {
12843  // found a key that is not in this -> add it
12844  const auto key = json_pointer::escape(it.key());
12845  result.push_back(
12846  {
12847  {"op", "add"},
12848  {"path", path + "/" + key},
12849  {"value", it.value()}
12850  });
12851  }
12852  }
12853 
12854  break;
12855  }
12856 
12857  default:
12858  {
12859  // both primitive type: replace value
12860  result.push_back(
12861  {
12862  {"op", "replace"},
12863  {"path", path},
12864  {"value", target}
12865  });
12866  break;
12867  }
12868  }
12869  }
12870 
12871  return result;
12872  }
12873 
12875 };
12876 
12878 // presets //
12880 
12890 } // namespace nlohmann
12891 
12892 
12894 // nonmember support //
12896 
12897 // specialization of std::swap, and std::hash
12898 namespace std
12899 {
12905 template<>
12906 inline void swap(nlohmann::json& j1,
12907  nlohmann::json& j2) noexcept(
12908  is_nothrow_move_constructible<nlohmann::json>::value and
12909  is_nothrow_move_assignable<nlohmann::json>::value
12910  )
12911 {
12912  j1.swap(j2);
12913 }
12914 
12916 template<>
12917 struct hash<nlohmann::json>
12918 {
12924  std::size_t operator()(const nlohmann::json& j) const
12925  {
12926  // a naive hashing via the string representation
12927  const auto& h = hash<nlohmann::json::string_t>();
12928  return h(j.dump());
12929  }
12930 };
12931 } // namespace std
12932 
12946 inline nlohmann::json operator "" _json(const char* s, std::size_t n)
12947 {
12948  return nlohmann::json::parse(s, s + n);
12949 }
12950 
12964 inline nlohmann::json::json_pointer operator "" _json_pointer(const char* s, std::size_t n)
12965 {
12967 }
12968 
12969 // clean up
12970 #undef JSON_CATCH
12971 #undef JSON_DEPRECATED
12972 #undef JSON_THROW
12973 #undef JSON_TRY
12974 
12975 #endif
reference operator+=(basic_json &&val)
add an object to an array
Definition: json.hpp:5261
reference operator[](T *key)
access specified object element
Definition: json.hpp:3932
ReferenceType get_ref()
get a reference value (implicit)
Definition: json.hpp:3415
object_t::key_type key() const
return the key of an object iterator
Definition: json.hpp:9509
iterator insert(const_iterator pos, size_type cnt, const basic_json &val)
inserts elements
Definition: json.hpp:5570
json_reverse_iterator operator--(int)
post-decrement (it–)
Definition: json.hpp:9461
iter_impl(pointer object) noexcept
constructor for a given JSON instance
Definition: json.hpp:8849
basic_json flatten() const
return flattened JSON value
Definition: json.hpp:12365
void swap(object_t &other)
exchanges the values
Definition: json.hpp:5780
const_reference at(const typename object_t::key_type &key) const
access specified object element with bounds checking
Definition: json.hpp:3645
typename std::conditional< std::is_const< U >::value, typename basic_json::const_reference, typename basic_json::reference >::type reference
defines a reference to the type iterated over (value_type)
Definition: json.hpp:8836
static void construct(BasicJsonType &j, typename BasicJsonType::number_integer_t val) noexcept
Definition: json.hpp:281
std::integral_constant< bool, std::is_convertible< T, int >::value and std::is_enum< T >::value > is_unscoped_enum
Definition: json.hpp:188
basic_json value_type
the type of elements in a basic_json container
Definition: json.hpp:1044
static basic_json object(std::initializer_list< basic_json > init=std::initializer_list< basic_json >())
explicitly create an object from an initializer list
Definition: json.hpp:2182
constexpr bool is_number_integer() const noexcept
return whether value is an integer number
Definition: json.hpp:2818
difference_type operator-(const iter_impl &other) const
return difference
Definition: json.hpp:9319
reference operator[](const typename object_t::key_type &key)
access specified object element
Definition: json.hpp:3775
const_reference operator[](const typename object_t::key_type &key) const
read-only access specified object element
Definition: json.hpp:3824
const_reference operator[](size_type idx) const
access specified array element
Definition: json.hpp:3737
friend bool operator<(const_reference lhs, const_reference rhs) noexcept
comparison: less than
Definition: json.hpp:6023
string_t dump(const int indent=-1) const
serialization
Definition: json.hpp:2624
#define JSON_CATCH(exception)
Definition: json.hpp:77
iter_impl & operator++()
pre-increment (++it)
Definition: json.hpp:9080
reference at(const json_pointer &ptr)
access specified element via JSON Pointer
Definition: json.hpp:12313
static void construct(BasicJsonType &j, typename BasicJsonType::boolean_t b) noexcept
Definition: json.hpp:225
reference operator[](difference_type n) const
access to successor
Definition: json.hpp:9346
friend bool operator==(json_pointer const &lhs, json_pointer const &rhs) noexcept
Definition: json.hpp:12205
const_reference at(size_type idx) const
access specified array element with bounds checking
Definition: json.hpp:3551
basic_json(InputIT first, InputIT last)
construct a JSON container given an iterator range
Definition: json.hpp:2253
typename std::allocator_traits< allocator_type >::pointer pointer
the type of an element pointer
Definition: json.hpp:1060
constexpr bool is_primitive() const noexcept
return whether type is primitive
Definition: json.hpp:2688
iter_impl(const iter_impl &other) noexcept
copy constructor
Definition: json.hpp:8902
const_reverse_iterator crbegin() const noexcept
returns a const reverse iterator to the last element
Definition: json.hpp:4862
bool operator<=(const iter_impl &other) const
comparison: less than or equal
Definition: json.hpp:9230
ValueType value(const typename object_t::key_type &key, ValueType default_value) const
access specified object element with default value
Definition: json.hpp:4044
friend bool operator!=(json_pointer const &lhs, json_pointer const &rhs) noexcept
Definition: json.hpp:12211
bool empty() const noexcept
checks whether the container is empty
Definition: json.hpp:4972
basic_json(std::nullptr_t=nullptr) noexcept
create a null object
Definition: json.hpp:1917
static void construct(BasicJsonType &j, const typename BasicJsonType::string_t &s)
Definition: json.hpp:237
iter_impl operator++(int)
post-increment (it++)
Definition: json.hpp:9069
static iteration_proxy< iterator > iterator_wrapper(reference cont)
wrapper to access iterator member functions in range-based for
Definition: json.hpp:4912
size_type count(typename object_t::key_type key) const
returns the number of occurrences of a key in a JSON object
Definition: json.hpp:4607
size_type size() const noexcept
returns the number of elements
Definition: json.hpp:5040
iter_impl & operator+=(difference_type i)
add to iterator
Definition: json.hpp:9257
void erase(const size_type idx)
remove element from a JSON array given an index
Definition: json.hpp:4508
json_reverse_iterator operator+(difference_type i) const
add to iterator
Definition: json.hpp:9481
a class to store JSON values
Definition: json.hpp:1016
iterator begin() noexcept
returns an iterator to the first element
Definition: json.hpp:4647
void from_json_array_impl(const BasicJsonType &j, CompatibleArrayType &arr, priority_tag< 0 >)
Definition: json.hpp:692
const_iterator find(typename object_t::key_type key) const
find an element in a JSON object
Definition: json.hpp:4574
static basic_json parse(std::istream &i, const parser_callback_t cb=nullptr)
deserialize from stream
Definition: json.hpp:6329
default JSONSerializer template argument
Definition: json.hpp:888
constexpr bool is_null() const noexcept
return whether value is null
Definition: json.hpp:2737
iter_impl & operator=(iter_impl other) noexcept(std::is_nothrow_move_constructible< pointer >::value and std::is_nothrow_move_assignable< pointer >::value and std::is_nothrow_move_constructible< internal_iterator >::value and std::is_nothrow_move_assignable< internal_iterator >::value)
copy assignment
Definition: json.hpp:8911
friend std::ostream & operator<<(std::ostream &o, const basic_json &j)
serialize to stream
Definition: json.hpp:6199
PointerType get_ptr() noexcept
get a pointer value (implicit)
Definition: json.hpp:3338
const_reference back() const
access the last element
Definition: json.hpp:4222
void swap(nlohmann::json &j1, nlohmann::json &j2) noexcept(is_nothrow_move_constructible< nlohmann::json >::value and is_nothrow_move_assignable< nlohmann::json >::value)
exchanges the values of two JSON objects
Definition: json.hpp:12906
reference front()
access the first element
Definition: json.hpp:4169
const_iterator cend() const noexcept
returns a const iterator to one past the last element
Definition: json.hpp:4758
AllocatorType< basic_json > allocator_type
the allocator type
Definition: json.hpp:1057
static basic_json array(std::initializer_list< basic_json > init=std::initializer_list< basic_json >())
explicitly create an array from an initializer list
Definition: json.hpp:2142
ArrayType< basic_json, AllocatorType< basic_json > > array_t
a type for an array
Definition: json.hpp:1305
JSONSerializer< T, SFINAE > json_serializer
Definition: json.hpp:1032
Definition: json.hpp:12898
reference value() const
return the value of an iterator
Definition: json.hpp:9399
static void construct(BasicJsonType &j, const CompatibleObjectType &obj)
Definition: json.hpp:329
IteratorType erase(IteratorType pos)
remove element given an iterator
Definition: json.hpp:4278
object_t::key_type key() const
return the key of an object iterator
Definition: json.hpp:9383
bool operator<(const iter_impl &other) const
comparison: smaller
Definition: json.hpp:9197
friend bool operator!=(const ScalarType lhs, const_reference rhs) noexcept
comparison: not equal
Definition: json.hpp:5994
typename std::allocator_traits< allocator_type >::const_pointer const_pointer
the type of an element const pointer
Definition: json.hpp:1062
iterator find(typename object_t::key_type key)
find an element in a JSON object
Definition: json.hpp:4558
basic_json unflatten() const
unflatten a previously flattened JSON value
Definition: json.hpp:12399
ObjectType< StringType, basic_json, std::less< StringType >, AllocatorType< std::pair< const StringType, basic_json > >> object_t
a type for an object
Definition: json.hpp:1259
basic_json patch(const basic_json &json_patch) const
applies a JSON patch
Definition: json.hpp:12449
typename std::enable_if< B, T >::type enable_if_t
Definition: json.hpp:179
friend bool operator==(const ScalarType lhs, const_reference rhs) noexcept
comparison: equal
Definition: json.hpp:5951
void get_arithmetic_value(const BasicJsonType &j, ArithmeticType &val)
Definition: json.hpp:581
discarded by the the parser callback function
void swap(string_t &other)
exchanges the values
Definition: json.hpp:5813
constexpr bool is_number_float() const noexcept
return whether value is a floating-point number
Definition: json.hpp:2874
static void construct(BasicJsonType &j, typename BasicJsonType::number_unsigned_t val) noexcept
Definition: json.hpp:269
json_reverse_iterator operator-(difference_type i) const
subtract from iterator
Definition: json.hpp:9489
iter_impl operator-(difference_type i)
subtract from iterator
Definition: json.hpp:9308
std::size_t operator()(const nlohmann::json &j) const
return a hash value for a JSON object
Definition: json.hpp:12924
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:4068
void to_json(BasicJsonType &j, T b) noexcept
Definition: json.hpp:505
std::string type_name() const
return the type as string
Definition: json.hpp:8042
void emplace_back(Args &&... args)
add an object to an array
Definition: json.hpp:5421
iter_impl & operator-=(difference_type i)
subtract from iterator
Definition: json.hpp:9288
constexpr bool is_structured() const noexcept
return whether type is structured
Definition: json.hpp:2715
static basic_json parse(IteratorType first, IteratorType last, const parser_callback_t cb=nullptr)
deserialize from an iterator range with contiguous storage
Definition: json.hpp:6389
std::pair< iterator, bool > emplace(Args &&... args)
add an object to an object if key does not exist
Definition: json.hpp:5469
iter_impl operator--(int)
post-decrement (it–)
Definition: json.hpp:9112
NLOHMANN_JSON_HAS_HELPER(mapped_type)
static void construct(BasicJsonType &j, const typename BasicJsonType::object_t &obj)
Definition: json.hpp:318
size_type erase(const typename object_t::key_type &key)
remove element from a JSON object given a key
Definition: json.hpp:4473
const_reference front() const
access the first element
Definition: json.hpp:4177
void push_back(basic_json &&val)
add an object to an array
Definition: json.hpp:5235
json_reverse_iterator & operator+=(difference_type i)
add to iterator
Definition: json.hpp:9474
ValueType value(const json_pointer &ptr, ValueType default_value) const
access specified object element via JSON Pointer with default value
Definition: json.hpp:4116
number value (signed integer)
iterator insert(const_iterator pos, const basic_json &val)
inserts element
Definition: json.hpp:5517
reference operator*() const
return a reference to the value pointed to by the iterator
Definition: json.hpp:8996
static void to_json(BasicJsonType &j, ValueType &&val) noexcept(noexcept(::nlohmann::to_json(j, std::forward< ValueType >(val))))
convert any value type to a JSON value
Definition: json.hpp:916
friend class basic_json
allow basic_json to access private members
Definition: json.hpp:8817
#define JSON_THROW(exception)
Definition: json.hpp:75
void swap(reference other) noexcept(std::is_nothrow_move_constructible< value_t >::value and std::is_nothrow_move_assignable< value_t >::value and std::is_nothrow_move_constructible< json_value >::value and std::is_nothrow_move_assignable< json_value >::value)
exchanges the values
Definition: json.hpp:5715
#define JSON_DEPRECATED
Definition: json.hpp:66
parse string into a built-in arithmetic type as if the current locale is POSIX.
Definition: json.hpp:11077
json_reverse_iterator operator++(int)
post-increment (it++)
Definition: json.hpp:9448
json_pointer(const std::string &s="")
create JSON pointer
Definition: json.hpp:11651
NumberUnsignedType number_unsigned_t
a type for a number (unsigned)
Definition: json.hpp:1527
reverse_iterator rbegin() noexcept
returns an iterator to the reverse-beginning
Definition: json.hpp:4788
JSON_DEPRECATED basic_json(std::istream &i, const parser_callback_t cb=nullptr)
construct a JSON value given an input stream
Definition: json.hpp:2373
friend bool operator==(const_reference lhs, const ScalarType rhs) noexcept
comparison: equal
Definition: json.hpp:5940
constexpr bool is_object() const noexcept
return whether value is an object
Definition: json.hpp:2896
~basic_json()
destructor
Definition: json.hpp:2552
bool operator<(const value_t lhs, const value_t rhs) noexcept
comparison operator for JSON types
Definition: json.hpp:148
json_reverse_iterator & operator--()
pre-decrement (–it)
Definition: json.hpp:9467
json_reverse_iterator(const typename base_iterator::iterator_type &it) noexcept
create reverse iterator from iterator
Definition: json.hpp:9438
namespace for Niels Lohmann
Definition: json.hpp:85
static basic_json from_msgpack(const std::vector< uint8_t > &v, const size_t start_index=0)
create a JSON value from a byte vector in MessagePack format
Definition: json.hpp:7951
void push_back(const typename object_t::value_type &val)
add an object to an object
Definition: json.hpp:5321
constexpr bool is_string() const noexcept
return whether value is a string
Definition: json.hpp:2940
iter_impl & operator--()
pre-decrement (–it)
Definition: json.hpp:9123
reference at(size_type idx)
access specified array element with bounds checking
Definition: json.hpp:3508
const_iterator end() const noexcept
returns a const iterator to one past the last element
Definition: json.hpp:4728
static std::vector< uint8_t > to_cbor(const basic_json &j)
create a MessagePack serialization of a given JSON value
Definition: json.hpp:7981
static basic_json meta()
returns version information on the library
Definition: json.hpp:1107
basic_json(const basic_json &other)
copy constructor
Definition: json.hpp:2405
size_type max_size() const noexcept
returns the maximum possible number of elements
Definition: json.hpp:5106
friend std::istream & operator>>(std::istream &i, basic_json &j)
deserialize from stream
Definition: json.hpp:6501
number value (unsigned integer)
const value_type & const_reference
the type of an element const reference
Definition: json.hpp:1049
friend bool operator==(const_reference lhs, const_reference rhs) noexcept
comparison: equal
Definition: json.hpp:5859
friend std::ostream & operator>>(const basic_json &j, std::ostream &o)
serialize to stream
Definition: json.hpp:6218
static void from_json(BasicJsonType &&j, ValueType &val) noexcept(noexcept(::nlohmann::from_json(std::forward< BasicJsonType >(j), val)))
convert a JSON value to any value type
Definition: json.hpp:900
friend std::istream & operator<<(basic_json &j, std::istream &i)
deserialize from stream
Definition: json.hpp:6491
constexpr bool is_discarded() const noexcept
return whether value is discarded
Definition: json.hpp:2967
const_reference at(const json_pointer &ptr) const
access specified element via JSON Pointer
Definition: json.hpp:12338
reverse_iterator rend() noexcept
returns an iterator to the reverse-end
Definition: json.hpp:4825
basic_json(basic_json &&other) noexcept
move constructor
Definition: json.hpp:2482
void push_back(const basic_json &val)
add an object to an array
Definition: json.hpp:5271
typename Base::reference reference
the reference type for the pointed-to element
Definition: json.hpp:9435
basic_json(const value_t value_type)
create an empty value with a given type
Definition: json.hpp:1893
ReferenceType get_ref() const
get a reference value (implicit)
Definition: json.hpp:3428
constexpr value_t type() const noexcept
return the type of the JSON value (explicit)
Definition: json.hpp:2658
char buf[1024]
Definition: ethernet.c:91
#define JSON_TRY
Definition: json.hpp:76
pointer operator->() const
dereference the iterator
Definition: json.hpp:9035
StringType string_t
a type for a string
Definition: json.hpp:1358
string_t value(const json_pointer &ptr, const char *default_value) const
overload for a default value of type const char*
Definition: json.hpp:4139
bool operator>=(const iter_impl &other) const
comparison: greater than or equal
Definition: json.hpp:9248
static std::vector< uint8_t > to_msgpack(const basic_json &j)
create a MessagePack serialization of a given JSON value
Definition: json.hpp:7918
const_reverse_iterator rend() const noexcept
returns a const reverse iterator to one before the first
Definition: json.hpp:4833
reference at(const typename object_t::key_type &key)
access specified object element with bounds checking
Definition: json.hpp:3598
reference operator[](T *(&key)[n])
access specified object element
Definition: json.hpp:3864
friend bool operator>(const_reference lhs, const_reference rhs) noexcept
comparison: greater than
Definition: json.hpp:6140
void from_json(const BasicJsonType &j, ArithmeticType &val)
Definition: json.hpp:776
static void construct(BasicJsonType &j, const CompatibleArrayType &arr)
Definition: json.hpp:304
const_reference operator[](T *key) const
read-only access specified object element
Definition: json.hpp:3982
static basic_json parse(T(&array)[N], const parser_callback_t cb=nullptr)
deserialize from an array
Definition: json.hpp:6261
NumberIntegerType number_integer_t
a type for a number (integer)
Definition: json.hpp:1456
int16_t half
half is a 16-bit IEEE floating-point standard number format.
void push_back(std::initializer_list< basic_json > init)
add an object to an object
Definition: json.hpp:5376
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:1983
reference & operator=(basic_json other) noexcept(std::is_nothrow_move_constructible< value_t >::value and std::is_nothrow_move_assignable< value_t >::value and std::is_nothrow_move_constructible< json_value >::value and std::is_nothrow_move_assignable< json_value >::value)
copy assignment
Definition: json.hpp:2519
iterator insert(const_iterator pos, const_iterator first, const_iterator last)
inserts elements
Definition: json.hpp:5620
static basic_json from_cbor(const std::vector< uint8_t > &v, const size_t start_index=0)
create a JSON value from a byte vector in CBOR format
Definition: json.hpp:8014
static basic_json parse(const ContiguousContainer &c, const parser_callback_t cb=nullptr)
deserialize from a container with contiguous storage
Definition: json.hpp:6461
static void construct(BasicJsonType &j, const typename BasicJsonType::array_t &arr)
Definition: json.hpp:293
json_reverse_iterator & operator++()
pre-increment (++it)
Definition: json.hpp:9454
strtonum(const char *start, const char *end)
Definition: json.hpp:11080
std::size_t size_type
a type to represent container sizes
Definition: json.hpp:1054
object (unordered set of name/value pairs)
std::function< bool(int depth, parse_event_t event, basic_json &parsed)> parser_callback_t
per-element parser callback type
Definition: json.hpp:1854
parse_event_t
JSON callback events.
Definition: json.hpp:1784
iter_impl operator+(difference_type i)
add to iterator
Definition: json.hpp:9297
constexpr bool is_boolean() const noexcept
return whether value is a boolean
Definition: json.hpp:2759
constexpr bool is_number_unsigned() const noexcept
return whether value is an unsigned integer number
Definition: json.hpp:2846
const_reverse_iterator crend() const noexcept
returns a const reverse iterator to one before the first
Definition: json.hpp:4891
static 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:12742
static basic_json parse(std::istream &&i, const parser_callback_t cb=nullptr)
deserialize from stream
Definition: json.hpp:6338
reference operator[](difference_type n) const
access to successor
Definition: json.hpp:9503
constexpr const PointerType get_ptr() const noexcept
get a pointer value (implicit)
Definition: json.hpp:3366
json_reverse_iterator(const base_iterator &it) noexcept
create reverse iterator from base class
Definition: json.hpp:9443
iterator insert(const_iterator pos, basic_json &&val)
inserts element
Definition: json.hpp:5541
typename basic_json::value_type value_type
the type of the values when the iterator is dereferenced
Definition: json.hpp:8826
IteratorType erase(IteratorType first, IteratorType last)
remove elements given an iterator range
Definition: json.hpp:4385
reference operator+=(const typename object_t::value_type &val)
add an object to an object
Definition: json.hpp:5345
reference operator[](size_type idx)
access specified array element
Definition: json.hpp:3691
const_reference operator[](T *(&key)[n]) const
read-only access specified object element
Definition: json.hpp:3899
reference operator+=(std::initializer_list< basic_json > init)
add an object to an object
Definition: json.hpp:5393
bool operator==(const iter_impl &other) const
comparison: equal
Definition: json.hpp:9155
const_iterator begin() const noexcept
returns a const iterator to the first element
Definition: json.hpp:4657
std::ptrdiff_t difference_type
a type to represent differences between iterators
Definition: json.hpp:1052
const_iterator cbegin() const noexcept
returns a const iterator to the first element
Definition: json.hpp:4687
reference operator+=(const basic_json &val)
add an object to an array
Definition: json.hpp:5295
reference back()
access the last element
Definition: json.hpp:4212
reference operator[](const json_pointer &ptr)
access specified element via JSON Pointer
Definition: json.hpp:12261
iterator end() noexcept
returns an iterator to one past the last element
Definition: json.hpp:4718
friend bool operator!=(const_reference lhs, const ScalarType rhs) noexcept
comparison: not equal
Definition: json.hpp:5983
difference_type operator-(const json_reverse_iterator &other) const
return difference
Definition: json.hpp:9497
bool operator>(const iter_impl &other) const
comparison: greater than
Definition: json.hpp:9239
static basic_json parse(const CharT s, const parser_callback_t cb=nullptr)
deserialize from string literal
Definition: json.hpp:6299
def res
Definition: master.py:498
a template for a reverse iterator class
Definition: json.hpp:1029
constexpr bool is_array() const noexcept
return whether value is an array
Definition: json.hpp:2918
typename basic_json::difference_type difference_type
a type to represent differences between iterators
Definition: json.hpp:8828
basic_json(size_type cnt, const basic_json &val)
construct an array with count copies of given value
Definition: json.hpp:2206
number value (floating-point)
static allocator_type get_allocator()
returns the allocator associated with the container
Definition: json.hpp:1079
void from_json(const BasicJsonType &j, typename BasicJsonType::boolean_t &b)
Definition: json.hpp:612
std::reverse_iterator< Base > base_iterator
shortcut to the reverse iterator adaptor
Definition: json.hpp:9433
constexpr bool is_number() const noexcept
return whether value is a number
Definition: json.hpp:2789
const_reference operator[](const json_pointer &ptr) const
access specified element via JSON Pointer
Definition: json.hpp:12288
BooleanType boolean_t
a type for a boolean
Definition: json.hpp:1384
bool operator!=(const iter_impl &other) const
comparison: not equal
Definition: json.hpp:9188
std::string to_string() const noexcept
return a string representation of the JSON pointer
Definition: json.hpp:11670
void operator()(BasicJsonType &j, T &&val) const noexcept(noexcept(std::declval< to_json_fn >().call(j, std::forward< T >(val), priority_tag< 1 > {})))
Definition: json.hpp:826
void swap(array_t &other)
exchanges the values
Definition: json.hpp:5747
friend bool operator<=(const_reference lhs, const_reference rhs) noexcept
comparison: less than or equal
Definition: json.hpp:6118
basic_json(std::initializer_list< basic_json > 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:2059
friend bool operator>=(const_reference lhs, const_reference rhs) noexcept
comparison: greater than or equal
Definition: json.hpp:6162
NumberFloatType number_float_t
a type for a number (floating-point)
Definition: json.hpp:1595
friend bool operator!=(const_reference lhs, const_reference rhs) noexcept
comparison: not equal
Definition: json.hpp:5972
std::bidirectional_iterator_tag iterator_category
the category of the iterator
Definition: json.hpp:8838
array (ordered collection of values)
const_reverse_iterator rbegin() const noexcept
returns a const reverse iterator to the last element
Definition: json.hpp:4796
void to_json(BasicJsonType &j, const CompatibleObjectType &arr)
Definition: json.hpp:565
reference value() const
return the value of an iterator
Definition: json.hpp:9516
static void construct(BasicJsonType &j, typename BasicJsonType::number_float_t val) noexcept
Definition: json.hpp:249
a template for a random access iterator for the basic_json class
Definition: json.hpp:1028
value_t
the JSON type enumeration
Definition: json.hpp:126
typename std::remove_cv< typename std::remove_reference< T >::type >::type uncvref_t
Definition: json.hpp:182
void clear() noexcept
clears the contents
Definition: json.hpp:5162
void operator()(const BasicJsonType &j, T &val) const noexcept(noexcept(std::declval< from_json_fn >().call(j, val, priority_tag< 1 > {})))
Definition: json.hpp:853
typename std::conditional< std::is_const< U >::value, typename basic_json::const_pointer, typename basic_json::pointer >::type pointer
defines a pointer to the type iterated over (value_type)
Definition: json.hpp:8832
iterator insert(const_iterator pos, std::initializer_list< basic_json > ilist)
inserts elements
Definition: json.hpp:5678
static iteration_proxy< const_iterator > iterator_wrapper(const_reference cont)
wrapper to access iterator member functions in range-based for
Definition: json.hpp:4920