mirror of
https://github.com/nlohmann/json.git
synced 2026-10-08 15:37:13 +00:00
Merge branch 'json-view/21-images' into json-view/22-view-dump-fast
Signed-off-by: Niels Lohmann <mail@nlohmann.me>
This commit is contained in:
4 files changed
+27
-14
No files matched your search
@@ -13,7 +13,7 @@
|
||||
#include <intrin0.h> // __umulh, _umul128
|
||||
#endif
|
||||
|
||||
#include <nlohmann/detail/abi_macros.hpp>
|
||||
#include <nlohmann/detail/macro_scope.hpp> // JSON_HEDLEY_ALWAYS_INLINE, NLOHMANN_JSON_NAMESPACE_BEGIN
|
||||
|
||||
// Portable bit-level helpers for the number and string scanners. They use
|
||||
// compiler builtins or platform-specific intrinsics where available and plain
|
||||
|
||||
@@ -1258,7 +1258,7 @@ inline char* write_decimal(char* first, std::uint64_t digits, int exp) noexcept
|
||||
first[1] = '.';
|
||||
char* const end = first + (k == 1 ? 1 : k + 1);
|
||||
const int e = n - 1;
|
||||
const auto ea = static_cast<unsigned>(e < 0 ? -e : e);
|
||||
const auto ea = e < 0 ? 0u - static_cast<unsigned>(e) : static_cast<unsigned>(e); // (unsigned: no signed overflow to assume)
|
||||
const bool three = ea >= 100;
|
||||
end[0] = 'e';
|
||||
end[1] = e < 0 ? '-' : '+';
|
||||
@@ -1298,7 +1298,7 @@ inline char* write_shortest(char* first, const zmij::shortest_decimal d) noexcep
|
||||
// NOLINTBEGIN(portability-simd-intrinsics)
|
||||
// the two halves in the 64-bit lanes, each as abcd * 2^32 + efgh, then as
|
||||
// bytes (as eight_digit_bytes(), one lane each)
|
||||
const __m128i x = _mm_set_epi64x(static_cast<long long>(sig - (upper * 100000000u)), static_cast<long long>(upper));
|
||||
const __m128i x = _mm_set_epi64x(static_cast<long long>(sig - (upper * 100000000u)), static_cast<long long>(upper)); // NOLINT(runtime/int)
|
||||
const __m128i abcd = _mm_srli_epi64(_mm_mul_epu32(x, _mm_set1_epi64x(109951163)), 40); // 2^40 / 10000 + 1
|
||||
const __m128i abcd_efgh = _mm_add_epi64(x, _mm_mul_epu32(abcd, _mm_set1_epi64x(4294957296))); // 2^32 - 10000
|
||||
// 32-bit lanes in the order of the text: abcd, efgh of both halves
|
||||
@@ -1413,7 +1413,7 @@ inline char* write_shortest(char* first, const zmij::shortest_decimal d) noexcep
|
||||
first[1] = '.';
|
||||
char* const end = first + (len == 1 ? 1 : len + 1);
|
||||
const int e = n - 1;
|
||||
const auto ea = static_cast<unsigned>(e < 0 ? -e : e);
|
||||
const auto ea = e < 0 ? 0u - static_cast<unsigned>(e) : static_cast<unsigned>(e); // (unsigned: no signed overflow to assume)
|
||||
const bool three = ea >= 100;
|
||||
end[0] = 'e';
|
||||
end[1] = e < 0 ? '-' : '+';
|
||||
@@ -1472,6 +1472,7 @@ JSON_HEDLEY_RETURNS_NON_NULL
|
||||
char* write_positive(char* first, const char* last, FloatType value)
|
||||
{
|
||||
JSON_ASSERT(last - first >= std::numeric_limits<FloatType>::max_digits10);
|
||||
static_cast<void>(last); // (only used in the assertion)
|
||||
|
||||
// Compute v = buffer * 10^decimal_exponent.
|
||||
// The decimal digits are stored in the buffer, which needs to be interpreted
|
||||
@@ -1513,7 +1514,7 @@ inline char* write_positive(char* first, const char* last, double value)
|
||||
}
|
||||
std::array<char, 64> buf; // NOLINT(cppcoreguidelines-pro-type-member-init,hicpp-member-init): written before read
|
||||
const auto len = static_cast<std::size_t>(write_shortest(buf.data(), d) - buf.data());
|
||||
JSON_ASSERT(static_cast<std::size_t>(last - first) >= len);
|
||||
JSON_ASSERT(last - first >= static_cast<std::ptrdiff_t>(len));
|
||||
std::memcpy(first, buf.data(), len);
|
||||
return first + len;
|
||||
}
|
||||
|
||||
@@ -8867,8 +8867,8 @@ NLOHMANN_JSON_NAMESPACE_END
|
||||
#include <intrin0.h> // __umulh, _umul128
|
||||
#endif
|
||||
|
||||
// #include <nlohmann/detail/abi_macros.hpp>
|
||||
|
||||
// #include <nlohmann/detail/macro_scope.hpp>
|
||||
// JSON_HEDLEY_ALWAYS_INLINE, NLOHMANN_JSON_NAMESPACE_BEGIN
|
||||
|
||||
// Portable bit-level helpers for the number and string scanners. They use
|
||||
// compiler builtins or platform-specific intrinsics where available and plain
|
||||
@@ -26670,7 +26670,7 @@ inline char* write_decimal(char* first, std::uint64_t digits, int exp) noexcept
|
||||
first[1] = '.';
|
||||
char* const end = first + (k == 1 ? 1 : k + 1);
|
||||
const int e = n - 1;
|
||||
const auto ea = static_cast<unsigned>(e < 0 ? -e : e);
|
||||
const auto ea = e < 0 ? 0u - static_cast<unsigned>(e) : static_cast<unsigned>(e); // (unsigned: no signed overflow to assume)
|
||||
const bool three = ea >= 100;
|
||||
end[0] = 'e';
|
||||
end[1] = e < 0 ? '-' : '+';
|
||||
@@ -26710,7 +26710,7 @@ inline char* write_shortest(char* first, const zmij::shortest_decimal d) noexcep
|
||||
// NOLINTBEGIN(portability-simd-intrinsics)
|
||||
// the two halves in the 64-bit lanes, each as abcd * 2^32 + efgh, then as
|
||||
// bytes (as eight_digit_bytes(), one lane each)
|
||||
const __m128i x = _mm_set_epi64x(static_cast<long long>(sig - (upper * 100000000u)), static_cast<long long>(upper));
|
||||
const __m128i x = _mm_set_epi64x(static_cast<long long>(sig - (upper * 100000000u)), static_cast<long long>(upper)); // NOLINT(runtime/int)
|
||||
const __m128i abcd = _mm_srli_epi64(_mm_mul_epu32(x, _mm_set1_epi64x(109951163)), 40); // 2^40 / 10000 + 1
|
||||
const __m128i abcd_efgh = _mm_add_epi64(x, _mm_mul_epu32(abcd, _mm_set1_epi64x(4294957296))); // 2^32 - 10000
|
||||
// 32-bit lanes in the order of the text: abcd, efgh of both halves
|
||||
@@ -26825,7 +26825,7 @@ inline char* write_shortest(char* first, const zmij::shortest_decimal d) noexcep
|
||||
first[1] = '.';
|
||||
char* const end = first + (len == 1 ? 1 : len + 1);
|
||||
const int e = n - 1;
|
||||
const auto ea = static_cast<unsigned>(e < 0 ? -e : e);
|
||||
const auto ea = e < 0 ? 0u - static_cast<unsigned>(e) : static_cast<unsigned>(e); // (unsigned: no signed overflow to assume)
|
||||
const bool three = ea >= 100;
|
||||
end[0] = 'e';
|
||||
end[1] = e < 0 ? '-' : '+';
|
||||
@@ -26884,6 +26884,7 @@ JSON_HEDLEY_RETURNS_NON_NULL
|
||||
char* write_positive(char* first, const char* last, FloatType value)
|
||||
{
|
||||
JSON_ASSERT(last - first >= std::numeric_limits<FloatType>::max_digits10);
|
||||
static_cast<void>(last); // (only used in the assertion)
|
||||
|
||||
// Compute v = buffer * 10^decimal_exponent.
|
||||
// The decimal digits are stored in the buffer, which needs to be interpreted
|
||||
@@ -26925,7 +26926,7 @@ inline char* write_positive(char* first, const char* last, double value)
|
||||
}
|
||||
std::array<char, 64> buf; // NOLINT(cppcoreguidelines-pro-type-member-init,hicpp-member-init): written before read
|
||||
const auto len = static_cast<std::size_t>(write_shortest(buf.data(), d) - buf.data());
|
||||
JSON_ASSERT(static_cast<std::size_t>(last - first) >= len);
|
||||
JSON_ASSERT(last - first >= static_cast<std::ptrdiff_t>(len));
|
||||
std::memcpy(first, buf.data(), len);
|
||||
return first + len;
|
||||
}
|
||||
|
||||
@@ -639,12 +639,22 @@ std::pair<std::string, int> digits_and_exponent(const std::string& s)
|
||||
return {digits, e};
|
||||
}
|
||||
|
||||
/// the correctly rounded double of a decimal text
|
||||
/// (not std::strtod: the C runtimes of some platforms, e.g. MinGW's, round
|
||||
/// some 16 and 17 digit inputs wrongly)
|
||||
double parse_double(const std::string& text)
|
||||
{
|
||||
const nlohmann::json j = nlohmann::json::parse(text, nullptr, false);
|
||||
// (a discarded value: out of range, as strtod's HUGE_VAL)
|
||||
return j.is_discarded() ? std::numeric_limits<double>::infinity() : j.get<double>();
|
||||
}
|
||||
|
||||
/// whether the decimal digits * 10^e reads back as v
|
||||
bool reads_back(const std::string& digits, int e, double v)
|
||||
{
|
||||
const std::string text = digits + "e" + std::to_string(e);
|
||||
// (compared bit for bit: v is positive and finite, and -Wfloat-equal)
|
||||
return reinterpret_bits<std::uint64_t>(std::strtod(text.c_str(), nullptr)) == reinterpret_bits<std::uint64_t>(v);
|
||||
return reinterpret_bits<std::uint64_t>(parse_double(text)) == reinterpret_bits<std::uint64_t>(v);
|
||||
}
|
||||
|
||||
/// Check the representation of a positive finite double: it reads back as
|
||||
@@ -655,7 +665,7 @@ void check_shortest(double v)
|
||||
char* end = nlohmann::detail::to_chars(buf.data(), buf.data() + 32, v);
|
||||
const std::string text(buf.data(), end);
|
||||
CAPTURE(text)
|
||||
CHECK(std::strtod(text.c_str(), nullptr) == v);
|
||||
CHECK(parse_double(text) == v);
|
||||
// the layout is that of format_buffer() for the same digits
|
||||
std::array<char, 64> reference{};
|
||||
int len = 0;
|
||||
@@ -691,7 +701,8 @@ void check_shortest(double v)
|
||||
CHECK(!reads_back(std::to_string(candidate), e, v));
|
||||
}
|
||||
}
|
||||
#if defined(JSON_HAS_CPP_17) && defined(__cpp_lib_to_chars)
|
||||
// (icpc with libstdc++ 11 defines __cpp_lib_to_chars, but has no floating-point std::to_chars)
|
||||
#if defined(JSON_HAS_CPP_17) && defined(__cpp_lib_to_chars) && !defined(__INTEL_COMPILER)
|
||||
// the closest of the shortest representations, as std::to_chars finds it
|
||||
std::array<char, 64> std_text{};
|
||||
const auto r = std::to_chars(std_text.data(), std_text.data() + std_text.size(), v, std::chars_format::scientific);
|
||||
|
||||
Reference in new issue
Block a user