6494 using number_integer_t =
typename BasicJsonType::number_integer_t;
6495 using number_unsigned_t =
typename BasicJsonType::number_unsigned_t;
6496 using number_float_t =
typename BasicJsonType::number_float_t;
6497 using string_t =
typename BasicJsonType::string_t;
6498 using json_sax_t = SAX;
6521 const bool strict =
true)
6524 bool result =
false;
6529 result = parse_bson_internal();
6533 result = parse_cbor_internal();
6537 result = parse_msgpack_internal();
6541 result = parse_ubjson_internal();
6562 if (
JSON_UNLIKELY(current != std::char_traits<char>::eof()))
6564 return sax->parse_error(chars_read, get_token_string(),
6565 parse_error::create(110, chars_read, exception_message(
format,
"expected end of input; last byte: 0x" + get_token_string(),
"value")));
6581 return (*
reinterpret_cast<char*
>(&
num) == 1);
6593 bool parse_bson_internal()
6595 std::int32_t document_size;
6608 return sax->end_object();
6618 bool get_bson_cstr(string_t& result)
6620 auto out = std::back_inserter(result);
6628 if (current == 0x00)
6632 *out++ =
static_cast<char>(current);
6649 template<
typename NumberType>
6650 bool get_bson_string(
const NumberType len, string_t& result)
6654 auto last_token = get_token_string();
6655 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")));
6658 return get_string(
input_format_t::bson, len -
static_cast<NumberType
>(1), result) and get() != std::char_traits<char>::eof();
6671 bool parse_bson_element_internal(
const int element_type,
6672 const std::size_t element_type_parse_position)
6674 switch (element_type)
6679 return get_number<double, true>(
input_format_t::bson, number) and sax->number_float(
static_cast<number_float_t
>(number),
"");
6691 return parse_bson_internal();
6696 return parse_bson_array();
6701 return sax->boolean(get() != 0);
6724 (std::snprintf)(cr,
sizeof(cr),
"%.2hhX",
static_cast<unsigned char>(element_type));
6725 return sax->parse_error(element_type_parse_position, std::string(cr),
parse_error::create(114, element_type_parse_position,
"Unsupported BSON record type 0x" + std::string(cr)));
6742 bool parse_bson_element_list(
const bool is_array)
6745 while (
int element_type = get())
6752 const std::size_t element_type_parse_position = chars_read;
6760 if (not sax->key(key))
6766 if (
JSON_UNLIKELY(not parse_bson_element_internal(element_type, element_type_parse_position)))
6782 bool parse_bson_array()
6784 std::int32_t document_size;
6797 return sax->end_array();
6811 bool parse_cbor_internal(
const bool get_char =
true)
6813 switch (get_char ? get() : current)
6816 case std::char_traits<char>::eof():
6844 return sax->number_unsigned(
static_cast<number_unsigned_t
>(current));
6895 return sax->number_integer(
static_cast<int8_t
>(0x20 - 1 - current));
6900 return get_number(
input_format_t::cbor, number) and sax->number_integer(
static_cast<number_integer_t
>(-1) - number);
6906 return get_number(
input_format_t::cbor, number) and sax->number_integer(
static_cast<number_integer_t
>(-1) - number);
6912 return get_number(
input_format_t::cbor, number) and sax->number_integer(
static_cast<number_integer_t
>(-1) - number);
6918 return get_number(
input_format_t::cbor, number) and sax->number_integer(
static_cast<number_integer_t
>(-1)
6919 -
static_cast<number_integer_t
>(number));
6954 return get_cbor_string(s) and sax->string(s);
6982 return get_cbor_array(
static_cast<std::size_t
>(current & 0x1F));
6987 return get_number(
input_format_t::cbor, len) and get_cbor_array(
static_cast<std::size_t
>(len));
6993 return get_number(
input_format_t::cbor, len) and get_cbor_array(
static_cast<std::size_t
>(len));
6999 return get_number(
input_format_t::cbor, len) and get_cbor_array(
static_cast<std::size_t
>(len));
7005 return get_number(
input_format_t::cbor, len) and get_cbor_array(
static_cast<std::size_t
>(len));
7009 return get_cbor_array(std::size_t(-1));
7036 return get_cbor_object(
static_cast<std::size_t
>(current & 0x1F));
7041 return get_number(
input_format_t::cbor, len) and get_cbor_object(
static_cast<std::size_t
>(len));
7047 return get_number(
input_format_t::cbor, len) and get_cbor_object(
static_cast<std::size_t
>(len));
7053 return get_number(
input_format_t::cbor, len) and get_cbor_object(
static_cast<std::size_t
>(len));
7059 return get_number(
input_format_t::cbor, len) and get_cbor_object(
static_cast<std::size_t
>(len));
7063 return get_cbor_object(std::size_t(-1));
7066 return sax->boolean(
false);
7069 return sax->boolean(
true);
7076 const int byte1_raw = get();
7081 const int byte2_raw = get();
7087 const auto byte1 =
static_cast<unsigned char>(byte1_raw);
7088 const auto byte2 =
static_cast<unsigned char>(byte2_raw);
7098 const int half = (byte1 << 8) + byte2;
7099 const double val = [&half]
7101 const int exp = (half >> 10) & 0x1F;
7102 const int mant = half & 0x3FF;
7103 assert(0 <=
exp and
exp <= 32);
7104 assert(0 <= mant and mant <= 1024);
7108 return std::ldexp(mant, -24);
7111 ? std::numeric_limits<double>::infinity()
7112 : std::numeric_limits<double>::quiet_NaN();
7114 return std::ldexp(mant + 1024,
exp - 25);
7117 return sax->number_float((half & 0x8000) != 0
7118 ?
static_cast<number_float_t
>(-val)
7119 :
static_cast<number_float_t
>(val),
"");
7125 return get_number(
input_format_t::cbor, number) and sax->number_float(
static_cast<number_float_t
>(number),
"");
7131 return get_number(
input_format_t::cbor, number) and sax->number_float(
static_cast<number_float_t
>(number),
"");
7136 auto last_token = get_token_string();
7153 bool get_cbor_string(string_t& result)
7217 while (get() != 0xFF)
7220 if (not get_cbor_string(chunk))
7224 result.append(chunk);
7231 auto last_token = get_token_string();
7232 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")));
7242 bool get_cbor_array(
const std::size_t len)
7249 if (len != std::size_t(-1))
7251 for (std::size_t i = 0; i < len; ++i)
7261 while (get() != 0xFF)
7270 return sax->end_array();
7278 bool get_cbor_object(
const std::size_t len)
7286 if (len != std::size_t(-1))
7288 for (std::size_t i = 0; i < len; ++i)
7291 if (
JSON_UNLIKELY(not get_cbor_string(key) or not sax->key(key)))
7305 while (get() != 0xFF)
7307 if (
JSON_UNLIKELY(not get_cbor_string(key) or not sax->key(key)))
7320 return sax->end_object();
7330 bool parse_msgpack_internal()
7335 case std::char_traits<char>::eof():
7467 return sax->number_unsigned(
static_cast<number_unsigned_t
>(current));
7486 return get_msgpack_object(
static_cast<std::size_t
>(current & 0x0F));
7505 return get_msgpack_array(
static_cast<std::size_t
>(current & 0x0F));
7542 return get_msgpack_string(s) and sax->string(s);
7549 return sax->boolean(
false);
7552 return sax->boolean(
true);
7557 return get_number(
input_format_t::msgpack, number) and sax->number_float(
static_cast<number_float_t
>(number),
"");
7563 return get_number(
input_format_t::msgpack, number) and sax->number_float(
static_cast<number_float_t
>(number),
"");
7619 return get_msgpack_string(s) and sax->string(s);
7679 return sax->number_integer(
static_cast<int8_t
>(current));
7683 auto last_token = get_token_string();
7699 bool get_msgpack_string(string_t& result)
7765 auto last_token = get_token_string();
7766 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")));
7775 bool get_msgpack_array(
const std::size_t len)
7782 for (std::size_t i = 0; i < len; ++i)
7790 return sax->end_array();
7797 bool get_msgpack_object(
const std::size_t len)
7805 for (std::size_t i = 0; i < len; ++i)
7808 if (
JSON_UNLIKELY(not get_msgpack_string(key) or not sax->key(key)))
7820 return sax->end_object();
7834 bool parse_ubjson_internal(
const bool get_char =
true)
7836 return get_ubjson_value(get_char ? get_ignore_noop() : current);
7853 bool get_ubjson_string(string_t& result,
const bool get_char =
true)
7898 auto last_token = get_token_string();
7899 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")));
7907 bool get_ubjson_size_value(std::size_t& result)
7909 switch (get_ignore_noop())
7918 result =
static_cast<std::size_t
>(number);
7929 result =
static_cast<std::size_t
>(number);
7940 result =
static_cast<std::size_t
>(number);
7951 result =
static_cast<std::size_t
>(number);
7962 result =
static_cast<std::size_t
>(number);
7968 auto last_token = get_token_string();
7969 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")));
7984 bool get_ubjson_size_type(std::pair<std::size_t, int>& result)
7986 result.first = string_t::npos;
7993 result.second = get();
8006 auto last_token = get_token_string();
8007 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")));
8010 return get_ubjson_size_value(result.first);
8012 else if (current ==
'#')
8014 return get_ubjson_size_value(result.first);
8023 bool get_ubjson_value(
const int prefix)
8027 case std::char_traits<char>::eof():
8031 return sax->boolean(
true);
8033 return sax->boolean(
false);
8071 return get_number(
input_format_t::ubjson, number) and sax->number_float(
static_cast<number_float_t
>(number),
"");
8077 return get_number(
input_format_t::ubjson, number) and sax->number_float(
static_cast<number_float_t
>(number),
"");
8089 auto last_token = get_token_string();
8090 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")));
8092 string_t s(1,
static_cast<char>(current));
8093 return sax->string(s);
8099 return get_ubjson_string(s) and sax->string(s);
8103 return get_ubjson_array();
8106 return get_ubjson_object();
8110 auto last_token = get_token_string();
8119 bool get_ubjson_array()
8121 std::pair<std::size_t, int> size_and_type;
8127 if (size_and_type.first != string_t::npos)
8129 if (
JSON_UNLIKELY(not sax->start_array(size_and_type.first)))
8134 if (size_and_type.second != 0)
8136 if (size_and_type.second !=
'N')
8138 for (std::size_t i = 0; i < size_and_type.first; ++i)
8140 if (
JSON_UNLIKELY(not get_ubjson_value(size_and_type.second)))
8149 for (std::size_t i = 0; i < size_and_type.first; ++i)
8165 while (current !=
']')
8175 return sax->end_array();
8181 bool get_ubjson_object()
8183 std::pair<std::size_t, int> size_and_type;
8190 if (size_and_type.first != string_t::npos)
8192 if (
JSON_UNLIKELY(not sax->start_object(size_and_type.first)))
8197 if (size_and_type.second != 0)
8199 for (std::size_t i = 0; i < size_and_type.first; ++i)
8201 if (
JSON_UNLIKELY(not get_ubjson_string(key) or not sax->key(key)))
8205 if (
JSON_UNLIKELY(not get_ubjson_value(size_and_type.second)))
8214 for (std::size_t i = 0; i < size_and_type.first; ++i)
8216 if (
JSON_UNLIKELY(not get_ubjson_string(key) or not sax->key(key)))
8235 while (current !=
'}')
8237 if (
JSON_UNLIKELY(not get_ubjson_string(key,
false) or not sax->key(key)))
8250 return sax->end_object();
8269 return (current = ia->get_character());
8275 int get_ignore_noop()
8281 while (current ==
'N');
8299 template<
typename NumberType,
bool InputIsLittleEndian = false>
8303 std::array<uint8_t,
sizeof(NumberType)> vec;
8304 for (std::size_t i = 0; i <
sizeof(NumberType); ++i)
8313 if (is_little_endian && !InputIsLittleEndian)
8315 vec[
sizeof(NumberType) - i - 1] =
static_cast<uint8_t
>(current);
8319 vec[i] =
static_cast<uint8_t
>(current);
8324 std::memcpy(&result, vec.data(),
sizeof(NumberType));
8342 template<
typename NumberType>
8344 const NumberType len,
8347 bool success =
true;
8348 std::generate_n(std::back_inserter(result), len, [
this, &success, &
format]()
8355 return static_cast<char>(current);
8367 if (
JSON_UNLIKELY(current == std::char_traits<char>::eof()))
8369 return sax->parse_error(chars_read,
"<end of file>",
8378 std::string get_token_string()
const
8381 (std::snprintf)(cr, 3,
"%.2hhX",
static_cast<unsigned char>(current));
8382 return std::string{cr};
8392 const std::string& detail,
8393 const std::string& context)
const
8395 std::string error_msg =
"syntax error while parsing ";
8400 error_msg +=
"CBOR";
8404 error_msg +=
"MessagePack";
8408 error_msg +=
"UBJSON";
8412 error_msg +=
"BSON";
8421 return error_msg +
" " + context +
": " + detail;
8429 int current = std::char_traits<char>::eof();
8432 std::size_t chars_read = 0;
8438 json_sax_t* sax =
nullptr;
10930 using string_t =
typename BasicJsonType::string_t;
10931 using number_float_t =
typename BasicJsonType::number_float_t;
10932 using number_integer_t =
typename BasicJsonType::number_integer_t;
10933 using number_unsigned_t =
typename BasicJsonType::number_unsigned_t;
10934 static constexpr uint8_t UTF8_ACCEPT = 0;
10935 static constexpr uint8_t UTF8_REJECT = 1;
10946 , loc(
std::localeconv())
10947 , thousands_sep(
'\0')
10948 , decimal_point(
'.')
10949 , indent_char(ichar)
10950 , indent_string(512, indent_char)
10951 , error_handler(error_handler_)
10978 void dump(
const BasicJsonType& val,
const bool pretty_print,
10979 const bool ensure_ascii,
10980 const unsigned int indent_step,
10981 const unsigned int current_indent = 0)
10983 switch (val.m_type)
10987 if (val.m_value.object->empty())
10989 o->write_characters(
"{}", 2);
10995 o->write_characters(
"{\n", 2);
10998 const auto new_indent = current_indent + indent_step;
11001 indent_string.resize(indent_string.size() * 2,
' ');
11005 auto i = val.m_value.object->cbegin();
11006 for (std::size_t cnt = 0; cnt < val.m_value.object->size() - 1; ++cnt, ++i)
11008 o->write_characters(indent_string.c_str(), new_indent);
11009 o->write_character(
'\"');
11010 dump_escaped(i->first, ensure_ascii);
11011 o->write_characters(
"\": ", 3);
11012 dump(i->second,
true, ensure_ascii, indent_step, new_indent);
11013 o->write_characters(
",\n", 2);
11017 assert(i != val.m_value.object->cend());
11018 assert(std::next(i) == val.m_value.object->cend());
11019 o->write_characters(indent_string.c_str(), new_indent);
11020 o->write_character(
'\"');
11021 dump_escaped(i->first, ensure_ascii);
11022 o->write_characters(
"\": ", 3);
11023 dump(i->second,
true, ensure_ascii, indent_step, new_indent);
11025 o->write_character(
'\n');
11026 o->write_characters(indent_string.c_str(), current_indent);
11027 o->write_character(
'}');
11031 o->write_character(
'{');
11034 auto i = val.m_value.object->cbegin();
11035 for (std::size_t cnt = 0; cnt < val.m_value.object->size() - 1; ++cnt, ++i)
11037 o->write_character(
'\"');
11038 dump_escaped(i->first, ensure_ascii);
11039 o->write_characters(
"\":", 2);
11040 dump(i->second,
false, ensure_ascii, indent_step, current_indent);
11041 o->write_character(
',');
11045 assert(i != val.m_value.object->cend());
11046 assert(std::next(i) == val.m_value.object->cend());
11047 o->write_character(
'\"');
11048 dump_escaped(i->first, ensure_ascii);
11049 o->write_characters(
"\":", 2);
11050 dump(i->second,
false, ensure_ascii, indent_step, current_indent);
11052 o->write_character(
'}');
11060 if (val.m_value.array->empty())
11062 o->write_characters(
"[]", 2);
11068 o->write_characters(
"[\n", 2);
11071 const auto new_indent = current_indent + indent_step;
11074 indent_string.resize(indent_string.size() * 2,
' ');
11078 for (
auto i = val.m_value.array->cbegin();
11079 i != val.m_value.array->cend() - 1; ++i)
11081 o->write_characters(indent_string.c_str(), new_indent);
11082 dump(*i,
true, ensure_ascii, indent_step, new_indent);
11083 o->write_characters(
",\n", 2);
11087 assert(not val.m_value.array->empty());
11088 o->write_characters(indent_string.c_str(), new_indent);
11089 dump(val.m_value.array->back(),
true, ensure_ascii, indent_step, new_indent);
11091 o->write_character(
'\n');
11092 o->write_characters(indent_string.c_str(), current_indent);
11093 o->write_character(
']');
11097 o->write_character(
'[');
11100 for (
auto i = val.m_value.array->cbegin();
11101 i != val.m_value.array->cend() - 1; ++i)
11103 dump(*i,
false, ensure_ascii, indent_step, current_indent);
11104 o->write_character(
',');
11108 assert(not val.m_value.array->empty());
11109 dump(val.m_value.array->back(),
false, ensure_ascii, indent_step, current_indent);
11111 o->write_character(
']');
11119 o->write_character(
'\"');
11120 dump_escaped(*val.m_value.string, ensure_ascii);
11121 o->write_character(
'\"');
11127 if (val.m_value.boolean)
11129 o->write_characters(
"true", 4);
11133 o->write_characters(
"false", 5);
11140 dump_integer(val.m_value.number_integer);
11146 dump_integer(val.m_value.number_unsigned);
11152 dump_float(val.m_value.number_float);
11158 o->write_characters(
"<discarded>", 11);
11164 o->write_characters(
"null", 4);
11185 void dump_escaped(
const string_t& s,
const bool ensure_ascii)
11187 uint32_t codepoint;
11188 uint8_t state = UTF8_ACCEPT;
11189 std::size_t bytes = 0;
11192 std::size_t bytes_after_last_accept = 0;
11193 std::size_t undumped_chars = 0;
11195 for (std::size_t i = 0; i < s.size(); ++i)
11197 const auto byte =
static_cast<uint8_t
>(s[i]);
11199 switch (
decode(state, codepoint,
byte))
11207 string_buffer[bytes++] =
'\\';
11208 string_buffer[bytes++] =
'b';
11214 string_buffer[bytes++] =
'\\';
11215 string_buffer[bytes++] =
't';
11221 string_buffer[bytes++] =
'\\';
11222 string_buffer[bytes++] =
'n';
11228 string_buffer[bytes++] =
'\\';
11229 string_buffer[bytes++] =
'f';
11235 string_buffer[bytes++] =
'\\';
11236 string_buffer[bytes++] =
'r';
11242 string_buffer[bytes++] =
'\\';
11243 string_buffer[bytes++] =
'\"';
11249 string_buffer[bytes++] =
'\\';
11250 string_buffer[bytes++] =
'\\';
11258 if ((codepoint <= 0x1F) or (ensure_ascii and (codepoint >= 0x7F)))
11260 if (codepoint <= 0xFFFF)
11262 (std::snprintf)(string_buffer.data() + bytes, 7,
"\\u%04x",
11263 static_cast<uint16_t
>(codepoint));
11268 (std::snprintf)(string_buffer.data() + bytes, 13,
"\\u%04x\\u%04x",
11269 static_cast<uint16_t
>(0xD7C0 + (codepoint >> 10)),
11270 static_cast<uint16_t
>(0xDC00 + (codepoint & 0x3FF)));
11278 string_buffer[bytes++] = s[i];
11287 if (string_buffer.size() - bytes < 13)
11289 o->write_characters(string_buffer.data(), bytes);
11294 bytes_after_last_accept = bytes;
11295 undumped_chars = 0;
11301 switch (error_handler)
11305 std::string sn(3,
'\0');
11306 (std::snprintf)(&sn[0], sn.size(),
"%.2X",
byte);
11317 if (undumped_chars > 0)
11324 bytes = bytes_after_last_accept;
11331 string_buffer[bytes++] =
'\\';
11332 string_buffer[bytes++] =
'u';
11333 string_buffer[bytes++] =
'f';
11334 string_buffer[bytes++] =
'f';
11335 string_buffer[bytes++] =
'f';
11336 string_buffer[bytes++] =
'd';
11344 bytes_after_last_accept = bytes;
11347 undumped_chars = 0;
11350 state = UTF8_ACCEPT;
11359 if (not ensure_ascii)
11362 string_buffer[bytes++] = s[i];
11376 o->write_characters(string_buffer.data(), bytes);
11382 switch (error_handler)
11386 std::string sn(3,
'\0');
11387 (std::snprintf)(&sn[0], sn.size(),
"%.2X",
static_cast<uint8_t
>(s.back()));
11394 o->write_characters(string_buffer.data(), bytes_after_last_accept);
11401 o->write_characters(string_buffer.data(), bytes_after_last_accept);
11405 o->write_characters(
"\\ufffd", 6);
11409 o->write_characters(
"\xEF\xBF\xBD", 3);
11427 std::is_same<NumberType, number_unsigned_t>::value or
11428 std::is_same<NumberType, number_integer_t>::value,
11430 void dump_integer(NumberType x)
11435 o->write_character(
'0');
11439 const bool is_negative = std::is_same<NumberType, number_integer_t>::value and not (x >= 0);
11445 assert(i < number_buffer.size() - 1);
11447 const auto digit = std::labs(
static_cast<long>(x % 10));
11448 number_buffer[i++] =
static_cast<char>(
'0' + digit);
11455 assert(i < number_buffer.size() - 2);
11456 number_buffer[i++] =
'-';
11459 std::reverse(number_buffer.begin(), number_buffer.begin() + i);
11460 o->write_characters(number_buffer.data(), i);
11471 void dump_float(number_float_t x)
11474 if (not std::isfinite(x))
11476 o->write_characters(
"null", 4);
11485 static constexpr bool is_ieee_single_or_double
11486 = (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
11487 (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);
11489 dump_float(x, std::integral_constant<bool, is_ieee_single_or_double>());
11492 void dump_float(number_float_t x, std::true_type )
11494 char*
begin = number_buffer.data();
11497 o->write_characters(begin,
static_cast<size_t>(end - begin));
11500 void dump_float(number_float_t x, std::false_type )
11503 static constexpr auto d = std::numeric_limits<number_float_t>::max_digits10;
11506 std::ptrdiff_t len = (std::snprintf)(number_buffer.data(), number_buffer.size(),
"%.*g",
d, x);
11511 assert(
static_cast<std::size_t
>(len) < number_buffer.size());
11514 if (thousands_sep !=
'\0')
11516 const auto end = std::remove(number_buffer.begin(),
11517 number_buffer.begin() + len, thousands_sep);
11518 std::fill(end, number_buffer.end(),
'\0');
11519 assert((end - number_buffer.begin()) <= len);
11520 len = (
end - number_buffer.begin());
11524 if (decimal_point !=
'\0' and decimal_point !=
'.')
11526 const auto dec_pos = std::find(number_buffer.begin(), number_buffer.end(), decimal_point);
11527 if (dec_pos != number_buffer.end())
11533 o->write_characters(number_buffer.data(),
static_cast<std::size_t
>(len));
11536 const bool value_is_int_like =
11537 std::none_of(number_buffer.begin(), number_buffer.begin() + len + 1,
11540 return (c ==
'.' or c ==
'e');
11543 if (value_is_int_like)
11545 o->write_characters(
".0", 2);
11570 static uint8_t decode(uint8_t& state, uint32_t& codep,
const uint8_t
byte)
noexcept
11572 static const std::array<uint8_t, 400> utf8d =
11575 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,
11576 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,
11577 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,
11578 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,
11579 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,
11580 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,
11581 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,
11582 0xA, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x4, 0x3, 0x3,
11583 0xB, 0x6, 0x6, 0x6, 0x5, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8,
11584 0x0, 0x1, 0x2, 0x3, 0x5, 0x8, 0x7, 0x1, 0x1, 0x1, 0x4, 0x6, 0x1, 0x1, 0x1, 0x1,
11585 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,
11586 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,
11587 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,
11588 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
11592 const uint8_t type = utf8d[byte];
11594 codep = (state != UTF8_ACCEPT)
11595 ? (
byte & 0x3fu) | (codep << 6)
11596 : static_cast<uint32_t>(0xff >> type) & (byte);
11598 state = utf8d[256u + state * 16u + type];
11607 std::array<char, 64> number_buffer{{}};
11610 const std::lconv* loc =
nullptr;
11612 const char thousands_sep =
'\0';
11614 const char decimal_point =
'\0';
11617 std::array<char, 512> string_buffer{{}};
11620 const char indent_char;
11622 string_t indent_string;
12551 friend ::nlohmann::json_pointer<basic_json>;
12552 friend ::nlohmann::detail::parser<basic_json>;
12553 friend ::nlohmann::detail::serializer<basic_json>;
12554 template<
typename BasicJsonType>
12555 friend class ::nlohmann::detail::iter_impl;
12556 template<
typename BasicJsonType,
typename CharType>
12557 friend class ::nlohmann::detail::binary_writer;
12558 template<
typename BasicJsonType,
typename SAX>
12559 friend class ::nlohmann::detail::binary_reader;
12560 template<
typename BasicJsonType>
12561 friend class ::nlohmann::detail::json_sax_dom_parser;
12562 template<
typename BasicJsonType>
12563 friend class ::nlohmann::detail::json_sax_dom_callback_parser;
12573 template<
typename BasicJsonType>
12575 template<
typename BasicJsonType>
12577 template<
typename Iterator>
12581 template<
typename CharType>
12593 template<
typename T,
typename SFINAE>
12654 using pointer =
typename std::allocator_traits<allocator_type>::pointer;
12656 using const_pointer =
typename std::allocator_traits<allocator_type>::const_pointer;
12708 result[
"copyright"] =
"(C) 2013-2017 Niels Lohmann";
12709 result[
"name"] =
"JSON for Modern C++";
12710 result[
"url"] =
"https://github.com/nlohmann/json";
12711 result[
"version"][
"string"] =
12720 result[
"platform"] =
"win32";
12721#elif defined __linux__
12722 result[
"platform"] =
"linux";
12723#elif defined __APPLE__
12724 result[
"platform"] =
"apple";
12725#elif defined __unix__
12726 result[
"platform"] =
"unix";
12728 result[
"platform"] =
"unknown";
12731#if defined(__ICC) || defined(__INTEL_COMPILER)
12732 result[
"compiler"] = {{
"family",
"icc"}, {
"version", __INTEL_COMPILER}};
12733#elif defined(__clang__)
12734 result[
"compiler"] = {{
"family",
"clang"}, {
"version", __clang_version__}};
12735#elif defined(__GNUC__) || defined(__GNUG__)
12736 result[
"compiler"] = {{
"family",
"gcc"}, {
"version", std::to_string(__GNUC__) +
"." + std::to_string(__GNUC_MINOR__) +
"." + std::to_string(__GNUC_PATCHLEVEL__)}};
12737#elif defined(__HP_cc) || defined(__HP_aCC)
12738 result[
"compiler"] =
"hp"
12739#elif defined(__IBMCPP__)
12740 result[
"compiler"] = {{
"family",
"ilecpp"}, {
"version", __IBMCPP__}};
12741#elif defined(_MSC_VER)
12742 result[
"compiler"] = {{
"family",
"msvc"}, {
"version", _MSC_VER}};
12743#elif defined(__PGI)
12744 result[
"compiler"] = {{
"family",
"pgcpp"}, {
"version", __PGI}};
12745#elif defined(__SUNPRO_CC)
12746 result[
"compiler"] = {{
"family",
"sunpro"}, {
"version", __SUNPRO_CC}};
12748 result[
"compiler"] = {{
"family",
"unknown"}, {
"version",
"unknown"}};
12752 result[
"compiler"][
"c++"] = std::to_string(__cplusplus);
12754 result[
"compiler"][
"c++"] =
"unknown";
12769#if defined(JSON_HAS_CPP_14)
12772 using object_comparator_t = std::less<>;
12774 using object_comparator_t = std::less<StringType>;
12862 object_comparator_t,
12863 AllocatorType<std::pair<
const StringType,
13207 template<
typename T,
typename... Args>
13208 static T* create(Args&& ... args)
13210 AllocatorType<T> alloc;
13211 using AllocatorTraits = std::allocator_traits<AllocatorType<T>>;
13213 auto deleter = [&](
T * object)
13215 AllocatorTraits::deallocate(alloc,
object, 1);
13217 std::unique_ptr<
T,
decltype(deleter)>
object(AllocatorTraits::allocate(alloc, 1), deleter);
13218 AllocatorTraits::construct(alloc,
object.get(), std::forward<Args>(args)...);
13219 assert(
object !=
nullptr);
13220 return object.release();
13262 number_integer_t number_integer;
13264 number_unsigned_t number_unsigned;
13266 number_float_t number_float;
13269 json_value() =
default;
13271 json_value(boolean_t v) noexcept : boolean(v) {}
13273 json_value(number_integer_t v) noexcept : number_integer(v) {}
13279 json_value(value_t t)
13283 case value_t::object:
13285 object = create<object_t>();
13289 case value_t::array:
13291 array = create<array_t>();
13295 case value_t::string:
13297 string = create<string_t>(
"");
13301 case value_t::boolean:
13303 boolean = boolean_t(
false);
13307 case value_t::number_integer:
13313 case value_t::number_unsigned:
13319 case value_t::number_float:
13325 case value_t::null:
13336 JSON_THROW(other_error::create(500,
"961c151d2e87f2686a955a9be24d316f1362bf21 3.5.0"));
13344 json_value(
const string_t& value)
13346 string = create<string_t>(value);
13350 json_value(string_t&& value)
13352 string = create<string_t>(std::move(value));
13356 json_value(
const object_t& value)
13358 object = create<object_t>(value);
13362 json_value(object_t&& value)
13364 object = create<object_t>(std::move(value));
13368 json_value(
const array_t& value)
13370 array = create<array_t>(value);
13374 json_value(array_t&& value)
13376 array = create<array_t>(std::move(value));
13379 void destroy(value_t t)
noexcept
13383 case value_t::object:
13385 AllocatorType<object_t> alloc;
13386 std::allocator_traits<
decltype(alloc)>::destroy(alloc,
object);
13387 std::allocator_traits<
decltype(alloc)>::deallocate(alloc,
object, 1);
13391 case value_t::array:
13393 AllocatorType<array_t> alloc;
13394 std::allocator_traits<
decltype(alloc)>::destroy(alloc, array);
13395 std::allocator_traits<
decltype(alloc)>::deallocate(alloc, array, 1);
13399 case value_t::string:
13401 AllocatorType<string_t> alloc;
13402 std::allocator_traits<
decltype(alloc)>::destroy(alloc,
string);
13403 std::allocator_traits<
decltype(alloc)>::deallocate(alloc,
string, 1);
13424 void assert_invariant() const noexcept
13426 assert(m_type != value_t::object or m_value.object !=
nullptr);
13427 assert(m_type != value_t::array or m_value.array !=
nullptr);
13428 assert(m_type != value_t::string or m_value.string !=
nullptr);
13545 assert_invariant();
13566 basic_json(std::nullptr_t =
nullptr) noexcept
13569 assert_invariant();
13629 template <
typename CompatibleType,
13630 typename U = detail::uncvref_t<CompatibleType>,
13631 detail::enable_if_t<
13632 not detail::is_basic_json<U>::value and detail::is_compatible_type<basic_json_t, U>::value,
int> = 0>
13633 basic_json(CompatibleType && val)
noexcept(
noexcept(
13634 JSONSerializer<U>::to_json(std::declval<basic_json_t&>(),
13635 std::forward<CompatibleType>(val))))
13637 JSONSerializer<U>::to_json(*
this, std::forward<CompatibleType>(val));
13638 assert_invariant();
13667 template <
typename BasicJsonType,
13668 detail::enable_if_t<
13669 detail::is_basic_json<BasicJsonType>::value and not std::is_same<basic_json, BasicJsonType>::value,
int> = 0>
13670 basic_json(
const BasicJsonType& val)
13672 using other_boolean_t =
typename BasicJsonType::boolean_t;
13673 using other_number_float_t =
typename BasicJsonType::number_float_t;
13674 using other_number_integer_t =
typename BasicJsonType::number_integer_t;
13675 using other_number_unsigned_t =
typename BasicJsonType::number_unsigned_t;
13676 using other_string_t =
typename BasicJsonType::string_t;
13677 using other_object_t =
typename BasicJsonType::object_t;
13678 using other_array_t =
typename BasicJsonType::array_t;
13680 switch (val.type())
13682 case value_t::boolean:
13683 JSONSerializer<other_boolean_t>::to_json(*
this, val.template get<other_boolean_t>());
13685 case value_t::number_float:
13686 JSONSerializer<other_number_float_t>::to_json(*
this, val.template get<other_number_float_t>());
13688 case value_t::number_integer:
13689 JSONSerializer<other_number_integer_t>::to_json(*
this, val.template get<other_number_integer_t>());
13691 case value_t::number_unsigned:
13692 JSONSerializer<other_number_unsigned_t>::to_json(*
this, val.template get<other_number_unsigned_t>());
13694 case value_t::string:
13695 JSONSerializer<other_string_t>::to_json(*
this, val.template get_ref<const other_string_t&>());
13697 case value_t::object:
13698 JSONSerializer<other_object_t>::to_json(*
this, val.template get_ref<const other_object_t&>());
13700 case value_t::array:
13701 JSONSerializer<other_array_t>::to_json(*
this, val.template get_ref<const other_array_t&>());
13703 case value_t::null:
13706 case value_t::discarded:
13707 m_type = value_t::discarded;
13710 assert_invariant();
13787 basic_json(initializer_list_t init,
13788 bool type_deduction =
true,
13789 value_t manual_type = value_t::array)
13793 bool is_an_object = std::all_of(init.begin(), init.end(),
13794 [](
const detail::json_ref<basic_json>& element_ref)
13796 return (element_ref->is_array() and element_ref->size() == 2 and (*element_ref)[0].is_string());
13800 if (not type_deduction)
13803 if (manual_type == value_t::array)
13805 is_an_object =
false;
13809 if (
JSON_UNLIKELY(manual_type == value_t::object and not is_an_object))
13811 JSON_THROW(type_error::create(301,
"cannot create object from initializer list"));
13818 m_type = value_t::object;
13819 m_value = value_t::object;
13821 std::for_each(init.begin(), init.end(), [
this](
const detail::json_ref<basic_json>& element_ref)
13823 auto element = element_ref.moved_or_copied();
13824 m_value.object->emplace(
13825 std::move(*((*element.m_value.array)[0].m_value.string)),
13826 std::move((*element.m_value.array)[1]));
13832 m_type = value_t::array;
13833 m_value.array = create<array_t>(init.begin(), init.end());
13836 assert_invariant();
13876 static basic_json
array(initializer_list_t init = {})
13878 return basic_json(init,
false, value_t::array);
13919 static basic_json
object(initializer_list_t init = {})
13921 return basic_json(init,
false, value_t::object);
13946 basic_json(size_type cnt,
const basic_json& val)
13949 m_value.array = create<array_t>(cnt, val);
13950 assert_invariant();
14008 template<
class InputIT,
typename std::enable_if<
14009 std::is_same<InputIT, typename basic_json_t::iterator>::value or
14010 std::is_same<InputIT, typename basic_json_t::const_iterator>::value,
int>::type = 0>
14011 basic_json(InputIT first, InputIT last)
14013 assert(first.m_object !=
nullptr);
14014 assert(last.m_object !=
nullptr);
14019 JSON_THROW(invalid_iterator::create(201,
"iterators are not compatible"));
14023 m_type = first.m_object->m_type;
14028 case value_t::boolean:
14029 case value_t::number_float:
14030 case value_t::number_integer:
14031 case value_t::number_unsigned:
14032 case value_t::string:
14034 if (
JSON_UNLIKELY(not first.m_it.primitive_iterator.is_begin()
14035 or not last.m_it.primitive_iterator.is_end()))
14037 JSON_THROW(invalid_iterator::create(204,
"iterators out of range"));
14048 case value_t::number_integer:
14050 m_value.number_integer = first.m_object->m_value.number_integer;
14054 case value_t::number_unsigned:
14056 m_value.number_unsigned = first.m_object->m_value.number_unsigned;
14060 case value_t::number_float:
14062 m_value.number_float = first.m_object->m_value.number_float;
14066 case value_t::boolean:
14068 m_value.boolean = first.m_object->m_value.boolean;
14072 case value_t::string:
14074 m_value = *first.m_object->m_value.string;
14078 case value_t::object:
14080 m_value.object = create<object_t>(first.m_it.object_iterator,
14081 last.m_it.object_iterator);
14085 case value_t::array:
14087 m_value.array = create<array_t>(first.m_it.array_iterator,
14088 last.m_it.array_iterator);
14093 JSON_THROW(invalid_iterator::create(206,
"cannot construct with iterators from " +
14094 std::string(first.m_object->type_name())));
14097 assert_invariant();
14106 basic_json(
const detail::json_ref<basic_json>& ref)
14107 : basic_json(ref.moved_or_copied())
14135 basic_json(
const basic_json& other)
14136 : m_type(other.m_type)
14139 other.assert_invariant();
14143 case value_t::object:
14145 m_value = *other.m_value.object;
14149 case value_t::array:
14151 m_value = *other.m_value.array;
14155 case value_t::string:
14157 m_value = *other.m_value.string;
14161 case value_t::boolean:
14163 m_value = other.m_value.boolean;
14167 case value_t::number_integer:
14169 m_value = other.m_value.number_integer;
14173 case value_t::number_unsigned:
14175 m_value = other.m_value.number_unsigned;
14179 case value_t::number_float:
14181 m_value = other.m_value.number_float;
14189 assert_invariant();
14218 basic_json(basic_json&& other)
noexcept
14219 : m_type(std::move(other.m_type)),
14220 m_value(std::move(other.m_value))
14223 other.assert_invariant();
14226 other.m_type = value_t::null;
14227 other.m_value = {};
14229 assert_invariant();
14255 basic_json& operator=(basic_json other)
noexcept (
14256 std::is_nothrow_move_constructible<value_t>::value and
14257 std::is_nothrow_move_assignable<value_t>::value and
14258 std::is_nothrow_move_constructible<json_value>::value and
14259 std::is_nothrow_move_assignable<json_value>::value
14263 other.assert_invariant();
14266 swap(m_type, other.m_type);
14267 swap(m_value, other.m_value);
14269 assert_invariant();
14288 ~basic_json() noexcept
14290 assert_invariant();
14291 m_value.destroy(m_type);
14346 string_t dump(
const int indent = -1,
14347 const char indent_char =
' ',
14348 const bool ensure_ascii =
false,
14349 const error_handler_t error_handler = error_handler_t::strict)
const
14352 serializer s(detail::output_adapter<char, string_t>(result), indent_char, error_handler);
14356 s.dump(*
this,
true, ensure_ascii,
static_cast<unsigned int>(indent));
14360 s.dump(*
this,
false, ensure_ascii, 0);
14398 constexpr value_t type() const noexcept
14428 constexpr bool is_primitive() const noexcept
14430 return is_null() or is_string() or is_boolean() or
is_number();
14455 constexpr
bool is_structured() const noexcept
14457 return is_array() or is_object();
14477 constexpr
bool is_null() const noexcept
14479 return (m_type == value_t::null);
14499 constexpr bool is_boolean() const noexcept
14501 return (m_type == value_t::boolean);
14529 constexpr bool is_number() const noexcept
14531 return is_number_integer() or is_number_float();
14558 constexpr
bool is_number_integer() const noexcept
14560 return (m_type == value_t::number_integer or m_type == value_t::number_unsigned);
14586 constexpr bool is_number_unsigned() const noexcept
14588 return (m_type == value_t::number_unsigned);
14614 constexpr bool is_number_float() const noexcept
14616 return (m_type == value_t::number_float);
14636 constexpr bool is_object() const noexcept
14638 return (m_type == value_t::object);
14658 constexpr bool is_array() const noexcept
14660 return (m_type == value_t::array);
14680 constexpr bool is_string() const noexcept
14682 return (m_type == value_t::string);
14707 constexpr bool is_discarded() const noexcept
14709 return (m_type == value_t::discarded);
14733 constexpr operator value_t() const noexcept
14746 boolean_t get_impl(boolean_t* )
const
14750 return m_value.boolean;
14753 JSON_THROW(type_error::create(302,
"type must be boolean, but is " + std::string(type_name())));
14757 object_t* get_impl_ptr(object_t* )
noexcept
14759 return is_object() ? m_value.object :
nullptr;
14763 constexpr const object_t* get_impl_ptr(
const object_t* )
const noexcept
14765 return is_object() ? m_value.object :
nullptr;
14769 array_t* get_impl_ptr(array_t* )
noexcept
14771 return is_array() ? m_value.array :
nullptr;
14775 constexpr const array_t* get_impl_ptr(
const array_t* )
const noexcept
14777 return is_array() ? m_value.array :
nullptr;
14781 string_t* get_impl_ptr(string_t* )
noexcept
14783 return is_string() ? m_value.string :
nullptr;
14787 constexpr const string_t* get_impl_ptr(
const string_t* )
const noexcept
14789 return is_string() ? m_value.string :
nullptr;
14793 boolean_t* get_impl_ptr(boolean_t* )
noexcept
14795 return is_boolean() ? &m_value.boolean :
nullptr;
14799 constexpr const boolean_t* get_impl_ptr(
const boolean_t* )
const noexcept
14801 return is_boolean() ? &m_value.boolean :
nullptr;
14805 number_integer_t* get_impl_ptr(number_integer_t* )
noexcept
14807 return is_number_integer() ? &m_value.number_integer :
nullptr;
14811 constexpr const number_integer_t* get_impl_ptr(
const number_integer_t* )
const noexcept
14813 return is_number_integer() ? &m_value.number_integer :
nullptr;
14817 number_unsigned_t* get_impl_ptr(number_unsigned_t* )
noexcept
14819 return is_number_unsigned() ? &m_value.number_unsigned :
nullptr;
14823 constexpr const number_unsigned_t* get_impl_ptr(
const number_unsigned_t* )
const noexcept
14825 return is_number_unsigned() ? &m_value.number_unsigned :
nullptr;
14829 number_float_t* get_impl_ptr(number_float_t* )
noexcept
14831 return is_number_float() ? &m_value.number_float :
nullptr;
14835 constexpr const number_float_t* get_impl_ptr(
const number_float_t* )
const noexcept
14837 return is_number_float() ? &m_value.number_float :
nullptr;
14851 template<
typename ReferenceType,
typename ThisType>
14852 static ReferenceType get_ref_impl(ThisType& obj)
14855 auto ptr = obj.template get_ptr<typename std::add_pointer<ReferenceType>::type>();
14862 JSON_THROW(type_error::create(303,
"incompatible ReferenceType for get_ref, actual type is " + std::string(obj.type_name())));
14884 template<
typename BasicJsonType, detail::enable_if_t<
14885 std::is_same<typename std::remove_const<BasicJsonType>::type, basic_json_t>::value,
14887 basic_json
get()
const
14907 template<
typename BasicJsonType, detail::enable_if_t<
14908 not std::is_same<BasicJsonType, basic_json>::value and
14909 detail::is_basic_json<BasicJsonType>::value,
int> = 0>
14910 BasicJsonType
get()
const
14954 template<
typename ValueTypeCV,
typename ValueType = detail::uncvref_t<ValueTypeCV>,
14955 detail::enable_if_t <
14956 not detail::is_basic_json<ValueType>::value and
14957 detail::has_from_json<basic_json_t, ValueType>::value and
14958 not detail::has_non_default_from_json<basic_json_t, ValueType>::value,
14960 ValueType
get() const noexcept(noexcept(
14961 JSONSerializer<ValueType>::from_json(
std::declval<const basic_json_t&>(),
std::declval<ValueType&>())))
14966 static_assert(not std::is_reference<ValueTypeCV>::value,
14967 "get() cannot be used with reference types, you might want to use get_ref()");
14968 static_assert(std::is_default_constructible<ValueType>::value,
14969 "types must be DefaultConstructible when used with get()");
14972 JSONSerializer<ValueType>::from_json(*
this,
ret);
15007 template<
typename ValueTypeCV,
typename ValueType = detail::uncvref_t<ValueTypeCV>,
15008 detail::enable_if_t<not std::is_same<basic_json_t, ValueType>::value and
15009 detail::has_non_default_from_json<basic_json_t, ValueType>::value,
15011 ValueType
get() const noexcept(noexcept(
15012 JSONSerializer<ValueTypeCV>::from_json(
std::declval<const basic_json_t&>())))
15014 static_assert(not std::is_reference<ValueTypeCV>::value,
15015 "get() cannot be used with reference types, you might want to use get_ref()");
15016 return JSONSerializer<ValueTypeCV>::from_json(*
this);
15052 template<
typename ValueType,
15053 detail::enable_if_t <
15054 not detail::is_basic_json<ValueType>::value and
15055 detail::has_from_json<basic_json_t, ValueType>::value,
15057 ValueType & get_to(ValueType& v)
const noexcept(
noexcept(
15058 JSONSerializer<ValueType>::from_json(std::declval<const basic_json_t&>(), v)))
15060 JSONSerializer<ValueType>::from_json(*
this, v);
15091 template<
typename PointerType,
typename std::enable_if<
15092 std::is_pointer<PointerType>::value,
int>::type = 0>
15093 auto get_ptr() noexcept -> decltype(
std::declval<basic_json_t&>().get_impl_ptr(
std::declval<PointerType>()))
15096 return get_impl_ptr(
static_cast<PointerType
>(
nullptr));
15103 template<
typename PointerType,
typename std::enable_if<
15104 std::is_pointer<PointerType>::value and
15105 std::is_const<typename std::remove_pointer<PointerType>::type>::value,
int>::type = 0>
15106 constexpr auto get_ptr() const noexcept -> decltype(
std::declval<const basic_json_t&>().get_impl_ptr(
std::declval<PointerType>()))
15109 return get_impl_ptr(
static_cast<PointerType
>(
nullptr));
15139 template<
typename PointerType,
typename std::enable_if<
15140 std::is_pointer<PointerType>::value,
int>::type = 0>
15141 auto get() noexcept -> decltype(
std::declval<basic_json_t&>().template get_ptr<PointerType>())
15144 return get_ptr<PointerType>();
15151 template<
typename PointerType,
typename std::enable_if<
15152 std::is_pointer<PointerType>::value,
int>::type = 0>
15153 constexpr auto get() const noexcept -> decltype(
std::declval<const basic_json_t&>().template get_ptr<PointerType>())
15156 return get_ptr<PointerType>();
15185 template<
typename ReferenceType,
typename std::enable_if<
15186 std::is_reference<ReferenceType>::value,
int>::type = 0>
15187 ReferenceType get_ref()
15190 return get_ref_impl<ReferenceType>(*
this);
15197 template<
typename ReferenceType,
typename std::enable_if<
15198 std::is_reference<ReferenceType>::value and
15199 std::is_const<typename std::remove_reference<ReferenceType>::type>::value,
int>::type = 0>
15200 ReferenceType get_ref()
const
15203 return get_ref_impl<ReferenceType>(*
this);
15235 template <
typename ValueType,
typename std::enable_if <
15236 not std::is_pointer<ValueType>::value and
15237 not std::is_same<ValueType, detail::json_ref<basic_json>>::value and
15238 not std::is_same<ValueType, typename string_t::value_type>::value and
15239 not detail::is_basic_json<ValueType>::value
15242 and not std::is_same<ValueType, std::initializer_list<typename string_t::value_type>>::value
15243#if defined(JSON_HAS_CPP_17) && defined(_MSC_VER) and _MSC_VER <= 1914
15244 and not std::is_same<ValueType, typename std::string_view>::value
15247 and detail::is_detected<detail::get_template_function, const basic_json_t&, ValueType>::value
15248 ,
int >::type = 0 >
15249 operator ValueType()
const
15252 return get<ValueType>();
15292 reference at(size_type idx)
15299 return m_value.array->at(idx);
15304 JSON_THROW(out_of_range::create(401,
"array index " + std::to_string(idx) +
" is out of range"));
15309 JSON_THROW(type_error::create(304,
"cannot use at() with " + std::string(type_name())));
15339 const_reference at(size_type idx)
const
15346 return m_value.array->at(idx);
15351 JSON_THROW(out_of_range::create(401,
"array index " + std::to_string(idx) +
" is out of range"));
15356 JSON_THROW(type_error::create(304,
"cannot use at() with " + std::string(type_name())));
15390 reference at(
const typename object_t::key_type& key)
15397 return m_value.object->at(key);
15402 JSON_THROW(out_of_range::create(403,
"key '" + key +
"' not found"));
15407 JSON_THROW(type_error::create(304,
"cannot use at() with " + std::string(type_name())));
15441 const_reference at(
const typename object_t::key_type& key)
const
15448 return m_value.object->at(key);
15453 JSON_THROW(out_of_range::create(403,
"key '" + key +
"' not found"));
15458 JSON_THROW(type_error::create(304,
"cannot use at() with " + std::string(type_name())));
15487 reference operator[](size_type idx)
15492 m_type = value_t::array;
15493 m_value.array = create<array_t>();
15494 assert_invariant();
15501 if (idx >= m_value.array->size())
15503 m_value.array->insert(m_value.array->end(),
15504 idx - m_value.array->size() + 1,
15508 return m_value.array->operator[](idx);
15511 JSON_THROW(type_error::create(305,
"cannot use operator[] with a numeric argument with " + std::string(type_name())));
15533 const_reference operator[](size_type idx)
const
15538 return m_value.array->operator[](idx);
15541 JSON_THROW(type_error::create(305,
"cannot use operator[] with a numeric argument with " + std::string(type_name())));
15571 reference operator[](
const typename object_t::key_type& key)
15576 m_type = value_t::object;
15577 m_value.object = create<object_t>();
15578 assert_invariant();
15584 return m_value.object->operator[](key);
15587 JSON_THROW(type_error::create(305,
"cannot use operator[] with a string argument with " + std::string(type_name())));
15620 const_reference operator[](
const typename object_t::key_type& key)
const
15625 assert(m_value.object->find(key) != m_value.object->end());
15626 return m_value.object->find(key)->second;
15629 JSON_THROW(type_error::create(305,
"cannot use operator[] with a string argument with " + std::string(type_name())));
15659 template<
typename T>
15660 reference operator[](
T* key)
15665 m_type = value_t::object;
15666 m_value = value_t::object;
15667 assert_invariant();
15673 return m_value.object->operator[](key);
15676 JSON_THROW(type_error::create(305,
"cannot use operator[] with a string argument with " + std::string(type_name())));
15709 template<
typename T>
15710 const_reference operator[](
T* key)
const
15715 assert(m_value.object->find(key) != m_value.object->end());
15716 return m_value.object->find(key)->second;
15719 JSON_THROW(type_error::create(305,
"cannot use operator[] with a string argument with " + std::string(type_name())));
15770 template<
class ValueType,
typename std::enable_if<
15771 std::is_convertible<basic_json_t, ValueType>::value,
int>::type = 0>
15772 ValueType value(
const typename object_t::key_type& key,
const ValueType& default_value)
const
15778 const auto it =
find(key);
15784 return default_value;
15787 JSON_THROW(type_error::create(306,
"cannot use value() with " + std::string(type_name())));
15794 string_t value(
const typename object_t::key_type& key,
const char* default_value)
const
15796 return value(key, string_t(default_value));
15840 template<
class ValueType,
typename std::enable_if<
15841 std::is_convertible<basic_json_t, ValueType>::value,
int>::type = 0>
15842 ValueType value(
const json_pointer& ptr,
const ValueType& default_value)
const
15850 return ptr.get_checked(
this);
15854 return default_value;
15858 JSON_THROW(type_error::create(306,
"cannot use value() with " + std::string(type_name())));
15865 string_t value(
const json_pointer& ptr,
const char* default_value)
const
15867 return value(ptr, string_t(default_value));
15903 const_reference front()
const
15949 const_reference back()
const
16002 template<
class IteratorType,
typename std::enable_if<
16003 std::is_same<IteratorType, typename basic_json_t::iterator>::value or
16004 std::is_same<IteratorType, typename basic_json_t::const_iterator>::value,
int>::type
16006 IteratorType erase(IteratorType pos)
16011 JSON_THROW(invalid_iterator::create(202,
"iterator does not fit current value"));
16014 IteratorType result =
end();
16018 case value_t::boolean:
16019 case value_t::number_float:
16020 case value_t::number_integer:
16021 case value_t::number_unsigned:
16022 case value_t::string:
16024 if (
JSON_UNLIKELY(not pos.m_it.primitive_iterator.is_begin()))
16026 JSON_THROW(invalid_iterator::create(205,
"iterator out of range"));
16031 AllocatorType<string_t> alloc;
16032 std::allocator_traits<
decltype(alloc)>::destroy(alloc, m_value.string);
16033 std::allocator_traits<
decltype(alloc)>::deallocate(alloc, m_value.string, 1);
16034 m_value.string =
nullptr;
16037 m_type = value_t::null;
16038 assert_invariant();
16042 case value_t::object:
16044 result.m_it.object_iterator = m_value.object->erase(pos.m_it.object_iterator);
16048 case value_t::array:
16050 result.m_it.array_iterator = m_value.array->erase(pos.m_it.array_iterator);
16055 JSON_THROW(type_error::create(307,
"cannot use erase() with " + std::string(type_name())));
16107 template<
class IteratorType,
typename std::enable_if<
16108 std::is_same<IteratorType, typename basic_json_t::iterator>::value or
16109 std::is_same<IteratorType, typename basic_json_t::const_iterator>::value,
int>::type
16111 IteratorType erase(IteratorType first, IteratorType last)
16114 if (
JSON_UNLIKELY(
this != first.m_object or
this != last.m_object))
16116 JSON_THROW(invalid_iterator::create(203,
"iterators do not fit current value"));
16119 IteratorType result =
end();
16123 case value_t::boolean:
16124 case value_t::number_float:
16125 case value_t::number_integer:
16126 case value_t::number_unsigned:
16127 case value_t::string:
16129 if (
JSON_LIKELY(not first.m_it.primitive_iterator.is_begin()
16130 or not last.m_it.primitive_iterator.is_end()))
16132 JSON_THROW(invalid_iterator::create(204,
"iterators out of range"));
16137 AllocatorType<string_t> alloc;
16138 std::allocator_traits<
decltype(alloc)>::destroy(alloc, m_value.string);
16139 std::allocator_traits<
decltype(alloc)>::deallocate(alloc, m_value.string, 1);
16140 m_value.string =
nullptr;
16143 m_type = value_t::null;
16144 assert_invariant();
16148 case value_t::object:
16150 result.m_it.object_iterator = m_value.object->erase(first.m_it.object_iterator,
16151 last.m_it.object_iterator);
16155 case value_t::array:
16157 result.m_it.array_iterator = m_value.array->erase(first.m_it.array_iterator,
16158 last.m_it.array_iterator);
16163 JSON_THROW(type_error::create(307,
"cannot use erase() with " + std::string(type_name())));
16198 size_type erase(
const typename object_t::key_type& key)
16203 return m_value.object->erase(key);
16206 JSON_THROW(type_error::create(307,
"cannot use erase() with " + std::string(type_name())));
16233 void erase(
const size_type idx)
16240 JSON_THROW(out_of_range::create(401,
"array index " + std::to_string(idx) +
" is out of range"));
16243 m_value.array->erase(m_value.array->begin() +
static_cast<difference_type
>(idx));
16247 JSON_THROW(type_error::create(307,
"cannot use erase() with " + std::string(type_name())));
16283 template<
typename KeyT>
16284 iterator
find(KeyT&& key)
16286 auto result =
end();
16290 result.m_it.object_iterator = m_value.object->find(std::forward<KeyT>(key));
16300 template<
typename KeyT>
16301 const_iterator
find(KeyT&& key)
const
16303 auto result = cend();
16307 result.m_it.object_iterator = m_value.object->find(std::forward<KeyT>(key));
16334 template<
typename KeyT>
16335 size_type
count(KeyT&& key)
const
16338 return is_object() ? m_value.object->count(std::forward<KeyT>(key)) : 0;
16375 iterator
begin() noexcept
16377 iterator result(
this);
16378 result.set_begin();
16385 const_iterator
begin() const noexcept
16415 const_iterator cbegin() const noexcept
16417 const_iterator result(
this);
16418 result.set_begin();
16446 iterator
end() noexcept
16448 iterator result(
this);
16456 const_iterator
end() const noexcept
16486 const_iterator cend() const noexcept
16488 const_iterator result(
this);
16516 reverse_iterator rbegin() noexcept
16518 return reverse_iterator(
end());
16524 const_reverse_iterator rbegin() const noexcept
16553 reverse_iterator rend() noexcept
16555 return reverse_iterator(
begin());
16561 const_reverse_iterator rend() const noexcept
16590 const_reverse_iterator crbegin() const noexcept
16592 return const_reverse_iterator(cend());
16619 const_reverse_iterator crend() const noexcept
16621 return const_reverse_iterator(cbegin());
16683 static iteration_proxy<iterator> iterator_wrapper(reference ref)
noexcept
16685 return ref.items();
16692 static iteration_proxy<const_iterator> iterator_wrapper(const_reference ref)
noexcept
16694 return ref.items();
16760 iteration_proxy<iterator> items() noexcept
16762 return iteration_proxy<iterator>(*
this);
16768 iteration_proxy<const_iterator> items() const noexcept
16770 return iteration_proxy<const_iterator>(*
this);
16824 bool empty() const noexcept
16828 case value_t::null:
16834 case value_t::array:
16837 return m_value.array->empty();
16840 case value_t::object:
16843 return m_value.object->empty();
16896 size_type
size() const noexcept
16900 case value_t::null:
16906 case value_t::array:
16909 return m_value.array->size();
16912 case value_t::object:
16915 return m_value.object->size();
16966 size_type max_size() const noexcept
16970 case value_t::array:
16973 return m_value.array->max_size();
16976 case value_t::object:
16979 return m_value.object->max_size();
17036 void clear() noexcept
17040 case value_t::number_integer:
17042 m_value.number_integer = 0;
17046 case value_t::number_unsigned:
17048 m_value.number_unsigned = 0;
17052 case value_t::number_float:
17054 m_value.number_float = 0.0;
17058 case value_t::boolean:
17060 m_value.boolean =
false;
17064 case value_t::string:
17066 m_value.string->clear();
17070 case value_t::array:
17072 m_value.array->clear();
17076 case value_t::object:
17078 m_value.object->clear();
17107 void push_back(basic_json&& val)
17112 JSON_THROW(type_error::create(308,
"cannot use push_back() with " + std::string(type_name())));
17118 m_type = value_t::array;
17119 m_value = value_t::array;
17120 assert_invariant();
17124 m_value.array->push_back(std::move(val));
17126 val.m_type = value_t::null;
17135 push_back(std::move(val));
17143 void push_back(
const basic_json& val)
17148 JSON_THROW(type_error::create(308,
"cannot use push_back() with " + std::string(type_name())));
17154 m_type = value_t::array;
17155 m_value = value_t::array;
17156 assert_invariant();
17160 m_value.array->push_back(val);
17193 void push_back(
const typename object_t::value_type& val)
17198 JSON_THROW(type_error::create(308,
"cannot use push_back() with " + std::string(type_name())));
17204 m_type = value_t::object;
17205 m_value = value_t::object;
17206 assert_invariant();
17210 m_value.object->insert(val);
17217 reference
operator+=(
const typename object_t::value_type& val)
17248 void push_back(initializer_list_t init)
17250 if (is_object() and init.size() == 2 and (*init.begin())->is_string())
17252 basic_json&& key = init.begin()->moved_or_copied();
17253 push_back(
typename object_t::value_type(
17254 std::move(key.get_ref<string_t&>()), (init.begin() + 1)->moved_or_copied()));
17258 push_back(basic_json(init));
17266 reference
operator+=(initializer_list_t init)
17293 template<
class... Args>
17294 void emplace_back(Args&& ... args)
17299 JSON_THROW(type_error::create(311,
"cannot use emplace_back() with " + std::string(type_name())));
17305 m_type = value_t::array;
17306 m_value = value_t::array;
17307 assert_invariant();
17311 m_value.array->emplace_back(std::forward<Args>(args)...);
17341 template<
class... Args>
17342 std::pair<iterator, bool> emplace(Args&& ... args)
17347 JSON_THROW(type_error::create(311,
"cannot use emplace() with " + std::string(type_name())));
17353 m_type = value_t::object;
17354 m_value = value_t::object;
17355 assert_invariant();
17359 auto res = m_value.object->emplace(std::forward<Args>(args)...);
17362 it.m_it.object_iterator = res.first;
17365 return {it, res.second};
17371 template<
typename... Args>
17372 iterator insert_iterator(const_iterator pos, Args&& ... args)
17374 iterator result(
this);
17375 assert(m_value.array !=
nullptr);
17377 auto insert_pos = std::distance(m_value.array->begin(), pos.m_it.array_iterator);
17378 m_value.array->insert(pos.m_it.array_iterator, std::forward<Args>(args)...);
17379 result.m_it.array_iterator = m_value.array->begin() + insert_pos;
17410 iterator
insert(const_iterator pos,
const basic_json& val)
17418 JSON_THROW(invalid_iterator::create(202,
"iterator does not fit current value"));
17422 return insert_iterator(pos, val);
17425 JSON_THROW(type_error::create(309,
"cannot use insert() with " + std::string(type_name())));
17432 iterator
insert(const_iterator pos, basic_json&& val)
17434 return insert(pos, val);
17461 iterator
insert(const_iterator pos, size_type cnt,
const basic_json& val)
17469 JSON_THROW(invalid_iterator::create(202,
"iterator does not fit current value"));
17473 return insert_iterator(pos, cnt, val);
17476 JSON_THROW(type_error::create(309,
"cannot use insert() with " + std::string(type_name())));
17509 iterator
insert(const_iterator pos, const_iterator first, const_iterator last)
17514 JSON_THROW(type_error::create(309,
"cannot use insert() with " + std::string(type_name())));
17520 JSON_THROW(invalid_iterator::create(202,
"iterator does not fit current value"));
17526 JSON_THROW(invalid_iterator::create(210,
"iterators do not fit"));
17531 JSON_THROW(invalid_iterator::create(211,
"passed iterators may not belong to container"));
17535 return insert_iterator(pos, first.m_it.array_iterator, last.m_it.array_iterator);
17562 iterator
insert(const_iterator pos, initializer_list_t ilist)
17567 JSON_THROW(type_error::create(309,
"cannot use insert() with " + std::string(type_name())));
17573 JSON_THROW(invalid_iterator::create(202,
"iterator does not fit current value"));
17577 return insert_iterator(pos, ilist.begin(), ilist.end());
17603 void insert(const_iterator first, const_iterator last)
17608 JSON_THROW(type_error::create(309,
"cannot use insert() with " + std::string(type_name())));
17614 JSON_THROW(invalid_iterator::create(210,
"iterators do not fit"));
17620 JSON_THROW(invalid_iterator::create(202,
"iterators first and last must point to objects"));
17623 m_value.object->insert(first.m_it.object_iterator, last.m_it.object_iterator);
17645 void update(const_reference j)
17650 m_type = value_t::object;
17651 m_value.object = create<object_t>();
17652 assert_invariant();
17657 JSON_THROW(type_error::create(312,
"cannot use update() with " + std::string(type_name())));
17661 JSON_THROW(type_error::create(312,
"cannot use update() with " + std::string(j.type_name())));
17664 for (
auto it = j.cbegin(); it != j.cend(); ++it)
17666 m_value.object->operator[](it.key()) = it.value();
17696 void update(const_iterator first, const_iterator last)
17701 m_type = value_t::object;
17702 m_value.object = create<object_t>();
17703 assert_invariant();
17708 JSON_THROW(type_error::create(312,
"cannot use update() with " + std::string(type_name())));
17714 JSON_THROW(invalid_iterator::create(210,
"iterators do not fit"));
17719 or not last.m_object->is_object()))
17721 JSON_THROW(invalid_iterator::create(202,
"iterators first and last must point to objects"));
17724 for (
auto it = first; it != last; ++it)
17726 m_value.object->operator[](it.key()) = it.value();
17747 void swap(reference other)
noexcept (
17748 std::is_nothrow_move_constructible<value_t>::value and
17749 std::is_nothrow_move_assignable<value_t>::value and
17750 std::is_nothrow_move_constructible<json_value>::value and
17751 std::is_nothrow_move_assignable<json_value>::value
17754 std::swap(m_type, other.m_type);
17755 std::swap(m_value, other.m_value);
17756 assert_invariant();
17779 void swap(array_t& other)
17784 std::swap(*(m_value.array), other);
17788 JSON_THROW(type_error::create(310,
"cannot use swap() with " + std::string(type_name())));
17812 void swap(object_t& other)
17817 std::swap(*(m_value.object), other);
17821 JSON_THROW(type_error::create(310,
"cannot use swap() with " + std::string(type_name())));
17845 void swap(string_t& other)
17850 std::swap(*(m_value.string), other);
17854 JSON_THROW(type_error::create(310,
"cannot use swap() with " + std::string(type_name())));
17907 friend bool operator==(const_reference lhs, const_reference rhs)
noexcept
17909 const auto lhs_type = lhs.type();
17910 const auto rhs_type = rhs.type();
17912 if (lhs_type == rhs_type)
17916 case value_t::array:
17917 return (*lhs.m_value.array == *rhs.m_value.array);
17919 case value_t::object:
17920 return (*lhs.m_value.object == *rhs.m_value.object);
17922 case value_t::null:
17925 case value_t::string:
17926 return (*lhs.m_value.string == *rhs.m_value.string);
17928 case value_t::boolean:
17929 return (lhs.m_value.boolean == rhs.m_value.boolean);
17931 case value_t::number_integer:
17932 return (lhs.m_value.number_integer == rhs.m_value.number_integer);
17934 case value_t::number_unsigned:
17935 return (lhs.m_value.number_unsigned == rhs.m_value.number_unsigned);
17937 case value_t::number_float:
17938 return (lhs.m_value.number_float == rhs.m_value.number_float);
17944 else if (lhs_type == value_t::number_integer and rhs_type == value_t::number_float)
17946 return (
static_cast<number_float_t
>(lhs.m_value.number_integer) == rhs.m_value.number_float);
17948 else if (lhs_type == value_t::number_float and rhs_type == value_t::number_integer)
17950 return (lhs.m_value.number_float ==
static_cast<number_float_t
>(rhs.m_value.number_integer));
17952 else if (lhs_type == value_t::number_unsigned and rhs_type == value_t::number_float)
17954 return (
static_cast<number_float_t
>(lhs.m_value.number_unsigned) == rhs.m_value.number_float);
17956 else if (lhs_type == value_t::number_float and rhs_type == value_t::number_unsigned)
17958 return (lhs.m_value.number_float ==
static_cast<number_float_t
>(rhs.m_value.number_unsigned));
17960 else if (lhs_type == value_t::number_unsigned and rhs_type == value_t::number_integer)
17962 return (
static_cast<number_integer_t
>(lhs.m_value.number_unsigned) == rhs.m_value.number_integer);
17964 else if (lhs_type == value_t::number_integer and rhs_type == value_t::number_unsigned)
17966 return (lhs.m_value.number_integer ==
static_cast<number_integer_t
>(rhs.m_value.number_unsigned));
17976 template<
typename ScalarType,
typename std::enable_if<
17977 std::is_scalar<ScalarType>::value,
int>::type = 0>
17978 friend bool operator==(const_reference lhs,
const ScalarType rhs)
noexcept
17980 return (lhs == basic_json(rhs));
17987 template<
typename ScalarType,
typename std::enable_if<
17988 std::is_scalar<ScalarType>::value,
int>::type = 0>
17989 friend bool operator==(
const ScalarType lhs, const_reference rhs)
noexcept
17991 return (basic_json(lhs) == rhs);
18012 friend bool operator!=(const_reference lhs, const_reference rhs)
noexcept
18014 return not (lhs == rhs);
18021 template<
typename ScalarType,
typename std::enable_if<
18022 std::is_scalar<ScalarType>::value,
int>::type = 0>
18023 friend bool operator!=(const_reference lhs,
const ScalarType rhs)
noexcept
18025 return (lhs != basic_json(rhs));
18032 template<
typename ScalarType,
typename std::enable_if<
18033 std::is_scalar<ScalarType>::value,
int>::type = 0>
18034 friend bool operator!=(
const ScalarType lhs, const_reference rhs)
noexcept
18036 return (basic_json(lhs) != rhs);
18065 friend bool operator<(const_reference lhs, const_reference rhs)
noexcept
18067 const auto lhs_type = lhs.type();
18068 const auto rhs_type = rhs.type();
18070 if (lhs_type == rhs_type)
18074 case value_t::array:
18075 return (*lhs.m_value.array) < (*rhs.m_value.array);
18077 case value_t::object:
18078 return *lhs.m_value.object < *rhs.m_value.object;
18080 case value_t::null:
18083 case value_t::string:
18084 return *lhs.m_value.string < *rhs.m_value.string;
18086 case value_t::boolean:
18087 return lhs.m_value.boolean < rhs.m_value.boolean;
18089 case value_t::number_integer:
18090 return lhs.m_value.number_integer < rhs.m_value.number_integer;
18092 case value_t::number_unsigned:
18093 return lhs.m_value.number_unsigned < rhs.m_value.number_unsigned;
18095 case value_t::number_float:
18096 return lhs.m_value.number_float < rhs.m_value.number_float;
18102 else if (lhs_type == value_t::number_integer and rhs_type == value_t::number_float)
18104 return static_cast<number_float_t
>(lhs.m_value.number_integer) < rhs.m_value.number_float;
18106 else if (lhs_type == value_t::number_float and rhs_type == value_t::number_integer)
18108 return lhs.m_value.number_float <
static_cast<number_float_t
>(rhs.m_value.number_integer);
18110 else if (lhs_type == value_t::number_unsigned and rhs_type == value_t::number_float)
18112 return static_cast<number_float_t
>(lhs.m_value.number_unsigned) < rhs.m_value.number_float;
18114 else if (lhs_type == value_t::number_float and rhs_type == value_t::number_unsigned)
18116 return lhs.m_value.number_float <
static_cast<number_float_t
>(rhs.m_value.number_unsigned);
18118 else if (lhs_type == value_t::number_integer and rhs_type == value_t::number_unsigned)
18120 return lhs.m_value.number_integer <
static_cast<number_integer_t
>(rhs.m_value.number_unsigned);
18122 else if (lhs_type == value_t::number_unsigned and rhs_type == value_t::number_integer)
18124 return static_cast<number_integer_t
>(lhs.m_value.number_unsigned) < rhs.m_value.number_integer;
18137 template<
typename ScalarType,
typename std::enable_if<
18138 std::is_scalar<ScalarType>::value,
int>::type = 0>
18139 friend bool operator<(const_reference lhs,
const ScalarType rhs)
noexcept
18141 return (lhs < basic_json(rhs));
18148 template<
typename ScalarType,
typename std::enable_if<
18149 std::is_scalar<ScalarType>::value,
int>::type = 0>
18150 friend bool operator<(
const ScalarType lhs, const_reference rhs)
noexcept
18152 return (basic_json(lhs) < rhs);
18174 friend bool operator<=(const_reference lhs, const_reference rhs)
noexcept
18176 return not (rhs < lhs);
18183 template<
typename ScalarType,
typename std::enable_if<
18184 std::is_scalar<ScalarType>::value,
int>::type = 0>
18185 friend bool operator<=(const_reference lhs,
const ScalarType rhs)
noexcept
18187 return (lhs <= basic_json(rhs));
18194 template<
typename ScalarType,
typename std::enable_if<
18195 std::is_scalar<ScalarType>::value,
int>::type = 0>
18196 friend bool operator<=(
const ScalarType lhs, const_reference rhs)
noexcept
18198 return (basic_json(lhs) <= rhs);
18220 friend bool operator>(const_reference lhs, const_reference rhs)
noexcept
18222 return not (lhs <= rhs);
18229 template<
typename ScalarType,
typename std::enable_if<
18230 std::is_scalar<ScalarType>::value,
int>::type = 0>
18231 friend bool operator>(const_reference lhs,
const ScalarType rhs)
noexcept
18233 return (lhs > basic_json(rhs));
18240 template<
typename ScalarType,
typename std::enable_if<
18241 std::is_scalar<ScalarType>::value,
int>::type = 0>
18242 friend bool operator>(
const ScalarType lhs, const_reference rhs)
noexcept
18244 return (basic_json(lhs) > rhs);
18266 friend bool operator>=(const_reference lhs, const_reference rhs)
noexcept
18268 return not (lhs < rhs);
18275 template<
typename ScalarType,
typename std::enable_if<
18276 std::is_scalar<ScalarType>::value,
int>::type = 0>
18277 friend bool operator>=(const_reference lhs,
const ScalarType rhs)
noexcept
18279 return (lhs >= basic_json(rhs));
18286 template<
typename ScalarType,
typename std::enable_if<
18287 std::is_scalar<ScalarType>::value,
int>::type = 0>
18288 friend bool operator>=(
const ScalarType lhs, const_reference rhs)
noexcept
18290 return (basic_json(lhs) >= rhs);
18333 friend std::ostream&
operator<<(std::ostream& o,
const basic_json& j)
18336 const bool pretty_print = (o.width() > 0);
18337 const auto indentation = (pretty_print ? o.width() : 0);
18343 serializer s(detail::output_adapter<char>(o), o.fill());
18344 s.dump(j, pretty_print,
false,
static_cast<unsigned int>(indentation));
18357 friend std::ostream&
operator>>(
const basic_json& j, std::ostream& o)
18436 static basic_json parse(detail::input_adapter&& i,
18437 const parser_callback_t cb =
nullptr,
18438 const bool allow_exceptions =
true)
18441 parser(i, cb, allow_exceptions).parse(
true, result);
18445 static bool accept(detail::input_adapter&& i)
18447 return parser(i).accept(
true);
18506 template <
typename SAX>
18507 static bool sax_parse(detail::input_adapter&& i, SAX* sax,
18508 input_format_t
format = input_format_t::json,
18509 const bool strict =
true)
18514 case input_format_t::json:
18515 return parser(std::move(i)).sax_parse(sax, strict);
18517 return detail::binary_reader<basic_json, SAX>(std::move(i)).sax_parse(
format, sax, strict);
18568 template<
class IteratorType,
typename std::enable_if<
18570 std::random_access_iterator_tag,
18571 typename std::iterator_traits<IteratorType>::iterator_category>::value,
int>::type = 0>
18572 static basic_json parse(IteratorType first, IteratorType last,
18573 const parser_callback_t cb =
nullptr,
18574 const bool allow_exceptions =
true)
18577 parser(detail::input_adapter(first, last), cb, allow_exceptions).parse(
true, result);
18581 template<
class IteratorType,
typename std::enable_if<
18583 std::random_access_iterator_tag,
18584 typename std::iterator_traits<IteratorType>::iterator_category>::value,
int>::type = 0>
18585 static bool accept(IteratorType first, IteratorType last)
18587 return parser(detail::input_adapter(first, last)).accept(
true);
18590 template<
class IteratorType,
class SAX,
typename std::enable_if<
18592 std::random_access_iterator_tag,
18593 typename std::iterator_traits<IteratorType>::iterator_category>::value,
int>::type = 0>
18594 static bool sax_parse(IteratorType first, IteratorType last, SAX* sax)
18596 return parser(detail::input_adapter(first, last)).sax_parse(sax);
18608 friend std::istream&
operator<<(basic_json& j, std::istream& i)
18638 friend std::istream&
operator>>(std::istream& i, basic_json& j)
18640 parser(detail::input_adapter(i)).parse(
false, j);
18680 const char* type_name() const noexcept
18685 case value_t::null:
18687 case value_t::object:
18689 case value_t::array:
18691 case value_t::string:
18693 case value_t::boolean:
18695 case value_t::discarded:
18696 return "discarded";
18710 value_t m_type = value_t::null;
18811 static std::vector<uint8_t> to_cbor(
const basic_json& j)
18813 std::vector<uint8_t> result;
18814 to_cbor(j, result);
18818 static void to_cbor(
const basic_json& j, detail::output_adapter<uint8_t> o)
18820 binary_writer<uint8_t>(o).write_cbor(j);
18823 static void to_cbor(
const basic_json& j, detail::output_adapter<char> o)
18825 binary_writer<char>(o).write_cbor(j);
18907 static std::vector<uint8_t> to_msgpack(
const basic_json& j)
18909 std::vector<uint8_t> result;
18910 to_msgpack(j, result);
18914 static void to_msgpack(
const basic_json& j, detail::output_adapter<uint8_t> o)
18916 binary_writer<uint8_t>(o).write_msgpack(j);
18919 static void to_msgpack(
const basic_json& j, detail::output_adapter<char> o)
18921 binary_writer<char>(o).write_msgpack(j);
19004 static std::vector<uint8_t> to_ubjson(
const basic_json& j,
19005 const bool use_size =
false,
19006 const bool use_type =
false)
19008 std::vector<uint8_t> result;
19009 to_ubjson(j, result, use_size, use_type);
19013 static void to_ubjson(
const basic_json& j, detail::output_adapter<uint8_t> o,
19014 const bool use_size =
false,
const bool use_type =
false)
19016 binary_writer<uint8_t>(o).write_ubjson(j, use_size, use_type);
19019 static void to_ubjson(
const basic_json& j, detail::output_adapter<char> o,
19020 const bool use_size =
false,
const bool use_type =
false)
19022 binary_writer<char>(o).write_ubjson(j, use_size, use_type);
19081 static std::vector<uint8_t> to_bson(
const basic_json& j)
19083 std::vector<uint8_t> result;
19084 to_bson(j, result);
19096 static void to_bson(
const basic_json& j, detail::output_adapter<uint8_t> o)
19098 binary_writer<uint8_t>(o).write_bson(j);
19104 static void to_bson(
const basic_json& j, detail::output_adapter<char> o)
19106 binary_writer<char>(o).write_bson(j);
19207 static basic_json from_cbor(detail::input_adapter&& i,
19208 const bool strict =
true,
19209 const bool allow_exceptions =
true)
19212 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
19213 const bool res = binary_reader(detail::input_adapter(i)).sax_parse(input_format_t::cbor, &sdp, strict);
19214 return res ? result : basic_json(value_t::discarded);
19220 template<
typename A1,
typename A2,
19221 detail::enable_if_t<std::is_constructible<detail::input_adapter, A1, A2>::value,
int> = 0>
19222 static basic_json from_cbor(A1 && a1, A2 && a2,
19223 const bool strict =
true,
19224 const bool allow_exceptions =
true)
19227 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
19228 const bool res = binary_reader(detail::input_adapter(std::forward<A1>(a1), std::forward<A2>(a2))).sax_parse(input_format_t::cbor, &sdp, strict);
19229 return res ? result : basic_json(value_t::discarded);
19312 static basic_json from_msgpack(detail::input_adapter&& i,
19313 const bool strict =
true,
19314 const bool allow_exceptions =
true)
19317 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
19318 const bool res = binary_reader(detail::input_adapter(i)).sax_parse(input_format_t::msgpack, &sdp, strict);
19319 return res ? result : basic_json(value_t::discarded);
19325 template<
typename A1,
typename A2,
19326 detail::enable_if_t<std::is_constructible<detail::input_adapter, A1, A2>::value,
int> = 0>
19327 static basic_json from_msgpack(A1 && a1, A2 && a2,
19328 const bool strict =
true,
19329 const bool allow_exceptions =
true)
19332 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
19333 const bool res = binary_reader(detail::input_adapter(std::forward<A1>(a1), std::forward<A2>(a2))).sax_parse(input_format_t::msgpack, &sdp, strict);
19334 return res ? result : basic_json(value_t::discarded);
19396 static basic_json from_ubjson(detail::input_adapter&& i,
19397 const bool strict =
true,
19398 const bool allow_exceptions =
true)
19401 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
19402 const bool res = binary_reader(detail::input_adapter(i)).sax_parse(input_format_t::ubjson, &sdp, strict);
19403 return res ? result : basic_json(value_t::discarded);
19409 template<
typename A1,
typename A2,
19410 detail::enable_if_t<std::is_constructible<detail::input_adapter, A1, A2>::value,
int> = 0>
19411 static basic_json from_ubjson(A1 && a1, A2 && a2,
19412 const bool strict =
true,
19413 const bool allow_exceptions =
true)
19416 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
19417 const bool res = binary_reader(detail::input_adapter(std::forward<A1>(a1), std::forward<A2>(a2))).sax_parse(input_format_t::ubjson, &sdp, strict);
19418 return res ? result : basic_json(value_t::discarded);
19479 static basic_json from_bson(detail::input_adapter&& i,
19480 const bool strict =
true,
19481 const bool allow_exceptions =
true)
19484 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
19485 const bool res = binary_reader(detail::input_adapter(i)).sax_parse(input_format_t::bson, &sdp, strict);
19486 return res ? result : basic_json(value_t::discarded);
19492 template<
typename A1,
typename A2,
19493 detail::enable_if_t<std::is_constructible<detail::input_adapter, A1, A2>::value,
int> = 0>
19494 static basic_json from_bson(A1 && a1, A2 && a2,
19495 const bool strict =
true,
19496 const bool allow_exceptions =
true)
19499 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
19500 const bool res = binary_reader(detail::input_adapter(std::forward<A1>(a1), std::forward<A2>(a2))).sax_parse(input_format_t::bson, &sdp, strict);
19501 return res ? result : basic_json(value_t::discarded);
19548 reference operator[](
const json_pointer& ptr)
19550 return ptr.get_unchecked(
this);
19576 const_reference operator[](
const json_pointer& ptr)
const
19578 return ptr.get_unchecked(
this);
19619 reference at(
const json_pointer& ptr)
19621 return ptr.get_checked(
this);
19662 const_reference at(
const json_pointer& ptr)
const
19664 return ptr.get_checked(
this);
19689 basic_json flatten()
const
19691 basic_json result(value_t::object);
19692 json_pointer::flatten(
"", *
this, result);
19726 basic_json unflatten()
const
19728 return json_pointer::unflatten(*
this);
19787 basic_json patch(
const basic_json& json_patch)
const
19790 basic_json result = *
this;
19793 enum class patch_operations {
add, remove,
replace, move, copy,
test, invalid};
19795 const auto get_op = [](
const std::string & op)
19799 return patch_operations::add;
19801 if (op ==
"remove")
19803 return patch_operations::remove;
19805 if (op ==
"replace")
19807 return patch_operations::replace;
19811 return patch_operations::move;
19815 return patch_operations::copy;
19819 return patch_operations::test;
19822 return patch_operations::invalid;
19826 const auto operation_add = [&result](json_pointer & ptr, basic_json val)
19836 json_pointer top_pointer = ptr.top();
19837 if (top_pointer != ptr)
19839 result.at(top_pointer);
19843 const auto last_path = ptr.pop_back();
19844 basic_json& parent = result[ptr];
19846 switch (parent.m_type)
19848 case value_t::null:
19849 case value_t::object:
19852 parent[last_path] = val;
19856 case value_t::array:
19858 if (last_path ==
"-")
19861 parent.push_back(val);
19865 const auto idx = json_pointer::array_index(last_path);
19866 if (
JSON_UNLIKELY(
static_cast<size_type
>(idx) > parent.size()))
19869 JSON_THROW(out_of_range::create(401,
"array index " + std::to_string(idx) +
" is out of range"));
19873 parent.insert(parent.begin() +
static_cast<difference_type
>(idx), val);
19890 const auto operation_remove = [&result](json_pointer & ptr)
19893 const auto last_path = ptr.pop_back();
19894 basic_json& parent = result.at(ptr);
19897 if (parent.is_object())
19900 auto it = parent.find(last_path);
19907 JSON_THROW(out_of_range::create(403,
"key '" + last_path +
"' not found"));
19910 else if (parent.is_array())
19913 parent.erase(
static_cast<size_type
>(json_pointer::array_index(last_path)));
19920 JSON_THROW(parse_error::create(104, 0,
"JSON patch must be an array of objects"));
19924 for (
const auto& val : json_patch)
19927 const auto get_value = [&val](
const std::string & op,
19928 const std::string & member,
19932 auto it = val.m_value.object->find(member);
19935 const auto error_msg = (op ==
"op") ?
"operation" :
"operation '" + op +
"'";
19940 JSON_THROW(parse_error::create(105, 0, error_msg +
" must have member '" + member +
"'"));
19944 if (
JSON_UNLIKELY(string_type and not it->second.is_string()))
19946 JSON_THROW(parse_error::create(105, 0, error_msg +
" must have string member '" + member +
"'"));
19956 JSON_THROW(parse_error::create(104, 0,
"JSON patch must be an array of objects"));
19960 const std::string op = get_value(
"op",
"op",
true);
19961 const std::string path = get_value(op,
"path",
true);
19962 json_pointer ptr(path);
19964 switch (get_op(op))
19966 case patch_operations::add:
19968 operation_add(ptr, get_value(
"add",
"value",
false));
19972 case patch_operations::remove:
19974 operation_remove(ptr);
19978 case patch_operations::replace:
19981 result.at(ptr) = get_value(
"replace",
"value",
false);
19985 case patch_operations::move:
19987 const std::string from_path = get_value(
"move",
"from",
true);
19988 json_pointer from_ptr(from_path);
19991 basic_json v = result.at(from_ptr);
19997 operation_remove(from_ptr);
19998 operation_add(ptr, v);
20002 case patch_operations::copy:
20004 const std::string from_path = get_value(
"copy",
"from",
true);
20005 const json_pointer from_ptr(from_path);
20008 basic_json v = result.at(from_ptr);
20013 operation_add(ptr, v);
20017 case patch_operations::test:
20019 bool success =
false;
20024 success = (result.at(ptr) == get_value(
"test",
"value",
false));
20034 JSON_THROW(other_error::create(501,
"unsuccessful: " + val.dump()));
20040 case patch_operations::invalid:
20044 JSON_THROW(parse_error::create(105, 0,
"operation value '" + op +
"' is invalid"));
20085 static basic_json diff(
const basic_json& source,
const basic_json& target,
20086 const std::string& path =
"")
20089 basic_json result(value_t::array);
20092 if (source == target)
20097 if (source.type() != target.type())
20102 {
"op",
"replace"}, {
"path", path}, {
"value", target}
20107 switch (source.type())
20109 case value_t::array:
20113 while (i < source.size() and i < target.size())
20116 auto temp_diff = diff(source[i], target[i], path +
"/" + std::to_string(i));
20117 result.insert(result.end(), temp_diff.begin(), temp_diff.end());
20125 const auto end_index =
static_cast<difference_type
>(result.size());
20126 while (i < source.size())
20130 result.insert(result.begin() + end_index,
object(
20133 {
"path", path +
"/" + std::to_string(i)}
20139 while (i < target.size())
20144 {
"path", path +
"/" + std::to_string(i)},
20145 {
"value", target[i]}
20153 case value_t::object:
20156 for (
auto it = source.cbegin(); it != source.cend(); ++it)
20159 const auto key = json_pointer::escape(it.key());
20161 if (target.find(it.key()) != target.end())
20164 auto temp_diff = diff(it.value(), target[it.key()], path +
"/" + key);
20165 result.insert(result.end(), temp_diff.begin(), temp_diff.end());
20170 result.push_back(
object(
20172 {
"op",
"remove"}, {
"path", path +
"/" + key}
20178 for (
auto it = target.cbegin(); it != target.cend(); ++it)
20180 if (source.find(it.key()) == source.end())
20183 const auto key = json_pointer::escape(it.key());
20186 {
"op",
"add"}, {
"path", path +
"/" + key},
20187 {
"value", it.value()}
20200 {
"op",
"replace"}, {
"path", path}, {
"value", target}
20261 void merge_patch(
const basic_json& apply_patch)
20263 if (apply_patch.is_object())
20265 if (not is_object())
20269 for (
auto it = apply_patch.begin(); it != apply_patch.end(); ++it)
20271 if (it.value().is_null())
20277 operator[](it.key()).merge_patch(it.value());
20283 *
this = apply_patch;