Merge branch 'develop' of https://github.com/nlohmann/json into issue2179
Conflicts: single_include/nlohmann/json.hpp
This commit is contained in:
commit
9c21285133
44 changed files with 1769 additions and 868 deletions
|
@ -1,7 +1,6 @@
|
|||
#pragma once
|
||||
|
||||
#include <array> // array
|
||||
#include <cassert> // assert
|
||||
#include <cmath> // signbit, isfinite
|
||||
#include <cstdint> // intN_t, uintN_t
|
||||
#include <cstring> // memcpy, memmove
|
||||
|
@ -63,8 +62,8 @@ struct diyfp // f * 2^e
|
|||
*/
|
||||
static diyfp sub(const diyfp& x, const diyfp& y) noexcept
|
||||
{
|
||||
assert(x.e == y.e);
|
||||
assert(x.f >= y.f);
|
||||
JSON_ASSERT(x.e == y.e);
|
||||
JSON_ASSERT(x.f >= y.f);
|
||||
|
||||
return {x.f - y.f, x.e};
|
||||
}
|
||||
|
@ -140,7 +139,7 @@ struct diyfp // f * 2^e
|
|||
*/
|
||||
static diyfp normalize(diyfp x) noexcept
|
||||
{
|
||||
assert(x.f != 0);
|
||||
JSON_ASSERT(x.f != 0);
|
||||
|
||||
while ((x.f >> 63u) == 0)
|
||||
{
|
||||
|
@ -159,8 +158,8 @@ struct diyfp // f * 2^e
|
|||
{
|
||||
const int delta = x.e - target_exponent;
|
||||
|
||||
assert(delta >= 0);
|
||||
assert(((x.f << delta) >> delta) == x.f);
|
||||
JSON_ASSERT(delta >= 0);
|
||||
JSON_ASSERT(((x.f << delta) >> delta) == x.f);
|
||||
|
||||
return {x.f << delta, target_exponent};
|
||||
}
|
||||
|
@ -182,8 +181,8 @@ boundaries.
|
|||
template <typename FloatType>
|
||||
boundaries compute_boundaries(FloatType value)
|
||||
{
|
||||
assert(std::isfinite(value));
|
||||
assert(value > 0);
|
||||
JSON_ASSERT(std::isfinite(value));
|
||||
JSON_ASSERT(value > 0);
|
||||
|
||||
// Convert the IEEE representation into a diyfp.
|
||||
//
|
||||
|
@ -463,18 +462,18 @@ inline cached_power get_cached_power_for_binary_exponent(int e)
|
|||
// k = ceil((kAlpha - e - 1) * 0.30102999566398114)
|
||||
// for |e| <= 1500, but doesn't require floating-point operations.
|
||||
// NB: log_10(2) ~= 78913 / 2^18
|
||||
assert(e >= -1500);
|
||||
assert(e <= 1500);
|
||||
JSON_ASSERT(e >= -1500);
|
||||
JSON_ASSERT(e <= 1500);
|
||||
const int f = kAlpha - e - 1;
|
||||
const int k = (f * 78913) / (1 << 18) + static_cast<int>(f > 0);
|
||||
|
||||
const int index = (-kCachedPowersMinDecExp + k + (kCachedPowersDecStep - 1)) / kCachedPowersDecStep;
|
||||
assert(index >= 0);
|
||||
assert(static_cast<std::size_t>(index) < kCachedPowers.size());
|
||||
JSON_ASSERT(index >= 0);
|
||||
JSON_ASSERT(static_cast<std::size_t>(index) < kCachedPowers.size());
|
||||
|
||||
const cached_power cached = kCachedPowers[static_cast<std::size_t>(index)];
|
||||
assert(kAlpha <= cached.e + e + 64);
|
||||
assert(kGamma >= cached.e + e + 64);
|
||||
JSON_ASSERT(kAlpha <= cached.e + e + 64);
|
||||
JSON_ASSERT(kGamma >= cached.e + e + 64);
|
||||
|
||||
return cached;
|
||||
}
|
||||
|
@ -542,10 +541,10 @@ inline int find_largest_pow10(const std::uint32_t n, std::uint32_t& pow10)
|
|||
inline void grisu2_round(char* buf, int len, std::uint64_t dist, std::uint64_t delta,
|
||||
std::uint64_t rest, std::uint64_t ten_k)
|
||||
{
|
||||
assert(len >= 1);
|
||||
assert(dist <= delta);
|
||||
assert(rest <= delta);
|
||||
assert(ten_k > 0);
|
||||
JSON_ASSERT(len >= 1);
|
||||
JSON_ASSERT(dist <= delta);
|
||||
JSON_ASSERT(rest <= delta);
|
||||
JSON_ASSERT(ten_k > 0);
|
||||
|
||||
// <--------------------------- delta ---->
|
||||
// <---- dist --------->
|
||||
|
@ -570,7 +569,7 @@ inline void grisu2_round(char* buf, int len, std::uint64_t dist, std::uint64_t d
|
|||
and delta - rest >= ten_k
|
||||
and (rest + ten_k < dist or dist - rest > rest + ten_k - dist))
|
||||
{
|
||||
assert(buf[len - 1] != '0');
|
||||
JSON_ASSERT(buf[len - 1] != '0');
|
||||
buf[len - 1]--;
|
||||
rest += ten_k;
|
||||
}
|
||||
|
@ -598,8 +597,8 @@ inline void grisu2_digit_gen(char* buffer, int& length, int& decimal_exponent,
|
|||
// Grisu2 generates the digits of M+ from left to right and stops as soon as
|
||||
// V is in [M-,M+].
|
||||
|
||||
assert(M_plus.e >= kAlpha);
|
||||
assert(M_plus.e <= kGamma);
|
||||
JSON_ASSERT(M_plus.e >= kAlpha);
|
||||
JSON_ASSERT(M_plus.e <= kGamma);
|
||||
|
||||
std::uint64_t delta = diyfp::sub(M_plus, M_minus).f; // (significand of (M+ - M-), implicit exponent is e)
|
||||
std::uint64_t dist = diyfp::sub(M_plus, w ).f; // (significand of (M+ - w ), implicit exponent is e)
|
||||
|
@ -620,7 +619,7 @@ inline void grisu2_digit_gen(char* buffer, int& length, int& decimal_exponent,
|
|||
//
|
||||
// Generate the digits of the integral part p1 = d[n-1]...d[1]d[0]
|
||||
|
||||
assert(p1 > 0);
|
||||
JSON_ASSERT(p1 > 0);
|
||||
|
||||
std::uint32_t pow10;
|
||||
const int k = find_largest_pow10(p1, pow10);
|
||||
|
@ -656,7 +655,7 @@ inline void grisu2_digit_gen(char* buffer, int& length, int& decimal_exponent,
|
|||
// M+ = buffer * 10^n + (d * 10^(n-1) + r) + p2 * 2^e
|
||||
// = (buffer * 10 + d) * 10^(n-1) + (r + p2 * 2^e)
|
||||
//
|
||||
assert(d <= 9);
|
||||
JSON_ASSERT(d <= 9);
|
||||
buffer[length++] = static_cast<char>('0' + d); // buffer := buffer * 10 + d
|
||||
//
|
||||
// M+ = buffer * 10^(n-1) + (r + p2 * 2^e)
|
||||
|
@ -743,7 +742,7 @@ inline void grisu2_digit_gen(char* buffer, int& length, int& decimal_exponent,
|
|||
//
|
||||
// and stop as soon as 10^-m * r * 2^e <= delta * 2^e
|
||||
|
||||
assert(p2 > delta);
|
||||
JSON_ASSERT(p2 > delta);
|
||||
|
||||
int m = 0;
|
||||
for (;;)
|
||||
|
@ -754,7 +753,7 @@ inline void grisu2_digit_gen(char* buffer, int& length, int& decimal_exponent,
|
|||
// = buffer * 10^-m + 10^-m * (1/10 * (10 * p2) ) * 2^e
|
||||
// = buffer * 10^-m + 10^-m * (1/10 * ((10*p2 div 2^-e) * 2^-e + (10*p2 mod 2^-e)) * 2^e
|
||||
//
|
||||
assert(p2 <= (std::numeric_limits<std::uint64_t>::max)() / 10);
|
||||
JSON_ASSERT(p2 <= (std::numeric_limits<std::uint64_t>::max)() / 10);
|
||||
p2 *= 10;
|
||||
const std::uint64_t d = p2 >> -one.e; // d = (10 * p2) div 2^-e
|
||||
const std::uint64_t r = p2 & (one.f - 1); // r = (10 * p2) mod 2^-e
|
||||
|
@ -763,7 +762,7 @@ inline void grisu2_digit_gen(char* buffer, int& length, int& decimal_exponent,
|
|||
// = buffer * 10^-m + 10^-m * (1/10 * (d + r * 2^e))
|
||||
// = (buffer * 10 + d) * 10^(-m-1) + 10^(-m-1) * r * 2^e
|
||||
//
|
||||
assert(d <= 9);
|
||||
JSON_ASSERT(d <= 9);
|
||||
buffer[length++] = static_cast<char>('0' + d); // buffer := buffer * 10 + d
|
||||
//
|
||||
// M+ = buffer * 10^(-m-1) + 10^(-m-1) * r * 2^e
|
||||
|
@ -824,8 +823,8 @@ JSON_HEDLEY_NON_NULL(1)
|
|||
inline void grisu2(char* buf, int& len, int& decimal_exponent,
|
||||
diyfp m_minus, diyfp v, diyfp m_plus)
|
||||
{
|
||||
assert(m_plus.e == m_minus.e);
|
||||
assert(m_plus.e == v.e);
|
||||
JSON_ASSERT(m_plus.e == m_minus.e);
|
||||
JSON_ASSERT(m_plus.e == v.e);
|
||||
|
||||
// --------(-----------------------+-----------------------)-------- (A)
|
||||
// m- v m+
|
||||
|
@ -886,8 +885,8 @@ void grisu2(char* buf, int& len, int& decimal_exponent, FloatType value)
|
|||
static_assert(diyfp::kPrecision >= std::numeric_limits<FloatType>::digits + 3,
|
||||
"internal error: not enough precision");
|
||||
|
||||
assert(std::isfinite(value));
|
||||
assert(value > 0);
|
||||
JSON_ASSERT(std::isfinite(value));
|
||||
JSON_ASSERT(value > 0);
|
||||
|
||||
// If the neighbors (and boundaries) of 'value' are always computed for double-precision
|
||||
// numbers, all float's can be recovered using strtod (and strtof). However, the resulting
|
||||
|
@ -923,8 +922,8 @@ JSON_HEDLEY_NON_NULL(1)
|
|||
JSON_HEDLEY_RETURNS_NON_NULL
|
||||
inline char* append_exponent(char* buf, int e)
|
||||
{
|
||||
assert(e > -1000);
|
||||
assert(e < 1000);
|
||||
JSON_ASSERT(e > -1000);
|
||||
JSON_ASSERT(e < 1000);
|
||||
|
||||
if (e < 0)
|
||||
{
|
||||
|
@ -976,8 +975,8 @@ JSON_HEDLEY_RETURNS_NON_NULL
|
|||
inline char* format_buffer(char* buf, int len, int decimal_exponent,
|
||||
int min_exp, int max_exp)
|
||||
{
|
||||
assert(min_exp < 0);
|
||||
assert(max_exp > 0);
|
||||
JSON_ASSERT(min_exp < 0);
|
||||
JSON_ASSERT(max_exp > 0);
|
||||
|
||||
const int k = len;
|
||||
const int n = len + decimal_exponent;
|
||||
|
@ -1003,7 +1002,7 @@ inline char* format_buffer(char* buf, int len, int decimal_exponent,
|
|||
// dig.its
|
||||
// len <= max_digits10 + 1
|
||||
|
||||
assert(k > n);
|
||||
JSON_ASSERT(k > n);
|
||||
|
||||
std::memmove(buf + (static_cast<size_t>(n) + 1), buf + n, static_cast<size_t>(k) - static_cast<size_t>(n));
|
||||
buf[n] = '.';
|
||||
|
@ -1061,7 +1060,7 @@ JSON_HEDLEY_RETURNS_NON_NULL
|
|||
char* to_chars(char* first, const char* last, FloatType value)
|
||||
{
|
||||
static_cast<void>(last); // maybe unused - fix warning
|
||||
assert(std::isfinite(value));
|
||||
JSON_ASSERT(std::isfinite(value));
|
||||
|
||||
// Use signbit(value) instead of (value < 0) since signbit works for -0.
|
||||
if (std::signbit(value))
|
||||
|
@ -1079,7 +1078,7 @@ char* to_chars(char* first, const char* last, FloatType value)
|
|||
return first;
|
||||
}
|
||||
|
||||
assert(last - first >= std::numeric_limits<FloatType>::max_digits10);
|
||||
JSON_ASSERT(last - first >= std::numeric_limits<FloatType>::max_digits10);
|
||||
|
||||
// Compute v = buffer * 10^decimal_exponent.
|
||||
// The decimal digits are stored in the buffer, which needs to be interpreted
|
||||
|
@ -1089,16 +1088,16 @@ char* to_chars(char* first, const char* last, FloatType value)
|
|||
int decimal_exponent = 0;
|
||||
dtoa_impl::grisu2(first, len, decimal_exponent, value);
|
||||
|
||||
assert(len <= std::numeric_limits<FloatType>::max_digits10);
|
||||
JSON_ASSERT(len <= std::numeric_limits<FloatType>::max_digits10);
|
||||
|
||||
// Format the buffer like printf("%.*g", prec, value)
|
||||
constexpr int kMinExp = -4;
|
||||
// Use digits10 here to increase compatibility with version 2.
|
||||
constexpr int kMaxExp = std::numeric_limits<FloatType>::digits10;
|
||||
|
||||
assert(last - first >= kMaxExp + 2);
|
||||
assert(last - first >= 2 + (-kMinExp - 1) + std::numeric_limits<FloatType>::max_digits10);
|
||||
assert(last - first >= std::numeric_limits<FloatType>::max_digits10 + 6);
|
||||
JSON_ASSERT(last - first >= kMaxExp + 2);
|
||||
JSON_ASSERT(last - first >= 2 + (-kMinExp - 1) + std::numeric_limits<FloatType>::max_digits10);
|
||||
JSON_ASSERT(last - first >= std::numeric_limits<FloatType>::max_digits10 + 6);
|
||||
|
||||
return dtoa_impl::format_buffer(first, len, decimal_exponent, kMinExp, kMaxExp);
|
||||
}
|
||||
|
|
|
@ -2,7 +2,6 @@
|
|||
|
||||
#include <algorithm> // generate_n
|
||||
#include <array> // array
|
||||
#include <cassert> // assert
|
||||
#include <cmath> // ldexp
|
||||
#include <cstddef> // size_t
|
||||
#include <cstdint> // uint8_t, uint16_t, uint32_t, uint64_t
|
||||
|
@ -109,7 +108,7 @@ class binary_reader
|
|||
break;
|
||||
|
||||
default: // LCOV_EXCL_LINE
|
||||
assert(false); // LCOV_EXCL_LINE
|
||||
JSON_ASSERT(false); // LCOV_EXCL_LINE
|
||||
}
|
||||
|
||||
// strict mode: next byte must be EOF
|
||||
|
@ -145,7 +144,7 @@ class binary_reader
|
|||
*/
|
||||
bool parse_bson_internal()
|
||||
{
|
||||
std::int32_t document_size;
|
||||
std::int32_t document_size{};
|
||||
get_number<std::int32_t, true>(input_format_t::bson, document_size);
|
||||
|
||||
if (JSON_HEDLEY_UNLIKELY(not sax->start_object(std::size_t(-1))))
|
||||
|
@ -184,8 +183,6 @@ class binary_reader
|
|||
}
|
||||
*out++ = static_cast<typename string_t::value_type>(current);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/*!
|
||||
|
@ -230,7 +227,7 @@ class binary_reader
|
|||
}
|
||||
|
||||
// All BSON binary values have a subtype
|
||||
std::uint8_t subtype;
|
||||
std::uint8_t subtype{};
|
||||
get_number<std::uint8_t>(input_format_t::bson, subtype);
|
||||
result.set_subtype(subtype);
|
||||
|
||||
|
@ -254,13 +251,13 @@ class binary_reader
|
|||
{
|
||||
case 0x01: // double
|
||||
{
|
||||
double number;
|
||||
double number{};
|
||||
return get_number<double, true>(input_format_t::bson, number) and sax->number_float(static_cast<number_float_t>(number), "");
|
||||
}
|
||||
|
||||
case 0x02: // string
|
||||
{
|
||||
std::int32_t len;
|
||||
std::int32_t len{};
|
||||
string_t value;
|
||||
return get_number<std::int32_t, true>(input_format_t::bson, len) and get_bson_string(len, value) and sax->string(value);
|
||||
}
|
||||
|
@ -277,7 +274,7 @@ class binary_reader
|
|||
|
||||
case 0x05: // binary
|
||||
{
|
||||
std::int32_t len;
|
||||
std::int32_t len{};
|
||||
binary_t value;
|
||||
return get_number<std::int32_t, true>(input_format_t::bson, len) and get_bson_binary(len, value) and sax->binary(value);
|
||||
}
|
||||
|
@ -294,13 +291,13 @@ class binary_reader
|
|||
|
||||
case 0x10: // int32
|
||||
{
|
||||
std::int32_t value;
|
||||
std::int32_t value{};
|
||||
return get_number<std::int32_t, true>(input_format_t::bson, value) and sax->number_integer(value);
|
||||
}
|
||||
|
||||
case 0x12: // int64
|
||||
{
|
||||
std::int64_t value;
|
||||
std::int64_t value{};
|
||||
return get_number<std::int64_t, true>(input_format_t::bson, value) and sax->number_integer(value);
|
||||
}
|
||||
|
||||
|
@ -365,7 +362,7 @@ class binary_reader
|
|||
*/
|
||||
bool parse_bson_array()
|
||||
{
|
||||
std::int32_t document_size;
|
||||
std::int32_t document_size{};
|
||||
get_number<std::int32_t, true>(input_format_t::bson, document_size);
|
||||
|
||||
if (JSON_HEDLEY_UNLIKELY(not sax->start_array(std::size_t(-1))))
|
||||
|
@ -429,25 +426,25 @@ class binary_reader
|
|||
|
||||
case 0x18: // Unsigned integer (one-byte uint8_t follows)
|
||||
{
|
||||
std::uint8_t number;
|
||||
std::uint8_t number{};
|
||||
return get_number(input_format_t::cbor, number) and sax->number_unsigned(number);
|
||||
}
|
||||
|
||||
case 0x19: // Unsigned integer (two-byte uint16_t follows)
|
||||
{
|
||||
std::uint16_t number;
|
||||
std::uint16_t number{};
|
||||
return get_number(input_format_t::cbor, number) and sax->number_unsigned(number);
|
||||
}
|
||||
|
||||
case 0x1A: // Unsigned integer (four-byte uint32_t follows)
|
||||
{
|
||||
std::uint32_t number;
|
||||
std::uint32_t number{};
|
||||
return get_number(input_format_t::cbor, number) and sax->number_unsigned(number);
|
||||
}
|
||||
|
||||
case 0x1B: // Unsigned integer (eight-byte uint64_t follows)
|
||||
{
|
||||
std::uint64_t number;
|
||||
std::uint64_t number{};
|
||||
return get_number(input_format_t::cbor, number) and sax->number_unsigned(number);
|
||||
}
|
||||
|
||||
|
@ -480,25 +477,25 @@ class binary_reader
|
|||
|
||||
case 0x38: // Negative integer (one-byte uint8_t follows)
|
||||
{
|
||||
std::uint8_t number;
|
||||
std::uint8_t number{};
|
||||
return get_number(input_format_t::cbor, number) and sax->number_integer(static_cast<number_integer_t>(-1) - number);
|
||||
}
|
||||
|
||||
case 0x39: // Negative integer -1-n (two-byte uint16_t follows)
|
||||
{
|
||||
std::uint16_t number;
|
||||
std::uint16_t number{};
|
||||
return get_number(input_format_t::cbor, number) and sax->number_integer(static_cast<number_integer_t>(-1) - number);
|
||||
}
|
||||
|
||||
case 0x3A: // Negative integer -1-n (four-byte uint32_t follows)
|
||||
{
|
||||
std::uint32_t number;
|
||||
std::uint32_t number{};
|
||||
return get_number(input_format_t::cbor, number) and sax->number_integer(static_cast<number_integer_t>(-1) - number);
|
||||
}
|
||||
|
||||
case 0x3B: // Negative integer -1-n (eight-byte uint64_t follows)
|
||||
{
|
||||
std::uint64_t number;
|
||||
std::uint64_t number{};
|
||||
return get_number(input_format_t::cbor, number) and sax->number_integer(static_cast<number_integer_t>(-1)
|
||||
- static_cast<number_integer_t>(number));
|
||||
}
|
||||
|
@ -602,25 +599,25 @@ class binary_reader
|
|||
|
||||
case 0x98: // array (one-byte uint8_t for n follows)
|
||||
{
|
||||
std::uint8_t len;
|
||||
std::uint8_t len{};
|
||||
return get_number(input_format_t::cbor, len) and get_cbor_array(static_cast<std::size_t>(len));
|
||||
}
|
||||
|
||||
case 0x99: // array (two-byte uint16_t for n follow)
|
||||
{
|
||||
std::uint16_t len;
|
||||
std::uint16_t len{};
|
||||
return get_number(input_format_t::cbor, len) and get_cbor_array(static_cast<std::size_t>(len));
|
||||
}
|
||||
|
||||
case 0x9A: // array (four-byte uint32_t for n follow)
|
||||
{
|
||||
std::uint32_t len;
|
||||
std::uint32_t len{};
|
||||
return get_number(input_format_t::cbor, len) and get_cbor_array(static_cast<std::size_t>(len));
|
||||
}
|
||||
|
||||
case 0x9B: // array (eight-byte uint64_t for n follow)
|
||||
{
|
||||
std::uint64_t len;
|
||||
std::uint64_t len{};
|
||||
return get_number(input_format_t::cbor, len) and get_cbor_array(static_cast<std::size_t>(len));
|
||||
}
|
||||
|
||||
|
@ -656,25 +653,25 @@ class binary_reader
|
|||
|
||||
case 0xB8: // map (one-byte uint8_t for n follows)
|
||||
{
|
||||
std::uint8_t len;
|
||||
std::uint8_t len{};
|
||||
return get_number(input_format_t::cbor, len) and get_cbor_object(static_cast<std::size_t>(len));
|
||||
}
|
||||
|
||||
case 0xB9: // map (two-byte uint16_t for n follow)
|
||||
{
|
||||
std::uint16_t len;
|
||||
std::uint16_t len{};
|
||||
return get_number(input_format_t::cbor, len) and get_cbor_object(static_cast<std::size_t>(len));
|
||||
}
|
||||
|
||||
case 0xBA: // map (four-byte uint32_t for n follow)
|
||||
{
|
||||
std::uint32_t len;
|
||||
std::uint32_t len{};
|
||||
return get_number(input_format_t::cbor, len) and get_cbor_object(static_cast<std::size_t>(len));
|
||||
}
|
||||
|
||||
case 0xBB: // map (eight-byte uint64_t for n follow)
|
||||
{
|
||||
std::uint64_t len;
|
||||
std::uint64_t len{};
|
||||
return get_number(input_format_t::cbor, len) and get_cbor_object(static_cast<std::size_t>(len));
|
||||
}
|
||||
|
||||
|
@ -719,8 +716,8 @@ class binary_reader
|
|||
{
|
||||
const int exp = (half >> 10u) & 0x1Fu;
|
||||
const unsigned int mant = half & 0x3FFu;
|
||||
assert(0 <= exp and exp <= 32);
|
||||
assert(mant <= 1024);
|
||||
JSON_ASSERT(0 <= exp and exp <= 32);
|
||||
JSON_ASSERT(mant <= 1024);
|
||||
switch (exp)
|
||||
{
|
||||
case 0:
|
||||
|
@ -740,13 +737,13 @@ class binary_reader
|
|||
|
||||
case 0xFA: // Single-Precision Float (four-byte IEEE 754)
|
||||
{
|
||||
float number;
|
||||
float number{};
|
||||
return get_number(input_format_t::cbor, number) and sax->number_float(static_cast<number_float_t>(number), "");
|
||||
}
|
||||
|
||||
case 0xFB: // Double-Precision Float (eight-byte IEEE 754)
|
||||
{
|
||||
double number;
|
||||
double number{};
|
||||
return get_number(input_format_t::cbor, number) and sax->number_float(static_cast<number_float_t>(number), "");
|
||||
}
|
||||
|
||||
|
@ -809,25 +806,25 @@ class binary_reader
|
|||
|
||||
case 0x78: // UTF-8 string (one-byte uint8_t for n follows)
|
||||
{
|
||||
std::uint8_t len;
|
||||
std::uint8_t len{};
|
||||
return get_number(input_format_t::cbor, len) and get_string(input_format_t::cbor, len, result);
|
||||
}
|
||||
|
||||
case 0x79: // UTF-8 string (two-byte uint16_t for n follow)
|
||||
{
|
||||
std::uint16_t len;
|
||||
std::uint16_t len{};
|
||||
return get_number(input_format_t::cbor, len) and get_string(input_format_t::cbor, len, result);
|
||||
}
|
||||
|
||||
case 0x7A: // UTF-8 string (four-byte uint32_t for n follow)
|
||||
{
|
||||
std::uint32_t len;
|
||||
std::uint32_t len{};
|
||||
return get_number(input_format_t::cbor, len) and get_string(input_format_t::cbor, len, result);
|
||||
}
|
||||
|
||||
case 0x7B: // UTF-8 string (eight-byte uint64_t for n follow)
|
||||
{
|
||||
std::uint64_t len;
|
||||
std::uint64_t len{};
|
||||
return get_number(input_format_t::cbor, len) and get_string(input_format_t::cbor, len, result);
|
||||
}
|
||||
|
||||
|
@ -904,28 +901,28 @@ class binary_reader
|
|||
|
||||
case 0x58: // Binary data (one-byte uint8_t for n follows)
|
||||
{
|
||||
std::uint8_t len;
|
||||
std::uint8_t len{};
|
||||
return get_number(input_format_t::cbor, len) and
|
||||
get_binary(input_format_t::cbor, len, result);
|
||||
}
|
||||
|
||||
case 0x59: // Binary data (two-byte uint16_t for n follow)
|
||||
{
|
||||
std::uint16_t len;
|
||||
std::uint16_t len{};
|
||||
return get_number(input_format_t::cbor, len) and
|
||||
get_binary(input_format_t::cbor, len, result);
|
||||
}
|
||||
|
||||
case 0x5A: // Binary data (four-byte uint32_t for n follow)
|
||||
{
|
||||
std::uint32_t len;
|
||||
std::uint32_t len{};
|
||||
return get_number(input_format_t::cbor, len) and
|
||||
get_binary(input_format_t::cbor, len, result);
|
||||
}
|
||||
|
||||
case 0x5B: // Binary data (eight-byte uint64_t for n follow)
|
||||
{
|
||||
std::uint64_t len;
|
||||
std::uint64_t len{};
|
||||
return get_number(input_format_t::cbor, len) and
|
||||
get_binary(input_format_t::cbor, len, result);
|
||||
}
|
||||
|
@ -1290,85 +1287,85 @@ class binary_reader
|
|||
|
||||
case 0xCA: // float 32
|
||||
{
|
||||
float number;
|
||||
float number{};
|
||||
return get_number(input_format_t::msgpack, number) and sax->number_float(static_cast<number_float_t>(number), "");
|
||||
}
|
||||
|
||||
case 0xCB: // float 64
|
||||
{
|
||||
double number;
|
||||
double number{};
|
||||
return get_number(input_format_t::msgpack, number) and sax->number_float(static_cast<number_float_t>(number), "");
|
||||
}
|
||||
|
||||
case 0xCC: // uint 8
|
||||
{
|
||||
std::uint8_t number;
|
||||
std::uint8_t number{};
|
||||
return get_number(input_format_t::msgpack, number) and sax->number_unsigned(number);
|
||||
}
|
||||
|
||||
case 0xCD: // uint 16
|
||||
{
|
||||
std::uint16_t number;
|
||||
std::uint16_t number{};
|
||||
return get_number(input_format_t::msgpack, number) and sax->number_unsigned(number);
|
||||
}
|
||||
|
||||
case 0xCE: // uint 32
|
||||
{
|
||||
std::uint32_t number;
|
||||
std::uint32_t number{};
|
||||
return get_number(input_format_t::msgpack, number) and sax->number_unsigned(number);
|
||||
}
|
||||
|
||||
case 0xCF: // uint 64
|
||||
{
|
||||
std::uint64_t number;
|
||||
std::uint64_t number{};
|
||||
return get_number(input_format_t::msgpack, number) and sax->number_unsigned(number);
|
||||
}
|
||||
|
||||
case 0xD0: // int 8
|
||||
{
|
||||
std::int8_t number;
|
||||
std::int8_t number{};
|
||||
return get_number(input_format_t::msgpack, number) and sax->number_integer(number);
|
||||
}
|
||||
|
||||
case 0xD1: // int 16
|
||||
{
|
||||
std::int16_t number;
|
||||
std::int16_t number{};
|
||||
return get_number(input_format_t::msgpack, number) and sax->number_integer(number);
|
||||
}
|
||||
|
||||
case 0xD2: // int 32
|
||||
{
|
||||
std::int32_t number;
|
||||
std::int32_t number{};
|
||||
return get_number(input_format_t::msgpack, number) and sax->number_integer(number);
|
||||
}
|
||||
|
||||
case 0xD3: // int 64
|
||||
{
|
||||
std::int64_t number;
|
||||
std::int64_t number{};
|
||||
return get_number(input_format_t::msgpack, number) and sax->number_integer(number);
|
||||
}
|
||||
|
||||
case 0xDC: // array 16
|
||||
{
|
||||
std::uint16_t len;
|
||||
std::uint16_t len{};
|
||||
return get_number(input_format_t::msgpack, len) and get_msgpack_array(static_cast<std::size_t>(len));
|
||||
}
|
||||
|
||||
case 0xDD: // array 32
|
||||
{
|
||||
std::uint32_t len;
|
||||
std::uint32_t len{};
|
||||
return get_number(input_format_t::msgpack, len) and get_msgpack_array(static_cast<std::size_t>(len));
|
||||
}
|
||||
|
||||
case 0xDE: // map 16
|
||||
{
|
||||
std::uint16_t len;
|
||||
std::uint16_t len{};
|
||||
return get_number(input_format_t::msgpack, len) and get_msgpack_object(static_cast<std::size_t>(len));
|
||||
}
|
||||
|
||||
case 0xDF: // map 32
|
||||
{
|
||||
std::uint32_t len;
|
||||
std::uint32_t len{};
|
||||
return get_number(input_format_t::msgpack, len) and get_msgpack_object(static_cast<std::size_t>(len));
|
||||
}
|
||||
|
||||
|
@ -1473,19 +1470,19 @@ class binary_reader
|
|||
|
||||
case 0xD9: // str 8
|
||||
{
|
||||
std::uint8_t len;
|
||||
std::uint8_t len{};
|
||||
return get_number(input_format_t::msgpack, len) and get_string(input_format_t::msgpack, len, result);
|
||||
}
|
||||
|
||||
case 0xDA: // str 16
|
||||
{
|
||||
std::uint16_t len;
|
||||
std::uint16_t len{};
|
||||
return get_number(input_format_t::msgpack, len) and get_string(input_format_t::msgpack, len, result);
|
||||
}
|
||||
|
||||
case 0xDB: // str 32
|
||||
{
|
||||
std::uint32_t len;
|
||||
std::uint32_t len{};
|
||||
return get_number(input_format_t::msgpack, len) and get_string(input_format_t::msgpack, len, result);
|
||||
}
|
||||
|
||||
|
@ -1520,29 +1517,29 @@ class binary_reader
|
|||
{
|
||||
case 0xC4: // bin 8
|
||||
{
|
||||
std::uint8_t len;
|
||||
std::uint8_t len{};
|
||||
return get_number(input_format_t::msgpack, len) and
|
||||
get_binary(input_format_t::msgpack, len, result);
|
||||
}
|
||||
|
||||
case 0xC5: // bin 16
|
||||
{
|
||||
std::uint16_t len;
|
||||
std::uint16_t len{};
|
||||
return get_number(input_format_t::msgpack, len) and
|
||||
get_binary(input_format_t::msgpack, len, result);
|
||||
}
|
||||
|
||||
case 0xC6: // bin 32
|
||||
{
|
||||
std::uint32_t len;
|
||||
std::uint32_t len{};
|
||||
return get_number(input_format_t::msgpack, len) and
|
||||
get_binary(input_format_t::msgpack, len, result);
|
||||
}
|
||||
|
||||
case 0xC7: // ext 8
|
||||
{
|
||||
std::uint8_t len;
|
||||
std::int8_t subtype;
|
||||
std::uint8_t len{};
|
||||
std::int8_t subtype{};
|
||||
return get_number(input_format_t::msgpack, len) and
|
||||
get_number(input_format_t::msgpack, subtype) and
|
||||
get_binary(input_format_t::msgpack, len, result) and
|
||||
|
@ -1551,8 +1548,8 @@ class binary_reader
|
|||
|
||||
case 0xC8: // ext 16
|
||||
{
|
||||
std::uint16_t len;
|
||||
std::int8_t subtype;
|
||||
std::uint16_t len{};
|
||||
std::int8_t subtype{};
|
||||
return get_number(input_format_t::msgpack, len) and
|
||||
get_number(input_format_t::msgpack, subtype) and
|
||||
get_binary(input_format_t::msgpack, len, result) and
|
||||
|
@ -1561,8 +1558,8 @@ class binary_reader
|
|||
|
||||
case 0xC9: // ext 32
|
||||
{
|
||||
std::uint32_t len;
|
||||
std::int8_t subtype;
|
||||
std::uint32_t len{};
|
||||
std::int8_t subtype{};
|
||||
return get_number(input_format_t::msgpack, len) and
|
||||
get_number(input_format_t::msgpack, subtype) and
|
||||
get_binary(input_format_t::msgpack, len, result) and
|
||||
|
@ -1571,7 +1568,7 @@ class binary_reader
|
|||
|
||||
case 0xD4: // fixext 1
|
||||
{
|
||||
std::int8_t subtype;
|
||||
std::int8_t subtype{};
|
||||
return get_number(input_format_t::msgpack, subtype) and
|
||||
get_binary(input_format_t::msgpack, 1, result) and
|
||||
assign_and_return_true(subtype);
|
||||
|
@ -1579,7 +1576,7 @@ class binary_reader
|
|||
|
||||
case 0xD5: // fixext 2
|
||||
{
|
||||
std::int8_t subtype;
|
||||
std::int8_t subtype{};
|
||||
return get_number(input_format_t::msgpack, subtype) and
|
||||
get_binary(input_format_t::msgpack, 2, result) and
|
||||
assign_and_return_true(subtype);
|
||||
|
@ -1587,7 +1584,7 @@ class binary_reader
|
|||
|
||||
case 0xD6: // fixext 4
|
||||
{
|
||||
std::int8_t subtype;
|
||||
std::int8_t subtype{};
|
||||
return get_number(input_format_t::msgpack, subtype) and
|
||||
get_binary(input_format_t::msgpack, 4, result) and
|
||||
assign_and_return_true(subtype);
|
||||
|
@ -1595,7 +1592,7 @@ class binary_reader
|
|||
|
||||
case 0xD7: // fixext 8
|
||||
{
|
||||
std::int8_t subtype;
|
||||
std::int8_t subtype{};
|
||||
return get_number(input_format_t::msgpack, subtype) and
|
||||
get_binary(input_format_t::msgpack, 8, result) and
|
||||
assign_and_return_true(subtype);
|
||||
|
@ -1603,7 +1600,7 @@ class binary_reader
|
|||
|
||||
case 0xD8: // fixext 16
|
||||
{
|
||||
std::int8_t subtype;
|
||||
std::int8_t subtype{};
|
||||
return get_number(input_format_t::msgpack, subtype) and
|
||||
get_binary(input_format_t::msgpack, 16, result) and
|
||||
assign_and_return_true(subtype);
|
||||
|
@ -1712,31 +1709,31 @@ class binary_reader
|
|||
{
|
||||
case 'U':
|
||||
{
|
||||
std::uint8_t len;
|
||||
std::uint8_t len{};
|
||||
return get_number(input_format_t::ubjson, len) and get_string(input_format_t::ubjson, len, result);
|
||||
}
|
||||
|
||||
case 'i':
|
||||
{
|
||||
std::int8_t len;
|
||||
std::int8_t len{};
|
||||
return get_number(input_format_t::ubjson, len) and get_string(input_format_t::ubjson, len, result);
|
||||
}
|
||||
|
||||
case 'I':
|
||||
{
|
||||
std::int16_t len;
|
||||
std::int16_t len{};
|
||||
return get_number(input_format_t::ubjson, len) and get_string(input_format_t::ubjson, len, result);
|
||||
}
|
||||
|
||||
case 'l':
|
||||
{
|
||||
std::int32_t len;
|
||||
std::int32_t len{};
|
||||
return get_number(input_format_t::ubjson, len) and get_string(input_format_t::ubjson, len, result);
|
||||
}
|
||||
|
||||
case 'L':
|
||||
{
|
||||
std::int64_t len;
|
||||
std::int64_t len{};
|
||||
return get_number(input_format_t::ubjson, len) and get_string(input_format_t::ubjson, len, result);
|
||||
}
|
||||
|
||||
|
@ -1756,7 +1753,7 @@ class binary_reader
|
|||
{
|
||||
case 'U':
|
||||
{
|
||||
std::uint8_t number;
|
||||
std::uint8_t number{};
|
||||
if (JSON_HEDLEY_UNLIKELY(not get_number(input_format_t::ubjson, number)))
|
||||
{
|
||||
return false;
|
||||
|
@ -1767,7 +1764,7 @@ class binary_reader
|
|||
|
||||
case 'i':
|
||||
{
|
||||
std::int8_t number;
|
||||
std::int8_t number{};
|
||||
if (JSON_HEDLEY_UNLIKELY(not get_number(input_format_t::ubjson, number)))
|
||||
{
|
||||
return false;
|
||||
|
@ -1778,7 +1775,7 @@ class binary_reader
|
|||
|
||||
case 'I':
|
||||
{
|
||||
std::int16_t number;
|
||||
std::int16_t number{};
|
||||
if (JSON_HEDLEY_UNLIKELY(not get_number(input_format_t::ubjson, number)))
|
||||
{
|
||||
return false;
|
||||
|
@ -1789,7 +1786,7 @@ class binary_reader
|
|||
|
||||
case 'l':
|
||||
{
|
||||
std::int32_t number;
|
||||
std::int32_t number{};
|
||||
if (JSON_HEDLEY_UNLIKELY(not get_number(input_format_t::ubjson, number)))
|
||||
{
|
||||
return false;
|
||||
|
@ -1800,7 +1797,7 @@ class binary_reader
|
|||
|
||||
case 'L':
|
||||
{
|
||||
std::int64_t number;
|
||||
std::int64_t number{};
|
||||
if (JSON_HEDLEY_UNLIKELY(not get_number(input_format_t::ubjson, number)))
|
||||
{
|
||||
return false;
|
||||
|
@ -1885,43 +1882,43 @@ class binary_reader
|
|||
|
||||
case 'U':
|
||||
{
|
||||
std::uint8_t number;
|
||||
std::uint8_t number{};
|
||||
return get_number(input_format_t::ubjson, number) and sax->number_unsigned(number);
|
||||
}
|
||||
|
||||
case 'i':
|
||||
{
|
||||
std::int8_t number;
|
||||
std::int8_t number{};
|
||||
return get_number(input_format_t::ubjson, number) and sax->number_integer(number);
|
||||
}
|
||||
|
||||
case 'I':
|
||||
{
|
||||
std::int16_t number;
|
||||
std::int16_t number{};
|
||||
return get_number(input_format_t::ubjson, number) and sax->number_integer(number);
|
||||
}
|
||||
|
||||
case 'l':
|
||||
{
|
||||
std::int32_t number;
|
||||
std::int32_t number{};
|
||||
return get_number(input_format_t::ubjson, number) and sax->number_integer(number);
|
||||
}
|
||||
|
||||
case 'L':
|
||||
{
|
||||
std::int64_t number;
|
||||
std::int64_t number{};
|
||||
return get_number(input_format_t::ubjson, number) and sax->number_integer(number);
|
||||
}
|
||||
|
||||
case 'd':
|
||||
{
|
||||
float number;
|
||||
float number{};
|
||||
return get_number(input_format_t::ubjson, number) and sax->number_float(static_cast<number_float_t>(number), "");
|
||||
}
|
||||
|
||||
case 'D':
|
||||
{
|
||||
double number;
|
||||
double number{};
|
||||
return get_number(input_format_t::ubjson, number) and sax->number_float(static_cast<number_float_t>(number), "");
|
||||
}
|
||||
|
||||
|
@ -2297,7 +2294,7 @@ class binary_reader
|
|||
break;
|
||||
|
||||
default: // LCOV_EXCL_LINE
|
||||
assert(false); // LCOV_EXCL_LINE
|
||||
JSON_ASSERT(false); // LCOV_EXCL_LINE
|
||||
}
|
||||
|
||||
return error_msg + " " + context + ": " + detail;
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
#pragma once
|
||||
|
||||
#include <array> // array
|
||||
#include <cassert> // assert
|
||||
#include <cstddef> // size_t
|
||||
#include <cstdio> //FILE *
|
||||
#include <cstring> // strlen
|
||||
|
@ -76,7 +75,7 @@ class input_stream_adapter
|
|||
{
|
||||
// clear stream flags; we use underlying streambuf I/O, do not
|
||||
// maintain ifstream flags, except eof
|
||||
if (is)
|
||||
if (is != nullptr)
|
||||
{
|
||||
is->clear(is->rdstate() & std::ios::eofbit);
|
||||
}
|
||||
|
@ -297,13 +296,13 @@ class wide_string_input_adapter
|
|||
{
|
||||
fill_buffer<sizeof(WideCharType)>();
|
||||
|
||||
assert(utf8_bytes_filled > 0);
|
||||
assert(utf8_bytes_index == 0);
|
||||
JSON_ASSERT(utf8_bytes_filled > 0);
|
||||
JSON_ASSERT(utf8_bytes_index == 0);
|
||||
}
|
||||
|
||||
// use buffer
|
||||
assert(utf8_bytes_filled > 0);
|
||||
assert(utf8_bytes_index < utf8_bytes_filled);
|
||||
JSON_ASSERT(utf8_bytes_filled > 0);
|
||||
JSON_ASSERT(utf8_bytes_index < utf8_bytes_filled);
|
||||
return utf8_bytes[utf8_bytes_index++];
|
||||
}
|
||||
|
||||
|
@ -411,7 +410,7 @@ template < typename CharT,
|
|||
contiguous_bytes_input_adapter input_adapter(CharT b)
|
||||
{
|
||||
auto length = std::strlen(reinterpret_cast<const char*>(b));
|
||||
auto ptr = reinterpret_cast<const char*>(b);
|
||||
const auto* ptr = reinterpret_cast<const char*>(b);
|
||||
return input_adapter(ptr, ptr + length);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
#pragma once
|
||||
|
||||
#include <cassert> // assert
|
||||
#include <cstddef>
|
||||
#include <string> // string
|
||||
#include <utility> // move
|
||||
|
@ -269,18 +268,18 @@ class json_sax_dom_parser
|
|||
switch ((ex.id / 100) % 100)
|
||||
{
|
||||
case 1:
|
||||
JSON_THROW(*static_cast<const detail::parse_error*>(&ex));
|
||||
JSON_THROW(*dynamic_cast<const detail::parse_error*>(&ex));
|
||||
case 4:
|
||||
JSON_THROW(*static_cast<const detail::out_of_range*>(&ex));
|
||||
JSON_THROW(*dynamic_cast<const detail::out_of_range*>(&ex));
|
||||
// LCOV_EXCL_START
|
||||
case 2:
|
||||
JSON_THROW(*static_cast<const detail::invalid_iterator*>(&ex));
|
||||
JSON_THROW(*dynamic_cast<const detail::invalid_iterator*>(&ex));
|
||||
case 3:
|
||||
JSON_THROW(*static_cast<const detail::type_error*>(&ex));
|
||||
JSON_THROW(*dynamic_cast<const detail::type_error*>(&ex));
|
||||
case 5:
|
||||
JSON_THROW(*static_cast<const detail::other_error*>(&ex));
|
||||
JSON_THROW(*dynamic_cast<const detail::other_error*>(&ex));
|
||||
default:
|
||||
assert(false);
|
||||
JSON_ASSERT(false);
|
||||
// LCOV_EXCL_STOP
|
||||
}
|
||||
}
|
||||
|
@ -309,7 +308,7 @@ class json_sax_dom_parser
|
|||
return &root;
|
||||
}
|
||||
|
||||
assert(ref_stack.back()->is_array() or ref_stack.back()->is_object());
|
||||
JSON_ASSERT(ref_stack.back()->is_array() or ref_stack.back()->is_object());
|
||||
|
||||
if (ref_stack.back()->is_array())
|
||||
{
|
||||
|
@ -317,8 +316,8 @@ class json_sax_dom_parser
|
|||
return &(ref_stack.back()->m_value.array->back());
|
||||
}
|
||||
|
||||
assert(ref_stack.back()->is_object());
|
||||
assert(object_element);
|
||||
JSON_ASSERT(ref_stack.back()->is_object());
|
||||
JSON_ASSERT(object_element);
|
||||
*object_element = BasicJsonType(std::forward<Value>(v));
|
||||
return object_element;
|
||||
}
|
||||
|
@ -447,8 +446,8 @@ class json_sax_dom_callback_parser
|
|||
*ref_stack.back() = discarded;
|
||||
}
|
||||
|
||||
assert(not ref_stack.empty());
|
||||
assert(not keep_stack.empty());
|
||||
JSON_ASSERT(not ref_stack.empty());
|
||||
JSON_ASSERT(not keep_stack.empty());
|
||||
ref_stack.pop_back();
|
||||
keep_stack.pop_back();
|
||||
|
||||
|
@ -499,8 +498,8 @@ class json_sax_dom_callback_parser
|
|||
}
|
||||
}
|
||||
|
||||
assert(not ref_stack.empty());
|
||||
assert(not keep_stack.empty());
|
||||
JSON_ASSERT(not ref_stack.empty());
|
||||
JSON_ASSERT(not keep_stack.empty());
|
||||
ref_stack.pop_back();
|
||||
keep_stack.pop_back();
|
||||
|
||||
|
@ -523,18 +522,18 @@ class json_sax_dom_callback_parser
|
|||
switch ((ex.id / 100) % 100)
|
||||
{
|
||||
case 1:
|
||||
JSON_THROW(*static_cast<const detail::parse_error*>(&ex));
|
||||
JSON_THROW(*dynamic_cast<const detail::parse_error*>(&ex));
|
||||
case 4:
|
||||
JSON_THROW(*static_cast<const detail::out_of_range*>(&ex));
|
||||
JSON_THROW(*dynamic_cast<const detail::out_of_range*>(&ex));
|
||||
// LCOV_EXCL_START
|
||||
case 2:
|
||||
JSON_THROW(*static_cast<const detail::invalid_iterator*>(&ex));
|
||||
JSON_THROW(*dynamic_cast<const detail::invalid_iterator*>(&ex));
|
||||
case 3:
|
||||
JSON_THROW(*static_cast<const detail::type_error*>(&ex));
|
||||
JSON_THROW(*dynamic_cast<const detail::type_error*>(&ex));
|
||||
case 5:
|
||||
JSON_THROW(*static_cast<const detail::other_error*>(&ex));
|
||||
JSON_THROW(*dynamic_cast<const detail::other_error*>(&ex));
|
||||
default:
|
||||
assert(false);
|
||||
JSON_ASSERT(false);
|
||||
// LCOV_EXCL_STOP
|
||||
}
|
||||
}
|
||||
|
@ -565,7 +564,7 @@ class json_sax_dom_callback_parser
|
|||
template<typename Value>
|
||||
std::pair<bool, BasicJsonType*> handle_value(Value&& v, const bool skip_callback = false)
|
||||
{
|
||||
assert(not keep_stack.empty());
|
||||
JSON_ASSERT(not keep_stack.empty());
|
||||
|
||||
// do not handle this value if we know it would be added to a discarded
|
||||
// container
|
||||
|
@ -600,7 +599,7 @@ class json_sax_dom_callback_parser
|
|||
}
|
||||
|
||||
// we now only expect arrays and objects
|
||||
assert(ref_stack.back()->is_array() or ref_stack.back()->is_object());
|
||||
JSON_ASSERT(ref_stack.back()->is_array() or ref_stack.back()->is_object());
|
||||
|
||||
// array
|
||||
if (ref_stack.back()->is_array())
|
||||
|
@ -610,9 +609,9 @@ class json_sax_dom_callback_parser
|
|||
}
|
||||
|
||||
// object
|
||||
assert(ref_stack.back()->is_object());
|
||||
JSON_ASSERT(ref_stack.back()->is_object());
|
||||
// check if we should store an element for the current key
|
||||
assert(not key_keep_stack.empty());
|
||||
JSON_ASSERT(not key_keep_stack.empty());
|
||||
const bool store_element = key_keep_stack.back();
|
||||
key_keep_stack.pop_back();
|
||||
|
||||
|
@ -621,7 +620,7 @@ class json_sax_dom_callback_parser
|
|||
return {false, nullptr};
|
||||
}
|
||||
|
||||
assert(object_element);
|
||||
JSON_ASSERT(object_element);
|
||||
*object_element = std::move(value);
|
||||
return {true, object_element};
|
||||
}
|
||||
|
|
|
@ -112,8 +112,11 @@ class lexer : public lexer_base<BasicJsonType>
|
|||
public:
|
||||
using token_type = typename lexer_base<BasicJsonType>::token_type;
|
||||
|
||||
explicit lexer(InputAdapterType&& adapter)
|
||||
: ia(std::move(adapter)), decimal_point_char(static_cast<char_int_type>(get_decimal_point())) {}
|
||||
explicit lexer(InputAdapterType&& adapter, bool ignore_comments_ = false)
|
||||
: ia(std::move(adapter))
|
||||
, ignore_comments(ignore_comments_)
|
||||
, decimal_point_char(static_cast<char_int_type>(get_decimal_point()))
|
||||
{}
|
||||
|
||||
// delete because of pointer members
|
||||
lexer(const lexer&) = delete;
|
||||
|
@ -131,8 +134,8 @@ class lexer : public lexer_base<BasicJsonType>
|
|||
JSON_HEDLEY_PURE
|
||||
static char get_decimal_point() noexcept
|
||||
{
|
||||
const auto loc = localeconv();
|
||||
assert(loc != nullptr);
|
||||
const auto* loc = localeconv();
|
||||
JSON_ASSERT(loc != nullptr);
|
||||
return (loc->decimal_point == nullptr) ? '.' : *(loc->decimal_point);
|
||||
}
|
||||
|
||||
|
@ -158,7 +161,7 @@ class lexer : public lexer_base<BasicJsonType>
|
|||
int get_codepoint()
|
||||
{
|
||||
// this function only makes sense after reading `\u`
|
||||
assert(current == 'u');
|
||||
JSON_ASSERT(current == 'u');
|
||||
int codepoint = 0;
|
||||
|
||||
const auto factors = { 12u, 8u, 4u, 0u };
|
||||
|
@ -184,7 +187,7 @@ class lexer : public lexer_base<BasicJsonType>
|
|||
}
|
||||
}
|
||||
|
||||
assert(0x0000 <= codepoint and codepoint <= 0xFFFF);
|
||||
JSON_ASSERT(0x0000 <= codepoint and codepoint <= 0xFFFF);
|
||||
return codepoint;
|
||||
}
|
||||
|
||||
|
@ -205,7 +208,7 @@ class lexer : public lexer_base<BasicJsonType>
|
|||
*/
|
||||
bool next_byte_in_range(std::initializer_list<char_int_type> ranges)
|
||||
{
|
||||
assert(ranges.size() == 2 or ranges.size() == 4 or ranges.size() == 6);
|
||||
JSON_ASSERT(ranges.size() == 2 or ranges.size() == 4 or ranges.size() == 6);
|
||||
add(current);
|
||||
|
||||
for (auto range = ranges.begin(); range != ranges.end(); ++range)
|
||||
|
@ -246,7 +249,7 @@ class lexer : public lexer_base<BasicJsonType>
|
|||
reset();
|
||||
|
||||
// we entered the function by reading an open quote
|
||||
assert(current == '\"');
|
||||
JSON_ASSERT(current == '\"');
|
||||
|
||||
while (true)
|
||||
{
|
||||
|
@ -366,7 +369,7 @@ class lexer : public lexer_base<BasicJsonType>
|
|||
}
|
||||
|
||||
// result of the above calculation yields a proper codepoint
|
||||
assert(0x00 <= codepoint and codepoint <= 0x10FFFF);
|
||||
JSON_ASSERT(0x00 <= codepoint and codepoint <= 0x10FFFF);
|
||||
|
||||
// translate codepoint into bytes
|
||||
if (codepoint < 0x80)
|
||||
|
@ -826,6 +829,77 @@ class lexer : public lexer_base<BasicJsonType>
|
|||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief scan a comment
|
||||
* @return whether comment could be scanned successfully
|
||||
*/
|
||||
bool scan_comment()
|
||||
{
|
||||
switch (get())
|
||||
{
|
||||
// single-line comments skip input until a newline or EOF is read
|
||||
case '/':
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
switch (get())
|
||||
{
|
||||
case '\n':
|
||||
case '\r':
|
||||
case std::char_traits<char_type>::eof():
|
||||
case '\0':
|
||||
return true;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// multi-line comments skip input until */ is read
|
||||
case '*':
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
switch (get())
|
||||
{
|
||||
case std::char_traits<char_type>::eof():
|
||||
case '\0':
|
||||
{
|
||||
error_message = "invalid comment; missing closing '*/'";
|
||||
return false;
|
||||
}
|
||||
|
||||
case '*':
|
||||
{
|
||||
switch (get())
|
||||
{
|
||||
case '/':
|
||||
return true;
|
||||
|
||||
default:
|
||||
{
|
||||
unget();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// unexpected character after reading '/'
|
||||
default:
|
||||
{
|
||||
error_message = "invalid comment; expecting '/' or '*' after '/'";
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
JSON_HEDLEY_NON_NULL(2)
|
||||
static void strtof(float& f, const char* str, char** endptr) noexcept
|
||||
{
|
||||
|
@ -924,7 +998,7 @@ class lexer : public lexer_base<BasicJsonType>
|
|||
|
||||
// all other characters are rejected outside scan_number()
|
||||
default: // LCOV_EXCL_LINE
|
||||
assert(false); // LCOV_EXCL_LINE
|
||||
JSON_ASSERT(false); // LCOV_EXCL_LINE
|
||||
}
|
||||
|
||||
scan_number_minus:
|
||||
|
@ -1171,7 +1245,7 @@ scan_number_done:
|
|||
const auto x = std::strtoull(token_buffer.data(), &endptr, 10);
|
||||
|
||||
// we checked the number format before
|
||||
assert(endptr == token_buffer.data() + token_buffer.size());
|
||||
JSON_ASSERT(endptr == token_buffer.data() + token_buffer.size());
|
||||
|
||||
if (errno == 0)
|
||||
{
|
||||
|
@ -1187,7 +1261,7 @@ scan_number_done:
|
|||
const auto x = std::strtoll(token_buffer.data(), &endptr, 10);
|
||||
|
||||
// we checked the number format before
|
||||
assert(endptr == token_buffer.data() + token_buffer.size());
|
||||
JSON_ASSERT(endptr == token_buffer.data() + token_buffer.size());
|
||||
|
||||
if (errno == 0)
|
||||
{
|
||||
|
@ -1204,7 +1278,7 @@ scan_number_done:
|
|||
strtof(value_float, token_buffer.data(), &endptr);
|
||||
|
||||
// we checked the number format before
|
||||
assert(endptr == token_buffer.data() + token_buffer.size());
|
||||
JSON_ASSERT(endptr == token_buffer.data() + token_buffer.size());
|
||||
|
||||
return token_type::value_float;
|
||||
}
|
||||
|
@ -1218,7 +1292,7 @@ scan_number_done:
|
|||
token_type scan_literal(const char_type* literal_text, const std::size_t length,
|
||||
token_type return_type)
|
||||
{
|
||||
assert(std::char_traits<char_type>::to_char_type(current) == literal_text[0]);
|
||||
JSON_ASSERT(std::char_traits<char_type>::to_char_type(current) == literal_text[0]);
|
||||
for (std::size_t i = 1; i < length; ++i)
|
||||
{
|
||||
if (JSON_HEDLEY_UNLIKELY(std::char_traits<char_type>::to_char_type(get()) != literal_text[i]))
|
||||
|
@ -1310,7 +1384,7 @@ scan_number_done:
|
|||
|
||||
if (JSON_HEDLEY_LIKELY(current != std::char_traits<char_type>::eof()))
|
||||
{
|
||||
assert(not token_string.empty());
|
||||
JSON_ASSERT(not token_string.empty());
|
||||
token_string.pop_back();
|
||||
}
|
||||
}
|
||||
|
@ -1415,6 +1489,15 @@ scan_number_done:
|
|||
return true;
|
||||
}
|
||||
|
||||
void skip_whitespace()
|
||||
{
|
||||
do
|
||||
{
|
||||
get();
|
||||
}
|
||||
while (current == ' ' or current == '\t' or current == '\n' or current == '\r');
|
||||
}
|
||||
|
||||
token_type scan()
|
||||
{
|
||||
// initially, skip the BOM
|
||||
|
@ -1425,11 +1508,19 @@ scan_number_done:
|
|||
}
|
||||
|
||||
// read next character and ignore whitespace
|
||||
do
|
||||
skip_whitespace();
|
||||
|
||||
// ignore comments
|
||||
if (ignore_comments and current == '/')
|
||||
{
|
||||
get();
|
||||
if (not scan_comment())
|
||||
{
|
||||
return token_type::parse_error;
|
||||
}
|
||||
|
||||
// skip following whitespace
|
||||
skip_whitespace();
|
||||
}
|
||||
while (current == ' ' or current == '\t' or current == '\n' or current == '\r');
|
||||
|
||||
switch (current)
|
||||
{
|
||||
|
@ -1499,6 +1590,9 @@ scan_number_done:
|
|||
/// input adapter
|
||||
InputAdapterType ia;
|
||||
|
||||
/// whether comments should be ignored (true) or signaled as errors (false)
|
||||
const bool ignore_comments = false;
|
||||
|
||||
/// the current character
|
||||
char_int_type current = std::char_traits<char_type>::eof();
|
||||
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
#pragma once
|
||||
|
||||
#include <cassert> // assert
|
||||
#include <cmath> // isfinite
|
||||
#include <cstdint> // uint8_t
|
||||
#include <functional> // function
|
||||
|
@ -63,8 +62,11 @@ class parser
|
|||
/// a parser reading from an input adapter
|
||||
explicit parser(InputAdapterType&& adapter,
|
||||
const parser_callback_t<BasicJsonType> cb = nullptr,
|
||||
const bool allow_exceptions_ = true)
|
||||
: callback(cb), m_lexer(std::move(adapter)), allow_exceptions(allow_exceptions_)
|
||||
const bool allow_exceptions_ = true,
|
||||
const bool skip_comments = false)
|
||||
: callback(cb)
|
||||
, m_lexer(std::move(adapter), skip_comments)
|
||||
, allow_exceptions(allow_exceptions_)
|
||||
{
|
||||
// read first token
|
||||
get_token();
|
||||
|
@ -380,7 +382,7 @@ class parser
|
|||
// new value, we need to evaluate the new state first.
|
||||
// By setting skip_to_state_evaluation to false, we
|
||||
// are effectively jumping to the beginning of this if.
|
||||
assert(not states.empty());
|
||||
JSON_ASSERT(not states.empty());
|
||||
states.pop_back();
|
||||
skip_to_state_evaluation = true;
|
||||
continue;
|
||||
|
@ -436,7 +438,7 @@ class parser
|
|||
// new value, we need to evaluate the new state first.
|
||||
// By setting skip_to_state_evaluation to false, we
|
||||
// are effectively jumping to the beginning of this if.
|
||||
assert(not states.empty());
|
||||
JSON_ASSERT(not states.empty());
|
||||
states.pop_back();
|
||||
skip_to_state_evaluation = true;
|
||||
continue;
|
||||
|
|
|
@ -18,8 +18,6 @@ template<typename BasicJsonType> struct internal_iterator
|
|||
typename BasicJsonType::object_t::iterator object_iterator {};
|
||||
/// iterator for JSON arrays
|
||||
typename BasicJsonType::array_t::iterator array_iterator {};
|
||||
/// iterator for JSON binary arrays
|
||||
typename BasicJsonType::binary_t::container_type::iterator binary_iterator {};
|
||||
/// generic iterator for all other types
|
||||
primitive_iterator_t primitive_iterator {};
|
||||
};
|
||||
|
|
|
@ -85,7 +85,7 @@ class iter_impl
|
|||
*/
|
||||
explicit iter_impl(pointer object) noexcept : m_object(object)
|
||||
{
|
||||
assert(m_object != nullptr);
|
||||
JSON_ASSERT(m_object != nullptr);
|
||||
|
||||
switch (m_object->m_type)
|
||||
{
|
||||
|
@ -171,7 +171,7 @@ class iter_impl
|
|||
*/
|
||||
void set_begin() noexcept
|
||||
{
|
||||
assert(m_object != nullptr);
|
||||
JSON_ASSERT(m_object != nullptr);
|
||||
|
||||
switch (m_object->m_type)
|
||||
{
|
||||
|
@ -208,7 +208,7 @@ class iter_impl
|
|||
*/
|
||||
void set_end() noexcept
|
||||
{
|
||||
assert(m_object != nullptr);
|
||||
JSON_ASSERT(m_object != nullptr);
|
||||
|
||||
switch (m_object->m_type)
|
||||
{
|
||||
|
@ -239,19 +239,19 @@ class iter_impl
|
|||
*/
|
||||
reference operator*() const
|
||||
{
|
||||
assert(m_object != nullptr);
|
||||
JSON_ASSERT(m_object != nullptr);
|
||||
|
||||
switch (m_object->m_type)
|
||||
{
|
||||
case value_t::object:
|
||||
{
|
||||
assert(m_it.object_iterator != m_object->m_value.object->end());
|
||||
JSON_ASSERT(m_it.object_iterator != m_object->m_value.object->end());
|
||||
return m_it.object_iterator->second;
|
||||
}
|
||||
|
||||
case value_t::array:
|
||||
{
|
||||
assert(m_it.array_iterator != m_object->m_value.array->end());
|
||||
JSON_ASSERT(m_it.array_iterator != m_object->m_value.array->end());
|
||||
return *m_it.array_iterator;
|
||||
}
|
||||
|
||||
|
@ -276,19 +276,19 @@ class iter_impl
|
|||
*/
|
||||
pointer operator->() const
|
||||
{
|
||||
assert(m_object != nullptr);
|
||||
JSON_ASSERT(m_object != nullptr);
|
||||
|
||||
switch (m_object->m_type)
|
||||
{
|
||||
case value_t::object:
|
||||
{
|
||||
assert(m_it.object_iterator != m_object->m_value.object->end());
|
||||
JSON_ASSERT(m_it.object_iterator != m_object->m_value.object->end());
|
||||
return &(m_it.object_iterator->second);
|
||||
}
|
||||
|
||||
case value_t::array:
|
||||
{
|
||||
assert(m_it.array_iterator != m_object->m_value.array->end());
|
||||
JSON_ASSERT(m_it.array_iterator != m_object->m_value.array->end());
|
||||
return &*m_it.array_iterator;
|
||||
}
|
||||
|
||||
|
@ -321,7 +321,7 @@ class iter_impl
|
|||
*/
|
||||
iter_impl& operator++()
|
||||
{
|
||||
assert(m_object != nullptr);
|
||||
JSON_ASSERT(m_object != nullptr);
|
||||
|
||||
switch (m_object->m_type)
|
||||
{
|
||||
|
@ -364,7 +364,7 @@ class iter_impl
|
|||
*/
|
||||
iter_impl& operator--()
|
||||
{
|
||||
assert(m_object != nullptr);
|
||||
JSON_ASSERT(m_object != nullptr);
|
||||
|
||||
switch (m_object->m_type)
|
||||
{
|
||||
|
@ -402,7 +402,7 @@ class iter_impl
|
|||
JSON_THROW(invalid_iterator::create(212, "cannot compare iterators of different containers"));
|
||||
}
|
||||
|
||||
assert(m_object != nullptr);
|
||||
JSON_ASSERT(m_object != nullptr);
|
||||
|
||||
switch (m_object->m_type)
|
||||
{
|
||||
|
@ -438,7 +438,7 @@ class iter_impl
|
|||
JSON_THROW(invalid_iterator::create(212, "cannot compare iterators of different containers"));
|
||||
}
|
||||
|
||||
assert(m_object != nullptr);
|
||||
JSON_ASSERT(m_object != nullptr);
|
||||
|
||||
switch (m_object->m_type)
|
||||
{
|
||||
|
@ -486,7 +486,7 @@ class iter_impl
|
|||
*/
|
||||
iter_impl& operator+=(difference_type i)
|
||||
{
|
||||
assert(m_object != nullptr);
|
||||
JSON_ASSERT(m_object != nullptr);
|
||||
|
||||
switch (m_object->m_type)
|
||||
{
|
||||
|
@ -557,7 +557,7 @@ class iter_impl
|
|||
*/
|
||||
difference_type operator-(const iter_impl& other) const
|
||||
{
|
||||
assert(m_object != nullptr);
|
||||
JSON_ASSERT(m_object != nullptr);
|
||||
|
||||
switch (m_object->m_type)
|
||||
{
|
||||
|
@ -578,7 +578,7 @@ class iter_impl
|
|||
*/
|
||||
reference operator[](difference_type n) const
|
||||
{
|
||||
assert(m_object != nullptr);
|
||||
JSON_ASSERT(m_object != nullptr);
|
||||
|
||||
switch (m_object->m_type)
|
||||
{
|
||||
|
@ -609,7 +609,7 @@ class iter_impl
|
|||
*/
|
||||
const typename object_t::key_type& key() const
|
||||
{
|
||||
assert(m_object != nullptr);
|
||||
JSON_ASSERT(m_object != nullptr);
|
||||
|
||||
if (JSON_HEDLEY_LIKELY(m_object->is_object()))
|
||||
{
|
||||
|
|
|
@ -15,7 +15,9 @@ namespace detail
|
|||
template<typename string_type>
|
||||
void int_to_string( string_type& target, std::size_t value )
|
||||
{
|
||||
target = std::to_string(value);
|
||||
// For ADL
|
||||
using std::to_string;
|
||||
target = to_string(value);
|
||||
}
|
||||
template <typename IteratorType> class iteration_proxy_value
|
||||
{
|
||||
|
@ -72,7 +74,7 @@ template <typename IteratorType> class iteration_proxy_value
|
|||
/// return key of the iterator
|
||||
const string_type& key() const
|
||||
{
|
||||
assert(anchor.m_object != nullptr);
|
||||
JSON_ASSERT(anchor.m_object != nullptr);
|
||||
|
||||
switch (anchor.m_object->type())
|
||||
{
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
#pragma once
|
||||
|
||||
#include <algorithm> // all_of
|
||||
#include <cassert> // assert
|
||||
#include <cctype> // isdigit
|
||||
#include <limits> // max
|
||||
#include <numeric> // accumulate
|
||||
#include <string> // string
|
||||
#include <utility> // move
|
||||
|
@ -325,10 +325,15 @@ class json_pointer
|
|||
|
||||
@return integer representation of @a s
|
||||
|
||||
@throw parse_error.106 if an array index begins with '0'
|
||||
@throw parse_error.109 if an array index begins not with a digit
|
||||
@throw out_of_range.404 if string @a s could not be converted to an integer
|
||||
@throw out_of_range.410 if an array index exceeds size_type
|
||||
*/
|
||||
static int array_index(const std::string& s)
|
||||
static typename BasicJsonType::size_type array_index(const std::string& s)
|
||||
{
|
||||
using size_type = typename BasicJsonType::size_type;
|
||||
|
||||
// error condition (cf. RFC 6901, Sect. 4)
|
||||
if (JSON_HEDLEY_UNLIKELY(s.size() > 1 and s[0] == '0'))
|
||||
{
|
||||
|
@ -344,10 +349,10 @@ class json_pointer
|
|||
}
|
||||
|
||||
std::size_t processed_chars = 0;
|
||||
int res = 0;
|
||||
unsigned long long res = 0;
|
||||
JSON_TRY
|
||||
{
|
||||
res = std::stoi(s, &processed_chars);
|
||||
res = std::stoull(s, &processed_chars);
|
||||
}
|
||||
JSON_CATCH(std::out_of_range&)
|
||||
{
|
||||
|
@ -360,7 +365,14 @@ class json_pointer
|
|||
JSON_THROW(detail::out_of_range::create(404, "unresolved reference token '" + s + "'"));
|
||||
}
|
||||
|
||||
return res;
|
||||
// only triggered on special platforms (like 32bit), see also
|
||||
// https://github.com/nlohmann/json/pull/2203
|
||||
if (res >= static_cast<unsigned long long>((std::numeric_limits<size_type>::max)()))
|
||||
{
|
||||
JSON_THROW(detail::out_of_range::create(410, "array index " + s + " exceeds size_type")); // LCOV_EXCL_LINE
|
||||
}
|
||||
|
||||
return static_cast<size_type>(res);
|
||||
}
|
||||
|
||||
json_pointer top() const
|
||||
|
@ -385,7 +397,6 @@ class json_pointer
|
|||
*/
|
||||
BasicJsonType& get_and_create(BasicJsonType& j) const
|
||||
{
|
||||
using size_type = typename BasicJsonType::size_type;
|
||||
auto result = &j;
|
||||
|
||||
// in case no reference tokens exist, return a reference to the JSON value
|
||||
|
@ -419,7 +430,7 @@ class json_pointer
|
|||
case detail::value_t::array:
|
||||
{
|
||||
// create an entry in the array
|
||||
result = &result->operator[](static_cast<size_type>(array_index(reference_token)));
|
||||
result = &result->operator[](array_index(reference_token));
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -458,7 +469,6 @@ class json_pointer
|
|||
*/
|
||||
BasicJsonType& get_unchecked(BasicJsonType* ptr) const
|
||||
{
|
||||
using size_type = typename BasicJsonType::size_type;
|
||||
for (const auto& reference_token : reference_tokens)
|
||||
{
|
||||
// convert null values to arrays or objects before continuing
|
||||
|
@ -497,8 +507,7 @@ class json_pointer
|
|||
else
|
||||
{
|
||||
// convert array index to number; unchecked access
|
||||
ptr = &ptr->operator[](
|
||||
static_cast<size_type>(array_index(reference_token)));
|
||||
ptr = &ptr->operator[](array_index(reference_token));
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -519,7 +528,6 @@ class json_pointer
|
|||
*/
|
||||
BasicJsonType& get_checked(BasicJsonType* ptr) const
|
||||
{
|
||||
using size_type = typename BasicJsonType::size_type;
|
||||
for (const auto& reference_token : reference_tokens)
|
||||
{
|
||||
switch (ptr->type())
|
||||
|
@ -542,7 +550,7 @@ class json_pointer
|
|||
}
|
||||
|
||||
// note: at performs range check
|
||||
ptr = &ptr->at(static_cast<size_type>(array_index(reference_token)));
|
||||
ptr = &ptr->at(array_index(reference_token));
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -569,7 +577,6 @@ class json_pointer
|
|||
*/
|
||||
const BasicJsonType& get_unchecked(const BasicJsonType* ptr) const
|
||||
{
|
||||
using size_type = typename BasicJsonType::size_type;
|
||||
for (const auto& reference_token : reference_tokens)
|
||||
{
|
||||
switch (ptr->type())
|
||||
|
@ -592,8 +599,7 @@ class json_pointer
|
|||
}
|
||||
|
||||
// use unchecked array access
|
||||
ptr = &ptr->operator[](
|
||||
static_cast<size_type>(array_index(reference_token)));
|
||||
ptr = &ptr->operator[](array_index(reference_token));
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -613,7 +619,6 @@ class json_pointer
|
|||
*/
|
||||
const BasicJsonType& get_checked(const BasicJsonType* ptr) const
|
||||
{
|
||||
using size_type = typename BasicJsonType::size_type;
|
||||
for (const auto& reference_token : reference_tokens)
|
||||
{
|
||||
switch (ptr->type())
|
||||
|
@ -636,7 +641,7 @@ class json_pointer
|
|||
}
|
||||
|
||||
// note: at performs range check
|
||||
ptr = &ptr->at(static_cast<size_type>(array_index(reference_token)));
|
||||
ptr = &ptr->at(array_index(reference_token));
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -654,7 +659,6 @@ class json_pointer
|
|||
*/
|
||||
bool contains(const BasicJsonType* ptr) const
|
||||
{
|
||||
using size_type = typename BasicJsonType::size_type;
|
||||
for (const auto& reference_token : reference_tokens)
|
||||
{
|
||||
switch (ptr->type())
|
||||
|
@ -700,7 +704,7 @@ class json_pointer
|
|||
}
|
||||
}
|
||||
|
||||
const auto idx = static_cast<size_type>(array_index(reference_token));
|
||||
const auto idx = array_index(reference_token);
|
||||
if (idx >= ptr->size())
|
||||
{
|
||||
// index out of range
|
||||
|
@ -776,7 +780,7 @@ class json_pointer
|
|||
pos != std::string::npos;
|
||||
pos = reference_token.find_first_of('~', pos + 1))
|
||||
{
|
||||
assert(reference_token[pos] == '~');
|
||||
JSON_ASSERT(reference_token[pos] == '~');
|
||||
|
||||
// ~ must be followed by 0 or 1
|
||||
if (JSON_HEDLEY_UNLIKELY(pos == reference_token.size() - 1 or
|
||||
|
@ -811,7 +815,7 @@ class json_pointer
|
|||
static void replace_substring(std::string& s, const std::string& f,
|
||||
const std::string& t)
|
||||
{
|
||||
assert(not f.empty());
|
||||
JSON_ASSERT(not f.empty());
|
||||
for (auto pos = s.find(f); // find first occurrence of f
|
||||
pos != std::string::npos; // make sure f was found
|
||||
s.replace(pos, f.size(), t), // replace with t, and
|
||||
|
|
|
@ -16,23 +16,30 @@ class json_ref
|
|||
using value_type = BasicJsonType;
|
||||
|
||||
json_ref(value_type&& value)
|
||||
: owned_value(std::move(value)), value_ref(&owned_value), is_rvalue(true)
|
||||
: owned_value(std::move(value))
|
||||
, value_ref(&owned_value)
|
||||
, is_rvalue(true)
|
||||
{}
|
||||
|
||||
json_ref(const value_type& value)
|
||||
: value_ref(const_cast<value_type*>(&value)), is_rvalue(false)
|
||||
: value_ref(const_cast<value_type*>(&value))
|
||||
, is_rvalue(false)
|
||||
{}
|
||||
|
||||
json_ref(std::initializer_list<json_ref> init)
|
||||
: owned_value(init), value_ref(&owned_value), is_rvalue(true)
|
||||
: owned_value(init)
|
||||
, value_ref(&owned_value)
|
||||
, is_rvalue(true)
|
||||
{}
|
||||
|
||||
template <
|
||||
class... Args,
|
||||
enable_if_t<std::is_constructible<value_type, Args...>::value, int> = 0 >
|
||||
json_ref(Args && ... args)
|
||||
: owned_value(std::forward<Args>(args)...), value_ref(&owned_value),
|
||||
is_rvalue(true) {}
|
||||
: owned_value(std::forward<Args>(args)...)
|
||||
, value_ref(&owned_value)
|
||||
, is_rvalue(true)
|
||||
{}
|
||||
|
||||
// class should be movable only
|
||||
json_ref(json_ref&&) = default;
|
||||
|
@ -63,7 +70,7 @@ class json_ref
|
|||
private:
|
||||
mutable value_type owned_value = nullptr;
|
||||
value_type* value_ref = nullptr;
|
||||
const bool is_rvalue;
|
||||
const bool is_rvalue = true;
|
||||
};
|
||||
} // namespace detail
|
||||
} // namespace nlohmann
|
||||
|
|
|
@ -20,7 +20,11 @@
|
|||
#endif
|
||||
|
||||
// C++ language standard detection
|
||||
#if (defined(__cplusplus) && __cplusplus >= 201703L) || (defined(_HAS_CXX17) && _HAS_CXX17 == 1) // fix for issue #464
|
||||
#if (defined(__cplusplus) && __cplusplus >= 202002L) || (defined(_MSVC_LANG) && _MSVC_LANG >= 202002L)
|
||||
#define JSON_HAS_CPP_20
|
||||
#define JSON_HAS_CPP_17
|
||||
#define JSON_HAS_CPP_14
|
||||
#elif (defined(__cplusplus) && __cplusplus >= 201703L) || (defined(_HAS_CXX17) && _HAS_CXX17 == 1) // fix for issue #464
|
||||
#define JSON_HAS_CPP_17
|
||||
#define JSON_HAS_CPP_14
|
||||
#elif (defined(__cplusplus) && __cplusplus >= 201402L) || (defined(_HAS_CXX14) && _HAS_CXX14 == 1)
|
||||
|
@ -73,6 +77,12 @@
|
|||
#define JSON_INTERNAL_CATCH JSON_INTERNAL_CATCH_USER
|
||||
#endif
|
||||
|
||||
// allow to override assert
|
||||
#if !defined(JSON_ASSERT)
|
||||
#include <cassert> // assert
|
||||
#define JSON_ASSERT(x) assert(x)
|
||||
#endif
|
||||
|
||||
/*!
|
||||
@brief macro to briefly define a mapping between an enum and JSON
|
||||
@def NLOHMANN_JSON_SERIALIZE_ENUM
|
||||
|
@ -120,3 +130,44 @@
|
|||
basic_json<ObjectType, ArrayType, StringType, BooleanType, \
|
||||
NumberIntegerType, NumberUnsignedType, NumberFloatType, \
|
||||
AllocatorType, JSONSerializer, BinaryType>
|
||||
|
||||
// Macros to simplify conversion from/to types
|
||||
|
||||
#define NLOHMANN_JSON_EXPAND( x ) x
|
||||
#define NLOHMANN_JSON_GET_MACRO(_1,_2,_3,_4,_5,_6, _7, _8, _9, _10, _11, NAME,...) NAME
|
||||
|
||||
#define NLOHMANN_JSON_PASTE(...) NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_GET_MACRO(__VA_ARGS__, NLOHMANN_JSON_PASTE11, \
|
||||
NLOHMANN_JSON_PASTE10, NLOHMANN_JSON_PASTE9, NLOHMANN_JSON_PASTE8, NLOHMANN_JSON_PASTE7, \
|
||||
NLOHMANN_JSON_PASTE6, NLOHMANN_JSON_PASTE5, NLOHMANN_JSON_PASTE4, NLOHMANN_JSON_PASTE3, \
|
||||
NLOHMANN_JSON_PASTE2, NLOHMANN_JSON_PASTE1)(__VA_ARGS__))
|
||||
#define NLOHMANN_JSON_PASTE2(func, v1) func(v1)
|
||||
#define NLOHMANN_JSON_PASTE3(func, v1, v2) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE2(func, v2)
|
||||
#define NLOHMANN_JSON_PASTE4(func, v1, v2, v3) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE3(func, v2, v3)
|
||||
#define NLOHMANN_JSON_PASTE5(func, v1, v2, v3, v4) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE4(func, v2, v3, v4)
|
||||
#define NLOHMANN_JSON_PASTE6(func, v1, v2, v3, v4, v5) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE5(func, v2, v3, v4, v5)
|
||||
#define NLOHMANN_JSON_PASTE7(func, v1, v2, v3, v4, v5, v6) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE6(func, v2, v3, v4, v5, v6)
|
||||
#define NLOHMANN_JSON_PASTE8(func, v1, v2, v3, v4, v5, v6, v7) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE7(func, v2, v3, v4, v5, v6, v7)
|
||||
#define NLOHMANN_JSON_PASTE9(func, v1, v2, v3, v4, v5, v6, v7, v8) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE8(func, v2, v3, v4, v5, v6, v7, v8)
|
||||
#define NLOHMANN_JSON_PASTE10(func, v1, v2, v3, v4, v5, v6, v7, v8, v9) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE8(func, v2, v3, v4, v5, v6, v7, v8, v9)
|
||||
#define NLOHMANN_JSON_PASTE11(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE8(func, v2, v3, v4, v5, v6, v7, v8, v9, v10)
|
||||
|
||||
#define NLOHMANN_JSON_TO(v1) j[#v1] = t.v1;
|
||||
#define NLOHMANN_JSON_FROM(v1) j.at(#v1).get_to(t.v1);
|
||||
|
||||
/*!
|
||||
@brief macro
|
||||
@def NLOHMANN_DEFINE_TYPE_INTRUSIVE
|
||||
@since version 3.9.0
|
||||
*/
|
||||
#define NLOHMANN_DEFINE_TYPE_INTRUSIVE(Type, ...) \
|
||||
friend void to_json(nlohmann::json& j, const Type& t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) } \
|
||||
friend void from_json(const nlohmann::json& j, Type& t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM, __VA_ARGS__)) }
|
||||
|
||||
/*!
|
||||
@brief macro
|
||||
@def NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE
|
||||
@since version 3.9.0
|
||||
*/
|
||||
#define NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(Type, ...) \
|
||||
void to_json(nlohmann::json& j, const Type& t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) } \
|
||||
void from_json(const nlohmann::json& j, Type& t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM, __VA_ARGS__)) }
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
#endif
|
||||
|
||||
// clean up
|
||||
#undef JSON_ASSERT
|
||||
#undef JSON_INTERNAL_CATCH
|
||||
#undef JSON_CATCH
|
||||
#undef JSON_THROW
|
||||
|
|
|
@ -28,6 +28,7 @@ class binary_writer
|
|||
{
|
||||
using string_t = typename BasicJsonType::string_t;
|
||||
using binary_t = typename BasicJsonType::binary_t;
|
||||
using number_float_t = typename BasicJsonType::number_float_t;
|
||||
|
||||
public:
|
||||
/*!
|
||||
|
@ -37,7 +38,7 @@ class binary_writer
|
|||
*/
|
||||
explicit binary_writer(output_adapter_t<CharType> adapter) : oa(adapter)
|
||||
{
|
||||
assert(oa);
|
||||
JSON_ASSERT(oa);
|
||||
}
|
||||
|
||||
/*!
|
||||
|
@ -194,18 +195,7 @@ class binary_writer
|
|||
}
|
||||
else
|
||||
{
|
||||
if (static_cast<double>(j.m_value.number_float) >= static_cast<double>(std::numeric_limits<float>::lowest()) and
|
||||
static_cast<double>(j.m_value.number_float) <= static_cast<double>((std::numeric_limits<float>::max)()) and
|
||||
static_cast<double>(static_cast<float>(j.m_value.number_float)) == static_cast<double>(j.m_value.number_float))
|
||||
{
|
||||
oa->write_character(get_cbor_float_prefix(static_cast<float>(j.m_value.number_float)));
|
||||
write_number(static_cast<float>(j.m_value.number_float));
|
||||
}
|
||||
else
|
||||
{
|
||||
oa->write_character(get_cbor_float_prefix(j.m_value.number_float));
|
||||
write_number(j.m_value.number_float);
|
||||
}
|
||||
write_compact_float(j.m_value.number_float, detail::input_format_t::cbor);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -504,8 +494,7 @@ class binary_writer
|
|||
|
||||
case value_t::number_float:
|
||||
{
|
||||
oa->write_character(get_msgpack_float_prefix(j.m_value.number_float));
|
||||
write_number(j.m_value.number_float);
|
||||
write_compact_float(j.m_value.number_float, detail::input_format_t::msgpack);
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -584,7 +573,7 @@ class binary_writer
|
|||
const auto N = j.m_value.binary->size();
|
||||
if (N <= (std::numeric_limits<std::uint8_t>::max)())
|
||||
{
|
||||
std::uint8_t output_type;
|
||||
std::uint8_t output_type{};
|
||||
bool fixed = true;
|
||||
if (use_ext)
|
||||
{
|
||||
|
@ -626,30 +615,18 @@ class binary_writer
|
|||
}
|
||||
else if (N <= (std::numeric_limits<std::uint16_t>::max)())
|
||||
{
|
||||
std::uint8_t output_type;
|
||||
if (use_ext)
|
||||
{
|
||||
output_type = 0xC8; // ext 16
|
||||
}
|
||||
else
|
||||
{
|
||||
output_type = 0xC5; // bin 16
|
||||
}
|
||||
std::uint8_t output_type = use_ext
|
||||
? 0xC8 // ext 16
|
||||
: 0xC5; // bin 16
|
||||
|
||||
oa->write_character(to_char_type(output_type));
|
||||
write_number(static_cast<std::uint16_t>(N));
|
||||
}
|
||||
else if (N <= (std::numeric_limits<std::uint32_t>::max)())
|
||||
{
|
||||
std::uint8_t output_type;
|
||||
if (use_ext)
|
||||
{
|
||||
output_type = 0xC9; // ext 32
|
||||
}
|
||||
else
|
||||
{
|
||||
output_type = 0xC6; // bin 32
|
||||
}
|
||||
std::uint8_t output_type = use_ext
|
||||
? 0xC9 // ext 32
|
||||
: 0xC6; // bin 32
|
||||
|
||||
oa->write_character(to_char_type(output_type));
|
||||
write_number(static_cast<std::uint32_t>(N));
|
||||
|
@ -777,7 +754,7 @@ class binary_writer
|
|||
bool prefix_required = true;
|
||||
if (use_type and not j.m_value.array->empty())
|
||||
{
|
||||
assert(use_count);
|
||||
JSON_ASSERT(use_count);
|
||||
const CharType first_prefix = ubjson_prefix(j.front());
|
||||
const bool same_prefix = std::all_of(j.begin() + 1, j.end(),
|
||||
[this, first_prefix](const BasicJsonType & v)
|
||||
|
@ -821,7 +798,7 @@ class binary_writer
|
|||
|
||||
if (use_type and not j.m_value.binary->empty())
|
||||
{
|
||||
assert(use_count);
|
||||
JSON_ASSERT(use_count);
|
||||
oa->write_character(to_char_type('$'));
|
||||
oa->write_character('U');
|
||||
}
|
||||
|
@ -865,7 +842,7 @@ class binary_writer
|
|||
bool prefix_required = true;
|
||||
if (use_type and not j.m_value.object->empty())
|
||||
{
|
||||
assert(use_count);
|
||||
JSON_ASSERT(use_count);
|
||||
const CharType first_prefix = ubjson_prefix(j.front());
|
||||
const bool same_prefix = std::all_of(j.begin(), j.end(),
|
||||
[this, first_prefix](const BasicJsonType & v)
|
||||
|
@ -1157,7 +1134,7 @@ class binary_writer
|
|||
|
||||
// LCOV_EXCL_START
|
||||
default:
|
||||
assert(false);
|
||||
JSON_ASSERT(false);
|
||||
return 0ul;
|
||||
// LCOV_EXCL_STOP
|
||||
}
|
||||
|
@ -1204,7 +1181,7 @@ class binary_writer
|
|||
|
||||
// LCOV_EXCL_START
|
||||
default:
|
||||
assert(false);
|
||||
JSON_ASSERT(false);
|
||||
return;
|
||||
// LCOV_EXCL_STOP
|
||||
}
|
||||
|
@ -1518,6 +1495,26 @@ class binary_writer
|
|||
oa->write_characters(vec.data(), sizeof(NumberType));
|
||||
}
|
||||
|
||||
void write_compact_float(const number_float_t n, detail::input_format_t format)
|
||||
{
|
||||
if (static_cast<double>(n) >= static_cast<double>(std::numeric_limits<float>::lowest()) and
|
||||
static_cast<double>(n) <= static_cast<double>((std::numeric_limits<float>::max)()) and
|
||||
static_cast<double>(static_cast<float>(n)) == static_cast<double>(n))
|
||||
{
|
||||
oa->write_character(format == detail::input_format_t::cbor
|
||||
? get_cbor_float_prefix(static_cast<float>(n))
|
||||
: get_msgpack_float_prefix(static_cast<float>(n)));
|
||||
write_number(static_cast<float>(n));
|
||||
}
|
||||
else
|
||||
{
|
||||
oa->write_character(format == detail::input_format_t::cbor
|
||||
? get_cbor_float_prefix(n)
|
||||
: get_msgpack_float_prefix(n));
|
||||
write_number(n);
|
||||
}
|
||||
}
|
||||
|
||||
public:
|
||||
// The following to_char_type functions are implement the conversion
|
||||
// between uint8_t and CharType. In case CharType is not unsigned,
|
||||
|
|
|
@ -2,14 +2,13 @@
|
|||
|
||||
#include <algorithm> // reverse, remove, fill, find, none_of
|
||||
#include <array> // array
|
||||
#include <cassert> // assert
|
||||
#include <clocale> // localeconv, lconv
|
||||
#include <cmath> // labs, isfinite, isnan, signbit
|
||||
#include <cstddef> // size_t, ptrdiff_t
|
||||
#include <cstdint> // uint8_t
|
||||
#include <cstdio> // snprintf
|
||||
#include <limits> // numeric_limits
|
||||
#include <string> // string
|
||||
#include <string> // string, char_traits
|
||||
#include <type_traits> // is_same
|
||||
#include <utility> // move
|
||||
|
||||
|
@ -59,8 +58,8 @@ class serializer
|
|||
error_handler_t error_handler_ = error_handler_t::strict)
|
||||
: o(std::move(s))
|
||||
, loc(std::localeconv())
|
||||
, thousands_sep(loc->thousands_sep == nullptr ? '\0' : * (loc->thousands_sep))
|
||||
, decimal_point(loc->decimal_point == nullptr ? '\0' : * (loc->decimal_point))
|
||||
, thousands_sep(loc->thousands_sep == nullptr ? '\0' : std::char_traits<char>::to_char_type(* (loc->thousands_sep)))
|
||||
, decimal_point(loc->decimal_point == nullptr ? '\0' : std::char_traits<char>::to_char_type(* (loc->decimal_point)))
|
||||
, indent_char(ichar)
|
||||
, indent_string(512, indent_char)
|
||||
, error_handler(error_handler_)
|
||||
|
@ -135,8 +134,8 @@ class serializer
|
|||
}
|
||||
|
||||
// last element
|
||||
assert(i != val.m_value.object->cend());
|
||||
assert(std::next(i) == val.m_value.object->cend());
|
||||
JSON_ASSERT(i != val.m_value.object->cend());
|
||||
JSON_ASSERT(std::next(i) == val.m_value.object->cend());
|
||||
o->write_characters(indent_string.c_str(), new_indent);
|
||||
o->write_character('\"');
|
||||
dump_escaped(i->first, ensure_ascii);
|
||||
|
@ -163,8 +162,8 @@ class serializer
|
|||
}
|
||||
|
||||
// last element
|
||||
assert(i != val.m_value.object->cend());
|
||||
assert(std::next(i) == val.m_value.object->cend());
|
||||
JSON_ASSERT(i != val.m_value.object->cend());
|
||||
JSON_ASSERT(std::next(i) == val.m_value.object->cend());
|
||||
o->write_character('\"');
|
||||
dump_escaped(i->first, ensure_ascii);
|
||||
o->write_characters("\":", 2);
|
||||
|
@ -205,7 +204,7 @@ class serializer
|
|||
}
|
||||
|
||||
// last element
|
||||
assert(not val.m_value.array->empty());
|
||||
JSON_ASSERT(not val.m_value.array->empty());
|
||||
o->write_characters(indent_string.c_str(), new_indent);
|
||||
dump(val.m_value.array->back(), true, ensure_ascii, indent_step, new_indent);
|
||||
|
||||
|
@ -226,7 +225,7 @@ class serializer
|
|||
}
|
||||
|
||||
// last element
|
||||
assert(not val.m_value.array->empty());
|
||||
JSON_ASSERT(not val.m_value.array->empty());
|
||||
dump(val.m_value.array->back(), false, ensure_ascii, indent_step, current_indent);
|
||||
|
||||
o->write_character(']');
|
||||
|
@ -360,7 +359,7 @@ class serializer
|
|||
}
|
||||
|
||||
default: // LCOV_EXCL_LINE
|
||||
assert(false); // LCOV_EXCL_LINE
|
||||
JSON_ASSERT(false); // LCOV_EXCL_LINE
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -559,7 +558,7 @@ class serializer
|
|||
}
|
||||
|
||||
default: // LCOV_EXCL_LINE
|
||||
assert(false); // LCOV_EXCL_LINE
|
||||
JSON_ASSERT(false); // LCOV_EXCL_LINE
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -622,7 +621,7 @@ class serializer
|
|||
}
|
||||
|
||||
default: // LCOV_EXCL_LINE
|
||||
assert(false); // LCOV_EXCL_LINE
|
||||
JSON_ASSERT(false); // LCOV_EXCL_LINE
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -723,7 +722,7 @@ class serializer
|
|||
}
|
||||
|
||||
// spare 1 byte for '\0'
|
||||
assert(n_chars < number_buffer.size() - 1);
|
||||
JSON_ASSERT(n_chars < number_buffer.size() - 1);
|
||||
|
||||
// jump to the end to generate the string from backward
|
||||
// so we later avoid reversing the result
|
||||
|
@ -799,9 +798,9 @@ class serializer
|
|||
std::ptrdiff_t len = (std::snprintf)(number_buffer.data(), number_buffer.size(), "%.*g", d, x);
|
||||
|
||||
// negative value indicates an error
|
||||
assert(len > 0);
|
||||
JSON_ASSERT(len > 0);
|
||||
// check if buffer was large enough
|
||||
assert(static_cast<std::size_t>(len) < number_buffer.size());
|
||||
JSON_ASSERT(static_cast<std::size_t>(len) < number_buffer.size());
|
||||
|
||||
// erase thousands separator
|
||||
if (thousands_sep != '\0')
|
||||
|
@ -809,7 +808,7 @@ class serializer
|
|||
const auto end = std::remove(number_buffer.begin(),
|
||||
number_buffer.begin() + len, thousands_sep);
|
||||
std::fill(end, number_buffer.end(), '\0');
|
||||
assert((end - number_buffer.begin()) <= len);
|
||||
JSON_ASSERT((end - number_buffer.begin()) <= len);
|
||||
len = (end - number_buffer.begin());
|
||||
}
|
||||
|
||||
|
@ -889,7 +888,7 @@ class serializer
|
|||
: (0xFFu >> type) & (byte);
|
||||
|
||||
std::size_t index = 256u + static_cast<size_t>(state) * 16u + static_cast<size_t>(type);
|
||||
assert(index < 400);
|
||||
JSON_ASSERT(index < 400);
|
||||
state = utf8d[index];
|
||||
return state;
|
||||
}
|
||||
|
@ -901,7 +900,7 @@ class serializer
|
|||
*/
|
||||
number_unsigned_t remove_sign(number_unsigned_t x)
|
||||
{
|
||||
assert(false); // LCOV_EXCL_LINE
|
||||
JSON_ASSERT(false); // LCOV_EXCL_LINE
|
||||
return x; // LCOV_EXCL_LINE
|
||||
}
|
||||
|
||||
|
@ -916,7 +915,7 @@ class serializer
|
|||
*/
|
||||
inline number_unsigned_t remove_sign(number_integer_t x) noexcept
|
||||
{
|
||||
assert(x < 0 and x < (std::numeric_limits<number_integer_t>::max)());
|
||||
JSON_ASSERT(x < 0 and x < (std::numeric_limits<number_integer_t>::max)());
|
||||
return static_cast<number_unsigned_t>(-(x + 1)) + 1;
|
||||
}
|
||||
|
||||
|
|
|
@ -35,7 +35,6 @@ SOFTWARE.
|
|||
#define NLOHMANN_JSON_VERSION_PATCH 0
|
||||
|
||||
#include <algorithm> // all_of, find, for_each
|
||||
#include <cassert> // assert
|
||||
#include <cstddef> // nullptr_t, ptrdiff_t, size_t
|
||||
#include <functional> // hash, less
|
||||
#include <initializer_list> // initializer_list
|
||||
|
@ -197,10 +196,12 @@ class basic_json
|
|||
static ::nlohmann::detail::parser<basic_json, InputAdapterType> parser(
|
||||
InputAdapterType adapter,
|
||||
detail::parser_callback_t<basic_json>cb = nullptr,
|
||||
bool allow_exceptions = true
|
||||
const bool allow_exceptions = true,
|
||||
const bool ignore_comments = false
|
||||
)
|
||||
{
|
||||
return ::nlohmann::detail::parser<basic_json, InputAdapterType>(std::move(adapter), std::move(cb), allow_exceptions);
|
||||
return ::nlohmann::detail::parser<basic_json, InputAdapterType>(std::move(adapter),
|
||||
std::move(cb), allow_exceptions, ignore_comments);
|
||||
}
|
||||
|
||||
using primitive_iterator_t = ::nlohmann::detail::primitive_iterator_t;
|
||||
|
@ -923,7 +924,7 @@ class basic_json
|
|||
};
|
||||
std::unique_ptr<T, decltype(deleter)> object(AllocatorTraits::allocate(alloc, 1), deleter);
|
||||
AllocatorTraits::construct(alloc, object.get(), std::forward<Args>(args)...);
|
||||
assert(object != nullptr);
|
||||
JSON_ASSERT(object != nullptr);
|
||||
return object.release();
|
||||
}
|
||||
|
||||
|
@ -1218,10 +1219,10 @@ class basic_json
|
|||
*/
|
||||
void assert_invariant() const noexcept
|
||||
{
|
||||
assert(m_type != value_t::object or m_value.object != nullptr);
|
||||
assert(m_type != value_t::array or m_value.array != nullptr);
|
||||
assert(m_type != value_t::string or m_value.string != nullptr);
|
||||
assert(m_type != value_t::binary or m_value.binary != nullptr);
|
||||
JSON_ASSERT(m_type != value_t::object or m_value.object != nullptr);
|
||||
JSON_ASSERT(m_type != value_t::array or m_value.array != nullptr);
|
||||
JSON_ASSERT(m_type != value_t::string or m_value.string != nullptr);
|
||||
JSON_ASSERT(m_type != value_t::binary or m_value.binary != nullptr);
|
||||
}
|
||||
|
||||
public:
|
||||
|
@ -1514,7 +1515,7 @@ class basic_json
|
|||
m_type = value_t::discarded;
|
||||
break;
|
||||
default: // LCOV_EXCL_LINE
|
||||
assert(false); // LCOV_EXCL_LINE
|
||||
JSON_ASSERT(false); // LCOV_EXCL_LINE
|
||||
}
|
||||
assert_invariant();
|
||||
}
|
||||
|
@ -1914,8 +1915,8 @@ class basic_json
|
|||
std::is_same<InputIT, typename basic_json_t::const_iterator>::value, int>::type = 0>
|
||||
basic_json(InputIT first, InputIT last)
|
||||
{
|
||||
assert(first.m_object != nullptr);
|
||||
assert(last.m_object != nullptr);
|
||||
JSON_ASSERT(first.m_object != nullptr);
|
||||
JSON_ASSERT(last.m_object != nullptr);
|
||||
|
||||
// make sure iterator fits the current value
|
||||
if (JSON_HEDLEY_UNLIKELY(first.m_object != last.m_object))
|
||||
|
@ -2237,7 +2238,8 @@ class basic_json
|
|||
@param[in] error_handler how to react on decoding errors; there are three
|
||||
possible values: `strict` (throws and exception in case a decoding error
|
||||
occurs; default), `replace` (replace invalid UTF-8 sequences with U+FFFD),
|
||||
and `ignore` (ignore invalid UTF-8 sequences during serialization).
|
||||
and `ignore` (ignore invalid UTF-8 sequences during serialization; all
|
||||
bytes are copied to the output unchanged).
|
||||
|
||||
@return string containing the serialization of the JSON value
|
||||
|
||||
|
@ -3018,6 +3020,18 @@ class basic_json
|
|||
return v;
|
||||
}
|
||||
|
||||
// specialization to allow to call get_to with a basic_json value
|
||||
// see https://github.com/nlohmann/json/issues/2175
|
||||
template<typename ValueType,
|
||||
detail::enable_if_t <
|
||||
detail::is_basic_json<ValueType>::value,
|
||||
int> = 0>
|
||||
ValueType & get_to(ValueType& v) const
|
||||
{
|
||||
v = *this;
|
||||
return v;
|
||||
}
|
||||
|
||||
template <
|
||||
typename T, std::size_t N,
|
||||
typename Array = T (&)[N],
|
||||
|
@ -3619,7 +3633,7 @@ class basic_json
|
|||
// const operator[] only works for objects
|
||||
if (JSON_HEDLEY_LIKELY(is_object()))
|
||||
{
|
||||
assert(m_value.object->find(key) != m_value.object->end());
|
||||
JSON_ASSERT(m_value.object->find(key) != m_value.object->end());
|
||||
return m_value.object->find(key)->second;
|
||||
}
|
||||
|
||||
|
@ -3711,7 +3725,7 @@ class basic_json
|
|||
// at only works for objects
|
||||
if (JSON_HEDLEY_LIKELY(is_object()))
|
||||
{
|
||||
assert(m_value.object->find(key) != m_value.object->end());
|
||||
JSON_ASSERT(m_value.object->find(key) != m_value.object->end());
|
||||
return m_value.object->find(key)->second;
|
||||
}
|
||||
|
||||
|
@ -5479,7 +5493,7 @@ class basic_json
|
|||
iterator insert_iterator(const_iterator pos, Args&& ... args)
|
||||
{
|
||||
iterator result(this);
|
||||
assert(m_value.array != nullptr);
|
||||
JSON_ASSERT(m_value.array != nullptr);
|
||||
|
||||
auto insert_pos = std::distance(m_value.array->begin(), pos.m_it.array_iterator);
|
||||
m_value.array->insert(pos.m_it.array_iterator, std::forward<Args>(args)...);
|
||||
|
@ -5866,6 +5880,34 @@ class basic_json
|
|||
/*!
|
||||
@brief exchanges the values
|
||||
|
||||
Exchanges the contents of the JSON value from @a left with those of @a right. Does not
|
||||
invoke any move, copy, or swap operations on individual elements. All
|
||||
iterators and references remain valid. The past-the-end iterator is
|
||||
invalidated. implemented as a friend function callable via ADL.
|
||||
|
||||
@param[in,out] left JSON value to exchange the contents with
|
||||
@param[in,out] right JSON value to exchange the contents with
|
||||
|
||||
@complexity Constant.
|
||||
|
||||
@liveexample{The example below shows how JSON values can be swapped with
|
||||
`swap()`.,swap__reference}
|
||||
|
||||
@since version 1.0.0
|
||||
*/
|
||||
friend void swap(reference left, reference right) noexcept (
|
||||
std::is_nothrow_move_constructible<value_t>::value and
|
||||
std::is_nothrow_move_assignable<value_t>::value and
|
||||
std::is_nothrow_move_constructible<json_value>::value and
|
||||
std::is_nothrow_move_assignable<json_value>::value
|
||||
)
|
||||
{
|
||||
left.swap(right);
|
||||
}
|
||||
|
||||
/*!
|
||||
@brief exchanges the values
|
||||
|
||||
Exchanges the contents of a JSON array with those of @a other. Does not
|
||||
invoke any move, copy, or swap operations on individual elements. All
|
||||
iterators and references remain valid. The past-the-end iterator is
|
||||
|
@ -6564,6 +6606,9 @@ class basic_json
|
|||
(optional)
|
||||
@param[in] allow_exceptions whether to throw exceptions in case of a
|
||||
parse error (optional, true by default)
|
||||
@param[in] ignore_comments whether comments should be ignored and treated
|
||||
like whitespace (true) or yield a parse error (true); (optional, false by
|
||||
default)
|
||||
|
||||
@return deserialized JSON value; in case of a parse error and
|
||||
@a allow_exceptions set to `false`, the return value will be
|
||||
|
@ -6592,16 +6637,18 @@ class basic_json
|
|||
@liveexample{The example below demonstrates the `parse()` function reading
|
||||
from a contiguous container.,parse__contiguouscontainer__parser_callback_t}
|
||||
|
||||
@since version 2.0.3 (contiguous containers)
|
||||
@since version 2.0.3 (contiguous containers); version 3.9.0 allowed to
|
||||
ignore comments.
|
||||
*/
|
||||
template<typename InputType>
|
||||
JSON_HEDLEY_WARN_UNUSED_RESULT
|
||||
static basic_json parse(InputType&& i,
|
||||
const parser_callback_t cb = nullptr,
|
||||
const bool allow_exceptions = true)
|
||||
const bool allow_exceptions = true,
|
||||
const bool ignore_comments = false)
|
||||
{
|
||||
basic_json result;
|
||||
parser(detail::input_adapter(std::forward<InputType>(i)), cb, allow_exceptions).parse(true, result);
|
||||
parser(detail::input_adapter(std::forward<InputType>(i)), cb, allow_exceptions, ignore_comments).parse(true, result);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -6618,6 +6665,9 @@ class basic_json
|
|||
(optional)
|
||||
@param[in] allow_exceptions whether to throw exceptions in case of a
|
||||
parse error (optional, true by default)
|
||||
@param[in] ignore_comments whether comments should be ignored and treated
|
||||
like whitespace (true) or yield a parse error (true); (optional, false by
|
||||
default)
|
||||
|
||||
@return deserialized JSON value; in case of a parse error and
|
||||
@a allow_exceptions set to `false`, the return value will be
|
||||
|
@ -6633,10 +6683,11 @@ class basic_json
|
|||
static basic_json parse(IteratorType first,
|
||||
IteratorType last,
|
||||
const parser_callback_t cb = nullptr,
|
||||
const bool allow_exceptions = true)
|
||||
const bool allow_exceptions = true,
|
||||
const bool ignore_comments = false)
|
||||
{
|
||||
basic_json result;
|
||||
parser(detail::input_adapter(std::move(first), std::move(last)), cb, allow_exceptions).parse(true, result);
|
||||
parser(detail::input_adapter(std::move(first), std::move(last)), cb, allow_exceptions, ignore_comments).parse(true, result);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -6644,10 +6695,11 @@ class basic_json
|
|||
JSON_HEDLEY_DEPRECATED_FOR(3.8.0, parse(ptr, ptr + len))
|
||||
static basic_json parse(detail::span_input_adapter&& i,
|
||||
const parser_callback_t cb = nullptr,
|
||||
const bool allow_exceptions = true)
|
||||
const bool allow_exceptions = true,
|
||||
const bool ignore_comments = false)
|
||||
{
|
||||
basic_json result;
|
||||
parser(i.get(), cb, allow_exceptions).parse(true, result);
|
||||
parser(i.get(), cb, allow_exceptions, ignore_comments).parse(true, result);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -6667,6 +6719,9 @@ class basic_json
|
|||
iterators.
|
||||
|
||||
@param[in] i input to read from
|
||||
@param[in] ignore_comments whether comments should be ignored and treated
|
||||
like whitespace (true) or yield a parse error (true); (optional, false by
|
||||
default)
|
||||
|
||||
@return Whether the input read from @a i is valid JSON.
|
||||
|
||||
|
@ -6679,22 +6734,25 @@ class basic_json
|
|||
from a string.,accept__string}
|
||||
*/
|
||||
template<typename InputType>
|
||||
static bool accept(InputType&& i)
|
||||
static bool accept(InputType&& i,
|
||||
const bool ignore_comments = false)
|
||||
{
|
||||
return parser(detail::input_adapter(std::forward<InputType>(i))).accept(true);
|
||||
return parser(detail::input_adapter(std::forward<InputType>(i)), nullptr, false, ignore_comments).accept(true);
|
||||
}
|
||||
|
||||
template<typename IteratorType>
|
||||
static bool accept(IteratorType first, IteratorType last)
|
||||
static bool accept(IteratorType first, IteratorType last,
|
||||
const bool ignore_comments = false)
|
||||
{
|
||||
return parser(detail::input_adapter(std::move(first), std::move(last))).accept(true);
|
||||
return parser(detail::input_adapter(std::move(first), std::move(last)), nullptr, false, ignore_comments).accept(true);
|
||||
}
|
||||
|
||||
JSON_HEDLEY_WARN_UNUSED_RESULT
|
||||
JSON_HEDLEY_DEPRECATED_FOR(3.8.0, accept(ptr, ptr + len))
|
||||
static bool accept(detail::span_input_adapter&& i)
|
||||
static bool accept(detail::span_input_adapter&& i,
|
||||
const bool ignore_comments = false)
|
||||
{
|
||||
return parser(i.get()).accept(true);
|
||||
return parser(i.get(), nullptr, false, ignore_comments).accept(true);
|
||||
}
|
||||
|
||||
/*!
|
||||
|
@ -6714,6 +6772,9 @@ class basic_json
|
|||
@param[in,out] sax SAX event listener
|
||||
@param[in] format the format to parse (JSON, CBOR, MessagePack, or UBJSON)
|
||||
@param[in] strict whether the input has to be consumed completely
|
||||
@param[in] ignore_comments whether comments should be ignored and treated
|
||||
like whitespace (true) or yield a parse error (true); (optional, false by
|
||||
default); only applies to the JSON file format.
|
||||
|
||||
@return return value of the last processed SAX event
|
||||
|
||||
|
@ -6738,11 +6799,12 @@ class basic_json
|
|||
JSON_HEDLEY_NON_NULL(2)
|
||||
static bool sax_parse(InputType&& i, SAX* sax,
|
||||
input_format_t format = input_format_t::json,
|
||||
const bool strict = true)
|
||||
const bool strict = true,
|
||||
const bool ignore_comments = false)
|
||||
{
|
||||
auto ia = detail::input_adapter(std::forward<InputType>(i));
|
||||
return format == input_format_t::json
|
||||
? parser(std::move(ia)).sax_parse(sax, strict)
|
||||
? parser(std::move(ia), nullptr, true, ignore_comments).sax_parse(sax, strict)
|
||||
: detail::binary_reader<basic_json, decltype(ia), SAX>(std::move(ia)).sax_parse(format, sax, strict);
|
||||
}
|
||||
|
||||
|
@ -6750,11 +6812,12 @@ class basic_json
|
|||
JSON_HEDLEY_NON_NULL(3)
|
||||
static bool sax_parse(IteratorType first, IteratorType last, SAX* sax,
|
||||
input_format_t format = input_format_t::json,
|
||||
const bool strict = true)
|
||||
const bool strict = true,
|
||||
const bool ignore_comments = false)
|
||||
{
|
||||
auto ia = detail::input_adapter(std::move(first), std::move(last));
|
||||
return format == input_format_t::json
|
||||
? parser(std::move(ia)).sax_parse(sax, strict)
|
||||
? parser(std::move(ia), nullptr, true, ignore_comments).sax_parse(sax, strict)
|
||||
: detail::binary_reader<basic_json, decltype(ia), SAX>(std::move(ia)).sax_parse(format, sax, strict);
|
||||
}
|
||||
|
||||
|
@ -6763,11 +6826,12 @@ class basic_json
|
|||
JSON_HEDLEY_NON_NULL(2)
|
||||
static bool sax_parse(detail::span_input_adapter&& i, SAX* sax,
|
||||
input_format_t format = input_format_t::json,
|
||||
const bool strict = true)
|
||||
const bool strict = true,
|
||||
const bool ignore_comments = false)
|
||||
{
|
||||
auto ia = i.get();
|
||||
return format == input_format_t::json
|
||||
? parser(std::move(ia)).sax_parse(sax, strict)
|
||||
? parser(std::move(ia), nullptr, true, ignore_comments).sax_parse(sax, strict)
|
||||
: detail::binary_reader<basic_json, decltype(ia), SAX>(std::move(ia)).sax_parse(format, sax, strict);
|
||||
}
|
||||
|
||||
|
@ -7041,7 +7105,8 @@ class basic_json
|
|||
number_unsigned | 256..65535 | uint 16 | 0xCD
|
||||
number_unsigned | 65536..4294967295 | uint 32 | 0xCE
|
||||
number_unsigned | 4294967296..18446744073709551615 | uint 64 | 0xCF
|
||||
number_float | *any value* | float 64 | 0xCB
|
||||
number_float | *any value representable by a float* | float 32 | 0xCA
|
||||
number_float | *any value NOT representable by a float* | float 64 | 0xCB
|
||||
string | *length*: 0..31 | fixstr | 0xA0..0xBF
|
||||
string | *length*: 32..255 | str 8 | 0xD9
|
||||
string | *length*: 256..65535 | str 16 | 0xDA
|
||||
|
@ -7065,9 +7130,6 @@ class basic_json
|
|||
- arrays with more than 4294967295 elements
|
||||
- objects with more than 4294967295 elements
|
||||
|
||||
@note The following MessagePack types are not used in the conversion:
|
||||
- float 32 (0xCA)
|
||||
|
||||
@note Any MessagePack output created @ref to_msgpack can be successfully
|
||||
parsed by @ref from_msgpack.
|
||||
|
||||
|
@ -8182,7 +8244,7 @@ class basic_json
|
|||
else
|
||||
{
|
||||
const auto idx = json_pointer::array_index(last_path);
|
||||
if (JSON_HEDLEY_UNLIKELY(static_cast<size_type>(idx) > parent.size()))
|
||||
if (JSON_HEDLEY_UNLIKELY(idx > parent.size()))
|
||||
{
|
||||
// avoid undefined behavior
|
||||
JSON_THROW(out_of_range::create(401, "array index " + std::to_string(idx) + " is out of range"));
|
||||
|
@ -8196,7 +8258,7 @@ class basic_json
|
|||
|
||||
// if there exists a parent it cannot be primitive
|
||||
default: // LCOV_EXCL_LINE
|
||||
assert(false); // LCOV_EXCL_LINE
|
||||
JSON_ASSERT(false); // LCOV_EXCL_LINE
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -8225,7 +8287,7 @@ class basic_json
|
|||
else if (parent.is_array())
|
||||
{
|
||||
// note erase performs range check
|
||||
parent.erase(static_cast<size_type>(json_pointer::array_index(last_path)));
|
||||
parent.erase(json_pointer::array_index(last_path));
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -8660,6 +8722,9 @@ struct less<::nlohmann::detail::value_t>
|
|||
}
|
||||
};
|
||||
|
||||
// C++20 prohibit function specialization in the std namespace.
|
||||
#ifndef JSON_HAS_CPP_20
|
||||
|
||||
/*!
|
||||
@brief exchanges the values of two JSON objects
|
||||
|
||||
|
@ -8674,6 +8739,8 @@ inline void swap<nlohmann::json>(nlohmann::json& j1, nlohmann::json& j2) noexcep
|
|||
j1.swap(j2);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
} // namespace std
|
||||
|
||||
/*!
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue