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>
This commit is contained in:
Niels Lohmann
2026-07-10 19:50:04 +02:00
parent 6ba332c7df
commit 2269656bc6
18 changed files with 612 additions and 44 deletions
+36
View File
@@ -168,4 +168,40 @@ TEST_CASE("Custom iterator")
CHECK(as_json.at(3) == 4);
}
// Custom sentinel type for testing heterogeneous iterator+sentinel support
struct CustomSentinel
{
const char* end_ptr;
// Support both directions for != comparison
friend bool operator!=(const char* it, const CustomSentinel& sentinel)
{
return it != sentinel.end_ptr;
}
friend bool operator!=(const CustomSentinel& sentinel, const char* it)
{
return it != sentinel.end_ptr;
}
};
TEST_CASE("Parse with heterogeneous iterator and sentinel types")
{
std::string json_str = R"({"key":"value"})";
const char* end_ptr = json_str.data() + json_str.size();
// Parse using pointer and sentinel (different types)
json j = json::parse(json_str.data(), CustomSentinel{end_ptr});
CHECK(j["key"] == "value");
// Accept using pointer and sentinel
CHECK(json::accept(json_str.data(), CustomSentinel{end_ptr}));
// Test that the same-type case still works
std::string raw_data = R"([1,2,3])";
std::list<char> data(raw_data.begin(), raw_data.end());
json j2 = json::parse(data.begin(), data.end());
CHECK(j2.at(0) == 1);
}
} // namespace