JSON for Modern C++  3.0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Groups
json.hpp
Go to the documentation of this file.
1 
30 #ifndef _NLOHMANN_JSON
31 #define _NLOHMANN_JSON
32 
33 #include <algorithm>
34 #include <cmath>
35 #include <cstdio>
36 #include <functional>
37 #include <initializer_list>
38 #include <iomanip>
39 #include <iostream>
40 #include <iterator>
41 #include <limits>
42 #include <map>
43 #include <memory>
44 #include <sstream>
45 #include <string>
46 #include <type_traits>
47 #include <utility>
48 #include <vector>
49 
54 namespace nlohmann
55 {
56 
57 
58 // Helper to determine whether there's a key_type for T.
59 // http://stackoverflow.com/a/7728728/266378
60 template<typename T>
62 {
63  private:
64  template<typename C> static char test(typename C::mapped_type*);
65  template<typename C> static int test(...);
66  public:
67  enum { value = sizeof(test<T>(0)) == sizeof(char) };
68 };
69 
93 template <
94  template<typename U, typename V, typename... Args> class ObjectType = std::map,
95  template<typename U, typename... Args> class ArrayType = std::vector,
96  class StringType = std::string,
97  class BooleanType = bool,
98  class NumberIntegerType = int64_t,
99  class NumberFloatType = double,
100  template<typename U> class Allocator = std::allocator
101  >
103 {
104  public:
106  // container types //
108 
109  // forward declarations
110  class iterator;
111  class const_iterator;
112  class reverse_iterator;
114 
120 
126 
131  using const_reference = const basic_json&;
132 
137  using difference_type = std::ptrdiff_t;
138 
143  using size_type = std::size_t;
144 
146  using allocator_type = Allocator<basic_json>;
147 
149  using pointer = basic_json*;
151  using const_pointer = const basic_json*;
152 
158 
164 
170 
176 
177 
180  {
181  return allocator_type();
182  }
183 
184 
186  // JSON value data types //
188 
190  using object_t = ObjectType<StringType, basic_json>;
192  using array_t = ArrayType<basic_json>;
194  using string_t = StringType;
196  using boolean_t = BooleanType;
198  using number_integer_t = NumberIntegerType;
200  using number_float_t = NumberFloatType;
202  using list_init_t = std::initializer_list<basic_json>;
203 
204 
206  // JSON value storage //
208 
211  {
224 
226  json_value() = default;
228  json_value(boolean_t v) : boolean(v) {}
230  json_value(number_integer_t v) : number_integer(v) {}
232  json_value(number_float_t v) : number_float(v) {}
233  };
234 
235 
237  // JSON value type enumeration //
239 
241  enum class value_t : uint8_t
242  {
243  null,
244  object,
245  array,
246  string,
247  boolean,
248  number_integer,
249  number_float
250  };
251 
259  friend bool operator<(const value_t lhs, const value_t rhs)
260  {
261  // no type is smaller than itself
262  if (lhs == rhs)
263  {
264  return false;
265  }
266 
267  switch (lhs)
268  {
269  case (value_t::null):
270  {
271  // nulls are smaller than all other types
272  return true;
273  }
274 
275  case (value_t::boolean):
276  {
277  // only nulls are smaller than booleans
278  return (rhs != value_t::null);
279  }
280 
281  case (value_t::number_float):
282  case (value_t::number_integer):
283  {
284  switch (rhs)
285  {
286  // numbers are smaller than objects, arrays, and string
287  case (value_t::object):
288  case (value_t::array):
289  case (value_t::string):
290  {
291  return true;
292  }
293 
294  default:
295  {
296  return false;
297  }
298  }
299  }
300 
301  case (value_t::object):
302  {
303  switch (rhs)
304  {
305  // objects are smaller than arrays and string
306  case (value_t::array):
307  case (value_t::string):
308  {
309  return true;
310  }
311 
312  default:
313  {
314  return false;
315  }
316  }
317  }
318 
319  case (value_t::array):
320  {
321  // arrays are smaller than strings
322  return (rhs == value_t::string);
323  }
324 
325  default:
326  {
327  // a string is not smaller than any other types
328  return false;
329  }
330  }
331  }
332 
333 
335  // constructors //
337 
344  inline basic_json(const value_t value)
345  : m_type(value)
346  {
347  switch (m_type)
348  {
349  case (value_t::null):
350  {
351  break;
352  }
353 
354  case (value_t::object):
355  {
356  Allocator<object_t> alloc;
357  m_value.object = alloc.allocate(1);
358  alloc.construct(m_value.object);
359  break;
360  }
361 
362  case (value_t::array):
363  {
364  Allocator<array_t> alloc;
365  m_value.array = alloc.allocate(1);
366  alloc.construct(m_value.array);
367  break;
368  }
369 
370  case (value_t::string):
371  {
372  Allocator<string_t> alloc;
373  m_value.string = alloc.allocate(1);
374  alloc.construct(m_value.string, "");
375  break;
376  }
377 
378  case (value_t::boolean):
379  {
380  m_value.boolean = boolean_t(false);
381  break;
382  }
383 
384  case (value_t::number_integer):
385  {
386  m_value.number_integer = number_integer_t(0);
387  break;
388  }
389 
390  case (value_t::number_float):
391  {
392  m_value.number_float = number_float_t(0.0);
393  break;
394  }
395  }
396  }
397 
402  inline basic_json() noexcept = default;
403 
405  inline basic_json(std::nullptr_t) noexcept
406  : m_type(value_t::null)
407  {}
408 
410  inline basic_json(const object_t& value)
411  : m_type(value_t::object)
412  {
413  Allocator<object_t> alloc;
414  m_value.object = alloc.allocate(1);
415  alloc.construct(m_value.object, value);
416  }
417 
419  template <class V, typename
420  std::enable_if<
421  std::is_constructible<typename object_t::key_type, typename V::key_type>::value and
422  std::is_constructible<basic_json, typename V::mapped_type>::value, int>::type
423  = 0>
424  inline basic_json(const V& value)
425  : m_type(value_t::object)
426  {
427  Allocator<object_t> alloc;
428  m_value.object = alloc.allocate(1);
429  using std::begin;
430  using std::end;
431  alloc.construct(m_value.object, begin(value), end(value));
432  }
433 
435  inline basic_json(const array_t& value)
436  : m_type(value_t::array)
437  {
438  Allocator<array_t> alloc;
439  m_value.array = alloc.allocate(1);
440  alloc.construct(m_value.array, value);
441  }
442 
444  template <class V, typename
445  std::enable_if<
446  not std::is_same<V, basic_json::iterator>::value and
447  not std::is_same<V, basic_json::const_iterator>::value and
448  not std::is_same<V, basic_json::reverse_iterator>::value and
449  not std::is_same<V, basic_json::const_reverse_iterator>::value and
450  not std::is_same<V, typename array_t::iterator>::value and
451  not std::is_same<V, typename array_t::const_iterator>::value and
452  std::is_constructible<basic_json, typename V::value_type>::value, int>::type
453  = 0>
454  inline basic_json(const V& value)
455  : m_type(value_t::array)
456  {
457  Allocator<array_t> alloc;
458  m_value.array = alloc.allocate(1);
459  using std::begin;
460  using std::end;
461  alloc.construct(m_value.array, begin(value), end(value));
462  }
463 
465  inline basic_json(const string_t& value)
466  : m_type(value_t::string)
467  {
468  Allocator<string_t> alloc;
469  m_value.string = alloc.allocate(1);
470  alloc.construct(m_value.string, value);
471  }
472 
474  inline basic_json(const typename string_t::value_type* value)
475  : m_type(value_t::string)
476  {
477  Allocator<string_t> alloc;
478  m_value.string = alloc.allocate(1);
479  alloc.construct(m_value.string, value);
480  }
481 
483  template <class V, typename
484  std::enable_if<
485  std::is_constructible<string_t, V>::value, int>::type
486  = 0>
487  inline basic_json(const V& value)
488  : basic_json(string_t(value))
489  {}
490 
493  : m_type(value_t::boolean), m_value(value)
494  {}
495 
498  : m_type(value_t::number_integer), m_value(value)
499  {}
500 
502  template<typename T, typename
503  std::enable_if<
504  std::is_constructible<number_integer_t, T>::value and
505  std::numeric_limits<T>::is_integer, T>::type
506  = 0>
507  inline basic_json(const T value) noexcept
508  : m_type(value_t::number_integer), m_value(number_integer_t(value))
509  {}
510 
513  : m_type(value_t::number_float), m_value(value)
514  {}
515 
517  template<typename T, typename = typename
518  std::enable_if<
519  std::is_constructible<number_float_t, T>::value and
520  std::is_floating_point<T>::value>::type
521  >
522  inline basic_json(const T value) noexcept
523  : m_type(value_t::number_float), m_value(number_float_t(value))
524  {}
525 
527  inline basic_json(list_init_t l, bool type_deduction = true, value_t manual_type = value_t::array)
528  {
529  // the initializer list could describe an object
530  bool is_object = true;
531 
532  // check if each element is an array with two elements whose first element
533  // is a string
534  for (const auto& element : l)
535  {
536  if ((element.m_final and element.m_type == value_t::array)
537  or (element.m_type != value_t::array or element.size() != 2
538  or element[0].m_type != value_t::string))
539  {
540  // we found an element that makes it impossible to use the
541  // initializer list as object
542  is_object = false;
543  break;
544  }
545  }
546 
547  // adjust type if type deduction is not wanted
548  if (not type_deduction)
549  {
550  // mark this object's type as final
551  m_final = true;
552 
553  // if array is wanted, do not create an object though possible
554  if (manual_type == value_t::array)
555  {
556  is_object = false;
557  }
558 
559  // if object is wanted but impossible, throw an exception
560  if (manual_type == value_t::object and not is_object)
561  {
562  throw std::logic_error("cannot create JSON object from initializer list");
563  }
564  }
565 
566  if (is_object)
567  {
568  // the initializer list is a list of pairs -> create object
569  m_type = value_t::object;
570  Allocator<object_t> alloc;
571  m_value.object = alloc.allocate(1);
572  alloc.construct(m_value.object);
573 
574  for (auto& element : l)
575  {
576  m_value.object->emplace(std::move(*(element[0].m_value.string)), std::move(element[1]));
577  }
578  }
579  else
580  {
581  // the initializer list describes an array -> create array
582  m_type = value_t::array;
583  Allocator<array_t> alloc;
584  m_value.array = alloc.allocate(1);
585  alloc.construct(m_value.array, std::move(l));
586  }
587  }
588 
591  {
592  return basic_json(l, false, value_t::array);
593  }
594 
597  {
598  return basic_json(l, false, value_t::object);
599  }
600 
601 
603  // other constructors and destructor //
605 
613  inline basic_json(const basic_json& other)
614  : m_type(other.m_type)
615  {
616  switch (m_type)
617  {
618  case (value_t::null):
619  {
620  break;
621  }
622 
623  case (value_t::object):
624  {
625  Allocator<object_t> alloc;
626  m_value.object = alloc.allocate(1);
627  alloc.construct(m_value.object, *other.m_value.object);
628  break;
629  }
630 
631  case (value_t::array):
632  {
633  Allocator<array_t> alloc;
634  m_value.array = alloc.allocate(1);
635  alloc.construct(m_value.array, *other.m_value.array);
636  break;
637  }
638 
639  case (value_t::string):
640  {
641  Allocator<string_t> alloc;
642  m_value.string = alloc.allocate(1);
643  alloc.construct(m_value.string, *other.m_value.string);
644  break;
645  }
646 
647  case (value_t::boolean):
648  {
649  m_value.boolean = other.m_value.boolean;
650  break;
651  }
652 
653  case (value_t::number_integer):
654  {
655  m_value.number_integer = other.m_value.number_integer;
656  break;
657  }
658 
659  case (value_t::number_float):
660  {
661  m_value.number_float = other.m_value.number_float;
662  break;
663  }
664  }
665  }
666 
668  inline basic_json(basic_json&& other) noexcept
669  : m_type(std::move(other.m_type)),
670  m_value(std::move(other.m_value))
671  {
672  // invalidate payload
673  other.m_type = value_t::null;
674  other.m_value = {};
675  }
676 
681  inline reference& operator=(basic_json other) noexcept (
682  std::is_nothrow_move_constructible<value_t>::value and
683  std::is_nothrow_move_assignable<value_t>::value and
684  std::is_nothrow_move_constructible<json_value>::value and
685  std::is_nothrow_move_assignable<json_value>::value
686  )
687  {
688  std::swap(m_type, other.m_type);
689  std::swap(m_value, other.m_value);
690  return *this;
691  }
692 
697  inline ~basic_json() noexcept
698  {
699  switch (m_type)
700  {
701  case (value_t::object):
702  {
703  Allocator<object_t> alloc;
704  alloc.destroy(m_value.object);
705  alloc.deallocate(m_value.object, 1);
706  m_value.object = nullptr;
707  break;
708  }
709 
710  case (value_t::array):
711  {
712  Allocator<array_t> alloc;
713  alloc.destroy(m_value.array);
714  alloc.deallocate(m_value.array, 1);
715  m_value.array = nullptr;
716  break;
717  }
718 
719  case (value_t::string):
720  {
721  Allocator<string_t> alloc;
722  alloc.destroy(m_value.string);
723  alloc.deallocate(m_value.string, 1);
724  m_value.string = nullptr;
725  break;
726  }
727 
728  default:
729  {
730  // all other types need no specific destructor
731  break;
732  }
733  }
734  }
735 
736 
737  public:
739  // object inspection //
741 
756  inline string_t dump(const int indent = -1) const noexcept
757  {
758  if (indent >= 0)
759  {
760  return dump(true, static_cast<unsigned int>(indent));
761  }
762  else
763  {
764  return dump(false, 0);
765  }
766  }
767 
769  inline value_t type() const noexcept
770  {
771  return m_type;
772  }
773 
774  // return whether value is null
775  inline bool is_null() const noexcept
776  {
777  return m_type == value_t::null;
778  }
779 
780  // return whether value is boolean
781  inline bool is_boolean() const noexcept
782  {
783  return m_type == value_t::boolean;
784  }
785 
786  // return whether value is number
787  inline bool is_number() const noexcept
788  {
789  return (m_type == value_t::number_integer) or (m_type == value_t::number_float);
790  }
791 
792  // return whether value is object
793  inline bool is_object() const noexcept
794  {
795  return m_type == value_t::object;
796  }
797 
798  // return whether value is array
799  inline bool is_array() const noexcept
800  {
801  return m_type == value_t::array;
802  }
803 
804  // return whether value is string
805  inline bool is_string() const noexcept
806  {
807  return m_type == value_t::string;
808  }
809 
811  inline operator value_t() const noexcept
812  {
813  return m_type;
814  }
815 
816  private:
818  // value conversion //
820 
822  template <class T, typename
823  std::enable_if<
824  std::is_convertible<typename object_t::key_type, typename T::key_type>::value and
825  std::is_convertible<basic_json, typename T::mapped_type>::value
826  , int>::type = 0>
827  inline T get_impl(T*) const
828  {
829  switch (m_type)
830  {
831  case (value_t::object):
832  {
833  return T(m_value.object->begin(), m_value.object->end());
834  }
835  default:
836  {
837  throw std::logic_error("cannot cast " + type_name() + " to " + typeid(T).name());
838  }
839  }
840  }
841 
843  inline object_t get_impl(object_t*) const
844  {
845  switch (m_type)
846  {
847  case (value_t::object):
848  {
849  return *(m_value.object);
850  }
851  default:
852  {
853  throw std::logic_error("cannot cast " + type_name() + " to object");
854  }
855  }
856  }
857 
859  template <class T, typename
860  std::enable_if<
861  std::is_convertible<basic_json, typename T::value_type>::value and
862  not std::is_same<basic_json, typename T::value_type>::value and
863  not std::is_arithmetic<T>::value and
864  not std::is_convertible<std::string, T>::value and
866  , int>::type = 0>
867  inline T get_impl(T*) const
868  {
869  switch (m_type)
870  {
871  case (value_t::array):
872  {
873  T to_vector;
874  //to_vector.reserve(m_value.array->size());
875  std::transform(m_value.array->begin(), m_value.array->end(),
876  std::inserter(to_vector, to_vector.end()), [](basic_json i)
877  {
878  return i.get<typename T::value_type>();
879  });
880  return to_vector;
881 
882  // return T(m_value.array->begin(), m_value.array->end());
883  }
884  default:
885  {
886  throw std::logic_error("cannot cast " + type_name() + " to " + typeid(T).name());
887  }
888  }
889  }
890 
892  template <class T, typename
893  std::enable_if<
894  std::is_convertible<basic_json, T>::value and
895  not std::is_same<basic_json, T>::value
896  , int>::type = 0>
897  inline std::vector<T> get_impl(std::vector<T>*) const
898  {
899  switch (m_type)
900  {
901  case (value_t::array):
902  {
903  std::vector<T> to_vector;
904  to_vector.reserve(m_value.array->size());
905  std::transform(m_value.array->begin(), m_value.array->end(),
906  std::inserter(to_vector, to_vector.end()), [](basic_json i)
907  {
908  return i.get<T>();
909  });
910  return to_vector;
911  }
912  default:
913  {
914  throw std::logic_error("cannot cast " + type_name() + " to " + typeid(T).name());
915  }
916  }
917  }
918 
920  template <class T, typename
921  std::enable_if<
922  std::is_same<basic_json, typename T::value_type>::value and
924  , int>::type = 0>
925  inline T get_impl(T*) const
926  {
927  switch (m_type)
928  {
929  case (value_t::array):
930  {
931  return T(m_value.array->begin(), m_value.array->end());
932  }
933  default:
934  {
935  throw std::logic_error("cannot cast " + type_name() + " to " + typeid(T).name());
936  }
937  }
938  }
939 
940  inline array_t get_impl(array_t*) const
941  {
942  switch (m_type)
943  {
944  case (value_t::array):
945  {
946  return *(m_value.array);
947  }
948  default:
949  {
950  throw std::logic_error("cannot cast " + type_name() + " to array");
951  }
952  }
953  }
954 
956  template <typename T, typename
957  std::enable_if<
958  std::is_convertible<string_t, T>::value
959  , int>::type = 0>
960  inline T get_impl(T*) const
961  {
962  switch (m_type)
963  {
964  case (value_t::string):
965  {
966  return *m_value.string;
967  }
968  default:
969  {
970  throw std::logic_error("cannot cast " + type_name() + " to " + typeid(T).name());
971  }
972  }
973  }
974 
976  template<typename T, typename
977  std::enable_if<
978  std::is_arithmetic<T>::value
979  , int>::type = 0>
980  inline T get_impl(T*) const
981  {
982  switch (m_type)
983  {
984  case (value_t::number_integer):
985  {
986  return static_cast<T>(m_value.number_integer);
987  }
988  case (value_t::number_float):
989  {
990  return static_cast<T>(m_value.number_float);
991  }
992  default:
993  {
994  throw std::logic_error("cannot cast " + type_name() + " to " + typeid(T).name());
995  }
996  }
997  }
998 
1001  {
1002  switch (m_type)
1003  {
1004  case (value_t::boolean):
1005  {
1006  return m_value.boolean;
1007  }
1008  default:
1009  {
1010  throw std::logic_error("cannot cast " + type_name() + " to " + typeid(boolean_t).name());
1011  }
1012  }
1013  }
1014 
1015  public:
1017  // <http://stackoverflow.com/a/8315197/266378>
1018  template<typename T>
1019  inline T get() const
1020  {
1021  return get_impl(static_cast<T*>(nullptr));
1022  }
1023 
1025  template<typename T>
1026  inline operator T() const
1027  {
1028  return get<T>();
1029  }
1030 
1031 
1033  // element access //
1035 
1037  inline reference at(size_type pos)
1038  {
1039  // at only works for arrays
1040  if (m_type != value_t::array)
1041  {
1042  throw std::runtime_error("cannot use at with " + type_name());
1043  }
1044 
1045  return m_value.array->at(pos);
1046  }
1047 
1049  inline const_reference at(size_type pos) const
1050  {
1051  // at only works for arrays
1052  if (m_type != value_t::array)
1053  {
1054  throw std::runtime_error("cannot use at with " + type_name());
1055  }
1056 
1057  return m_value.array->at(pos);
1058  }
1059 
1062  {
1063  // implicitly convert null to object
1064  if (m_type == value_t::null)
1065  {
1066  m_type = value_t::array;
1067  Allocator<array_t> alloc;
1068  m_value.array = alloc.allocate(1);
1069  alloc.construct(m_value.array);
1070  }
1071 
1072  // [] only works for arrays
1073  if (m_type != value_t::array)
1074  {
1075  throw std::runtime_error("cannot use [] with " + type_name());
1076  }
1077 
1078  for (size_t i = m_value.array->size(); i <= pos; ++i)
1079  {
1080  m_value.array->push_back(basic_json());
1081  }
1082 
1083  return m_value.array->operator[](pos);
1084  }
1085 
1088  {
1089  // at only works for arrays
1090  if (m_type != value_t::array)
1091  {
1092  throw std::runtime_error("cannot use [] with " + type_name());
1093  }
1094 
1095  return m_value.array->operator[](pos);
1096  }
1097 
1099  inline reference at(const typename object_t::key_type& key)
1100  {
1101  // at only works for objects
1102  if (m_type != value_t::object)
1103  {
1104  throw std::runtime_error("cannot use at with " + type_name());
1105  }
1106 
1107  return m_value.object->at(key);
1108  }
1109 
1111  inline const_reference at(const typename object_t::key_type& key) const
1112  {
1113  // at only works for objects
1114  if (m_type != value_t::object)
1115  {
1116  throw std::runtime_error("cannot use at with " + type_name());
1117  }
1118 
1119  return m_value.object->at(key);
1120  }
1121 
1123  inline reference operator[](const typename object_t::key_type& key)
1124  {
1125  // implicitly convert null to object
1126  if (m_type == value_t::null)
1127  {
1128  m_type = value_t::object;
1129  Allocator<object_t> alloc;
1130  m_value.object = alloc.allocate(1);
1131  alloc.construct(m_value.object);
1132  }
1133 
1134  // [] only works for objects
1135  if (m_type != value_t::object)
1136  {
1137  throw std::runtime_error("cannot use [] with " + type_name());
1138  }
1139 
1140  return m_value.object->operator[](key);
1141  }
1142 
1144  inline const_reference operator[](const typename object_t::key_type& key) const
1145  {
1146  // at only works for objects
1147  if (m_type != value_t::object)
1148  {
1149  throw std::runtime_error("cannot use [] with " + type_name());
1150  }
1151 
1152  return m_value.object->operator[](key);
1153  }
1154 
1156  template<typename T, size_t n>
1157  inline reference operator[](const T (&key)[n])
1158  {
1159  // implicitly convert null to object
1160  if (m_type == value_t::null)
1161  {
1162  m_type = value_t::object;
1163  Allocator<object_t> alloc;
1164  m_value.object = alloc.allocate(1);
1165  alloc.construct(m_value.object);
1166  }
1167 
1168  // at only works for objects
1169  if (m_type != value_t::object)
1170  {
1171  throw std::runtime_error("cannot use [] with " + type_name());
1172  }
1173 
1174  return m_value.object->operator[](key);
1175  }
1176 
1178  template<typename T, size_t n>
1179  inline const_reference operator[](const T (&key)[n]) const
1180  {
1181  // at only works for objects
1182  if (m_type != value_t::object)
1183  {
1184  throw std::runtime_error("cannot use [] with " + type_name());
1185  }
1186 
1187  return m_value.object->operator[](key);
1188  }
1189 
1191  inline size_type erase(const typename object_t::key_type& key)
1192  {
1193  // this erase only works for objects
1194  if (m_type != value_t::object)
1195  {
1196  throw std::runtime_error("cannot use erase with " + type_name());
1197  }
1198 
1199  return m_value.object->erase(key);
1200  }
1201 
1203  inline void erase(const size_type pos)
1204  {
1205  // this erase only works for arrays
1206  if (m_type != value_t::array)
1207  {
1208  throw std::runtime_error("cannot use erase with " + type_name());
1209  }
1210 
1211  if (pos >= size())
1212  {
1213  throw std::out_of_range("index out of range");
1214  }
1215 
1216  m_value.array->erase(m_value.array->begin() + static_cast<difference_type>(pos));
1217  }
1218 
1220  inline iterator find(typename object_t::key_type key)
1221  {
1222  auto result = end();
1223 
1224  if (m_type == value_t::object)
1225  {
1226  result.m_it.object_iterator = m_value.object->find(key);
1227  }
1228 
1229  return result;
1230  }
1231 
1233  inline const_iterator find(typename object_t::key_type key) const
1234  {
1235  auto result = cend();
1236 
1237  if (m_type == value_t::object)
1238  {
1239  result.m_it.object_iterator = m_value.object->find(key);
1240  }
1241 
1242  return result;
1243  }
1244 
1246  inline size_type count(typename object_t::key_type key) const
1247  {
1248  // return 0 for all nonobject types
1249  return (m_type == value_t::object) ? m_value.object->count(key) : 0;
1250  }
1251 
1252 
1254  // iterators //
1256 
1261  inline iterator begin() noexcept
1262  {
1263  iterator result(this);
1264  result.set_begin();
1265  return result;
1266  }
1267 
1272  inline const_iterator begin() const noexcept
1273  {
1274  const_iterator result(this);
1275  result.set_begin();
1276  return result;
1277  }
1278 
1283  inline const_iterator cbegin() const noexcept
1284  {
1285  const_iterator result(this);
1286  result.set_begin();
1287  return result;
1288  }
1289 
1294  inline iterator end() noexcept
1295  {
1296  iterator result(this);
1297  result.set_end();
1298  return result;
1299  }
1300 
1305  inline const_iterator end() const noexcept
1306  {
1307  const_iterator result(this);
1308  result.set_end();
1309  return result;
1310  }
1311 
1316  inline const_iterator cend() const noexcept
1317  {
1318  const_iterator result(this);
1319  result.set_end();
1320  return result;
1321  }
1322 
1327  inline reverse_iterator rbegin() noexcept
1328  {
1329  return reverse_iterator(end());
1330  }
1331 
1336  inline const_reverse_iterator rbegin() const noexcept
1337  {
1338  return const_reverse_iterator(end());
1339  }
1340 
1345  inline reverse_iterator rend() noexcept
1346  {
1347  return reverse_iterator(begin());
1348  }
1349 
1354  inline const_reverse_iterator rend() const noexcept
1355  {
1356  return const_reverse_iterator(begin());
1357  }
1358 
1363  inline const_reverse_iterator crbegin() const noexcept
1364  {
1365  return const_reverse_iterator(cend());
1366  }
1367 
1372  inline const_reverse_iterator crend() const noexcept
1373  {
1374  return const_reverse_iterator(cbegin());
1375  }
1376 
1377 
1379  // capacity //
1381 
1386  inline bool empty() const noexcept
1387  {
1388  switch (m_type)
1389  {
1390  case (value_t::null):
1391  {
1392  return true;
1393  }
1394 
1395  case (value_t::array):
1396  {
1397  return m_value.array->empty();
1398  }
1399 
1400  case (value_t::object):
1401  {
1402  return m_value.object->empty();
1403  }
1404 
1405  default:
1406  {
1407  // all other types are nonempty
1408  return false;
1409  }
1410  }
1411  }
1412 
1417  inline size_type size() const noexcept
1418  {
1419  switch (m_type)
1420  {
1421  case (value_t::null):
1422  {
1423  return 0;
1424  }
1425 
1426  case (value_t::array):
1427  {
1428  return m_value.array->size();
1429  }
1430 
1431  case (value_t::object):
1432  {
1433  return m_value.object->size();
1434  }
1435 
1436  default:
1437  {
1438  // all other types have size 1
1439  return 1;
1440  }
1441  }
1442  }
1443 
1448  inline size_type max_size() const noexcept
1449  {
1450  switch (m_type)
1451  {
1452  case (value_t::null):
1453  {
1454  return 0;
1455  }
1456 
1457  case (value_t::array):
1458  {
1459  return m_value.array->max_size();
1460  }
1461 
1462  case (value_t::object):
1463  {
1464  return m_value.object->max_size();
1465  }
1466 
1467  default:
1468  {
1469  // all other types have max_size 1
1470  return 1;
1471  }
1472  }
1473  }
1474 
1475 
1477  // modifiers //
1479 
1481  inline void clear() noexcept
1482  {
1483  switch (m_type)
1484  {
1485  case (value_t::null):
1486  {
1487  break;
1488  }
1489 
1490  case (value_t::number_integer):
1491  {
1492  m_value.number_integer = 0;
1493  break;
1494  }
1495 
1496  case (value_t::number_float):
1497  {
1498  m_value.number_float = 0.0;
1499  break;
1500  }
1501 
1502  case (value_t::boolean):
1503  {
1504  m_value.boolean = false;
1505  break;
1506  }
1507 
1508  case (value_t::string):
1509  {
1510  m_value.string->clear();
1511  break;
1512  }
1513 
1514  case (value_t::array):
1515  {
1516  m_value.array->clear();
1517  break;
1518  }
1519 
1520  case (value_t::object):
1521  {
1522  m_value.object->clear();
1523  break;
1524  }
1525  }
1526  }
1527 
1529  inline void push_back(basic_json&& value)
1530  {
1531  // push_back only works for null objects or arrays
1532  if (not(m_type == value_t::null or m_type == value_t::array))
1533  {
1534  throw std::runtime_error("cannot add element to " + type_name());
1535  }
1536 
1537  // transform null object into an array
1538  if (m_type == value_t::null)
1539  {
1540  m_type = value_t::array;
1541  Allocator<array_t> alloc;
1542  m_value.array = alloc.allocate(1);
1543  alloc.construct(m_value.array);
1544  }
1545 
1546  // add element to array (move semantics)
1547  m_value.array->push_back(std::move(value));
1548  // invalidate object
1549  value.m_type = value_t::null;
1550  }
1551 
1554  {
1555  push_back(std::move(value));
1556  return *this;
1557  }
1558 
1560  inline void push_back(const basic_json& value)
1561  {
1562  // push_back only works for null objects or arrays
1563  if (not(m_type == value_t::null or m_type == value_t::array))
1564  {
1565  throw std::runtime_error("cannot add element to " + type_name());
1566  }
1567 
1568  // transform null object into an array
1569  if (m_type == value_t::null)
1570  {
1571  m_type = value_t::array;
1572  Allocator<array_t> alloc;
1573  m_value.array = alloc.allocate(1);
1574  alloc.construct(m_value.array);
1575  }
1576 
1577  // add element to array
1578  m_value.array->push_back(value);
1579  }
1580 
1583  {
1584  push_back(value);
1585  return *this;
1586  }
1587 
1589  inline void push_back(const typename object_t::value_type& value)
1590  {
1591  // push_back only works for null objects or objects
1592  if (not(m_type == value_t::null or m_type == value_t::object))
1593  {
1594  throw std::runtime_error("cannot add element to " + type_name());
1595  }
1596 
1597  // transform null object into an object
1598  if (m_type == value_t::null)
1599  {
1600  m_type = value_t::object;
1601  Allocator<object_t> alloc;
1602  m_value.object = alloc.allocate(1);
1603  alloc.construct(m_value.object);
1604  }
1605 
1606  // add element to array
1607  m_value.object->insert(value);
1608  }
1609 
1611  inline reference operator+=(const typename object_t::value_type& value)
1612  {
1613  push_back(value);
1614  return operator[](value.first);
1615  }
1616 
1621  inline void swap(reference other) noexcept (
1622  std::is_nothrow_move_constructible<value_t>::value and
1623  std::is_nothrow_move_assignable<value_t>::value and
1624  std::is_nothrow_move_constructible<json_value>::value and
1625  std::is_nothrow_move_assignable<json_value>::value
1626  )
1627  {
1628  std::swap(m_type, other.m_type);
1629  std::swap(m_value, other.m_value);
1630  }
1631 
1633  inline void swap(array_t& other)
1634  {
1635  // swap only works for arrays
1636  if (m_type != value_t::array)
1637  {
1638  throw std::runtime_error("cannot use swap with " + type_name());
1639  }
1640 
1641  // swap arrays
1642  std::swap(*(m_value.array), other);
1643  }
1644 
1646  inline void swap(object_t& other)
1647  {
1648  // swap only works for objects
1649  if (m_type != value_t::object)
1650  {
1651  throw std::runtime_error("cannot use swap with " + type_name());
1652  }
1653 
1654  // swap arrays
1655  std::swap(*(m_value.object), other);
1656  }
1657 
1659  inline void swap(string_t& other)
1660  {
1661  // swap only works for strings
1662  if (m_type != value_t::string)
1663  {
1664  throw std::runtime_error("cannot use swap with " + type_name());
1665  }
1666 
1667  // swap arrays
1668  std::swap(*(m_value.string), other);
1669  }
1670 
1671 
1673  // lexicographical comparison operators //
1675 
1680  friend bool operator==(const_reference lhs, const_reference rhs) noexcept
1681  {
1682  switch (lhs.type())
1683  {
1684  case (value_t::array):
1685  {
1686  if (rhs.type() == value_t::array)
1687  {
1688  return *lhs.m_value.array == *rhs.m_value.array;
1689  }
1690  break;
1691  }
1692  case (value_t::object):
1693  {
1694  if (rhs.type() == value_t::object)
1695  {
1696  return *lhs.m_value.object == *rhs.m_value.object;
1697  }
1698  break;
1699  }
1700  case (value_t::null):
1701  {
1702  if (rhs.type() == value_t::null)
1703  {
1704  return true;
1705  }
1706  break;
1707  }
1708  case (value_t::string):
1709  {
1710  if (rhs.type() == value_t::string)
1711  {
1712  return *lhs.m_value.string == *rhs.m_value.string;
1713  }
1714  break;
1715  }
1716  case (value_t::boolean):
1717  {
1718  if (rhs.type() == value_t::boolean)
1719  {
1720  return lhs.m_value.boolean == rhs.m_value.boolean;
1721  }
1722  break;
1723  }
1724  case (value_t::number_integer):
1725  {
1726  if (rhs.type() == value_t::number_integer)
1727  {
1728  return lhs.m_value.number_integer == rhs.m_value.number_integer;
1729  }
1730  if (rhs.type() == value_t::number_float)
1731  {
1732  return lhs.m_value.number_integer == static_cast<number_integer_t>(rhs.m_value.number_float);
1733  }
1734  break;
1735  }
1736  case (value_t::number_float):
1737  {
1738  if (rhs.type() == value_t::number_integer)
1739  {
1740  return approx(lhs.m_value.number_float, static_cast<number_float_t>(rhs.m_value.number_integer));
1741  }
1742  if (rhs.type() == value_t::number_float)
1743  {
1744  return approx(lhs.m_value.number_float, rhs.m_value.number_float);
1745  }
1746  break;
1747  }
1748  }
1749 
1750  return false;
1751  }
1752 
1757  friend bool operator!=(const_reference lhs, const_reference rhs) noexcept
1758  {
1759  return not (lhs == rhs);
1760  }
1761 
1763  friend bool operator<(const_reference lhs, const_reference rhs) noexcept
1764  {
1765  switch (lhs.type())
1766  {
1767  case (value_t::array):
1768  {
1769  if (rhs.type() == value_t::array)
1770  {
1771  return *lhs.m_value.array < *rhs.m_value.array;
1772  }
1773  break;
1774  }
1775  case (value_t::object):
1776  {
1777  if (rhs.type() == value_t::object)
1778  {
1779  return *lhs.m_value.object < *rhs.m_value.object;
1780  }
1781  break;
1782  }
1783  case (value_t::null):
1784  {
1785  if (rhs.type() == value_t::null)
1786  {
1787  return false;
1788  }
1789  break;
1790  }
1791  case (value_t::string):
1792  {
1793  if (rhs.type() == value_t::string)
1794  {
1795  return *lhs.m_value.string < *rhs.m_value.string;
1796  }
1797  break;
1798  }
1799  case (value_t::boolean):
1800  {
1801  if (rhs.type() == value_t::boolean)
1802  {
1803  return lhs.m_value.boolean < rhs.m_value.boolean;
1804  }
1805  break;
1806  }
1807  case (value_t::number_integer):
1808  {
1809  if (rhs.type() == value_t::number_integer)
1810  {
1811  return lhs.m_value.number_integer < rhs.m_value.number_integer;
1812  }
1813  if (rhs.type() == value_t::number_float)
1814  {
1815  return lhs.m_value.number_integer < static_cast<number_integer_t>(rhs.m_value.number_float);
1816  }
1817  break;
1818  }
1819  case (value_t::number_float):
1820  {
1821  if (rhs.type() == value_t::number_integer)
1822  {
1823  return lhs.m_value.number_float < static_cast<number_float_t>(rhs.m_value.number_integer);
1824  }
1825  if (rhs.type() == value_t::number_float)
1826  {
1827  return lhs.m_value.number_float < rhs.m_value.number_float;
1828  }
1829  break;
1830  }
1831  }
1832 
1833  // We only reach this line if we cannot compare values. In that case,
1834  // we compare types.
1835  return lhs.type() < rhs.type();
1836  }
1837 
1839  friend bool operator<=(const_reference lhs, const_reference rhs) noexcept
1840  {
1841  return not (rhs < lhs);
1842  }
1843 
1845  friend bool operator>(const_reference lhs, const_reference rhs) noexcept
1846  {
1847  return not (lhs <= rhs);
1848  }
1849 
1851  friend bool operator>=(const_reference lhs, const_reference rhs) noexcept
1852  {
1853  return not (lhs < rhs);
1854  }
1855 
1856 
1858  // serialization //
1860 
1862  friend std::ostream& operator<<(std::ostream& o, const basic_json& j)
1863  {
1864  // read width member and use it as indentation parameter if nonzero
1865  const int indentation = (o.width() == 0) ? -1 : o.width();
1866 
1867  o << j.dump(indentation);
1868  return o;
1869  }
1870 
1872  friend std::ostream& operator>>(const basic_json& j, std::ostream& o)
1873  {
1874  // read width member and use it as indentation parameter if nonzero
1875  const int indentation = (o.width() == 0) ? -1 : o.width();
1876 
1877  o << j.dump(indentation);
1878  return o;
1879  }
1880 
1881 
1883  // deserialization //
1885 
1887  static basic_json parse(const string_t& s)
1888  {
1889  return parser(s).parse();
1890  }
1891 
1893  static basic_json parse(std::istream& i)
1894  {
1895  return parser(i).parse();
1896  }
1897 
1899  friend std::istream& operator>>(std::istream& i, basic_json& j)
1900  {
1901  j = parser(i).parse();
1902  return i;
1903  }
1904 
1906  friend std::istream& operator<<(basic_json& j, std::istream& i)
1907  {
1908  j = parser(i).parse();
1909  return i;
1910  }
1911 
1912 
1913  private:
1915  // convenience functions //
1917 
1919  inline string_t type_name() const noexcept
1920  {
1921  switch (m_type)
1922  {
1923  case (value_t::null):
1924  {
1925  return "null";
1926  }
1927 
1928  case (value_t::object):
1929  {
1930  return "object";
1931  }
1932 
1933  case (value_t::array):
1934  {
1935  return "array";
1936  }
1937 
1938  case (value_t::string):
1939  {
1940  return "string";
1941  }
1942 
1943  case (value_t::boolean):
1944  {
1945  return "boolean";
1946  }
1947 
1948  default:
1949  {
1950  return "number";
1951  }
1952  }
1953  }
1954 
1966  static string_t escape_string(const string_t& s) noexcept
1967  {
1968  // create a result string of at least the size than s
1969  string_t result;
1970  result.reserve(s.size());
1971 
1972  for (const auto c : s)
1973  {
1974  switch (c)
1975  {
1976  // quotation mark (0x22)
1977  case '"':
1978  {
1979  result += "\\\"";
1980  break;
1981  }
1982 
1983  // reverse solidus (0x5c)
1984  case '\\':
1985  {
1986  result += "\\\\";
1987  break;
1988  }
1989 
1990  // backspace (0x08)
1991  case '\b':
1992  {
1993  result += "\\b";
1994  break;
1995  }
1996 
1997  // formfeed (0x0c)
1998  case '\f':
1999  {
2000  result += "\\f";
2001  break;
2002  }
2003 
2004  // newline (0x0a)
2005  case '\n':
2006  {
2007  result += "\\n";
2008  break;
2009  }
2010 
2011  // carriage return (0x0d)
2012  case '\r':
2013  {
2014  result += "\\r";
2015  break;
2016  }
2017 
2018  // horizontal tab (0x09)
2019  case '\t':
2020  {
2021  result += "\\t";
2022  break;
2023  }
2024 
2025  default:
2026  {
2027  if (c >= 0 and c <= 0x1f)
2028  {
2029  // control characters (everything between 0x00 and 0x1f)
2030  // -> create four-digit hex representation
2031  std::stringstream ss;
2032  ss << "\\u" << std::hex << std::setw(4) << std::setfill('0') << int(c);
2033  result += ss.str();
2034  }
2035  else
2036  {
2037  // all other characters are added as-is
2038  result.append(1, c);
2039  }
2040  break;
2041  }
2042  }
2043  }
2044 
2045  return result;
2046  }
2047 
2048 
2066  inline string_t dump(const bool prettyPrint, const unsigned int indentStep,
2067  const unsigned int currentIndent = 0) const noexcept
2068  {
2069  // variable to hold indentation for recursive calls
2070  auto new_indent = currentIndent;
2071 
2072  // helper function to return whitespace as indentation
2073  const auto indent = [prettyPrint, &new_indent]()
2074  {
2075  return prettyPrint ? string_t(new_indent, ' ') : string_t();
2076  };
2077 
2078  switch (m_type)
2079  {
2080  case (value_t::object):
2081  {
2082  if (m_value.object->empty())
2083  {
2084  return "{}";
2085  }
2086 
2087  string_t result = "{";
2088 
2089  // increase indentation
2090  if (prettyPrint)
2091  {
2092  new_indent += indentStep;
2093  result += "\n";
2094  }
2095 
2096  for (auto i = m_value.object->cbegin(); i != m_value.object->cend(); ++i)
2097  {
2098  if (i != m_value.object->cbegin())
2099  {
2100  result += prettyPrint ? ",\n" : ",";
2101  }
2102  result += indent() + "\"" + escape_string(i->first) + "\":" + (prettyPrint ? " " : "")
2103  + i->second.dump(prettyPrint, indentStep, new_indent);
2104  }
2105 
2106  // decrease indentation
2107  if (prettyPrint)
2108  {
2109  new_indent -= indentStep;
2110  result += "\n";
2111  }
2112 
2113  return result + indent() + "}";
2114  }
2115 
2116  case (value_t::array):
2117  {
2118  if (m_value.array->empty())
2119  {
2120  return "[]";
2121  }
2122 
2123  string_t result = "[";
2124 
2125  // increase indentation
2126  if (prettyPrint)
2127  {
2128  new_indent += indentStep;
2129  result += "\n";
2130  }
2131 
2132  for (auto i = m_value.array->cbegin(); i != m_value.array->cend(); ++i)
2133  {
2134  if (i != m_value.array->cbegin())
2135  {
2136  result += prettyPrint ? ",\n" : ",";
2137  }
2138  result += indent() + i->dump(prettyPrint, indentStep, new_indent);
2139  }
2140 
2141  // decrease indentation
2142  if (prettyPrint)
2143  {
2144  new_indent -= indentStep;
2145  result += "\n";
2146  }
2147 
2148  return result + indent() + "]";
2149  }
2150 
2151  case (value_t::string):
2152  {
2153  return string_t("\"") + escape_string(*m_value.string) + "\"";
2154  }
2155 
2156  case (value_t::boolean):
2157  {
2158  return m_value.boolean ? "true" : "false";
2159  }
2160 
2161  case (value_t::number_integer):
2162  {
2163  return std::to_string(m_value.number_integer);
2164  }
2165 
2166  case (value_t::number_float):
2167  {
2168  // 15 digits of precision allows round-trip IEEE 754
2169  // string->double->string
2170  const auto sz = static_cast<unsigned int>(std::snprintf(nullptr, 0, "%.15g", m_value.number_float));
2171  std::vector<char> buf(sz + 1);
2172  std::snprintf(&buf[0], buf.size(), "%.15g", m_value.number_float);
2173  return string_t(buf.data());
2174  }
2175 
2176  default:
2177  {
2178  return "null";
2179  }
2180  }
2181  }
2182 
2184  template<typename T>
2185  inline static bool approx(const T a, const T b)
2186  {
2187  return not (a > b or a < b);
2188  }
2189 
2190 
2191  private:
2193  // member variables //
2195 
2197  value_t m_type = value_t::null;
2198 
2200  bool m_final = false;
2201 
2203  json_value m_value = {};
2204 
2205 
2206  private:
2208  // iterators //
2210 
2212  template<typename array_iterator_t, typename object_iterator_t>
2214  {
2216  object_iterator_t object_iterator;
2218  array_iterator_t array_iterator;
2221 
2223  internal_iterator() : generic_iterator(-1) {}
2224  };
2225 
2226  public:
2228  class iterator : public std::iterator<std::random_access_iterator_tag, basic_json>
2229  {
2230  // allow basic_json class to access m_it
2231  friend class basic_json;
2232 
2233  public:
2243  using iterator_category = std::bidirectional_iterator_tag;
2244 
2246  inline iterator() = default;
2247 
2249  inline iterator(pointer object) noexcept : m_object(object)
2250  {
2251  switch (m_object->m_type)
2252  {
2254  {
2255  m_it.object_iterator = typename object_t::iterator();
2256  break;
2257  }
2259  {
2260  m_it.array_iterator = typename array_t::iterator();
2261  break;
2262  }
2263  default:
2264  {
2265  m_it.generic_iterator = -1;
2266  break;
2267  }
2268  }
2269  }
2270 
2272  inline iterator(const iterator& other) noexcept
2273  : m_object(other.m_object), m_it(other.m_it)
2274  {}
2275 
2277  inline iterator& operator=(iterator other) noexcept (
2278  std::is_nothrow_move_constructible<pointer>::value and
2279  std::is_nothrow_move_assignable<pointer>::value and
2281  and
2283  )
2284  {
2285  std::swap(m_object, other.m_object);
2286  std::swap(m_it, other.m_it);
2287  return *this;
2288  }
2289 
2290  private:
2292  inline void set_begin() noexcept
2293  {
2294  switch (m_object->m_type)
2295  {
2297  {
2298  m_it.object_iterator = m_object->m_value.object->begin();
2299  break;
2300  }
2301 
2303  {
2304  m_it.array_iterator = m_object->m_value.array->begin();
2305  break;
2306  }
2307 
2309  {
2310  // set to end so begin()==end() is true: null is empty
2311  m_it.generic_iterator = 1;
2312  break;
2313  }
2314 
2315  default:
2316  {
2317  m_it.generic_iterator = 0;
2318  break;
2319  }
2320  }
2321  }
2322 
2324  inline void set_end() noexcept
2325  {
2326  switch (m_object->m_type)
2327  {
2329  {
2330  m_it.object_iterator = m_object->m_value.object->end();
2331  break;
2332  }
2333 
2335  {
2336  m_it.array_iterator = m_object->m_value.array->end();
2337  break;
2338  }
2339 
2340  default:
2341  {
2342  m_it.generic_iterator = 1;
2343  break;
2344  }
2345  }
2346  }
2347 
2348  public:
2351  {
2352  switch (m_object->m_type)
2353  {
2355  {
2356  return m_it.object_iterator->second;
2357  }
2358 
2360  {
2361  return *m_it.array_iterator;
2362  }
2363 
2365  {
2366  throw std::out_of_range("cannot get value");
2367  }
2368 
2369  default:
2370  {
2371  if (m_it.generic_iterator == 0)
2372  {
2373  return *m_object;
2374  }
2375  else
2376  {
2377  throw std::out_of_range("cannot get value");
2378  }
2379  }
2380  }
2381  }
2382 
2385  {
2386  switch (m_object->m_type)
2387  {
2389  {
2390  return &(m_it.object_iterator->second);
2391  }
2392 
2394  {
2395  return &*m_it.array_iterator;
2396  }
2397 
2399  {
2400  throw std::out_of_range("cannot get value");
2401  }
2402 
2403  default:
2404  {
2405  if (m_it.generic_iterator == 0)
2406  {
2407  return m_object;
2408  }
2409  else
2410  {
2411  throw std::out_of_range("cannot get value");
2412  }
2413  }
2414  }
2415  }
2416 
2418  inline iterator operator++(int)
2419  {
2420  auto result = *this;
2421 
2422  switch (m_object->m_type)
2423  {
2425  {
2426  m_it.object_iterator++;
2427  break;
2428  }
2429 
2431  {
2432  m_it.array_iterator++;
2433  break;
2434  }
2435 
2436  default:
2437  {
2438  m_it.generic_iterator++;
2439  break;
2440  }
2441  }
2442 
2443  return result;
2444  }
2445 
2448  {
2449  switch (m_object->m_type)
2450  {
2452  {
2453  ++m_it.object_iterator;
2454  break;
2455  }
2456 
2458  {
2459  ++m_it.array_iterator;
2460  break;
2461  }
2462 
2463  default:
2464  {
2465  ++m_it.generic_iterator;
2466  break;
2467  }
2468  }
2469 
2470  return *this;
2471  }
2472 
2474  inline iterator operator--(int)
2475  {
2476  auto result = *this;
2477 
2478  switch (m_object->m_type)
2479  {
2481  {
2482  m_it.object_iterator--;
2483  break;
2484  }
2485 
2487  {
2488  m_it.array_iterator--;
2489  break;
2490  }
2491 
2492  default:
2493  {
2494  m_it.generic_iterator--;
2495  break;
2496  }
2497  }
2498 
2499  return result;
2500  }
2501 
2504  {
2505  switch (m_object->m_type)
2506  {
2508  {
2509  --m_it.object_iterator;
2510  break;
2511  }
2512 
2514  {
2515  --m_it.array_iterator;
2516  break;
2517  }
2518 
2519  default:
2520  {
2521  --m_it.generic_iterator;
2522  break;
2523  }
2524  }
2525 
2526  return *this;
2527  }
2528 
2530  inline bool operator==(const iterator& other) const
2531  {
2532  // if objects are not the same, the comparison is undefined
2533  if (m_object != other.m_object)
2534  {
2535  throw std::domain_error("cannot compare iterators of different containers");
2536  }
2537 
2538  switch (m_object->m_type)
2539  {
2541  {
2542  return (m_it.object_iterator == other.m_it.object_iterator);
2543  }
2544 
2546  {
2547  return (m_it.array_iterator == other.m_it.array_iterator);
2548  }
2549 
2550  default:
2551  {
2552  return (m_it.generic_iterator == other.m_it.generic_iterator);
2553  }
2554  }
2555  }
2556 
2558  inline bool operator!=(const iterator& other) const
2559  {
2560  return not operator==(other);
2561  }
2562 
2564  inline bool operator<(const iterator& other) const
2565  {
2566  // if objects are not the same, the comparison is undefined
2567  if (m_object != other.m_object)
2568  {
2569  throw std::domain_error("cannot compare iterators of different containers");
2570  }
2571 
2572  switch (m_object->m_type)
2573  {
2575  {
2576  throw std::domain_error("cannot use operator< for object iterators");
2577  }
2578 
2580  {
2581  return (m_it.array_iterator < other.m_it.array_iterator);
2582  }
2583 
2584  default:
2585  {
2586  return (m_it.generic_iterator < other.m_it.generic_iterator);
2587  }
2588  }
2589  }
2590 
2592  inline bool operator<=(const iterator& other) const
2593  {
2594  return not other.operator < (*this);
2595  }
2596 
2598  inline bool operator>(const iterator& other) const
2599  {
2600  return not operator<=(other);
2601  }
2602 
2604  inline bool operator>=(const iterator& other) const
2605  {
2606  return not operator<(other);
2607  }
2608 
2611  {
2612  switch (m_object->m_type)
2613  {
2615  {
2616  throw std::domain_error("cannot use operator+= for object iterators");
2617  }
2618 
2620  {
2621  m_it.array_iterator += i;
2622  break;
2623  }
2624 
2625  default:
2626  {
2627  m_it.generic_iterator += i;
2628  break;
2629  }
2630  }
2631 
2632  return *this;
2633  }
2634 
2637  {
2638  return operator+=(-i);
2639  }
2640 
2643  {
2644  auto result = *this;
2645  result += i;
2646  return result;
2647  }
2648 
2651  {
2652  auto result = *this;
2653  result -= i;
2654  return result;
2655  }
2656 
2658  inline difference_type operator-(const iterator& other) const
2659  {
2660  switch (m_object->m_type)
2661  {
2663  {
2664  throw std::domain_error("cannot use operator- for object iterators");
2665  return 0;
2666  }
2667 
2669  {
2670  return m_it.array_iterator - other.m_it.array_iterator;
2671  }
2672 
2673  default:
2674  {
2675  return m_it.generic_iterator - other.m_it.generic_iterator;
2676  }
2677  }
2678  }
2679 
2682  {
2683  switch (m_object->m_type)
2684  {
2686  {
2687  throw std::domain_error("cannot use operator[] for object iterators");
2688  }
2689 
2691  {
2692  return *(m_it.array_iterator + n);
2693  }
2694 
2696  {
2697  throw std::out_of_range("cannot get value");
2698  }
2699 
2700  default:
2701  {
2702  if (m_it.generic_iterator == -n)
2703  {
2704  return *m_object;
2705  }
2706  else
2707  {
2708  throw std::out_of_range("cannot get value");
2709  }
2710  }
2711  }
2712  }
2713 
2715  inline typename object_t::key_type key() const
2716  {
2717  switch (m_object->m_type)
2718  {
2720  {
2721  return m_it.object_iterator->first;
2722  }
2723 
2724  default:
2725  {
2726  throw std::domain_error("cannot use key() for non-object iterators");
2727  }
2728  }
2729  }
2730 
2732  inline reference value()
2733  {
2734  return operator*();
2735  }
2736 
2737  private:
2739  pointer m_object = nullptr;
2742  };
2743 
2745  class const_iterator : public std::iterator<std::random_access_iterator_tag, const basic_json>
2746  {
2747  // allow basic_json class to access m_it
2748  friend class basic_json;
2749 
2750  public:
2760  using iterator_category = std::bidirectional_iterator_tag;
2761 
2763  inline const_iterator() = default;
2764 
2766  inline const_iterator(pointer object) noexcept : m_object(object)
2767  {
2768  switch (m_object->m_type)
2769  {
2771  {
2772  m_it.object_iterator = typename object_t::const_iterator();
2773  break;
2774  }
2776  {
2777  m_it.array_iterator = typename array_t::const_iterator();
2778  break;
2779  }
2780  default:
2781  {
2782  m_it.generic_iterator = -1;
2783  break;
2784  }
2785  }
2786  }
2787 
2789  inline const_iterator(const iterator& other) noexcept : m_object(other.m_object)
2790  {
2791  switch (m_object->m_type)
2792  {
2794  {
2795  m_it.object_iterator = other.m_it.object_iterator;
2796  break;
2797  }
2798 
2800  {
2801  m_it.array_iterator = other.m_it.array_iterator;
2802  break;
2803  }
2804 
2805  default:
2806  {
2807  m_it.generic_iterator = other.m_it.generic_iterator;
2808  break;
2809  }
2810  }
2811  }
2812 
2814  inline const_iterator(const const_iterator& other) noexcept
2815  : m_object(other.m_object), m_it(other.m_it)
2816  {}
2817 
2819  inline const_iterator& operator=(const_iterator other) noexcept(
2820  std::is_nothrow_move_constructible<pointer>::value and
2821  std::is_nothrow_move_assignable<pointer>::value and
2823  and
2825  )
2826  {
2827  std::swap(m_object, other.m_object);
2828  std::swap(m_it, other.m_it);
2829  return *this;
2830  }
2831 
2832  private:
2834  inline void set_begin() noexcept
2835  {
2836  switch (m_object->m_type)
2837  {
2839  {
2840  m_it.object_iterator = m_object->m_value.object->cbegin();
2841  break;
2842  }
2843 
2845  {
2846  m_it.array_iterator = m_object->m_value.array->cbegin();
2847  break;
2848  }
2849 
2851  {
2852  // set to end so begin()==end() is true: null is empty
2853  m_it.generic_iterator = 1;
2854  break;
2855  }
2856 
2857  default:
2858  {
2859  m_it.generic_iterator = 0;
2860  break;
2861  }
2862  }
2863  }
2864 
2866  inline void set_end() noexcept
2867  {
2868  switch (m_object->m_type)
2869  {
2871  {
2872  m_it.object_iterator = m_object->m_value.object->cend();
2873  break;
2874  }
2875 
2877  {
2878  m_it.array_iterator = m_object->m_value.array->cend();
2879  break;
2880  }
2881 
2882  default:
2883  {
2884  m_it.generic_iterator = 1;
2885  break;
2886  }
2887  }
2888  }
2889 
2890  public:
2892  inline reference operator*() const
2893  {
2894  switch (m_object->m_type)
2895  {
2897  {
2898  return m_it.object_iterator->second;
2899  }
2900 
2902  {
2903  return *m_it.array_iterator;
2904  }
2905 
2907  {
2908  throw std::out_of_range("cannot get value");
2909  }
2910 
2911  default:
2912  {
2913  if (m_it.generic_iterator == 0)
2914  {
2915  return *m_object;
2916  }
2917  else
2918  {
2919  throw std::out_of_range("cannot get value");
2920  }
2921  }
2922  }
2923  }
2924 
2926  inline pointer operator->() const
2927  {
2928  switch (m_object->m_type)
2929  {
2931  {
2932  return &(m_it.object_iterator->second);
2933  }
2934 
2936  {
2937  return &*m_it.array_iterator;
2938  }
2939 
2940  default:
2941  {
2942  if (m_it.generic_iterator == 0)
2943  {
2944  return m_object;
2945  }
2946  else
2947  {
2948  throw std::out_of_range("cannot get value");
2949  }
2950  }
2951  }
2952  }
2953 
2956  {
2957  auto result = *this;
2958 
2959  switch (m_object->m_type)
2960  {
2962  {
2963  m_it.object_iterator++;
2964  break;
2965  }
2966 
2968  {
2969  m_it.array_iterator++;
2970  break;
2971  }
2972 
2973  default:
2974  {
2975  m_it.generic_iterator++;
2976  break;
2977  }
2978  }
2979 
2980  return result;
2981  }
2982 
2985  {
2986  switch (m_object->m_type)
2987  {
2989  {
2990  ++m_it.object_iterator;
2991  break;
2992  }
2993 
2995  {
2996  ++m_it.array_iterator;
2997  break;
2998  }
2999 
3000  default:
3001  {
3002  ++m_it.generic_iterator;
3003  break;
3004  }
3005  }
3006 
3007  return *this;
3008  }
3009 
3012  {
3013  auto result = *this;
3014 
3015  switch (m_object->m_type)
3016  {
3018  {
3019  m_it.object_iterator--;
3020  break;
3021  }
3022 
3024  {
3025  m_it.array_iterator--;
3026  break;
3027  }
3028 
3029  default:
3030  {
3031  m_it.generic_iterator--;
3032  break;
3033  }
3034  }
3035 
3036  return result;
3037  }
3038 
3041  {
3042  switch (m_object->m_type)
3043  {
3045  {
3046  --m_it.object_iterator;
3047  break;
3048  }
3049 
3051  {
3052  --m_it.array_iterator;
3053  break;
3054  }
3055 
3056  default:
3057  {
3058  --m_it.generic_iterator;
3059  break;
3060  }
3061  }
3062 
3063  return *this;
3064  }
3065 
3067  inline bool operator==(const const_iterator& other) const
3068  {
3069  // if objects are not the same, the comparison is undefined
3070  if (m_object != other.m_object)
3071  {
3072  throw std::domain_error("cannot compare iterators of different containers");
3073  }
3074 
3075  switch (m_object->m_type)
3076  {
3078  {
3079  return (m_it.object_iterator == other.m_it.object_iterator);
3080  }
3081 
3083  {
3084  return (m_it.array_iterator == other.m_it.array_iterator);
3085  }
3086 
3087  default:
3088  {
3089  return (m_it.generic_iterator == other.m_it.generic_iterator);
3090  }
3091  }
3092  }
3093 
3095  inline bool operator!=(const const_iterator& other) const
3096  {
3097  return not operator==(other);
3098  }
3099 
3101  inline bool operator<(const const_iterator& other) const
3102  {
3103  // if objects are not the same, the comparison is undefined
3104  if (m_object != other.m_object)
3105  {
3106  throw std::domain_error("cannot compare iterators of different containers");
3107  }
3108 
3109  switch (m_object->m_type)
3110  {
3112  {
3113  throw std::domain_error("cannot use operator< for object iterators");
3114  }
3115 
3117  {
3118  return (m_it.array_iterator < other.m_it.array_iterator);
3119  }
3120 
3121  default:
3122  {
3123  return (m_it.generic_iterator < other.m_it.generic_iterator);
3124  }
3125  }
3126  }
3127 
3129  inline bool operator<=(const const_iterator& other) const
3130  {
3131  return not other.operator < (*this);
3132  }
3133 
3135  inline bool operator>(const const_iterator& other) const
3136  {
3137  return not operator<=(other);
3138  }
3139 
3141  inline bool operator>=(const const_iterator& other) const
3142  {
3143  return not operator<(other);
3144  }
3145 
3148  {
3149  switch (m_object->m_type)
3150  {
3152  {
3153  throw std::domain_error("cannot use operator+= for object iterators");
3154  break;
3155  }
3156 
3158  {
3159  m_it.array_iterator += i;
3160  break;
3161  }
3162 
3163  default:
3164  {
3165  m_it.generic_iterator += i;
3166  break;
3167  }
3168  }
3169 
3170  return *this;
3171  }
3172 
3175  {
3176  return operator+=(-i);
3177  }
3178 
3181  {
3182  auto result = *this;
3183  result += i;
3184  return result;
3185  }
3186 
3189  {
3190  auto result = *this;
3191  result -= i;
3192  return result;
3193  }
3194 
3196  inline difference_type operator-(const const_iterator& other) const
3197  {
3198  switch (m_object->m_type)
3199  {
3201  {
3202  throw std::domain_error("cannot use operator- for object iterators");
3203  }
3204 
3206  {
3207  return m_it.array_iterator - other.m_it.array_iterator;
3208  }
3209 
3210  default:
3211  {
3212  return m_it.generic_iterator - other.m_it.generic_iterator;
3213  }
3214  }
3215  }
3216 
3219  {
3220  switch (m_object->m_type)
3221  {
3223  {
3224  throw std::domain_error("cannot use operator[] for object iterators");
3225  }
3226 
3228  {
3229  return *(m_it.array_iterator + n);
3230  }
3231 
3233  {
3234  throw std::out_of_range("cannot get value");
3235  }
3236 
3237  default:
3238  {
3239  if (m_it.generic_iterator == -n)
3240  {
3241  return *m_object;
3242  }
3243  else
3244  {
3245  throw std::out_of_range("cannot get value");
3246  }
3247  }
3248  }
3249  }
3250 
3252  inline typename object_t::key_type key() const
3253  {
3254  switch (m_object->m_type)
3255  {
3257  {
3258  return m_it.object_iterator->first;
3259  }
3260 
3261  default:
3262  {
3263  throw std::domain_error("cannot use key() for non-object iterators");
3264  }
3265  }
3266  }
3267 
3269  inline reference value() const
3270  {
3271  return operator*();
3272  }
3273 
3274  private:
3276  pointer m_object = nullptr;
3279  };
3280 
3282  class reverse_iterator : private std::reverse_iterator<basic_json::iterator>
3283  {
3284  public:
3285  inline reverse_iterator(const typename std::reverse_iterator<basic_json::iterator>::iterator_type&
3286  it)
3287  : std::reverse_iterator<basic_json::iterator>(it) {}
3288 
3290  inline typename object_t::key_type key() const
3291  {
3292  return this->base().key();
3293  }
3294 
3296  inline reference value() const
3297  {
3298  return this->base().operator * ();
3299  }
3300  };
3301 
3303  class const_reverse_iterator : private std::reverse_iterator<basic_json::const_iterator>
3304  {
3305  public:
3306  inline const_reverse_iterator(const typename
3307  std::reverse_iterator<basic_json::const_iterator>::iterator_type& it)
3309 
3311  inline typename object_t::key_type key() const
3312  {
3313  return this->base().key();
3314  }
3315 
3317  inline reference value() const
3318  {
3319  return this->base().operator * ();
3320  }
3321  };
3322 
3323 
3324  private:
3326  // lexer and parser //
3328 
3336  class lexer
3337  {
3338  public:
3340  enum class token_type
3341  {
3342  uninitialized,
3343  literal_true,
3344  literal_false,
3345  literal_null,
3346  value_string,
3347  value_number,
3348  begin_array,
3349  begin_object,
3350  end_array,
3351  end_object,
3352  name_separator,
3353  value_separator,
3354  parse_error,
3355  end_of_input
3356  };
3357 
3359  using lexer_char_t = unsigned char;
3360 
3362  inline lexer(const string_t& s) noexcept
3363  : m_stream(nullptr), m_buffer(s)
3364  {
3365  m_content = reinterpret_cast<const lexer_char_t*>(s.c_str());
3366  m_start = m_cursor = m_content;
3367  m_limit = m_content + s.size();
3368  }
3369  inline lexer(std::istream* s) noexcept
3370  : m_stream(s)
3371  {
3372  getline(*m_stream, m_buffer);
3373  m_content = reinterpret_cast<const lexer_char_t*>(m_buffer.c_str());
3374  m_start = m_cursor = m_content;
3375  m_limit = m_content + m_buffer.size();
3376  }
3377 
3379  inline lexer() = default;
3380 
3392  inline static string_t to_unicode(const size_t codepoint1,
3393  const size_t codepoint2 = 0)
3394  {
3395  string_t result;
3396 
3397  // calculate the codepoint from the given code points
3398  size_t codepoint = codepoint1;
3399  if (codepoint1 >= 0xD800 and codepoint1 <= 0xDBFF)
3400  {
3401  if (codepoint2 >= 0xDC00 and codepoint2 <= 0xDFFF)
3402  {
3403  codepoint =
3404  // high surrogate occupies the most significant 22 bits
3405  (codepoint1 << 10)
3406  // low surrogate occupies the least significant 15 bits
3407  + codepoint2
3408  // there is still the 0xD800, 0xDC00 and 0x10000 noise
3409  // in the result so we have to substract with:
3410  // (0xD800 << 10) + DC00 - 0x10000 = 0x35FDC00
3411  - 0x35FDC00;
3412  }
3413  else
3414  {
3415  throw std::invalid_argument("missing or wrong low surrogate");
3416  }
3417  }
3418 
3419  if (codepoint <= 0x7f)
3420  {
3421  // 1-byte characters: 0xxxxxxx (ASCII)
3422  result.append(1, static_cast<typename string_t::value_type>(codepoint));
3423  }
3424  else if (codepoint <= 0x7ff)
3425  {
3426  // 2-byte characters: 110xxxxx 10xxxxxx
3427  result.append(1, static_cast<typename string_t::value_type>(0xC0 | ((codepoint >> 6) & 0x1F)));
3428  result.append(1, static_cast<typename string_t::value_type>(0x80 | (codepoint & 0x3F)));
3429  }
3430  else if (codepoint <= 0xffff)
3431  {
3432  // 3-byte characters: 1110xxxx 10xxxxxx 10xxxxxx
3433  result.append(1, static_cast<typename string_t::value_type>(0xE0 | ((codepoint >> 12) & 0x0F)));
3434  result.append(1, static_cast<typename string_t::value_type>(0x80 | ((codepoint >> 6) & 0x3F)));
3435  result.append(1, static_cast<typename string_t::value_type>(0x80 | (codepoint & 0x3F)));
3436  }
3437  else if (codepoint <= 0x10ffff)
3438  {
3439  // 4-byte characters: 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
3440  result.append(1, static_cast<typename string_t::value_type>(0xF0 | ((codepoint >> 18) & 0x07)));
3441  result.append(1, static_cast<typename string_t::value_type>(0x80 | ((codepoint >> 12) & 0x3F)));
3442  result.append(1, static_cast<typename string_t::value_type>(0x80 | ((codepoint >> 6) & 0x3F)));
3443  result.append(1, static_cast<typename string_t::value_type>(0x80 | (codepoint & 0x3F)));
3444  }
3445  else
3446  {
3447  throw std::out_of_range("code points above 0x10FFFF are invalid");
3448  }
3449 
3450  return result;
3451  }
3452 
3454  inline static std::string token_type_name(token_type t) noexcept
3455  {
3456  switch (t)
3457  {
3458  case (token_type::uninitialized):
3459  return "<uninitialized>";
3460  case (token_type::literal_true):
3461  return "true literal";
3462  case (token_type::literal_false):
3463  return "false literal";
3464  case (token_type::literal_null):
3465  return "null literal";
3466  case (token_type::value_string):
3467  return "string literal";
3468  case (token_type::value_number):
3469  return "number literal";
3470  case (token_type::begin_array):
3471  return "[";
3472  case (token_type::begin_object):
3473  return "{";
3474  case (token_type::end_array):
3475  return "]";
3476  case (token_type::end_object):
3477  return "}";
3478  case (token_type::name_separator):
3479  return ":";
3480  case (token_type::value_separator):
3481  return ",";
3482  case (token_type::end_of_input):
3483  return "<end of input>";
3484  default:
3485  return "<parse error>";
3486  }
3487  }
3488 
3499  inline token_type scan() noexcept
3500  {
3501  // pointer for backtracking information
3502  m_marker = nullptr;
3503 
3504  // remember the begin of the token
3505  m_start = m_cursor;
3506 
3507 
3508  {
3509  lexer_char_t yych;
3510  unsigned int yyaccept = 0;
3511  static const unsigned char yybm[] =
3512  {
3513  0, 64, 64, 64, 64, 64, 64, 64,
3514  64, 96, 96, 64, 64, 96, 64, 64,
3515  64, 64, 64, 64, 64, 64, 64, 64,
3516  64, 64, 64, 64, 64, 64, 64, 64,
3517  96, 64, 0, 64, 64, 64, 64, 64,
3518  64, 64, 64, 64, 64, 64, 64, 64,
3519  192, 192, 192, 192, 192, 192, 192, 192,
3520  192, 192, 64, 64, 64, 64, 64, 64,
3521  64, 64, 64, 64, 64, 64, 64, 64,
3522  64, 64, 64, 64, 64, 64, 64, 64,
3523  64, 64, 64, 64, 64, 64, 64, 64,
3524  64, 64, 64, 64, 0, 64, 64, 64,
3525  64, 64, 64, 64, 64, 64, 64, 64,
3526  64, 64, 64, 64, 64, 64, 64, 64,
3527  64, 64, 64, 64, 64, 64, 64, 64,
3528  64, 64, 64, 64, 64, 64, 64, 64,
3529  64, 64, 64, 64, 64, 64, 64, 64,
3530  64, 64, 64, 64, 64, 64, 64, 64,
3531  64, 64, 64, 64, 64, 64, 64, 64,
3532  64, 64, 64, 64, 64, 64, 64, 64,
3533  64, 64, 64, 64, 64, 64, 64, 64,
3534  64, 64, 64, 64, 64, 64, 64, 64,
3535  64, 64, 64, 64, 64, 64, 64, 64,
3536  64, 64, 64, 64, 64, 64, 64, 64,
3537  64, 64, 64, 64, 64, 64, 64, 64,
3538  64, 64, 64, 64, 64, 64, 64, 64,
3539  64, 64, 64, 64, 64, 64, 64, 64,
3540  64, 64, 64, 64, 64, 64, 64, 64,
3541  64, 64, 64, 64, 64, 64, 64, 64,
3542  64, 64, 64, 64, 64, 64, 64, 64,
3543  64, 64, 64, 64, 64, 64, 64, 64,
3544  64, 64, 64, 64, 64, 64, 64, 64,
3545  };
3546 
3547  if ((m_limit - m_cursor) < 5)
3548  {
3549  yyfill();
3550  };
3551  yych = *m_cursor;
3552  if (yych <= '9')
3553  {
3554  if (yych <= ' ')
3555  {
3556  if (yych <= '\n')
3557  {
3558  if (yych <= 0x00)
3559  {
3560  goto basic_json_parser_27;
3561  }
3562  if (yych <= 0x08)
3563  {
3564  goto basic_json_parser_29;
3565  }
3566  if (yych >= '\n')
3567  {
3568  goto basic_json_parser_4;
3569  }
3570  }
3571  else
3572  {
3573  if (yych == '\r')
3574  {
3575  goto basic_json_parser_2;
3576  }
3577  if (yych <= 0x1F)
3578  {
3579  goto basic_json_parser_29;
3580  }
3581  }
3582  }
3583  else
3584  {
3585  if (yych <= ',')
3586  {
3587  if (yych == '"')
3588  {
3589  goto basic_json_parser_26;
3590  }
3591  if (yych <= '+')
3592  {
3593  goto basic_json_parser_29;
3594  }
3595  goto basic_json_parser_14;
3596  }
3597  else
3598  {
3599  if (yych <= '-')
3600  {
3601  goto basic_json_parser_22;
3602  }
3603  if (yych <= '/')
3604  {
3605  goto basic_json_parser_29;
3606  }
3607  if (yych <= '0')
3608  {
3609  goto basic_json_parser_23;
3610  }
3611  goto basic_json_parser_25;
3612  }
3613  }
3614  }
3615  else
3616  {
3617  if (yych <= 'm')
3618  {
3619  if (yych <= '\\')
3620  {
3621  if (yych <= ':')
3622  {
3623  goto basic_json_parser_16;
3624  }
3625  if (yych == '[')
3626  {
3627  goto basic_json_parser_6;
3628  }
3629  goto basic_json_parser_29;
3630  }
3631  else
3632  {
3633  if (yych <= ']')
3634  {
3635  goto basic_json_parser_8;
3636  }
3637  if (yych == 'f')
3638  {
3639  goto basic_json_parser_21;
3640  }
3641  goto basic_json_parser_29;
3642  }
3643  }
3644  else
3645  {
3646  if (yych <= 'z')
3647  {
3648  if (yych <= 'n')
3649  {
3650  goto basic_json_parser_18;
3651  }
3652  if (yych == 't')
3653  {
3654  goto basic_json_parser_20;
3655  }
3656  goto basic_json_parser_29;
3657  }
3658  else
3659  {
3660  if (yych <= '{')
3661  {
3662  goto basic_json_parser_10;
3663  }
3664  if (yych == '}')
3665  {
3666  goto basic_json_parser_12;
3667  }
3668  goto basic_json_parser_29;
3669  }
3670  }
3671  }
3672 basic_json_parser_2:
3673  ++m_cursor;
3674  yych = *m_cursor;
3675  goto basic_json_parser_5;
3676 basic_json_parser_3:
3677  {
3678  return scan();
3679  }
3680 basic_json_parser_4:
3681  ++m_cursor;
3682  if (m_limit <= m_cursor)
3683  {
3684  yyfill();
3685  };
3686  yych = *m_cursor;
3687 basic_json_parser_5:
3688  if (yybm[0 + yych] & 32)
3689  {
3690  goto basic_json_parser_4;
3691  }
3692  goto basic_json_parser_3;
3693 basic_json_parser_6:
3694  ++m_cursor;
3695  {
3696  return token_type::begin_array;
3697  }
3698 basic_json_parser_8:
3699  ++m_cursor;
3700  {
3701  return token_type::end_array;
3702  }
3703 basic_json_parser_10:
3704  ++m_cursor;
3705  {
3706  return token_type::begin_object;
3707  }
3708 basic_json_parser_12:
3709  ++m_cursor;
3710  {
3711  return token_type::end_object;
3712  }
3713 basic_json_parser_14:
3714  ++m_cursor;
3715  {
3716  return token_type::value_separator;
3717  }
3718 basic_json_parser_16:
3719  ++m_cursor;
3720  {
3721  return token_type::name_separator;
3722  }
3723 basic_json_parser_18:
3724  yyaccept = 0;
3725  yych = *(m_marker = ++m_cursor);
3726  if (yych == 'u')
3727  {
3728  goto basic_json_parser_59;
3729  }
3730 basic_json_parser_19:
3731  {
3732  return token_type::parse_error;
3733  }
3734 basic_json_parser_20:
3735  yyaccept = 0;
3736  yych = *(m_marker = ++m_cursor);
3737  if (yych == 'r')
3738  {
3739  goto basic_json_parser_55;
3740  }
3741  goto basic_json_parser_19;
3742 basic_json_parser_21:
3743  yyaccept = 0;
3744  yych = *(m_marker = ++m_cursor);
3745  if (yych == 'a')
3746  {
3747  goto basic_json_parser_50;
3748  }
3749  goto basic_json_parser_19;
3750 basic_json_parser_22:
3751  yych = *++m_cursor;
3752  if (yych <= '/')
3753  {
3754  goto basic_json_parser_19;
3755  }
3756  if (yych <= '0')
3757  {
3758  goto basic_json_parser_49;
3759  }
3760  if (yych <= '9')
3761  {
3762  goto basic_json_parser_40;
3763  }
3764  goto basic_json_parser_19;
3765 basic_json_parser_23:
3766  yyaccept = 1;
3767  yych = *(m_marker = ++m_cursor);
3768  if (yych <= 'D')
3769  {
3770  if (yych == '.')
3771  {
3772  goto basic_json_parser_42;
3773  }
3774  }
3775  else
3776  {
3777  if (yych <= 'E')
3778  {
3779  goto basic_json_parser_43;
3780  }
3781  if (yych == 'e')
3782  {
3783  goto basic_json_parser_43;
3784  }
3785  }
3786 basic_json_parser_24:
3787  {
3788  return token_type::value_number;
3789  }
3790 basic_json_parser_25:
3791  yyaccept = 1;
3792  yych = *(m_marker = ++m_cursor);
3793  goto basic_json_parser_41;
3794 basic_json_parser_26:
3795  yyaccept = 0;
3796  yych = *(m_marker = ++m_cursor);
3797  if (yych <= 0x00)
3798  {
3799  goto basic_json_parser_19;
3800  }
3801  goto basic_json_parser_31;
3802 basic_json_parser_27:
3803  ++m_cursor;
3804  {
3805  return token_type::end_of_input;
3806  }
3807 basic_json_parser_29:
3808  yych = *++m_cursor;
3809  goto basic_json_parser_19;
3810 basic_json_parser_30:
3811  ++m_cursor;
3812  if (m_limit <= m_cursor)
3813  {
3814  yyfill();
3815  };
3816  yych = *m_cursor;
3817 basic_json_parser_31:
3818  if (yybm[0 + yych] & 64)
3819  {
3820  goto basic_json_parser_30;
3821  }
3822  if (yych <= 0x00)
3823  {
3824  goto basic_json_parser_32;
3825  }
3826  if (yych <= '"')
3827  {
3828  goto basic_json_parser_34;
3829  }
3830  goto basic_json_parser_33;
3831 basic_json_parser_32:
3832  m_cursor = m_marker;
3833  if (yyaccept == 0)
3834  {
3835  goto basic_json_parser_19;
3836  }
3837  else
3838  {
3839  goto basic_json_parser_24;
3840  }
3841 basic_json_parser_33:
3842  ++m_cursor;
3843  if (m_limit <= m_cursor)
3844  {
3845  yyfill();
3846  };
3847  yych = *m_cursor;
3848  if (yych <= 'e')
3849  {
3850  if (yych <= '/')
3851  {
3852  if (yych == '"')
3853  {
3854  goto basic_json_parser_30;
3855  }
3856  if (yych <= '.')
3857  {
3858  goto basic_json_parser_32;
3859  }
3860  goto basic_json_parser_30;
3861  }
3862  else
3863  {
3864  if (yych <= '\\')
3865  {
3866  if (yych <= '[')
3867  {
3868  goto basic_json_parser_32;
3869  }
3870  goto basic_json_parser_30;
3871  }
3872  else
3873  {
3874  if (yych == 'b')
3875  {
3876  goto basic_json_parser_30;
3877  }
3878  goto basic_json_parser_32;
3879  }
3880  }
3881  }
3882  else
3883  {
3884  if (yych <= 'q')
3885  {
3886  if (yych <= 'f')
3887  {
3888  goto basic_json_parser_30;
3889  }
3890  if (yych == 'n')
3891  {
3892  goto basic_json_parser_30;
3893  }
3894  goto basic_json_parser_32;
3895  }
3896  else
3897  {
3898  if (yych <= 's')
3899  {
3900  if (yych <= 'r')
3901  {
3902  goto basic_json_parser_30;
3903  }
3904  goto basic_json_parser_32;
3905  }
3906  else
3907  {
3908  if (yych <= 't')
3909  {
3910  goto basic_json_parser_30;
3911  }
3912  if (yych <= 'u')
3913  {
3914  goto basic_json_parser_36;
3915  }
3916  goto basic_json_parser_32;
3917  }
3918  }
3919  }
3920 basic_json_parser_34:
3921  ++m_cursor;
3922  {
3923  return token_type::value_string;
3924  }
3925 basic_json_parser_36:
3926  ++m_cursor;
3927  if (m_limit <= m_cursor)
3928  {
3929  yyfill();
3930  };
3931  yych = *m_cursor;
3932  if (yych <= '@')
3933  {
3934  if (yych <= '/')
3935  {
3936  goto basic_json_parser_32;
3937  }
3938  if (yych >= ':')
3939  {
3940  goto basic_json_parser_32;
3941  }
3942  }
3943  else
3944  {
3945  if (yych <= 'F')
3946  {
3947  goto basic_json_parser_37;
3948  }
3949  if (yych <= '`')
3950  {
3951  goto basic_json_parser_32;
3952  }
3953  if (yych >= 'g')
3954  {
3955  goto basic_json_parser_32;
3956  }
3957  }
3958 basic_json_parser_37:
3959  ++m_cursor;
3960  if (m_limit <= m_cursor)
3961  {
3962  yyfill();
3963  };
3964  yych = *m_cursor;
3965  if (yych <= '@')
3966  {
3967  if (yych <= '/')
3968  {
3969  goto basic_json_parser_32;
3970  }
3971  if (yych >= ':')
3972  {
3973  goto basic_json_parser_32;
3974  }
3975  }
3976  else
3977  {
3978  if (yych <= 'F')
3979  {
3980  goto basic_json_parser_38;
3981  }
3982  if (yych <= '`')
3983  {
3984  goto basic_json_parser_32;
3985  }
3986  if (yych >= 'g')
3987  {
3988  goto basic_json_parser_32;
3989  }
3990  }
3991 basic_json_parser_38:
3992  ++m_cursor;
3993  if (m_limit <= m_cursor)
3994  {
3995  yyfill();
3996  };
3997  yych = *m_cursor;
3998  if (yych <= '@')
3999  {
4000  if (yych <= '/')
4001  {
4002  goto basic_json_parser_32;
4003  }
4004  if (yych >= ':')
4005  {
4006  goto basic_json_parser_32;
4007  }
4008  }
4009  else
4010  {
4011  if (yych <= 'F')
4012  {
4013  goto basic_json_parser_39;
4014  }
4015  if (yych <= '`')
4016  {
4017  goto basic_json_parser_32;
4018  }
4019  if (yych >= 'g')
4020  {
4021  goto basic_json_parser_32;
4022  }
4023  }
4024 basic_json_parser_39:
4025  ++m_cursor;
4026  if (m_limit <= m_cursor)
4027  {
4028  yyfill();
4029  };
4030  yych = *m_cursor;
4031  if (yych <= '@')
4032  {
4033  if (yych <= '/')
4034  {
4035  goto basic_json_parser_32;
4036  }
4037  if (yych <= '9')
4038  {
4039  goto basic_json_parser_30;
4040  }
4041  goto basic_json_parser_32;
4042  }
4043  else
4044  {
4045  if (yych <= 'F')
4046  {
4047  goto basic_json_parser_30;
4048  }
4049  if (yych <= '`')
4050  {
4051  goto basic_json_parser_32;
4052  }
4053  if (yych <= 'f')
4054  {
4055  goto basic_json_parser_30;
4056  }
4057  goto basic_json_parser_32;
4058  }
4059 basic_json_parser_40:
4060  yyaccept = 1;
4061  m_marker = ++m_cursor;
4062  if ((m_limit - m_cursor) < 3)
4063  {
4064  yyfill();
4065  };
4066  yych = *m_cursor;
4067 basic_json_parser_41:
4068  if (yybm[0 + yych] & 128)
4069  {
4070  goto basic_json_parser_40;
4071  }
4072  if (yych <= 'D')
4073  {
4074  if (yych != '.')
4075  {
4076  goto basic_json_parser_24;
4077  }
4078  }
4079  else
4080  {
4081  if (yych <= 'E')
4082  {
4083  goto basic_json_parser_43;
4084  }
4085  if (yych == 'e')
4086  {
4087  goto basic_json_parser_43;
4088  }
4089  goto basic_json_parser_24;
4090  }
4091 basic_json_parser_42:
4092  yych = *++m_cursor;
4093  if (yych <= '/')
4094  {
4095  goto basic_json_parser_32;
4096  }
4097  if (yych <= '9')
4098  {
4099  goto basic_json_parser_47;
4100  }
4101  goto basic_json_parser_32;
4102 basic_json_parser_43:
4103  yych = *++m_cursor;
4104  if (yych <= ',')
4105  {
4106  if (yych != '+')
4107  {
4108  goto basic_json_parser_32;
4109  }
4110  }
4111  else
4112  {
4113  if (yych <= '-')
4114  {
4115  goto basic_json_parser_44;
4116  }
4117  if (yych <= '/')
4118  {
4119  goto basic_json_parser_32;
4120  }
4121  if (yych <= '9')
4122  {
4123  goto basic_json_parser_45;
4124  }
4125  goto basic_json_parser_32;
4126  }
4127 basic_json_parser_44:
4128  yych = *++m_cursor;
4129  if (yych <= '/')
4130  {
4131  goto basic_json_parser_32;
4132  }
4133  if (yych >= ':')
4134  {
4135  goto basic_json_parser_32;
4136  }
4137 basic_json_parser_45:
4138  ++m_cursor;
4139  if (m_limit <= m_cursor)
4140  {
4141  yyfill();
4142  };
4143  yych = *m_cursor;
4144  if (yych <= '/')
4145  {
4146  goto basic_json_parser_24;
4147  }
4148  if (yych <= '9')
4149  {
4150  goto basic_json_parser_45;
4151  }
4152  goto basic_json_parser_24;
4153 basic_json_parser_47:
4154  yyaccept = 1;
4155  m_marker = ++m_cursor;
4156  if ((m_limit - m_cursor) < 3)
4157  {
4158  yyfill();
4159  };
4160  yych = *m_cursor;
4161  if (yych <= 'D')
4162  {
4163  if (yych <= '/')
4164  {
4165  goto basic_json_parser_24;
4166  }
4167  if (yych <= '9')
4168  {
4169  goto basic_json_parser_47;
4170  }
4171  goto basic_json_parser_24;
4172  }
4173  else
4174  {
4175  if (yych <= 'E')
4176  {
4177  goto basic_json_parser_43;
4178  }
4179  if (yych == 'e')
4180  {
4181  goto basic_json_parser_43;
4182  }
4183  goto basic_json_parser_24;
4184  }
4185 basic_json_parser_49:
4186  yyaccept = 1;
4187  yych = *(m_marker = ++m_cursor);
4188  if (yych <= 'D')
4189  {
4190  if (yych == '.')
4191  {
4192  goto basic_json_parser_42;
4193  }
4194  goto basic_json_parser_24;
4195  }
4196  else
4197  {
4198  if (yych <= 'E')
4199  {
4200  goto basic_json_parser_43;
4201  }
4202  if (yych == 'e')
4203  {
4204  goto basic_json_parser_43;
4205  }
4206  goto basic_json_parser_24;
4207  }
4208 basic_json_parser_50:
4209  yych = *++m_cursor;
4210  if (yych != 'l')
4211  {
4212  goto basic_json_parser_32;
4213  }
4214  yych = *++m_cursor;
4215  if (yych != 's')
4216  {
4217  goto basic_json_parser_32;
4218  }
4219  yych = *++m_cursor;
4220  if (yych != 'e')
4221  {
4222  goto basic_json_parser_32;
4223  }
4224  ++m_cursor;
4225  {
4226  return token_type::literal_false;
4227  }
4228 basic_json_parser_55:
4229  yych = *++m_cursor;
4230  if (yych != 'u')
4231  {
4232  goto basic_json_parser_32;
4233  }
4234  yych = *++m_cursor;
4235  if (yych != 'e')
4236  {
4237  goto basic_json_parser_32;
4238  }
4239  ++m_cursor;
4240  {
4241  return token_type::literal_true;
4242  }
4243 basic_json_parser_59:
4244  yych = *++m_cursor;
4245  if (yych != 'l')
4246  {
4247  goto basic_json_parser_32;
4248  }
4249  yych = *++m_cursor;
4250  if (yych != 'l')
4251  {
4252  goto basic_json_parser_32;
4253  }
4254  ++m_cursor;
4255  {
4256  return token_type::literal_null;
4257  }
4258  }
4259 
4260 
4261  }
4262 
4264  inline void yyfill() noexcept
4265  {
4266  if (not m_stream or not * m_stream)
4267  {
4268  return;
4269  }
4270 
4271  const ssize_t offset_start = m_start - m_content;
4272  const ssize_t offset_marker = m_marker - m_start;
4273  const ssize_t offset_cursor = m_cursor - m_start;
4274 
4275  m_buffer.erase(0, static_cast<size_t>(offset_start));
4276  std::string line;
4277  std::getline(*m_stream, line);
4278  m_buffer += line;
4279 
4280  m_content = reinterpret_cast<const lexer_char_t*>(m_buffer.c_str());
4281  m_start = m_content;
4282  m_marker = m_start + offset_marker;
4283  m_cursor = m_start + offset_cursor;
4284  m_limit = m_start + m_buffer.size() - 1;
4285  }
4286 
4288  inline string_t get_token() const noexcept
4289  {
4290  return string_t(reinterpret_cast<typename string_t::const_pointer>(m_start),
4291  static_cast<size_t>(m_cursor - m_start));
4292  }
4293 
4315  inline string_t get_string() const
4316  {
4317  string_t result;
4318  result.reserve(static_cast<size_t>(m_cursor - m_start - 2));
4319 
4320  // iterate the result between the quotes
4321  for (const lexer_char_t* i = m_start + 1; i < m_cursor - 1; ++i)
4322  {
4323  // process escaped characters
4324  if (*i == '\\')
4325  {
4326  // read next character
4327  ++i;
4328 
4329  switch (*i)
4330  {
4331  // the default escapes
4332  case 't':
4333  {
4334  result += "\t";
4335  break;
4336  }
4337  case 'b':
4338  {
4339  result += "\b";
4340  break;
4341  }
4342  case 'f':
4343  {
4344  result += "\f";
4345  break;
4346  }
4347  case 'n':
4348  {
4349  result += "\n";
4350  break;
4351  }
4352  case 'r':
4353  {
4354  result += "\r";
4355  break;
4356  }
4357 
4358  // characters that are not "un"escsaped
4359  case '\\':
4360  {
4361  result += "\\\\";
4362  break;
4363  }
4364  case '/':
4365  {
4366  result += "\\/";
4367  break;
4368  }
4369  case '"':
4370  {
4371  result += "\\\"";
4372  break;
4373  }
4374 
4375  // unicode
4376  case 'u':
4377  {
4378  // get code xxxx from uxxxx
4379  auto codepoint = std::strtoul(std::string(reinterpret_cast<typename string_t::const_pointer>(i + 1),
4380  4).c_str(), nullptr, 16);
4381 
4382  if (codepoint >= 0xD800 and codepoint <= 0xDBFF)
4383  {
4384  // make sure there is a subsequent unicode
4385  if ((i + 6 >= m_limit) or * (i + 5) != '\\' or * (i + 6) != 'u')
4386  {
4387  throw std::invalid_argument("missing low surrogate");
4388  }
4389 
4390  // get code yyyy from uxxxx\uyyyy
4391  auto codepoint2 = std::strtoul(std::string(reinterpret_cast<typename string_t::const_pointer>
4392  (i + 7), 4).c_str(), nullptr, 16);
4393  result += to_unicode(codepoint, codepoint2);
4394  // skip the next 11 characters (xxxx\uyyyy)
4395  i += 11;
4396  }
4397  else
4398  {
4399  // add unicode character(s)
4400  result += to_unicode(codepoint);
4401  // skip the next four characters (xxxx)
4402  i += 4;
4403  }
4404  break;
4405  }
4406  }
4407  }
4408  else
4409  {
4410  // all other characters are just copied to the end of the
4411  // string
4412  result.append(1, static_cast<typename string_t::value_type>(*i));
4413  }
4414  }
4415 
4416  return result;
4417  }
4418 
4437  {
4438  // conversion
4439  typename string_t::value_type* endptr;
4440  const auto float_val = std::strtod(reinterpret_cast<typename string_t::const_pointer>(m_start),
4441  &endptr);
4442 
4443  // return float_val if the whole number was translated and NAN
4444  // otherwise
4445  return (reinterpret_cast<lexer_char_t*>(endptr) == m_cursor) ? float_val : NAN;
4446  }
4447 
4448  private:
4450  std::istream* m_stream;
4454  const lexer_char_t* m_content = nullptr;
4456  const lexer_char_t* m_start = nullptr;
4458  const lexer_char_t* m_marker = nullptr;
4460  const lexer_char_t* m_cursor = nullptr;
4462  const lexer_char_t* m_limit = nullptr;
4463  };
4464 
4468  class parser
4469  {
4470  public:
4472  inline parser(const string_t& s) : m_lexer(s)
4473  {
4474  // read first token
4475  get_token();
4476  }
4477 
4479  inline parser(std::istream& _is) : m_lexer(&_is)
4480  {
4481  // read first token
4482  get_token();
4483  }
4484 
4487  {
4488  basic_json result = parse_internal();
4489 
4490  expect(lexer::token_type::end_of_input);
4491 
4492  return result;
4493  }
4494 
4495  private:
4498  {
4499  switch (last_token)
4500  {
4501  case (lexer::token_type::begin_object):
4502  {
4503  // explicitly set result to object to cope with {}
4504  basic_json result(value_t::object);
4505 
4506  // read next token
4507  get_token();
4508 
4509  // closing } -> we are done
4510  if (last_token == lexer::token_type::end_object)
4511  {
4512  get_token();
4513  return result;
4514  }
4515 
4516  // otherwise: parse key-value pairs
4517  do
4518  {
4519  // ugly, but could be fixed with loop reorganization
4520  if (last_token == lexer::token_type::value_separator)
4521  {
4522  get_token();
4523  }
4524 
4525  // store key
4526  expect(lexer::token_type::value_string);
4527  const auto key = m_lexer.get_string();
4528 
4529  // parse separator (:)
4530  get_token();
4531  expect(lexer::token_type::name_separator);
4532 
4533  // parse value
4534  get_token();
4535  result[key] = parse_internal();
4536  }
4537  while (last_token == lexer::token_type::value_separator);
4538 
4539  // closing }
4540  expect(lexer::token_type::end_object);
4541  get_token();
4542 
4543  return result;
4544  }
4545 
4546  case (lexer::token_type::begin_array):
4547  {
4548  // explicitly set result to object to cope with []
4549  basic_json result(value_t::array);
4550 
4551  // read next token
4552  get_token();
4553 
4554  // closing ] -> we are done
4555  if (last_token == lexer::token_type::end_array)
4556  {
4557  get_token();
4558  return result;
4559  }
4560 
4561  // otherwise: parse values
4562  do
4563  {
4564  // ugly, but could be fixed with loop reorganization
4565  if (last_token == lexer::token_type::value_separator)
4566  {
4567  get_token();
4568  }
4569 
4570  // parse value
4571  result.push_back(parse_internal());
4572  }
4573  while (last_token == lexer::token_type::value_separator);
4574 
4575  // closing ]
4576  expect(lexer::token_type::end_array);
4577  get_token();
4578 
4579  return result;
4580  }
4581 
4582  case (lexer::token_type::literal_null):
4583  {
4584  get_token();
4585  return basic_json(nullptr);
4586  }
4587 
4588  case (lexer::token_type::value_string):
4589  {
4590  const auto s = m_lexer.get_string();
4591  get_token();
4592  return basic_json(s);
4593  }
4594 
4595  case (lexer::token_type::literal_true):
4596  {
4597  get_token();
4598  return basic_json(true);
4599  }
4600 
4601  case (lexer::token_type::literal_false):
4602  {
4603  get_token();
4604  return basic_json(false);
4605  }
4606 
4607  case (lexer::token_type::value_number):
4608  {
4609  auto float_val = m_lexer.get_number();
4610 
4611  // NAN is returned if token could not be translated
4612  // completely
4613  if (std::isnan(float_val))
4614  {
4615  throw std::invalid_argument(std::string("parse error - ") +
4616  m_lexer.get_token() + " is not a number");
4617  }
4618 
4619  get_token();
4620 
4621  // check if conversion loses precision
4622  const auto int_val = static_cast<number_integer_t>(float_val);
4623  if (approx(float_val, static_cast<number_float_t>(int_val)))
4624  {
4625  // we basic_json not lose precision -> return int
4626  return basic_json(int_val);
4627  }
4628  else
4629  {
4630  // we would lose precision -> returnfloat
4631  return basic_json(float_val);
4632  }
4633  }
4634 
4635  default:
4636  {
4637  std::string error_msg = "parse error - unexpected \'";
4638  error_msg += m_lexer.get_token();
4639  error_msg += "\' (";
4640  error_msg += lexer::token_type_name(last_token) + ")";
4641  throw std::invalid_argument(error_msg);
4642  }
4643  }
4644  }
4645 
4647  inline typename lexer::token_type get_token()
4648  {
4649  last_token = m_lexer.scan();
4650  return last_token;
4651  }
4652 
4653  inline void expect(typename lexer::token_type t) const
4654  {
4655  if (t != last_token)
4656  {
4657  std::string error_msg = "parse error - unexpected \'";
4658  error_msg += m_lexer.get_token();
4659  error_msg += "\' (" + lexer::token_type_name(last_token);
4660  error_msg += "); expected " + lexer::token_type_name(t);
4661  throw std::invalid_argument(error_msg);
4662  }
4663  }
4664 
4665  private:
4667  typename lexer::token_type last_token = lexer::token_type::uninitialized;
4670  };
4671 };
4672 
4673 
4675 // presets //
4677 
4680 }
4681 
4682 
4684 // nonmember functions //
4686 
4687 // specialization of std::swap, and std::hash
4688 namespace std
4689 {
4694 template <>
4695 inline void swap(nlohmann::json& j1,
4696  nlohmann::json& j2) noexcept(
4697  is_nothrow_move_constructible<nlohmann::json>::value and
4698  is_nothrow_move_assignable<nlohmann::json>::value
4699  )
4700 {
4701  j1.swap(j2);
4702 }
4703 
4705 template <>
4706 struct hash<nlohmann::json>
4707 {
4709  inline size_t operator()(const nlohmann::json& j) const
4710  {
4711  // a naive hashing via the string representation
4712  const auto& h = hash<nlohmann::json::string_t>();
4713  return h(j.dump());
4714  }
4715 };
4716 }
4717 
4726 inline nlohmann::json operator "" _json(const char* s, std::size_t)
4727 {
4728  return nlohmann::json::parse(reinterpret_cast<nlohmann::json::string_t::value_type*>
4729  (const_cast<char*>(s)));
4730 }
4731 
4732 #endif
json_value(boolean_t v)
constructor for booleans
Definition: json.hpp:228
T get() const
get a value (explicit)
Definition: json.hpp:1019
reference operator*()
return a reference to the value pointed to by the iterator
Definition: json.hpp:2350
const_iterator & operator-=(difference_type i)
subtract from iterator
Definition: json.hpp:3174
reference value()
return the key of an iterator
Definition: json.hpp:2732
std::vector< T > get_impl(std::vector< T > *) const
get an array (explicit)
Definition: json.hpp:897
const_iterator cbegin() const noexcept
returns a const iterator to the first element
Definition: json.hpp:1283
const_reverse_iterator crend() const noexcept
returns a const reverse iterator to one past the last element
Definition: json.hpp:1372
basic_json::iterator iterator
an iterator for a basic_json container
Definition: json.hpp:157
friend bool operator<(const_reference lhs, const_reference rhs) noexcept
comparison: less than
Definition: json.hpp:1763
void swap(array_t &other)
swaps the contents
Definition: json.hpp:1633
iterator operator-(difference_type i)
subtract from iterator
Definition: json.hpp:2650
const_reference operator[](size_type pos) const
access specified element
Definition: json.hpp:1087
friend bool operator<(const value_t lhs, const value_t rhs)
comparison operator for JSON value types
Definition: json.hpp:259
basic_json value_type
the type of elements in a basic_json container
Definition: json.hpp:119
basic_json(const number_float_t &value)
create a floating-point number (explicit)
Definition: json.hpp:512
static string_t escape_string(const string_t &s) noexcept
escape a string
Definition: json.hpp:1966
const_iterator & operator--()
pre-decrement (–it)
Definition: json.hpp:3040
const_iterator cend() const noexcept
returns a const iterator to one past the last element
Definition: json.hpp:1316
T get_impl(T *) const
get an object (explicit)
Definition: json.hpp:827
size_type count(typename object_t::key_type key) const
returns the number of occurrences of a key in an object
Definition: json.hpp:1246
number_float_t get_number() const
return number value for number tokens
Definition: json.hpp:4436
iterator begin() noexcept
returns an iterator to the first element
Definition: json.hpp:1261
reference value() const
return the value of an iterator
Definition: json.hpp:3269
void expect(typename lexer::token_type t) const
Definition: json.hpp:4653
static bool approx(const T a, const T b)
"equality" comparison for floating point numbers
Definition: json.hpp:2185
allocator_type get_allocator() const
returns the allocator associated with the container
Definition: json.hpp:179
reverse_iterator rbegin() noexcept
returns a reverse iterator to the first element
Definition: json.hpp:1327
const_iterator & operator=(const_iterator other) noexcept(std::is_nothrow_move_constructible< pointer >::value andstd::is_nothrow_move_assignable< pointer >::value andstd::is_nothrow_move_constructible< internal_iterator< typename array_t::const_iterator, typename object_t::const_iterator >>::valueandstd::is_nothrow_move_assignable< internal_iterator< typename array_t::const_iterator, typename object_t::const_iterator >>::value)
copy assignment
Definition: json.hpp:2819
basic_json::const_reverse_iterator const_reverse_iterator
a const reverse iterator for a basic_json container
Definition: json.hpp:175
lexer m_lexer
the lexer
Definition: json.hpp:4669
bool is_boolean() const noexcept
Definition: json.hpp:781
const_iterator & operator+=(difference_type i)
add to iterator
Definition: json.hpp:3147
string_t dump(const bool prettyPrint, const unsigned int indentStep, const unsigned int currentIndent=0) const noexcept
internal implementation of the serialization function
Definition: json.hpp:2066
iterator & operator+=(difference_type i)
add to iterator
Definition: json.hpp:2610
void set_begin() noexcept
set the iterator to the first value
Definition: json.hpp:2834
basic_json(boolean_t value)
create a boolean (explicit)
Definition: json.hpp:492
lexer::token_type get_token()
get next token from lexer
Definition: json.hpp:4647
friend std::ostream & operator<<(std::ostream &o, const basic_json &j)
serialize to stream
Definition: json.hpp:1862
object_t * object
object (stored with pointer to save storage)
Definition: json.hpp:213
const_iterator operator-(difference_type i)
subtract from iterator
Definition: json.hpp:3188
const_iterator(const iterator &other) noexcept
copy constructor given a nonconst iterator
Definition: json.hpp:2789
internal_iterator()
default constructor
Definition: json.hpp:2223
string_t dump(const int indent=-1) const noexcept
serialization
Definition: json.hpp:756
a random access iterator for the basic_json class
Definition: json.hpp:2228
bool operator<(const iterator &other) const
comparison: smaller
Definition: json.hpp:2564
pointer m_object
associated JSON instance
Definition: json.hpp:2739
basic_json parse_internal()
the actual parser
Definition: json.hpp:4497
const_reverse_iterator crbegin() const noexcept
returns a const reverse iterator to the first element
Definition: json.hpp:1363
a reverse random access iterator for the basic_json class
Definition: json.hpp:3282
BooleanType boolean_t
a type for a boolean
Definition: json.hpp:196
lexical analysis
Definition: json.hpp:3336
const_iterator operator--(int)
post-decrement (it–)
Definition: json.hpp:3011
const_reverse_iterator(const typename std::reverse_iterator< basic_json::const_iterator >::iterator_type &it)
Definition: json.hpp:3306
const_reference operator[](const T(&key)[n]) const
access specified element (needed for clang)
Definition: json.hpp:1179
size_type size() const noexcept
returns the number of elements
Definition: json.hpp:1417
string_t * string
string (stored with pointer to save storage)
Definition: json.hpp:217
const_reverse_iterator rbegin() const noexcept
returns a const reverse iterator to the first element
Definition: json.hpp:1336
const_iterator(pointer object) noexcept
constructor for a given JSON instance
Definition: json.hpp:2766
boolean_t boolean
bolean
Definition: json.hpp:219
std::istream * m_stream
optional input stream
Definition: json.hpp:4450
reference operator+=(basic_json &&value)
add an object to an array
Definition: json.hpp:1553
bool operator<=(const const_iterator &other) const
comparison: less than or equal
Definition: json.hpp:3129
object_t::key_type key() const
return the key of an object iterator
Definition: json.hpp:3290
lexer(std::istream *s) noexcept
Definition: json.hpp:3369
iterator end() noexcept
returns an iterator to one past the last element
Definition: json.hpp:1294
~basic_json() noexcept
destructor
Definition: json.hpp:697
json_value m_value
the value of the current element
Definition: json.hpp:2203
a const reverse random access iterator for the basic_json class
Definition: json.hpp:3303
difference_type operator-(const iterator &other) const
return difference
Definition: json.hpp:2658
void clear() noexcept
clears the contents
Definition: json.hpp:1481
std::ptrdiff_t difference_type
a type to represent differences between iterators
Definition: json.hpp:137
object_t get_impl(object_t *) const
get an object (explicit)
Definition: json.hpp:843
const_reference at(const typename object_t::key_type &key) const
access specified element with bounds checking
Definition: json.hpp:1111
basic_json(const object_t &value)
create an object (explicit)
Definition: json.hpp:410
string_t get_token() const noexcept
return string representation of last read token
Definition: json.hpp:4288
basic_json::const_iterator const_iterator
a const iterator for a basic_json container
Definition: json.hpp:163
reference operator[](size_type pos)
access specified element
Definition: json.hpp:1061
size_t operator()(const nlohmann::json &j) const
return a hash value for a JSON object
Definition: json.hpp:4709
value_t type() const noexcept
return the type of the object (explicit)
Definition: json.hpp:769
difference_type generic_iterator
generic iteraotr for all other value types
Definition: json.hpp:2220
iterator operator++(int)
post-increment (it++)
Definition: json.hpp:2418
reference operator[](difference_type n) const
access to successor
Definition: json.hpp:3218
void erase(const size_type pos)
remove element from an array given an index
Definition: json.hpp:1203
iterator operator+(difference_type i)
add to iterator
Definition: json.hpp:2642
object_t::key_type key() const
return the key of an object iterator
Definition: json.hpp:2715
string_t get_string() const
return string value for string tokens
Definition: json.hpp:4315
StringType string_t
a type for a string
Definition: json.hpp:194
void push_back(const basic_json &value)
add an object to an array
Definition: json.hpp:1560
static basic_json object(list_init_t l=list_init_t())
explicitly create an object from an initializer list
Definition: json.hpp:596
bool operator>(const iterator &other) const
comparison: greater than
Definition: json.hpp:2598
const_iterator end() const noexcept
returns a const iterator to one past the last element
Definition: json.hpp:1305
array_iterator_t array_iterator
iterator for JSON arrays
Definition: json.hpp:2218
reference at(size_type pos)
access specified element with bounds checking
Definition: json.hpp:1037
void push_back(basic_json &&value)
add an object to an array
Definition: json.hpp:1529
static basic_json array(list_init_t l=list_init_t())
explicitly create an array from an initializer list
Definition: json.hpp:590
parser(const string_t &s)
constructor for strings
Definition: json.hpp:4472
NumberIntegerType number_integer_t
a type for a number (integer)
Definition: json.hpp:198
pointer m_object
associated JSON instance
Definition: json.hpp:3276
reference value() const
return the value of an iterator
Definition: json.hpp:3296
void swap(reference other) noexcept(std::is_nothrow_move_constructible< value_t >::value andstd::is_nothrow_move_assignable< value_t >::value andstd::is_nothrow_move_constructible< json_value >::value andstd::is_nothrow_move_assignable< json_value >::value)
exchanges the values
Definition: json.hpp:1621
syntax analysis
Definition: json.hpp:4468
internal_iterator< typename array_t::iterator, typename object_t::iterator > m_it
the actual iterator of the associated instance
Definition: json.hpp:2741
basic_json::difference_type difference_type
a type to represent differences between iterators
Definition: json.hpp:2237
basic_json(const string_t &value)
create a string (explicit)
Definition: json.hpp:465
const_reverse_iterator rend() const noexcept
returns a const reverse iterator to one past the last element
Definition: json.hpp:1354
reference operator+=(const basic_json &value)
add an object to an array
Definition: json.hpp:1582
void swap(nlohmann::json &j1, nlohmann::json &j2) noexcept(is_nothrow_move_constructible< nlohmann::json >::value andis_nothrow_move_assignable< nlohmann::json >::value)
exchanges the values of two JSON objects
Definition: json.hpp:4695
basic_json * pointer
the type of an element pointer
Definition: json.hpp:149
void swap(string_t &other)
swaps the contents
Definition: json.hpp:1659
const basic_json & const_reference
the type of an element const reference
Definition: json.hpp:131
bool operator==(const iterator &other) const
comparison: equal
Definition: json.hpp:2530
iterator operator--(int)
post-decrement (it–)
Definition: json.hpp:2474
bool is_object() const noexcept
Definition: json.hpp:793
const basic_json * const_pointer
the type of an element const pointer
Definition: json.hpp:151
reference operator*() const
return a reference to the value pointed to by the iterator
Definition: json.hpp:2892
const_reference at(size_type pos) const
access specified element with bounds checking
Definition: json.hpp:1049
void set_begin() noexcept
set the iterator to the first value
Definition: json.hpp:2292
bool empty() const noexcept
checks whether the container is empty
Definition: json.hpp:1386
array_t get_impl(array_t *) const
Definition: json.hpp:940
std::bidirectional_iterator_tag iterator_category
the category of the iterator
Definition: json.hpp:2760
size_type max_size() const noexcept
returns the maximum possible number of elements
Definition: json.hpp:1448
friend std::istream & operator>>(std::istream &i, basic_json &j)
deserialize from stream
Definition: json.hpp:1899
basic_json(const V &value)
create an object (implicit)
Definition: json.hpp:424
static basic_json parse(const string_t &s)
deserialize from string
Definition: json.hpp:1887
friend std::ostream & operator>>(const basic_json &j, std::ostream &o)
serialize to stream
Definition: json.hpp:1872
friend std::istream & operator<<(basic_json &j, std::istream &i)
deserialize from stream
Definition: json.hpp:1906
static basic_json parse(std::istream &i)
deserialize from stream
Definition: json.hpp:1893
lexer(const string_t &s) noexcept
constructor with a given buffer
Definition: json.hpp:3362
Allocator< basic_json > allocator_type
the allocator type
Definition: json.hpp:146
reference operator[](const typename object_t::key_type &key)
access specified element
Definition: json.hpp:1123
json_value(number_float_t v)
constructor for numbers (floating-point)
Definition: json.hpp:232
basic_json(basic_json &&other) noexcept
move constructor
Definition: json.hpp:668
pointer operator->()
dereference the iterator
Definition: json.hpp:2384
NumberFloatType number_float_t
a type for a number (floating-point)
Definition: json.hpp:200
basic_json::difference_type difference_type
a type to represent differences between iterators
Definition: json.hpp:2754
iterator & operator--()
pre-decrement (–it)
Definition: json.hpp:2503
token_type
token types for the parser
Definition: json.hpp:3340
array (ordered collection of values)
static std::string token_type_name(token_type t) noexcept
return name of values of type token_type
Definition: json.hpp:3454
reference value() const
return the value of an iterator
Definition: json.hpp:3317
basic_json(const array_t &value)
create an array (explicit)
Definition: json.hpp:435
void yyfill() noexcept
append data from the stream to the internal buffer
Definition: json.hpp:4264
object_iterator_t object_iterator
iterator for JSON objects
Definition: json.hpp:2216
bool is_number() const noexcept
Definition: json.hpp:787
friend bool operator>(const_reference lhs, const_reference rhs) noexcept
comparison: greater than
Definition: json.hpp:1845
friend bool operator==(const_reference lhs, const_reference rhs) noexcept
comparison: equal
Definition: json.hpp:1680
pointer operator->() const
dereference the iterator
Definition: json.hpp:2926
basic_json(const T value) noexcept
create an integer number (implicit)
Definition: json.hpp:507
std::size_t size_type
a type to represent container sizes
Definition: json.hpp:143
bool operator>=(const const_iterator &other) const
comparison: greater than or equal
Definition: json.hpp:3141
string_t m_buffer
the buffer
Definition: json.hpp:4452
basic_json & reference
the type of an element reference
Definition: json.hpp:125
const_iterator & operator++()
pre-increment (++it)
Definition: json.hpp:2984
unsigned char lexer_char_t
the char type to use in the lexer
Definition: json.hpp:3359
void push_back(const typename object_t::value_type &value)
add an object to an object
Definition: json.hpp:1589
reference & operator=(basic_json other) noexcept(std::is_nothrow_move_constructible< value_t >::value andstd::is_nothrow_move_assignable< value_t >::value andstd::is_nothrow_move_constructible< json_value >::value andstd::is_nothrow_move_assignable< json_value >::value)
copy assignment
Definition: json.hpp:681
const_iterator operator+(difference_type i)
add to iterator
Definition: json.hpp:3180
number_integer_t number_integer
number (integer)
Definition: json.hpp:221
basic_json(const basic_json &other)
copy constructor
Definition: json.hpp:613
iterator(pointer object) noexcept
constructor for a given JSON instance
Definition: json.hpp:2249
size_type erase(const typename object_t::key_type &key)
remove element from an object given a key
Definition: json.hpp:1191
number_float_t number_float
number (floating-point)
Definition: json.hpp:223
basic_json(const value_t value)
create an empty value with a given type
Definition: json.hpp:344
token_type scan() noexcept
Definition: json.hpp:3499
object_t::key_type key() const
return the key of an object iterator
Definition: json.hpp:3252
basic_json(list_init_t l, bool type_deduction=true, value_t manual_type=value_t::array)
create a container (array or object) from an initializer list
Definition: json.hpp:527
boolean_t get_impl(boolean_t *) const
get a boolean (explicit)
Definition: json.hpp:1000
value_t
JSON value type enumeration.
Definition: json.hpp:241
const_iterator find(typename object_t::key_type key) const
find an element in an object
Definition: json.hpp:1233
basic_json(const typename string_t::value_type *value)
create a string (explicit)
Definition: json.hpp:474
const_iterator begin() const noexcept
returns a const iterator to the first element
Definition: json.hpp:1272
bool operator<=(const iterator &other) const
comparison: less than or equal
Definition: json.hpp:2592
static string_t to_unicode(const size_t codepoint1, const size_t codepoint2=0)
create a string from a Unicode code point
Definition: json.hpp:3392
const_iterator(const const_iterator &other) noexcept
copy constructor
Definition: json.hpp:2814
object (unordered set of name/value pairs)
reverse_iterator rend() noexcept
returns a reverse iterator to one past the last element
Definition: json.hpp:1345
void set_end() noexcept
set the iterator past the last value
Definition: json.hpp:2324
bool is_null() const noexcept
Definition: json.hpp:775
bool operator!=(const iterator &other) const
comparison: not equal
Definition: json.hpp:2558
basic_json(const number_integer_t &value)
create an integer number (explicit)
Definition: json.hpp:497
std::initializer_list< basic_json > list_init_t
a type for list initialization
Definition: json.hpp:202
json_value(number_integer_t v)
constructor for numbers (integer)
Definition: json.hpp:230
bool is_array() const noexcept
Definition: json.hpp:799
basic_json parse()
public parser interface
Definition: json.hpp:4486
bool operator<(const const_iterator &other) const
comparison: smaller
Definition: json.hpp:3101
reference at(const typename object_t::key_type &key)
access specified element with bounds checking
Definition: json.hpp:1099
std::bidirectional_iterator_tag iterator_category
the category of the iterator
Definition: json.hpp:2243
const_iterator operator++(int)
post-increment (it++)
Definition: json.hpp:2955
reference operator[](difference_type n)
access to successor
Definition: json.hpp:2681
friend bool operator!=(const_reference lhs, const_reference rhs) noexcept
comparison: not equal
Definition: json.hpp:1757
void set_end() noexcept
set the iterator past the last value
Definition: json.hpp:2866
iterator & operator++()
pre-increment (++it)
Definition: json.hpp:2447
basic_json<> json
default JSON class
Definition: json.hpp:4679
bool is_string() const noexcept
Definition: json.hpp:805
a const random access iterator for the basic_json class
Definition: json.hpp:2745
reverse_iterator(const typename std::reverse_iterator< basic_json::iterator >::iterator_type &it)
Definition: json.hpp:3285
ObjectType< StringType, basic_json > object_t
a type for an object
Definition: json.hpp:190
bool operator!=(const const_iterator &other) const
comparison: not equal
Definition: json.hpp:3095
bool operator>(const const_iterator &other) const
comparison: greater than
Definition: json.hpp:3135
reference operator[](const T(&key)[n])
access specified element (needed for clang)
Definition: json.hpp:1157
friend bool operator<=(const_reference lhs, const_reference rhs) noexcept
comparison: less than or equal
Definition: json.hpp:1839
reference operator+=(const typename object_t::value_type &value)
add an object to an object
Definition: json.hpp:1611
void swap(object_t &other)
swaps the contents
Definition: json.hpp:1646
friend bool operator>=(const_reference lhs, const_reference rhs) noexcept
comparison: greater than or equal
Definition: json.hpp:1851
iterator find(typename object_t::key_type key)
find an element in an object
Definition: json.hpp:1220
parser(std::istream &_is)
a parser reading from an input stream
Definition: json.hpp:4479
iterator(const iterator &other) noexcept
copy constructor
Definition: json.hpp:2272
internal_iterator< typename array_t::const_iterator, typename object_t::const_iterator > m_it
the actual iterator of the associated instance
Definition: json.hpp:3278
static char test(typename C::mapped_type *)
array_t * array
array (stored with pointer to save storage)
Definition: json.hpp:215
const_reference operator[](const typename object_t::key_type &key) const
access specified element
Definition: json.hpp:1144
string_t type_name() const noexcept
return the type as string
Definition: json.hpp:1919
difference_type operator-(const const_iterator &other) const
return difference
Definition: json.hpp:3196
ArrayType< basic_json > array_t
a type for an array
Definition: json.hpp:192
iterator & operator-=(difference_type i)
subtract from iterator
Definition: json.hpp:2636
iterator & operator=(iterator other) noexcept(std::is_nothrow_move_constructible< pointer >::value andstd::is_nothrow_move_assignable< pointer >::value andstd::is_nothrow_move_constructible< internal_iterator< typename array_t::iterator, typename object_t::iterator >>::valueandstd::is_nothrow_move_assignable< internal_iterator< typename array_t::iterator, typename object_t::iterator >>::value)
copy assignment
Definition: json.hpp:2277
basic_json::reverse_iterator reverse_iterator
a reverse iterator for a basic_json container
Definition: json.hpp:169
object_t::key_type key() const
return the key of an object iterator
Definition: json.hpp:3311
bool operator>=(const iterator &other) const
comparison: greater than or equal
Definition: json.hpp:2604
bool operator==(const const_iterator &other) const
comparison: equal
Definition: json.hpp:3067