29 #ifndef NLOHMANN_JSON_HPP 30 #define NLOHMANN_JSON_HPP 41 #include <initializer_list> 51 #include <type_traits> 56 #if defined(__clang__) || defined(__GNUC__) || defined(__GNUG__) 57 #pragma GCC diagnostic push 58 #pragma GCC diagnostic ignored "-Wfloat-equal" 81 struct has_mapped_type
84 template<
typename C>
static char test(
typename C::mapped_type*);
85 template<
typename C>
static char (&test(...))[2];
87 static constexpr
bool value =
sizeof(test<T>(0)) == 1;
164 template<
typename U,
typename V,
typename... Args>
class ObjectType =
std::map,
165 template<
typename U,
typename... Args>
class ArrayType =
std::vector,
166 class StringType = std::string,
167 class BooleanType = bool,
168 class NumberIntegerType = std::int64_t,
169 class NumberUnsignedType = std::uint64_t,
170 class NumberFloatType = double,
171 template<
typename U>
class AllocatorType = std::allocator
212 using pointer =
typename std::allocator_traits<allocator_type>::pointer;
214 using const_pointer =
typename std::allocator_traits<allocator_type>::const_pointer;
329 using object_t = ObjectType<StringType,
331 std::less<StringType>,
332 AllocatorType<std::pair<
const StringType,
379 using array_t = ArrayType<basic_json, AllocatorType<basic_json>>;
698 template<
typename T,
typename... Args>
701 AllocatorType<T> alloc;
702 auto deleter = [&](T * object)
704 alloc.deallocate(
object, 1);
706 std::unique_ptr<T, decltype(deleter)> object(alloc.allocate(1), deleter);
707 alloc.construct(
object.
get(), std::forward<Args>(args)...);
708 return object.release();
754 case value_t::object:
756 object = create<object_t>();
762 array = create<array_t>();
766 case value_t::string:
768 string = create<string_t>(
"");
772 case value_t::boolean:
778 case value_t::number_integer:
784 case value_t::number_unsigned:
790 case value_t::number_float:
806 string = create<string_t>(
value);
812 object = create<object_t>(
value);
818 array = create<array_t>(
value);
901 using parser_callback_t = std::function<bool(int depth, parse_event_t event, basic_json& parsed)>;
951 : m_type(value_type), m_value(value_type)
978 basic_json() =
default;
1026 : m_type(
value_t::object), m_value(val)
1055 template <
class CompatibleObjectType,
typename 1065 m_value.object = create<object_t>(begin(val), end(val));
1088 : m_type(
value_t::array), m_value(val)
1117 template <
class CompatibleArrayType,
typename 1132 m_value.array = create<array_t>(begin(val), end(val));
1157 : m_type(
value_t::string), m_value(val)
1207 template <
class CompatibleStringType,
typename 1230 : m_type(value_t::boolean), m_value(val)
1256 template<
typename T,
1257 typename std::enable_if<
1263 : m_type(value_t::number_integer), m_value(val)
1292 : m_type(value_t::number_integer),
1293 m_value(static_cast<number_integer_t>(val))
1321 template<
typename CompatibleNumberIntegerType,
typename 1324 std::numeric_limits<CompatibleNumberIntegerType>::is_integer and
1325 std::numeric_limits<CompatibleNumberIntegerType>::is_signed,
1326 CompatibleNumberIntegerType>::type
1329 : m_type(value_t::number_integer),
1330 m_value(static_cast<number_integer_t>(val))
1350 template<
typename T,
1351 typename std::enable_if<
1357 : m_type(value_t::number_unsigned), m_value(val)
1380 template <
typename CompatibleNumberUnsignedType,
typename 1383 std::numeric_limits<CompatibleNumberUnsignedType>::is_integer and
1384 !std::numeric_limits<CompatibleNumberUnsignedType>::is_signed,
1385 CompatibleNumberUnsignedType >::type
1388 : m_type(value_t::number_unsigned),
1389 m_value(static_cast<number_unsigned_t>(val))
1417 : m_type(value_t::number_float), m_value(val)
1420 if (not std::isfinite(val))
1422 m_type = value_t::null;
1457 template<
typename CompatibleNumberFloatType,
typename =
typename 1536 bool type_deduction =
true,
1537 value_t manual_type = value_t::array)
1540 bool is_an_object =
true;
1544 for (
const auto& element : init)
1546 if (not element.is_array() or element.size() != 2
1547 or not element[0].is_string())
1551 is_an_object =
false;
1557 if (not type_deduction)
1560 if (manual_type == value_t::array)
1562 is_an_object =
false;
1566 if (manual_type == value_t::object and not is_an_object)
1568 throw std::domain_error(
"cannot create object from initializer list");
1575 m_type = value_t::object;
1576 m_value = value_t::object;
1578 assert(m_value.object !=
nullptr);
1580 for (
auto& element : init)
1582 m_value.object->emplace(
std::move(*(element[0].m_value.string)),
std::move(element[1]));
1588 m_type = value_t::array;
1589 m_value.array = create<array_t>(
std::move(init));
1627 static basic_json
array(std::initializer_list<basic_json> init =
1628 std::initializer_list<basic_json>())
1630 return basic_json(init,
false, value_t::array);
1667 static basic_json
object(std::initializer_list<basic_json> init =
1668 std::initializer_list<basic_json>())
1670 return basic_json(init,
false, value_t::object);
1694 m_value.array = create<array_t>(cnt, val);
1731 template <
class InputIT,
typename 1737 basic_json(InputIT first, InputIT last) : m_type(first.m_object->m_type)
1740 if (first.m_object != last.m_object)
1742 throw std::domain_error(
"iterators are not compatible");
1748 case value_t::boolean:
1749 case value_t::number_float:
1750 case value_t::number_integer:
1751 case value_t::number_unsigned:
1752 case value_t::string:
1754 if (not first.m_it.primitive_iterator.is_begin() or not last.m_it.primitive_iterator.is_end())
1756 throw std::out_of_range(
"iterators out of range");
1769 case value_t::number_integer:
1771 assert(first.m_object !=
nullptr);
1772 m_value.number_integer = first.m_object->m_value.number_integer;
1776 case value_t::number_unsigned:
1778 assert(first.m_object !=
nullptr);
1779 m_value.number_unsigned = first.m_object->m_value.number_unsigned;
1783 case value_t::number_float:
1785 assert(first.m_object !=
nullptr);
1786 m_value.number_float = first.m_object->m_value.number_float;
1790 case value_t::boolean:
1792 assert(first.m_object !=
nullptr);
1793 m_value.boolean = first.m_object->m_value.boolean;
1797 case value_t::string:
1799 assert(first.m_object !=
nullptr);
1800 m_value = *first.m_object->m_value.string;
1804 case value_t::object:
1806 m_value.object = create<object_t>(first.m_it.object_iterator, last.m_it.object_iterator);
1810 case value_t::array:
1812 m_value.array = create<array_t>(first.m_it.array_iterator, last.m_it.array_iterator);
1818 assert(first.m_object !=
nullptr);
1819 throw std::domain_error(
"cannot use construct with iterators from " + first.m_object->type_name());
1876 : m_type(other.m_type)
1880 case value_t::object:
1887 case value_t::array:
1894 case value_t::string:
1901 case value_t::boolean:
1907 case value_t::number_integer:
1913 case value_t::number_unsigned:
1919 case value_t::number_float:
1951 : m_type(
std::
move(other.m_type)),
1952 m_value(
std::
move(other.m_value))
1955 other.m_type = value_t::null;
1990 swap(m_type, other.m_type);
1991 swap(m_value, other.m_value);
2014 case value_t::object:
2016 AllocatorType<object_t> alloc;
2017 alloc.destroy(m_value.object);
2018 alloc.deallocate(m_value.object, 1);
2022 case value_t::array:
2024 AllocatorType<array_t> alloc;
2025 alloc.destroy(m_value.array);
2026 alloc.deallocate(m_value.array, 1);
2030 case value_t::string:
2032 AllocatorType<string_t> alloc;
2033 alloc.destroy(m_value.string);
2034 alloc.deallocate(m_value.string, 1);
2081 std::stringstream ss;
2085 dump(ss,
true, static_cast<unsigned int>(indent));
2145 return is_null() or is_string() or is_boolean() or is_number();
2172 return is_array() or is_object();
2194 return m_type == value_t::null;
2216 return m_type == value_t::boolean;
2246 return is_number_integer() or is_number_float();
2275 return m_type == value_t::number_integer or m_type == value_t::number_unsigned;
2303 return m_type == value_t::number_unsigned;
2331 return m_type == value_t::number_float;
2353 return m_type == value_t::object;
2375 return m_type == value_t::array;
2397 return m_type == value_t::string;
2424 return m_type == value_t::discarded;
2458 template <
class T,
typename 2467 assert(m_value.object !=
nullptr);
2468 return T(m_value.object->begin(), m_value.object->end());
2472 throw std::domain_error(
"type must be object, but is " + type_name());
2481 assert(m_value.object !=
nullptr);
2482 return *(m_value.object);
2486 throw std::domain_error(
"type must be object, but is " + type_name());
2491 template <
class T,
typename 2504 assert(m_value.array !=
nullptr);
2505 std::transform(m_value.array->begin(), m_value.array->end(),
2506 std::inserter(to_vector, to_vector.end()), [](basic_json i)
2508 return i.
get<
typename T::value_type>();
2514 throw std::domain_error(
"type must be array, but is " + type_name());
2519 template <
class T,
typename 2529 assert(m_value.array !=
nullptr);
2530 to_vector.reserve(m_value.array->size());
2531 std::transform(m_value.array->begin(), m_value.array->end(),
2532 std::inserter(to_vector, to_vector.end()), [](basic_json i)
2540 throw std::domain_error(
"type must be array, but is " + type_name());
2545 template <
class T,
typename 2548 not has_mapped_type<T>::value
2554 assert(m_value.array !=
nullptr);
2555 return T(m_value.array->begin(), m_value.array->end());
2559 throw std::domain_error(
"type must be array, but is " + type_name());
2568 assert(m_value.array !=
nullptr);
2569 return *(m_value.array);
2573 throw std::domain_error(
"type must be array, but is " + type_name());
2578 template <
typename T,
typename 2586 assert(m_value.string !=
nullptr);
2587 return *m_value.string;
2591 throw std::domain_error(
"type must be string, but is " + type_name());
2596 template<
typename T,
typename 2604 case value_t::number_integer:
2606 return static_cast<T
>(m_value.number_integer);
2609 case value_t::number_unsigned:
2611 return static_cast<T
>(m_value.number_unsigned);
2614 case value_t::number_float:
2616 return static_cast<T
>(m_value.number_float);
2621 throw std::domain_error(
"type must be number, but is " + type_name());
2631 :
throw std::domain_error(
"type must be boolean, but is " + type_name());
2637 return is_object() ? m_value.object :
nullptr;
2643 return is_object() ? m_value.object :
nullptr;
2649 return is_array() ? m_value.array :
nullptr;
2655 return is_array() ? m_value.array :
nullptr;
2661 return is_string() ? m_value.string :
nullptr;
2667 return is_string() ? m_value.string :
nullptr;
2673 return is_boolean() ? &m_value.boolean :
nullptr;
2679 return is_boolean() ? &m_value.boolean :
nullptr;
2685 return is_number_integer() ? &m_value.number_integer :
nullptr;
2691 return is_number_integer() ? &m_value.number_integer :
nullptr;
2697 return is_number_unsigned() ? &m_value.number_unsigned :
nullptr;
2703 return is_number_unsigned() ? &m_value.number_unsigned :
nullptr;
2709 return is_number_float() ? &m_value.number_float :
nullptr;
2715 return is_number_float() ? &m_value.number_float :
nullptr;
2729 template<
typename ReferenceType,
typename ThisType>
2733 using PointerType =
typename std::add_pointer<ReferenceType>::type;
2734 auto ptr = obj.template get_ptr<PointerType>();
2742 throw std::domain_error(
"incompatible ReferenceType for get_ref, actual type is " +
2785 template<
typename ValueType,
typename 2789 ValueType
get()
const 2791 return get_impl(static_cast<ValueType*>(
nullptr));
2820 template<
typename PointerType,
typename 2824 PointerType
get() noexcept
2827 return get_ptr<PointerType>();
2834 template<
typename PointerType,
typename 2836 std::is_pointer<PointerType>::value
2838 constexpr
const PointerType
get()
const noexcept
2841 return get_ptr<PointerType>();
2869 template<
typename PointerType,
typename 2871 std::is_pointer<PointerType>::value
2876 return get_impl_ptr(static_cast<PointerType>(
nullptr));
2883 template<
typename PointerType,
typename 2885 std::is_pointer<PointerType>::value
2886 and std::is_const<typename std::remove_pointer<PointerType>::type>
::value 2888 constexpr
const PointerType
get_ptr() const noexcept
2891 return get_impl_ptr(static_cast<const PointerType>(
nullptr));
2920 template<
typename ReferenceType,
typename 2927 return get_ref_impl<ReferenceType>(*this);
2934 template<
typename ReferenceType,
typename 2936 std::is_reference<ReferenceType>::value
2937 and std::is_const<typename std::remove_reference<ReferenceType>::type>
::value 2942 return get_ref_impl<ReferenceType>(*this);
2973 template <
typename ValueType,
typename 2975 not std::is_pointer<ValueType>::value
2977 #ifndef _MSC_VER // Fix for issue #167 operator<< abiguity under VS2015 2978 and not std::is_same<ValueType, std::initializer_list<typename string_t::value_type>>::value
2981 operator ValueType()
const 2984 return get<ValueType>();
3026 assert(m_value.array !=
nullptr);
3027 return m_value.array->at(idx);
3029 catch (std::out_of_range&)
3032 throw std::out_of_range(
"array index " +
std::to_string(idx) +
" is out of range");
3037 throw std::domain_error(
"cannot use at() with " + type_name());
3070 assert(m_value.array !=
nullptr);
3071 return m_value.array->at(idx);
3073 catch (std::out_of_range&)
3076 throw std::out_of_range(
"array index " +
std::to_string(idx) +
" is out of range");
3081 throw std::domain_error(
"cannot use at() with " + type_name());
3118 assert(m_value.object !=
nullptr);
3119 return m_value.object->at(key);
3121 catch (std::out_of_range&)
3124 throw std::out_of_range(
"key '" + key +
"' not found");
3129 throw std::domain_error(
"cannot use at() with " + type_name());
3166 assert(m_value.object !=
nullptr);
3167 return m_value.object->at(key);
3169 catch (std::out_of_range&)
3172 throw std::out_of_range(
"key '" + key +
"' not found");
3177 throw std::domain_error(
"cannot use at() with " + type_name());
3211 m_type = value_t::array;
3212 m_value.
array = create<array_t>();
3219 assert(m_value.array !=
nullptr);
3220 for (
size_t i = m_value.array->size(); i <= idx; ++i)
3222 m_value.array->push_back(basic_json());
3225 return m_value.array->operator[](idx);
3229 throw std::domain_error(
"cannot use operator[] with " + type_name());
3257 assert(m_value.array !=
nullptr);
3258 return m_value.array->operator[](idx);
3262 throw std::domain_error(
"cannot use operator[] with " + type_name());
3298 m_type = value_t::object;
3299 m_value.
object = create<object_t>();
3305 assert(m_value.object !=
nullptr);
3306 return m_value.object->operator[](key);
3310 throw std::domain_error(
"cannot use operator[] with " + type_name());
3346 assert(m_value.object !=
nullptr);
3347 assert(m_value.object->find(key) != m_value.object->end());
3348 return m_value.object->find(key)->second;
3352 throw std::domain_error(
"cannot use operator[] with " + type_name());
3383 template<
typename T, std::
size_t n>
3386 return operator[](static_cast<const T>(key));
3418 template<
typename T, std::
size_t n>
3421 return operator[](static_cast<const T>(key));
3451 template<
typename T>
3457 m_type = value_t::object;
3458 m_value = value_t::object;
3464 assert(m_value.object !=
nullptr);
3465 return m_value.object->operator[](key);
3469 throw std::domain_error(
"cannot use operator[] with " + type_name());
3500 template<
typename T>
3506 assert(m_value.object !=
nullptr);
3507 assert(m_value.object->find(key) != m_value.object->end());
3508 return m_value.object->find(key)->second;
3512 throw std::domain_error(
"cannot use operator[] with " + type_name());
3564 template <
class ValueType,
typename 3568 ValueType
value(
const typename object_t::key_type& key, ValueType default_value)
const 3574 const auto it = find(key);
3581 return default_value;
3586 throw std::domain_error(
"cannot use value() with " + type_name());
3594 string_t value(
const typename object_t::key_type& key,
const char* default_value)
const 3727 template <
class InteratorType,
typename 3736 if (
this != pos.m_object)
3738 throw std::domain_error(
"iterator does not fit current value");
3741 InteratorType result = end();
3745 case value_t::boolean:
3746 case value_t::number_float:
3747 case value_t::number_integer:
3748 case value_t::number_unsigned:
3749 case value_t::string:
3751 if (not pos.m_it.primitive_iterator.is_begin())
3753 throw std::out_of_range(
"iterator out of range");
3758 delete m_value.string;
3759 m_value.string =
nullptr;
3762 m_type = value_t::null;
3766 case value_t::object:
3768 assert(m_value.object !=
nullptr);
3769 result.m_it.object_iterator = m_value.object->erase(pos.m_it.object_iterator);
3773 case value_t::array:
3775 assert(m_value.array !=
nullptr);
3776 result.m_it.array_iterator = m_value.array->erase(pos.m_it.array_iterator);
3782 throw std::domain_error(
"cannot use erase() with " + type_name());
3835 template <
class InteratorType,
typename 3838 std::is_same<InteratorType, typename basic_json_t::const_iterator>::value
3841 InteratorType
erase(InteratorType first, InteratorType last)
3844 if (
this != first.m_object or
this != last.m_object)
3846 throw std::domain_error(
"iterators do not fit current value");
3849 InteratorType result = end();
3853 case value_t::boolean:
3854 case value_t::number_float:
3855 case value_t::number_integer:
3856 case value_t::number_unsigned:
3857 case value_t::string:
3859 if (not first.m_it.primitive_iterator.is_begin() or not last.m_it.primitive_iterator.is_end())
3861 throw std::out_of_range(
"iterators out of range");
3866 delete m_value.string;
3867 m_value.string =
nullptr;
3870 m_type = value_t::null;
3874 case value_t::object:
3876 assert(m_value.object !=
nullptr);
3877 result.m_it.object_iterator = m_value.object->erase(first.m_it.object_iterator,
3878 last.m_it.object_iterator);
3882 case value_t::array:
3884 assert(m_value.array !=
nullptr);
3885 result.m_it.array_iterator = m_value.array->erase(first.m_it.array_iterator,
3886 last.m_it.array_iterator);
3892 throw std::domain_error(
"cannot use erase() with " + type_name());
3933 assert(m_value.object !=
nullptr);
3934 return m_value.object->erase(key);
3938 throw std::domain_error(
"cannot use erase() with " + type_name());
3973 throw std::out_of_range(
"index out of range");
3976 assert(m_value.array !=
nullptr);
3977 m_value.array->erase(m_value.array->begin() +
static_cast<difference_type>(idx));
3981 throw std::domain_error(
"cannot use erase() with " + type_name());
4014 auto result = end();
4018 assert(m_value.object !=
nullptr);
4019 result.m_it.object_iterator = m_value.object->find(key);
4031 auto result = cend();
4035 assert(m_value.object !=
nullptr);
4036 result.m_it.object_iterator = m_value.object->find(key);
4063 assert(not is_object() or m_value.object !=
nullptr);
4064 return is_object() ? m_value.object->count(key) : 0;
4432 case value_t::array:
4434 assert(m_value.array !=
nullptr);
4435 return m_value.array->empty();
4438 case value_t::object:
4440 assert(m_value.object !=
nullptr);
4441 return m_value.object->empty();
4495 case value_t::array:
4497 assert(m_value.array !=
nullptr);
4498 return m_value.array->size();
4501 case value_t::object:
4503 assert(m_value.object !=
nullptr);
4504 return m_value.object->size();
4555 case value_t::array:
4557 assert(m_value.array !=
nullptr);
4558 return m_value.array->max_size();
4561 case value_t::object:
4563 assert(m_value.object !=
nullptr);
4564 return m_value.object->max_size();
4614 case value_t::number_integer:
4616 m_value.number_integer = 0;
4620 case value_t::number_unsigned:
4622 m_value.number_unsigned = 0;
4626 case value_t::number_float:
4628 m_value.number_float = 0.0;
4632 case value_t::boolean:
4634 m_value.boolean =
false;
4638 case value_t::string:
4640 assert(m_value.string !=
nullptr);
4641 m_value.string->clear();
4645 case value_t::array:
4647 assert(m_value.array !=
nullptr);
4648 m_value.array->clear();
4652 case value_t::object:
4654 assert(m_value.object !=
nullptr);
4655 m_value.object->clear();
4689 if (not(is_null() or is_array()))
4691 throw std::domain_error(
"cannot use push_back() with " + type_name());
4697 m_type = value_t::array;
4698 m_value = value_t::array;
4702 assert(m_value.array !=
nullptr);
4703 m_value.array->push_back(
std::move(val));
4705 val.m_type = value_t::null;
4725 if (not(is_null() or is_array()))
4727 throw std::domain_error(
"cannot use push_back() with " + type_name());
4733 m_type = value_t::array;
4734 m_value = value_t::array;
4738 assert(m_value.array !=
nullptr);
4739 m_value.array->push_back(val);
4775 if (not(is_null() or is_object()))
4777 throw std::domain_error(
"cannot use push_back() with " + type_name());
4783 m_type = value_t::object;
4784 m_value = value_t::object;
4788 assert(m_value.object !=
nullptr);
4789 m_value.object->insert(val);
4799 return operator[](val.first);
4832 throw std::domain_error(
"iterator does not fit current value");
4837 assert(m_value.array !=
nullptr);
4843 throw std::domain_error(
"cannot use insert() with " + type_name());
4853 return insert(pos, val);
4888 throw std::domain_error(
"iterator does not fit current value");
4893 assert(m_value.array !=
nullptr);
4894 result.m_it.array_iterator = m_value.array->insert(pos.
m_it.
array_iterator, cnt, val);
4899 throw std::domain_error(
"cannot use insert() with " + type_name());
4938 throw std::domain_error(
"cannot use insert() with " + type_name());
4944 throw std::domain_error(
"iterator does not fit current value");
4949 throw std::domain_error(
"iterators do not fit");
4954 throw std::domain_error(
"passed iterators may not belong to container");
4959 assert(m_value.array !=
nullptr);
4960 result.m_it.array_iterator = m_value.array->insert(
4996 throw std::domain_error(
"cannot use insert() with " + type_name());
5002 throw std::domain_error(
"iterator does not fit current value");
5007 assert(m_value.array !=
nullptr);
5065 assert(m_value.array !=
nullptr);
5070 throw std::domain_error(
"cannot use swap() with " + type_name());
5099 assert(m_value.object !=
nullptr);
5104 throw std::domain_error(
"cannot use swap() with " + type_name());
5133 assert(m_value.string !=
nullptr);
5138 throw std::domain_error(
"cannot use swap() with " + type_name());
5164 static constexpr std::array<uint8_t, 8> order = {{
5177 if (lhs == value_t::discarded or rhs == value_t::discarded)
5182 return order[
static_cast<std::size_t
>(lhs)] < order[static_cast<std::size_t>(rhs)];
5211 const auto lhs_type = lhs.type();
5212 const auto rhs_type = rhs.type();
5214 if (lhs_type == rhs_type)
5218 case value_t::array:
5220 assert(lhs.m_value.array !=
nullptr);
5221 assert(rhs.m_value.array !=
nullptr);
5222 return *lhs.m_value.array == *rhs.m_value.array;
5224 case value_t::object:
5226 assert(lhs.m_value.object !=
nullptr);
5227 assert(rhs.m_value.object !=
nullptr);
5228 return *lhs.m_value.object == *rhs.m_value.object;
5234 case value_t::string:
5236 assert(lhs.m_value.string !=
nullptr);
5237 assert(rhs.m_value.string !=
nullptr);
5238 return *lhs.m_value.string == *rhs.m_value.string;
5240 case value_t::boolean:
5242 return lhs.m_value.boolean == rhs.m_value.boolean;
5244 case value_t::number_integer:
5246 return lhs.m_value.number_integer == rhs.m_value.number_integer;
5248 case value_t::number_unsigned:
5250 return lhs.m_value.number_unsigned == rhs.m_value.number_unsigned;
5252 case value_t::number_float:
5254 return lhs.m_value.number_float == rhs.m_value.number_float;
5262 else if (lhs_type == value_t::number_integer and rhs_type == value_t::number_float)
5264 return static_cast<number_float_t>(lhs.m_value.number_integer) == rhs.m_value.number_float;
5266 else if (lhs_type == value_t::number_float and rhs_type == value_t::number_integer)
5268 return lhs.m_value.number_float ==
static_cast<number_float_t>(rhs.m_value.number_integer);
5270 else if (lhs_type == value_t::number_unsigned and rhs_type == value_t::number_float)
5272 return static_cast<number_float_t>(lhs.m_value.number_unsigned) == rhs.m_value.number_float;
5274 else if (lhs_type == value_t::number_float and rhs_type == value_t::number_unsigned)
5276 return lhs.m_value.number_float ==
static_cast<number_float_t>(rhs.m_value.number_unsigned);
5278 else if (lhs_type == value_t::number_unsigned and rhs_type == value_t::number_integer)
5280 return static_cast<number_integer_t>(lhs.m_value.number_unsigned) == rhs.m_value.number_integer;
5282 else if (lhs_type == value_t::number_integer and rhs_type == value_t::number_unsigned)
5284 return lhs.m_value.number_integer ==
static_cast<number_integer_t>(rhs.m_value.number_unsigned);
5340 return not (lhs == rhs);
5372 return not v.is_null();
5401 const auto lhs_type = lhs.type();
5402 const auto rhs_type = rhs.type();
5404 if (lhs_type == rhs_type)
5408 case value_t::array:
5410 assert(lhs.m_value.array !=
nullptr);
5411 assert(rhs.m_value.array !=
nullptr);
5412 return *lhs.m_value.array < *rhs.m_value.array;
5414 case value_t::object:
5416 assert(lhs.m_value.object !=
nullptr);
5417 assert(rhs.m_value.object !=
nullptr);
5418 return *lhs.m_value.object < *rhs.m_value.object;
5424 case value_t::string:
5426 assert(lhs.m_value.string !=
nullptr);
5427 assert(rhs.m_value.string !=
nullptr);
5428 return *lhs.m_value.string < *rhs.m_value.string;
5430 case value_t::boolean:
5432 return lhs.m_value.boolean < rhs.m_value.boolean;
5434 case value_t::number_integer:
5436 return lhs.m_value.number_integer < rhs.m_value.number_integer;
5438 case value_t::number_unsigned:
5440 return lhs.m_value.number_unsigned < rhs.m_value.number_unsigned;
5442 case value_t::number_float:
5444 return lhs.m_value.number_float < rhs.m_value.number_float;
5452 else if (lhs_type == value_t::number_integer and rhs_type == value_t::number_float)
5454 return static_cast<number_float_t>(lhs.m_value.number_integer) < rhs.m_value.number_float;
5456 else if (lhs_type == value_t::number_float and rhs_type == value_t::number_integer)
5458 return lhs.m_value.number_float <
static_cast<number_float_t>(rhs.m_value.number_integer);
5460 else if (lhs_type == value_t::number_unsigned and rhs_type == value_t::number_float)
5462 return static_cast<number_float_t>(lhs.m_value.number_unsigned) < rhs.m_value.number_float;
5464 else if (lhs_type == value_t::number_float and rhs_type == value_t::number_unsigned)
5466 return lhs.m_value.number_float <
static_cast<number_float_t>(rhs.m_value.number_unsigned);
5468 else if (lhs_type == value_t::number_integer and rhs_type == value_t::number_unsigned)
5470 return lhs.m_value.number_integer <
static_cast<number_integer_t>(rhs.m_value.number_unsigned);
5472 else if (lhs_type == value_t::number_unsigned and rhs_type == value_t::number_integer)
5474 return static_cast<number_integer_t>(lhs.m_value.number_unsigned) < rhs.m_value.number_integer;
5502 return not (rhs < lhs);
5524 return not (lhs <= rhs);
5546 return not (lhs < rhs);
5581 friend std::ostream&
operator<<(std::ostream& o,
const basic_json& j)
5585 const auto indentation = (pretty_print ? o.width() : 0);
5591 j.
dump(o, pretty_print, static_cast<unsigned int>(indentation));
5599 friend std::ostream&
operator>>(
const basic_json& j, std::ostream& o)
5734 case value_t::object:
5736 case value_t::array:
5738 case value_t::string:
5740 case value_t::boolean:
5742 case value_t::discarded:
5759 std::size_t result = 0;
5761 for (
const auto& c : s)
5780 if (c >= 0x00 and c <= 0x1f)
5808 const auto space = extra_space(s);
5815 string_t result(s.size() + space,
'\\');
5816 std::size_t pos = 0;
5818 for (
const auto& c : s)
5825 result[pos + 1] =
'"';
5841 result[pos + 1] =
'b';
5849 result[pos + 1] =
'f';
5857 result[pos + 1] =
'n';
5865 result[pos + 1] =
'r';
5873 result[pos + 1] =
't';
5880 if (c >= 0x00 and c <= 0x1f)
5884 auto hexify = [](
const char v) ->
char 5886 return (v < 10) ? (
'0' + v) : (
'a' + v - 10);
5891 {
'u',
'0',
'0', hexify(c >> 4), hexify(c & 0x0f)
5931 const unsigned int indent_step,
5932 const unsigned int current_indent = 0)
const 5935 unsigned int new_indent = current_indent;
5939 case value_t::object:
5941 assert(m_value.object !=
nullptr);
5943 if (m_value.object->empty())
5954 new_indent += indent_step;
5958 for (
auto i = m_value.object->cbegin(); i != m_value.object->cend(); ++i)
5960 if (i != m_value.object->cbegin())
5962 o << (pretty_print ?
",\n" :
",");
5964 o <<
string_t(new_indent,
' ') <<
"\"" 5965 << escape_string(i->first) <<
"\":" 5966 << (pretty_print ?
" " :
"");
5967 i->second.dump(o, pretty_print, indent_step, new_indent);
5973 new_indent -= indent_step;
5977 o <<
string_t(new_indent,
' ') +
"}";
5981 case value_t::array:
5983 assert(m_value.array !=
nullptr);
5985 if (m_value.array->empty())
5996 new_indent += indent_step;
6000 for (
auto i = m_value.array->cbegin(); i != m_value.array->cend(); ++i)
6002 if (i != m_value.array->cbegin())
6004 o << (pretty_print ?
",\n" :
",");
6007 i->dump(o, pretty_print, indent_step, new_indent);
6013 new_indent -= indent_step;
6017 o <<
string_t(new_indent,
' ') <<
"]";
6021 case value_t::string:
6023 assert(m_value.string !=
nullptr);
6024 o <<
string_t(
"\"") << escape_string(*m_value.string) <<
"\"";
6028 case value_t::boolean:
6030 o << (m_value.boolean ?
"true" :
"false");
6034 case value_t::number_integer:
6036 o << m_value.number_integer;
6040 case value_t::number_unsigned:
6042 o << m_value.number_unsigned;
6046 case value_t::number_float:
6054 if (std::fmod(m_value.number_float, 1) == 0)
6056 o << std::fixed << std::setprecision(1);
6061 o.unsetf(std::ios_base::floatfield);
6062 o << std::setprecision(std::numeric_limits<double>::digits10);
6064 o << m_value.number_float;
6068 case value_t::discarded:
6126 return (m_it == begin_value);
6132 return (m_it == end_value);
6173 : object_iterator(), array_iterator(), primitive_iterator()
6178 template<
typename IteratorType>
6189 size_t array_index = 0;
6214 return anchor != o.
anchor;
6220 assert(anchor.m_object !=
nullptr);
6222 switch (anchor.m_object->type())
6225 case value_t::array:
6231 case value_t::object:
6233 return anchor.key();
6245 typename IteratorType::reference
value()
const 6247 return anchor.value();
6287 class const_iterator :
public std::iterator<std::random_access_iterator_tag, const basic_json>
6290 friend class basic_json;
6311 assert(m_object !=
nullptr);
6313 switch (m_object->m_type)
6317 m_it.object_iterator =
typename object_t::iterator();
6323 m_it.array_iterator =
typename array_t::iterator();
6337 : m_object(other.m_object)
6339 assert(m_object !=
nullptr);
6341 switch (m_object->m_type)
6345 m_it.object_iterator = other.m_it.object_iterator;
6351 m_it.array_iterator = other.m_it.array_iterator;
6357 m_it.primitive_iterator = other.m_it.primitive_iterator;
6365 : m_object(other.m_object), m_it(other.m_it)
6385 assert(m_object !=
nullptr);
6387 switch (m_object->m_type)
6391 assert(m_object->m_value.object !=
nullptr);
6392 m_it.object_iterator = m_object->m_value.object->begin();
6398 assert(m_object->m_value.array !=
nullptr);
6399 m_it.array_iterator = m_object->m_value.array->begin();
6406 m_it.primitive_iterator.set_end();
6412 m_it.primitive_iterator.set_begin();
6421 assert(m_object !=
nullptr);
6423 switch (m_object->m_type)
6427 assert(m_object->m_value.object !=
nullptr);
6428 m_it.object_iterator = m_object->m_value.object->end();
6434 assert(m_object->m_value.array !=
nullptr);
6435 m_it.array_iterator = m_object->m_value.array->end();
6441 m_it.primitive_iterator.set_end();
6451 assert(m_object !=
nullptr);
6453 switch (m_object->m_type)
6457 assert(m_object->m_value.object);
6458 assert(m_it.object_iterator != m_object->m_value.object->end());
6459 return m_it.object_iterator->second;
6464 assert(m_object->m_value.array);
6465 assert(m_it.array_iterator != m_object->m_value.array->end());
6466 return *m_it.array_iterator;
6471 throw std::out_of_range(
"cannot get value");
6476 if (m_it.primitive_iterator.is_begin())
6482 throw std::out_of_range(
"cannot get value");
6491 assert(m_object !=
nullptr);
6493 switch (m_object->m_type)
6497 assert(m_object->m_value.object);
6498 assert(m_it.object_iterator != m_object->m_value.object->end());
6499 return &(m_it.object_iterator->second);
6504 assert(m_object->m_value.array);
6505 assert(m_it.array_iterator != m_object->m_value.array->end());
6506 return &*m_it.array_iterator;
6511 if (m_it.primitive_iterator.is_begin())
6517 throw std::out_of_range(
"cannot get value");
6526 auto result = *
this;
6534 assert(m_object !=
nullptr);
6536 switch (m_object->m_type)
6540 ++m_it.object_iterator;
6546 ++m_it.array_iterator;
6552 ++m_it.primitive_iterator;
6563 auto result = *
this;
6571 assert(m_object !=
nullptr);
6573 switch (m_object->m_type)
6577 --m_it.object_iterator;
6583 --m_it.array_iterator;
6589 --m_it.primitive_iterator;
6603 throw std::domain_error(
"cannot compare iterators of different containers");
6606 assert(m_object !=
nullptr);
6608 switch (m_object->m_type)
6639 throw std::domain_error(
"cannot compare iterators of different containers");
6642 assert(m_object !=
nullptr);
6644 switch (m_object->m_type)
6648 throw std::domain_error(
"cannot compare order of object iterators");
6666 return not other.operator < (*this);
6672 return not operator<=(other);
6684 assert(m_object !=
nullptr);
6686 switch (m_object->m_type)
6690 throw std::domain_error(
"cannot use offsets with object iterators");
6695 m_it.array_iterator += i;
6701 m_it.primitive_iterator += i;
6712 return operator+=(-i);
6718 auto result = *
this;
6726 auto result = *
this;
6734 assert(m_object !=
nullptr);
6736 switch (m_object->m_type)
6740 throw std::domain_error(
"cannot use offsets with object iterators");
6758 assert(m_object !=
nullptr);
6760 switch (m_object->m_type)
6764 throw std::domain_error(
"cannot use operator[] for object iterators");
6769 return *(m_it.array_iterator + n);
6774 throw std::out_of_range(
"cannot get value");
6779 if (m_it.primitive_iterator == -n)
6785 throw std::out_of_range(
"cannot get value");
6792 typename object_t::key_type
key()
const 6794 assert(m_object !=
nullptr);
6796 if (m_object->is_object())
6798 return m_it.object_iterator->first;
6802 throw std::domain_error(
"cannot use key() for non-object iterators");
6859 base_iterator::operator=(other);
6872 return const_cast<pointer>(base_iterator::operator->());
6879 base_iterator::operator++();
6886 base_iterator::operator++();
6894 base_iterator::operator--();
6901 base_iterator::operator--();
6908 base_iterator::operator+=(i);
6915 base_iterator::operator-=(i);
6922 auto result = *
this;
6930 auto result = *
this;
6938 return base_iterator::operator-(other);
6944 return const_cast<reference>(base_iterator::operator[](n));
6971 template<
typename Base>
6993 return base_iterator::operator++(1);
6999 base_iterator::operator++();
7006 return base_iterator::operator--(1);
7012 base_iterator::operator--();
7019 base_iterator::operator+=(i);
7026 auto result = *
this;
7034 auto result = *
this;
7042 return this->base() - other.base();
7048 return *(this->operator+(n));
7052 typename object_t::key_type
key()
const 7054 auto it = --this->base();
7061 auto it = --this->base();
7062 return it.operator * ();
7106 : m_stream(
nullptr), m_buffer(s)
7108 m_content =
reinterpret_cast<const lexer_char_t*
>(s.c_str());
7109 assert(m_content !=
nullptr);
7110 m_start = m_cursor = m_content;
7111 m_limit = m_content + s.size();
7115 explicit lexer(std::istream* s) noexcept
7116 : m_stream(s), m_buffer()
7118 assert(m_stream !=
nullptr);
7119 getline(*m_stream, m_buffer);
7120 m_content =
reinterpret_cast<const lexer_char_t*
>(m_buffer.c_str());
7121 assert(m_content !=
nullptr);
7122 m_start = m_cursor = m_content;
7123 m_limit = m_content + m_buffer.size();
7149 const std::size_t codepoint2 = 0)
7152 std::size_t codepoint = codepoint1;
7155 if (codepoint1 >= 0xD800 and codepoint1 <= 0xDBFF)
7158 if (codepoint2 >= 0xDC00 and codepoint2 <= 0xDFFF)
7172 throw std::invalid_argument(
"missing or wrong low surrogate");
7178 if (codepoint < 0x80)
7181 result.append(1, static_cast<typename string_t::value_type>(codepoint));
7183 else if (codepoint <= 0x7ff)
7186 result.append(1, static_cast<typename string_t::value_type>(0xC0 | ((codepoint >> 6) & 0x1F)));
7187 result.append(1, static_cast<typename string_t::value_type>(0x80 | (codepoint & 0x3F)));
7189 else if (codepoint <= 0xffff)
7192 result.append(1, static_cast<typename string_t::value_type>(0xE0 | ((codepoint >> 12) & 0x0F)));
7193 result.append(1, static_cast<typename string_t::value_type>(0x80 | ((codepoint >> 6) & 0x3F)));
7194 result.append(1, static_cast<typename string_t::value_type>(0x80 | (codepoint & 0x3F)));
7196 else if (codepoint <= 0x10ffff)
7199 result.append(1, static_cast<typename string_t::value_type>(0xF0 | ((codepoint >> 18) & 0x07)));
7200 result.append(1, static_cast<typename string_t::value_type>(0x80 | ((codepoint >> 12) & 0x3F)));
7201 result.append(1, static_cast<typename string_t::value_type>(0x80 | ((codepoint >> 6) & 0x3F)));
7202 result.append(1, static_cast<typename string_t::value_type>(0x80 | (codepoint & 0x3F)));
7206 throw std::out_of_range(
"code points above 0x10FFFF are invalid");
7217 case token_type::uninitialized:
7218 return "<uninitialized>";
7219 case token_type::literal_true:
7220 return "true literal";
7221 case token_type::literal_false:
7222 return "false literal";
7223 case token_type::literal_null:
7224 return "null literal";
7225 case token_type::value_string:
7226 return "string literal";
7227 case token_type::value_number:
7228 return "number literal";
7229 case token_type::begin_array:
7231 case token_type::begin_object:
7233 case token_type::end_array:
7235 case token_type::end_object:
7237 case token_type::name_separator:
7239 case token_type::value_separator:
7241 case token_type::parse_error:
7242 return "<parse error>";
7243 case token_type::end_of_input:
7244 return "end of input";
7248 return "unknown token";
7270 assert(m_start !=
nullptr);
7275 unsigned int yyaccept = 0;
7276 static const unsigned char yybm[] =
7278 0, 0, 0, 0, 0, 0, 0, 0,
7279 0, 32, 32, 0, 0, 32, 0, 0,
7280 128, 128, 128, 128, 128, 128, 128, 128,
7281 128, 128, 128, 128, 128, 128, 128, 128,
7282 160, 128, 0, 128, 128, 128, 128, 128,
7283 128, 128, 128, 128, 128, 128, 128, 128,
7284 192, 192, 192, 192, 192, 192, 192, 192,
7285 192, 192, 128, 128, 128, 128, 128, 128,
7286 128, 128, 128, 128, 128, 128, 128, 128,
7287 128, 128, 128, 128, 128, 128, 128, 128,
7288 128, 128, 128, 128, 128, 128, 128, 128,
7289 128, 128, 128, 128, 0, 128, 128, 128,
7290 128, 128, 128, 128, 128, 128, 128, 128,
7291 128, 128, 128, 128, 128, 128, 128, 128,
7292 128, 128, 128, 128, 128, 128, 128, 128,
7293 128, 128, 128, 128, 128, 128, 128, 128,
7294 128, 128, 128, 128, 128, 128, 128, 128,
7295 128, 128, 128, 128, 128, 128, 128, 128,
7296 128, 128, 128, 128, 128, 128, 128, 128,
7297 128, 128, 128, 128, 128, 128, 128, 128,
7298 128, 128, 128, 128, 128, 128, 128, 128,
7299 128, 128, 128, 128, 128, 128, 128, 128,
7300 128, 128, 128, 128, 128, 128, 128, 128,
7301 128, 128, 128, 128, 128, 128, 128, 128,
7302 128, 128, 128, 128, 128, 128, 128, 128,
7303 128, 128, 128, 128, 128, 128, 128, 128,
7304 128, 128, 128, 128, 128, 128, 128, 128,
7305 128, 128, 128, 128, 128, 128, 128, 128,
7306 128, 128, 128, 128, 128, 128, 128, 128,
7307 128, 128, 128, 128, 128, 128, 128, 128,
7308 128, 128, 128, 128, 128, 128, 128, 128,
7309 128, 128, 128, 128, 128, 128, 128, 128,
7311 if ((m_limit - m_cursor) < 5)
7316 if (yybm[0 + yych] & 32)
7318 goto basic_json_parser_6;
7328 goto basic_json_parser_2;
7332 goto basic_json_parser_4;
7334 goto basic_json_parser_9;
7340 goto basic_json_parser_4;
7344 goto basic_json_parser_10;
7346 goto basic_json_parser_12;
7355 goto basic_json_parser_4;
7359 goto basic_json_parser_13;
7361 goto basic_json_parser_15;
7367 goto basic_json_parser_17;
7371 goto basic_json_parser_19;
7373 goto basic_json_parser_4;
7385 goto basic_json_parser_21;
7389 goto basic_json_parser_4;
7391 goto basic_json_parser_23;
7397 goto basic_json_parser_24;
7401 goto basic_json_parser_4;
7403 goto basic_json_parser_25;
7412 goto basic_json_parser_26;
7414 goto basic_json_parser_4;
7420 goto basic_json_parser_28;
7424 goto basic_json_parser_30;
7426 goto basic_json_parser_4;
7430 basic_json_parser_2:
7433 return token_type::end_of_input;
7435 basic_json_parser_4:
7437 basic_json_parser_5:
7439 return token_type::parse_error;
7441 basic_json_parser_6:
7443 if (m_limit <= m_cursor)
7448 if (yybm[0 + yych] & 32)
7450 goto basic_json_parser_6;
7455 basic_json_parser_9:
7457 yych = *(m_marker = ++m_cursor);
7460 goto basic_json_parser_5;
7462 goto basic_json_parser_32;
7463 basic_json_parser_10:
7466 return token_type::value_separator;
7468 basic_json_parser_12:
7472 goto basic_json_parser_5;
7476 goto basic_json_parser_13;
7480 goto basic_json_parser_15;
7482 goto basic_json_parser_5;
7483 basic_json_parser_13:
7485 yych = *(m_marker = ++m_cursor);
7490 goto basic_json_parser_37;
7497 goto basic_json_parser_38;
7501 goto basic_json_parser_38;
7504 basic_json_parser_14:
7506 return token_type::value_number;
7508 basic_json_parser_15:
7510 m_marker = ++m_cursor;
7511 if ((m_limit - m_cursor) < 3)
7516 if (yybm[0 + yych] & 64)
7518 goto basic_json_parser_15;
7524 goto basic_json_parser_37;
7526 goto basic_json_parser_14;
7532 goto basic_json_parser_38;
7536 goto basic_json_parser_38;
7538 goto basic_json_parser_14;
7540 basic_json_parser_17:
7543 return token_type::name_separator;
7545 basic_json_parser_19:
7548 return token_type::begin_array;
7550 basic_json_parser_21:
7553 return token_type::end_array;
7555 basic_json_parser_23:
7557 yych = *(m_marker = ++m_cursor);
7560 goto basic_json_parser_39;
7562 goto basic_json_parser_5;
7563 basic_json_parser_24:
7565 yych = *(m_marker = ++m_cursor);
7568 goto basic_json_parser_40;
7570 goto basic_json_parser_5;
7571 basic_json_parser_25:
7573 yych = *(m_marker = ++m_cursor);
7576 goto basic_json_parser_41;
7578 goto basic_json_parser_5;
7579 basic_json_parser_26:
7582 return token_type::begin_object;
7584 basic_json_parser_28:
7587 return token_type::end_object;
7589 basic_json_parser_30:
7591 yych = *(m_marker = ++m_cursor);
7594 goto basic_json_parser_42;
7596 goto basic_json_parser_5;
7597 basic_json_parser_31:
7599 if (m_limit <= m_cursor)
7604 basic_json_parser_32:
7605 if (yybm[0 + yych] & 128)
7607 goto basic_json_parser_31;
7611 goto basic_json_parser_33;
7615 goto basic_json_parser_34;
7617 goto basic_json_parser_36;
7618 basic_json_parser_33:
7619 m_cursor = m_marker;
7622 goto basic_json_parser_5;
7626 goto basic_json_parser_14;
7628 basic_json_parser_34:
7631 return token_type::value_string;
7633 basic_json_parser_36:
7635 if (m_limit <= m_cursor)
7646 goto basic_json_parser_31;
7650 goto basic_json_parser_33;
7652 goto basic_json_parser_31;
7660 goto basic_json_parser_33;
7662 goto basic_json_parser_31;
7668 goto basic_json_parser_31;
7670 goto basic_json_parser_33;
7680 goto basic_json_parser_31;
7684 goto basic_json_parser_31;
7686 goto basic_json_parser_33;
7694 goto basic_json_parser_31;
7696 goto basic_json_parser_33;
7702 goto basic_json_parser_31;
7706 goto basic_json_parser_43;
7708 goto basic_json_parser_33;
7712 basic_json_parser_37:
7716 goto basic_json_parser_33;
7720 goto basic_json_parser_44;
7722 goto basic_json_parser_33;
7723 basic_json_parser_38:
7729 goto basic_json_parser_46;
7731 goto basic_json_parser_33;
7737 goto basic_json_parser_46;
7741 goto basic_json_parser_33;
7745 goto basic_json_parser_47;
7747 goto basic_json_parser_33;
7749 basic_json_parser_39:
7753 goto basic_json_parser_49;
7755 goto basic_json_parser_33;
7756 basic_json_parser_40:
7760 goto basic_json_parser_50;
7762 goto basic_json_parser_33;
7763 basic_json_parser_41:
7767 goto basic_json_parser_51;
7769 goto basic_json_parser_33;
7770 basic_json_parser_42:
7774 goto basic_json_parser_52;
7776 goto basic_json_parser_33;
7777 basic_json_parser_43:
7779 if (m_limit <= m_cursor)
7788 goto basic_json_parser_33;
7792 goto basic_json_parser_54;
7794 goto basic_json_parser_33;
7800 goto basic_json_parser_54;
7804 goto basic_json_parser_33;
7808 goto basic_json_parser_54;
7810 goto basic_json_parser_33;
7812 basic_json_parser_44:
7814 m_marker = ++m_cursor;
7815 if ((m_limit - m_cursor) < 3)
7824 goto basic_json_parser_14;
7828 goto basic_json_parser_44;
7830 goto basic_json_parser_14;
7836 goto basic_json_parser_38;
7840 goto basic_json_parser_38;
7842 goto basic_json_parser_14;
7844 basic_json_parser_46:
7848 goto basic_json_parser_33;
7852 goto basic_json_parser_33;
7854 basic_json_parser_47:
7856 if (m_limit <= m_cursor)
7863 goto basic_json_parser_14;
7867 goto basic_json_parser_47;
7869 goto basic_json_parser_14;
7870 basic_json_parser_49:
7874 goto basic_json_parser_55;
7876 goto basic_json_parser_33;
7877 basic_json_parser_50:
7881 goto basic_json_parser_56;
7883 goto basic_json_parser_33;
7884 basic_json_parser_51:
7888 goto basic_json_parser_58;
7890 goto basic_json_parser_33;
7891 basic_json_parser_52:
7896 basic_json_parser_54:
7898 if (m_limit <= m_cursor)
7907 goto basic_json_parser_33;
7911 goto basic_json_parser_60;
7913 goto basic_json_parser_33;
7919 goto basic_json_parser_60;
7923 goto basic_json_parser_33;
7927 goto basic_json_parser_60;
7929 goto basic_json_parser_33;
7931 basic_json_parser_55:
7935 goto basic_json_parser_61;
7937 goto basic_json_parser_33;
7938 basic_json_parser_56:
7941 return token_type::literal_null;
7943 basic_json_parser_58:
7946 return token_type::literal_true;
7948 basic_json_parser_60:
7950 if (m_limit <= m_cursor)
7959 goto basic_json_parser_33;
7963 goto basic_json_parser_63;
7965 goto basic_json_parser_33;
7971 goto basic_json_parser_63;
7975 goto basic_json_parser_33;
7979 goto basic_json_parser_63;
7981 goto basic_json_parser_33;
7983 basic_json_parser_61:
7986 return token_type::literal_false;
7988 basic_json_parser_63:
7990 if (m_limit <= m_cursor)
7999 goto basic_json_parser_33;
8003 goto basic_json_parser_31;
8005 goto basic_json_parser_33;
8011 goto basic_json_parser_31;
8015 goto basic_json_parser_33;
8019 goto basic_json_parser_31;
8021 goto basic_json_parser_33;
8030 if (m_stream ==
nullptr or not * m_stream)
8035 const auto offset_start = m_start - m_content;
8036 const auto offset_marker = m_marker - m_start;
8037 const auto offset_cursor = m_cursor - m_start;
8039 m_buffer.erase(0, static_cast<size_t>(offset_start));
8041 assert(m_stream !=
nullptr);
8042 std::getline(*m_stream, line);
8043 m_buffer +=
"\n" +
line;
8045 m_content =
reinterpret_cast<const lexer_char_t*
>(m_buffer.c_str());
8046 assert(m_content !=
nullptr);
8047 m_start = m_content;
8048 m_marker = m_start + offset_marker;
8049 m_cursor = m_start + offset_cursor;
8050 m_limit = m_start + m_buffer.size() - 1;
8056 assert(m_start !=
nullptr);
8057 return string_t(reinterpret_cast<typename string_t::const_pointer>(m_start),
8058 static_cast<size_t>(m_cursor - m_start));
8085 result.reserve(static_cast<size_t>(m_cursor - m_start - 2));
8088 for (
const lexer_char_t* i = m_start + 1; i < m_cursor - 1; ++i)
8144 auto codepoint = std::strtoul(std::string(reinterpret_cast<typename string_t::const_pointer>(i + 1),
8145 4).c_str(),
nullptr, 16);
8148 if (codepoint >= 0xD800 and codepoint <= 0xDBFF)
8151 if ((i + 6 >= m_limit) or * (i + 5) !=
'\\' or * (i + 6) !=
'u')
8153 throw std::invalid_argument(
"missing low surrogate");
8157 auto codepoint2 = std::strtoul(std::string(reinterpret_cast<typename string_t::const_pointer>
8158 (i + 7), 4).c_str(),
nullptr, 16);
8159 result += to_unicode(codepoint, codepoint2);
8166 result += to_unicode(codepoint);
8178 result.append(1, static_cast<typename string_t::value_type>(*i));
8207 return std::strtold(reinterpret_cast<typename string_t::const_pointer>(m_start), endptr);
8227 return std::strtod(reinterpret_cast<typename string_t::const_pointer>(m_start), endptr);
8247 return std::strtof(reinterpret_cast<typename string_t::const_pointer>(m_start), endptr);
8262 template <
typename T_A,
typename T_B>
8265 dest =
static_cast<T_B
>(source);
8266 return (source == static_cast<T_A>(dest));
8309 typename string_t::value_type* endptr;
8310 assert(m_start !=
nullptr);
8315 if (*reinterpret_cast<typename string_t::const_pointer>(m_start) !=
'-')
8319 if (attempt_cast(std::strtoull(reinterpret_cast<typename string_t::const_pointer>(m_start), &endptr,
8322 result.
m_type = value_t::number_unsigned;
8327 result.
m_type = value_t::number_float;
8334 if (attempt_cast(std::strtoll(reinterpret_cast<typename string_t::const_pointer>(m_start), &endptr,
8337 result.
m_type = value_t::number_integer;
8342 result.
m_type = value_t::number_float;
8348 if (reinterpret_cast<lexer_char_t*>(endptr) != m_cursor || errno == ERANGE)
8350 result.
m_type = value_t::number_float;
8353 if (result.
m_type == value_t::number_float)
8360 result.
m_value.
number_float = str_to_float_t(static_cast<number_float_t*>(
nullptr), &endptr);
8363 if (reinterpret_cast<lexer_char_t*>(endptr) != m_cursor)
8365 throw std::invalid_argument(std::string(
"parse error - ") + get_token() +
" is not a number");
8372 std::istream* m_stream =
nullptr;
8397 : callback(cb), m_lexer(s)
8405 : callback(cb), m_lexer(&_is)
8414 basic_json result = parse_internal(
true);
8416 expect(lexer::token_type::end_of_input);
8427 auto result = basic_json(value_t::discarded);
8431 case lexer::token_type::begin_object:
8433 if (keep and (not callback or (keep = callback(depth++, parse_event_t::object_start, result))))
8436 result.m_type = value_t::object;
8437 result.m_value =
json_value(value_t::object);
8444 if (last_token == lexer::token_type::end_object)
8447 if (keep and callback and not callback(--depth, parse_event_t::object_end, result))
8449 result = basic_json(value_t::discarded);
8455 unexpect(lexer::token_type::value_separator);
8461 if (last_token == lexer::token_type::value_separator)
8467 expect(lexer::token_type::value_string);
8468 const auto key = m_lexer.get_string();
8470 bool keep_tag =
false;
8476 keep_tag = callback(depth, parse_event_t::key, k);
8486 expect(lexer::token_type::name_separator);
8490 auto value = parse_internal(keep);
8491 if (keep and keep_tag and not value.is_discarded())
8496 while (last_token == lexer::token_type::value_separator);
8499 expect(lexer::token_type::end_object);
8501 if (keep and callback and not callback(--depth, parse_event_t::object_end, result))
8503 result = basic_json(value_t::discarded);
8509 case lexer::token_type::begin_array:
8511 if (keep and (not callback or (keep = callback(depth++, parse_event_t::array_start, result))))
8514 result.m_type = value_t::array;
8522 if (last_token == lexer::token_type::end_array)
8525 if (callback and not callback(--depth, parse_event_t::array_end, result))
8527 result = basic_json(value_t::discarded);
8533 unexpect(lexer::token_type::value_separator);
8539 if (last_token == lexer::token_type::value_separator)
8545 auto value = parse_internal(keep);
8546 if (keep and not value.is_discarded())
8551 while (last_token == lexer::token_type::value_separator);
8554 expect(lexer::token_type::end_array);
8556 if (keep and callback and not callback(--depth, parse_event_t::array_end, result))
8558 result = basic_json(value_t::discarded);
8564 case lexer::token_type::literal_null:
8567 result.m_type = value_t::null;
8571 case lexer::token_type::value_string:
8573 const auto s = m_lexer.get_string();
8575 result = basic_json(s);
8579 case lexer::token_type::literal_true:
8582 result.m_type = value_t::boolean;
8583 result.m_value =
true;
8587 case lexer::token_type::literal_false:
8590 result.m_type = value_t::boolean;
8591 result.m_value =
false;
8595 case lexer::token_type::value_number:
8597 m_lexer.get_number(result);
8605 unexpect(last_token);
8611 result = basic_json(value_t::discarded);
8619 last_token = m_lexer.scan();
8625 if (t != last_token)
8627 std::string error_msg =
"parse error - unexpected ";
8628 error_msg += (last_token == lexer::token_type::parse_error ? (
"'" + m_lexer.get_token() +
"'") :
8629 lexer::token_type_name(last_token));
8630 error_msg +=
"; expected " + lexer::token_type_name(t);
8631 throw std::invalid_argument(error_msg);
8637 if (t == last_token)
8639 std::string error_msg =
"parse error - unexpected ";
8640 error_msg += (last_token == lexer::token_type::parse_error ? (
"'" + m_lexer.get_token() +
"'") :
8641 lexer::token_type_name(last_token));
8642 throw std::invalid_argument(error_msg);
8709 const auto& h = hash<nlohmann::json::string_t>();
8733 #if defined(__clang__) || defined(__GNUC__) || defined(__GNUG__) 8734 #pragma GCC diagnostic pop const_iterator & operator+=(difference_type i)
add to iterator
json_value(const object_t &value)
constructor for objects
iterator operator++(int)
post-increment (it++)
iteration_proxy_internal end() noexcept
return iterator end (needed for range-based for)
reference operator[](difference_type n) const
access to successor
reference at(const typename object_t::key_type &key)
access specified object element with bounds checking
iterator & operator+=(difference_type i)
add to iterator
bool operator>=(const const_iterator &other) const
comparison: greater than or equal
json_reverse_iterator & operator--()
pre-decrement (–it)
void swap(string_t &other)
exchanges the values
json_value(const array_t &value)
constructor for arrays
const_iterator end() const noexcept
returns a const iterator to one past the last element
size_type max_size() const noexcept
returns the maximum possible number of elements
object_t::iterator object_iterator
iterator for JSON objects
const value_type & const_reference
the type of an element const reference
iterator insert(const_iterator pos, const_iterator first, const_iterator last)
inserts elements
typename basic_json::difference_type difference_type
a type to represent differences between iterators
std::bidirectional_iterator_tag iterator_category
the category of the iterator
bool operator>(const const_iterator &other) const
comparison: greater than
difference_type operator-(const json_reverse_iterator &other) const
return difference
constexpr bool is_structured() const noexcept
return whether type is structured
json_reverse_iterator operator--(int)
post-decrement (it–)
iterator insert(const_iterator pos, const basic_json &val)
inserts element
number_integer_t number_integer
number (integer)
reference operator[](difference_type n) const
access to successor
friend bool operator<(const_reference lhs, const_reference rhs) noexcept
comparison: less than
string_t value(const typename object_t::key_type &key, const char *default_value) const
overload for a default value of type const char*
std::ptrdiff_t difference_type
a type to represent differences between iterators
an iterator for primitive JSON types
json_reverse_iterator(const base_iterator &it) noexcept
create reverse iterator from base class
double str_to_float_t(double *, char **endptr) const
parse floating point number
iterator & operator--()
pre-decrement (–it)
string_t type_name() const noexcept
return the type as string
json_value(const string_t &value)
constructor for strings
const_iterator(pointer object) noexcept
constructor for a given JSON instance
const_reference front() const
access the first element
constexpr bool is_primitive() const noexcept
return whether type is primitive
number_float_t number_float
number (floating-point)
ValueType get() const
get a value (explicit)
basic_json(std::nullptr_t) noexcept
create a null object (explicitly)
pointer operator->()
dereference the iterator
AllocatorType< basic_json > allocator_type
the allocator type
void push_back(const basic_json &val)
add an object to an array
basic_json(const number_float_t val) noexcept
create a floating-point number (explicit)
iteration_proxy_internal & operator++()
increment operator (needed for range-based for)
const_reference back() const
access the last element
constexpr const object_t * get_impl_ptr(const object_t *) const noexcept
get a pointer to the value (object)
helper class for iteration
const_iterator cend() const noexcept
returns a const iterator to one past the last element
string_t * string
string (stored with pointer to save storage)
a class to store JSON values
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 >::value andstd::is_nothrow_move_assignable< internal_iterator >::value)
copy assignment
basic_json(const CompatibleStringType &val)
create a string (implicit)
static std::string token_type_name(token_type t)
return name of values of type token_type (only used for errors)
basic_json(InputIT first, InputIT last)
construct a JSON container given an iterator range
basic_json(std::istream &i, parser_callback_t cb=nullptr)
construct a JSON value given an input stream
constexpr bool is_discarded() const noexcept
return whether value is discarded
iteration_proxy_internal begin() noexcept
return iterator begin (needed for range-based for)
constexpr const PointerType get_ptr() const noexcept
get a pointer value (implicit)
object_t * get_impl_ptr(object_t *) noexcept
get a pointer to the value (object)
friend std::ostream & operator<<(std::ostream &o, const basic_json &j)
serialize to stream
constexpr bool is_number_unsigned() const noexcept
return whether value is an unsigned integer number
InteratorType erase(InteratorType pos)
remove element given an iterator
iterator(pointer object) noexcept
constructor for a given JSON instance
a mutable random access iterator for the basic_json class
constexpr bool is_object() const noexcept
return whether value is an object
PointerType get_ptr() noexcept
get a pointer value (implicit)
object_t get_impl(object_t *) const
get an object (explicit)
ObjectType< StringType, basic_json, std::less< StringType >, AllocatorType< std::pair< const StringType, basic_json >>> object_t
a type for an object
iterator & operator-=(difference_type i)
subtract from iterator
const_iterator & operator-=(difference_type i)
subtract from iterator
static bool attempt_cast(T_A source, T_B &dest)
static_cast between two types and indicate if it results in error
size_type size() const noexcept
returns the number of elements
const_reference operator[](const typename object_t::key_type &key) const
read-only access specified object element
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
static allocator_type get_allocator()
returns the allocator associated with the container
constexpr bool is_array() const noexcept
return whether value is an array
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 >::value andstd::is_nothrow_move_assignable< internal_iterator >::value)
copy assignment
pointer operator->() const
dereference the iterator
const_iterator operator-(difference_type i)
subtract from iterator
basic_json(const CompatibleObjectType &val)
create an object (implicit)
json_value(boolean_t v) noexcept
constructor for booleans
number_integer_t * get_impl_ptr(number_integer_t *) noexcept
get a pointer to the value (integer number)
basic_json(const CompatibleNumberFloatType val) noexcept
create an floating-point number (implicit)
string_t get_token() const
return string representation of last read token
internal_iterator m_it
the actual iterator of the associated instance
friend bool operator==(const_reference v, std::nullptr_t) noexcept
comparison: equal
boolean_t * get_impl_ptr(boolean_t *) noexcept
get a pointer to the value (boolean)
IteratorType::reference value() const
return value of the 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
lexer(std::istream *s) noexcept
constructor with a given stream
std::string to_string(const T &value)
reference value() const
return the value of an iterator
iterator end() noexcept
returns an iterator to one past the last element
const_iterator operator--(int)
post-decrement (it–)
basic_json(const int val) noexcept
create an integer number from an enum type (explicit)
basic_json(const CompatibleArrayType &val)
create an array (implicit)
reference back()
access the last element
reverse_iterator rend() noexcept
returns an iterator to the reverse-end
ValueType value(const typename object_t::key_type &key, ValueType default_value) const
access specified object element with default value
json_value(number_unsigned_t v) noexcept
constructor for numbers (unsigned)
reference operator[](difference_type n) const
access to successor
json_reverse_iterator(const typename base_iterator::iterator_type &it) noexcept
create reverse iterator from iterator
static basic_json object(std::initializer_list< basic_json > init=std::initializer_list< basic_json >())
explicitly create an object from an initializer list
constexpr const number_float_t * get_impl_ptr(const number_float_t *) const noexcept
get a pointer to the value (floating-point number)
reference operator+=(const basic_json &val)
add an object to an array
static iteration_proxy< const_iterator > iterator_wrapper(const_reference cont)
wrapper to access iterator member functions in range-based for
NumberFloatType number_float_t
a type for a number (floating-point)
void set_end() noexcept
set iterator to a defined past the end
string_t m_buffer
the buffer
json_reverse_iterator operator+(difference_type i) const
add to iterator
constexpr const array_t * get_impl_ptr(const array_t *) const noexcept
get a pointer to the value (array)
static constexpr bool value
typename basic_json::const_pointer pointer
defines a pointer to the type iterated over (value_type)
basic_json(const value_t value_type)
create an empty value with a given type
const_reference at(const typename object_t::key_type &key) const
access specified object element with bounds checking
number_float_t * get_impl_ptr(number_float_t *) noexcept
get a pointer to the value (floating-point number)
UnitSI operator*(const UnitSI &a, const UnitSI &b)
Product of two units.
string_t get_string() const
return string value for string tokens
constexpr const number_unsigned_t * get_impl_ptr(const number_unsigned_t *) const noexcept
get a pointer to the value (unsigned number)
json_reverse_iterator & operator+=(difference_type i)
add to iterator
const_reverse_iterator rend() const noexcept
returns a const reverse iterator to one before the first
static T * create(Args &&...args)
helper for exception-safe object creation
bool operator==(const Null &, const Null &)
number_unsigned_t number_unsigned
number (unsigned integer)
const_iterator find(typename object_t::key_type key) const
find an element in a JSON object
basic_json(const object_t &val)
create an object (explicit)
fmt::BufferedFile & move(fmt::BufferedFile &f)
std::size_t operator()(const nlohmann::json &j) const
return a hash value for a JSON object
parser_callback_t callback
callback function
reverse_iterator rbegin() noexcept
returns an iterator to the reverse-beginning
basic_json(const string_t &val)
create a string (explicit)
basic_json::string_t key() const
return key of the iterator
lexer::token_type get_token() noexcept
get next token from lexer
unsigned char lexer_char_t
the char type to use in the lexer
static std::size_t extra_space(const string_t &s) noexcept
calculates the extra space to escape a JSON string
iterator find(typename object_t::key_type key)
find an element in a JSON object
constexpr bool is_number() const noexcept
return whether value is a number
iteration_proxy_internal & operator*()
dereference operator (needed for range-based for)
array_t get_impl(array_t *) const
get an array (explicit)
void set_begin() noexcept
set iterator to a defined beginning
array_t * get_impl_ptr(array_t *) noexcept
get a pointer to the value (array)
difference_type operator-(const const_iterator &other) const
return difference
parser(std::istream &_is, parser_callback_t cb=nullptr) noexcept
a parser reading from an input stream
parser(const string_t &s, parser_callback_t cb=nullptr) noexcept
constructor for strings
void swap(object_t &other)
exchanges the values
BooleanType boolean_t
a type for a boolean
reference operator[](T *(&key)[n])
access specified object element
const_iterator(const iterator &other) noexcept
copy constructor given a nonconst iterator
void unexpect(typename lexer::token_type t) const
string_t * get_impl_ptr(string_t *) noexcept
get a pointer to the value (string)
token_type scan() noexcept
array_t::iterator array_iterator
iterator for JSON arrays
json_reverse_iterator & operator++()
pre-increment (++it)
namespace for Niels Lohmann
parse_event_t
JSON callback events.
constexpr bool is_end() const noexcept
return whether the iterator is at end
constexpr value_t type() const noexcept
return the type of the JSON value (explicit)
static basic_json parse(std::istream &&i, parser_callback_t cb=nullptr)
deserialize from stream
basic_json(size_type cnt, const basic_json &val)
construct an array with count copies of given value
const_reverse_iterator crend() const noexcept
returns a const reverse iterator to one before the first
constexpr const number_integer_t * get_impl_ptr(const number_integer_t *) const noexcept
get a pointer to the value (integer number)
std::function< bool(int depth, parse_event_t event, basic_json &parsed)> parser_callback_t
per-element parser callback type
const_iterator & operator--()
pre-decrement (–it)
internal_iterator() noexcept
create an uninitialized internal_iterator
constexpr bool is_string() const noexcept
return whether value is a string
json_reverse_iterator operator-(difference_type i) const
subtract from iterator
basic_json value_type
the type of elements in a basic_json container
basic_json(boolean_t val) noexcept
create a boolean (explicit)
IteratorType anchor
the iterator
json_value(value_t t)
constructor for empty values of a given type
basic_json(basic_json &&other) noexcept
move constructor
static basic_json array(std::initializer_list< basic_json > init=std::initializer_list< basic_json >())
explicitly create an array from an initializer list
friend std::istream & operator>>(std::istream &i, basic_json &j)
deserialize from stream
basic_json(const typename string_t::value_type *val)
create a string (explicit)
object_t::key_type key() const
return the key of an object iterator
friend bool operator==(const_reference lhs, const_reference rhs) noexcept
comparison: equal
std::vector< T > get_impl(std::vector< T > *) const
get an array (explicit)
const_reference at(size_type idx) const
access specified array element with bounds checking
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
reference operator+=(const typename object_t::value_type &val)
add an object to an object
std::size_t size_type
a type to represent container sizes
reference value() const
return the value of an iterator
static iteration_proxy< iterator > iterator_wrapper(reference cont)
wrapper to access iterator member functions in range-based for
reference operator+=(basic_json &&val)
add an object to an array
bool operator!=(const const_iterator &other) const
comparison: not equal
json_value m_value
the value of the current element
void dump(std::ostream &o, const bool pretty_print, const unsigned int indent_step, const unsigned int current_indent=0) const
internal implementation of the serialization function
reference operator[](size_type idx)
access specified array element
const_iterator begin() const noexcept
returns a const iterator to the first element
friend bool operator!=(const_reference v, std::nullptr_t) noexcept
comparison: not equal
primitive_iterator_t primitive_iterator
generic iterator for all other types
typename basic_json::value_type value_type
the type of the values when the iterator is dereferenced
const_reverse_iterator crbegin() const noexcept
returns a const reverse iterator to the last element
constexpr bool is_number_float() const noexcept
return whether value is a floating-point number
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
const_iterator cbegin() const noexcept
returns a const iterator to the first element
pointer m_object
associated JSON instance
token_type
token types for the parser
array (ordered collection of values)
constexpr bool is_number_integer() const noexcept
return whether value is an integer number
value_t m_type
the type of the current element
basic_json(const CompatibleNumberUnsignedType val) noexcept
create an unsigned number (implicit)
json_reverse_iterator operator++(int)
post-increment (it++)
constexpr bool is_boolean() const noexcept
return whether value is a boolean
void push_back(basic_json &&val)
add an object to an array
typename std::allocator_traits< allocator_type >::const_pointer const_pointer
the type of an element const pointer
ReferenceType get_ref()
get a reference value (implicit)
friend bool operator>(const_reference lhs, const_reference rhs) noexcept
comparison: greater than
const_reverse_iterator rbegin() const noexcept
returns a const reverse iterator to the last element
NumberIntegerType number_integer_t
a type for a number (integer)
iterator operator--(int)
post-decrement (it–)
reference operator*() const
return a reference to the value pointed to by the iterator
basic_json(const number_unsigned_t val) noexcept
create an unsigned integer number (explicit)
iterator insert(const_iterator pos, basic_json &&val)
inserts element
bool empty() const noexcept
checks whether the container is empty
basic_json(const number_integer_t val) noexcept
create an integer number (explicit)
bool operator==(const const_iterator &other) const
comparison: equal
constexpr bool is_null() const noexcept
return whether value is null
static ReferenceType get_ref_impl(ThisType &obj)
helper function to implement get_ref()
size_type count(typename object_t::key_type key) const
returns the number of occurrences of a key in a JSON object
iterator operator+(difference_type i)
add to iterator
difference_type operator-(const iterator &other) const
return difference
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
void get_number(basic_json &result) const
return number value for number tokens
const_reference operator[](T *key) const
read-only access specified object element
typename std::allocator_traits< allocator_type >::pointer pointer
the type of an element pointer
proxy class for the iterator_wrapper functions
value_t
the JSON type enumeration
reference value() const
return the value of an iterator
basic_json parse_internal(bool keep)
the actual parser
iterator & operator++()
pre-increment (++it)
reference at(size_type idx)
access specified array element with bounds checking
static string_t escape_string(const string_t &s)
escape a string
constexpr boolean_t get_impl(boolean_t *) const
get a boolean (explicit)
basic_json(const CompatibleNumberIntegerType val) noexcept
create an integer number (implicit)
void push_back(const typename object_t::value_type &val)
add an object to an object
string_t dump(const int indent=-1) const
serialization
void expect(typename lexer::token_type t) const
iterator operator-(difference_type i)
subtract from iterator
object (unordered set of name/value pairs)
IteratorType::reference container
the container to iterate
ReferenceType get_ref() const
get a reference value (implicit)
friend bool operator<(const value_t lhs, const value_t rhs) noexcept
comparison operator for JSON types
const_iterator & operator++()
pre-increment (++it)
basic_json(const array_t &val)
create an array (explicit)
iteration_proxy(typename IteratorType::reference cont)
construct iteration proxy from a container
reference operator*()
return a reference to the value pointed to by the iterator
typename basic_json::const_reference reference
defines a reference to the type iterated over (value_type)
iterator(const iterator &other) noexcept
copy constructor
object_t * object
object (stored with pointer to save storage)
void yyfill() noexcept
append data from the stream to the internal buffer
const_reference operator[](T *(&key)[n]) const
read-only access specified object element
iterator insert(const_iterator pos, std::initializer_list< basic_json > ilist)
inserts elements
json_value(number_integer_t v) noexcept
constructor for numbers (integer)
number_unsigned_t * get_impl_ptr(number_unsigned_t *) noexcept
get a pointer to the value (unsigned number)
size_type erase(const typename object_t::key_type &key)
remove element from a JSON object given a key
void erase(const size_type idx)
remove element from a JSON array given an index
static string_t to_unicode(const std::size_t codepoint1, const std::size_t codepoint2=0)
create a string from a Unicode code point
void clear() noexcept
clears the contents
a const random access iterator for the basic_json class
a template for a reverse iterator class
NumberUnsignedType number_unsigned_t
a type for a number (unsigned)
T get_impl(T *) const
get an object (explicit)
long double str_to_float_t(long double *, char **endptr) const
parse floating point number
object_t::key_type key() const
return the key of an object iterator
std::reverse_iterator< Base > base_iterator
shortcut to the reverse iterator adaptor
iteration_proxy_internal(IteratorType it) noexcept
const_iterator operator++(int)
post-increment (it++)
reference operator[](T *key)
access specified object element
lexer(const string_t &s) noexcept
constructor with a given buffer
friend bool operator!=(std::nullptr_t, const_reference v) noexcept
comparison: not equal
bool operator<=(const const_iterator &other) const
comparison: less than or equal
typename Base::reference reference
the reference type for the pointed-to element
friend bool operator<=(const_reference lhs, const_reference rhs) noexcept
comparison: less than or equal
bool operator<(const const_iterator &other) const
comparison: smaller
void set_begin() noexcept
set the iterator to the first value
friend bool operator>=(const_reference lhs, const_reference rhs) noexcept
comparison: greater than or equal
const_iterator operator+(difference_type i)
add to iterator
static basic_json parse(std::istream &i, parser_callback_t cb=nullptr)
deserialize from stream
friend bool operator!=(const_reference lhs, const_reference rhs) noexcept
comparison: not equal
basic_json parse()
public parser interface
iterator begin() noexcept
returns an iterator to the first element
InteratorType erase(InteratorType first, InteratorType last)
remove elements given an iterator range
float str_to_float_t(float *, char **endptr) const
parse floating point number
constexpr const string_t * get_impl_ptr(const string_t *) const noexcept
get a pointer to the value (string)
StringType string_t
a type for a string
constexpr const boolean_t * get_impl_ptr(const boolean_t *) const noexcept
get a pointer to the value (boolean)
bool operator<(IntersectionResult a, IntersectionResult b)
reference front()
access the first element
iterator insert(const_iterator pos, size_type cnt, const basic_json &val)
inserts elements
friend bool operator==(std::nullptr_t, const_reference v) noexcept
comparison: equal
void set_end() noexcept
set the iterator past the last value
value_type & reference
the type of an element reference
basic_json(const basic_json &other)
copy constructor
ArrayType< basic_json, AllocatorType< basic_json >> array_t
a type for an array
const_reference operator[](size_type idx) const
access specified array element
json_value(number_float_t v) noexcept
constructor for numbers (floating-point)
static basic_json parse(const string_t &s, parser_callback_t cb=nullptr)
deserialize from string
constexpr bool is_begin() const noexcept
return whether the iterator can be dereferenced
array_t * array
array (stored with pointer to save storage)
const_iterator(const const_iterator &other) noexcept
copy constructor
void swap(array_t &other)
exchanges the values
reference operator[](const typename object_t::key_type &key)
access specified object element