5177 using number_integer_t =
typename BasicJsonType::number_integer_t;
5178 using number_unsigned_t =
typename BasicJsonType::number_unsigned_t;
5179 using number_float_t =
typename BasicJsonType::number_float_t;
5180 using string_t =
typename BasicJsonType::string_t;
5181 using json_sax_t = SAX;
5209 JSON_HEDLEY_NON_NULL(3)
5212 const
bool strict = true)
5215 bool result =
false;
5219 case input_format_t::bson:
5220 result = parse_bson_internal();
5223 case input_format_t::cbor:
5224 result = parse_cbor_internal();
5227 case input_format_t::msgpack:
5228 result = parse_msgpack_internal();
5231 case input_format_t::ubjson:
5232 result = parse_ubjson_internal();
5242 if (format == input_format_t::ubjson)
5251 if (JSON_HEDLEY_UNLIKELY(current != std::char_traits<char>::eof()))
5253 return sax->parse_error(chars_read, get_token_string(),
5254 parse_error::create(110, chars_read, exception_message(format,
"expected end of input; last byte: 0x" + get_token_string(),
"value")));
5270 return *
reinterpret_cast<char*
>(&num) == 1;
5282 bool parse_bson_internal()
5284 std::int32_t document_size;
5285 get_number<std::int32_t, true>(input_format_t::bson, document_size);
5287 if (JSON_HEDLEY_UNLIKELY(not sax->start_object(std::size_t(-1))))
5292 if (JSON_HEDLEY_UNLIKELY(not parse_bson_element_list(
false)))
5297 return sax->end_object();
5307 bool get_bson_cstr(string_t& result)
5309 auto out = std::back_inserter(result);
5313 if (JSON_HEDLEY_UNLIKELY(not unexpect_eof(input_format_t::bson,
"cstring")))
5317 if (current == 0x00)
5321 *out++ =
static_cast<char>(current);
5338 template<
typename NumberType>
5339 bool get_bson_string(
const NumberType len, string_t& result)
5341 if (JSON_HEDLEY_UNLIKELY(len < 1))
5343 auto last_token = get_token_string();
5344 return sax->parse_error(chars_read, last_token,
parse_error::create(112, chars_read, exception_message(input_format_t::bson,
"string length must be at least 1, is " + std::to_string(len),
"string")));
5347 return get_string(input_format_t::bson, len -
static_cast<NumberType
>(1), result) and get() != std::char_traits<char>::eof();
5360 bool parse_bson_element_internal(
const int element_type,
5361 const std::size_t element_type_parse_position)
5363 switch (element_type)
5368 return get_number<double, true>(input_format_t::bson, number) and sax->number_float(
static_cast<number_float_t
>(number),
"");
5375 return get_number<std::int32_t, true>(input_format_t::bson, len) and get_bson_string(len, value) and sax->string(value);
5380 return parse_bson_internal();
5385 return parse_bson_array();
5390 return sax->boolean(get() != 0);
5401 return get_number<std::int32_t, true>(input_format_t::bson, value) and sax->number_integer(value);
5407 return get_number<std::int64_t, true>(input_format_t::bson, value) and sax->number_integer(value);
5412 std::array<char, 3> cr{{}};
5413 (std::snprintf)(cr.data(), cr.size(),
"%.2hhX",
static_cast<unsigned char>(element_type));
5414 return sax->parse_error(element_type_parse_position, std::string(cr.data()),
parse_error::create(114, element_type_parse_position,
"Unsupported BSON record type 0x" + std::string(cr.data())));
5431 bool parse_bson_element_list(
const bool is_array)
5434 while (
int element_type = get())
5436 if (JSON_HEDLEY_UNLIKELY(not unexpect_eof(input_format_t::bson,
"element list")))
5441 const std::size_t element_type_parse_position = chars_read;
5442 if (JSON_HEDLEY_UNLIKELY(not get_bson_cstr(key)))
5447 if (not is_array and not sax->key(key))
5452 if (JSON_HEDLEY_UNLIKELY(not parse_bson_element_internal(element_type, element_type_parse_position)))
5468 bool parse_bson_array()
5470 std::int32_t document_size;
5471 get_number<std::int32_t, true>(input_format_t::bson, document_size);
5473 if (JSON_HEDLEY_UNLIKELY(not sax->start_array(std::size_t(-1))))
5478 if (JSON_HEDLEY_UNLIKELY(not parse_bson_element_list(
true)))
5483 return sax->end_array();
5497 bool parse_cbor_internal(
const bool get_char =
true)
5499 switch (get_char ? get() : current)
5502 case std::char_traits<char>::eof():
5530 return sax->number_unsigned(
static_cast<number_unsigned_t
>(current));
5534 std::uint8_t number;
5535 return get_number(input_format_t::cbor, number) and sax->number_unsigned(number);
5540 std::uint16_t number;
5541 return get_number(input_format_t::cbor, number) and sax->number_unsigned(number);
5546 std::uint32_t number;
5547 return get_number(input_format_t::cbor, number) and sax->number_unsigned(number);
5552 std::uint64_t number;
5553 return get_number(input_format_t::cbor, number) and sax->number_unsigned(number);
5581 return sax->number_integer(
static_cast<std::int8_t
>(0x20 - 1 - current));
5585 std::uint8_t number;
5586 return get_number(input_format_t::cbor, number) and sax->number_integer(
static_cast<number_integer_t
>(-1) - number);
5591 std::uint16_t number;
5592 return get_number(input_format_t::cbor, number) and sax->number_integer(
static_cast<number_integer_t
>(-1) - number);
5597 std::uint32_t number;
5598 return get_number(input_format_t::cbor, number) and sax->number_integer(
static_cast<number_integer_t
>(-1) - number);
5603 std::uint64_t number;
5604 return get_number(input_format_t::cbor, number) and sax->number_integer(
static_cast<number_integer_t
>(-1)
5605 -
static_cast<number_integer_t
>(number));
5640 return get_cbor_string(s) and sax->string(s);
5668 return get_cbor_array(
static_cast<std::size_t
>(
static_cast<unsigned int>(current) & 0x1Fu));
5673 return get_number(input_format_t::cbor, len) and get_cbor_array(
static_cast<std::size_t
>(len));
5679 return get_number(input_format_t::cbor, len) and get_cbor_array(
static_cast<std::size_t
>(len));
5685 return get_number(input_format_t::cbor, len) and get_cbor_array(
static_cast<std::size_t
>(len));
5691 return get_number(input_format_t::cbor, len) and get_cbor_array(
static_cast<std::size_t
>(len));
5695 return get_cbor_array(std::size_t(-1));
5722 return get_cbor_object(
static_cast<std::size_t
>(
static_cast<unsigned int>(current) & 0x1Fu));
5727 return get_number(input_format_t::cbor, len) and get_cbor_object(
static_cast<std::size_t
>(len));
5733 return get_number(input_format_t::cbor, len) and get_cbor_object(
static_cast<std::size_t
>(len));
5739 return get_number(input_format_t::cbor, len) and get_cbor_object(
static_cast<std::size_t
>(len));
5745 return get_number(input_format_t::cbor, len) and get_cbor_object(
static_cast<std::size_t
>(len));
5749 return get_cbor_object(std::size_t(-1));
5752 return sax->boolean(
false);
5755 return sax->boolean(
true);
5762 const int byte1_raw = get();
5763 if (JSON_HEDLEY_UNLIKELY(not unexpect_eof(input_format_t::cbor,
"number")))
5767 const int byte2_raw = get();
5768 if (JSON_HEDLEY_UNLIKELY(not unexpect_eof(input_format_t::cbor,
"number")))
5773 const auto byte1 =
static_cast<unsigned char>(byte1_raw);
5774 const auto byte2 =
static_cast<unsigned char>(byte2_raw);
5784 const auto half =
static_cast<unsigned int>((byte1 << 8u) + byte2);
5785 const double val = [&half]
5787 const int exp = (half >> 10u) & 0x1Fu;
5788 const unsigned int mant = half & 0x3FFu;
5789 assert(0 <= exp and exp <= 32);
5790 assert(mant <= 1024);
5794 return std::ldexp(mant, -24);
5797 ? std::numeric_limits<double>::infinity()
5798 : std::numeric_limits<double>::quiet_NaN();
5800 return std::ldexp(mant + 1024, exp - 25);
5803 return sax->number_float((half & 0x8000u) != 0
5804 ?
static_cast<number_float_t
>(-val)
5805 :
static_cast<number_float_t
>(val),
"");
5811 return get_number(input_format_t::cbor, number) and sax->number_float(
static_cast<number_float_t
>(number),
"");
5817 return get_number(input_format_t::cbor, number) and sax->number_float(
static_cast<number_float_t
>(number),
"");
5822 auto last_token = get_token_string();
5823 return sax->parse_error(chars_read, last_token,
parse_error::create(112, chars_read, exception_message(input_format_t::cbor,
"invalid byte: 0x" + last_token,
"value")));
5839 bool get_cbor_string(string_t& result)
5841 if (JSON_HEDLEY_UNLIKELY(not unexpect_eof(input_format_t::cbor,
"string")))
5874 return get_string(input_format_t::cbor,
static_cast<unsigned int>(current) & 0x1Fu, result);
5880 return get_number(input_format_t::cbor, len) and get_string(input_format_t::cbor, len, result);
5886 return get_number(input_format_t::cbor, len) and get_string(input_format_t::cbor, len, result);
5892 return get_number(input_format_t::cbor, len) and get_string(input_format_t::cbor, len, result);
5898 return get_number(input_format_t::cbor, len) and get_string(input_format_t::cbor, len, result);
5903 while (get() != 0xFF)
5906 if (not get_cbor_string(chunk))
5910 result.append(chunk);
5917 auto last_token = get_token_string();
5918 return sax->parse_error(chars_read, last_token,
parse_error::create(113, chars_read, exception_message(input_format_t::cbor,
"expected length specification (0x60-0x7B) or indefinite string type (0x7F); last byte: 0x" + last_token,
"string")));
5928 bool get_cbor_array(
const std::size_t len)
5930 if (JSON_HEDLEY_UNLIKELY(not sax->start_array(len)))
5935 if (len != std::size_t(-1))
5937 for (std::size_t i = 0; i < len; ++i)
5939 if (JSON_HEDLEY_UNLIKELY(not parse_cbor_internal()))
5947 while (get() != 0xFF)
5949 if (JSON_HEDLEY_UNLIKELY(not parse_cbor_internal(
false)))
5956 return sax->end_array();
5964 bool get_cbor_object(
const std::size_t len)
5966 if (JSON_HEDLEY_UNLIKELY(not sax->start_object(len)))
5972 if (len != std::size_t(-1))
5974 for (std::size_t i = 0; i < len; ++i)
5977 if (JSON_HEDLEY_UNLIKELY(not get_cbor_string(key) or not sax->key(key)))
5982 if (JSON_HEDLEY_UNLIKELY(not parse_cbor_internal()))
5991 while (get() != 0xFF)
5993 if (JSON_HEDLEY_UNLIKELY(not get_cbor_string(key) or not sax->key(key)))
5998 if (JSON_HEDLEY_UNLIKELY(not parse_cbor_internal()))
6006 return sax->end_object();
6016 bool parse_msgpack_internal()
6021 case std::char_traits<char>::eof():
6153 return sax->number_unsigned(
static_cast<number_unsigned_t
>(current));
6172 return get_msgpack_object(
static_cast<std::size_t
>(
static_cast<unsigned int>(current) & 0x0Fu));
6191 return get_msgpack_array(
static_cast<std::size_t
>(
static_cast<unsigned int>(current) & 0x0Fu));
6231 return get_msgpack_string(s) and sax->string(s);
6238 return sax->boolean(
false);
6241 return sax->boolean(
true);
6246 return get_number(input_format_t::msgpack, number) and sax->number_float(
static_cast<number_float_t
>(number),
"");
6252 return get_number(input_format_t::msgpack, number) and sax->number_float(
static_cast<number_float_t
>(number),
"");
6257 std::uint8_t number;
6258 return get_number(input_format_t::msgpack, number) and sax->number_unsigned(number);
6263 std::uint16_t number;
6264 return get_number(input_format_t::msgpack, number) and sax->number_unsigned(number);
6269 std::uint32_t number;
6270 return get_number(input_format_t::msgpack, number) and sax->number_unsigned(number);
6275 std::uint64_t number;
6276 return get_number(input_format_t::msgpack, number) and sax->number_unsigned(number);
6282 return get_number(input_format_t::msgpack, number) and sax->number_integer(number);
6287 std::int16_t number;
6288 return get_number(input_format_t::msgpack, number) and sax->number_integer(number);
6293 std::int32_t number;
6294 return get_number(input_format_t::msgpack, number) and sax->number_integer(number);
6299 std::int64_t number;
6300 return get_number(input_format_t::msgpack, number) and sax->number_integer(number);
6306 return get_number(input_format_t::msgpack, len) and get_msgpack_array(
static_cast<std::size_t
>(len));
6312 return get_number(input_format_t::msgpack, len) and get_msgpack_array(
static_cast<std::size_t
>(len));
6318 return get_number(input_format_t::msgpack, len) and get_msgpack_object(
static_cast<std::size_t
>(len));
6324 return get_number(input_format_t::msgpack, len) and get_msgpack_object(
static_cast<std::size_t
>(len));
6360 return sax->number_integer(
static_cast<std::int8_t
>(current));
6364 auto last_token = get_token_string();
6365 return sax->parse_error(chars_read, last_token,
parse_error::create(112, chars_read, exception_message(input_format_t::msgpack,
"invalid byte: 0x" + last_token,
"value")));
6380 bool get_msgpack_string(string_t& result)
6382 if (JSON_HEDLEY_UNLIKELY(not unexpect_eof(input_format_t::msgpack,
"string")))
6423 return get_string(input_format_t::msgpack,
static_cast<unsigned int>(current) & 0x1Fu, result);
6429 return get_number(input_format_t::msgpack, len) and get_string(input_format_t::msgpack, len, result);
6435 return get_number(input_format_t::msgpack, len) and get_string(input_format_t::msgpack, len, result);
6441 return get_number(input_format_t::msgpack, len) and get_string(input_format_t::msgpack, len, result);
6446 auto last_token = get_token_string();
6447 return sax->parse_error(chars_read, last_token,
parse_error::create(113, chars_read, exception_message(input_format_t::msgpack,
"expected length specification (0xA0-0xBF, 0xD9-0xDB); last byte: 0x" + last_token,
"string")));
6456 bool get_msgpack_array(
const std::size_t len)
6458 if (JSON_HEDLEY_UNLIKELY(not sax->start_array(len)))
6463 for (std::size_t i = 0; i < len; ++i)
6465 if (JSON_HEDLEY_UNLIKELY(not parse_msgpack_internal()))
6471 return sax->end_array();
6478 bool get_msgpack_object(
const std::size_t len)
6480 if (JSON_HEDLEY_UNLIKELY(not sax->start_object(len)))
6486 for (std::size_t i = 0; i < len; ++i)
6489 if (JSON_HEDLEY_UNLIKELY(not get_msgpack_string(key) or not sax->key(key)))
6494 if (JSON_HEDLEY_UNLIKELY(not parse_msgpack_internal()))
6501 return sax->end_object();
6515 bool parse_ubjson_internal(
const bool get_char =
true)
6517 return get_ubjson_value(get_char ? get_ignore_noop() : current);
6534 bool get_ubjson_string(string_t& result,
const bool get_char =
true)
6541 if (JSON_HEDLEY_UNLIKELY(not unexpect_eof(input_format_t::ubjson,
"value")))
6551 return get_number(input_format_t::ubjson, len) and get_string(input_format_t::ubjson, len, result);
6557 return get_number(input_format_t::ubjson, len) and get_string(input_format_t::ubjson, len, result);
6563 return get_number(input_format_t::ubjson, len) and get_string(input_format_t::ubjson, len, result);
6569 return get_number(input_format_t::ubjson, len) and get_string(input_format_t::ubjson, len, result);
6575 return get_number(input_format_t::ubjson, len) and get_string(input_format_t::ubjson, len, result);
6579 auto last_token = get_token_string();
6580 return sax->parse_error(chars_read, last_token,
parse_error::create(113, chars_read, exception_message(input_format_t::ubjson,
"expected length type specification (U, i, I, l, L); last byte: 0x" + last_token,
"string")));
6588 bool get_ubjson_size_value(std::size_t& result)
6590 switch (get_ignore_noop())
6594 std::uint8_t number;
6595 if (JSON_HEDLEY_UNLIKELY(not get_number(input_format_t::ubjson, number)))
6599 result =
static_cast<std::size_t
>(number);
6606 if (JSON_HEDLEY_UNLIKELY(not get_number(input_format_t::ubjson, number)))
6610 result =
static_cast<std::size_t
>(number);
6616 std::int16_t number;
6617 if (JSON_HEDLEY_UNLIKELY(not get_number(input_format_t::ubjson, number)))
6621 result =
static_cast<std::size_t
>(number);
6627 std::int32_t number;
6628 if (JSON_HEDLEY_UNLIKELY(not get_number(input_format_t::ubjson, number)))
6632 result =
static_cast<std::size_t
>(number);
6638 std::int64_t number;
6639 if (JSON_HEDLEY_UNLIKELY(not get_number(input_format_t::ubjson, number)))
6643 result =
static_cast<std::size_t
>(number);
6649 auto last_token = get_token_string();
6650 return sax->parse_error(chars_read, last_token,
parse_error::create(113, chars_read, exception_message(input_format_t::ubjson,
"expected length type specification (U, i, I, l, L) after '#'; last byte: 0x" + last_token,
"size")));
6665 bool get_ubjson_size_type(std::pair<std::size_t, int>& result)
6667 result.first = string_t::npos;
6674 result.second = get();
6675 if (JSON_HEDLEY_UNLIKELY(not unexpect_eof(input_format_t::ubjson,
"type")))
6681 if (JSON_HEDLEY_UNLIKELY(current !=
'#'))
6683 if (JSON_HEDLEY_UNLIKELY(not unexpect_eof(input_format_t::ubjson,
"value")))
6687 auto last_token = get_token_string();
6688 return sax->parse_error(chars_read, last_token,
parse_error::create(112, chars_read, exception_message(input_format_t::ubjson,
"expected '#' after type information; last byte: 0x" + last_token,
"size")));
6691 return get_ubjson_size_value(result.first);
6696 return get_ubjson_size_value(result.first);
6706 bool get_ubjson_value(
const int prefix)
6710 case std::char_traits<char>::eof():
6714 return sax->boolean(
true);
6716 return sax->boolean(
false);
6723 std::uint8_t number;
6724 return get_number(input_format_t::ubjson, number) and sax->number_unsigned(number);
6730 return get_number(input_format_t::ubjson, number) and sax->number_integer(number);
6735 std::int16_t number;
6736 return get_number(input_format_t::ubjson, number) and sax->number_integer(number);
6741 std::int32_t number;
6742 return get_number(input_format_t::ubjson, number) and sax->number_integer(number);
6747 std::int64_t number;
6748 return get_number(input_format_t::ubjson, number) and sax->number_integer(number);
6754 return get_number(input_format_t::ubjson, number) and sax->number_float(
static_cast<number_float_t
>(number),
"");
6760 return get_number(input_format_t::ubjson, number) and sax->number_float(
static_cast<number_float_t
>(number),
"");
6766 if (JSON_HEDLEY_UNLIKELY(not unexpect_eof(input_format_t::ubjson,
"char")))
6770 if (JSON_HEDLEY_UNLIKELY(current > 127))
6772 auto last_token = get_token_string();
6773 return sax->parse_error(chars_read, last_token,
parse_error::create(113, chars_read, exception_message(input_format_t::ubjson,
"byte after 'C' must be in range 0x00..0x7F; last byte: 0x" + last_token,
"char")));
6775 string_t s(1,
static_cast<char>(current));
6776 return sax->string(s);
6782 return get_ubjson_string(s) and sax->string(s);
6786 return get_ubjson_array();
6789 return get_ubjson_object();
6793 auto last_token = get_token_string();
6794 return sax->parse_error(chars_read, last_token,
parse_error::create(112, chars_read, exception_message(input_format_t::ubjson,
"invalid byte: 0x" + last_token,
"value")));
6802 bool get_ubjson_array()
6804 std::pair<std::size_t, int> size_and_type;
6805 if (JSON_HEDLEY_UNLIKELY(not get_ubjson_size_type(size_and_type)))
6810 if (size_and_type.first != string_t::npos)
6812 if (JSON_HEDLEY_UNLIKELY(not sax->start_array(size_and_type.first)))
6817 if (size_and_type.second != 0)
6819 if (size_and_type.second !=
'N')
6821 for (std::size_t i = 0; i < size_and_type.first; ++i)
6823 if (JSON_HEDLEY_UNLIKELY(not get_ubjson_value(size_and_type.second)))
6832 for (std::size_t i = 0; i < size_and_type.first; ++i)
6834 if (JSON_HEDLEY_UNLIKELY(not parse_ubjson_internal()))
6843 if (JSON_HEDLEY_UNLIKELY(not sax->start_array(std::size_t(-1))))
6848 while (current !=
']')
6850 if (JSON_HEDLEY_UNLIKELY(not parse_ubjson_internal(
false)))
6858 return sax->end_array();
6864 bool get_ubjson_object()
6866 std::pair<std::size_t, int> size_and_type;
6867 if (JSON_HEDLEY_UNLIKELY(not get_ubjson_size_type(size_and_type)))
6873 if (size_and_type.first != string_t::npos)
6875 if (JSON_HEDLEY_UNLIKELY(not sax->start_object(size_and_type.first)))
6880 if (size_and_type.second != 0)
6882 for (std::size_t i = 0; i < size_and_type.first; ++i)
6884 if (JSON_HEDLEY_UNLIKELY(not get_ubjson_string(key) or not sax->key(key)))
6888 if (JSON_HEDLEY_UNLIKELY(not get_ubjson_value(size_and_type.second)))
6897 for (std::size_t i = 0; i < size_and_type.first; ++i)
6899 if (JSON_HEDLEY_UNLIKELY(not get_ubjson_string(key) or not sax->key(key)))
6903 if (JSON_HEDLEY_UNLIKELY(not parse_ubjson_internal()))
6913 if (JSON_HEDLEY_UNLIKELY(not sax->start_object(std::size_t(-1))))
6918 while (current !=
'}')
6920 if (JSON_HEDLEY_UNLIKELY(not get_ubjson_string(key,
false) or not sax->key(key)))
6924 if (JSON_HEDLEY_UNLIKELY(not parse_ubjson_internal()))
6933 return sax->end_object();
6952 return current = ia->get_character();
6958 int get_ignore_noop()
6964 while (current ==
'N');
6982 template<
typename NumberType,
bool InputIsLittleEndian = false>
6986 std::array<std::uint8_t,
sizeof(NumberType)> vec;
6987 for (std::size_t i = 0; i <
sizeof(NumberType); ++i)
6990 if (JSON_HEDLEY_UNLIKELY(not unexpect_eof(format,
"number")))
6996 if (is_little_endian != InputIsLittleEndian)
6998 vec[
sizeof(NumberType) - i - 1] =
static_cast<std::uint8_t
>(current);
7002 vec[i] =
static_cast<std::uint8_t
>(current);
7007 std::memcpy(&result, vec.data(),
sizeof(NumberType));
7025 template<
typename NumberType>
7027 const NumberType len,
7030 bool success =
true;
7031 std::generate_n(std::back_inserter(result), len, [
this, &success, &format]()
7034 if (JSON_HEDLEY_UNLIKELY(not unexpect_eof(format,
"string")))
7038 return static_cast<char>(current);
7048 JSON_HEDLEY_NON_NULL(3)
7049 bool unexpect_eof(const
input_format_t format, const
char* context)
const
7051 if (JSON_HEDLEY_UNLIKELY(current == std::char_traits<char>::eof()))
7053 return sax->parse_error(chars_read,
"<end of file>",
7054 parse_error::create(110, chars_read, exception_message(format,
"unexpected end of input", context)));
7062 std::string get_token_string()
const
7064 std::array<char, 3> cr{{}};
7065 (std::snprintf)(cr.data(), cr.size(),
"%.2hhX",
static_cast<unsigned char>(current));
7066 return std::string{cr.data()};
7076 const std::string& detail,
7077 const std::string& context)
const
7079 std::string error_msg =
"syntax error while parsing ";
7083 case input_format_t::cbor:
7084 error_msg +=
"CBOR";
7087 case input_format_t::msgpack:
7088 error_msg +=
"MessagePack";
7091 case input_format_t::ubjson:
7092 error_msg +=
"UBJSON";
7095 case input_format_t::bson:
7096 error_msg +=
"BSON";
7103 return error_msg +
" " + context +
": " + detail;
7111 int current = std::char_traits<char>::eof();
7114 std::size_t chars_read = 0;
7120 json_sax_t* sax =
nullptr;
13789 using string_t =
typename BasicJsonType::string_t;
13790 using number_float_t =
typename BasicJsonType::number_float_t;
13791 using number_integer_t =
typename BasicJsonType::number_integer_t;
13792 using number_unsigned_t =
typename BasicJsonType::number_unsigned_t;
13793 static constexpr std::uint8_t UTF8_ACCEPT = 0;
13794 static constexpr std::uint8_t UTF8_REJECT = 1;
13805 , loc(std::localeconv())
13806 , thousands_sep(loc->thousands_sep == nullptr ?
'\0' : * (loc->thousands_sep))
13807 , decimal_point(loc->decimal_point == nullptr ?
'\0' : * (loc->decimal_point))
13808 , indent_char(ichar)
13809 , indent_string(512, indent_char)
13810 , error_handler(error_handler_)
13837 void dump(
const BasicJsonType& val,
const bool pretty_print,
13838 const bool ensure_ascii,
13839 const unsigned int indent_step,
13840 const unsigned int current_indent = 0)
13842 switch (val.m_type)
13846 if (val.m_value.object->empty())
13848 o->write_characters(
"{}", 2);
13854 o->write_characters(
"{\n", 2);
13857 const auto new_indent = current_indent + indent_step;
13858 if (JSON_HEDLEY_UNLIKELY(indent_string.size() < new_indent))
13860 indent_string.resize(indent_string.size() * 2,
' ');
13864 auto i = val.m_value.object->cbegin();
13865 for (std::size_t cnt = 0; cnt < val.m_value.object->size() - 1; ++cnt, ++i)
13867 o->write_characters(indent_string.c_str(), new_indent);
13868 o->write_character(
'\"');
13869 dump_escaped(i->first, ensure_ascii);
13870 o->write_characters(
"\": ", 3);
13871 dump(i->second,
true, ensure_ascii, indent_step, new_indent);
13872 o->write_characters(
",\n", 2);
13876 assert(i != val.m_value.object->cend());
13877 assert(std::next(i) == val.m_value.object->cend());
13878 o->write_characters(indent_string.c_str(), new_indent);
13879 o->write_character(
'\"');
13880 dump_escaped(i->first, ensure_ascii);
13881 o->write_characters(
"\": ", 3);
13882 dump(i->second,
true, ensure_ascii, indent_step, new_indent);
13884 o->write_character(
'\n');
13885 o->write_characters(indent_string.c_str(), current_indent);
13886 o->write_character(
'}');
13890 o->write_character(
'{');
13893 auto i = val.m_value.object->cbegin();
13894 for (std::size_t cnt = 0; cnt < val.m_value.object->size() - 1; ++cnt, ++i)
13896 o->write_character(
'\"');
13897 dump_escaped(i->first, ensure_ascii);
13898 o->write_characters(
"\":", 2);
13899 dump(i->second,
false, ensure_ascii, indent_step, current_indent);
13900 o->write_character(
',');
13904 assert(i != val.m_value.object->cend());
13905 assert(std::next(i) == val.m_value.object->cend());
13906 o->write_character(
'\"');
13907 dump_escaped(i->first, ensure_ascii);
13908 o->write_characters(
"\":", 2);
13909 dump(i->second,
false, ensure_ascii, indent_step, current_indent);
13911 o->write_character(
'}');
13919 if (val.m_value.array->empty())
13921 o->write_characters(
"[]", 2);
13927 o->write_characters(
"[\n", 2);
13930 const auto new_indent = current_indent + indent_step;
13931 if (JSON_HEDLEY_UNLIKELY(indent_string.size() < new_indent))
13933 indent_string.resize(indent_string.size() * 2,
' ');
13937 for (
auto i = val.m_value.array->cbegin();
13938 i != val.m_value.array->cend() - 1; ++i)
13940 o->write_characters(indent_string.c_str(), new_indent);
13941 dump(*i,
true, ensure_ascii, indent_step, new_indent);
13942 o->write_characters(
",\n", 2);
13946 assert(not val.m_value.array->empty());
13947 o->write_characters(indent_string.c_str(), new_indent);
13948 dump(val.m_value.array->back(),
true, ensure_ascii, indent_step, new_indent);
13950 o->write_character(
'\n');
13951 o->write_characters(indent_string.c_str(), current_indent);
13952 o->write_character(
']');
13956 o->write_character(
'[');
13959 for (
auto i = val.m_value.array->cbegin();
13960 i != val.m_value.array->cend() - 1; ++i)
13962 dump(*i,
false, ensure_ascii, indent_step, current_indent);
13963 o->write_character(
',');
13967 assert(not val.m_value.array->empty());
13968 dump(val.m_value.array->back(),
false, ensure_ascii, indent_step, current_indent);
13970 o->write_character(
']');
13978 o->write_character(
'\"');
13979 dump_escaped(*val.m_value.string, ensure_ascii);
13980 o->write_character(
'\"');
13986 if (val.m_value.boolean)
13988 o->write_characters(
"true", 4);
13992 o->write_characters(
"false", 5);
13999 dump_integer(val.m_value.number_integer);
14005 dump_integer(val.m_value.number_unsigned);
14011 dump_float(val.m_value.number_float);
14017 o->write_characters(
"<discarded>", 11);
14023 o->write_characters(
"null", 4);
14047 void dump_escaped(
const string_t& s,
const bool ensure_ascii)
14049 std::uint32_t codepoint;
14050 std::uint8_t
state = UTF8_ACCEPT;
14051 std::size_t bytes = 0;
14054 std::size_t bytes_after_last_accept = 0;
14055 std::size_t undumped_chars = 0;
14057 for (std::size_t i = 0; i < s.size(); ++i)
14059 const auto byte =
static_cast<uint8_t
>(s[i]);
14061 switch (decode(
state, codepoint,
byte))
14069 string_buffer[bytes++] =
'\\';
14070 string_buffer[bytes++] =
'b';
14076 string_buffer[bytes++] =
'\\';
14077 string_buffer[bytes++] =
't';
14083 string_buffer[bytes++] =
'\\';
14084 string_buffer[bytes++] =
'n';
14090 string_buffer[bytes++] =
'\\';
14091 string_buffer[bytes++] =
'f';
14097 string_buffer[bytes++] =
'\\';
14098 string_buffer[bytes++] =
'r';
14104 string_buffer[bytes++] =
'\\';
14105 string_buffer[bytes++] =
'\"';
14111 string_buffer[bytes++] =
'\\';
14112 string_buffer[bytes++] =
'\\';
14120 if ((codepoint <= 0x1F) or (ensure_ascii and (codepoint >= 0x7F)))
14122 if (codepoint <= 0xFFFF)
14124 (std::snprintf)(string_buffer.data() + bytes, 7,
"\\u%04x",
14125 static_cast<std::uint16_t
>(codepoint));
14130 (std::snprintf)(string_buffer.data() + bytes, 13,
"\\u%04x\\u%04x",
14131 static_cast<std::uint16_t
>(0xD7C0u + (codepoint >> 10u)),
14132 static_cast<std::uint16_t
>(0xDC00u + (codepoint & 0x3FFu)));
14140 string_buffer[bytes++] = s[i];
14149 if (string_buffer.size() - bytes < 13)
14151 o->write_characters(string_buffer.data(), bytes);
14156 bytes_after_last_accept = bytes;
14157 undumped_chars = 0;
14163 switch (error_handler)
14167 std::string sn(3,
'\0');
14168 (std::snprintf)(&sn[0], sn.size(),
"%.2X",
byte);
14169 JSON_THROW(type_error::create(316,
"invalid UTF-8 byte at index " + std::to_string(i) +
": 0x" + sn));
14179 if (undumped_chars > 0)
14186 bytes = bytes_after_last_accept;
14193 string_buffer[bytes++] =
'\\';
14194 string_buffer[bytes++] =
'u';
14195 string_buffer[bytes++] =
'f';
14196 string_buffer[bytes++] =
'f';
14197 string_buffer[bytes++] =
'f';
14198 string_buffer[bytes++] =
'd';
14202 string_buffer[bytes++] = detail::binary_writer<BasicJsonType, char>::to_char_type(
'\xEF');
14203 string_buffer[bytes++] = detail::binary_writer<BasicJsonType, char>::to_char_type(
'\xBF');
14204 string_buffer[bytes++] = detail::binary_writer<BasicJsonType, char>::to_char_type(
'\xBD');
14210 if (string_buffer.size() - bytes < 13)
14212 o->write_characters(string_buffer.data(), bytes);
14216 bytes_after_last_accept = bytes;
14219 undumped_chars = 0;
14222 state = UTF8_ACCEPT;
14234 if (not ensure_ascii)
14237 string_buffer[bytes++] = s[i];
14246 if (JSON_HEDLEY_LIKELY(state == UTF8_ACCEPT))
14251 o->write_characters(string_buffer.data(), bytes);
14257 switch (error_handler)
14261 std::string sn(3,
'\0');
14262 (std::snprintf)(&sn[0], sn.size(),
"%.2X",
static_cast<std::uint8_t
>(s.back()));
14263 JSON_THROW(type_error::create(316,
"incomplete UTF-8 string; last byte: 0x" + sn));
14269 o->write_characters(string_buffer.data(), bytes_after_last_accept);
14276 o->write_characters(string_buffer.data(), bytes_after_last_accept);
14280 o->write_characters(
"\\ufffd", 6);
14284 o->write_characters(
"\xEF\xBF\xBD", 3);
14303 inline unsigned int count_digits(number_unsigned_t x)
noexcept
14305 unsigned int n_digits = 1;
14314 return n_digits + 1;
14318 return n_digits + 2;
14322 return n_digits + 3;
14338 template<
typename NumberType, detail::enable_if_t<
14339 std::is_same<NumberType, number_unsigned_t>::value or
14340 std::is_same<NumberType, number_integer_t>::value,
14342 void dump_integer(NumberType x)
14344 static constexpr std::array<std::array<char, 2>, 100> digits_to_99
14347 {{
'0',
'0'}}, {{
'0',
'1'}}, {{
'0',
'2'}}, {{
'0',
'3'}}, {{
'0',
'4'}}, {{
'0',
'5'}}, {{
'0',
'6'}}, {{
'0',
'7'}}, {{
'0',
'8'}}, {{
'0',
'9'}},
14348 {{
'1',
'0'}}, {{
'1',
'1'}}, {{
'1',
'2'}}, {{
'1',
'3'}}, {{
'1',
'4'}}, {{
'1',
'5'}}, {{
'1',
'6'}}, {{
'1',
'7'}}, {{
'1',
'8'}}, {{
'1',
'9'}},
14349 {{
'2',
'0'}}, {{
'2',
'1'}}, {{
'2',
'2'}}, {{
'2',
'3'}}, {{
'2',
'4'}}, {{
'2',
'5'}}, {{
'2',
'6'}}, {{
'2',
'7'}}, {{
'2',
'8'}}, {{
'2',
'9'}},
14350 {{
'3',
'0'}}, {{
'3',
'1'}}, {{
'3',
'2'}}, {{
'3',
'3'}}, {{
'3',
'4'}}, {{
'3',
'5'}}, {{
'3',
'6'}}, {{
'3',
'7'}}, {{
'3',
'8'}}, {{
'3',
'9'}},
14351 {{
'4',
'0'}}, {{
'4',
'1'}}, {{
'4',
'2'}}, {{
'4',
'3'}}, {{
'4',
'4'}}, {{
'4',
'5'}}, {{
'4',
'6'}}, {{
'4',
'7'}}, {{
'4',
'8'}}, {{
'4',
'9'}},
14352 {{
'5',
'0'}}, {{
'5',
'1'}}, {{
'5',
'2'}}, {{
'5',
'3'}}, {{
'5',
'4'}}, {{
'5',
'5'}}, {{
'5',
'6'}}, {{
'5',
'7'}}, {{
'5',
'8'}}, {{
'5',
'9'}},
14353 {{
'6',
'0'}}, {{
'6',
'1'}}, {{
'6',
'2'}}, {{
'6',
'3'}}, {{
'6',
'4'}}, {{
'6',
'5'}}, {{
'6',
'6'}}, {{
'6',
'7'}}, {{
'6',
'8'}}, {{
'6',
'9'}},
14354 {{
'7',
'0'}}, {{
'7',
'1'}}, {{
'7',
'2'}}, {{
'7',
'3'}}, {{
'7',
'4'}}, {{
'7',
'5'}}, {{
'7',
'6'}}, {{
'7',
'7'}}, {{
'7',
'8'}}, {{
'7',
'9'}},
14355 {{
'8',
'0'}}, {{
'8',
'1'}}, {{
'8',
'2'}}, {{
'8',
'3'}}, {{
'8',
'4'}}, {{
'8',
'5'}}, {{
'8',
'6'}}, {{
'8',
'7'}}, {{
'8',
'8'}}, {{
'8',
'9'}},
14356 {{
'9',
'0'}}, {{
'9',
'1'}}, {{
'9',
'2'}}, {{
'9',
'3'}}, {{
'9',
'4'}}, {{
'9',
'5'}}, {{
'9',
'6'}}, {{
'9',
'7'}}, {{
'9',
'8'}}, {{
'9',
'9'}},
14363 o->write_character(
'0');
14368 auto buffer_ptr = number_buffer.begin();
14370 const bool is_negative = std::is_same<NumberType, number_integer_t>::value and not(x >= 0);
14371 number_unsigned_t abs_value;
14373 unsigned int n_chars;
14378 abs_value = remove_sign(x);
14381 n_chars = 1 + count_digits(abs_value);
14385 abs_value =
static_cast<number_unsigned_t
>(x);
14386 n_chars = count_digits(abs_value);
14390 assert(n_chars < number_buffer.size() - 1);
14394 buffer_ptr += n_chars;
14398 while (abs_value >= 100)
14400 const auto digits_index =
static_cast<unsigned>((abs_value % 100));
14402 *(--buffer_ptr) = digits_to_99[digits_index][1];
14403 *(--buffer_ptr) = digits_to_99[digits_index][0];
14406 if (abs_value >= 10)
14408 const auto digits_index =
static_cast<unsigned>(abs_value);
14409 *(--buffer_ptr) = digits_to_99[digits_index][1];
14410 *(--buffer_ptr) = digits_to_99[digits_index][0];
14414 *(--buffer_ptr) =
static_cast<char>(
'0' + abs_value);
14417 o->write_characters(number_buffer.data(), n_chars);
14428 void dump_float(number_float_t x)
14431 if (not std::isfinite(x))
14433 o->write_characters(
"null", 4);
14442 static constexpr bool is_ieee_single_or_double
14443 = (std::numeric_limits<number_float_t>::is_iec559 and std::numeric_limits<number_float_t>::digits == 24 and std::numeric_limits<number_float_t>::max_exponent == 128) or
14444 (std::numeric_limits<number_float_t>::is_iec559 and std::numeric_limits<number_float_t>::digits == 53 and std::numeric_limits<number_float_t>::max_exponent == 1024);
14446 dump_float(x, std::integral_constant<bool, is_ieee_single_or_double>());
14449 void dump_float(number_float_t x, std::true_type )
14451 char* begin = number_buffer.data();
14454 o->write_characters(begin,
static_cast<size_t>(end - begin));
14457 void dump_float(number_float_t x, std::false_type )
14460 static constexpr auto d = std::numeric_limits<number_float_t>::max_digits10;
14463 std::ptrdiff_t len = (std::snprintf)(number_buffer.data(), number_buffer.size(),
"%.*g", d, x);
14468 assert(
static_cast<std::size_t
>(len) < number_buffer.size());
14471 if (thousands_sep !=
'\0')
14473 const auto end = std::remove(number_buffer.begin(),
14474 number_buffer.begin() + len, thousands_sep);
14475 std::fill(end, number_buffer.end(),
'\0');
14476 assert((end - number_buffer.begin()) <= len);
14477 len = (end - number_buffer.begin());
14481 if (decimal_point !=
'\0' and decimal_point !=
'.')
14483 const auto dec_pos = std::find(number_buffer.begin(), number_buffer.end(), decimal_point);
14484 if (dec_pos != number_buffer.end())
14490 o->write_characters(number_buffer.data(),
static_cast<std::size_t
>(len));
14493 const bool value_is_int_like =
14494 std::none_of(number_buffer.begin(), number_buffer.begin() + len + 1,
14497 return c ==
'.' or c ==
'e';
14500 if (value_is_int_like)
14502 o->write_characters(
".0", 2);
14527 static std::uint8_t decode(std::uint8_t& state, std::uint32_t& codep,
const std::uint8_t
byte)
noexcept
14529 static const std::array<std::uint8_t, 400> utf8d =
14532 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
14533 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
14534 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
14535 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
14536 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
14537 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
14538 8, 8, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
14539 0xA, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x4, 0x3, 0x3,
14540 0xB, 0x6, 0x6, 0x6, 0x5, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8,
14541 0x0, 0x1, 0x2, 0x3, 0x5, 0x8, 0x7, 0x1, 0x1, 0x1, 0x4, 0x6, 0x1, 0x1, 0x1, 0x1,
14542 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1,
14543 1, 2, 1, 1, 1, 1, 1, 2, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1,
14544 1, 2, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 1, 3, 1, 1, 1, 1, 1, 1,
14545 1, 3, 1, 1, 1, 1, 1, 3, 1, 3, 1, 1, 1, 1, 1, 1, 1, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1
14549 const std::uint8_t type = utf8d[byte];
14551 codep = (state != UTF8_ACCEPT)
14552 ? (
byte & 0x3fu) | (codep << 6u)
14553 : (0xFFu >> type) & (byte);
14555 state = utf8d[256u + state * 16u + type];
14564 number_unsigned_t remove_sign(number_unsigned_t x)
14579 inline number_unsigned_t remove_sign(number_integer_t x)
noexcept
14581 assert(x < 0 and x < (std::numeric_limits<number_integer_t>::max)());
14582 return static_cast<number_unsigned_t
>(-(x + 1)) + 1;
14587 output_adapter_t<char> o =
nullptr;
14590 std::array<char, 64> number_buffer{{}};
14593 const std::lconv* loc =
nullptr;
14595 const char thousands_sep =
'\0';
14597 const char decimal_point =
'\0';
14600 std::array<char, 512> string_buffer{{}};
14603 const char indent_char;
14605 string_t indent_string;
14712 friend ::nlohmann::json_pointer<basic_json>;
14713 friend ::nlohmann::detail::parser<basic_json>;
14714 friend ::nlohmann::detail::serializer<basic_json>;
14715 template<
typename BasicJsonType>
14716 friend class ::nlohmann::detail::iter_impl;
14717 template<
typename BasicJsonType,
typename CharType>
14718 friend class ::nlohmann::detail::binary_writer;
14719 template<
typename BasicJsonType,
typename SAX>
14720 friend class ::nlohmann::detail::binary_reader;
14721 template<
typename BasicJsonType>
14722 friend class ::nlohmann::detail::json_sax_dom_parser;
14723 template<
typename BasicJsonType>
14724 friend class ::nlohmann::detail::json_sax_dom_callback_parser;
14727 using basic_json_t = NLOHMANN_BASIC_JSON_TPL;
14734 template<
typename BasicJsonType>
14736 template<
typename BasicJsonType>
14738 template<
typename Iterator>
14742 template<
typename CharType>
14743 using output_adapter_t = ::nlohmann::detail::output_adapter_t<CharType>;
14754 template<
typename T,
typename SFINAE>
14755 using json_serializer = JSONSerializer<T, SFINAE>;
14759 using initializer_list_t = std::initializer_list<detail::json_ref<basic_json>>;
14802 using reference = value_type&;
14804 using const_reference =
const value_type&;
14807 using difference_type = std::ptrdiff_t;
14809 using size_type = std::size_t;
14812 using allocator_type = AllocatorType<basic_json>;
14815 using pointer =
typename std::allocator_traits<allocator_type>::pointer;
14817 using const_pointer =
typename std::allocator_traits<allocator_type>::const_pointer;
14820 using iterator = iter_impl<basic_json>;
14822 using const_iterator = iter_impl<const basic_json>;
14824 using reverse_iterator = json_reverse_iterator<typename basic_json::iterator>;
14826 using const_reverse_iterator = json_reverse_iterator<typename basic_json::const_iterator>;
14836 return allocator_type();
14865 JSON_HEDLEY_WARN_UNUSED_RESULT
14870 result[
"copyright"] =
"(C) 2013-2017 Niels Lohmann";
14871 result[
"name"] =
"JSON for Modern C++";
14872 result[
"url"] =
"https://github.com/nlohmann/json";
14873 result[
"version"][
"string"] =
14874 std::to_string(NLOHMANN_JSON_VERSION_MAJOR) +
"." +
14875 std::to_string(NLOHMANN_JSON_VERSION_MINOR) +
"." +
14876 std::to_string(NLOHMANN_JSON_VERSION_PATCH);
14877 result[
"version"][
"major"] = NLOHMANN_JSON_VERSION_MAJOR;
14878 result[
"version"][
"minor"] = NLOHMANN_JSON_VERSION_MINOR;
14879 result[
"version"][
"patch"] = NLOHMANN_JSON_VERSION_PATCH;
14882 result[
"platform"] =
"win32";
14883#elif defined __linux__
14884 result[
"platform"] =
"linux";
14885#elif defined __APPLE__
14886 result[
"platform"] =
"apple";
14887#elif defined __unix__
14888 result[
"platform"] =
"unix";
14890 result[
"platform"] =
"unknown";
14893#if defined(__ICC) || defined(__INTEL_COMPILER)
14894 result[
"compiler"] = {{
"family",
"icc"}, {
"version", __INTEL_COMPILER}};
14895#elif defined(__clang__)
14896 result[
"compiler"] = {{
"family",
"clang"}, {
"version", __clang_version__}};
14897#elif defined(__GNUC__) || defined(__GNUG__)
14898 result[
"compiler"] = {{
"family",
"gcc"}, {
"version", std::to_string(__GNUC__) +
"." + std::to_string(__GNUC_MINOR__) +
"." + std::to_string(__GNUC_PATCHLEVEL__)}};
14899#elif defined(__HP_cc) || defined(__HP_aCC)
14900 result[
"compiler"] =
"hp"
14901#elif defined(__IBMCPP__)
14902 result[
"compiler"] = {{
"family",
"ilecpp"}, {
"version", __IBMCPP__}};
14903#elif defined(_MSC_VER)
14904 result[
"compiler"] = {{
"family",
"msvc"}, {
"version", _MSC_VER}};
14905#elif defined(__PGI)
14906 result[
"compiler"] = {{
"family",
"pgcpp"}, {
"version", __PGI}};
14907#elif defined(__SUNPRO_CC)
14908 result[
"compiler"] = {{
"family",
"sunpro"}, {
"version", __SUNPRO_CC}};
14910 result[
"compiler"] = {{
"family",
"unknown"}, {
"version",
"unknown"}};
14914 result[
"compiler"][
"c++"] = std::to_string(__cplusplus);
14916 result[
"compiler"][
"c++"] =
"unknown";
14931#if defined(JSON_HAS_CPP_14)
14934 using object_comparator_t = std::less<>;
14936 using object_comparator_t = std::less<StringType>;
15024 object_comparator_t,
15025 AllocatorType<std::pair<
const StringType,
15072 using array_t = ArrayType<basic_json, AllocatorType<basic_json>>;
15369 template<
typename T,
typename... Args>
15370 JSON_HEDLEY_RETURNS_NON_NULL
15371 static T* create(Args&& ... args)
15373 AllocatorType<T> alloc;
15374 using AllocatorTraits = std::allocator_traits<AllocatorType<T>>;
15376 auto deleter = [&](T * object)
15378 AllocatorTraits::deallocate(alloc,
object, 1);
15380 std::unique_ptr<T,
decltype(deleter)>
object(AllocatorTraits::allocate(alloc, 1), deleter);
15381 AllocatorTraits::construct(alloc,
object.get(), std::forward<Args>(args)...);
15382 assert(
object !=
nullptr);
15383 return object.release();
15432 json_value() =
default;
15434 json_value(
boolean_t v) noexcept : boolean(v) {}
15442 json_value(value_t t)
15446 case value_t::object:
15448 object = create<object_t>();
15452 case value_t::array:
15454 array = create<array_t>();
15458 case value_t::string:
15460 string = create<string_t>(
"");
15464 case value_t::boolean:
15470 case value_t::number_integer:
15476 case value_t::number_unsigned:
15482 case value_t::number_float:
15488 case value_t::null:
15497 if (JSON_HEDLEY_UNLIKELY(t == value_t::null))
15499 JSON_THROW(other_error::create(500,
"961c151d2e87f2686a955a9be24d316f1362bf21 3.7.3"));
15509 string = create<string_t>(value);
15515 string = create<string_t>(std::move(value));
15521 object = create<object_t>(value);
15527 object = create<object_t>(std::move(value));
15531 json_value(
const array_t& value)
15533 array = create<array_t>(value);
15539 array = create<array_t>(std::move(value));
15542 void destroy(value_t t)
noexcept
15545 std::vector<basic_json> stack;
15548 if (t == value_t::array)
15550 stack.reserve(array->size());
15551 std::move(array->begin(), array->end(), std::back_inserter(stack));
15553 else if (t == value_t::object)
15555 stack.reserve(object->size());
15556 for (
auto&& it : *
object)
15558 stack.push_back(std::move(it.second));
15562 while (not stack.empty())
15565 basic_json current_item(std::move(stack.back()));
15570 if (current_item.is_array())
15572 std::move(current_item.m_value.array->begin(), current_item.m_value.array->end(),
15573 std::back_inserter(stack));
15575 current_item.m_value.array->clear();
15577 else if (current_item.is_object())
15579 for (
auto&& it : *current_item.m_value.object)
15581 stack.push_back(std::move(it.second));
15584 current_item.m_value.object->clear();
15593 case value_t::object:
15595 AllocatorType<object_t> alloc;
15596 std::allocator_traits<
decltype(alloc)>::destroy(alloc,
object);
15597 std::allocator_traits<
decltype(alloc)>::deallocate(alloc,
object, 1);
15601 case value_t::array:
15603 AllocatorType<array_t> alloc;
15604 std::allocator_traits<
decltype(alloc)>::destroy(alloc, array);
15605 std::allocator_traits<
decltype(alloc)>::deallocate(alloc, array, 1);
15609 case value_t::string:
15611 AllocatorType<string_t> alloc;
15612 std::allocator_traits<
decltype(alloc)>::destroy(alloc,
string);
15613 std::allocator_traits<
decltype(alloc)>::deallocate(alloc,
string, 1);
15634 void assert_invariant() const noexcept
15636 assert(m_type != value_t::object or m_value.object !=
nullptr);
15637 assert(m_type != value_t::array or m_value.array !=
nullptr);
15638 assert(m_type != value_t::string or m_value.string !=
nullptr);
15753 : m_type(v), m_value(v)
15755 assert_invariant();
15776 basic_json(std::nullptr_t =
nullptr) noexcept
15779 assert_invariant();
15839 template <
typename CompatibleType,
15840 typename U = detail::uncvref_t<CompatibleType>,
15841 detail::enable_if_t<
15842 not detail::is_basic_json<U>::value and detail::is_compatible_type<basic_json_t, U>::value,
int> = 0>
15843 basic_json(CompatibleType && val)
noexcept(
noexcept(
15844 JSONSerializer<U>::to_json(std::declval<basic_json_t&>(),
15845 std::forward<CompatibleType>(val))))
15847 JSONSerializer<U>::to_json(*
this, std::forward<CompatibleType>(val));
15848 assert_invariant();
15877 template <
typename BasicJsonType,
15878 detail::enable_if_t<
15879 detail::is_basic_json<BasicJsonType>::value and not std::is_same<basic_json, BasicJsonType>::value,
int> = 0>
15880 basic_json(
const BasicJsonType& val)
15882 using other_boolean_t =
typename BasicJsonType::boolean_t;
15883 using other_number_float_t =
typename BasicJsonType::number_float_t;
15884 using other_number_integer_t =
typename BasicJsonType::number_integer_t;
15885 using other_number_unsigned_t =
typename BasicJsonType::number_unsigned_t;
15886 using other_string_t =
typename BasicJsonType::string_t;
15887 using other_object_t =
typename BasicJsonType::object_t;
15888 using other_array_t =
typename BasicJsonType::array_t;
15890 switch (val.type())
15892 case value_t::boolean:
15893 JSONSerializer<other_boolean_t>::to_json(*
this, val.template get<other_boolean_t>());
15895 case value_t::number_float:
15896 JSONSerializer<other_number_float_t>::to_json(*
this, val.template get<other_number_float_t>());
15898 case value_t::number_integer:
15899 JSONSerializer<other_number_integer_t>::to_json(*
this, val.template get<other_number_integer_t>());
15901 case value_t::number_unsigned:
15902 JSONSerializer<other_number_unsigned_t>::to_json(*
this, val.template get<other_number_unsigned_t>());
15904 case value_t::string:
15905 JSONSerializer<other_string_t>::to_json(*
this, val.template get_ref<const other_string_t&>());
15907 case value_t::object:
15908 JSONSerializer<other_object_t>::to_json(*
this, val.template get_ref<const other_object_t&>());
15910 case value_t::array:
15911 JSONSerializer<other_array_t>::to_json(*
this, val.template get_ref<const other_array_t&>());
15913 case value_t::null:
15916 case value_t::discarded:
15917 m_type = value_t::discarded;
15922 assert_invariant();
15999 basic_json(initializer_list_t init,
16000 bool type_deduction =
true,
16001 value_t manual_type = value_t::array)
16005 bool is_an_object = std::all_of(init.begin(), init.end(),
16006 [](
const detail::json_ref<basic_json>& element_ref)
16008 return element_ref->is_array() and element_ref->size() == 2 and (*element_ref)[0].is_string();
16012 if (not type_deduction)
16015 if (manual_type == value_t::array)
16017 is_an_object =
false;
16021 if (JSON_HEDLEY_UNLIKELY(manual_type == value_t::object and not is_an_object))
16023 JSON_THROW(type_error::create(301,
"cannot create object from initializer list"));
16030 m_type = value_t::object;
16031 m_value = value_t::object;
16033 std::for_each(init.begin(), init.end(), [
this](
const detail::json_ref<basic_json>& element_ref)
16035 auto element = element_ref.moved_or_copied();
16036 m_value.object->emplace(
16037 std::move(*((*element.m_value.array)[0].m_value.string)),
16038 std::move((*element.m_value.array)[1]));
16044 m_type = value_t::array;
16045 m_value.array = create<array_t>(init.begin(), init.end());
16048 assert_invariant();
16088 JSON_HEDLEY_WARN_UNUSED_RESULT
16089 static basic_json
array(initializer_list_t init = {})
16091 return basic_json(init,
false, value_t::array);
16132 JSON_HEDLEY_WARN_UNUSED_RESULT
16133 static basic_json
object(initializer_list_t init = {})
16135 return basic_json(init,
false, value_t::object);
16160 basic_json(size_type cnt,
const basic_json& val)
16161 : m_type(value_t::
array)
16163 m_value.array = create<array_t>(cnt, val);
16164 assert_invariant();
16222 template<
class InputIT,
typename std::enable_if<
16223 std::is_same<InputIT, typename basic_json_t::iterator>::value or
16224 std::is_same<InputIT, typename basic_json_t::const_iterator>::value,
int>::type = 0>
16225 basic_json(InputIT first, InputIT last)
16227 assert(first.m_object !=
nullptr);
16228 assert(last.m_object !=
nullptr);
16231 if (JSON_HEDLEY_UNLIKELY(first.m_object != last.m_object))
16233 JSON_THROW(invalid_iterator::create(201,
"iterators are not compatible"));
16237 m_type = first.m_object->m_type;
16242 case value_t::boolean:
16243 case value_t::number_float:
16244 case value_t::number_integer:
16245 case value_t::number_unsigned:
16246 case value_t::string:
16248 if (JSON_HEDLEY_UNLIKELY(not first.m_it.primitive_iterator.is_begin()
16249 or not last.m_it.primitive_iterator.is_end()))
16251 JSON_THROW(invalid_iterator::create(204,
"iterators out of range"));
16262 case value_t::number_integer:
16264 m_value.number_integer = first.m_object->m_value.number_integer;
16268 case value_t::number_unsigned:
16270 m_value.number_unsigned = first.m_object->m_value.number_unsigned;
16274 case value_t::number_float:
16276 m_value.number_float = first.m_object->m_value.number_float;
16280 case value_t::boolean:
16282 m_value.boolean = first.m_object->m_value.boolean;
16286 case value_t::string:
16288 m_value = *first.m_object->m_value.string;
16292 case value_t::object:
16294 m_value.object = create<object_t>(first.m_it.object_iterator,
16295 last.m_it.object_iterator);
16299 case value_t::array:
16301 m_value.array = create<array_t>(first.m_it.array_iterator,
16302 last.m_it.array_iterator);
16307 JSON_THROW(invalid_iterator::create(206,
"cannot construct with iterators from " +
16308 std::string(first.m_object->type_name())));
16311 assert_invariant();
16320 basic_json(
const detail::json_ref<basic_json>& ref)
16321 : basic_json(ref.moved_or_copied())
16349 basic_json(
const basic_json& other)
16350 : m_type(other.m_type)
16353 other.assert_invariant();
16357 case value_t::object:
16359 m_value = *other.m_value.object;
16363 case value_t::array:
16365 m_value = *other.m_value.array;
16369 case value_t::string:
16371 m_value = *other.m_value.string;
16375 case value_t::boolean:
16377 m_value = other.m_value.boolean;
16381 case value_t::number_integer:
16383 m_value = other.m_value.number_integer;
16387 case value_t::number_unsigned:
16389 m_value = other.m_value.number_unsigned;
16393 case value_t::number_float:
16395 m_value = other.m_value.number_float;
16403 assert_invariant();
16432 basic_json(basic_json&& other) noexcept
16433 : m_type(std::move(other.m_type)),
16434 m_value(std::move(other.m_value))
16437 other.assert_invariant();
16440 other.m_type = value_t::null;
16441 other.m_value = {};
16443 assert_invariant();
16469 basic_json& operator=(basic_json other)
noexcept (
16470 std::is_nothrow_move_constructible<value_t>::value and
16471 std::is_nothrow_move_assignable<value_t>::value and
16472 std::is_nothrow_move_constructible<json_value>::value and
16473 std::is_nothrow_move_assignable<json_value>::value
16477 other.assert_invariant();
16480 swap(m_type, other.m_type);
16481 swap(m_value, other.m_value);
16483 assert_invariant();
16502 ~basic_json() noexcept
16504 assert_invariant();
16505 m_value.destroy(m_type);
16560 string_t dump(
const int indent = -1,
16561 const char indent_char =
' ',
16562 const bool ensure_ascii =
false,
16563 const error_handler_t error_handler = error_handler_t::strict)
const
16566 serializer s(detail::output_adapter<char, string_t>(result), indent_char, error_handler);
16570 s.dump(*
this,
true, ensure_ascii,
static_cast<unsigned int>(indent));
16574 s.dump(*
this,
false, ensure_ascii, 0);
16612 constexpr value_t type() const noexcept
16642 constexpr bool is_primitive() const noexcept
16644 return is_null() or is_string() or is_boolean() or is_number();
16669 constexpr
bool is_structured() const noexcept
16671 return is_array() or is_object();
16691 constexpr
bool is_null() const noexcept
16693 return m_type == value_t::null;
16713 constexpr bool is_boolean() const noexcept
16715 return m_type == value_t::boolean;
16743 constexpr bool is_number() const noexcept
16745 return is_number_integer() or is_number_float();
16772 constexpr
bool is_number_integer() const noexcept
16774 return m_type == value_t::number_integer or m_type == value_t::number_unsigned;
16800 constexpr bool is_number_unsigned() const noexcept
16802 return m_type == value_t::number_unsigned;
16828 constexpr bool is_number_float() const noexcept
16830 return m_type == value_t::number_float;
16850 constexpr bool is_object() const noexcept
16852 return m_type == value_t::object;
16872 constexpr bool is_array() const noexcept
16874 return m_type == value_t::array;
16894 constexpr bool is_string() const noexcept
16896 return m_type == value_t::string;
16921 constexpr bool is_discarded() const noexcept
16923 return m_type == value_t::discarded;
16947 constexpr operator value_t() const noexcept
16962 if (JSON_HEDLEY_LIKELY(is_boolean()))
16964 return m_value.boolean;
16967 JSON_THROW(type_error::create(302,
"type must be boolean, but is " + std::string(type_name())));
16973 return is_object() ? m_value.object :
nullptr;
16979 return is_object() ? m_value.object :
nullptr;
16985 return is_array() ? m_value.array :
nullptr;
16989 constexpr const array_t* get_impl_ptr(
const array_t* )
const noexcept
16991 return is_array() ? m_value.array :
nullptr;
16997 return is_string() ? m_value.string :
nullptr;
17003 return is_string() ? m_value.string :
nullptr;
17009 return is_boolean() ? &m_value.boolean :
nullptr;
17015 return is_boolean() ? &m_value.boolean :
nullptr;
17021 return is_number_integer() ? &m_value.number_integer :
nullptr;
17027 return is_number_integer() ? &m_value.number_integer :
nullptr;
17033 return is_number_unsigned() ? &m_value.number_unsigned :
nullptr;
17039 return is_number_unsigned() ? &m_value.number_unsigned :
nullptr;
17045 return is_number_float() ? &m_value.number_float :
nullptr;
17051 return is_number_float() ? &m_value.number_float :
nullptr;
17065 template<
typename ReferenceType,
typename ThisType>
17066 static ReferenceType get_ref_impl(ThisType& obj)
17069 auto ptr = obj.template get_ptr<typename std::add_pointer<ReferenceType>::type>();
17071 if (JSON_HEDLEY_LIKELY(ptr !=
nullptr))
17076 JSON_THROW(type_error::create(303,
"incompatible ReferenceType for get_ref, actual type is " + std::string(obj.type_name())));
17098 template<
typename BasicJsonType, detail::enable_if_t<
17099 std::is_same<typename std::remove_const<BasicJsonType>::type, basic_json_t>::value,
17101 basic_json get()
const
17121 template<
typename BasicJsonType, detail::enable_if_t<
17122 not std::is_same<BasicJsonType, basic_json>::value and
17123 detail::is_basic_json<BasicJsonType>::value,
int> = 0>
17124 BasicJsonType get()
const
17168 template<
typename ValueTypeCV,
typename ValueType = detail::uncvref_t<ValueTypeCV>,
17169 detail::enable_if_t <
17170 not detail::is_basic_json<ValueType>::value and
17171 detail::has_from_json<basic_json_t, ValueType>::value and
17172 not detail::has_non_default_from_json<basic_json_t, ValueType>::value,
17174 ValueType get() const noexcept(noexcept(
17175 JSONSerializer<ValueType>::from_json(std::declval<const basic_json_t&>(), std::declval<ValueType&>())))
17180 static_assert(not std::is_reference<ValueTypeCV>::value,
17181 "get() cannot be used with reference types, you might want to use get_ref()");
17182 static_assert(std::is_default_constructible<ValueType>::value,
17183 "types must be DefaultConstructible when used with get()");
17186 JSONSerializer<ValueType>::from_json(*
this, ret);
17221 template<
typename ValueTypeCV,
typename ValueType = detail::uncvref_t<ValueTypeCV>,
17222 detail::enable_if_t<not std::is_same<basic_json_t, ValueType>::value and
17223 detail::has_non_default_from_json<basic_json_t, ValueType>::value,
17225 ValueType get() const noexcept(noexcept(
17226 JSONSerializer<ValueType>::from_json(std::declval<const basic_json_t&>())))
17228 static_assert(not std::is_reference<ValueTypeCV>::value,
17229 "get() cannot be used with reference types, you might want to use get_ref()");
17230 return JSONSerializer<ValueType>::from_json(*
this);
17266 template<
typename ValueType,
17267 detail::enable_if_t <
17268 not detail::is_basic_json<ValueType>::value and
17269 detail::has_from_json<basic_json_t, ValueType>::value,
17271 ValueType & get_to(ValueType& v)
const noexcept(
noexcept(
17272 JSONSerializer<ValueType>::from_json(std::declval<const basic_json_t&>(), v)))
17274 JSONSerializer<ValueType>::from_json(*
this, v);
17279 typename T, std::size_t N,
17280 typename Array = T (&)[N],
17281 detail::enable_if_t <
17282 detail::has_from_json<basic_json_t, Array>::value,
int > = 0 >
17283 Array get_to(T (&v)[N])
const
17284 noexcept(
noexcept(JSONSerializer<Array>::from_json(
17285 std::declval<const basic_json_t&>(), v)))
17287 JSONSerializer<Array>::from_json(*
this, v);
17318 template<
typename PointerType,
typename std::enable_if<
17319 std::is_pointer<PointerType>::value,
int>::type = 0>
17320 auto get_ptr() noexcept -> decltype(std::declval<basic_json_t&>().get_impl_ptr(std::declval<PointerType>()))
17323 return get_impl_ptr(
static_cast<PointerType
>(
nullptr));
17330 template<
typename PointerType,
typename std::enable_if<
17331 std::is_pointer<PointerType>::value and
17332 std::is_const<typename std::remove_pointer<PointerType>::type>::value,
int>::type = 0>
17333 constexpr auto get_ptr() const noexcept -> decltype(std::declval<const basic_json_t&>().get_impl_ptr(std::declval<PointerType>()))
17336 return get_impl_ptr(
static_cast<PointerType
>(
nullptr));
17366 template<
typename PointerType,
typename std::enable_if<
17367 std::is_pointer<PointerType>::value,
int>::type = 0>
17368 auto get() noexcept -> decltype(std::declval<basic_json_t&>().template get_ptr<PointerType>())
17371 return get_ptr<PointerType>();
17378 template<
typename PointerType,
typename std::enable_if<
17379 std::is_pointer<PointerType>::value,
int>::type = 0>
17380 constexpr auto get() const noexcept -> decltype(std::declval<const basic_json_t&>().template get_ptr<PointerType>())
17383 return get_ptr<PointerType>();
17412 template<
typename ReferenceType,
typename std::enable_if<
17413 std::is_reference<ReferenceType>::value,
int>::type = 0>
17414 ReferenceType get_ref()
17417 return get_ref_impl<ReferenceType>(*
this);
17424 template<
typename ReferenceType,
typename std::enable_if<
17425 std::is_reference<ReferenceType>::value and
17426 std::is_const<typename std::remove_reference<ReferenceType>::type>::value,
int>::type = 0>
17427 ReferenceType get_ref()
const
17430 return get_ref_impl<ReferenceType>(*
this);
17462 template <
typename ValueType,
typename std::enable_if <
17463 not std::is_pointer<ValueType>::value and
17464 not std::is_same<ValueType, detail::json_ref<basic_json>>::value and
17465 not std::is_same<ValueType, typename string_t::value_type>::value and
17466 not detail::is_basic_json<ValueType>::value
17469 and not std::is_same<ValueType, std::initializer_list<typename string_t::value_type>>::value
17470#if defined(JSON_HAS_CPP_17) && (defined(__GNUC__) || (defined(_MSC_VER) and _MSC_VER <= 1914))
17471 and not std::is_same<ValueType, typename std::string_view>::value
17474 and detail::is_detected<detail::get_template_function, const basic_json_t&, ValueType>::value
17475 ,
int >::type = 0 >
17476 operator ValueType()
const
17479 return get<ValueType>();
17519 reference at(size_type idx)
17522 if (JSON_HEDLEY_LIKELY(is_array()))
17526 return m_value.array->at(idx);
17528 JSON_CATCH (std::out_of_range&)
17531 JSON_THROW(out_of_range::create(401,
"array index " + std::to_string(idx) +
" is out of range"));
17536 JSON_THROW(type_error::create(304,
"cannot use at() with " + std::string(type_name())));
17566 const_reference at(size_type idx)
const
17569 if (JSON_HEDLEY_LIKELY(is_array()))
17573 return m_value.array->at(idx);
17575 JSON_CATCH (std::out_of_range&)
17578 JSON_THROW(out_of_range::create(401,
"array index " + std::to_string(idx) +
" is out of range"));
17583 JSON_THROW(type_error::create(304,
"cannot use at() with " + std::string(type_name())));
17617 reference at(
const typename object_t::key_type& key)
17620 if (JSON_HEDLEY_LIKELY(is_object()))
17624 return m_value.object->at(key);
17626 JSON_CATCH (std::out_of_range&)
17629 JSON_THROW(out_of_range::create(403,
"key '" + key +
"' not found"));
17634 JSON_THROW(type_error::create(304,
"cannot use at() with " + std::string(type_name())));
17668 const_reference at(
const typename object_t::key_type& key)
const
17671 if (JSON_HEDLEY_LIKELY(is_object()))
17675 return m_value.object->at(key);
17677 JSON_CATCH (std::out_of_range&)
17680 JSON_THROW(out_of_range::create(403,
"key '" + key +
"' not found"));
17685 JSON_THROW(type_error::create(304,
"cannot use at() with " + std::string(type_name())));
17714 reference operator[](size_type idx)
17719 m_type = value_t::array;
17720 m_value.array = create<array_t>();
17721 assert_invariant();
17725 if (JSON_HEDLEY_LIKELY(is_array()))
17728 if (idx >= m_value.array->size())
17730 m_value.array->insert(m_value.array->end(),
17731 idx - m_value.array->size() + 1,
17735 return m_value.array->operator[](idx);
17738 JSON_THROW(type_error::create(305,
"cannot use operator[] with a numeric argument with " + std::string(type_name())));
17760 const_reference operator[](size_type idx)
const
17763 if (JSON_HEDLEY_LIKELY(is_array()))
17765 return m_value.array->operator[](idx);
17768 JSON_THROW(type_error::create(305,
"cannot use operator[] with a numeric argument with " + std::string(type_name())));
17798 reference operator[](
const typename object_t::key_type& key)
17803 m_type = value_t::object;
17804 m_value.object = create<object_t>();
17805 assert_invariant();
17809 if (JSON_HEDLEY_LIKELY(is_object()))
17811 return m_value.object->operator[](key);
17814 JSON_THROW(type_error::create(305,
"cannot use operator[] with a string argument with " + std::string(type_name())));
17847 const_reference operator[](
const typename object_t::key_type& key)
const
17850 if (JSON_HEDLEY_LIKELY(is_object()))
17852 assert(m_value.object->find(key) != m_value.object->end());
17853 return m_value.object->find(key)->second;
17856 JSON_THROW(type_error::create(305,
"cannot use operator[] with a string argument with " + std::string(type_name())));
17886 template<
typename T>
17887 JSON_HEDLEY_NON_NULL(2)
17888 reference operator[](T* key)
17893 m_type = value_t::object;
17894 m_value = value_t::object;
17895 assert_invariant();
17899 if (JSON_HEDLEY_LIKELY(is_object()))
17901 return m_value.object->operator[](key);
17904 JSON_THROW(type_error::create(305,
"cannot use operator[] with a string argument with " + std::string(type_name())));
17937 template<
typename T>
17938 JSON_HEDLEY_NON_NULL(2)
17939 const_reference operator[](T* key)
const
17942 if (JSON_HEDLEY_LIKELY(is_object()))
17944 assert(m_value.object->find(key) != m_value.object->end());
17945 return m_value.object->find(key)->second;
17948 JSON_THROW(type_error::create(305,
"cannot use operator[] with a string argument with " + std::string(type_name())));
18001 template<
class ValueType,
typename std::enable_if<
18002 std::is_convertible<basic_json_t, ValueType>::value,
int>::type = 0>
18003 ValueType value(
const typename object_t::key_type& key,
const ValueType& default_value)
const
18006 if (JSON_HEDLEY_LIKELY(is_object()))
18009 const auto it = find(key);
18015 return default_value;
18018 JSON_THROW(type_error::create(306,
"cannot use value() with " + std::string(type_name())));
18025 string_t value(
const typename object_t::key_type& key,
const char* default_value)
const
18027 return value(key,
string_t(default_value));
18073 template<
class ValueType,
typename std::enable_if<
18074 std::is_convertible<basic_json_t, ValueType>::value,
int>::type = 0>
18075 ValueType value(
const json_pointer& ptr,
const ValueType& default_value)
const
18078 if (JSON_HEDLEY_LIKELY(is_object()))
18083 return ptr.get_checked(
this);
18085 JSON_INTERNAL_CATCH (out_of_range&)
18087 return default_value;
18091 JSON_THROW(type_error::create(306,
"cannot use value() with " + std::string(type_name())));
18098 JSON_HEDLEY_NON_NULL(3)
18099 string_t value(const json_pointer& ptr, const
char* default_value)
const
18101 return value(ptr,
string_t(default_value));
18137 const_reference front()
const
18183 const_reference back()
const
18236 template<
class IteratorType,
typename std::enable_if<
18237 std::is_same<IteratorType, typename basic_json_t::iterator>::value or
18238 std::is_same<IteratorType, typename basic_json_t::const_iterator>::value,
int>::type
18240 IteratorType erase(IteratorType pos)
18243 if (JSON_HEDLEY_UNLIKELY(
this != pos.m_object))
18245 JSON_THROW(invalid_iterator::create(202,
"iterator does not fit current value"));
18248 IteratorType result = end();
18252 case value_t::boolean:
18253 case value_t::number_float:
18254 case value_t::number_integer:
18255 case value_t::number_unsigned:
18256 case value_t::string:
18258 if (JSON_HEDLEY_UNLIKELY(not pos.m_it.primitive_iterator.is_begin()))
18260 JSON_THROW(invalid_iterator::create(205,
"iterator out of range"));
18265 AllocatorType<string_t> alloc;
18266 std::allocator_traits<
decltype(alloc)>::destroy(alloc, m_value.string);
18267 std::allocator_traits<
decltype(alloc)>::deallocate(alloc, m_value.string, 1);
18268 m_value.string =
nullptr;
18271 m_type = value_t::null;
18272 assert_invariant();
18276 case value_t::object:
18278 result.m_it.object_iterator = m_value.object->erase(pos.m_it.object_iterator);
18282 case value_t::array:
18284 result.m_it.array_iterator = m_value.array->erase(pos.m_it.array_iterator);
18289 JSON_THROW(type_error::create(307,
"cannot use erase() with " + std::string(type_name())));
18341 template<
class IteratorType,
typename std::enable_if<
18342 std::is_same<IteratorType, typename basic_json_t::iterator>::value or
18343 std::is_same<IteratorType, typename basic_json_t::const_iterator>::value,
int>::type
18345 IteratorType erase(IteratorType first, IteratorType last)
18348 if (JSON_HEDLEY_UNLIKELY(
this != first.m_object or
this != last.m_object))
18350 JSON_THROW(invalid_iterator::create(203,
"iterators do not fit current value"));
18353 IteratorType result = end();
18357 case value_t::boolean:
18358 case value_t::number_float:
18359 case value_t::number_integer:
18360 case value_t::number_unsigned:
18361 case value_t::string:
18363 if (JSON_HEDLEY_LIKELY(not first.m_it.primitive_iterator.is_begin()
18364 or not last.m_it.primitive_iterator.is_end()))
18366 JSON_THROW(invalid_iterator::create(204,
"iterators out of range"));
18371 AllocatorType<string_t> alloc;
18372 std::allocator_traits<
decltype(alloc)>::destroy(alloc, m_value.string);
18373 std::allocator_traits<
decltype(alloc)>::deallocate(alloc, m_value.string, 1);
18374 m_value.string =
nullptr;
18377 m_type = value_t::null;
18378 assert_invariant();
18382 case value_t::object:
18384 result.m_it.object_iterator = m_value.object->erase(first.m_it.object_iterator,
18385 last.m_it.object_iterator);
18389 case value_t::array:
18391 result.m_it.array_iterator = m_value.array->erase(first.m_it.array_iterator,
18392 last.m_it.array_iterator);
18397 JSON_THROW(type_error::create(307,
"cannot use erase() with " + std::string(type_name())));
18432 size_type erase(
const typename object_t::key_type& key)
18435 if (JSON_HEDLEY_LIKELY(is_object()))
18437 return m_value.object->erase(key);
18440 JSON_THROW(type_error::create(307,
"cannot use erase() with " + std::string(type_name())));
18467 void erase(
const size_type idx)
18470 if (JSON_HEDLEY_LIKELY(is_array()))
18472 if (JSON_HEDLEY_UNLIKELY(idx >= size()))
18474 JSON_THROW(out_of_range::create(401,
"array index " + std::to_string(idx) +
" is out of range"));
18477 m_value.array->erase(m_value.array->begin() +
static_cast<difference_type
>(idx));
18481 JSON_THROW(type_error::create(307,
"cannot use erase() with " + std::string(type_name())));
18519 template<
typename KeyT>
18520 iterator find(KeyT&& key)
18522 auto result = end();
18526 result.m_it.object_iterator = m_value.object->find(std::forward<KeyT>(key));
18536 template<
typename KeyT>
18537 const_iterator find(KeyT&& key)
const
18539 auto result = cend();
18543 result.m_it.object_iterator = m_value.object->find(std::forward<KeyT>(key));
18570 template<
typename KeyT>
18571 size_type count(KeyT&& key)
const
18574 return is_object() ? m_value.object->count(std::forward<KeyT>(key)) : 0;
18602 template<
typename KeyT,
typename std::enable_if<
18603 not std::is_same<typename std::decay<KeyT>::type, json_pointer>::value,
int>::type = 0>
18604 bool contains(KeyT && key)
const
18606 return is_object() and m_value.
object->find(std::forward<KeyT>(key)) != m_value.
object->end();
18635 bool contains(const json_pointer& ptr)
const
18637 return ptr.contains(
this);
18674 iterator begin() noexcept
18676 iterator result(
this);
18677 result.set_begin();
18684 const_iterator begin() const noexcept
18714 const_iterator cbegin() const noexcept
18716 const_iterator result(
this);
18717 result.set_begin();
18745 iterator end() noexcept
18747 iterator result(
this);
18755 const_iterator end() const noexcept
18785 const_iterator cend() const noexcept
18787 const_iterator result(
this);
18815 reverse_iterator rbegin() noexcept
18817 return reverse_iterator(end());
18823 const_reverse_iterator rbegin() const noexcept
18852 reverse_iterator rend() noexcept
18854 return reverse_iterator(begin());
18860 const_reverse_iterator rend() const noexcept
18889 const_reverse_iterator crbegin() const noexcept
18891 return const_reverse_iterator(cend());
18918 const_reverse_iterator crend() const noexcept
18920 return const_reverse_iterator(cbegin());
18981 JSON_HEDLEY_DEPRECATED(3.1.0)
18982 static iteration_proxy<iterator> iterator_wrapper(reference ref) noexcept
18984 return ref.items();
18990 JSON_HEDLEY_DEPRECATED(3.1.0)
18991 static iteration_proxy<const_iterator> iterator_wrapper(const_reference ref) noexcept
18993 return ref.items();
19059 iteration_proxy<iterator> items() noexcept
19061 return iteration_proxy<iterator>(*
this);
19067 iteration_proxy<const_iterator> items() const noexcept
19069 return iteration_proxy<const_iterator>(*
this);
19123 bool empty() const noexcept
19127 case value_t::null:
19133 case value_t::array:
19136 return m_value.array->empty();
19139 case value_t::object:
19142 return m_value.object->empty();
19195 size_type size() const noexcept
19199 case value_t::null:
19205 case value_t::array:
19208 return m_value.array->size();
19211 case value_t::object:
19214 return m_value.object->size();
19265 size_type max_size() const noexcept
19269 case value_t::array:
19272 return m_value.array->max_size();
19275 case value_t::object:
19278 return m_value.object->max_size();
19335 void clear() noexcept
19339 case value_t::number_integer:
19341 m_value.number_integer = 0;
19345 case value_t::number_unsigned:
19347 m_value.number_unsigned = 0;
19351 case value_t::number_float:
19353 m_value.number_float = 0.0;
19357 case value_t::boolean:
19359 m_value.boolean =
false;
19363 case value_t::string:
19365 m_value.string->clear();
19369 case value_t::array:
19371 m_value.array->clear();
19375 case value_t::object:
19377 m_value.object->clear();
19406 void push_back(basic_json&& val)
19409 if (JSON_HEDLEY_UNLIKELY(not(is_null() or is_array())))
19411 JSON_THROW(type_error::create(308,
"cannot use push_back() with " + std::string(type_name())));
19417 m_type = value_t::array;
19418 m_value = value_t::array;
19419 assert_invariant();
19423 m_value.array->push_back(std::move(val));
19426 val.m_type = value_t::null;
19433 reference operator+=(basic_json&& val)
19435 push_back(std::move(val));
19443 void push_back(
const basic_json& val)
19446 if (JSON_HEDLEY_UNLIKELY(not(is_null() or is_array())))
19448 JSON_THROW(type_error::create(308,
"cannot use push_back() with " + std::string(type_name())));
19454 m_type = value_t::array;
19455 m_value = value_t::array;
19456 assert_invariant();
19460 m_value.array->push_back(val);
19467 reference operator+=(
const basic_json& val)
19493 void push_back(
const typename object_t::value_type& val)
19496 if (JSON_HEDLEY_UNLIKELY(not(is_null() or is_object())))
19498 JSON_THROW(type_error::create(308,
"cannot use push_back() with " + std::string(type_name())));
19504 m_type = value_t::object;
19505 m_value = value_t::object;
19506 assert_invariant();
19510 m_value.object->insert(val);
19517 reference operator+=(
const typename object_t::value_type& val)
19548 void push_back(initializer_list_t init)
19550 if (is_object() and init.size() == 2 and (*init.begin())->is_string())
19552 basic_json&& key = init.begin()->moved_or_copied();
19553 push_back(
typename object_t::value_type(
19554 std::move(key.get_ref<
string_t&>()), (init.begin() + 1)->moved_or_copied()));
19558 push_back(basic_json(init));
19566 reference operator+=(initializer_list_t init)
19595 template<
class... Args>
19596 reference emplace_back(Args&& ... args)
19599 if (JSON_HEDLEY_UNLIKELY(not(is_null() or is_array())))
19601 JSON_THROW(type_error::create(311,
"cannot use emplace_back() with " + std::string(type_name())));
19607 m_type = value_t::array;
19608 m_value = value_t::array;
19609 assert_invariant();
19613#ifdef JSON_HAS_CPP_17
19614 return m_value.array->emplace_back(std::forward<Args>(args)...);
19616 m_value.array->emplace_back(std::forward<Args>(args)...);
19617 return m_value.array->back();
19648 template<
class... Args>
19649 std::pair<iterator, bool> emplace(Args&& ... args)
19652 if (JSON_HEDLEY_UNLIKELY(not(is_null() or is_object())))
19654 JSON_THROW(type_error::create(311,
"cannot use emplace() with " + std::string(type_name())));
19660 m_type = value_t::object;
19661 m_value = value_t::object;
19662 assert_invariant();
19666 auto res = m_value.object->emplace(std::forward<Args>(args)...);
19669 it.m_it.object_iterator = res.first;
19672 return {it, res.second};
19678 template<
typename... Args>
19679 iterator insert_iterator(const_iterator pos, Args&& ... args)
19681 iterator result(
this);
19682 assert(m_value.array !=
nullptr);
19684 auto insert_pos = std::distance(m_value.array->begin(), pos.m_it.array_iterator);
19685 m_value.array->insert(pos.m_it.array_iterator, std::forward<Args>(args)...);
19686 result.m_it.array_iterator = m_value.array->begin() + insert_pos;
19717 iterator insert(const_iterator pos,
const basic_json& val)
19720 if (JSON_HEDLEY_LIKELY(is_array()))
19723 if (JSON_HEDLEY_UNLIKELY(pos.m_object !=
this))
19725 JSON_THROW(invalid_iterator::create(202,
"iterator does not fit current value"));
19729 return insert_iterator(pos, val);
19732 JSON_THROW(type_error::create(309,
"cannot use insert() with " + std::string(type_name())));
19739 iterator insert(const_iterator pos, basic_json&& val)
19741 return insert(pos, val);
19768 iterator insert(const_iterator pos, size_type cnt,
const basic_json& val)
19771 if (JSON_HEDLEY_LIKELY(is_array()))
19774 if (JSON_HEDLEY_UNLIKELY(pos.m_object !=
this))
19776 JSON_THROW(invalid_iterator::create(202,
"iterator does not fit current value"));
19780 return insert_iterator(pos, cnt, val);
19783 JSON_THROW(type_error::create(309,
"cannot use insert() with " + std::string(type_name())));
19816 iterator insert(const_iterator pos, const_iterator first, const_iterator last)
19819 if (JSON_HEDLEY_UNLIKELY(not is_array()))
19821 JSON_THROW(type_error::create(309,
"cannot use insert() with " + std::string(type_name())));
19825 if (JSON_HEDLEY_UNLIKELY(pos.m_object !=
this))
19827 JSON_THROW(invalid_iterator::create(202,
"iterator does not fit current value"));
19831 if (JSON_HEDLEY_UNLIKELY(first.m_object != last.m_object))
19833 JSON_THROW(invalid_iterator::create(210,
"iterators do not fit"));
19836 if (JSON_HEDLEY_UNLIKELY(first.m_object ==
this))
19838 JSON_THROW(invalid_iterator::create(211,
"passed iterators may not belong to container"));
19842 return insert_iterator(pos, first.m_it.array_iterator, last.m_it.array_iterator);
19869 iterator insert(const_iterator pos, initializer_list_t ilist)
19872 if (JSON_HEDLEY_UNLIKELY(not is_array()))
19874 JSON_THROW(type_error::create(309,
"cannot use insert() with " + std::string(type_name())));
19878 if (JSON_HEDLEY_UNLIKELY(pos.m_object !=
this))
19880 JSON_THROW(invalid_iterator::create(202,
"iterator does not fit current value"));
19884 return insert_iterator(pos, ilist.begin(), ilist.end());
19910 void insert(const_iterator first, const_iterator last)
19913 if (JSON_HEDLEY_UNLIKELY(not is_object()))
19915 JSON_THROW(type_error::create(309,
"cannot use insert() with " + std::string(type_name())));
19919 if (JSON_HEDLEY_UNLIKELY(first.m_object != last.m_object))
19921 JSON_THROW(invalid_iterator::create(210,
"iterators do not fit"));
19925 if (JSON_HEDLEY_UNLIKELY(not first.m_object->is_object()))
19927 JSON_THROW(invalid_iterator::create(202,
"iterators first and last must point to objects"));
19930 m_value.object->insert(first.m_it.object_iterator, last.m_it.object_iterator);
19952 void update(const_reference j)
19957 m_type = value_t::object;
19958 m_value.object = create<object_t>();
19959 assert_invariant();
19962 if (JSON_HEDLEY_UNLIKELY(not is_object()))
19964 JSON_THROW(type_error::create(312,
"cannot use update() with " + std::string(type_name())));
19966 if (JSON_HEDLEY_UNLIKELY(not j.is_object()))
19968 JSON_THROW(type_error::create(312,
"cannot use update() with " + std::string(j.type_name())));
19971 for (
auto it = j.cbegin(); it != j.cend(); ++it)
19973 m_value.object->operator[](it.key()) = it.value();
20003 void update(const_iterator first, const_iterator last)
20008 m_type = value_t::object;
20009 m_value.object = create<object_t>();
20010 assert_invariant();
20013 if (JSON_HEDLEY_UNLIKELY(not is_object()))
20015 JSON_THROW(type_error::create(312,
"cannot use update() with " + std::string(type_name())));
20019 if (JSON_HEDLEY_UNLIKELY(first.m_object != last.m_object))
20021 JSON_THROW(invalid_iterator::create(210,
"iterators do not fit"));
20025 if (JSON_HEDLEY_UNLIKELY(not first.m_object->is_object()
20026 or not last.m_object->is_object()))
20028 JSON_THROW(invalid_iterator::create(202,
"iterators first and last must point to objects"));
20031 for (
auto it = first; it != last; ++it)
20033 m_value.object->operator[](it.key()) = it.value();
20054 void swap(reference other)
noexcept (
20055 std::is_nothrow_move_constructible<value_t>::value and
20056 std::is_nothrow_move_assignable<value_t>::value and
20057 std::is_nothrow_move_constructible<json_value>::value and
20058 std::is_nothrow_move_assignable<json_value>::value
20061 std::swap(m_type, other.m_type);
20062 std::swap(m_value, other.m_value);
20063 assert_invariant();
20089 if (JSON_HEDLEY_LIKELY(is_array()))
20091 std::swap(*(m_value.array), other);
20095 JSON_THROW(type_error::create(310,
"cannot use swap() with " + std::string(type_name())));
20122 if (JSON_HEDLEY_LIKELY(is_object()))
20124 std::swap(*(m_value.object), other);
20128 JSON_THROW(type_error::create(310,
"cannot use swap() with " + std::string(type_name())));
20155 if (JSON_HEDLEY_LIKELY(is_string()))
20157 std::swap(*(m_value.string), other);
20161 JSON_THROW(type_error::create(310,
"cannot use swap() with " + std::string(type_name())));
20214 friend bool operator==(const_reference lhs, const_reference rhs)
noexcept
20216 const auto lhs_type = lhs.type();
20217 const auto rhs_type = rhs.type();
20219 if (lhs_type == rhs_type)
20223 case value_t::array:
20224 return *lhs.m_value.array == *rhs.m_value.array;
20226 case value_t::object:
20227 return *lhs.m_value.object == *rhs.m_value.object;
20229 case value_t::null:
20232 case value_t::string:
20233 return *lhs.m_value.string == *rhs.m_value.string;
20235 case value_t::boolean:
20236 return lhs.m_value.boolean == rhs.m_value.boolean;
20238 case value_t::number_integer:
20239 return lhs.m_value.number_integer == rhs.m_value.number_integer;
20241 case value_t::number_unsigned:
20242 return lhs.m_value.number_unsigned == rhs.m_value.number_unsigned;
20244 case value_t::number_float:
20245 return lhs.m_value.number_float == rhs.m_value.number_float;
20251 else if (lhs_type == value_t::number_integer and rhs_type == value_t::number_float)
20253 return static_cast<number_float_t>(lhs.m_value.number_integer) == rhs.m_value.number_float;
20255 else if (lhs_type == value_t::number_float and rhs_type == value_t::number_integer)
20257 return lhs.m_value.number_float ==
static_cast<number_float_t>(rhs.m_value.number_integer);
20259 else if (lhs_type == value_t::number_unsigned and rhs_type == value_t::number_float)
20261 return static_cast<number_float_t>(lhs.m_value.number_unsigned) == rhs.m_value.number_float;
20263 else if (lhs_type == value_t::number_float and rhs_type == value_t::number_unsigned)
20265 return lhs.m_value.number_float ==
static_cast<number_float_t>(rhs.m_value.number_unsigned);
20267 else if (lhs_type == value_t::number_unsigned and rhs_type == value_t::number_integer)
20269 return static_cast<number_integer_t>(lhs.m_value.number_unsigned) == rhs.m_value.number_integer;
20271 else if (lhs_type == value_t::number_integer and rhs_type == value_t::number_unsigned)
20273 return lhs.m_value.number_integer ==
static_cast<number_integer_t>(rhs.m_value.number_unsigned);
20283 template<
typename ScalarType,
typename std::enable_if<
20284 std::is_scalar<ScalarType>::value,
int>::type = 0>
20285 friend bool operator==(const_reference lhs,
const ScalarType rhs)
noexcept
20287 return lhs == basic_json(rhs);
20294 template<
typename ScalarType,
typename std::enable_if<
20295 std::is_scalar<ScalarType>::value,
int>::type = 0>
20296 friend bool operator==(
const ScalarType lhs, const_reference rhs)
noexcept
20298 return basic_json(lhs) == rhs;
20319 friend bool operator!=(const_reference lhs, const_reference rhs)
noexcept
20321 return not (lhs == rhs);
20328 template<
typename ScalarType,
typename std::enable_if<
20329 std::is_scalar<ScalarType>::value,
int>::type = 0>
20330 friend bool operator!=(const_reference lhs,
const ScalarType rhs)
noexcept
20332 return lhs != basic_json(rhs);
20339 template<
typename ScalarType,
typename std::enable_if<
20340 std::is_scalar<ScalarType>::value,
int>::type = 0>
20341 friend bool operator!=(
const ScalarType lhs, const_reference rhs)
noexcept
20343 return basic_json(lhs) != rhs;
20372 friend bool operator<(const_reference lhs, const_reference rhs)
noexcept
20374 const auto lhs_type = lhs.type();
20375 const auto rhs_type = rhs.type();
20377 if (lhs_type == rhs_type)
20381 case value_t::array:
20384 return (*lhs.m_value.array) < (*rhs.m_value.array);
20386 case value_t::object:
20387 return (*lhs.m_value.object) < (*rhs.m_value.object);
20389 case value_t::null:
20392 case value_t::string:
20393 return (*lhs.m_value.string) < (*rhs.m_value.string);
20395 case value_t::boolean:
20396 return (lhs.m_value.boolean) < (rhs.m_value.boolean);
20398 case value_t::number_integer:
20399 return (lhs.m_value.number_integer) < (rhs.m_value.number_integer);
20401 case value_t::number_unsigned:
20402 return (lhs.m_value.number_unsigned) < (rhs.m_value.number_unsigned);
20404 case value_t::number_float:
20405 return (lhs.m_value.number_float) < (rhs.m_value.number_float);
20411 else if (lhs_type == value_t::number_integer and rhs_type == value_t::number_float)
20413 return static_cast<number_float_t>(lhs.m_value.number_integer) < rhs.m_value.number_float;
20415 else if (lhs_type == value_t::number_float and rhs_type == value_t::number_integer)
20417 return lhs.m_value.number_float <
static_cast<number_float_t>(rhs.m_value.number_integer);
20419 else if (lhs_type == value_t::number_unsigned and rhs_type == value_t::number_float)
20421 return static_cast<number_float_t>(lhs.m_value.number_unsigned) < rhs.m_value.number_float;
20423 else if (lhs_type == value_t::number_float and rhs_type == value_t::number_unsigned)
20425 return lhs.m_value.number_float <
static_cast<number_float_t>(rhs.m_value.number_unsigned);
20427 else if (lhs_type == value_t::number_integer and rhs_type == value_t::number_unsigned)
20429 return lhs.m_value.number_integer <
static_cast<number_integer_t>(rhs.m_value.number_unsigned);
20431 else if (lhs_type == value_t::number_unsigned and rhs_type == value_t::number_integer)
20433 return static_cast<number_integer_t>(lhs.m_value.number_unsigned) < rhs.m_value.number_integer;
20446 template<
typename ScalarType,
typename std::enable_if<
20447 std::is_scalar<ScalarType>::value,
int>::type = 0>
20448 friend bool operator<(const_reference lhs,
const ScalarType rhs)
noexcept
20450 return lhs < basic_json(rhs);
20457 template<
typename ScalarType,
typename std::enable_if<
20458 std::is_scalar<ScalarType>::value,
int>::type = 0>
20459 friend bool operator<(
const ScalarType lhs, const_reference rhs)
noexcept
20461 return basic_json(lhs) < rhs;
20483 friend bool operator<=(const_reference lhs, const_reference rhs)
noexcept
20485 return not (rhs < lhs);
20492 template<
typename ScalarType,
typename std::enable_if<
20493 std::is_scalar<ScalarType>::value,
int>::type = 0>
20494 friend bool operator<=(const_reference lhs,
const ScalarType rhs)
noexcept
20496 return lhs <= basic_json(rhs);
20503 template<
typename ScalarType,
typename std::enable_if<
20504 std::is_scalar<ScalarType>::value,
int>::type = 0>
20505 friend bool operator<=(
const ScalarType lhs, const_reference rhs)
noexcept
20507 return basic_json(lhs) <= rhs;
20529 friend bool operator>(const_reference lhs, const_reference rhs)
noexcept
20531 return not (lhs <= rhs);
20538 template<
typename ScalarType,
typename std::enable_if<
20539 std::is_scalar<ScalarType>::value,
int>::type = 0>
20540 friend bool operator>(const_reference lhs,
const ScalarType rhs)
noexcept
20542 return lhs > basic_json(rhs);
20549 template<
typename ScalarType,
typename std::enable_if<
20550 std::is_scalar<ScalarType>::value,
int>::type = 0>
20551 friend bool operator>(
const ScalarType lhs, const_reference rhs)
noexcept
20553 return basic_json(lhs) > rhs;
20575 friend bool operator>=(const_reference lhs, const_reference rhs)
noexcept
20577 return not (lhs < rhs);
20584 template<
typename ScalarType,
typename std::enable_if<
20585 std::is_scalar<ScalarType>::value,
int>::type = 0>
20586 friend bool operator>=(const_reference lhs,
const ScalarType rhs)
noexcept
20588 return lhs >= basic_json(rhs);
20595 template<
typename ScalarType,
typename std::enable_if<
20596 std::is_scalar<ScalarType>::value,
int>::type = 0>
20597 friend bool operator>=(
const ScalarType lhs, const_reference rhs)
noexcept
20599 return basic_json(lhs) >= rhs;
20642 friend std::ostream& operator<<(std::ostream& o,
const basic_json& j)
20645 const bool pretty_print = o.width() > 0;
20646 const auto indentation = pretty_print ? o.width() : 0;
20652 serializer s(detail::output_adapter<char>(o), o.fill());
20653 s.dump(j, pretty_print,
false,
static_cast<unsigned int>(indentation));
20665 JSON_HEDLEY_DEPRECATED(3.0.0)
20666 friend std::ostream& operator>>(const basic_json& j, std::ostream& o)
20744 JSON_HEDLEY_WARN_UNUSED_RESULT
20745 static basic_json parse(detail::input_adapter&& i,
20747 const bool allow_exceptions =
true)
20750 parser(i, cb, allow_exceptions).parse(
true, result);
20754 static bool accept(detail::input_adapter&& i)
20756 return parser(i).accept(
true);
20812 template <
typename SAX>
20813 JSON_HEDLEY_NON_NULL(2)
20814 static
bool sax_parse(detail::input_adapter&& i, SAX* sax,
20815 input_format_t format = input_format_t::
json,
20816 const
bool strict = true)
20819 return format == input_format_t::json
20820 ? parser(std::move(i)).sax_parse(sax, strict)
20821 : detail::binary_reader<basic_json, SAX>(std::move(i)).sax_parse(format, sax, strict);
20873 template<
class IteratorType,
typename std::enable_if<
20875 std::random_access_iterator_tag,
20876 typename std::iterator_traits<IteratorType>::iterator_category>::value,
int>::type = 0>
20877 static basic_json parse(IteratorType first, IteratorType last,
20879 const bool allow_exceptions =
true)
20882 parser(detail::input_adapter(first, last), cb, allow_exceptions).parse(
true, result);
20886 template<
class IteratorType,
typename std::enable_if<
20888 std::random_access_iterator_tag,
20889 typename std::iterator_traits<IteratorType>::iterator_category>::value,
int>::type = 0>
20890 static bool accept(IteratorType first, IteratorType last)
20892 return parser(detail::input_adapter(first, last)).accept(
true);
20895 template<
class IteratorType,
class SAX,
typename std::enable_if<
20897 std::random_access_iterator_tag,
20898 typename std::iterator_traits<IteratorType>::iterator_category>::value,
int>::type = 0>
20899 JSON_HEDLEY_NON_NULL(3)
20900 static
bool sax_parse(IteratorType first, IteratorType last, SAX* sax)
20902 return parser(detail::input_adapter(first, last)).sax_parse(sax);
20913 JSON_HEDLEY_DEPRECATED(3.0.0)
20914 friend std::istream& operator<<(basic_json& j, std::istream& i)
20916 return operator>>(i, j);
20944 friend std::istream& operator>>(std::istream& i, basic_json& j)
20946 parser(detail::input_adapter(i)).parse(
false, j);
20986 JSON_HEDLEY_RETURNS_NON_NULL
20987 const char* type_name() const noexcept
20992 case value_t::null:
20994 case value_t::object:
20996 case value_t::array:
20998 case value_t::string:
21000 case value_t::boolean:
21002 case value_t::discarded:
21003 return "discarded";
21017 value_t m_type = value_t::null;
21020 json_value m_value = {};
21118 static std::vector<uint8_t> to_cbor(
const basic_json& j)
21120 std::vector<uint8_t> result;
21121 to_cbor(j, result);
21125 static void to_cbor(
const basic_json& j, detail::output_adapter<uint8_t> o)
21127 binary_writer<uint8_t>(o).write_cbor(j);
21130 static void to_cbor(
const basic_json& j, detail::output_adapter<char> o)
21132 binary_writer<char>(o).write_cbor(j);
21214 static std::vector<uint8_t> to_msgpack(
const basic_json& j)
21216 std::vector<uint8_t> result;
21217 to_msgpack(j, result);
21221 static void to_msgpack(
const basic_json& j, detail::output_adapter<uint8_t> o)
21223 binary_writer<uint8_t>(o).write_msgpack(j);
21226 static void to_msgpack(
const basic_json& j, detail::output_adapter<char> o)
21228 binary_writer<char>(o).write_msgpack(j);
21311 static std::vector<uint8_t> to_ubjson(
const basic_json& j,
21312 const bool use_size =
false,
21313 const bool use_type =
false)
21315 std::vector<uint8_t> result;
21316 to_ubjson(j, result, use_size, use_type);
21320 static void to_ubjson(
const basic_json& j, detail::output_adapter<uint8_t> o,
21321 const bool use_size =
false,
const bool use_type =
false)
21323 binary_writer<uint8_t>(o).write_ubjson(j, use_size, use_type);
21326 static void to_ubjson(
const basic_json& j, detail::output_adapter<char> o,
21327 const bool use_size =
false,
const bool use_type =
false)
21329 binary_writer<char>(o).write_ubjson(j, use_size, use_type);
21388 static std::vector<uint8_t> to_bson(
const basic_json& j)
21390 std::vector<uint8_t> result;
21391 to_bson(j, result);
21403 static void to_bson(
const basic_json& j, detail::output_adapter<uint8_t> o)
21405 binary_writer<uint8_t>(o).write_bson(j);
21411 static void to_bson(
const basic_json& j, detail::output_adapter<char> o)
21413 binary_writer<char>(o).write_bson(j);
21516 JSON_HEDLEY_WARN_UNUSED_RESULT
21517 static basic_json from_cbor(detail::input_adapter&& i,
21518 const bool strict =
true,
21519 const bool allow_exceptions =
true)
21522 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
21523 const bool res = binary_reader(detail::input_adapter(i)).sax_parse(input_format_t::cbor, &sdp, strict);
21524 return res ? result : basic_json(value_t::discarded);
21530 template<
typename A1,
typename A2,
21531 detail::enable_if_t<std::is_constructible<detail::input_adapter, A1, A2>::value,
int> = 0>
21532 JSON_HEDLEY_WARN_UNUSED_RESULT
21533 static basic_json from_cbor(A1 && a1, A2 && a2,
21534 const bool strict =
true,
21535 const bool allow_exceptions =
true)
21538 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
21539 const bool res = binary_reader(detail::input_adapter(std::forward<A1>(a1), std::forward<A2>(a2))).sax_parse(input_format_t::cbor, &sdp, strict);
21540 return res ? result : basic_json(value_t::discarded);
21625 JSON_HEDLEY_WARN_UNUSED_RESULT
21626 static basic_json from_msgpack(detail::input_adapter&& i,
21627 const bool strict =
true,
21628 const bool allow_exceptions =
true)
21631 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
21632 const bool res = binary_reader(detail::input_adapter(i)).sax_parse(input_format_t::msgpack, &sdp, strict);
21633 return res ? result : basic_json(value_t::discarded);
21639 template<
typename A1,
typename A2,
21640 detail::enable_if_t<std::is_constructible<detail::input_adapter, A1, A2>::value,
int> = 0>
21641 JSON_HEDLEY_WARN_UNUSED_RESULT
21642 static basic_json from_msgpack(A1 && a1, A2 && a2,
21643 const bool strict =
true,
21644 const bool allow_exceptions =
true)
21647 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
21648 const bool res = binary_reader(detail::input_adapter(std::forward<A1>(a1), std::forward<A2>(a2))).sax_parse(input_format_t::msgpack, &sdp, strict);
21649 return res ? result : basic_json(value_t::discarded);
21713 JSON_HEDLEY_WARN_UNUSED_RESULT
21714 static basic_json from_ubjson(detail::input_adapter&& i,
21715 const bool strict =
true,
21716 const bool allow_exceptions =
true)
21719 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
21720 const bool res = binary_reader(detail::input_adapter(i)).sax_parse(input_format_t::ubjson, &sdp, strict);
21721 return res ? result : basic_json(value_t::discarded);
21727 template<
typename A1,
typename A2,
21728 detail::enable_if_t<std::is_constructible<detail::input_adapter, A1, A2>::value,
int> = 0>
21729 JSON_HEDLEY_WARN_UNUSED_RESULT
21730 static basic_json from_ubjson(A1 && a1, A2 && a2,
21731 const bool strict =
true,
21732 const bool allow_exceptions =
true)
21735 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
21736 const bool res = binary_reader(detail::input_adapter(std::forward<A1>(a1), std::forward<A2>(a2))).sax_parse(input_format_t::ubjson, &sdp, strict);
21737 return res ? result : basic_json(value_t::discarded);
21800 JSON_HEDLEY_WARN_UNUSED_RESULT
21801 static basic_json from_bson(detail::input_adapter&& i,
21802 const bool strict =
true,
21803 const bool allow_exceptions =
true)
21806 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
21807 const bool res = binary_reader(detail::input_adapter(i)).sax_parse(input_format_t::bson, &sdp, strict);
21808 return res ? result : basic_json(value_t::discarded);
21814 template<
typename A1,
typename A2,
21815 detail::enable_if_t<std::is_constructible<detail::input_adapter, A1, A2>::value,
int> = 0>
21816 JSON_HEDLEY_WARN_UNUSED_RESULT
21817 static basic_json from_bson(A1 && a1, A2 && a2,
21818 const bool strict =
true,
21819 const bool allow_exceptions =
true)
21822 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
21823 const bool res = binary_reader(detail::input_adapter(std::forward<A1>(a1), std::forward<A2>(a2))).sax_parse(input_format_t::bson, &sdp, strict);
21824 return res ? result : basic_json(value_t::discarded);
21871 reference operator[](
const json_pointer& ptr)
21873 return ptr.get_unchecked(
this);
21899 const_reference operator[](
const json_pointer& ptr)
const
21901 return ptr.get_unchecked(
this);
21942 reference at(
const json_pointer& ptr)
21944 return ptr.get_checked(
this);
21985 const_reference at(
const json_pointer& ptr)
const
21987 return ptr.get_checked(
this);
22012 basic_json flatten()
const
22014 basic_json result(value_t::object);
22015 json_pointer::flatten(
"", *
this, result);
22049 basic_json unflatten()
const
22051 return json_pointer::unflatten(*
this);
22110 basic_json patch(
const basic_json& json_patch)
const
22113 basic_json result = *
this;
22116 enum class patch_operations {add, remove,
replace, move, copy, test, invalid};
22118 const auto get_op = [](
const std::string & op)
22122 return patch_operations::add;
22124 if (op ==
"remove")
22126 return patch_operations::remove;
22128 if (op ==
"replace")
22130 return patch_operations::replace;
22134 return patch_operations::move;
22138 return patch_operations::copy;
22142 return patch_operations::test;
22145 return patch_operations::invalid;
22149 const auto operation_add = [&result](json_pointer & ptr, basic_json val)
22159 json_pointer top_pointer = ptr.top();
22160 if (top_pointer != ptr)
22162 result.at(top_pointer);
22166 const auto last_path = ptr.back();
22168 basic_json& parent = result[ptr];
22170 switch (parent.m_type)
22172 case value_t::null:
22173 case value_t::object:
22176 parent[last_path] = val;
22180 case value_t::array:
22182 if (last_path ==
"-")
22185 parent.push_back(val);
22189 const auto idx = json_pointer::array_index(last_path);
22190 if (JSON_HEDLEY_UNLIKELY(
static_cast<size_type
>(idx) > parent.size()))
22193 JSON_THROW(out_of_range::create(401,
"array index " + std::to_string(idx) +
" is out of range"));
22197 parent.insert(parent.begin() +
static_cast<difference_type
>(idx), val);
22209 const auto operation_remove = [&result](json_pointer & ptr)
22212 const auto last_path = ptr.back();
22214 basic_json& parent = result.at(ptr);
22217 if (parent.is_object())
22220 auto it = parent.find(last_path);
22221 if (JSON_HEDLEY_LIKELY(it != parent.end()))
22227 JSON_THROW(out_of_range::create(403,
"key '" + last_path +
"' not found"));
22230 else if (parent.is_array())
22233 parent.erase(
static_cast<size_type
>(json_pointer::array_index(last_path)));
22238 if (JSON_HEDLEY_UNLIKELY(not json_patch.is_array()))
22240 JSON_THROW(parse_error::create(104, 0,
"JSON patch must be an array of objects"));
22244 for (
const auto& val : json_patch)
22247 const auto get_value = [&val](
const std::string & op,
22248 const std::string & member,
22249 bool string_type) -> basic_json &
22252 auto it = val.m_value.object->find(member);
22255 const auto error_msg = (op ==
"op") ?
"operation" :
"operation '" + op +
"'";
22258 if (JSON_HEDLEY_UNLIKELY(it == val.m_value.object->end()))
22260 JSON_THROW(parse_error::create(105, 0, error_msg +
" must have member '" + member +
"'"));
22264 if (JSON_HEDLEY_UNLIKELY(string_type and not it->second.is_string()))
22266 JSON_THROW(parse_error::create(105, 0, error_msg +
" must have string member '" + member +
"'"));
22274 if (JSON_HEDLEY_UNLIKELY(not val.is_object()))
22276 JSON_THROW(parse_error::create(104, 0,
"JSON patch must be an array of objects"));
22280 const std::string op = get_value(
"op",
"op",
true);
22281 const std::string path = get_value(op,
"path",
true);
22282 json_pointer ptr(path);
22284 switch (get_op(op))
22286 case patch_operations::add:
22288 operation_add(ptr, get_value(
"add",
"value",
false));
22292 case patch_operations::remove:
22294 operation_remove(ptr);
22298 case patch_operations::replace:
22301 result.at(ptr) = get_value(
"replace",
"value",
false);
22305 case patch_operations::move:
22307 const std::string from_path = get_value(
"move",
"from",
true);
22308 json_pointer from_ptr(from_path);
22311 basic_json v = result.at(from_ptr);
22317 operation_remove(from_ptr);
22318 operation_add(ptr, v);
22322 case patch_operations::copy:
22324 const std::string from_path = get_value(
"copy",
"from",
true);
22325 const json_pointer from_ptr(from_path);
22328 basic_json v = result.at(from_ptr);
22333 operation_add(ptr, v);
22337 case patch_operations::test:
22339 bool success =
false;
22344 success = (result.at(ptr) == get_value(
"test",
"value",
false));
22346 JSON_INTERNAL_CATCH (out_of_range&)
22352 if (JSON_HEDLEY_UNLIKELY(not success))
22354 JSON_THROW(other_error::create(501,
"unsuccessful: " + val.dump()));
22364 JSON_THROW(parse_error::create(105, 0,
"operation value '" + op +
"' is invalid"));
22405 JSON_HEDLEY_WARN_UNUSED_RESULT
22406 static basic_json diff(
const basic_json& source,
const basic_json& target,
22407 const std::string& path =
"")
22410 basic_json result(value_t::array);
22413 if (source == target)
22418 if (source.type() != target.type())
22423 {
"op",
"replace"}, {
"path", path}, {
"value", target}
22428 switch (source.type())
22430 case value_t::array:
22434 while (i < source.size() and i < target.size())
22437 auto temp_diff = diff(source[i], target[i], path +
"/" + std::to_string(i));
22438 result.insert(result.end(), temp_diff.begin(), temp_diff.end());
22446 const auto end_index =
static_cast<difference_type
>(result.size());
22447 while (i < source.size())
22451 result.insert(result.begin() + end_index,
object(
22454 {
"path", path +
"/" + std::to_string(i)}
22460 while (i < target.size())
22465 {
"path", path +
"/" + std::to_string(i)},
22466 {
"value", target[i]}
22474 case value_t::object:
22477 for (
auto it = source.cbegin(); it != source.cend(); ++it)
22480 const auto key = json_pointer::escape(it.key());
22482 if (target.find(it.key()) != target.end())
22485 auto temp_diff = diff(it.value(), target[it.key()], path +
"/" + key);
22486 result.insert(result.end(), temp_diff.begin(), temp_diff.end());
22491 result.push_back(
object(
22493 {
"op",
"remove"}, {
"path", path +
"/" + key}
22499 for (
auto it = target.cbegin(); it != target.cend(); ++it)
22501 if (source.find(it.key()) == source.end())
22504 const auto key = json_pointer::escape(it.key());
22507 {
"op",
"add"}, {
"path", path +
"/" + key},
22508 {
"value", it.value()}
22521 {
"op",
"replace"}, {
"path", path}, {
"value", target}
22581 void merge_patch(
const basic_json& apply_patch)
22583 if (apply_patch.is_object())
22585 if (not is_object())
22589 for (
auto it = apply_patch.begin(); it != apply_patch.end(); ++it)
22591 if (it.value().is_null())
22597 operator[](it.key()).merge_patch(it.value());
22603 *
this = apply_patch;