mirror of
https://github.com/nlohmann/json.git
synced 2026-07-24 03:14:55 +00:00
* Add iterator+sentinel tests and docs for binary deserializers This commit extends the C++20 ranges support (iterator+sentinel pairs) to the binary format deserializers from_cbor, from_msgpack, from_ubjson, from_bjdata, and from_bson, matching what was already done for parse(), accept(), and sax_parse(). Changes: - Add istreambuf_sentinel helper to test_utils.hpp for EOF detection in tests - Add 5 new test cases that read binary files directly via std::istreambuf_iterator<char> + sentinel, without pre-buffering - Update documentation for all 5 from_* functions to document overload (3) with SentinelType parameter - All tests pass; verified against existing test suite data - Fix potential buffer over-read warning in heterogeneous iterator test Signed-off-by: Niels Lohmann <mail@nlohmann.me> * Merge iterator+sentinel overloads and fix ambiguity/CI issues Address PR review feedback and CI failures: - Merge the separate same-type and sentinel-type iterator overloads of parse(), accept(), sax_parse(), and the five from_* binary deserializers into a single overload with SentinelType defaulted to IteratorType, as suggested in review. Applied the same simplification to the detail::input_adapter() free functions. - Fix a latent ambiguity: some compilers (e.g. GCC 4.8) unreliably SFINAE the operator!= detection for std::nullptr_t against container/string types, making calls like parse(s, nullptr, ...) ambiguous with the compatible-input overload. can_compare_ne now explicitly excludes std::nullptr_t as a SentinelType. - Use a named enable_if_t template parameter instead of an unnamed function parameter for the SFINAE guard, fixing a clang-tidy hicpp-named-parameter/readability-named-parameter failure. - Update parse.md, accept.md, sax_parse.md, and the five from_*.md pages to document the merged overload instead of separate (2)/(3) overloads, also fixing an over-160-char line that broke the documentation style_check CI job. - Rework the BSON iterator+sentinel test to parse a BSON file already present in the test suite instead of writing/deleting a temp file. Signed-off-by: Niels Lohmann <mail@nlohmann.me> * Fix -Wunneeded-internal-declaration for CustomSentinel in test CustomSentinel lives in an anonymous namespace (internal linkage), and the library's parse loop only ever evaluates the iterator-first direction (it != last), so the reversed-order friend operator!= was never referenced. Clang's -Weverything flags such unused internal declarations as an error. Drop the unused overload; the used direction is enough to satisfy can_compare_ne's either-order detection. Signed-off-by: Niels Lohmann <mail@nlohmann.me> * Fix clang-tidy hicpp-named-parameter and misc-const-correctness - Drop the unused reversed-order operator!= overload from utils::istreambuf_sentinel (only iterator != sentinel is ever evaluated) and name the remaining friend's sentinel parameter, fixing hicpp-named-parameter/readability-named-parameter. - Mark the istreambuf_iterator first/last helper variable const in the five binary-format sentinel tests, fixing misc-const-correctness. Signed-off-by: Niels Lohmann <mail@nlohmann.me> * Fix clang-tidy misc-const-correctness in heterogeneous sentinel test json_str is only read via .data()/.size() and never reassigned, so clang-tidy correctly flags it as const-able. Verified against the exact CI job (silkeh/clang:dev, ci_clang_tidy target) by running clang-tidy directly on this file plus the five binary-format sentinel tests touched by prior commits; all are now clean. Signed-off-by: Niels Lohmann <mail@nlohmann.me> --------- Signed-off-by: Niels Lohmann <mail@nlohmann.me>
47 lines
1.5 KiB
C++
47 lines
1.5 KiB
C++
// __ _____ _____ _____
|
|
// __| | __| | | | JSON for Modern C++ (supporting code)
|
|
// | | |__ | | | | | | version 3.12.0
|
|
// |_____|_____|_____|_|___| https://github.com/nlohmann/json
|
|
//
|
|
// SPDX-FileCopyrightText: 2013-2026 Niels Lohmann <https://nlohmann.me>
|
|
// SPDX-License-Identifier: MIT
|
|
|
|
#pragma once
|
|
|
|
#include <cstdint> // uint8_t
|
|
#include <fstream> // ifstream, istreambuf_iterator, ios
|
|
#include <vector> // vector
|
|
|
|
namespace utils
|
|
{
|
|
|
|
inline std::vector<std::uint8_t> read_binary_file(const std::string& filename)
|
|
{
|
|
std::ifstream file(filename, std::ios::binary);
|
|
file.unsetf(std::ios::skipws);
|
|
|
|
file.seekg(0, std::ios::end);
|
|
const auto size = file.tellg();
|
|
file.seekg(0, std::ios::beg);
|
|
|
|
std::vector<std::uint8_t> byte_vector;
|
|
byte_vector.reserve(static_cast<std::size_t>(size));
|
|
byte_vector.insert(byte_vector.begin(), std::istream_iterator<std::uint8_t>(file), std::istream_iterator<std::uint8_t>());
|
|
return byte_vector;
|
|
}
|
|
|
|
// sentinel for istreambuf_iterator; compares != true until EOF is reached
|
|
// lets tests read a file directly via the new iterator+sentinel overloads
|
|
// instead of buffering the whole file into a vector first.
|
|
// Only the iterator-first direction (it != sentinel) is ever evaluated by
|
|
// the library's parse loop, so no reversed-order overload is needed.
|
|
struct istreambuf_sentinel
|
|
{
|
|
friend bool operator!=(const std::istreambuf_iterator<char>& it, const istreambuf_sentinel& /*unused*/) noexcept
|
|
{
|
|
return it != std::istreambuf_iterator<char>();
|
|
}
|
|
};
|
|
|
|
} // namespace utils
|