30 #ifndef _NLOHMANN_JSON
31 #define _NLOHMANN_JSON
37 #include <initializer_list>
46 #include <type_traits>
64 template<
typename C>
static char test(
typename C::mapped_type*);
65 template<
typename C>
static int test(...);
67 enum {
value =
sizeof(test<T>(0)) ==
sizeof(char) };
94 template<
typename U,
typename V,
typename... Args>
class ObjectType = std::map,
95 template<
typename U,
typename... Args>
class ArrayType = std::vector,
96 class StringType = std::string,
97 class BooleanType = bool,
98 class NumberIntegerType = int64_t,
99 class NumberFloatType = double,
100 template<
typename U>
class Allocator = std::allocator
190 using object_t = ObjectType<StringType, basic_json>;
269 case (value_t::null):
275 case (value_t::boolean):
278 return (rhs != value_t::null);
281 case (value_t::number_float):
282 case (value_t::number_integer):
287 case (value_t::object):
288 case (value_t::array):
289 case (value_t::string):
301 case (value_t::object):
306 case (value_t::array):
307 case (value_t::string):
319 case (value_t::array):
322 return (rhs == value_t::string);
349 case (value_t::null):
354 case (value_t::object):
356 Allocator<object_t> alloc;
357 m_value.object = alloc.allocate(1);
358 alloc.construct(m_value.object);
362 case (value_t::array):
364 Allocator<array_t> alloc;
365 m_value.array = alloc.allocate(1);
366 alloc.construct(m_value.array);
370 case (value_t::string):
372 Allocator<string_t> alloc;
373 m_value.string = alloc.allocate(1);
374 alloc.construct(m_value.string,
"");
378 case (value_t::boolean):
384 case (value_t::number_integer):
390 case (value_t::number_float):
413 Allocator<object_t> alloc;
414 m_value.object = alloc.allocate(1);
415 alloc.construct(m_value.object, value);
419 template <
class V,
typename
421 std::is_constructible<typename object_t::key_type, typename V::key_type>::value and
422 std::is_constructible<basic_json, typename V::mapped_type>::value,
int>::type
427 Allocator<object_t> alloc;
428 m_value.object = alloc.allocate(1);
431 alloc.construct(m_value.object, begin(value), end(value));
438 Allocator<array_t> alloc;
439 m_value.array = alloc.allocate(1);
440 alloc.construct(m_value.array, value);
444 template <
class V,
typename
446 not std::is_same<V, basic_json::iterator>::value and
447 not std::is_same<V, basic_json::const_iterator>::value and
448 not std::is_same<V, basic_json::reverse_iterator>::value and
449 not std::is_same<V, basic_json::const_reverse_iterator>::value and
450 not std::is_same<V, typename array_t::iterator>::value and
451 not std::is_same<V, typename array_t::const_iterator>::value and
452 std::is_constructible<basic_json, typename V::value_type>::value,
int>::type
457 Allocator<array_t> alloc;
458 m_value.array = alloc.allocate(1);
461 alloc.construct(m_value.array, begin(value), end(value));
468 Allocator<string_t> alloc;
469 m_value.string = alloc.allocate(1);
470 alloc.construct(m_value.string, value);
477 Allocator<string_t> alloc;
478 m_value.string = alloc.allocate(1);
479 alloc.construct(m_value.string, value);
483 template <
class V,
typename
485 std::is_constructible<string_t, V>::value,
int>::type
493 : m_type(
value_t::boolean), m_value(value)
498 : m_type(
value_t::number_integer), m_value(value)
502 template<
typename T,
typename
504 std::is_constructible<number_integer_t, T>::value and
505 std::numeric_limits<T>::is_integer, T>::type
513 : m_type(
value_t::number_float), m_value(value)
517 template<
typename T,
typename =
typename
519 std::is_constructible<number_float_t, T>::value and
520 std::is_floating_point<T>::value>::type
530 bool is_object =
true;
534 for (
const auto& element : l)
536 if ((element.m_final and element.m_type == value_t::array)
537 or (element.m_type != value_t::array or element.size() != 2
538 or element[0].m_type != value_t::string))
548 if (not type_deduction)
554 if (manual_type == value_t::array)
560 if (manual_type == value_t::object and not is_object)
562 throw std::logic_error(
"cannot create JSON object from initializer list");
569 m_type = value_t::object;
570 Allocator<object_t> alloc;
571 m_value.object = alloc.allocate(1);
572 alloc.construct(m_value.object);
574 for (
auto& element : l)
576 m_value.object->emplace(std::move(*(element[0].m_value.string)), std::move(element[1]));
582 m_type = value_t::array;
583 Allocator<array_t> alloc;
584 m_value.array = alloc.allocate(1);
585 alloc.construct(m_value.array, std::move(l));
614 : m_type(other.m_type)
618 case (value_t::null):
623 case (value_t::object):
625 Allocator<object_t> alloc;
626 m_value.object = alloc.allocate(1);
631 case (value_t::array):
633 Allocator<array_t> alloc;
634 m_value.array = alloc.allocate(1);
639 case (value_t::string):
641 Allocator<string_t> alloc;
642 m_value.string = alloc.allocate(1);
647 case (value_t::boolean):
653 case (value_t::number_integer):
659 case (value_t::number_float):
669 : m_type(std::move(other.m_type)),
670 m_value(std::move(other.m_value))
673 other.m_type = value_t::null;
682 std::is_nothrow_move_constructible<value_t>::value and
683 std::is_nothrow_move_assignable<value_t>::value and
684 std::is_nothrow_move_constructible<json_value>::value and
685 std::is_nothrow_move_assignable<json_value>::value
701 case (value_t::object):
703 Allocator<object_t> alloc;
704 alloc.destroy(m_value.object);
705 alloc.deallocate(m_value.object, 1);
706 m_value.object =
nullptr;
710 case (value_t::array):
712 Allocator<array_t> alloc;
713 alloc.destroy(m_value.array);
714 alloc.deallocate(m_value.array, 1);
715 m_value.array =
nullptr;
719 case (value_t::string):
721 Allocator<string_t> alloc;
722 alloc.destroy(m_value.string);
723 alloc.deallocate(m_value.string, 1);
724 m_value.string =
nullptr;
760 return dump(
true, static_cast<unsigned int>(indent));
764 return dump(
false, 0);
777 return m_type == value_t::null;
783 return m_type == value_t::boolean;
789 return (m_type == value_t::number_integer) or (m_type == value_t::number_float);
795 return m_type == value_t::object;
801 return m_type == value_t::array;
807 return m_type == value_t::string;
822 template <
class T,
typename
824 std::is_convertible<typename object_t::key_type, typename T::key_type>::value and
825 std::is_convertible<basic_json, typename T::mapped_type>::value
831 case (value_t::object):
833 return T(m_value.object->begin(), m_value.object->end());
837 throw std::logic_error(
"cannot cast " + type_name() +
" to " +
typeid(T).name());
847 case (value_t::object):
849 return *(m_value.object);
853 throw std::logic_error(
"cannot cast " + type_name() +
" to object");
859 template <
class T,
typename
861 std::is_convertible<basic_json, typename T::value_type>::value and
862 not std::is_same<basic_json, typename T::value_type>::value and
863 not std::is_arithmetic<T>::value and
864 not std::is_convertible<std::string, T>::value and
871 case (value_t::array):
875 std::transform(m_value.array->begin(), m_value.array->end(),
876 std::inserter(to_vector, to_vector.end()), [](
basic_json i)
878 return i.
get<
typename T::value_type>();
886 throw std::logic_error(
"cannot cast " + type_name() +
" to " +
typeid(T).name());
892 template <
class T,
typename
894 std::is_convertible<basic_json, T>::value and
895 not std::is_same<basic_json, T>::value
897 inline std::vector<T>
get_impl(std::vector<T>*)
const
901 case (value_t::array):
903 std::vector<T> to_vector;
904 to_vector.reserve(m_value.array->size());
905 std::transform(m_value.array->begin(), m_value.array->end(),
906 std::inserter(to_vector, to_vector.end()), [](
basic_json i)
914 throw std::logic_error(
"cannot cast " + type_name() +
" to " +
typeid(T).name());
920 template <
class T,
typename
922 std::is_same<basic_json, typename T::value_type>::value and
929 case (value_t::array):
931 return T(m_value.array->begin(), m_value.array->end());
935 throw std::logic_error(
"cannot cast " + type_name() +
" to " +
typeid(T).name());
944 case (value_t::array):
946 return *(m_value.array);
950 throw std::logic_error(
"cannot cast " + type_name() +
" to array");
956 template <
typename T,
typename
958 std::is_convertible<string_t, T>::value
964 case (value_t::string):
966 return *m_value.string;
970 throw std::logic_error(
"cannot cast " + type_name() +
" to " +
typeid(T).name());
976 template<
typename T,
typename
978 std::is_arithmetic<T>::value
984 case (value_t::number_integer):
986 return static_cast<T
>(m_value.number_integer);
988 case (value_t::number_float):
990 return static_cast<T
>(m_value.number_float);
994 throw std::logic_error(
"cannot cast " + type_name() +
" to " +
typeid(T).name());
1004 case (value_t::boolean):
1006 return m_value.boolean;
1010 throw std::logic_error(
"cannot cast " + type_name() +
" to " +
typeid(
boolean_t).name());
1018 template<
typename T>
1019 inline T
get()
const
1021 return get_impl(static_cast<T*>(
nullptr));
1025 template<
typename T>
1026 inline operator T()
const
1040 if (m_type != value_t::array)
1042 throw std::runtime_error(
"cannot use at with " + type_name());
1045 return m_value.array->at(pos);
1052 if (m_type != value_t::array)
1054 throw std::runtime_error(
"cannot use at with " + type_name());
1057 return m_value.array->at(pos);
1064 if (m_type == value_t::null)
1066 m_type = value_t::array;
1067 Allocator<array_t> alloc;
1068 m_value.
array = alloc.allocate(1);
1069 alloc.construct(m_value.array);
1073 if (m_type != value_t::array)
1075 throw std::runtime_error(
"cannot use [] with " + type_name());
1078 for (
size_t i = m_value.array->size(); i <= pos; ++i)
1083 return m_value.array->operator[](pos);
1090 if (m_type != value_t::array)
1092 throw std::runtime_error(
"cannot use [] with " + type_name());
1095 return m_value.array->operator[](pos);
1102 if (m_type != value_t::object)
1104 throw std::runtime_error(
"cannot use at with " + type_name());
1107 return m_value.object->at(key);
1114 if (m_type != value_t::object)
1116 throw std::runtime_error(
"cannot use at with " + type_name());
1119 return m_value.object->at(key);
1126 if (m_type == value_t::null)
1128 m_type = value_t::object;
1129 Allocator<object_t> alloc;
1130 m_value.
object = alloc.allocate(1);
1131 alloc.construct(m_value.object);
1135 if (m_type != value_t::object)
1137 throw std::runtime_error(
"cannot use [] with " + type_name());
1140 return m_value.object->operator[](key);
1147 if (m_type != value_t::object)
1149 throw std::runtime_error(
"cannot use [] with " + type_name());
1152 return m_value.object->operator[](key);
1156 template<
typename T,
size_t n>
1160 if (m_type == value_t::null)
1162 m_type = value_t::object;
1163 Allocator<object_t> alloc;
1164 m_value.
object = alloc.allocate(1);
1165 alloc.construct(m_value.object);
1169 if (m_type != value_t::object)
1171 throw std::runtime_error(
"cannot use [] with " + type_name());
1174 return m_value.object->operator[](key);
1178 template<
typename T,
size_t n>
1182 if (m_type != value_t::object)
1184 throw std::runtime_error(
"cannot use [] with " + type_name());
1187 return m_value.object->operator[](key);
1194 if (m_type != value_t::object)
1196 throw std::runtime_error(
"cannot use erase with " + type_name());
1199 return m_value.object->erase(key);
1206 if (m_type != value_t::array)
1208 throw std::runtime_error(
"cannot use erase with " + type_name());
1213 throw std::out_of_range(
"index out of range");
1216 m_value.array->erase(m_value.array->begin() +
static_cast<difference_type>(pos));
1222 auto result = end();
1224 if (m_type == value_t::object)
1226 result.m_it.object_iterator = m_value.object->find(key);
1235 auto result = cend();
1237 if (m_type == value_t::object)
1239 result.m_it.object_iterator = m_value.object->find(key);
1249 return (m_type == value_t::object) ? m_value.object->count(key) : 0;
1390 case (value_t::null):
1395 case (value_t::array):
1397 return m_value.array->empty();
1400 case (value_t::object):
1402 return m_value.object->empty();
1421 case (value_t::null):
1426 case (value_t::array):
1428 return m_value.array->size();
1431 case (value_t::object):
1433 return m_value.object->size();
1452 case (value_t::null):
1457 case (value_t::array):
1459 return m_value.array->max_size();
1462 case (value_t::object):
1464 return m_value.object->max_size();
1485 case (value_t::null):
1490 case (value_t::number_integer):
1492 m_value.number_integer = 0;
1496 case (value_t::number_float):
1498 m_value.number_float = 0.0;
1502 case (value_t::boolean):
1504 m_value.boolean =
false;
1508 case (value_t::string):
1510 m_value.string->clear();
1514 case (value_t::array):
1516 m_value.array->clear();
1520 case (value_t::object):
1522 m_value.object->clear();
1532 if (not(m_type == value_t::null or m_type == value_t::array))
1534 throw std::runtime_error(
"cannot add element to " + type_name());
1538 if (m_type == value_t::null)
1540 m_type = value_t::array;
1541 Allocator<array_t> alloc;
1542 m_value.array = alloc.allocate(1);
1543 alloc.construct(m_value.array);
1547 m_value.array->push_back(std::move(
value));
1549 value.m_type = value_t::null;
1555 push_back(std::move(
value));
1563 if (not(m_type == value_t::null or m_type == value_t::array))
1565 throw std::runtime_error(
"cannot add element to " + type_name());
1569 if (m_type == value_t::null)
1571 m_type = value_t::array;
1572 Allocator<array_t> alloc;
1573 m_value.array = alloc.allocate(1);
1574 alloc.construct(m_value.array);
1578 m_value.array->push_back(value);
1592 if (not(m_type == value_t::null or m_type == value_t::object))
1594 throw std::runtime_error(
"cannot add element to " + type_name());
1598 if (m_type == value_t::null)
1600 m_type = value_t::object;
1601 Allocator<object_t> alloc;
1602 m_value.object = alloc.allocate(1);
1603 alloc.construct(m_value.object);
1607 m_value.object->insert(value);
1614 return operator[](value.first);
1622 std::is_nothrow_move_constructible<value_t>::value and
1623 std::is_nothrow_move_assignable<value_t>::value and
1624 std::is_nothrow_move_constructible<json_value>::value and
1625 std::is_nothrow_move_assignable<json_value>::value
1636 if (m_type != value_t::array)
1638 throw std::runtime_error(
"cannot use swap with " + type_name());
1649 if (m_type != value_t::object)
1651 throw std::runtime_error(
"cannot use swap with " + type_name());
1662 if (m_type != value_t::string)
1664 throw std::runtime_error(
"cannot use swap with " + type_name());
1684 case (value_t::array):
1686 if (rhs.type() == value_t::array)
1688 return *lhs.m_value.array == *rhs.m_value.array;
1692 case (value_t::object):
1694 if (rhs.type() == value_t::object)
1696 return *lhs.m_value.object == *rhs.m_value.object;
1700 case (value_t::null):
1702 if (rhs.type() == value_t::null)
1708 case (value_t::string):
1710 if (rhs.type() == value_t::string)
1712 return *lhs.m_value.string == *rhs.m_value.string;
1716 case (value_t::boolean):
1718 if (rhs.type() == value_t::boolean)
1720 return lhs.m_value.boolean == rhs.m_value.boolean;
1724 case (value_t::number_integer):
1726 if (rhs.type() == value_t::number_integer)
1728 return lhs.m_value.number_integer == rhs.m_value.number_integer;
1730 if (rhs.type() == value_t::number_float)
1732 return lhs.m_value.number_integer ==
static_cast<number_integer_t>(rhs.m_value.number_float);
1736 case (value_t::number_float):
1738 if (rhs.type() == value_t::number_integer)
1740 return approx(lhs.m_value.number_float, static_cast<number_float_t>(rhs.m_value.number_integer));
1742 if (rhs.type() == value_t::number_float)
1744 return approx(lhs.m_value.number_float, rhs.m_value.number_float);
1759 return not (lhs == rhs);
1767 case (value_t::array):
1769 if (rhs.type() == value_t::array)
1771 return *lhs.m_value.array < *rhs.m_value.array;
1775 case (value_t::object):
1777 if (rhs.type() == value_t::object)
1779 return *lhs.m_value.object < *rhs.m_value.object;
1783 case (value_t::null):
1785 if (rhs.type() == value_t::null)
1791 case (value_t::string):
1793 if (rhs.type() == value_t::string)
1795 return *lhs.m_value.string < *rhs.m_value.string;
1799 case (value_t::boolean):
1801 if (rhs.type() == value_t::boolean)
1803 return lhs.m_value.boolean < rhs.m_value.boolean;
1807 case (value_t::number_integer):
1809 if (rhs.type() == value_t::number_integer)
1811 return lhs.m_value.number_integer < rhs.m_value.number_integer;
1813 if (rhs.type() == value_t::number_float)
1815 return lhs.m_value.number_integer <
static_cast<number_integer_t>(rhs.m_value.number_float);
1819 case (value_t::number_float):
1821 if (rhs.type() == value_t::number_integer)
1823 return lhs.m_value.number_float <
static_cast<number_float_t>(rhs.m_value.number_integer);
1825 if (rhs.type() == value_t::number_float)
1827 return lhs.m_value.number_float < rhs.m_value.number_float;
1835 return lhs.type() < rhs.type();
1841 return not (rhs < lhs);
1847 return not (lhs <= rhs);
1853 return not (lhs < rhs);
1865 const int indentation = (o.width() == 0) ? -1 : o.width();
1867 o << j.
dump(indentation);
1875 const int indentation = (o.width() == 0) ? -1 : o.width();
1877 o << j.
dump(indentation);
1923 case (value_t::null):
1928 case (value_t::object):
1933 case (value_t::array):
1938 case (value_t::string):
1943 case (value_t::boolean):
1970 result.reserve(s.size());
1972 for (
const auto c : s)
2027 if (c >= 0 and c <= 0x1f)
2031 std::stringstream ss;
2032 ss <<
"\\u" << std::hex << std::setw(4) << std::setfill(
'0') << int(c);
2038 result.append(1, c);
2066 inline string_t dump(
const bool prettyPrint,
const unsigned int indentStep,
2067 const unsigned int currentIndent = 0) const noexcept
2070 auto new_indent = currentIndent;
2073 const auto indent = [prettyPrint, &new_indent]()
2075 return prettyPrint ?
string_t(new_indent,
' ') : string_t();
2080 case (value_t::object):
2082 if (m_value.object->empty())
2092 new_indent += indentStep;
2096 for (
auto i = m_value.object->cbegin(); i != m_value.object->cend(); ++i)
2098 if (i != m_value.object->cbegin())
2100 result += prettyPrint ?
",\n" :
",";
2102 result += indent() +
"\"" + escape_string(i->first) +
"\":" + (prettyPrint ?
" " :
"")
2103 + i->second.dump(prettyPrint, indentStep, new_indent);
2109 new_indent -= indentStep;
2113 return result + indent() +
"}";
2116 case (value_t::array):
2118 if (m_value.array->empty())
2128 new_indent += indentStep;
2132 for (
auto i = m_value.array->cbegin(); i != m_value.array->cend(); ++i)
2134 if (i != m_value.array->cbegin())
2136 result += prettyPrint ?
",\n" :
",";
2138 result += indent() + i->dump(prettyPrint, indentStep, new_indent);
2144 new_indent -= indentStep;
2148 return result + indent() +
"]";
2151 case (value_t::string):
2153 return string_t(
"\"") + escape_string(*m_value.string) +
"\"";
2156 case (value_t::boolean):
2158 return m_value.boolean ?
"true" :
"false";
2161 case (value_t::number_integer):
2163 return std::to_string(m_value.number_integer);
2166 case (value_t::number_float):
2170 const auto sz =
static_cast<unsigned int>(std::snprintf(
nullptr, 0,
"%.15g", m_value.number_float));
2171 std::vector<char> buf(sz + 1);
2172 std::snprintf(&buf[0], buf.size(),
"%.15g", m_value.number_float);
2184 template<
typename T>
2185 inline static bool approx(
const T a,
const T b)
2187 return not (a > b or a < b);
2200 bool m_final =
false;
2212 template<
typename array_iterator_t,
typename object_iterator_t>
2228 class iterator :
public std::iterator<std::random_access_iterator_tag, basic_json>
2251 switch (m_object->m_type)
2255 m_it.object_iterator =
typename object_t::iterator();
2260 m_it.array_iterator =
typename array_t::iterator();
2265 m_it.generic_iterator = -1;
2273 : m_object(other.m_object), m_it(other.m_it)
2278 std::is_nothrow_move_constructible<pointer>::value and
2279 std::is_nothrow_move_assignable<pointer>::value and
2294 switch (m_object->m_type)
2298 m_it.object_iterator = m_object->m_value.object->begin();
2304 m_it.array_iterator = m_object->m_value.array->begin();
2311 m_it.generic_iterator = 1;
2317 m_it.generic_iterator = 0;
2326 switch (m_object->m_type)
2330 m_it.object_iterator = m_object->m_value.object->end();
2336 m_it.array_iterator = m_object->m_value.array->end();
2342 m_it.generic_iterator = 1;
2352 switch (m_object->m_type)
2356 return m_it.object_iterator->second;
2361 return *m_it.array_iterator;
2366 throw std::out_of_range(
"cannot get value");
2371 if (m_it.generic_iterator == 0)
2377 throw std::out_of_range(
"cannot get value");
2386 switch (m_object->m_type)
2390 return &(m_it.object_iterator->second);
2395 return &*m_it.array_iterator;
2400 throw std::out_of_range(
"cannot get value");
2405 if (m_it.generic_iterator == 0)
2411 throw std::out_of_range(
"cannot get value");
2420 auto result = *
this;
2422 switch (m_object->m_type)
2426 m_it.object_iterator++;
2432 m_it.array_iterator++;
2438 m_it.generic_iterator++;
2449 switch (m_object->m_type)
2453 ++m_it.object_iterator;
2459 ++m_it.array_iterator;
2465 ++m_it.generic_iterator;
2476 auto result = *
this;
2478 switch (m_object->m_type)
2482 m_it.object_iterator--;
2488 m_it.array_iterator--;
2494 m_it.generic_iterator--;
2505 switch (m_object->m_type)
2509 --m_it.object_iterator;
2515 --m_it.array_iterator;
2521 --m_it.generic_iterator;
2535 throw std::domain_error(
"cannot compare iterators of different containers");
2538 switch (m_object->m_type)
2542 return (m_it.object_iterator == other.
m_it.object_iterator);
2547 return (m_it.array_iterator == other.
m_it.array_iterator);
2552 return (m_it.generic_iterator == other.
m_it.generic_iterator);
2560 return not operator==(other);
2569 throw std::domain_error(
"cannot compare iterators of different containers");
2572 switch (m_object->m_type)
2576 throw std::domain_error(
"cannot use operator< for object iterators");
2581 return (m_it.array_iterator < other.
m_it.array_iterator);
2586 return (m_it.generic_iterator < other.
m_it.generic_iterator);
2594 return not other.operator < (*this);
2600 return not operator<=(other);
2606 return not operator<(other);
2612 switch (m_object->m_type)
2616 throw std::domain_error(
"cannot use operator+= for object iterators");
2621 m_it.array_iterator += i;
2627 m_it.generic_iterator += i;
2638 return operator+=(-i);
2644 auto result = *
this;
2652 auto result = *
this;
2660 switch (m_object->m_type)
2664 throw std::domain_error(
"cannot use operator- for object iterators");
2670 return m_it.array_iterator - other.
m_it.array_iterator;
2675 return m_it.generic_iterator - other.
m_it.generic_iterator;
2683 switch (m_object->m_type)
2687 throw std::domain_error(
"cannot use operator[] for object iterators");
2692 return *(m_it.array_iterator + n);
2697 throw std::out_of_range(
"cannot get value");
2702 if (m_it.generic_iterator == -n)
2708 throw std::out_of_range(
"cannot get value");
2715 inline typename object_t::key_type
key()
const
2717 switch (m_object->m_type)
2721 return m_it.object_iterator->first;
2726 throw std::domain_error(
"cannot use key() for non-object iterators");
2745 class const_iterator :
public std::iterator<std::random_access_iterator_tag, const basic_json>
2768 switch (m_object->m_type)
2772 m_it.object_iterator =
typename object_t::const_iterator();
2777 m_it.array_iterator =
typename array_t::const_iterator();
2782 m_it.generic_iterator = -1;
2791 switch (m_object->m_type)
2795 m_it.object_iterator = other.m_it.object_iterator;
2801 m_it.array_iterator = other.m_it.array_iterator;
2807 m_it.generic_iterator = other.m_it.generic_iterator;
2815 : m_object(other.m_object), m_it(other.m_it)
2820 std::is_nothrow_move_constructible<pointer>::value and
2821 std::is_nothrow_move_assignable<pointer>::value and
2836 switch (m_object->m_type)
2840 m_it.object_iterator = m_object->m_value.object->cbegin();
2846 m_it.array_iterator = m_object->m_value.array->cbegin();
2853 m_it.generic_iterator = 1;
2859 m_it.generic_iterator = 0;
2868 switch (m_object->m_type)
2872 m_it.object_iterator = m_object->m_value.object->cend();
2878 m_it.array_iterator = m_object->m_value.array->cend();
2884 m_it.generic_iterator = 1;
2894 switch (m_object->m_type)
2898 return m_it.object_iterator->second;
2903 return *m_it.array_iterator;
2908 throw std::out_of_range(
"cannot get value");
2913 if (m_it.generic_iterator == 0)
2919 throw std::out_of_range(
"cannot get value");
2928 switch (m_object->m_type)
2932 return &(m_it.object_iterator->second);
2937 return &*m_it.array_iterator;
2942 if (m_it.generic_iterator == 0)
2948 throw std::out_of_range(
"cannot get value");
2957 auto result = *
this;
2959 switch (m_object->m_type)
2963 m_it.object_iterator++;
2969 m_it.array_iterator++;
2975 m_it.generic_iterator++;
2986 switch (m_object->m_type)
2990 ++m_it.object_iterator;
2996 ++m_it.array_iterator;
3002 ++m_it.generic_iterator;
3013 auto result = *
this;
3015 switch (m_object->m_type)
3019 m_it.object_iterator--;
3025 m_it.array_iterator--;
3031 m_it.generic_iterator--;
3042 switch (m_object->m_type)
3046 --m_it.object_iterator;
3052 --m_it.array_iterator;
3058 --m_it.generic_iterator;
3072 throw std::domain_error(
"cannot compare iterators of different containers");
3075 switch (m_object->m_type)
3079 return (m_it.object_iterator == other.
m_it.object_iterator);
3084 return (m_it.array_iterator == other.
m_it.array_iterator);
3089 return (m_it.generic_iterator == other.
m_it.generic_iterator);
3097 return not operator==(other);
3106 throw std::domain_error(
"cannot compare iterators of different containers");
3109 switch (m_object->m_type)
3113 throw std::domain_error(
"cannot use operator< for object iterators");
3118 return (m_it.array_iterator < other.
m_it.array_iterator);
3123 return (m_it.generic_iterator < other.
m_it.generic_iterator);
3131 return not other.operator < (*this);
3137 return not operator<=(other);
3143 return not operator<(other);
3149 switch (m_object->m_type)
3153 throw std::domain_error(
"cannot use operator+= for object iterators");
3159 m_it.array_iterator += i;
3165 m_it.generic_iterator += i;
3176 return operator+=(-i);
3182 auto result = *
this;
3190 auto result = *
this;
3198 switch (m_object->m_type)
3202 throw std::domain_error(
"cannot use operator- for object iterators");
3207 return m_it.array_iterator - other.
m_it.array_iterator;
3212 return m_it.generic_iterator - other.
m_it.generic_iterator;
3220 switch (m_object->m_type)
3224 throw std::domain_error(
"cannot use operator[] for object iterators");
3229 return *(m_it.array_iterator + n);
3234 throw std::out_of_range(
"cannot get value");
3239 if (m_it.generic_iterator == -n)
3245 throw std::out_of_range(
"cannot get value");
3252 inline typename object_t::key_type
key()
const
3254 switch (m_object->m_type)
3258 return m_it.object_iterator->first;
3263 throw std::domain_error(
"cannot use key() for non-object iterators");
3285 inline reverse_iterator(
const typename std::reverse_iterator<basic_json::iterator>::iterator_type&
3290 inline typename object_t::key_type
key()
const
3292 return this->base().key();
3298 return this->base().operator * ();
3307 std::reverse_iterator<basic_json::const_iterator>::iterator_type& it)
3311 inline typename object_t::key_type
key()
const
3313 return this->base().key();
3319 return this->base().operator * ();
3363 : m_stream(
nullptr), m_buffer(s)
3365 m_content =
reinterpret_cast<const lexer_char_t*
>(s.c_str());
3366 m_start = m_cursor = m_content;
3367 m_limit = m_content + s.size();
3372 getline(*m_stream, m_buffer);
3373 m_content =
reinterpret_cast<const lexer_char_t*
>(m_buffer.c_str());
3374 m_start = m_cursor = m_content;
3375 m_limit = m_content + m_buffer.size();
3379 inline lexer() =
default;
3393 const size_t codepoint2 = 0)
3398 size_t codepoint = codepoint1;
3399 if (codepoint1 >= 0xD800 and codepoint1 <= 0xDBFF)
3401 if (codepoint2 >= 0xDC00 and codepoint2 <= 0xDFFF)
3415 throw std::invalid_argument(
"missing or wrong low surrogate");
3419 if (codepoint <= 0x7f)
3422 result.append(1, static_cast<typename string_t::value_type>(codepoint));
3424 else if (codepoint <= 0x7ff)
3427 result.append(1, static_cast<typename string_t::value_type>(0xC0 | ((codepoint >> 6) & 0x1F)));
3428 result.append(1, static_cast<typename string_t::value_type>(0x80 | (codepoint & 0x3F)));
3430 else if (codepoint <= 0xffff)
3433 result.append(1, static_cast<typename string_t::value_type>(0xE0 | ((codepoint >> 12) & 0x0F)));
3434 result.append(1, static_cast<typename string_t::value_type>(0x80 | ((codepoint >> 6) & 0x3F)));
3435 result.append(1, static_cast<typename string_t::value_type>(0x80 | (codepoint & 0x3F)));
3437 else if (codepoint <= 0x10ffff)
3440 result.append(1, static_cast<typename string_t::value_type>(0xF0 | ((codepoint >> 18) & 0x07)));
3441 result.append(1, static_cast<typename string_t::value_type>(0x80 | ((codepoint >> 12) & 0x3F)));
3442 result.append(1, static_cast<typename string_t::value_type>(0x80 | ((codepoint >> 6) & 0x3F)));
3443 result.append(1, static_cast<typename string_t::value_type>(0x80 | (codepoint & 0x3F)));
3447 throw std::out_of_range(
"code points above 0x10FFFF are invalid");
3458 case (token_type::uninitialized):
3459 return "<uninitialized>";
3460 case (token_type::literal_true):
3461 return "true literal";
3462 case (token_type::literal_false):
3463 return "false literal";
3464 case (token_type::literal_null):
3465 return "null literal";
3466 case (token_type::value_string):
3467 return "string literal";
3468 case (token_type::value_number):
3469 return "number literal";
3470 case (token_type::begin_array):
3472 case (token_type::begin_object):
3474 case (token_type::end_array):
3476 case (token_type::end_object):
3478 case (token_type::name_separator):
3480 case (token_type::value_separator):
3482 case (token_type::end_of_input):
3483 return "<end of input>";
3485 return "<parse error>";
3510 unsigned int yyaccept = 0;
3511 static const unsigned char yybm[] =
3513 0, 64, 64, 64, 64, 64, 64, 64,
3514 64, 96, 96, 64, 64, 96, 64, 64,
3515 64, 64, 64, 64, 64, 64, 64, 64,
3516 64, 64, 64, 64, 64, 64, 64, 64,
3517 96, 64, 0, 64, 64, 64, 64, 64,
3518 64, 64, 64, 64, 64, 64, 64, 64,
3519 192, 192, 192, 192, 192, 192, 192, 192,
3520 192, 192, 64, 64, 64, 64, 64, 64,
3521 64, 64, 64, 64, 64, 64, 64, 64,
3522 64, 64, 64, 64, 64, 64, 64, 64,
3523 64, 64, 64, 64, 64, 64, 64, 64,
3524 64, 64, 64, 64, 0, 64, 64, 64,
3525 64, 64, 64, 64, 64, 64, 64, 64,
3526 64, 64, 64, 64, 64, 64, 64, 64,
3527 64, 64, 64, 64, 64, 64, 64, 64,
3528 64, 64, 64, 64, 64, 64, 64, 64,
3529 64, 64, 64, 64, 64, 64, 64, 64,
3530 64, 64, 64, 64, 64, 64, 64, 64,
3531 64, 64, 64, 64, 64, 64, 64, 64,
3532 64, 64, 64, 64, 64, 64, 64, 64,
3533 64, 64, 64, 64, 64, 64, 64, 64,
3534 64, 64, 64, 64, 64, 64, 64, 64,
3535 64, 64, 64, 64, 64, 64, 64, 64,
3536 64, 64, 64, 64, 64, 64, 64, 64,
3537 64, 64, 64, 64, 64, 64, 64, 64,
3538 64, 64, 64, 64, 64, 64, 64, 64,
3539 64, 64, 64, 64, 64, 64, 64, 64,
3540 64, 64, 64, 64, 64, 64, 64, 64,
3541 64, 64, 64, 64, 64, 64, 64, 64,
3542 64, 64, 64, 64, 64, 64, 64, 64,
3543 64, 64, 64, 64, 64, 64, 64, 64,
3544 64, 64, 64, 64, 64, 64, 64, 64,
3547 if ((m_limit - m_cursor) < 5)
3560 goto basic_json_parser_27;
3564 goto basic_json_parser_29;
3568 goto basic_json_parser_4;
3575 goto basic_json_parser_2;
3579 goto basic_json_parser_29;
3589 goto basic_json_parser_26;
3593 goto basic_json_parser_29;
3595 goto basic_json_parser_14;
3601 goto basic_json_parser_22;
3605 goto basic_json_parser_29;
3609 goto basic_json_parser_23;
3611 goto basic_json_parser_25;
3623 goto basic_json_parser_16;
3627 goto basic_json_parser_6;
3629 goto basic_json_parser_29;
3635 goto basic_json_parser_8;
3639 goto basic_json_parser_21;
3641 goto basic_json_parser_29;
3650 goto basic_json_parser_18;
3654 goto basic_json_parser_20;
3656 goto basic_json_parser_29;
3662 goto basic_json_parser_10;
3666 goto basic_json_parser_12;
3668 goto basic_json_parser_29;
3672 basic_json_parser_2:
3675 goto basic_json_parser_5;
3676 basic_json_parser_3:
3680 basic_json_parser_4:
3682 if (m_limit <= m_cursor)
3687 basic_json_parser_5:
3688 if (yybm[0 + yych] & 32)
3690 goto basic_json_parser_4;
3692 goto basic_json_parser_3;
3693 basic_json_parser_6:
3696 return token_type::begin_array;
3698 basic_json_parser_8:
3701 return token_type::end_array;
3703 basic_json_parser_10:
3706 return token_type::begin_object;
3708 basic_json_parser_12:
3711 return token_type::end_object;
3713 basic_json_parser_14:
3716 return token_type::value_separator;
3718 basic_json_parser_16:
3721 return token_type::name_separator;
3723 basic_json_parser_18:
3725 yych = *(m_marker = ++m_cursor);
3728 goto basic_json_parser_59;
3730 basic_json_parser_19:
3732 return token_type::parse_error;
3734 basic_json_parser_20:
3736 yych = *(m_marker = ++m_cursor);
3739 goto basic_json_parser_55;
3741 goto basic_json_parser_19;
3742 basic_json_parser_21:
3744 yych = *(m_marker = ++m_cursor);
3747 goto basic_json_parser_50;
3749 goto basic_json_parser_19;
3750 basic_json_parser_22:
3754 goto basic_json_parser_19;
3758 goto basic_json_parser_49;
3762 goto basic_json_parser_40;
3764 goto basic_json_parser_19;
3765 basic_json_parser_23:
3767 yych = *(m_marker = ++m_cursor);
3772 goto basic_json_parser_42;
3779 goto basic_json_parser_43;
3783 goto basic_json_parser_43;
3786 basic_json_parser_24:
3788 return token_type::value_number;
3790 basic_json_parser_25:
3792 yych = *(m_marker = ++m_cursor);
3793 goto basic_json_parser_41;
3794 basic_json_parser_26:
3796 yych = *(m_marker = ++m_cursor);
3799 goto basic_json_parser_19;
3801 goto basic_json_parser_31;
3802 basic_json_parser_27:
3805 return token_type::end_of_input;
3807 basic_json_parser_29:
3809 goto basic_json_parser_19;
3810 basic_json_parser_30:
3812 if (m_limit <= m_cursor)
3817 basic_json_parser_31:
3818 if (yybm[0 + yych] & 64)
3820 goto basic_json_parser_30;
3824 goto basic_json_parser_32;
3828 goto basic_json_parser_34;
3830 goto basic_json_parser_33;
3831 basic_json_parser_32:
3832 m_cursor = m_marker;
3835 goto basic_json_parser_19;
3839 goto basic_json_parser_24;
3841 basic_json_parser_33:
3843 if (m_limit <= m_cursor)
3854 goto basic_json_parser_30;
3858 goto basic_json_parser_32;
3860 goto basic_json_parser_30;
3868 goto basic_json_parser_32;
3870 goto basic_json_parser_30;
3876 goto basic_json_parser_30;
3878 goto basic_json_parser_32;
3888 goto basic_json_parser_30;
3892 goto basic_json_parser_30;
3894 goto basic_json_parser_32;
3902 goto basic_json_parser_30;
3904 goto basic_json_parser_32;
3910 goto basic_json_parser_30;
3914 goto basic_json_parser_36;
3916 goto basic_json_parser_32;
3920 basic_json_parser_34:
3923 return token_type::value_string;
3925 basic_json_parser_36:
3927 if (m_limit <= m_cursor)
3936 goto basic_json_parser_32;
3940 goto basic_json_parser_32;
3947 goto basic_json_parser_37;
3951 goto basic_json_parser_32;
3955 goto basic_json_parser_32;
3958 basic_json_parser_37:
3960 if (m_limit <= m_cursor)
3969 goto basic_json_parser_32;
3973 goto basic_json_parser_32;
3980 goto basic_json_parser_38;
3984 goto basic_json_parser_32;
3988 goto basic_json_parser_32;
3991 basic_json_parser_38:
3993 if (m_limit <= m_cursor)
4002 goto basic_json_parser_32;
4006 goto basic_json_parser_32;
4013 goto basic_json_parser_39;
4017 goto basic_json_parser_32;
4021 goto basic_json_parser_32;
4024 basic_json_parser_39:
4026 if (m_limit <= m_cursor)
4035 goto basic_json_parser_32;
4039 goto basic_json_parser_30;
4041 goto basic_json_parser_32;
4047 goto basic_json_parser_30;
4051 goto basic_json_parser_32;
4055 goto basic_json_parser_30;
4057 goto basic_json_parser_32;
4059 basic_json_parser_40:
4061 m_marker = ++m_cursor;
4062 if ((m_limit - m_cursor) < 3)
4067 basic_json_parser_41:
4068 if (yybm[0 + yych] & 128)
4070 goto basic_json_parser_40;
4076 goto basic_json_parser_24;
4083 goto basic_json_parser_43;
4087 goto basic_json_parser_43;
4089 goto basic_json_parser_24;
4091 basic_json_parser_42:
4095 goto basic_json_parser_32;
4099 goto basic_json_parser_47;
4101 goto basic_json_parser_32;
4102 basic_json_parser_43:
4108 goto basic_json_parser_32;
4115 goto basic_json_parser_44;
4119 goto basic_json_parser_32;
4123 goto basic_json_parser_45;
4125 goto basic_json_parser_32;
4127 basic_json_parser_44:
4131 goto basic_json_parser_32;
4135 goto basic_json_parser_32;
4137 basic_json_parser_45:
4139 if (m_limit <= m_cursor)
4146 goto basic_json_parser_24;
4150 goto basic_json_parser_45;
4152 goto basic_json_parser_24;
4153 basic_json_parser_47:
4155 m_marker = ++m_cursor;
4156 if ((m_limit - m_cursor) < 3)
4165 goto basic_json_parser_24;
4169 goto basic_json_parser_47;
4171 goto basic_json_parser_24;
4177 goto basic_json_parser_43;
4181 goto basic_json_parser_43;
4183 goto basic_json_parser_24;
4185 basic_json_parser_49:
4187 yych = *(m_marker = ++m_cursor);
4192 goto basic_json_parser_42;
4194 goto basic_json_parser_24;
4200 goto basic_json_parser_43;
4204 goto basic_json_parser_43;
4206 goto basic_json_parser_24;
4208 basic_json_parser_50:
4212 goto basic_json_parser_32;
4217 goto basic_json_parser_32;
4222 goto basic_json_parser_32;
4226 return token_type::literal_false;
4228 basic_json_parser_55:
4232 goto basic_json_parser_32;
4237 goto basic_json_parser_32;
4241 return token_type::literal_true;
4243 basic_json_parser_59:
4247 goto basic_json_parser_32;
4252 goto basic_json_parser_32;
4256 return token_type::literal_null;
4266 if (not m_stream or not * m_stream)
4271 const ssize_t offset_start = m_start - m_content;
4272 const ssize_t offset_marker = m_marker - m_start;
4273 const ssize_t offset_cursor = m_cursor - m_start;
4275 m_buffer.erase(0, static_cast<size_t>(offset_start));
4277 std::getline(*m_stream, line);
4280 m_content =
reinterpret_cast<const lexer_char_t*
>(m_buffer.c_str());
4281 m_start = m_content;
4282 m_marker = m_start + offset_marker;
4283 m_cursor = m_start + offset_cursor;
4284 m_limit = m_start + m_buffer.size() - 1;
4290 return string_t(reinterpret_cast<typename string_t::const_pointer>(m_start),
4291 static_cast<size_t>(m_cursor - m_start));
4318 result.reserve(static_cast<size_t>(m_cursor - m_start - 2));
4321 for (
const lexer_char_t* i = m_start + 1; i < m_cursor - 1; ++i)
4379 auto codepoint = std::strtoul(std::string(reinterpret_cast<typename string_t::const_pointer>(i + 1),
4380 4).c_str(),
nullptr, 16);
4382 if (codepoint >= 0xD800 and codepoint <= 0xDBFF)
4385 if ((i + 6 >= m_limit) or * (i + 5) !=
'\\' or * (i + 6) !=
'u')
4387 throw std::invalid_argument(
"missing low surrogate");
4391 auto codepoint2 = std::strtoul(std::string(reinterpret_cast<typename string_t::const_pointer>
4392 (i + 7), 4).c_str(),
nullptr, 16);
4393 result += to_unicode(codepoint, codepoint2);
4400 result += to_unicode(codepoint);
4412 result.append(1, static_cast<typename string_t::value_type>(*i));
4439 typename string_t::value_type* endptr;
4440 const auto float_val = std::strtod(reinterpret_cast<typename string_t::const_pointer>(m_start),
4445 return (reinterpret_cast<lexer_char_t*>(endptr) == m_cursor) ? float_val : NAN;
4479 inline parser(std::istream& _is) : m_lexer(&_is)
4490 expect(lexer::token_type::end_of_input);
4501 case (lexer::token_type::begin_object):
4510 if (last_token == lexer::token_type::end_object)
4520 if (last_token == lexer::token_type::value_separator)
4526 expect(lexer::token_type::value_string);
4527 const auto key = m_lexer.get_string();
4531 expect(lexer::token_type::name_separator);
4535 result[key] = parse_internal();
4537 while (last_token == lexer::token_type::value_separator);
4540 expect(lexer::token_type::end_object);
4546 case (lexer::token_type::begin_array):
4555 if (last_token == lexer::token_type::end_array)
4565 if (last_token == lexer::token_type::value_separator)
4573 while (last_token == lexer::token_type::value_separator);
4576 expect(lexer::token_type::end_array);
4582 case (lexer::token_type::literal_null):
4588 case (lexer::token_type::value_string):
4590 const auto s = m_lexer.get_string();
4595 case (lexer::token_type::literal_true):
4601 case (lexer::token_type::literal_false):
4607 case (lexer::token_type::value_number):
4609 auto float_val = m_lexer.get_number();
4613 if (std::isnan(float_val))
4615 throw std::invalid_argument(std::string(
"parse error - ") +
4616 m_lexer.get_token() +
" is not a number");
4623 if (approx(float_val, static_cast<number_float_t>(int_val)))
4637 std::string error_msg =
"parse error - unexpected \'";
4638 error_msg += m_lexer.get_token();
4639 error_msg +=
"\' (";
4640 error_msg += lexer::token_type_name(last_token) +
")";
4641 throw std::invalid_argument(error_msg);
4649 last_token = m_lexer.scan();
4655 if (t != last_token)
4657 std::string error_msg =
"parse error - unexpected \'";
4658 error_msg += m_lexer.get_token();
4659 error_msg +=
"\' (" + lexer::token_type_name(last_token);
4660 error_msg +=
"); expected " + lexer::token_type_name(t);
4661 throw std::invalid_argument(error_msg);
4697 is_nothrow_move_constructible<nlohmann::json>::value and
4698 is_nothrow_move_assignable<nlohmann::json>::value
4712 const auto& h = hash<nlohmann::json::string_t>();
4729 (const_cast<char*>(s)));
json_value(boolean_t v)
constructor for booleans
T get() const
get a value (explicit)
reference operator*()
return a reference to the value pointed to by the iterator
const_iterator & operator-=(difference_type i)
subtract from iterator
reference value()
return the key of an iterator
std::vector< T > get_impl(std::vector< T > *) const
get an array (explicit)
const_iterator cbegin() const noexcept
returns a const iterator to the first element
const_reverse_iterator crend() const noexcept
returns a const reverse iterator to one past the last element
basic_json::iterator iterator
an iterator for a basic_json container
friend bool operator<(const_reference lhs, const_reference rhs) noexcept
comparison: less than
void swap(array_t &other)
swaps the contents
iterator operator-(difference_type i)
subtract from iterator
const_reference operator[](size_type pos) const
access specified element
friend bool operator<(const value_t lhs, const value_t rhs)
comparison operator for JSON value types
basic_json value_type
the type of elements in a basic_json container
basic_json(const number_float_t &value)
create a floating-point number (explicit)
static string_t escape_string(const string_t &s) noexcept
escape a string
const_iterator & operator--()
pre-decrement (–it)
const_iterator cend() const noexcept
returns a const iterator to one past the last element
T get_impl(T *) const
get an object (explicit)
size_type count(typename object_t::key_type key) const
returns the number of occurrences of a key in an object
number_float_t get_number() const
return number value for number tokens
iterator begin() noexcept
returns an iterator to the first element
reference value() const
return the value of an iterator
void expect(typename lexer::token_type t) const
static bool approx(const T a, const T b)
"equality" comparison for floating point numbers
allocator_type get_allocator() const
returns the allocator associated with the container
reverse_iterator rbegin() noexcept
returns a reverse iterator to the first element
const_iterator & operator=(const_iterator other) noexcept(std::is_nothrow_move_constructible< pointer >::value andstd::is_nothrow_move_assignable< pointer >::value andstd::is_nothrow_move_constructible< internal_iterator< typename array_t::const_iterator, typename object_t::const_iterator >>::valueandstd::is_nothrow_move_assignable< internal_iterator< typename array_t::const_iterator, typename object_t::const_iterator >>::value)
copy assignment
basic_json::const_reverse_iterator const_reverse_iterator
a const reverse iterator for a basic_json container
bool is_boolean() const noexcept
const_iterator & operator+=(difference_type i)
add to iterator
string_t dump(const bool prettyPrint, const unsigned int indentStep, const unsigned int currentIndent=0) const noexcept
internal implementation of the serialization function
iterator & operator+=(difference_type i)
add to iterator
void set_begin() noexcept
set the iterator to the first value
basic_json(boolean_t value)
create a boolean (explicit)
lexer::token_type get_token()
get next token from lexer
friend std::ostream & operator<<(std::ostream &o, const basic_json &j)
serialize to stream
object_t * object
object (stored with pointer to save storage)
const_iterator operator-(difference_type i)
subtract from iterator
const_iterator(const iterator &other) noexcept
copy constructor given a nonconst iterator
internal_iterator()
default constructor
string_t dump(const int indent=-1) const noexcept
serialization
a random access iterator for the basic_json class
bool operator<(const iterator &other) const
comparison: smaller
pointer m_object
associated JSON instance
basic_json parse_internal()
the actual parser
const_reverse_iterator crbegin() const noexcept
returns a const reverse iterator to the first element
a reverse random access iterator for the basic_json class
BooleanType boolean_t
a type for a boolean
const_iterator operator--(int)
post-decrement (it–)
const_reverse_iterator(const typename std::reverse_iterator< basic_json::const_iterator >::iterator_type &it)
const_reference operator[](const T(&key)[n]) const
access specified element (needed for clang)
size_type size() const noexcept
returns the number of elements
string_t * string
string (stored with pointer to save storage)
const_reverse_iterator rbegin() const noexcept
returns a const reverse iterator to the first element
const_iterator(pointer object) noexcept
constructor for a given JSON instance
std::istream * m_stream
optional input stream
reference operator+=(basic_json &&value)
add an object to an array
bool operator<=(const const_iterator &other) const
comparison: less than or equal
object_t::key_type key() const
return the key of an object iterator
lexer(std::istream *s) noexcept
iterator end() noexcept
returns an iterator to one past the last element
~basic_json() noexcept
destructor
json_value m_value
the value of the current element
a const reverse random access iterator for the basic_json class
difference_type operator-(const iterator &other) const
return difference
void clear() noexcept
clears the contents
std::ptrdiff_t difference_type
a type to represent differences between iterators
object_t get_impl(object_t *) const
get an object (explicit)
const_reference at(const typename object_t::key_type &key) const
access specified element with bounds checking
basic_json(const object_t &value)
create an object (explicit)
string_t get_token() const noexcept
return string representation of last read token
basic_json::const_iterator const_iterator
a const iterator for a basic_json container
reference operator[](size_type pos)
access specified element
size_t operator()(const nlohmann::json &j) const
return a hash value for a JSON object
value_t type() const noexcept
return the type of the object (explicit)
difference_type generic_iterator
generic iteraotr for all other value types
iterator operator++(int)
post-increment (it++)
reference operator[](difference_type n) const
access to successor
void erase(const size_type pos)
remove element from an array given an index
iterator operator+(difference_type i)
add to iterator
object_t::key_type key() const
return the key of an object iterator
string_t get_string() const
return string value for string tokens
StringType string_t
a type for a string
void push_back(const basic_json &value)
add an object to an array
static basic_json object(list_init_t l=list_init_t())
explicitly create an object from an initializer list
bool operator>(const iterator &other) const
comparison: greater than
const_iterator end() const noexcept
returns a const iterator to one past the last element
array_iterator_t array_iterator
iterator for JSON arrays
reference at(size_type pos)
access specified element with bounds checking
void push_back(basic_json &&value)
add an object to an array
static basic_json array(list_init_t l=list_init_t())
explicitly create an array from an initializer list
parser(const string_t &s)
constructor for strings
NumberIntegerType number_integer_t
a type for a number (integer)
pointer m_object
associated JSON instance
reference value() const
return the value of an iterator
void swap(reference other) noexcept(std::is_nothrow_move_constructible< value_t >::value andstd::is_nothrow_move_assignable< value_t >::value andstd::is_nothrow_move_constructible< json_value >::value andstd::is_nothrow_move_assignable< json_value >::value)
exchanges the values
internal_iterator< typename array_t::iterator, typename object_t::iterator > m_it
the actual iterator of the associated instance
basic_json::difference_type difference_type
a type to represent differences between iterators
basic_json(const string_t &value)
create a string (explicit)
const_reverse_iterator rend() const noexcept
returns a const reverse iterator to one past the last element
reference operator+=(const basic_json &value)
add an object to an array
void swap(nlohmann::json &j1, nlohmann::json &j2) noexcept(is_nothrow_move_constructible< nlohmann::json >::value andis_nothrow_move_assignable< nlohmann::json >::value)
exchanges the values of two JSON objects
basic_json * pointer
the type of an element pointer
void swap(string_t &other)
swaps the contents
const basic_json & const_reference
the type of an element const reference
bool operator==(const iterator &other) const
comparison: equal
iterator operator--(int)
post-decrement (it–)
bool is_object() const noexcept
const basic_json * const_pointer
the type of an element const pointer
reference operator*() const
return a reference to the value pointed to by the iterator
const_reference at(size_type pos) const
access specified element with bounds checking
void set_begin() noexcept
set the iterator to the first value
bool empty() const noexcept
checks whether the container is empty
array_t get_impl(array_t *) const
std::bidirectional_iterator_tag iterator_category
the category of the iterator
size_type max_size() const noexcept
returns the maximum possible number of elements
friend std::istream & operator>>(std::istream &i, basic_json &j)
deserialize from stream
basic_json(const V &value)
create an object (implicit)
static basic_json parse(const string_t &s)
deserialize from string
friend std::ostream & operator>>(const basic_json &j, std::ostream &o)
serialize to stream
friend std::istream & operator<<(basic_json &j, std::istream &i)
deserialize from stream
static basic_json parse(std::istream &i)
deserialize from stream
lexer(const string_t &s) noexcept
constructor with a given buffer
Allocator< basic_json > allocator_type
the allocator type
reference operator[](const typename object_t::key_type &key)
access specified element
json_value(number_float_t v)
constructor for numbers (floating-point)
basic_json(basic_json &&other) noexcept
move constructor
pointer operator->()
dereference the iterator
NumberFloatType number_float_t
a type for a number (floating-point)
basic_json::difference_type difference_type
a type to represent differences between iterators
iterator & operator--()
pre-decrement (–it)
token_type
token types for the parser
array (ordered collection of values)
static std::string token_type_name(token_type t) noexcept
return name of values of type token_type
reference value() const
return the value of an iterator
basic_json(const array_t &value)
create an array (explicit)
void yyfill() noexcept
append data from the stream to the internal buffer
object_iterator_t object_iterator
iterator for JSON objects
bool is_number() const noexcept
friend bool operator>(const_reference lhs, const_reference rhs) noexcept
comparison: greater than
friend bool operator==(const_reference lhs, const_reference rhs) noexcept
comparison: equal
pointer operator->() const
dereference the iterator
basic_json(const T value) noexcept
create an integer number (implicit)
std::size_t size_type
a type to represent container sizes
bool operator>=(const const_iterator &other) const
comparison: greater than or equal
string_t m_buffer
the buffer
basic_json & reference
the type of an element reference
const_iterator & operator++()
pre-increment (++it)
unsigned char lexer_char_t
the char type to use in the lexer
void push_back(const typename object_t::value_type &value)
add an object to an object
reference & operator=(basic_json other) noexcept(std::is_nothrow_move_constructible< value_t >::value andstd::is_nothrow_move_assignable< value_t >::value andstd::is_nothrow_move_constructible< json_value >::value andstd::is_nothrow_move_assignable< json_value >::value)
copy assignment
const_iterator operator+(difference_type i)
add to iterator
number_integer_t number_integer
number (integer)
basic_json(const basic_json &other)
copy constructor
iterator(pointer object) noexcept
constructor for a given JSON instance
size_type erase(const typename object_t::key_type &key)
remove element from an object given a key
number_float_t number_float
number (floating-point)
basic_json(const value_t value)
create an empty value with a given type
token_type scan() noexcept
object_t::key_type key() const
return the key of an object iterator
basic_json(list_init_t l, bool type_deduction=true, value_t manual_type=value_t::array)
create a container (array or object) from an initializer list
boolean_t get_impl(boolean_t *) const
get a boolean (explicit)
value_t
JSON value type enumeration.
const_iterator find(typename object_t::key_type key) const
find an element in an object
basic_json(const typename string_t::value_type *value)
create a string (explicit)
const_iterator begin() const noexcept
returns a const iterator to the first element
bool operator<=(const iterator &other) const
comparison: less than or equal
static string_t to_unicode(const size_t codepoint1, const size_t codepoint2=0)
create a string from a Unicode code point
const_iterator(const const_iterator &other) noexcept
copy constructor
object (unordered set of name/value pairs)
reverse_iterator rend() noexcept
returns a reverse iterator to one past the last element
void set_end() noexcept
set the iterator past the last value
bool is_null() const noexcept
bool operator!=(const iterator &other) const
comparison: not equal
basic_json(const number_integer_t &value)
create an integer number (explicit)
std::initializer_list< basic_json > list_init_t
a type for list initialization
json_value(number_integer_t v)
constructor for numbers (integer)
bool is_array() const noexcept
basic_json parse()
public parser interface
bool operator<(const const_iterator &other) const
comparison: smaller
reference at(const typename object_t::key_type &key)
access specified element with bounds checking
std::bidirectional_iterator_tag iterator_category
the category of the iterator
const_iterator operator++(int)
post-increment (it++)
reference operator[](difference_type n)
access to successor
friend bool operator!=(const_reference lhs, const_reference rhs) noexcept
comparison: not equal
void set_end() noexcept
set the iterator past the last value
iterator & operator++()
pre-increment (++it)
basic_json<> json
default JSON class
bool is_string() const noexcept
a const random access iterator for the basic_json class
reverse_iterator(const typename std::reverse_iterator< basic_json::iterator >::iterator_type &it)
ObjectType< StringType, basic_json > object_t
a type for an object
bool operator!=(const const_iterator &other) const
comparison: not equal
bool operator>(const const_iterator &other) const
comparison: greater than
reference operator[](const T(&key)[n])
access specified element (needed for clang)
friend bool operator<=(const_reference lhs, const_reference rhs) noexcept
comparison: less than or equal
reference operator+=(const typename object_t::value_type &value)
add an object to an object
void swap(object_t &other)
swaps the contents
friend bool operator>=(const_reference lhs, const_reference rhs) noexcept
comparison: greater than or equal
iterator find(typename object_t::key_type key)
find an element in an object
parser(std::istream &_is)
a parser reading from an input stream
iterator(const iterator &other) noexcept
copy constructor
internal_iterator< typename array_t::const_iterator, typename object_t::const_iterator > m_it
the actual iterator of the associated instance
static char test(typename C::mapped_type *)
array_t * array
array (stored with pointer to save storage)
const_reference operator[](const typename object_t::key_type &key) const
access specified element
string_t type_name() const noexcept
return the type as string
difference_type operator-(const const_iterator &other) const
return difference
ArrayType< basic_json > array_t
a type for an array
iterator & operator-=(difference_type i)
subtract from iterator
iterator & operator=(iterator other) noexcept(std::is_nothrow_move_constructible< pointer >::value andstd::is_nothrow_move_assignable< pointer >::value andstd::is_nothrow_move_constructible< internal_iterator< typename array_t::iterator, typename object_t::iterator >>::valueandstd::is_nothrow_move_assignable< internal_iterator< typename array_t::iterator, typename object_t::iterator >>::value)
copy assignment
basic_json::reverse_iterator reverse_iterator
a reverse iterator for a basic_json container
object_t::key_type key() const
return the key of an object iterator
bool operator>=(const iterator &other) const
comparison: greater than or equal
bool operator==(const const_iterator &other) const
comparison: equal