JSON for Modern C++  1.0.0-rc1
json.hpp
1 
38 #ifndef NLOHMANN_JSON_HPP
39 #define NLOHMANN_JSON_HPP
40 
41 #include <algorithm>
42 #include <array>
43 #include <ciso646>
44 #include <cmath>
45 #include <cstdio>
46 #include <functional>
47 #include <initializer_list>
48 #include <iomanip>
49 #include <iostream>
50 #include <iterator>
51 #include <limits>
52 #include <map>
53 #include <memory>
54 #include <sstream>
55 #include <string>
56 #include <type_traits>
57 #include <utility>
58 #include <vector>
59 
60 // enable ssize_t on MinGW
61 #ifdef __GNUC__
62  #ifdef __MINGW32__
63  #include <sys/types.h>
64  #endif
65 #endif
66 
67 // enable ssize_t for MSVC
68 #ifdef _MSC_VER
69  #include <basetsd.h>
70  using ssize_t = SSIZE_T;
71 #endif
72 
78 namespace nlohmann
79 {
80 
81 
86 namespace
87 {
92 template<typename T>
93 struct has_mapped_type
94 {
95  private:
96  template<typename C> static char test(typename C::mapped_type*);
97  template<typename C> static int test(...);
98  public:
99  enum { value = sizeof(test<T>(0)) == sizeof(char) };
100 };
101 
103 template<typename T>
104 static bool approx(const T a, const T b)
105 {
106  return not (a > b or a < b);
107 }
108 }
109 
178 template <
179  template<typename U, typename V, typename... Args> class ObjectType = std::map,
180  template<typename U, typename... Args> class ArrayType = std::vector,
181  class StringType = std::string,
182  class BooleanType = bool,
183  class NumberIntegerType = int64_t,
184  class NumberFloatType = double,
185  template<typename U> class AllocatorType = std::allocator
186  >
188 {
189  private:
191  using basic_json_t = basic_json<ObjectType,
192  ArrayType,
193  StringType,
194  BooleanType,
195  NumberIntegerType,
196  NumberFloatType,
197  AllocatorType>;
198 
199  public:
200 
202  // container types //
204 
207 
210 
213 
215  using const_reference = const value_type&;
216 
218  using difference_type = std::ptrdiff_t;
219 
221  using size_type = std::size_t;
222 
224  using allocator_type = AllocatorType<basic_json>;
225 
227  using pointer = typename std::allocator_traits<allocator_type>::pointer;
229  using const_pointer = typename std::allocator_traits<allocator_type>::const_pointer;
230 
231  // forward declaration
232  template<typename Base> class json_reverse_iterator;
233 
235  class iterator;
237  class const_iterator;
242 
244 
245 
250  {
251  return allocator_type();
252  }
253 
254 
256  // JSON value data types //
258 
261 
336  using object_t = ObjectType<StringType,
337  basic_json,
338  std::less<StringType>,
339  AllocatorType<std::pair<const StringType,
340  basic_json>>>;
341 
386  using array_t = ArrayType<basic_json, AllocatorType<basic_json>>;
387 
433  using string_t = StringType;
434 
459  using boolean_t = BooleanType;
460 
527  using number_integer_t = NumberIntegerType;
528 
592  using number_float_t = NumberFloatType;
593 
595 
596 
598  // JSON type enumeration //
600 
611  enum class value_t : uint8_t
612  {
613  null,
614  object,
615  array,
616  string,
617  boolean,
619  number_float,
620  discarded
621  };
622 
623 
624  private:
626  template<typename T, typename... Args>
627  static T* create(Args&& ... args)
628  {
629  AllocatorType<T> alloc;
630  auto deleter = [&](T * object)
631  {
632  alloc.deallocate(object, 1);
633  };
634  std::unique_ptr<T, decltype(deleter)> object(alloc.allocate(1), deleter);
635  alloc.construct(object.get(), std::forward<Args>(args)...);
636  return object.release();
637  }
638 
640  // JSON value storage //
642 
650  union json_value
651  {
653  object_t* object;
655  array_t* array;
657  string_t* string;
659  boolean_t boolean;
661  number_integer_t number_integer;
663  number_float_t number_float;
664 
666  json_value() noexcept = default;
668  json_value(boolean_t v) noexcept : boolean(v) {}
670  json_value(number_integer_t v) noexcept : number_integer(v) {}
672  json_value(number_float_t v) noexcept : number_float(v) {}
674  json_value(value_t t)
675  {
676  switch (t)
677  {
678  case value_t::object:
679  {
680  object = create<object_t>();
681  break;
682  }
683 
684  case value_t::array:
685  {
686  array = create<array_t>();
687  break;
688  }
689 
690  case value_t::string:
691  {
692  string = create<string_t>("");
693  break;
694  }
695 
696  case value_t::boolean:
697  {
698  boolean = boolean_t(false);
699  break;
700  }
701 
703  {
704  number_integer = number_integer_t(0);
705  break;
706  }
707 
709  {
710  number_float = number_float_t(0.0);
711  break;
712  }
713 
714  default:
715  {
716  break;
717  }
718  }
719  }
720 
722  json_value(const string_t& value)
723  {
724  string = create<string_t>(value);
725  }
726 
728  json_value(const object_t& value)
729  {
730  object = create<object_t>(value);
731  }
732 
734  json_value(const array_t& value)
735  {
736  array = create<array_t>(value);
737  }
738  };
739 
740 
741  public:
743  // JSON parser callback //
745 
754  enum class parse_event_t : uint8_t
755  {
757  object_start,
759  object_end,
761  array_start,
763  array_end,
765  key,
767  value
768  };
769 
819  using parser_callback_t = std::function<bool(int depth, parse_event_t event, basic_json& parsed)>;
820 
821 
823  // constructors //
825 
828 
867  : m_type(value), m_value(value)
868  {}
869 
889  basic_json() noexcept = default;
890 
910  basic_json(std::nullptr_t) noexcept
911  : basic_json(value_t::null)
912  {}
913 
934  : m_type(value_t::object), m_value(value)
935  {}
936 
960  template <class CompatibleObjectType, typename
961  std::enable_if<
962  std::is_constructible<typename object_t::key_type, typename CompatibleObjectType::key_type>::value and
963  std::is_constructible<basic_json, typename CompatibleObjectType::mapped_type>::value, int>::type
964  = 0>
965  basic_json(const CompatibleObjectType& value)
966  : m_type(value_t::object)
967  {
968  using std::begin;
969  using std::end;
970  m_value.object = create<object_t>(begin(value), end(value));
971  }
972 
993  : m_type(value_t::array), m_value(value)
994  {}
995 
1019  template <class CompatibleArrayType, typename
1020  std::enable_if<
1021  not std::is_same<CompatibleArrayType, typename basic_json_t::iterator>::value and
1022  not std::is_same<CompatibleArrayType, typename basic_json_t::const_iterator>::value and
1023  not std::is_same<CompatibleArrayType, typename basic_json_t::reverse_iterator>::value and
1024  not std::is_same<CompatibleArrayType, typename basic_json_t::const_reverse_iterator>::value and
1025  not std::is_same<CompatibleArrayType, typename array_t::iterator>::value and
1026  not std::is_same<CompatibleArrayType, typename array_t::const_iterator>::value and
1027  std::is_constructible<basic_json, typename CompatibleArrayType::value_type>::value, int>::type
1028  = 0>
1029  basic_json(const CompatibleArrayType& value)
1030  : m_type(value_t::array)
1031  {
1032  using std::begin;
1033  using std::end;
1034  m_value.array = create<array_t>(begin(value), end(value));
1035  }
1036 
1059  : m_type(value_t::string), m_value(value)
1060  {}
1061 
1082  basic_json(const typename string_t::value_type* value)
1083  : basic_json(string_t(value))
1084  {}
1085 
1109  template <class CompatibleStringType, typename
1110  std::enable_if<
1111  std::is_constructible<string_t, CompatibleStringType>::value, int>::type
1112  = 0>
1113  basic_json(const CompatibleStringType& value)
1114  : basic_json(string_t(value))
1115  {}
1116 
1132  : m_type(value_t::boolean), m_value(value)
1133  {}
1134 
1160  template<typename T,
1161  typename std::enable_if<
1162  not (std::is_same<T, int>::value)
1163  and std::is_same<T, number_integer_t>::value
1164  , int>::type = 0>
1165  basic_json(const number_integer_t value)
1166  : m_type(value_t::number_integer), m_value(value)
1167  {}
1168 
1194  basic_json(const int value)
1195  : m_type(value_t::number_integer),
1196  m_value(static_cast<number_integer_t>(value))
1197  {}
1198 
1224  template<typename CompatibleNumberIntegerType, typename
1225  std::enable_if<
1226  std::is_constructible<number_integer_t, CompatibleNumberIntegerType>::value and
1227  std::numeric_limits<CompatibleNumberIntegerType>::is_integer, CompatibleNumberIntegerType>::type
1228  = 0>
1229  basic_json(const CompatibleNumberIntegerType value) noexcept
1230  : m_type(value_t::number_integer),
1231  m_value(static_cast<number_integer_t>(value))
1232  {}
1233 
1259  : m_type(value_t::number_float), m_value(value)
1260  {
1261  // replace infinity and NAN by null
1262  if (not std::isfinite(value))
1263  {
1264  m_type = value_t::null;
1265  m_value = json_value();
1266  }
1267  }
1268 
1299  template<typename CompatibleNumberFloatType, typename = typename
1300  std::enable_if<
1301  std::is_constructible<number_float_t, CompatibleNumberFloatType>::value and
1302  std::is_floating_point<CompatibleNumberFloatType>::value>::type
1303  >
1304  basic_json(const CompatibleNumberFloatType value) noexcept
1306  {}
1307 
1376  basic_json(std::initializer_list<basic_json> init,
1377  bool type_deduction = true,
1378  value_t manual_type = value_t::array)
1379  {
1380  // the initializer list could describe an object
1381  bool is_object = true;
1382 
1383  // check if each element is an array with two elements whose first
1384  // element is a string
1385  for (const auto& element : init)
1386  {
1387  if (not element.is_array() or element.size() != 2
1388  or not element[0].is_string())
1389  {
1390  // we found an element that makes it impossible to use the
1391  // initializer list as object
1392  is_object = false;
1393  break;
1394  }
1395  }
1396 
1397  // adjust type if type deduction is not wanted
1398  if (not type_deduction)
1399  {
1400  // if array is wanted, do not create an object though possible
1401  if (manual_type == value_t::array)
1402  {
1403  is_object = false;
1404  }
1405 
1406  // if object is wanted but impossible, throw an exception
1407  if (manual_type == value_t::object and not is_object)
1408  {
1409  throw std::domain_error("cannot create object from initializer list");
1410  }
1411  }
1412 
1413  if (is_object)
1414  {
1415  // the initializer list is a list of pairs -> create object
1416  m_type = value_t::object;
1417  m_value = value_t::object;
1418 
1419  for (auto& element : init)
1420  {
1421  m_value.object->emplace(std::move(*(element[0].m_value.string)), std::move(element[1]));
1422  }
1423  }
1424  else
1425  {
1426  // the initializer list describes an array -> create array
1427  m_type = value_t::array;
1428  m_value.array = create<array_t>(std::move(init));
1429  }
1430  }
1431 
1466  static basic_json array(std::initializer_list<basic_json> init =
1467  std::initializer_list<basic_json>())
1468  {
1469  return basic_json(init, false, value_t::array);
1470  }
1471 
1506  static basic_json object(std::initializer_list<basic_json> init =
1507  std::initializer_list<basic_json>())
1508  {
1509  return basic_json(init, false, value_t::object);
1510  }
1511 
1530  basic_json(size_type count, const basic_json& value)
1531  : m_type(value_t::array)
1532  {
1533  m_value.array = create<array_t>(count, value);
1534  }
1535 
1568  template <class InputIT, typename
1569  std::enable_if<
1570  std::is_same<InputIT, typename basic_json_t::iterator>::value or
1571  std::is_same<InputIT, typename basic_json_t::const_iterator>::value
1572  , int>::type
1573  = 0>
1574  basic_json(InputIT first, InputIT last) : m_type(first.m_object->m_type)
1575  {
1576  // make sure iterator fits the current value
1577  if (first.m_object != last.m_object)
1578  {
1579  throw std::domain_error("iterators are not compatible");
1580  }
1581 
1582  // check if iterator range is complete for primitive values
1583  switch (m_type)
1584  {
1585  case value_t::boolean:
1586  case value_t::number_float:
1588  case value_t::string:
1589  {
1590  if (not first.m_it.primitive_iterator.is_begin() or not last.m_it.primitive_iterator.is_end())
1591  {
1592  throw std::out_of_range("iterators out of range");
1593  }
1594  break;
1595  }
1596 
1597  default:
1598  {
1599  break;
1600  }
1601  }
1602 
1603  switch (m_type)
1604  {
1606  {
1607  m_value.number_integer = first.m_object->m_value.number_integer;
1608  break;
1609  }
1610 
1611  case value_t::number_float:
1612  {
1613  m_value.number_float = first.m_object->m_value.number_float;
1614  break;
1615  }
1616 
1617  case value_t::boolean:
1618  {
1619  m_value.boolean = first.m_object->m_value.boolean;
1620  break;
1621  }
1622 
1623  case value_t::string:
1624  {
1625  m_value = *first.m_object->m_value.string;
1626  break;
1627  }
1628 
1629  case value_t::object:
1630  {
1631  m_value.object = create<object_t>(first.m_it.object_iterator, last.m_it.object_iterator);
1632  break;
1633  }
1634 
1635  case value_t::array:
1636  {
1637  m_value.array = create<array_t>(first.m_it.array_iterator, last.m_it.array_iterator);
1638  break;
1639  }
1640 
1641  default:
1642  {
1643  throw std::domain_error("cannot use construct with iterators from " + first.m_object->type_name());
1644  }
1645  }
1646  }
1647 
1649  // other constructors and destructor //
1651 
1672  basic_json(const basic_json& other)
1673  : m_type(other.m_type)
1674  {
1675  switch (m_type)
1676  {
1677  case value_t::object:
1678  {
1679  m_value = *other.m_value.object;
1680  break;
1681  }
1682 
1683  case value_t::array:
1684  {
1685  m_value = *other.m_value.array;
1686  break;
1687  }
1688 
1689  case value_t::string:
1690  {
1691  m_value = *other.m_value.string;
1692  break;
1693  }
1694 
1695  case value_t::boolean:
1696  {
1697  m_value = other.m_value.boolean;
1698  break;
1699  }
1700 
1702  {
1703  m_value = other.m_value.number_integer;
1704  break;
1705  }
1706 
1707  case value_t::number_float:
1708  {
1709  m_value = other.m_value.number_float;
1710  break;
1711  }
1712 
1713  default:
1714  {
1715  break;
1716  }
1717  }
1718  }
1719 
1738  basic_json(basic_json&& other) noexcept
1739  : m_type(std::move(other.m_type)),
1740  m_value(std::move(other.m_value))
1741  {
1742  // invalidate payload
1743  other.m_type = value_t::null;
1744  other.m_value = {};
1745  }
1746 
1768  reference& operator=(basic_json other) noexcept (
1769  std::is_nothrow_move_constructible<value_t>::value and
1770  std::is_nothrow_move_assignable<value_t>::value and
1771  std::is_nothrow_move_constructible<json_value>::value and
1772  std::is_nothrow_move_assignable<json_value>::value
1773  )
1774  {
1775  using std::swap;
1776  swap(m_type, other.m_type);
1777  swap(m_value, other.m_value);
1778  return *this;
1779  }
1780 
1795  {
1796  switch (m_type)
1797  {
1798  case value_t::object:
1799  {
1800  AllocatorType<object_t> alloc;
1801  alloc.destroy(m_value.object);
1802  alloc.deallocate(m_value.object, 1);
1803  break;
1804  }
1805 
1806  case value_t::array:
1807  {
1808  AllocatorType<array_t> alloc;
1809  alloc.destroy(m_value.array);
1810  alloc.deallocate(m_value.array, 1);
1811  break;
1812  }
1813 
1814  case value_t::string:
1815  {
1816  AllocatorType<string_t> alloc;
1817  alloc.destroy(m_value.string);
1818  alloc.deallocate(m_value.string, 1);
1819  break;
1820  }
1821 
1822  default:
1823  {
1824  // all other types need no specific destructor
1825  break;
1826  }
1827  }
1828  }
1829 
1831 
1832  public:
1834  // object inspection //
1836 
1839 
1863  string_t dump(const int indent = -1) const
1864  {
1865  std::stringstream ss;
1866 
1867  if (indent >= 0)
1868  {
1869  dump(ss, true, static_cast<unsigned int>(indent));
1870  }
1871  else
1872  {
1873  dump(ss, false, 0);
1874  }
1875 
1876  return ss.str();
1877  }
1878 
1894  value_t type() const noexcept
1895  {
1896  return m_type;
1897  }
1898 
1915  bool is_primitive() const noexcept
1916  {
1917  return is_null() or is_string() or is_boolean() or is_number();
1918  }
1919 
1935  bool is_structured() const noexcept
1936  {
1937  return is_array() or is_object();
1938  }
1939 
1954  bool is_null() const noexcept
1955  {
1956  return m_type == value_t::null;
1957  }
1958 
1973  bool is_boolean() const noexcept
1974  {
1975  return m_type == value_t::boolean;
1976  }
1977 
1997  bool is_number() const noexcept
1998  {
1999  return is_number_integer() or is_number_float();
2000  }
2001 
2020  bool is_number_integer() const noexcept
2021  {
2022  return m_type == value_t::number_integer;
2023  }
2024 
2043  bool is_number_float() const noexcept
2044  {
2045  return m_type == value_t::number_float;
2046  }
2047 
2062  bool is_object() const noexcept
2063  {
2064  return m_type == value_t::object;
2065  }
2066 
2081  bool is_array() const noexcept
2082  {
2083  return m_type == value_t::array;
2084  }
2085 
2100  bool is_string() const noexcept
2101  {
2102  return m_type == value_t::string;
2103  }
2104 
2124  bool is_discarded() const noexcept
2125  {
2126  return m_type == value_t::discarded;
2127  }
2128 
2144  operator value_t() const noexcept
2145  {
2146  return m_type;
2147  }
2148 
2150 
2151  private:
2153  // value access //
2155 
2157  template <class T, typename
2158  std::enable_if<
2159  std::is_convertible<typename object_t::key_type, typename T::key_type>::value and
2160  std::is_convertible<basic_json_t, typename T::mapped_type>::value
2161  , int>::type = 0>
2162  T get_impl(T*) const
2163  {
2164  return is_object()
2165  ? T(m_value.object->begin(), m_value.object->end())
2166  : throw std::domain_error("type must be object, but is " + type_name());
2167  }
2168 
2170  object_t get_impl(object_t*) const
2171  {
2172  return is_object()
2173  ? *(m_value.object)
2174  : throw std::domain_error("type must be object, but is " + type_name());
2175  }
2176 
2178  template <class T, typename
2179  std::enable_if<
2180  std::is_convertible<basic_json_t, typename T::value_type>::value and
2181  not std::is_same<basic_json_t, typename T::value_type>::value and
2182  not std::is_arithmetic<T>::value and
2183  not std::is_convertible<std::string, T>::value and
2184  not has_mapped_type<T>::value
2185  , int>::type = 0>
2186  T get_impl(T*) const
2187  {
2188  if (is_array())
2189  {
2190  T to_vector;
2191  std::transform(m_value.array->begin(), m_value.array->end(),
2192  std::inserter(to_vector, to_vector.end()), [](basic_json i)
2193  {
2194  return i.get<typename T::value_type>();
2195  });
2196  return to_vector;
2197  }
2198  else
2199  {
2200  throw std::domain_error("type must be array, but is " + type_name());
2201  }
2202  }
2203 
2205  template <class T, typename
2206  std::enable_if<
2207  std::is_convertible<basic_json_t, T>::value and
2208  not std::is_same<basic_json_t, T>::value
2209  , int>::type = 0>
2210  std::vector<T> get_impl(std::vector<T>*) const
2211  {
2212  if (is_array())
2213  {
2214  std::vector<T> to_vector;
2215  to_vector.reserve(m_value.array->size());
2216  std::transform(m_value.array->begin(), m_value.array->end(),
2217  std::inserter(to_vector, to_vector.end()), [](basic_json i)
2218  {
2219  return i.get<T>();
2220  });
2221  return to_vector;
2222  }
2223  else
2224  {
2225  throw std::domain_error("type must be array, but is " + type_name());
2226  }
2227  }
2228 
2230  template <class T, typename
2231  std::enable_if<
2232  std::is_same<basic_json, typename T::value_type>::value and
2233  not has_mapped_type<T>::value
2234  , int>::type = 0>
2235  T get_impl(T*) const
2236  {
2237  return is_array()
2238  ? T(m_value.array->begin(), m_value.array->end())
2239  : throw std::domain_error("type must be array, but is " + type_name());
2240  }
2241 
2243  array_t get_impl(array_t*) const
2244  {
2245  return is_array()
2246  ? *(m_value.array)
2247  : throw std::domain_error("type must be array, but is " + type_name());
2248  }
2249 
2251  template <typename T, typename
2252  std::enable_if<
2253  std::is_convertible<string_t, T>::value
2254  , int>::type = 0>
2255  T get_impl(T*) const
2256  {
2257  return is_string()
2258  ? *m_value.string
2259  : throw std::domain_error("type must be string, but is " + type_name());
2260  }
2261 
2263  template<typename T, typename
2264  std::enable_if<
2265  std::is_arithmetic<T>::value
2266  , int>::type = 0>
2267  T get_impl(T*) const
2268  {
2269  switch (m_type)
2270  {
2272  {
2273  return static_cast<T>(m_value.number_integer);
2274  }
2275 
2276  case value_t::number_float:
2277  {
2278  return static_cast<T>(m_value.number_float);
2279  }
2280 
2281  default:
2282  {
2283  throw std::domain_error("type must be number, but is " + type_name());
2284  }
2285  }
2286  }
2287 
2289  boolean_t get_impl(boolean_t*) const
2290  {
2291  return is_boolean()
2292  ? m_value.boolean
2293  : throw std::domain_error("type must be boolean, but is " + type_name());
2294  }
2295 
2297  object_t* get_impl_ptr(object_t*) noexcept
2298  {
2299  return is_object() ? m_value.object : nullptr;
2300  }
2301 
2303  const object_t* get_impl_ptr(const object_t*) const noexcept
2304  {
2305  return is_object() ? m_value.object : nullptr;
2306  }
2307 
2309  array_t* get_impl_ptr(array_t*) noexcept
2310  {
2311  return is_array() ? m_value.array : nullptr;
2312  }
2313 
2315  const array_t* get_impl_ptr(const array_t*) const noexcept
2316  {
2317  return is_array() ? m_value.array : nullptr;
2318  }
2319 
2321  string_t* get_impl_ptr(string_t*) noexcept
2322  {
2323  return is_string() ? m_value.string : nullptr;
2324  }
2325 
2327  const string_t* get_impl_ptr(const string_t*) const noexcept
2328  {
2329  return is_string() ? m_value.string : nullptr;
2330  }
2331 
2333  boolean_t* get_impl_ptr(boolean_t*) noexcept
2334  {
2335  return is_boolean() ? &m_value.boolean : nullptr;
2336  }
2337 
2339  const boolean_t* get_impl_ptr(const boolean_t*) const noexcept
2340  {
2341  return is_boolean() ? &m_value.boolean : nullptr;
2342  }
2343 
2345  number_integer_t* get_impl_ptr(number_integer_t*) noexcept
2346  {
2347  return is_number_integer() ? &m_value.number_integer : nullptr;
2348  }
2349 
2351  const number_integer_t* get_impl_ptr(const number_integer_t*) const noexcept
2352  {
2353  return is_number_integer() ? &m_value.number_integer : nullptr;
2354  }
2355 
2357  number_float_t* get_impl_ptr(number_float_t*) noexcept
2358  {
2359  return is_number_float() ? &m_value.number_float : nullptr;
2360  }
2361 
2363  const number_float_t* get_impl_ptr(const number_float_t*) const noexcept
2364  {
2365  return is_number_float() ? &m_value.number_float : nullptr;
2366  }
2367 
2368  public:
2369 
2372 
2406  template<typename ValueType, typename
2407  std::enable_if<
2408  not std::is_pointer<ValueType>::value
2409  , int>::type = 0>
2410  ValueType get() const
2411  {
2412  return get_impl(static_cast<ValueType*>(nullptr));
2413  }
2414 
2441  template<typename PointerType, typename
2442  std::enable_if<
2443  std::is_pointer<PointerType>::value
2444  , int>::type = 0>
2445  PointerType get() noexcept
2446  {
2447  // delegate the call to get_ptr
2448  return get_ptr<PointerType>();
2449  }
2450 
2455  template<typename PointerType, typename
2456  std::enable_if<
2457  std::is_pointer<PointerType>::value
2458  , int>::type = 0>
2459  const PointerType get() const noexcept
2460  {
2461  // delegate the call to get_ptr
2462  return get_ptr<PointerType>();
2463  }
2464 
2490  template<typename PointerType, typename
2491  std::enable_if<
2492  std::is_pointer<PointerType>::value
2493  , int>::type = 0>
2494  PointerType get_ptr() noexcept
2495  {
2496  // delegate the call to get_impl_ptr<>()
2497  return get_impl_ptr(static_cast<PointerType>(nullptr));
2498  }
2499 
2504  template<typename PointerType, typename
2505  std::enable_if<
2506  std::is_pointer<PointerType>::value
2507  and std::is_const<typename std::remove_pointer<PointerType>::type>::value
2508  , int>::type = 0>
2509  const PointerType get_ptr() const noexcept
2510  {
2511  // delegate the call to get_impl_ptr<>() const
2512  return get_impl_ptr(static_cast<const PointerType>(nullptr));
2513  }
2514 
2541  template<typename ValueType, typename
2542  std::enable_if<
2543  not std::is_pointer<ValueType>::value
2544  , int>::type = 0>
2545  operator ValueType() const
2546  {
2547  // delegate the call to get<>() const
2548  return get<ValueType>();
2549  }
2550 
2552 
2553 
2555  // element access //
2557 
2560 
2583  {
2584  // at only works for arrays
2585  return is_array()
2586  ? m_value.array->at(idx)
2587  : throw std::domain_error("cannot use at() with " + type_name());
2588  }
2589 
2612  {
2613  // at only works for arrays
2614  return is_array()
2615  ? m_value.array->at(idx)
2616  : throw std::domain_error("cannot use at() with " + type_name());
2617  }
2618 
2644  reference at(const typename object_t::key_type& key)
2645  {
2646  // at only works for objects
2647  return is_object()
2648  ? m_value.object->at(key)
2649  : throw std::domain_error("cannot use at() with " + type_name());
2650  }
2651 
2677  const_reference at(const typename object_t::key_type& key) const
2678  {
2679  // at only works for objects
2680  return is_object()
2681  ? m_value.object->at(key)
2682  : throw std::domain_error("cannot use at() with " + type_name());
2683  }
2684 
2710  {
2711  // implicitly convert null to object
2712  if (is_null())
2713  {
2714  m_type = value_t::array;
2715  m_value.array = create<array_t>();
2716  }
2717 
2718  // [] only works for arrays
2719  if (is_array())
2720  {
2721  for (size_t i = m_value.array->size(); i <= idx; ++i)
2722  {
2723  m_value.array->push_back(basic_json());
2724  }
2725 
2726  return m_value.array->operator[](idx);
2727  }
2728  else
2729  {
2730  throw std::domain_error("cannot use operator[] with " + type_name());
2731  }
2732  }
2733 
2753  {
2754  // at only works for arrays
2755  return is_array()
2756  ? m_value.array->operator[](idx)
2757  : throw std::domain_error("cannot use operator[] with " + type_name());
2758  }
2759 
2786  reference operator[](const typename object_t::key_type& key)
2787  {
2788  // implicitly convert null to object
2789  if (is_null())
2790  {
2791  m_type = value_t::object;
2792  m_value.object = create<object_t>();
2793  }
2794 
2795  // [] only works for objects
2796  return is_object()
2797  ? m_value.object->operator[](key)
2798  : throw std::domain_error("cannot use operator[] with " + type_name());
2799  }
2800 
2829  template<typename T, std::size_t n>
2830  reference operator[](const T (&key)[n])
2831  {
2832  // implicitly convert null to object
2833  if (is_null())
2834  {
2835  m_type = value_t::object;
2836  m_value = value_t::object;
2837  }
2838 
2839  // at only works for objects
2840  return is_object()
2841  ? m_value.object->operator[](key)
2842  : throw std::domain_error("cannot use operator[] with " + type_name());
2843  }
2844 
2892  template <class ValueType, typename
2893  std::enable_if<
2894  std::is_convertible<basic_json_t, ValueType>::value
2895  , int>::type = 0>
2896  ValueType value(const typename object_t::key_type& key, ValueType default_value) const
2897  {
2898  // at only works for objects
2899  if (is_object())
2900  {
2901  // if key is found, return value and given default value otherwise
2902  const auto it = find(key);
2903  if (it != end())
2904  {
2905  return *it;
2906  }
2907  else
2908  {
2909  return default_value;
2910  }
2911  }
2912  else
2913  {
2914  throw std::domain_error("cannot use value() with " + type_name());
2915  }
2916  }
2917 
2922  string_t value(const typename object_t::key_type& key, const char* default_value) const
2923  {
2924  return value(key, string_t(default_value));
2925  }
2926 
2948  {
2949  return *begin();
2950  }
2951 
2956  {
2957  return *cbegin();
2958  }
2959 
2982  {
2983  auto tmp = end();
2984  --tmp;
2985  return *tmp;
2986  }
2987 
2992  {
2993  auto tmp = cend();
2994  --tmp;
2995  return *tmp;
2996  }
2997 
3040  template <class InteratorType, typename
3041  std::enable_if<
3042  std::is_same<InteratorType, typename basic_json_t::iterator>::value or
3043  std::is_same<InteratorType, typename basic_json_t::const_iterator>::value
3044  , int>::type
3045  = 0>
3046  InteratorType erase(InteratorType pos)
3047  {
3048  // make sure iterator fits the current value
3049  if (this != pos.m_object)
3050  {
3051  throw std::domain_error("iterator does not fit current value");
3052  }
3053 
3054  InteratorType result = end();
3055 
3056  switch (m_type)
3057  {
3058  case value_t::boolean:
3059  case value_t::number_float:
3061  case value_t::string:
3062  {
3063  if (not pos.m_it.primitive_iterator.is_begin())
3064  {
3065  throw std::out_of_range("iterator out of range");
3066  }
3067 
3068  if (is_string())
3069  {
3070  delete m_value.string;
3071  m_value.string = nullptr;
3072  }
3073 
3074  m_type = value_t::null;
3075  break;
3076  }
3077 
3078  case value_t::object:
3079  {
3080  result.m_it.object_iterator = m_value.object->erase(pos.m_it.object_iterator);
3081  break;
3082  }
3083 
3084  case value_t::array:
3085  {
3086  result.m_it.array_iterator = m_value.array->erase(pos.m_it.array_iterator);
3087  break;
3088  }
3089 
3090  default:
3091  {
3092  throw std::domain_error("cannot use erase() with " + type_name());
3093  }
3094  }
3095 
3096  return result;
3097  }
3098 
3141  template <class InteratorType, typename
3142  std::enable_if<
3143  std::is_same<InteratorType, typename basic_json_t::iterator>::value or
3144  std::is_same<InteratorType, typename basic_json_t::const_iterator>::value
3145  , int>::type
3146  = 0>
3147  InteratorType erase(InteratorType first, InteratorType last)
3148  {
3149  // make sure iterator fits the current value
3150  if (this != first.m_object or this != last.m_object)
3151  {
3152  throw std::domain_error("iterators do not fit current value");
3153  }
3154 
3155  InteratorType result = end();
3156 
3157  switch (m_type)
3158  {
3159  case value_t::boolean:
3160  case value_t::number_float:
3162  case value_t::string:
3163  {
3164  if (not first.m_it.primitive_iterator.is_begin() or not last.m_it.primitive_iterator.is_end())
3165  {
3166  throw std::out_of_range("iterators out of range");
3167  }
3168 
3169  if (is_string())
3170  {
3171  delete m_value.string;
3172  m_value.string = nullptr;
3173  }
3174 
3175  m_type = value_t::null;
3176  break;
3177  }
3178 
3179  case value_t::object:
3180  {
3181  result.m_it.object_iterator = m_value.object->erase(first.m_it.object_iterator,
3182  last.m_it.object_iterator);
3183  break;
3184  }
3185 
3186  case value_t::array:
3187  {
3188  result.m_it.array_iterator = m_value.array->erase(first.m_it.array_iterator,
3189  last.m_it.array_iterator);
3190  break;
3191  }
3192 
3193  default:
3194  {
3195  throw std::domain_error("cannot use erase with " + type_name());
3196  }
3197  }
3198 
3199  return result;
3200  }
3201 
3227  size_type erase(const typename object_t::key_type& key)
3228  {
3229  // this erase only works for objects
3230  return is_object()
3231  ? m_value.object->erase(key)
3232  : throw std::domain_error("cannot use erase() with " + type_name());
3233  }
3234 
3257  void erase(const size_type idx)
3258  {
3259  // this erase only works for arrays
3260  if (is_array())
3261  {
3262  if (idx >= size())
3263  {
3264  throw std::out_of_range("index out of range");
3265  }
3266 
3267  m_value.array->erase(m_value.array->begin() + static_cast<difference_type>(idx));
3268  }
3269  else
3270  {
3271  throw std::domain_error("cannot use erase() with " + type_name());
3272  }
3273  }
3274 
3292  iterator find(typename object_t::key_type key)
3293  {
3294  auto result = end();
3295 
3296  if (is_object())
3297  {
3298  result.m_it.object_iterator = m_value.object->find(key);
3299  }
3300 
3301  return result;
3302  }
3303 
3308  const_iterator find(typename object_t::key_type key) const
3309  {
3310  auto result = cend();
3311 
3312  if (is_object())
3313  {
3314  result.m_it.object_iterator = m_value.object->find(key);
3315  }
3316 
3317  return result;
3318  }
3319 
3338  size_type count(typename object_t::key_type key) const
3339  {
3340  // return 0 for all nonobject types
3341  return is_object() ? m_value.object->count(key) : 0;
3342  }
3343 
3345 
3346 
3348  // iterators //
3350 
3353 
3373  {
3374  iterator result(this);
3375  result.set_begin();
3376  return result;
3377  }
3378 
3383  {
3384  return cbegin();
3385  }
3386 
3407  {
3408  const_iterator result(this);
3409  result.set_begin();
3410  return result;
3411  }
3412 
3432  {
3433  iterator result(this);
3434  result.set_end();
3435  return result;
3436  }
3437 
3442  {
3443  return cend();
3444  }
3445 
3466  {
3467  const_iterator result(this);
3468  result.set_end();
3469  return result;
3470  }
3471 
3490  {
3491  return reverse_iterator(end());
3492  }
3493 
3498  {
3499  return crbegin();
3500  }
3501 
3521  {
3522  return reverse_iterator(begin());
3523  }
3524 
3529  {
3530  return crend();
3531  }
3532 
3552  {
3553  return const_reverse_iterator(cend());
3554  }
3555 
3575  {
3576  return const_reverse_iterator(cbegin());
3577  }
3578 
3580 
3581 
3583  // capacity //
3585 
3588 
3618  bool empty() const noexcept
3619  {
3620  switch (m_type)
3621  {
3622  case value_t::null:
3623  {
3624  // null values are empty
3625  return true;
3626  }
3627 
3628  case value_t::array:
3629  {
3630  return m_value.array->empty();
3631  }
3632 
3633  case value_t::object:
3634  {
3635  return m_value.object->empty();
3636  }
3637 
3638  default:
3639  {
3640  // all other types are nonempty
3641  return false;
3642  }
3643  }
3644  }
3645 
3675  size_type size() const noexcept
3676  {
3677  switch (m_type)
3678  {
3679  case value_t::null:
3680  {
3681  // null values are empty
3682  return 0;
3683  }
3684 
3685  case value_t::array:
3686  {
3687  return m_value.array->size();
3688  }
3689 
3690  case value_t::object:
3691  {
3692  return m_value.object->size();
3693  }
3694 
3695  default:
3696  {
3697  // all other types have size 1
3698  return 1;
3699  }
3700  }
3701  }
3702 
3735  size_type max_size() const noexcept
3736  {
3737  switch (m_type)
3738  {
3739  case value_t::array:
3740  {
3741  return m_value.array->max_size();
3742  }
3743 
3744  case value_t::object:
3745  {
3746  return m_value.object->max_size();
3747  }
3748 
3749  default:
3750  {
3751  // all other types have max_size() == size()
3752  return size();
3753  }
3754  }
3755  }
3756 
3758 
3759 
3761  // modifiers //
3763 
3766 
3792  void clear() noexcept
3793  {
3794  switch (m_type)
3795  {
3797  {
3798  m_value.number_integer = 0;
3799  break;
3800  }
3801 
3802  case value_t::number_float:
3803  {
3804  m_value.number_float = 0.0;
3805  break;
3806  }
3807 
3808  case value_t::boolean:
3809  {
3810  m_value.boolean = false;
3811  break;
3812  }
3813 
3814  case value_t::string:
3815  {
3816  m_value.string->clear();
3817  break;
3818  }
3819 
3820  case value_t::array:
3821  {
3822  m_value.array->clear();
3823  break;
3824  }
3825 
3826  case value_t::object:
3827  {
3828  m_value.object->clear();
3829  break;
3830  }
3831 
3832  default:
3833  {
3834  break;
3835  }
3836  }
3837  }
3838 
3858  void push_back(basic_json&& value)
3859  {
3860  // push_back only works for null objects or arrays
3861  if (not(is_null() or is_array()))
3862  {
3863  throw std::domain_error("cannot use push_back() with " + type_name());
3864  }
3865 
3866  // transform null object into an array
3867  if (is_null())
3868  {
3869  m_type = value_t::array;
3870  m_value = value_t::array;
3871  }
3872 
3873  // add element to array (move semantics)
3874  m_value.array->push_back(std::move(value));
3875  // invalidate object
3876  value.m_type = value_t::null;
3877  }
3878 
3884  {
3885  push_back(std::move(value));
3886  return *this;
3887  }
3888 
3893  void push_back(const basic_json& value)
3894  {
3895  // push_back only works for null objects or arrays
3896  if (not(is_null() or is_array()))
3897  {
3898  throw std::domain_error("cannot use push_back() with " + type_name());
3899  }
3900 
3901  // transform null object into an array
3902  if (is_null())
3903  {
3904  m_type = value_t::array;
3905  m_value = value_t::array;
3906  }
3907 
3908  // add element to array
3909  m_value.array->push_back(value);
3910  }
3911 
3916  reference operator+=(const basic_json& value)
3917  {
3918  push_back(value);
3919  return *this;
3920  }
3921 
3942  void push_back(const typename object_t::value_type& value)
3943  {
3944  // push_back only works for null objects or objects
3945  if (not(is_null() or is_object()))
3946  {
3947  throw std::domain_error("cannot use push_back() with " + type_name());
3948  }
3949 
3950  // transform null object into an object
3951  if (is_null())
3952  {
3953  m_type = value_t::object;
3954  m_value = value_t::object;
3955  }
3956 
3957  // add element to array
3958  m_value.object->insert(value);
3959  }
3960 
3965  reference operator+=(const typename object_t::value_type& value)
3966  {
3967  push_back(value);
3968  return operator[](value.first);
3969  }
3970 
3991  iterator insert(const_iterator pos, const basic_json& value)
3992  {
3993  // insert only works for arrays
3994  if (is_array())
3995  {
3996  // check if iterator pos fits to this JSON value
3997  if (pos.m_object != this)
3998  {
3999  throw std::domain_error("iterator does not fit current value");
4000  }
4001 
4002  // insert to array and return iterator
4003  iterator result(this);
4004  result.m_it.array_iterator = m_value.array->insert(pos.m_it.array_iterator, value);
4005  return result;
4006  }
4007  else
4008  {
4009  throw std::domain_error("cannot use insert() with " + type_name());
4010  }
4011  }
4012 
4018  {
4019  return insert(pos, value);
4020  }
4021 
4045  {
4046  // insert only works for arrays
4047  if (is_array())
4048  {
4049  // check if iterator pos fits to this JSON value
4050  if (pos.m_object != this)
4051  {
4052  throw std::domain_error("iterator does not fit current value");
4053  }
4054 
4055  // insert to array and return iterator
4056  iterator result(this);
4057  result.m_it.array_iterator = m_value.array->insert(pos.m_it.array_iterator, count, value);
4058  return result;
4059  }
4060  else
4061  {
4062  throw std::domain_error("cannot use insert() with " + type_name());
4063  }
4064  }
4065 
4093  {
4094  // insert only works for arrays
4095  if (not is_array())
4096  {
4097  throw std::domain_error("cannot use insert() with " + type_name());
4098  }
4099 
4100  // check if iterator pos fits to this JSON value
4101  if (pos.m_object != this)
4102  {
4103  throw std::domain_error("iterator does not fit current value");
4104  }
4105 
4106  if (first.m_object != last.m_object)
4107  {
4108  throw std::domain_error("iterators do not fit");
4109  }
4110 
4111  if (first.m_object == this or last.m_object == this)
4112  {
4113  throw std::domain_error("passed iterators may not belong to container");
4114  }
4115 
4116  // insert to array and return iterator
4117  iterator result(this);
4118  result.m_it.array_iterator = m_value.array->insert(
4119  pos.m_it.array_iterator,
4120  first.m_it.array_iterator,
4121  last.m_it.array_iterator);
4122  return result;
4123  }
4124 
4146  iterator insert(const_iterator pos, std::initializer_list<basic_json> ilist)
4147  {
4148  // insert only works for arrays
4149  if (not is_array())
4150  {
4151  throw std::domain_error("cannot use insert() with " + type_name());
4152  }
4153 
4154  // check if iterator pos fits to this JSON value
4155  if (pos.m_object != this)
4156  {
4157  throw std::domain_error("iterator does not fit current value");
4158  }
4159 
4160  // insert to array and return iterator
4161  iterator result(this);
4162  result.m_it.array_iterator = m_value.array->insert(pos.m_it.array_iterator, ilist);
4163  return result;
4164  }
4165 
4183  void swap(reference other) noexcept (
4184  std::is_nothrow_move_constructible<value_t>::value and
4185  std::is_nothrow_move_assignable<value_t>::value and
4186  std::is_nothrow_move_constructible<json_value>::value and
4187  std::is_nothrow_move_assignable<json_value>::value
4188  )
4189  {
4190  std::swap(m_type, other.m_type);
4191  std::swap(m_value, other.m_value);
4192  }
4193 
4213  void swap(array_t& other)
4214  {
4215  // swap only works for arrays
4216  if (is_array())
4217  {
4218  std::swap(*(m_value.array), other);
4219  }
4220  else
4221  {
4222  throw std::domain_error("cannot use swap() with " + type_name());
4223  }
4224  }
4225 
4245  void swap(object_t& other)
4246  {
4247  // swap only works for objects
4248  if (is_object())
4249  {
4250  std::swap(*(m_value.object), other);
4251  }
4252  else
4253  {
4254  throw std::domain_error("cannot use swap() with " + type_name());
4255  }
4256  }
4257 
4277  void swap(string_t& other)
4278  {
4279  // swap only works for strings
4280  if (is_string())
4281  {
4282  std::swap(*(m_value.string), other);
4283  }
4284  else
4285  {
4286  throw std::domain_error("cannot use swap() with " + type_name());
4287  }
4288  }
4289 
4291 
4292 
4294  // lexicographical comparison operators //
4296 
4299 
4300  private:
4310  friend bool operator<(const value_t lhs, const value_t rhs)
4311  {
4312  static constexpr std::array<uint8_t, 7> order = {{
4313  0, // null
4314  3, // object
4315  4, // array
4316  5, // string
4317  1, // boolean
4318  2, // integer
4319  2 // float
4320  }
4321  };
4322 
4323  // discarded values are not comparable
4324  if (lhs == value_t::discarded or rhs == value_t::discarded)
4325  {
4326  return false;
4327  }
4328 
4329  return order[static_cast<std::size_t>(lhs)] < order[static_cast<std::size_t>(rhs)];
4330  }
4331 
4332  public:
4356  friend bool operator==(const_reference lhs, const_reference rhs) noexcept
4357  {
4358  const auto lhs_type = lhs.type();
4359  const auto rhs_type = rhs.type();
4360 
4361  if (lhs_type == rhs_type)
4362  {
4363  switch (lhs_type)
4364  {
4365  case value_t::array:
4366  return *lhs.m_value.array == *rhs.m_value.array;
4367  case value_t::object:
4368  return *lhs.m_value.object == *rhs.m_value.object;
4369  case value_t::null:
4370  return true;
4371  case value_t::string:
4372  return *lhs.m_value.string == *rhs.m_value.string;
4373  case value_t::boolean:
4374  return lhs.m_value.boolean == rhs.m_value.boolean;
4376  return lhs.m_value.number_integer == rhs.m_value.number_integer;
4377  case value_t::number_float:
4378  return approx(lhs.m_value.number_float, rhs.m_value.number_float);
4379  default:
4380  return false;
4381  }
4382  }
4383  else if (lhs_type == value_t::number_integer and rhs_type == value_t::number_float)
4384  {
4385  return approx(static_cast<number_float_t>(lhs.m_value.number_integer),
4386  rhs.m_value.number_float);
4387  }
4388  else if (lhs_type == value_t::number_float and rhs_type == value_t::number_integer)
4389  {
4390  return approx(lhs.m_value.number_float,
4391  static_cast<number_float_t>(rhs.m_value.number_integer));
4392  }
4393  return false;
4394  }
4395 
4414  friend bool operator==(const_reference v, std::nullptr_t) noexcept
4415  {
4416  return v.is_null();
4417  }
4418 
4423  friend bool operator==(std::nullptr_t, const_reference v) noexcept
4424  {
4425  return v.is_null();
4426  }
4427 
4444  friend bool operator!=(const_reference lhs, const_reference rhs) noexcept
4445  {
4446  return not (lhs == rhs);
4447  }
4448 
4467  friend bool operator!=(const_reference v, std::nullptr_t) noexcept
4468  {
4469  return not v.is_null();
4470  }
4471 
4476  friend bool operator!=(std::nullptr_t, const_reference v) noexcept
4477  {
4478  return not v.is_null();
4479  }
4480 
4505  friend bool operator<(const_reference lhs, const_reference rhs) noexcept
4506  {
4507  const auto lhs_type = lhs.type();
4508  const auto rhs_type = rhs.type();
4509 
4510  if (lhs_type == rhs_type)
4511  {
4512  switch (lhs_type)
4513  {
4514  case value_t::array:
4515  return *lhs.m_value.array < *rhs.m_value.array;
4516  case value_t::object:
4517  return *lhs.m_value.object < *rhs.m_value.object;
4518  case value_t::null:
4519  return false;
4520  case value_t::string:
4521  return *lhs.m_value.string < *rhs.m_value.string;
4522  case value_t::boolean:
4523  return lhs.m_value.boolean < rhs.m_value.boolean;
4525  return lhs.m_value.number_integer < rhs.m_value.number_integer;
4526  case value_t::number_float:
4527  return lhs.m_value.number_float < rhs.m_value.number_float;
4528  default:
4529  return false;
4530  }
4531  }
4532  else if (lhs_type == value_t::number_integer and rhs_type == value_t::number_float)
4533  {
4534  return static_cast<number_float_t>(lhs.m_value.number_integer) <
4535  rhs.m_value.number_float;
4536  }
4537  else if (lhs_type == value_t::number_float and rhs_type == value_t::number_integer)
4538  {
4539  return lhs.m_value.number_float <
4540  static_cast<number_float_t>(rhs.m_value.number_integer);
4541  }
4542 
4543  // We only reach this line if we cannot compare values. In that case,
4544  // we compare types. Note we have to call the operator explicitly,
4545  // because MSVC has problems otherwise.
4546  return operator<(lhs_type, rhs_type);
4547  }
4548 
4566  friend bool operator<=(const_reference lhs, const_reference rhs) noexcept
4567  {
4568  return not (rhs < lhs);
4569  }
4570 
4588  friend bool operator>(const_reference lhs, const_reference rhs) noexcept
4589  {
4590  return not (lhs <= rhs);
4591  }
4592 
4610  friend bool operator>=(const_reference lhs, const_reference rhs) noexcept
4611  {
4612  return not (lhs < rhs);
4613  }
4614 
4616 
4617 
4619  // serialization //
4621 
4624 
4647  friend std::ostream& operator<<(std::ostream& o, const basic_json& j)
4648  {
4649  // read width member and use it as indentation parameter if nonzero
4650  const bool pretty_print = (o.width() > 0);
4651  const auto indentation = (pretty_print ? o.width() : 0);
4652 
4653  // reset width to 0 for subsequent calls to this stream
4654  o.width(0);
4655 
4656  // do the actual serialization
4657  j.dump(o, pretty_print, static_cast<unsigned int>(indentation));
4658  return o;
4659  }
4660 
4665  friend std::ostream& operator>>(const basic_json& j, std::ostream& o)
4666  {
4667  return o << j;
4668  }
4669 
4671 
4672 
4674  // deserialization //
4676 
4679 
4704  static basic_json parse(const string_t& s, parser_callback_t cb = nullptr)
4705  {
4706  return parser(s, cb).parse();
4707  }
4708 
4733  static basic_json parse(std::istream& i, parser_callback_t cb = nullptr)
4734  {
4735  return parser(i, cb).parse();
4736  }
4737 
4741  static basic_json parse(std::istream&& i, parser_callback_t cb = nullptr)
4742  {
4743  return parser(i, cb).parse();
4744  }
4745 
4769  friend std::istream& operator<<(basic_json& j, std::istream& i)
4770  {
4771  j = parser(i).parse();
4772  return i;
4773  }
4774 
4779  friend std::istream& operator>>(std::istream& i, basic_json& j)
4780  {
4781  j = parser(i).parse();
4782  return i;
4783  }
4784 
4786 
4787 
4788  private:
4790  // convenience functions //
4792 
4794  string_t type_name() const
4795  {
4796  switch (m_type)
4797  {
4798  case value_t::null:
4799  return "null";
4800  case value_t::object:
4801  return "object";
4802  case value_t::array:
4803  return "array";
4804  case value_t::string:
4805  return "string";
4806  case value_t::boolean:
4807  return "boolean";
4808  case value_t::discarded:
4809  return "discarded";
4810  default:
4811  return "number";
4812  }
4813  }
4814 
4823  static std::size_t extra_space(const string_t& s) noexcept
4824  {
4825  std::size_t result = 0;
4826 
4827  for (const auto& c : s)
4828  {
4829  switch (c)
4830  {
4831  case '"':
4832  case '\\':
4833  case '\b':
4834  case '\f':
4835  case '\n':
4836  case '\r':
4837  case '\t':
4838  {
4839  // from c (1 byte) to \x (2 bytes)
4840  result += 1;
4841  break;
4842  }
4843 
4844  default:
4845  {
4846  if (c >= 0x00 and c <= 0x1f)
4847  {
4848  // from c (1 byte) to \uxxxx (6 bytes)
4849  result += 5;
4850  }
4851  break;
4852  }
4853  }
4854  }
4855 
4856  return result;
4857  }
4858 
4872  static string_t escape_string(const string_t& s) noexcept
4873  {
4874  const auto space = extra_space(s);
4875  if (space == 0)
4876  {
4877  return s;
4878  }
4879 
4880  // create a result string of necessary size
4881  string_t result(s.size() + space, '\\');
4882  std::size_t pos = 0;
4883 
4884  for (const auto& c : s)
4885  {
4886  switch (c)
4887  {
4888  // quotation mark (0x22)
4889  case '"':
4890  {
4891  result[pos + 1] = '"';
4892  pos += 2;
4893  break;
4894  }
4895 
4896  // reverse solidus (0x5c)
4897  case '\\':
4898  {
4899  // nothing to change
4900  pos += 2;
4901  break;
4902  }
4903 
4904  // backspace (0x08)
4905  case '\b':
4906  {
4907  result[pos + 1] = 'b';
4908  pos += 2;
4909  break;
4910  }
4911 
4912  // formfeed (0x0c)
4913  case '\f':
4914  {
4915  result[pos + 1] = 'f';
4916  pos += 2;
4917  break;
4918  }
4919 
4920  // newline (0x0a)
4921  case '\n':
4922  {
4923  result[pos + 1] = 'n';
4924  pos += 2;
4925  break;
4926  }
4927 
4928  // carriage return (0x0d)
4929  case '\r':
4930  {
4931  result[pos + 1] = 'r';
4932  pos += 2;
4933  break;
4934  }
4935 
4936  // horizontal tab (0x09)
4937  case '\t':
4938  {
4939  result[pos + 1] = 't';
4940  pos += 2;
4941  break;
4942  }
4943 
4944  default:
4945  {
4946  if (c >= 0x00 and c <= 0x1f)
4947  {
4948  // convert a number 0..15 to its hex representation (0..f)
4949  auto hexify = [](const char v) -> char
4950  {
4951  return (v < 10) ? ('0' + v) : ('a' + v - 10);
4952  };
4953 
4954  // print character c as \uxxxx
4955  for (const char m :
4956  { 'u', '0', '0', hexify(c >> 4), hexify(c & 0x0f)
4957  })
4958  {
4959  result[++pos] = m;
4960  }
4961 
4962  ++pos;
4963  }
4964  else
4965  {
4966  // all other characters are added as-is
4967  result[pos++] = c;
4968  }
4969  break;
4970  }
4971  }
4972  }
4973 
4974  return result;
4975  }
4976 
4994  void dump(std::ostream& o,
4995  const bool pretty_print,
4996  const unsigned int indent_step,
4997  const unsigned int current_indent = 0) const
4998  {
4999  // variable to hold indentation for recursive calls
5000  unsigned int new_indent = current_indent;
5001 
5002  switch (m_type)
5003  {
5004  case value_t::object:
5005  {
5006  if (m_value.object->empty())
5007  {
5008  o << "{}";
5009  return;
5010  }
5011 
5012  o << "{";
5013 
5014  // increase indentation
5015  if (pretty_print)
5016  {
5017  new_indent += indent_step;
5018  o << "\n";
5019  }
5020 
5021  for (auto i = m_value.object->cbegin(); i != m_value.object->cend(); ++i)
5022  {
5023  if (i != m_value.object->cbegin())
5024  {
5025  o << (pretty_print ? ",\n" : ",");
5026  }
5027  o << string_t(new_indent, ' ') << "\""
5028  << escape_string(i->first) << "\":"
5029  << (pretty_print ? " " : "");
5030  i->second.dump(o, pretty_print, indent_step, new_indent);
5031  }
5032 
5033  // decrease indentation
5034  if (pretty_print)
5035  {
5036  new_indent -= indent_step;
5037  o << "\n";
5038  }
5039 
5040  o << string_t(new_indent, ' ') + "}";
5041  return;
5042  }
5043 
5044  case value_t::array:
5045  {
5046  if (m_value.array->empty())
5047  {
5048  o << "[]";
5049  return;
5050  }
5051 
5052  o << "[";
5053 
5054  // increase indentation
5055  if (pretty_print)
5056  {
5057  new_indent += indent_step;
5058  o << "\n";
5059  }
5060 
5061  for (auto i = m_value.array->cbegin(); i != m_value.array->cend(); ++i)
5062  {
5063  if (i != m_value.array->cbegin())
5064  {
5065  o << (pretty_print ? ",\n" : ",");
5066  }
5067  o << string_t(new_indent, ' ');
5068  i->dump(o, pretty_print, indent_step, new_indent);
5069  }
5070 
5071  // decrease indentation
5072  if (pretty_print)
5073  {
5074  new_indent -= indent_step;
5075  o << "\n";
5076  }
5077 
5078  o << string_t(new_indent, ' ') << "]";
5079  return;
5080  }
5081 
5082  case value_t::string:
5083  {
5084  o << string_t("\"") << escape_string(*m_value.string) << "\"";
5085  return;
5086  }
5087 
5088  case value_t::boolean:
5089  {
5090  o << (m_value.boolean ? "true" : "false");
5091  return;
5092  }
5093 
5095  {
5096  o << m_value.number_integer;
5097  return;
5098  }
5099 
5100  case value_t::number_float:
5101  {
5102  // 15 digits of precision allows round-trip IEEE 754
5103  // string->double->string; to be safe, we read this value from
5104  // std::numeric_limits<number_float_t>::digits10
5105  o << std::setprecision(std::numeric_limits<number_float_t>::digits10) << m_value.number_float;
5106  return;
5107  }
5108 
5109  case value_t::discarded:
5110  {
5111  o << "<discarded>";
5112  return;
5113  }
5114 
5115  case value_t::null:
5116  {
5117  o << "null";
5118  return;
5119  }
5120  }
5121  }
5122 
5123  private:
5125  // member variables //
5127 
5129  value_t m_type = value_t::null;
5130 
5132  json_value m_value = {};
5133 
5134 
5135  private:
5137  // iterators //
5139 
5149  class primitive_iterator_t
5150  {
5151  public:
5153  void set_begin()
5154  {
5155  m_it = begin_value;
5156  }
5157 
5159  void set_end()
5160  {
5161  m_it = end_value;
5162  }
5163 
5165  bool is_begin() const
5166  {
5167  return (m_it == begin_value);
5168  }
5169 
5171  bool is_end() const
5172  {
5173  return (m_it == end_value);
5174  }
5175 
5177  operator difference_type& ()
5178  {
5179  return m_it;
5180  }
5181 
5183  operator difference_type () const
5184  {
5185  return m_it;
5186  }
5187 
5188  private:
5189  static constexpr difference_type begin_value = 0;
5190  static constexpr difference_type end_value = begin_value + 1;
5191 
5193  difference_type m_it = std::numeric_limits<std::ptrdiff_t>::denorm_min();
5194  };
5195 
5203  struct internal_iterator
5204  {
5206  typename object_t::iterator object_iterator;
5208  typename array_t::iterator array_iterator;
5210  primitive_iterator_t primitive_iterator;
5211 
5213  internal_iterator()
5214  : object_iterator(), array_iterator(), primitive_iterator()
5215  {}
5216  };
5217 
5218  public:
5232  class const_iterator : public std::iterator<std::random_access_iterator_tag, const basic_json>
5233  {
5235  friend class basic_json;
5236 
5237  public:
5247  using iterator_category = std::bidirectional_iterator_tag;
5248 
5250  const_iterator() = default;
5251 
5253  const_iterator(pointer object) : m_object(object)
5254  {
5255  switch (m_object->m_type)
5256  {
5258  {
5259  m_it.object_iterator = typename object_t::iterator();
5260  break;
5261  }
5262 
5264  {
5265  m_it.array_iterator = typename array_t::iterator();
5266  break;
5267  }
5268 
5269  default:
5270  {
5271  m_it.primitive_iterator = primitive_iterator_t();
5272  break;
5273  }
5274  }
5275  }
5276 
5278  const_iterator(const iterator& other) : m_object(other.m_object)
5279  {
5280  switch (m_object->m_type)
5281  {
5283  {
5284  m_it.object_iterator = other.m_it.object_iterator;
5285  break;
5286  }
5287 
5289  {
5290  m_it.array_iterator = other.m_it.array_iterator;
5291  break;
5292  }
5293 
5294  default:
5295  {
5296  m_it.primitive_iterator = other.m_it.primitive_iterator;
5297  break;
5298  }
5299  }
5300  }
5301 
5303  const_iterator(const const_iterator& other) noexcept
5304  : m_object(other.m_object), m_it(other.m_it)
5305  {}
5306 
5309  std::is_nothrow_move_constructible<pointer>::value and
5310  std::is_nothrow_move_assignable<pointer>::value and
5311  std::is_nothrow_move_constructible<internal_iterator>::value and
5312  std::is_nothrow_move_assignable<internal_iterator>::value
5313  )
5314  {
5315  std::swap(m_object, other.m_object);
5316  std::swap(m_it, other.m_it);
5317  return *this;
5318  }
5319 
5320  private:
5322  void set_begin()
5323  {
5324  switch (m_object->m_type)
5325  {
5327  {
5328  m_it.object_iterator = m_object->m_value.object->begin();
5329  break;
5330  }
5331 
5333  {
5334  m_it.array_iterator = m_object->m_value.array->begin();
5335  break;
5336  }
5337 
5339  {
5340  // set to end so begin()==end() is true: null is empty
5341  m_it.primitive_iterator.set_end();
5342  break;
5343  }
5344 
5345  default:
5346  {
5347  m_it.primitive_iterator.set_begin();
5348  break;
5349  }
5350  }
5351  }
5352 
5354  void set_end()
5355  {
5356  switch (m_object->m_type)
5357  {
5359  {
5360  m_it.object_iterator = m_object->m_value.object->end();
5361  break;
5362  }
5363 
5365  {
5366  m_it.array_iterator = m_object->m_value.array->end();
5367  break;
5368  }
5369 
5370  default:
5371  {
5372  m_it.primitive_iterator.set_end();
5373  break;
5374  }
5375  }
5376  }
5377 
5378  public:
5381  {
5382  switch (m_object->m_type)
5383  {
5385  {
5386  return m_it.object_iterator->second;
5387  }
5388 
5390  {
5391  return *m_it.array_iterator;
5392  }
5393 
5395  {
5396  throw std::out_of_range("cannot get value");
5397  }
5398 
5399  default:
5400  {
5401  return m_it.primitive_iterator.is_begin()
5402  ? *m_object
5403  : throw std::out_of_range("cannot get value");
5404  }
5405  }
5406  }
5407 
5410  {
5411  switch (m_object->m_type)
5412  {
5414  {
5415  return &(m_it.object_iterator->second);
5416  }
5417 
5419  {
5420  return &*m_it.array_iterator;
5421  }
5422 
5423  default:
5424  {
5425  return m_it.primitive_iterator.is_begin()
5426  ? m_object
5427  : throw std::out_of_range("cannot get value");
5428  }
5429  }
5430  }
5431 
5434  {
5435  auto result = *this;
5436  ++(*this);
5437  return result;
5438  }
5439 
5442  {
5443  switch (m_object->m_type)
5444  {
5446  {
5447  ++m_it.object_iterator;
5448  break;
5449  }
5450 
5452  {
5453  ++m_it.array_iterator;
5454  break;
5455  }
5456 
5457  default:
5458  {
5459  ++m_it.primitive_iterator;
5460  break;
5461  }
5462  }
5463 
5464  return *this;
5465  }
5466 
5469  {
5470  auto result = *this;
5471  --(*this);
5472  return result;
5473  }
5474 
5477  {
5478  switch (m_object->m_type)
5479  {
5481  {
5482  --m_it.object_iterator;
5483  break;
5484  }
5485 
5487  {
5488  --m_it.array_iterator;
5489  break;
5490  }
5491 
5492  default:
5493  {
5494  --m_it.primitive_iterator;
5495  break;
5496  }
5497  }
5498 
5499  return *this;
5500  }
5501 
5503  bool operator==(const const_iterator& other) const
5504  {
5505  // if objects are not the same, the comparison is undefined
5506  if (m_object != other.m_object)
5507  {
5508  throw std::domain_error("cannot compare iterators of different containers");
5509  }
5510 
5511  switch (m_object->m_type)
5512  {
5514  {
5515  return (m_it.object_iterator == other.m_it.object_iterator);
5516  }
5517 
5519  {
5520  return (m_it.array_iterator == other.m_it.array_iterator);
5521  }
5522 
5523  default:
5524  {
5525  return (m_it.primitive_iterator == other.m_it.primitive_iterator);
5526  }
5527  }
5528  }
5529 
5531  bool operator!=(const const_iterator& other) const
5532  {
5533  return not operator==(other);
5534  }
5535 
5537  bool operator<(const const_iterator& other) const
5538  {
5539  // if objects are not the same, the comparison is undefined
5540  if (m_object != other.m_object)
5541  {
5542  throw std::domain_error("cannot compare iterators of different containers");
5543  }
5544 
5545  switch (m_object->m_type)
5546  {
5548  {
5549  throw std::domain_error("cannot use operator< for object iterators");
5550  }
5551 
5553  {
5554  return (m_it.array_iterator < other.m_it.array_iterator);
5555  }
5556 
5557  default:
5558  {
5559  return (m_it.primitive_iterator < other.m_it.primitive_iterator);
5560  }
5561  }
5562  }
5563 
5565  bool operator<=(const const_iterator& other) const
5566  {
5567  return not other.operator < (*this);
5568  }
5569 
5571  bool operator>(const const_iterator& other) const
5572  {
5573  return not operator<=(other);
5574  }
5575 
5577  bool operator>=(const const_iterator& other) const
5578  {
5579  return not operator<(other);
5580  }
5581 
5584  {
5585  switch (m_object->m_type)
5586  {
5588  {
5589  throw std::domain_error("cannot use operator+= for object iterators");
5590  }
5591 
5593  {
5594  m_it.array_iterator += i;
5595  break;
5596  }
5597 
5598  default:
5599  {
5600  m_it.primitive_iterator += i;
5601  break;
5602  }
5603  }
5604 
5605  return *this;
5606  }
5607 
5610  {
5611  return operator+=(-i);
5612  }
5613 
5616  {
5617  auto result = *this;
5618  result += i;
5619  return result;
5620  }
5621 
5624  {
5625  auto result = *this;
5626  result -= i;
5627  return result;
5628  }
5629 
5632  {
5633  switch (m_object->m_type)
5634  {
5636  {
5637  throw std::domain_error("cannot use operator- for object iterators");
5638  }
5639 
5641  {
5642  return m_it.array_iterator - other.m_it.array_iterator;
5643  }
5644 
5645  default:
5646  {
5647  return m_it.primitive_iterator - other.m_it.primitive_iterator;
5648  }
5649  }
5650  }
5651 
5654  {
5655  switch (m_object->m_type)
5656  {
5658  {
5659  throw std::domain_error("cannot use operator[] for object iterators");
5660  }
5661 
5663  {
5664  return *(m_it.array_iterator + n);
5665  }
5666 
5668  {
5669  throw std::out_of_range("cannot get value");
5670  }
5671 
5672  default:
5673  {
5674  return (m_it.primitive_iterator == -n)
5675  ? *m_object
5676  : throw std::out_of_range("cannot get value");
5677  }
5678  }
5679  }
5680 
5682  typename object_t::key_type key() const
5683  {
5684  return m_object->is_object()
5685  ? m_it.object_iterator->first
5686  : throw std::domain_error("cannot use key() for non-object iterators");
5687  }
5688 
5691  {
5692  return operator*();
5693  }
5694 
5695  private:
5697  pointer m_object = nullptr;
5699  internal_iterator m_it = internal_iterator();
5700  };
5701 
5714  class iterator : public const_iterator
5715  {
5716  public:
5718  using pointer = typename basic_json::pointer;
5720 
5722  iterator() = default;
5723 
5725  iterator(pointer object) noexcept : base_iterator(object)
5726  {}
5727 
5729  iterator(const iterator& other) noexcept
5730  : base_iterator(other)
5731  {}
5732 
5734  iterator& operator=(iterator other) noexcept(
5735  std::is_nothrow_move_constructible<pointer>::value and
5736  std::is_nothrow_move_assignable<pointer>::value and
5737  std::is_nothrow_move_constructible<internal_iterator>::value and
5738  std::is_nothrow_move_assignable<internal_iterator>::value
5739  )
5740  {
5741  base_iterator::operator=(other);
5742  return *this;
5743  }
5744 
5747  {
5748  return const_cast<reference>(base_iterator::operator*());
5749  }
5750 
5753  {
5754  return const_cast<pointer>(base_iterator::operator->());
5755  }
5756 
5759  {
5760  iterator result = *this;
5762  return result;
5763  }
5764 
5767  {
5769  return *this;
5770  }
5771 
5774  {
5775  iterator result = *this;
5777  return result;
5778  }
5779 
5782  {
5784  return *this;
5785  }
5786 
5789  {
5791  return *this;
5792  }
5793 
5796  {
5798  return *this;
5799  }
5800 
5803  {
5804  auto result = *this;
5805  result += i;
5806  return result;
5807  }
5808 
5811  {
5812  auto result = *this;
5813  result -= i;
5814  return result;
5815  }
5816 
5817  difference_type operator-(const iterator& other) const
5818  {
5819  return base_iterator::operator-(other);
5820  }
5821 
5824  {
5825  return const_cast<reference>(base_iterator::operator[](n));
5826  }
5827 
5830  {
5831  return const_cast<reference>(base_iterator::value());
5832  }
5833  };
5834 
5852  template<typename Base>
5853  class json_reverse_iterator : public std::reverse_iterator<Base>
5854  {
5855  public:
5857  using base_iterator = std::reverse_iterator<Base>;
5859  using reference = typename Base::reference;
5860 
5862  json_reverse_iterator(const typename base_iterator::iterator_type& it)
5863  : base_iterator(it) {}
5864 
5867 
5870  {
5871  return base_iterator::operator++(1);
5872  }
5873 
5876  {
5877  base_iterator::operator++();
5878  return *this;
5879  }
5880 
5883  {
5884  return base_iterator::operator--(1);
5885  }
5886 
5889  {
5890  base_iterator::operator--();
5891  return *this;
5892  }
5893 
5896  {
5897  base_iterator::operator+=(i);
5898  return *this;
5899  }
5900 
5903  {
5904  auto result = *this;
5905  result += i;
5906  return result;
5907  }
5908 
5911  {
5912  auto result = *this;
5913  result -= i;
5914  return result;
5915  }
5916 
5919  {
5920  return this->base() - other.base();
5921  }
5922 
5925  {
5926  return *(this->operator+(n));
5927  }
5928 
5930  typename object_t::key_type key() const
5931  {
5932  auto it = --this->base();
5933  return it.key();
5934  }
5935 
5938  {
5939  auto it = --this->base();
5940  return it.operator * ();
5941  }
5942  };
5943 
5952  {
5953  private:
5955  basic_json& container;
5957  using json_iterator = decltype(std::begin(container));
5958 
5960  class iterator_wrapper_internal
5961  {
5962  private:
5964  json_iterator anchor;
5966  size_t array_index = 0;
5967 
5968  public:
5970  iterator_wrapper_internal(json_iterator i) : anchor(i)
5971  {}
5972 
5974  iterator_wrapper_internal& operator*()
5975  {
5976  return *this;
5977  }
5978 
5980  iterator_wrapper_internal& operator++()
5981  {
5982  ++anchor;
5983  ++array_index;
5984 
5985  return *this;
5986  }
5987 
5989  bool operator!= (const iterator_wrapper_internal& o)
5990  {
5991  return anchor != o.anchor;
5992  }
5993 
5995  typename basic_json::string_t key() const
5996  {
5997  switch (anchor.m_object->type())
5998  {
5999  // use integer array index as key
6000  case value_t::array:
6001  {
6002  return std::to_string(array_index);
6003  }
6004 
6005  // use key from the object
6006  case value_t::object:
6007  {
6008  return anchor.key();
6009  }
6010 
6011  // use an empty key for all primitive types
6012  default:
6013  {
6014  return "";
6015  }
6016  }
6017  }
6018 
6020  typename json_iterator::reference value() const
6021  {
6022  return anchor.value();
6023  }
6024  };
6025 
6026  public:
6028  iterator_wrapper(basic_json& cont)
6029  : container(cont)
6030  {}
6031 
6033  iterator_wrapper_internal begin()
6034  {
6035  return iterator_wrapper_internal(container.begin());
6036  }
6037 
6039  iterator_wrapper_internal end()
6040  {
6041  return iterator_wrapper_internal(container.end());
6042  }
6043  };
6044 
6045  private:
6047  // lexer and parser //
6049 
6057  class lexer
6058  {
6059  public:
6061  enum class token_type
6062  {
6063  uninitialized,
6064  literal_true,
6065  literal_false,
6066  literal_null,
6067  value_string,
6068  value_number,
6069  begin_array,
6070  begin_object,
6071  end_array,
6072  end_object,
6073  name_separator,
6074  value_separator,
6075  parse_error,
6076  end_of_input
6077  };
6078 
6080  using lexer_char_t = unsigned char;
6081 
6083  explicit lexer(const string_t& s) noexcept
6084  : m_stream(nullptr), m_buffer(s)
6085  {
6086  m_content = reinterpret_cast<const lexer_char_t*>(s.c_str());
6087  m_start = m_cursor = m_content;
6088  m_limit = m_content + s.size();
6089  }
6090  explicit lexer(std::istream* s) noexcept
6091  : m_stream(s), m_buffer()
6092  {
6093  getline(*m_stream, m_buffer);
6094  m_content = reinterpret_cast<const lexer_char_t*>(m_buffer.c_str());
6095  m_start = m_cursor = m_content;
6096  m_limit = m_content + m_buffer.size();
6097  }
6098 
6100  lexer() = default;
6101 
6102  // switch of unwanted functions
6103  lexer(const lexer&) = delete;
6104  lexer operator=(const lexer&) = delete;
6105 
6117  static string_t to_unicode(const std::size_t codepoint1,
6118  const std::size_t codepoint2 = 0)
6119  {
6120  string_t result;
6121 
6122  // calculate the codepoint from the given code points
6123  std::size_t codepoint = codepoint1;
6124 
6125  // check if codepoint1 is a high surrogate
6126  if (codepoint1 >= 0xD800 and codepoint1 <= 0xDBFF)
6127  {
6128  // check if codepoint2 is a low surrogate
6129  if (codepoint2 >= 0xDC00 and codepoint2 <= 0xDFFF)
6130  {
6131  codepoint =
6132  // high surrogate occupies the most significant 22 bits
6133  (codepoint1 << 10)
6134  // low surrogate occupies the least significant 15 bits
6135  + codepoint2
6136  // there is still the 0xD800, 0xDC00 and 0x10000 noise
6137  // in the result so we have to substract with:
6138  // (0xD800 << 10) + DC00 - 0x10000 = 0x35FDC00
6139  - 0x35FDC00;
6140  }
6141  else
6142  {
6143  throw std::invalid_argument("missing or wrong low surrogate");
6144  }
6145  }
6146 
6147  if (codepoint < 0x80)
6148  {
6149  // 1-byte characters: 0xxxxxxx (ASCII)
6150  result.append(1, static_cast<typename string_t::value_type>(codepoint));
6151  }
6152  else if (codepoint <= 0x7ff)
6153  {
6154  // 2-byte characters: 110xxxxx 10xxxxxx
6155  result.append(1, static_cast<typename string_t::value_type>(0xC0 | ((codepoint >> 6) & 0x1F)));
6156  result.append(1, static_cast<typename string_t::value_type>(0x80 | (codepoint & 0x3F)));
6157  }
6158  else if (codepoint <= 0xffff)
6159  {
6160  // 3-byte characters: 1110xxxx 10xxxxxx 10xxxxxx
6161  result.append(1, static_cast<typename string_t::value_type>(0xE0 | ((codepoint >> 12) & 0x0F)));
6162  result.append(1, static_cast<typename string_t::value_type>(0x80 | ((codepoint >> 6) & 0x3F)));
6163  result.append(1, static_cast<typename string_t::value_type>(0x80 | (codepoint & 0x3F)));
6164  }
6165  else if (codepoint <= 0x10ffff)
6166  {
6167  // 4-byte characters: 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
6168  result.append(1, static_cast<typename string_t::value_type>(0xF0 | ((codepoint >> 18) & 0x07)));
6169  result.append(1, static_cast<typename string_t::value_type>(0x80 | ((codepoint >> 12) & 0x3F)));
6170  result.append(1, static_cast<typename string_t::value_type>(0x80 | ((codepoint >> 6) & 0x3F)));
6171  result.append(1, static_cast<typename string_t::value_type>(0x80 | (codepoint & 0x3F)));
6172  }
6173  else
6174  {
6175  throw std::out_of_range("code points above 0x10FFFF are invalid");
6176  }
6177 
6178  return result;
6179  }
6180 
6182  static std::string token_type_name(token_type t)
6183  {
6184  switch (t)
6185  {
6186  case token_type::uninitialized:
6187  return "<uninitialized>";
6188  case token_type::literal_true:
6189  return "true literal";
6190  case token_type::literal_false:
6191  return "false literal";
6192  case token_type::literal_null:
6193  return "null literal";
6194  case token_type::value_string:
6195  return "string literal";
6196  case token_type::value_number:
6197  return "number literal";
6198  case token_type::begin_array:
6199  return "[";
6200  case token_type::begin_object:
6201  return "{";
6202  case token_type::end_array:
6203  return "]";
6204  case token_type::end_object:
6205  return "}";
6206  case token_type::name_separator:
6207  return ":";
6208  case token_type::value_separator:
6209  return ",";
6210  case token_type::end_of_input:
6211  return "<end of input>";
6212  case token_type::parse_error:
6213  return "<parse error>";
6214  }
6215  }
6216 
6227  token_type scan() noexcept
6228  {
6229  // pointer for backtracking information
6230  m_marker = nullptr;
6231 
6232  // remember the begin of the token
6233  m_start = m_cursor;
6234 
6235 
6236  {
6237  lexer_char_t yych;
6238  unsigned int yyaccept = 0;
6239  static const unsigned char yybm[] =
6240  {
6241  0, 0, 0, 0, 0, 0, 0, 0,
6242  0, 32, 32, 0, 0, 32, 0, 0,
6243  64, 64, 64, 64, 64, 64, 64, 64,
6244  64, 64, 64, 64, 64, 64, 64, 64,
6245  96, 64, 0, 64, 64, 64, 64, 64,
6246  64, 64, 64, 64, 64, 64, 64, 64,
6247  192, 192, 192, 192, 192, 192, 192, 192,
6248  192, 192, 64, 64, 64, 64, 64, 64,
6249  64, 64, 64, 64, 64, 64, 64, 64,
6250  64, 64, 64, 64, 64, 64, 64, 64,
6251  64, 64, 64, 64, 64, 64, 64, 64,
6252  64, 64, 64, 64, 0, 64, 64, 64,
6253  64, 64, 64, 64, 64, 64, 64, 64,
6254  64, 64, 64, 64, 64, 64, 64, 64,
6255  64, 64, 64, 64, 64, 64, 64, 64,
6256  64, 64, 64, 64, 64, 64, 64, 64,
6257  64, 64, 64, 64, 64, 64, 64, 64,
6258  64, 64, 64, 64, 64, 64, 64, 64,
6259  64, 64, 64, 64, 64, 64, 64, 64,
6260  64, 64, 64, 64, 64, 64, 64, 64,
6261  64, 64, 64, 64, 64, 64, 64, 64,
6262  64, 64, 64, 64, 64, 64, 64, 64,
6263  64, 64, 64, 64, 64, 64, 64, 64,
6264  64, 64, 64, 64, 64, 64, 64, 64,
6265  64, 64, 64, 64, 64, 64, 64, 64,
6266  64, 64, 64, 64, 64, 64, 64, 64,
6267  64, 64, 64, 64, 64, 64, 64, 64,
6268  64, 64, 64, 64, 64, 64, 64, 64,
6269  64, 64, 64, 64, 64, 64, 64, 64,
6270  64, 64, 64, 64, 64, 64, 64, 64,
6271  64, 64, 64, 64, 64, 64, 64, 64,
6272  64, 64, 64, 64, 64, 64, 64, 64,
6273  };
6274  if ((m_limit - m_cursor) < 5)
6275  {
6276  yyfill(); // LCOV_EXCL_LINE;
6277  }
6278  yych = *m_cursor;
6279  if (yych <= ':')
6280  {
6281  if (yych <= ' ')
6282  {
6283  if (yych <= '\n')
6284  {
6285  if (yych <= 0x00)
6286  {
6287  goto basic_json_parser_28;
6288  }
6289  if (yych <= 0x08)
6290  {
6291  goto basic_json_parser_30;
6292  }
6293  if (yych >= '\n')
6294  {
6295  goto basic_json_parser_4;
6296  }
6297  }
6298  else
6299  {
6300  if (yych == '\r')
6301  {
6302  goto basic_json_parser_2;
6303  }
6304  if (yych <= 0x1F)
6305  {
6306  goto basic_json_parser_30;
6307  }
6308  }
6309  }
6310  else
6311  {
6312  if (yych <= ',')
6313  {
6314  if (yych == '"')
6315  {
6316  goto basic_json_parser_27;
6317  }
6318  if (yych <= '+')
6319  {
6320  goto basic_json_parser_30;
6321  }
6322  goto basic_json_parser_16;
6323  }
6324  else
6325  {
6326  if (yych <= '/')
6327  {
6328  if (yych <= '-')
6329  {
6330  goto basic_json_parser_23;
6331  }
6332  goto basic_json_parser_30;
6333  }
6334  else
6335  {
6336  if (yych <= '0')
6337  {
6338  goto basic_json_parser_24;
6339  }
6340  if (yych <= '9')
6341  {
6342  goto basic_json_parser_26;
6343  }
6344  goto basic_json_parser_18;
6345  }
6346  }
6347  }
6348  }
6349  else
6350  {
6351  if (yych <= 'n')
6352  {
6353  if (yych <= ']')
6354  {
6355  if (yych == '[')
6356  {
6357  goto basic_json_parser_8;
6358  }
6359  if (yych <= '\\')
6360  {
6361  goto basic_json_parser_30;
6362  }
6363  goto basic_json_parser_10;
6364  }
6365  else
6366  {
6367  if (yych == 'f')
6368  {
6369  goto basic_json_parser_22;
6370  }
6371  if (yych <= 'm')
6372  {
6373  goto basic_json_parser_30;
6374  }
6375  goto basic_json_parser_20;
6376  }
6377  }
6378  else
6379  {
6380  if (yych <= '{')
6381  {
6382  if (yych == 't')
6383  {
6384  goto basic_json_parser_21;
6385  }
6386  if (yych <= 'z')
6387  {
6388  goto basic_json_parser_30;
6389  }
6390  goto basic_json_parser_12;
6391  }
6392  else
6393  {
6394  if (yych <= '}')
6395  {
6396  if (yych <= '|')
6397  {
6398  goto basic_json_parser_30;
6399  }
6400  goto basic_json_parser_14;
6401  }
6402  else
6403  {
6404  if (yych == 0xEF)
6405  {
6406  goto basic_json_parser_6;
6407  }
6408  goto basic_json_parser_30;
6409  }
6410  }
6411  }
6412  }
6413 basic_json_parser_2:
6414  ++m_cursor;
6415  yych = *m_cursor;
6416  goto basic_json_parser_5;
6417 basic_json_parser_3:
6418  {
6419  return scan();
6420  }
6421 basic_json_parser_4:
6422  ++m_cursor;
6423  if (m_limit <= m_cursor)
6424  {
6425  yyfill(); // LCOV_EXCL_LINE;
6426  }
6427  yych = *m_cursor;
6428 basic_json_parser_5:
6429  if (yybm[0 + yych] & 32)
6430  {
6431  goto basic_json_parser_4;
6432  }
6433  goto basic_json_parser_3;
6434 basic_json_parser_6:
6435  yyaccept = 0;
6436  yych = *(m_marker = ++m_cursor);
6437  if (yych == 0xBB)
6438  {
6439  goto basic_json_parser_64;
6440  }
6441 basic_json_parser_7:
6442  {
6443  return token_type::parse_error;
6444  }
6445 basic_json_parser_8:
6446  ++m_cursor;
6447  {
6448  return token_type::begin_array;
6449  }
6450 basic_json_parser_10:
6451  ++m_cursor;
6452  {
6453  return token_type::end_array;
6454  }
6455 basic_json_parser_12:
6456  ++m_cursor;
6457  {
6458  return token_type::begin_object;
6459  }
6460 basic_json_parser_14:
6461  ++m_cursor;
6462  {
6463  return token_type::end_object;
6464  }
6465 basic_json_parser_16:
6466  ++m_cursor;
6467  {
6468  return token_type::value_separator;
6469  }
6470 basic_json_parser_18:
6471  ++m_cursor;
6472  {
6473  return token_type::name_separator;
6474  }
6475 basic_json_parser_20:
6476  yyaccept = 0;
6477  yych = *(m_marker = ++m_cursor);
6478  if (yych == 'u')
6479  {
6480  goto basic_json_parser_60;
6481  }
6482  goto basic_json_parser_7;
6483 basic_json_parser_21:
6484  yyaccept = 0;
6485  yych = *(m_marker = ++m_cursor);
6486  if (yych == 'r')
6487  {
6488  goto basic_json_parser_56;
6489  }
6490  goto basic_json_parser_7;
6491 basic_json_parser_22:
6492  yyaccept = 0;
6493  yych = *(m_marker = ++m_cursor);
6494  if (yych == 'a')
6495  {
6496  goto basic_json_parser_51;
6497  }
6498  goto basic_json_parser_7;
6499 basic_json_parser_23:
6500  yych = *++m_cursor;
6501  if (yych <= '/')
6502  {
6503  goto basic_json_parser_7;
6504  }
6505  if (yych <= '0')
6506  {
6507  goto basic_json_parser_50;
6508  }
6509  if (yych <= '9')
6510  {
6511  goto basic_json_parser_41;
6512  }
6513  goto basic_json_parser_7;
6514 basic_json_parser_24:
6515  yyaccept = 1;
6516  yych = *(m_marker = ++m_cursor);
6517  if (yych <= 'D')
6518  {
6519  if (yych == '.')
6520  {
6521  goto basic_json_parser_43;
6522  }
6523  }
6524  else
6525  {
6526  if (yych <= 'E')
6527  {
6528  goto basic_json_parser_44;
6529  }
6530  if (yych == 'e')
6531  {
6532  goto basic_json_parser_44;
6533  }
6534  }
6535 basic_json_parser_25:
6536  {
6537  return token_type::value_number;
6538  }
6539 basic_json_parser_26:
6540  yyaccept = 1;
6541  yych = *(m_marker = ++m_cursor);
6542  goto basic_json_parser_42;
6543 basic_json_parser_27:
6544  yyaccept = 0;
6545  yych = *(m_marker = ++m_cursor);
6546  if (yych <= 0x0F)
6547  {
6548  goto basic_json_parser_7;
6549  }
6550  goto basic_json_parser_32;
6551 basic_json_parser_28:
6552  ++m_cursor;
6553  {
6554  return token_type::end_of_input;
6555  }
6556 basic_json_parser_30:
6557  yych = *++m_cursor;
6558  goto basic_json_parser_7;
6559 basic_json_parser_31:
6560  ++m_cursor;
6561  if (m_limit <= m_cursor)
6562  {
6563  yyfill(); // LCOV_EXCL_LINE;
6564  }
6565  yych = *m_cursor;
6566 basic_json_parser_32:
6567  if (yybm[0 + yych] & 64)
6568  {
6569  goto basic_json_parser_31;
6570  }
6571  if (yych <= 0x0F)
6572  {
6573  goto basic_json_parser_33;
6574  }
6575  if (yych <= '"')
6576  {
6577  goto basic_json_parser_35;
6578  }
6579  goto basic_json_parser_34;
6580 basic_json_parser_33:
6581  m_cursor = m_marker;
6582  if (yyaccept == 0)
6583  {
6584  goto basic_json_parser_7;
6585  }
6586  else
6587  {
6588  goto basic_json_parser_25;
6589  }
6590 basic_json_parser_34:
6591  ++m_cursor;
6592  if (m_limit <= m_cursor)
6593  {
6594  yyfill(); // LCOV_EXCL_LINE;
6595  }
6596  yych = *m_cursor;
6597  if (yych <= 'e')
6598  {
6599  if (yych <= '/')
6600  {
6601  if (yych == '"')
6602  {
6603  goto basic_json_parser_31;
6604  }
6605  if (yych <= '.')
6606  {
6607  goto basic_json_parser_33;
6608  }
6609  goto basic_json_parser_31;
6610  }
6611  else
6612  {
6613  if (yych <= '\\')
6614  {
6615  if (yych <= '[')
6616  {
6617  goto basic_json_parser_33;
6618  }
6619  goto basic_json_parser_31;
6620  }
6621  else
6622  {
6623  if (yych == 'b')
6624  {
6625  goto basic_json_parser_31;
6626  }
6627  goto basic_json_parser_33;
6628  }
6629  }
6630  }
6631  else
6632  {
6633  if (yych <= 'q')
6634  {
6635  if (yych <= 'f')
6636  {
6637  goto basic_json_parser_31;
6638  }
6639  if (yych == 'n')
6640  {
6641  goto basic_json_parser_31;
6642  }
6643  goto basic_json_parser_33;
6644  }
6645  else
6646  {
6647  if (yych <= 's')
6648  {
6649  if (yych <= 'r')
6650  {
6651  goto basic_json_parser_31;
6652  }
6653  goto basic_json_parser_33;
6654  }
6655  else
6656  {
6657  if (yych <= 't')
6658  {
6659  goto basic_json_parser_31;
6660  }
6661  if (yych <= 'u')
6662  {
6663  goto basic_json_parser_37;
6664  }
6665  goto basic_json_parser_33;
6666  }
6667  }
6668  }
6669 basic_json_parser_35:
6670  ++m_cursor;
6671  {
6672  return token_type::value_string;
6673  }
6674 basic_json_parser_37:
6675  ++m_cursor;
6676  if (m_limit <= m_cursor)
6677  {
6678  yyfill(); // LCOV_EXCL_LINE;
6679  }
6680  yych = *m_cursor;
6681  if (yych <= '@')
6682  {
6683  if (yych <= '/')
6684  {
6685  goto basic_json_parser_33;
6686  }
6687  if (yych >= ':')
6688  {
6689  goto basic_json_parser_33;
6690  }
6691  }
6692  else
6693  {
6694  if (yych <= 'F')
6695  {
6696  goto basic_json_parser_38;
6697  }
6698  if (yych <= '`')
6699  {
6700  goto basic_json_parser_33;
6701  }
6702  if (yych >= 'g')
6703  {
6704  goto basic_json_parser_33;
6705  }
6706  }
6707 basic_json_parser_38:
6708  ++m_cursor;
6709  if (m_limit <= m_cursor)
6710  {
6711  yyfill(); // LCOV_EXCL_LINE;
6712  }
6713  yych = *m_cursor;
6714  if (yych <= '@')
6715  {
6716  if (yych <= '/')
6717  {
6718  goto basic_json_parser_33;
6719  }
6720  if (yych >= ':')
6721  {
6722  goto basic_json_parser_33;
6723  }
6724  }
6725  else
6726  {
6727  if (yych <= 'F')
6728  {
6729  goto basic_json_parser_39;
6730  }
6731  if (yych <= '`')
6732  {
6733  goto basic_json_parser_33;
6734  }
6735  if (yych >= 'g')
6736  {
6737  goto basic_json_parser_33;
6738  }
6739  }
6740 basic_json_parser_39:
6741  ++m_cursor;
6742  if (m_limit <= m_cursor)
6743  {
6744  yyfill(); // LCOV_EXCL_LINE;
6745  }
6746  yych = *m_cursor;
6747  if (yych <= '@')
6748  {
6749  if (yych <= '/')
6750  {
6751  goto basic_json_parser_33;
6752  }
6753  if (yych >= ':')
6754  {
6755  goto basic_json_parser_33;
6756  }
6757  }
6758  else
6759  {
6760  if (yych <= 'F')
6761  {
6762  goto basic_json_parser_40;
6763  }
6764  if (yych <= '`')
6765  {
6766  goto basic_json_parser_33;
6767  }
6768  if (yych >= 'g')
6769  {
6770  goto basic_json_parser_33;
6771  }
6772  }
6773 basic_json_parser_40:
6774  ++m_cursor;
6775  if (m_limit <= m_cursor)
6776  {
6777  yyfill(); // LCOV_EXCL_LINE;
6778  }
6779  yych = *m_cursor;
6780  if (yych <= '@')
6781  {
6782  if (yych <= '/')
6783  {
6784  goto basic_json_parser_33;
6785  }
6786  if (yych <= '9')
6787  {
6788  goto basic_json_parser_31;
6789  }
6790  goto basic_json_parser_33;
6791  }
6792  else
6793  {
6794  if (yych <= 'F')
6795  {
6796  goto basic_json_parser_31;
6797  }
6798  if (yych <= '`')
6799  {
6800  goto basic_json_parser_33;
6801  }
6802  if (yych <= 'f')
6803  {
6804  goto basic_json_parser_31;
6805  }
6806  goto basic_json_parser_33;
6807  }
6808 basic_json_parser_41:
6809  yyaccept = 1;
6810  m_marker = ++m_cursor;
6811  if ((m_limit - m_cursor) < 3)
6812  {
6813  yyfill(); // LCOV_EXCL_LINE;
6814  }
6815  yych = *m_cursor;
6816 basic_json_parser_42:
6817  if (yybm[0 + yych] & 128)
6818  {
6819  goto basic_json_parser_41;
6820  }
6821  if (yych <= 'D')
6822  {
6823  if (yych != '.')
6824  {
6825  goto basic_json_parser_25;
6826  }
6827  }
6828  else
6829  {
6830  if (yych <= 'E')
6831  {
6832  goto basic_json_parser_44;
6833  }
6834  if (yych == 'e')
6835  {
6836  goto basic_json_parser_44;
6837  }
6838  goto basic_json_parser_25;
6839  }
6840 basic_json_parser_43:
6841  yych = *++m_cursor;
6842  if (yych <= '/')
6843  {
6844  goto basic_json_parser_33;
6845  }
6846  if (yych <= '9')
6847  {
6848  goto basic_json_parser_48;
6849  }
6850  goto basic_json_parser_33;
6851 basic_json_parser_44:
6852  yych = *++m_cursor;
6853  if (yych <= ',')
6854  {
6855  if (yych != '+')
6856  {
6857  goto basic_json_parser_33;
6858  }
6859  }
6860  else
6861  {
6862  if (yych <= '-')
6863  {
6864  goto basic_json_parser_45;
6865  }
6866  if (yych <= '/')
6867  {
6868  goto basic_json_parser_33;
6869  }
6870  if (yych <= '9')
6871  {
6872  goto basic_json_parser_46;
6873  }
6874  goto basic_json_parser_33;
6875  }
6876 basic_json_parser_45:
6877  yych = *++m_cursor;
6878  if (yych <= '/')
6879  {
6880  goto basic_json_parser_33;
6881  }
6882  if (yych >= ':')
6883  {
6884  goto basic_json_parser_33;
6885  }
6886 basic_json_parser_46:
6887  ++m_cursor;
6888  if (m_limit <= m_cursor)
6889  {
6890  yyfill(); // LCOV_EXCL_LINE;
6891  }
6892  yych = *m_cursor;
6893  if (yych <= '/')
6894  {
6895  goto basic_json_parser_25;
6896  }
6897  if (yych <= '9')
6898  {
6899  goto basic_json_parser_46;
6900  }
6901  goto basic_json_parser_25;
6902 basic_json_parser_48:
6903  yyaccept = 1;
6904  m_marker = ++m_cursor;
6905  if ((m_limit - m_cursor) < 3)
6906  {
6907  yyfill(); // LCOV_EXCL_LINE;
6908  }
6909  yych = *m_cursor;
6910  if (yych <= 'D')
6911  {
6912  if (yych <= '/')
6913  {
6914  goto basic_json_parser_25;
6915  }
6916  if (yych <= '9')
6917  {
6918  goto basic_json_parser_48;
6919  }
6920  goto basic_json_parser_25;
6921  }
6922  else
6923  {
6924  if (yych <= 'E')
6925  {
6926  goto basic_json_parser_44;
6927  }
6928  if (yych == 'e')
6929  {
6930  goto basic_json_parser_44;
6931  }
6932  goto basic_json_parser_25;
6933  }
6934 basic_json_parser_50:
6935  yyaccept = 1;
6936  yych = *(m_marker = ++m_cursor);
6937  if (yych <= 'D')
6938  {
6939  if (yych == '.')
6940  {
6941  goto basic_json_parser_43;
6942  }
6943  goto basic_json_parser_25;
6944  }
6945  else
6946  {
6947  if (yych <= 'E')
6948  {
6949  goto basic_json_parser_44;
6950  }
6951  if (yych == 'e')
6952  {
6953  goto basic_json_parser_44;
6954  }
6955  goto basic_json_parser_25;
6956  }
6957 basic_json_parser_51:
6958  yych = *++m_cursor;
6959  if (yych != 'l')
6960  {
6961  goto basic_json_parser_33;
6962  }
6963  yych = *++m_cursor;
6964  if (yych != 's')
6965  {
6966  goto basic_json_parser_33;
6967  }
6968  yych = *++m_cursor;
6969  if (yych != 'e')
6970  {
6971  goto basic_json_parser_33;
6972  }
6973  ++m_cursor;
6974  {
6975  return token_type::literal_false;
6976  }
6977 basic_json_parser_56:
6978  yych = *++m_cursor;
6979  if (yych != 'u')
6980  {
6981  goto basic_json_parser_33;
6982  }
6983  yych = *++m_cursor;
6984  if (yych != 'e')
6985  {
6986  goto basic_json_parser_33;
6987  }
6988  ++m_cursor;
6989  {
6990  return token_type::literal_true;
6991  }
6992 basic_json_parser_60:
6993  yych = *++m_cursor;
6994  if (yych != 'l')
6995  {
6996  goto basic_json_parser_33;
6997  }
6998  yych = *++m_cursor;
6999  if (yych != 'l')
7000  {
7001  goto basic_json_parser_33;
7002  }
7003  ++m_cursor;
7004  {
7005  return token_type::literal_null;
7006  }
7007 basic_json_parser_64:
7008  yych = *++m_cursor;
7009  if (yych != 0xBF)
7010  {
7011  goto basic_json_parser_33;
7012  }
7013  ++m_cursor;
7014  {
7015  return scan();
7016  }
7017  }
7018 
7019 
7020  }
7021 
7023  void yyfill() noexcept
7024  {
7025  if (not m_stream or not * m_stream)
7026  {
7027  return;
7028  }
7029 
7030  const ssize_t offset_start = m_start - m_content;
7031  const ssize_t offset_marker = m_marker - m_start;
7032  const ssize_t offset_cursor = m_cursor - m_start;
7033 
7034  m_buffer.erase(0, static_cast<size_t>(offset_start));
7035  std::string line;
7036  std::getline(*m_stream, line);
7037  m_buffer += "\n" + line; // add line with newline symbol
7038 
7039  m_content = reinterpret_cast<const lexer_char_t*>(m_buffer.c_str());
7040  m_start = m_content;
7041  m_marker = m_start + offset_marker;
7042  m_cursor = m_start + offset_cursor;
7043  m_limit = m_start + m_buffer.size() - 1;
7044  }
7045 
7047  string_t get_token() const noexcept
7048  {
7049  return string_t(reinterpret_cast<typename string_t::const_pointer>(m_start),
7050  static_cast<size_t>(m_cursor - m_start));
7051  }
7052 
7074  string_t get_string() const
7075  {
7076  string_t result;
7077  result.reserve(static_cast<size_t>(m_cursor - m_start - 2));
7078 
7079  // iterate the result between the quotes
7080  for (const lexer_char_t* i = m_start + 1; i < m_cursor - 1; ++i)
7081  {
7082  // process escaped characters
7083  if (*i == '\\')
7084  {
7085  // read next character
7086  ++i;
7087 
7088  switch (*i)
7089  {
7090  // the default escapes
7091  case 't':
7092  {
7093  result += "\t";
7094  break;
7095  }
7096  case 'b':
7097  {
7098  result += "\b";
7099  break;
7100  }
7101  case 'f':
7102  {
7103  result += "\f";
7104  break;
7105  }
7106  case 'n':
7107  {
7108  result += "\n";
7109  break;
7110  }
7111  case 'r':
7112  {
7113  result += "\r";
7114  break;
7115  }
7116  case '\\':
7117  {
7118  result += "\\";
7119  break;
7120  }
7121  case '/':
7122  {
7123  result += "/";
7124  break;
7125  }
7126  case '"':
7127  {
7128  result += "\"";
7129  break;
7130  }
7131 
7132  // unicode
7133  case 'u':
7134  {
7135  // get code xxxx from uxxxx
7136  auto codepoint = std::strtoul(std::string(reinterpret_cast<typename string_t::const_pointer>(i + 1),
7137  4).c_str(), nullptr, 16);
7138 
7139  // check if codepoint is a high surrogate
7140  if (codepoint >= 0xD800 and codepoint <= 0xDBFF)
7141  {
7142  // make sure there is a subsequent unicode
7143  if ((i + 6 >= m_limit) or * (i + 5) != '\\' or * (i + 6) != 'u')
7144  {
7145  throw std::invalid_argument("missing low surrogate");
7146  }
7147 
7148  // get code yyyy from uxxxx\uyyyy
7149  auto codepoint2 = std::strtoul(std::string(reinterpret_cast<typename string_t::const_pointer>
7150  (i + 7), 4).c_str(), nullptr, 16);
7151  result += to_unicode(codepoint, codepoint2);
7152  // skip the next 10 characters (xxxx\uyyyy)
7153  i += 10;
7154  }
7155  else
7156  {
7157  // add unicode character(s)
7158  result += to_unicode(codepoint);
7159  // skip the next four characters (xxxx)
7160  i += 4;
7161  }
7162  break;
7163  }
7164  }
7165  }
7166  else
7167  {
7168  // all other characters are just copied to the end of the
7169  // string
7170  result.append(1, static_cast<typename string_t::value_type>(*i));
7171  }
7172  }
7173 
7174  return result;
7175  }
7176 
7194  long double get_number() const
7195  {
7196  // conversion
7197  typename string_t::value_type* endptr;
7198  const auto float_val = std::strtold(reinterpret_cast<typename string_t::const_pointer>(m_start),
7199  &endptr);
7200 
7201  // return float_val if the whole number was translated and NAN
7202  // otherwise
7203  return (reinterpret_cast<lexer_char_t*>(endptr) == m_cursor) ? float_val : NAN;
7204  }
7205 
7206  private:
7208  std::istream* m_stream;
7210  string_t m_buffer;
7212  const lexer_char_t* m_content = nullptr;
7214  const lexer_char_t* m_start = nullptr;
7216  const lexer_char_t* m_marker = nullptr;
7218  const lexer_char_t* m_cursor = nullptr;
7220  const lexer_char_t* m_limit = nullptr;
7221  };
7222 
7228  class parser
7229  {
7230  public:
7232  parser(const string_t& s, parser_callback_t cb = nullptr)
7233  : callback(cb), m_lexer(s)
7234  {
7235  // read first token
7236  get_token();
7237  }
7238 
7240  parser(std::istream& _is, parser_callback_t cb = nullptr)
7241  : callback(cb), m_lexer(&_is)
7242  {
7243  // read first token
7244  get_token();
7245  }
7246 
7248  basic_json parse()
7249  {
7250  basic_json result = parse_internal(true);
7251 
7252  expect(lexer::token_type::end_of_input);
7253 
7254  // return parser result and replace it with null in case the
7255  // top-level value was discarded by the callback function
7256  return result.is_discarded() ? basic_json() : result;
7257  }
7258 
7259  private:
7261  basic_json parse_internal(bool keep)
7262  {
7263  auto result = basic_json(value_t::discarded);
7264 
7265  switch (last_token)
7266  {
7267  case lexer::token_type::begin_object:
7268  {
7269  if (keep and (not callback or (keep = callback(depth++, parse_event_t::object_start, result))))
7270  {
7271  // explicitly set result to object to cope with {}
7272  result.m_type = value_t::object;
7273  result.m_value = json_value(value_t::object);
7274  }
7275 
7276  // read next token
7277  get_token();
7278 
7279  // closing } -> we are done
7280  if (last_token == lexer::token_type::end_object)
7281  {
7282  get_token();
7283  if (keep and callback and not callback(--depth, parse_event_t::object_end, result))
7284  {
7285  result = basic_json(value_t::discarded);
7286  }
7287  return result;
7288  }
7289 
7290  // no comma is expected here
7291  unexpect(lexer::token_type::value_separator);
7292 
7293  // otherwise: parse key-value pairs
7294  do
7295  {
7296  // ugly, but could be fixed with loop reorganization
7297  if (last_token == lexer::token_type::value_separator)
7298  {
7299  get_token();
7300  }
7301 
7302  // store key
7303  expect(lexer::token_type::value_string);
7304  const auto key = m_lexer.get_string();
7305 
7306  bool keep_tag = false;
7307  if (keep)
7308  {
7309  if (callback)
7310  {
7311  basic_json k(key);
7312  keep_tag = callback(depth, parse_event_t::key, k);
7313  }
7314  else
7315  {
7316  keep_tag = true;
7317  }
7318  }
7319 
7320  // parse separator (:)
7321  get_token();
7322  expect(lexer::token_type::name_separator);
7323 
7324  // parse and add value
7325  get_token();
7326  auto value = parse_internal(keep);
7327  if (keep and keep_tag and not value.is_discarded())
7328  {
7329  result[key] = std::move(value);
7330  }
7331  }
7332  while (last_token == lexer::token_type::value_separator);
7333 
7334  // closing }
7335  expect(lexer::token_type::end_object);
7336  get_token();
7337  if (keep and callback and not callback(--depth, parse_event_t::object_end, result))
7338  {
7339  result = basic_json(value_t::discarded);
7340  }
7341 
7342  return result;
7343  }
7344 
7345  case lexer::token_type::begin_array:
7346  {
7347  if (keep and (not callback or (keep = callback(depth++, parse_event_t::array_start, result))))
7348  {
7349  // explicitly set result to object to cope with []
7350  result.m_type = value_t::array;
7351  result.m_value = json_value(value_t::array);
7352  }
7353 
7354  // read next token
7355  get_token();
7356 
7357  // closing ] -> we are done
7358  if (last_token == lexer::token_type::end_array)
7359  {
7360  get_token();
7361  if (callback and not callback(--depth, parse_event_t::array_end, result))
7362  {
7363  result = basic_json(value_t::discarded);
7364  }
7365  return result;
7366  }
7367 
7368  // no comma is expected here
7369  unexpect(lexer::token_type::value_separator);
7370 
7371  // otherwise: parse values
7372  do
7373  {
7374  // ugly, but could be fixed with loop reorganization
7375  if (last_token == lexer::token_type::value_separator)
7376  {
7377  get_token();
7378  }
7379 
7380  // parse value
7381  auto value = parse_internal(keep);
7382  if (keep and not value.is_discarded())
7383  {
7384  result.push_back(std::move(value));
7385  }
7386  }
7387  while (last_token == lexer::token_type::value_separator);
7388 
7389  // closing ]
7390  expect(lexer::token_type::end_array);
7391  get_token();
7392  if (keep and callback and not callback(--depth, parse_event_t::array_end, result))
7393  {
7394  result = basic_json(value_t::discarded);
7395  }
7396 
7397  return result;
7398  }
7399 
7400  case lexer::token_type::literal_null:
7401  {
7402  get_token();
7403  result.m_type = value_t::null;
7404  break;
7405  }
7406 
7407  case lexer::token_type::value_string:
7408  {
7409  const auto s = m_lexer.get_string();
7410  get_token();
7411  result = basic_json(s);
7412  break;
7413  }
7414 
7415  case lexer::token_type::literal_true:
7416  {
7417  get_token();
7418  result.m_type = value_t::boolean;
7419  result.m_value = true;
7420  break;
7421  }
7422 
7423  case lexer::token_type::literal_false:
7424  {
7425  get_token();
7426  result.m_type = value_t::boolean;
7427  result.m_value = false;
7428  break;
7429  }
7430 
7431  case lexer::token_type::value_number:
7432  {
7433  auto float_val = m_lexer.get_number();
7434 
7435  // NAN is returned if token could not be translated
7436  // completely
7437  if (std::isnan(float_val))
7438  {
7439  throw std::invalid_argument(std::string("parse error - ") +
7440  m_lexer.get_token() + " is not a number");
7441  }
7442 
7443  get_token();
7444 
7445  // check if conversion loses precision
7446  const auto int_val = static_cast<number_integer_t>(float_val);
7447  if (approx(float_val, static_cast<long double>(int_val)))
7448  {
7449  // we would not lose precision -> return int
7450  result.m_type = value_t::number_integer;
7451  result.m_value = int_val;
7452  }
7453  else
7454  {
7455  // we would lose precision -> return float
7456  result.m_type = value_t::number_float;
7457  result.m_value = static_cast<number_float_t>(float_val);
7458  }
7459  break;
7460  }
7461 
7462  default:
7463  {
7464  // the last token was unexpected
7465  unexpect(last_token);
7466  }
7467  }
7468 
7469  if (keep and callback and not callback(depth, parse_event_t::value, result))
7470  {
7471  result = basic_json(value_t::discarded);
7472  }
7473  return result;
7474  }
7475 
7477  typename lexer::token_type get_token()
7478  {
7479  last_token = m_lexer.scan();
7480  return last_token;
7481  }
7482 
7483  void expect(typename lexer::token_type t) const
7484  {
7485  if (t != last_token)
7486  {
7487  std::string error_msg = "parse error - unexpected \'";
7488  error_msg += m_lexer.get_token();
7489  error_msg += "\' (" + lexer::token_type_name(last_token);
7490  error_msg += "); expected " + lexer::token_type_name(t);
7491  throw std::invalid_argument(error_msg);
7492  }
7493  }
7494 
7495  void unexpect(typename lexer::token_type t) const
7496  {
7497  if (t == last_token)
7498  {
7499  std::string error_msg = "parse error - unexpected \'";
7500  error_msg += m_lexer.get_token();
7501  error_msg += "\' (";
7502  error_msg += lexer::token_type_name(last_token) + ")";
7503  throw std::invalid_argument(error_msg);
7504  }
7505  }
7506 
7507  private:
7509  int depth = 0;
7511  parser_callback_t callback;
7513  typename lexer::token_type last_token = lexer::token_type::uninitialized;
7515  lexer m_lexer;
7516  };
7517 };
7518 
7519 
7521 // presets //
7523 
7533 }
7534 
7535 
7537 // nonmember functions //
7539 
7540 // specialization of std::swap, and std::hash
7541 namespace std
7542 {
7548 template <>
7549 inline void swap(nlohmann::json& j1,
7550  nlohmann::json& j2) noexcept(
7551  is_nothrow_move_constructible<nlohmann::json>::value and
7552  is_nothrow_move_assignable<nlohmann::json>::value
7553  )
7554 {
7555  j1.swap(j2);
7556 }
7557 
7559 template <>
7560 struct hash<nlohmann::json>
7561 {
7567  std::size_t operator()(const nlohmann::json& j) const
7568  {
7569  // a naive hashing via the string representation
7570  const auto& h = hash<nlohmann::json::string_t>();
7571  return h(j.dump());
7572  }
7573 };
7574 }
7575 
7588 inline nlohmann::json operator "" _json(const char* s, std::size_t)
7589 {
7590  return nlohmann::json::parse(reinterpret_cast<nlohmann::json::string_t::value_type*>
7591  (const_cast<char*>(s)));
7592 }
7593 
7594 #endif
basic_json(const number_float_t value)
create a floating-point number (explicit)
Definition: json.hpp:1258
json_reverse_iterator< typename basic_json::iterator > reverse_iterator
a reverse iterator for a basic_json container
Definition: json.hpp:239
iterator_wrapper(basic_json &cont)
construct iterator wrapper from a container
Definition: json.hpp:6028
bool operator!=(const const_iterator &other) const
comparison: not equal
Definition: json.hpp:5531
iterator operator++(int)
post-increment (it++)
Definition: json.hpp:5758
friend bool operator<=(const_reference lhs, const_reference rhs) noexcept
comparison: less than or equal
Definition: json.hpp:4566
iterator insert(const_iterator pos, basic_json &&value)
inserts element
Definition: json.hpp:4017
typename std::allocator_traits< allocator_type >::pointer pointer
the type of an element pointer
Definition: json.hpp:227
json_reverse_iterator operator-(difference_type i) const
subtract from iterator
Definition: json.hpp:5910
static basic_json object(std::initializer_list< basic_json > init=std::initializer_list< basic_json >())
explicitly create an object from an initializer list
Definition: json.hpp:1506
const_reference operator[](size_type idx) const
access specified array element
Definition: json.hpp:2752
reference operator[](const T(&key)[n])
access specified object element
Definition: json.hpp:2830
typename basic_json::const_pointer pointer
defines a pointer to the type iterated over (value_type)
Definition: json.hpp:5243
const_iterator & operator--()
pre-decrement (–it)
Definition: json.hpp:5476
friend std::istream & operator>>(std::istream &i, basic_json &j)
deserialize from stream
Definition: json.hpp:4779
const_iterator & operator=(const_iterator other) noexcept( std::is_nothrow_move_constructible< pointer >::value and std::is_nothrow_move_assignable< pointer >::value and std::is_nothrow_move_constructible< internal_iterator >::value and std::is_nothrow_move_assignable< internal_iterator >::value )
copy assignment
Definition: json.hpp:5308
typename basic_json::value_type value_type
the type of the values when the iterator is dereferenced
Definition: json.hpp:5239
reference & operator=(basic_json other) noexcept( std::is_nothrow_move_constructible< value_t >::value and std::is_nothrow_move_assignable< value_t >::value and std::is_nothrow_move_constructible< json_value >::value and std::is_nothrow_move_assignable< json_value >::value )
copy assignment
Definition: json.hpp:1768
iterator insert(const_iterator pos, const_iterator first, const_iterator last)
inserts elements
Definition: json.hpp:4092
basic_json(const int value)
create an integer number from an enum type (explicit)
Definition: json.hpp:1194
json_reverse_iterator operator--(int)
post-decrement (it–)
Definition: json.hpp:5882
StringType string_t
a type for a string
Definition: json.hpp:433
static basic_json array(std::initializer_list< basic_json > init=std::initializer_list< basic_json >())
explicitly create an array from an initializer list
Definition: json.hpp:1466
iterator & operator++()
pre-increment (++it)
Definition: json.hpp:5766
friend bool operator!=(const_reference lhs, const_reference rhs) noexcept
comparison: not equal
Definition: json.hpp:4444
reference operator+=(const typename object_t::value_type &value)
add an object to an object
Definition: json.hpp:3965
ArrayType< basic_json, AllocatorType< basic_json >> array_t
a type for an array
Definition: json.hpp:386
const_iterator & operator++()
pre-increment (++it)
Definition: json.hpp:5441
difference_type operator-(const json_reverse_iterator &other) const
return difference
Definition: json.hpp:5918
basic_json<> json
default JSON class
Definition: json.hpp:7532
reference front()
access the first element
Definition: json.hpp:2947
bool is_array() const noexcept
return whether value is an array
Definition: json.hpp:2081
const_iterator find(typename object_t::key_type key) const
find an element in a JSON object
Definition: json.hpp:3308
std::reverse_iterator< Base > base_iterator
shortcut to the reverse iterator adaptor
Definition: json.hpp:5857
json_reverse_iterator(const typename base_iterator::iterator_type &it)
create reverse iterator from iterator
Definition: json.hpp:5862
a class to store JSON values
Definition: json.hpp:187
json_reverse_iterator & operator--()
pre-decrement (–it)
Definition: json.hpp:5888
void push_back(const typename object_t::value_type &value)
add an object to an object
Definition: json.hpp:3942
friend bool operator==(std::nullptr_t, const_reference v) noexcept
comparison: equal
Definition: json.hpp:4423
const_iterator cbegin() const
returns a const iterator to the first element
Definition: json.hpp:3406
basic_json(const CompatibleObjectType &value)
create an object (implicit)
Definition: json.hpp:965
bool is_string() const noexcept
return whether value is a string
Definition: json.hpp:2100
iterator & operator+=(difference_type i)
add to iterator
Definition: json.hpp:5788
const PointerType get_ptr() const noexcept
get a pointer value (implicit)
Definition: json.hpp:2509
the parser read ] and finished processing a JSON array
const_iterator base_iterator
Definition: json.hpp:5717
a mutable random access iterator for the basic_json class
Definition: json.hpp:5714
iterator & operator-=(difference_type i)
subtract from iterator
Definition: json.hpp:5795
static basic_json parse(std::istream &&i, parser_callback_t cb=nullptr)
deserialize from stream
Definition: json.hpp:4741
reference operator[](const typename object_t::key_type &key)
access specified object element
Definition: json.hpp:2786
STL namespace.
difference_type operator-(const iterator &other) const
Definition: json.hpp:5817
reference value() const
return the value of an iterator
Definition: json.hpp:5690
iterator insert(const_iterator pos, size_type count, const basic_json &value)
inserts elements
Definition: json.hpp:4044
const_iterator end() const
returns a const iterator to one past the last element
Definition: json.hpp:3441
const_iterator(const const_iterator &other) noexcept
copy constructor
Definition: json.hpp:5303
reference at(const typename object_t::key_type &key)
access specified object element with bounds checking
Definition: json.hpp:2644
reference operator+=(const basic_json &value)
add an object to an array
Definition: json.hpp:3916
object_t::key_type key() const
return the key of an object iterator
Definition: json.hpp:5682
iterator end()
returns an iterator to one past the last element
Definition: json.hpp:3431
ObjectType< StringType, basic_json, std::less< StringType >, AllocatorType< std::pair< const StringType, basic_json >>> object_t
a type for an object
Definition: json.hpp:340
reference operator*()
return a reference to the value pointed to by the iterator
Definition: json.hpp:5746
reverse_iterator rend()
returns an iterator to the reverse-end
Definition: json.hpp:3520
bool is_object() const noexcept
return whether value is an object
Definition: json.hpp:2062
const_iterator operator-(difference_type i)
subtract from iterator
Definition: json.hpp:5623
bool is_discarded() const noexcept
return whether value is discarded
Definition: json.hpp:2124
typename basic_json::const_reference reference
defines a reference to the type iterated over (value_type)
Definition: json.hpp:5245
const_reverse_iterator rend() const
returns a const reverse iterator to one before the first
Definition: json.hpp:3528
basic_json(const CompatibleArrayType &value)
create an array (implicit)
Definition: json.hpp:1029
size_type erase(const typename object_t::key_type &key)
remove element from a JSON object given a key
Definition: json.hpp:3227
bool is_boolean() const noexcept
return whether value is a boolean
Definition: json.hpp:1973
iterator begin()
returns an iterator to the first element
Definition: json.hpp:3372
const_reference at(const typename object_t::key_type &key) const
access specified object element with bounds checking
Definition: json.hpp:2677
AllocatorType< basic_json > allocator_type
the allocator type
Definition: json.hpp:224
bool is_number_integer() const noexcept
return whether value is an integer number
Definition: json.hpp:2020
basic_json(const string_t &value)
create a string (explicit)
Definition: json.hpp:1058
iterator operator+(difference_type i)
add to iterator
Definition: json.hpp:5802
std::function< bool(int depth, parse_event_t event, basic_json &parsed)> parser_callback_t
per-element parser callback type
Definition: json.hpp:819
const_iterator()=default
default constructor
the parser read [ and started to process a JSON array
iterator find(typename object_t::key_type key)
find an element in a JSON object
Definition: json.hpp:3292
friend bool operator>=(const_reference lhs, const_reference rhs) noexcept
comparison: greater than or equal
Definition: json.hpp:4610
iterator & operator--()
pre-decrement (–it)
Definition: json.hpp:5781
friend bool operator<(const_reference lhs, const_reference rhs) noexcept
comparison: less than
Definition: json.hpp:4505
pointer operator->() const
dereference the iterator
Definition: json.hpp:5409
discarded by the the parser callback function
const_iterator cend() const
returns a const iterator to one past the last element
Definition: json.hpp:3465
typename Base::reference reference
the reference type for the pointed-to element
Definition: json.hpp:5859
size_type size() const noexcept
returns the number of elements
Definition: json.hpp:3675
static allocator_type get_allocator()
returns the allocator associated with the container
Definition: json.hpp:249
object (unordered set of name/value pairs)
reference at(size_type idx)
access specified array element with bounds checking
Definition: json.hpp:2582
the parser read } and finished processing a JSON object
iterator()=default
default constructor
json_reverse_iterator(const base_iterator &it)
create reverse iterator from base class
Definition: json.hpp:5866
iterator_wrapper_internal end()
return iterator end (needed for range-based for)
Definition: json.hpp:6039
value_t type() const noexcept
return the type of the JSON value (explicit)
Definition: json.hpp:1894
friend std::ostream & operator>>(const basic_json &j, std::ostream &o)
serialize to stream
Definition: json.hpp:4665
ValueType value(const typename object_t::key_type &key, ValueType default_value) const
access specified object element with default value
Definition: json.hpp:2896
basic_json(size_type count, const basic_json &value)
construct an array with count copies of given value
Definition: json.hpp:1530
object_t::key_type key() const
return the key of an object iterator
Definition: json.hpp:5930
bool is_structured() const noexcept
return whether type is structured
Definition: json.hpp:1935
namespace for Niels Lohmann
Definition: json.hpp:78
typename basic_json::difference_type difference_type
a type to represent differences between iterators
Definition: json.hpp:5241
void swap(array_t &other)
exchanges the values
Definition: json.hpp:4213
reverse_iterator rbegin()
returns an iterator to the reverse-beginning
Definition: json.hpp:3489
iterator_wrapper_internal begin()
return iterator begin (needed for range-based for)
Definition: json.hpp:6033
reference operator[](difference_type n) const
access to successor
Definition: json.hpp:5823
std::size_t size_type
a type to represent container sizes
Definition: json.hpp:221
reference operator+=(basic_json &&value)
add an object to an array
Definition: json.hpp:3883
const_reverse_iterator rbegin() const
returns a const reverse iterator to the last element
Definition: json.hpp:3497
~basic_json()
destructor
Definition: json.hpp:1794
basic_json(const array_t &value)
create an array (explicit)
Definition: json.hpp:992
basic_json(const basic_json &other)
copy constructor
Definition: json.hpp:1672
const_iterator operator+(difference_type i)
add to iterator
Definition: json.hpp:5615
basic_json(boolean_t value)
create a boolean (explicit)
Definition: json.hpp:1131
value_t
the JSON type enumeration
Definition: json.hpp:611
const value_type & const_reference
the type of an element const reference
Definition: json.hpp:215
basic_json(const CompatibleNumberFloatType value) noexcept
create an floating-point number (implicit)
Definition: json.hpp:1304
bool is_null() const noexcept
return whether value is null
Definition: json.hpp:1954
void swap(string_t &other)
exchanges the values
Definition: json.hpp:4277
reference value() const
return the value of an iterator
Definition: json.hpp:5829
void push_back(basic_json &&value)
add an object to an array
Definition: json.hpp:3858
const_iterator operator--(int)
post-decrement (it–)
Definition: json.hpp:5468
void erase(const size_type idx)
remove element from a JSON array given an index
Definition: json.hpp:3257
void clear() noexcept
clears the contents
Definition: json.hpp:3792
basic_json(const CompatibleStringType &value)
create a string (implicit)
Definition: json.hpp:1113
pointer operator->()
dereference the iterator
Definition: json.hpp:5752
basic_json value_type
the type of elements in a basic_json container
Definition: json.hpp:209
array (ordered collection of values)
const_reference front() const
access the first element
Definition: json.hpp:2955
bool operator>=(const const_iterator &other) const
comparison: greater than or equal
Definition: json.hpp:5577
iterator insert(const_iterator pos, std::initializer_list< basic_json > ilist)
inserts elements
Definition: json.hpp:4146
std::ptrdiff_t difference_type
a type to represent differences between iterators
Definition: json.hpp:218
const_iterator & operator+=(difference_type i)
add to iterator
Definition: json.hpp:5583
basic_json(std::initializer_list< basic_json > init, bool type_deduction=true, value_t manual_type=value_t::array)
create a container (array or object) from an initializer list
Definition: json.hpp:1376
difference_type operator-(const const_iterator &other) const
return difference
Definition: json.hpp:5631
friend bool operator==(const_reference lhs, const_reference rhs) noexcept
comparison: equal
Definition: json.hpp:4356
bool is_number() const noexcept
return whether value is a number
Definition: json.hpp:1997
BooleanType boolean_t
a type for a boolean
Definition: json.hpp:459
const_reverse_iterator crend() const
returns a const reverse iterator to one before the first
Definition: json.hpp:3574
basic_json() noexcept=default
create a null object (implicitly)
the parser read a key of a value in an object
bool empty() const noexcept
checks whether the container is empty
Definition: json.hpp:3618
string_t value(const typename object_t::key_type &key, const char *default_value) const
overload for a default value of type const char*
Definition: json.hpp:2922
void swap(reference other) noexcept( std::is_nothrow_move_constructible< value_t >::value and std::is_nothrow_move_assignable< value_t >::value and std::is_nothrow_move_constructible< json_value >::value and std::is_nothrow_move_assignable< json_value >::value )
exchanges the values
Definition: json.hpp:4183
basic_json(const object_t &value)
create an object (explicit)
Definition: json.hpp:933
json_reverse_iterator< typename basic_json::const_iterator > const_reverse_iterator
a const reverse iterator for a basic_json container
Definition: json.hpp:241
const_reverse_iterator crbegin() const
returns a const reverse iterator to the last element
Definition: json.hpp:3551
reference value() const
return the value of an iterator
Definition: json.hpp:5937
const_iterator(pointer object)
constructor for a given JSON instance
Definition: json.hpp:5253
friend bool operator<(const value_t lhs, const value_t rhs)
comparison operator for JSON types
Definition: json.hpp:4310
iterator(pointer object) noexcept
constructor for a given JSON instance
Definition: json.hpp:5725
bool operator<(const const_iterator &other) const
comparison: smaller
Definition: json.hpp:5537
string_t dump(const int indent=-1) const
serialization
Definition: json.hpp:1863
friend bool operator!=(const_reference v, std::nullptr_t) noexcept
comparison: not equal
Definition: json.hpp:4467
const_iterator & operator-=(difference_type i)
subtract from iterator
Definition: json.hpp:5609
number value (floating-point)
basic_json(const CompatibleNumberIntegerType value) noexcept
create an integer number (implicit)
Definition: json.hpp:1229
static basic_json parse(const string_t &s, parser_callback_t cb=nullptr)
deserialize from string
Definition: json.hpp:4704
InteratorType erase(InteratorType first, InteratorType last)
remove elements given an iterator range
Definition: json.hpp:3147
json_reverse_iterator operator++(int)
post-increment (it++)
Definition: json.hpp:5869
PointerType get_ptr() noexcept
get a pointer value (implicit)
Definition: json.hpp:2494
void push_back(const basic_json &value)
add an object to an array
Definition: json.hpp:3893
const_iterator(const iterator &other)
copy constructor given a nonconst iterator
Definition: json.hpp:5278
friend bool operator!=(std::nullptr_t, const_reference v) noexcept
comparison: not equal
Definition: json.hpp:4476
InteratorType erase(InteratorType pos)
remove element given an iterator
Definition: json.hpp:3046
basic_json(const typename string_t::value_type *value)
create a string (explicit)
Definition: json.hpp:1082
bool operator<=(const const_iterator &other) const
comparison: less than or equal
Definition: json.hpp:5565
reference back()
access the last element
Definition: json.hpp:2981
bool is_number_float() const noexcept
return whether value is a floating-point number
Definition: json.hpp:2043
the parser read { and started to process a JSON object
const_iterator operator++(int)
post-increment (it++)
Definition: json.hpp:5433
typename std::allocator_traits< allocator_type >::const_pointer const_pointer
the type of an element const pointer
Definition: json.hpp:229
iterator(const iterator &other) noexcept
copy constructor
Definition: json.hpp:5729
const_reference back() const
access the last element
Definition: json.hpp:2991
basic_json(InputIT first, InputIT last)
construct a JSON container given an iterator range
Definition: json.hpp:1574
static basic_json parse(std::istream &i, parser_callback_t cb=nullptr)
deserialize from stream
Definition: json.hpp:4733
size_type count(typename object_t::key_type key) const
returns the number of occurrences of a key in a JSON object
Definition: json.hpp:3338
size_type max_size() const noexcept
returns the maximum possible number of elements
Definition: json.hpp:3735
bool operator==(const const_iterator &other) const
comparison: equal
Definition: json.hpp:5503
json_reverse_iterator & operator++()
pre-increment (++it)
Definition: json.hpp:5875
bool operator>(const const_iterator &other) const
comparison: greater than
Definition: json.hpp:5571
friend bool operator>(const_reference lhs, const_reference rhs) noexcept
comparison: greater than
Definition: json.hpp:4588
basic_json(basic_json &&other) noexcept
move constructor
Definition: json.hpp:1738
const_iterator begin() const
returns a const iterator to the first element
Definition: json.hpp:3382
const_reference at(size_type idx) const
access specified array element with bounds checking
Definition: json.hpp:2611
json_reverse_iterator & operator+=(difference_type i)
add to iterator
Definition: json.hpp:5895
a const random access iterator for the basic_json class
Definition: json.hpp:5232
a template for a reverse iterator class
Definition: json.hpp:232
void swap(object_t &other)
exchanges the values
Definition: json.hpp:4245
std::bidirectional_iterator_tag iterator_category
the category of the iterator
Definition: json.hpp:5247
bool is_primitive() const noexcept
return whether type is primitive
Definition: json.hpp:1915
basic_json(const value_t value)
create an empty value with a given type
Definition: json.hpp:866
friend bool operator==(const_reference v, std::nullptr_t) noexcept
comparison: equal
Definition: json.hpp:4414
reference operator[](difference_type n) const
access to successor
Definition: json.hpp:5924
NumberIntegerType number_integer_t
a type for a number (integer)
Definition: json.hpp:527
reference operator[](difference_type n) const
access to successor
Definition: json.hpp:5653
reference operator*() const
return a reference to the value pointed to by the iterator
Definition: json.hpp:5380
iterator insert(const_iterator pos, const basic_json &value)
inserts element
Definition: json.hpp:3991
value_type & reference
the type of an element reference
Definition: json.hpp:212
friend std::istream & operator<<(basic_json &j, std::istream &i)
deserialize from stream
Definition: json.hpp:4769
the parser finished reading a JSON value
NumberFloatType number_float_t
a type for a number (floating-point)
Definition: json.hpp:592
std::size_t operator()(const nlohmann::json &j) const
return a hash value for a JSON object
Definition: json.hpp:7567
friend std::ostream & operator<<(std::ostream &o, const basic_json &j)
serialize to stream
Definition: json.hpp:4647
iterator & operator=(iterator other) noexcept( std::is_nothrow_move_constructible< pointer >::value and std::is_nothrow_move_assignable< pointer >::value and std::is_nothrow_move_constructible< internal_iterator >::value and std::is_nothrow_move_assignable< internal_iterator >::value )
copy assignment
Definition: json.hpp:5734
reference operator[](size_type idx)
access specified array element
Definition: json.hpp:2709
iterator operator--(int)
post-decrement (it–)
Definition: json.hpp:5773
json_reverse_iterator operator+(difference_type i) const
add to iterator
Definition: json.hpp:5902
parse_event_t
JSON callback events.
Definition: json.hpp:754
iterator operator-(difference_type i)
subtract from iterator
Definition: json.hpp:5810
wrapper to access iterator member functions in range-based for
Definition: json.hpp:5951