diff --git a/docs/mkdocs/docs/api/basic_json/accept.md b/docs/mkdocs/docs/api/basic_json/accept.md index 77100a045..dac5f9f36 100644 --- a/docs/mkdocs/docs/api/basic_json/accept.md +++ b/docs/mkdocs/docs/api/basic_json/accept.md @@ -8,13 +8,7 @@ static bool accept(InputType&& i, const bool ignore_trailing_commas = false); // (2) -template -static bool accept(IteratorType first, IteratorType last, - const bool ignore_comments = false, - const bool ignore_trailing_commas = false); - -// (3) -template +template static bool accept(IteratorType first, SentinelType last, const bool ignore_comments = false, const bool ignore_trailing_commas = false); @@ -23,14 +17,11 @@ static bool accept(IteratorType first, SentinelType last, Checks whether the input is valid JSON. 1. Reads from a compatible input. -2. Reads from a pair of character iterators (same type) +2. Reads from a pair of character iterators, or an iterator and a sentinel of a different type (C++20 ranges support) The value_type of the iterator must be an integral type with a size of 1, 2, or 4 bytes, which will be interpreted - respectively as UTF-8, UTF-16, and UTF-32. -3. Reads from an iterator and a sentinel (different types, C++20 ranges support) - - The value_type of the iterator must be an integral type with a size of 1, 2, or 4 bytes, which will be interpreted - respectively as UTF-8, UTF-16, and UTF-32. The sentinel type must be comparable to the iterator type with `operator!=`. + respectively as UTF-8, UTF-16, and UTF-32. If `SentinelType` differs from `IteratorType`, it must be comparable to + the iterator type with `operator!=`. Unlike the [`parse()`](parse.md) function, this function neither throws an exception in case of invalid JSON input (i.e., a parse error) nor creates diagnostic information. @@ -55,7 +46,7 @@ Unlike the [`parse()`](parse.md) function, this function neither throws an excep - a pair of pointers such as `ptr` and `ptr + len` `SentinelType` -: a sentinel type compatible with `IteratorType` (different from `IteratorType` and comparable via `operator!=`), for instance. +: defaults to `IteratorType`; may be a different type comparable to `IteratorType` via `operator!=`, for instance. - a custom sentinel type for C++20 ranges - `std::counted_iterator` with a different sentinel type @@ -128,7 +119,7 @@ A UTF-8 byte order mark is silently ignored. - Changed [runtime assertion](../../features/assertions.md) in case of `FILE*` null pointers to exception in version 3.12.0. - Added `ignore_trailing_commas` in version 3.13.0. - Extended container support (1) to include types with lvalue-only ADL `begin`/`end` (matching `std::begin`/`std::end` semantics) in version 3.13.0. -- Added overload (3) for heterogeneous iterator+sentinel pairs (C++20 ranges support) in version 3.13.0. +- Extended overload (2) to accept heterogeneous iterator+sentinel pairs (C++20 ranges support) in version 3.13.0. !!! warning "Deprecation" diff --git a/docs/mkdocs/docs/api/basic_json/from_bjdata.md b/docs/mkdocs/docs/api/basic_json/from_bjdata.md index 9c6768ef3..150f17aac 100644 --- a/docs/mkdocs/docs/api/basic_json/from_bjdata.md +++ b/docs/mkdocs/docs/api/basic_json/from_bjdata.md @@ -7,13 +7,7 @@ static basic_json from_bjdata(InputType&& i, const bool strict = true, const bool allow_exceptions = true); // (2) -template -static basic_json from_bjdata(IteratorType first, IteratorType last, - const bool strict = true, - const bool allow_exceptions = true); - -// (3) -template +template static basic_json from_bjdata(IteratorType first, SentinelType last, const bool strict = true, const bool allow_exceptions = true); @@ -22,8 +16,7 @@ static basic_json from_bjdata(IteratorType first, SentinelType last, Deserializes a given input to a JSON value using the BJData (Binary JData) serialization format. 1. Reads from a compatible input. -2. Reads from an iterator range. -3. Reads from an iterator and a sentinel (different types, C++20 ranges support). +2. Reads from an iterator range, or an iterator and a sentinel of a different type (C++20 ranges support). The exact mapping and its limitations are described on a [dedicated page](../../features/binary_formats/bjdata.md). @@ -43,7 +36,8 @@ The exact mapping and its limitations are described on a [dedicated page](../../ : a compatible iterator type `SentinelType` -: a sentinel type compatible with `IteratorType` (different from `IteratorType` and comparable via `operator!=`), for instance a custom sentinel type for C++20 ranges +: defaults to `IteratorType`; may be a different type comparable to `IteratorType` via `operator!=`, for instance a + custom sentinel type for C++20 ranges ## Parameters @@ -113,4 +107,4 @@ Linear in the size of the input. - Added in version 3.11.0. - Extended container support (1) to include types with lvalue-only ADL `begin`/`end` (matching `std::begin`/`std::end` semantics) in version 3.13.0. -- Added overload (3) for heterogeneous iterator+sentinel pairs (C++20 ranges support) in version 3.13.0. +- Extended overload (2) to accept heterogeneous iterator+sentinel pairs (C++20 ranges support) in version 3.13.0. diff --git a/docs/mkdocs/docs/api/basic_json/from_bson.md b/docs/mkdocs/docs/api/basic_json/from_bson.md index 5d9967c42..eb06a7177 100644 --- a/docs/mkdocs/docs/api/basic_json/from_bson.md +++ b/docs/mkdocs/docs/api/basic_json/from_bson.md @@ -7,13 +7,7 @@ static basic_json from_bson(InputType&& i, const bool strict = true, const bool allow_exceptions = true); // (2) -template -static basic_json from_bson(IteratorType first, IteratorType last, - const bool strict = true, - const bool allow_exceptions = true); - -// (3) -template +template static basic_json from_bson(IteratorType first, SentinelType last, const bool strict = true, const bool allow_exceptions = true); @@ -22,8 +16,7 @@ static basic_json from_bson(IteratorType first, SentinelType last, Deserializes a given input to a JSON value using the BSON (Binary JSON) serialization format. 1. Reads from a compatible input. -2. Reads from an iterator range. -3. Reads from an iterator and a sentinel (different types, C++20 ranges support). +2. Reads from an iterator range, or an iterator and a sentinel of a different type (C++20 ranges support). The exact mapping and its limitations are described on a [dedicated page](../../features/binary_formats/bson.md). @@ -43,7 +36,8 @@ The exact mapping and its limitations are described on a [dedicated page](../../ : a compatible iterator type `SentinelType` -: a sentinel type compatible with `IteratorType` (different from `IteratorType` and comparable via `operator!=`), for instance a custom sentinel type for C++20 ranges +: defaults to `IteratorType`; may be a different type comparable to `IteratorType` via `operator!=`, for instance a + custom sentinel type for C++20 ranges ## Parameters @@ -113,7 +107,7 @@ Linear in the size of the input. - Added in version 3.4.0. - Extended container support (1) to include types with lvalue-only ADL `begin`/`end` (matching `std::begin`/`std::end` semantics) in version 3.13.0. -- Added overload (3) for heterogeneous iterator+sentinel pairs (C++20 ranges support) in version 3.13.0. +- Extended overload (2) to accept heterogeneous iterator+sentinel pairs (C++20 ranges support) in version 3.13.0. !!! warning "Deprecation" diff --git a/docs/mkdocs/docs/api/basic_json/from_cbor.md b/docs/mkdocs/docs/api/basic_json/from_cbor.md index c9a326c96..3792307bd 100644 --- a/docs/mkdocs/docs/api/basic_json/from_cbor.md +++ b/docs/mkdocs/docs/api/basic_json/from_cbor.md @@ -9,14 +9,7 @@ static basic_json from_cbor(InputType&& i, const cbor_tag_handler_t tag_handler = cbor_tag_handler_t::error); // (2) -template -static basic_json from_cbor(IteratorType first, IteratorType last, - const bool strict = true, - const bool allow_exceptions = true, - const cbor_tag_handler_t tag_handler = cbor_tag_handler_t::error); - -// (3) -template +template static basic_json from_cbor(IteratorType first, SentinelType last, const bool strict = true, const bool allow_exceptions = true, @@ -26,8 +19,7 @@ static basic_json from_cbor(IteratorType first, SentinelType last, Deserializes a given input to a JSON value using the CBOR (Concise Binary Object Representation) serialization format. 1. Reads from a compatible input. -2. Reads from an iterator range. -3. Reads from an iterator and a sentinel (different types, C++20 ranges support). +2. Reads from an iterator range, or an iterator and a sentinel of a different type (C++20 ranges support). The exact mapping and its limitations are described on a [dedicated page](../../features/binary_formats/cbor.md). @@ -47,7 +39,8 @@ The exact mapping and its limitations are described on a [dedicated page](../../ : a compatible iterator type `SentinelType` -: a sentinel type compatible with `IteratorType` (different from `IteratorType` and comparable via `operator!=`), for instance a custom sentinel type for C++20 ranges +: defaults to `IteratorType`; may be a different type comparable to `IteratorType` via `operator!=`, for instance a + custom sentinel type for C++20 ranges ## Parameters @@ -124,7 +117,7 @@ Linear in the size of the input. - Added `allow_exceptions` parameter in version 3.2.0. - Added `tag_handler` parameter in version 3.9.0. - Extended container support (1) to include types with lvalue-only ADL `begin`/`end` (matching `std::begin`/`std::end` semantics) in version 3.13.0. -- Added overload (3) for heterogeneous iterator+sentinel pairs (C++20 ranges support) in version 3.13.0. +- Extended overload (2) to accept heterogeneous iterator+sentinel pairs (C++20 ranges support) in version 3.13.0. !!! warning "Deprecation" diff --git a/docs/mkdocs/docs/api/basic_json/from_msgpack.md b/docs/mkdocs/docs/api/basic_json/from_msgpack.md index 21876af72..dd7719804 100644 --- a/docs/mkdocs/docs/api/basic_json/from_msgpack.md +++ b/docs/mkdocs/docs/api/basic_json/from_msgpack.md @@ -7,13 +7,7 @@ static basic_json from_msgpack(InputType&& i, const bool strict = true, const bool allow_exceptions = true); // (2) -template -static basic_json from_msgpack(IteratorType first, IteratorType last, - const bool strict = true, - const bool allow_exceptions = true); - -// (3) -template +template static basic_json from_msgpack(IteratorType first, SentinelType last, const bool strict = true, const bool allow_exceptions = true); @@ -22,8 +16,7 @@ static basic_json from_msgpack(IteratorType first, SentinelType last, Deserializes a given input to a JSON value using the MessagePack serialization format. 1. Reads from a compatible input. -2. Reads from an iterator range. -3. Reads from an iterator and a sentinel (different types, C++20 ranges support). +2. Reads from an iterator range, or an iterator and a sentinel of a different type (C++20 ranges support). The exact mapping and its limitations are described on a [dedicated page](../../features/binary_formats/messagepack.md). @@ -43,7 +36,8 @@ The exact mapping and its limitations are described on a [dedicated page](../../ : a compatible iterator type `SentinelType` -: a sentinel type compatible with `IteratorType` (different from `IteratorType` and comparable via `operator!=`), for instance a custom sentinel type for C++20 ranges +: defaults to `IteratorType`; may be a different type comparable to `IteratorType` via `operator!=`, for instance a + custom sentinel type for C++20 ranges ## Parameters @@ -115,7 +109,7 @@ Linear in the size of the input. - Changed to consume input adapters, removed `start_index` parameter, and added `strict` parameter in version 3.0.0. - Added `allow_exceptions` parameter in version 3.2.0. - Extended container support (1) to include types with lvalue-only ADL `begin`/`end` (matching `std::begin`/`std::end` semantics) in version 3.13.0. -- Added overload (3) for heterogeneous iterator+sentinel pairs (C++20 ranges support) in version 3.13.0. +- Extended overload (2) to accept heterogeneous iterator+sentinel pairs (C++20 ranges support) in version 3.13.0. !!! warning "Deprecation" diff --git a/docs/mkdocs/docs/api/basic_json/from_ubjson.md b/docs/mkdocs/docs/api/basic_json/from_ubjson.md index 8a2d814ba..55c68c0ae 100644 --- a/docs/mkdocs/docs/api/basic_json/from_ubjson.md +++ b/docs/mkdocs/docs/api/basic_json/from_ubjson.md @@ -7,13 +7,7 @@ static basic_json from_ubjson(InputType&& i, const bool strict = true, const bool allow_exceptions = true); // (2) -template -static basic_json from_ubjson(IteratorType first, IteratorType last, - const bool strict = true, - const bool allow_exceptions = true); - -// (3) -template +template static basic_json from_ubjson(IteratorType first, SentinelType last, const bool strict = true, const bool allow_exceptions = true); @@ -22,8 +16,7 @@ static basic_json from_ubjson(IteratorType first, SentinelType last, Deserializes a given input to a JSON value using the UBJSON (Universal Binary JSON) serialization format. 1. Reads from a compatible input. -2. Reads from an iterator range. -3. Reads from an iterator and a sentinel (different types, C++20 ranges support). +2. Reads from an iterator range, or an iterator and a sentinel of a different type (C++20 ranges support). The exact mapping and its limitations are described on a [dedicated page](../../features/binary_formats/ubjson.md). @@ -43,7 +36,8 @@ The exact mapping and its limitations are described on a [dedicated page](../../ : a compatible iterator type `SentinelType` -: a sentinel type compatible with `IteratorType` (different from `IteratorType` and comparable via `operator!=`), for instance a custom sentinel type for C++20 ranges +: defaults to `IteratorType`; may be a different type comparable to `IteratorType` via `operator!=`, for instance a + custom sentinel type for C++20 ranges ## Parameters @@ -114,7 +108,7 @@ Linear in the size of the input. - Added in version 3.1.0. - Added `allow_exceptions` parameter in version 3.2.0. - Extended container support (1) to include types with lvalue-only ADL `begin`/`end` (matching `std::begin`/`std::end` semantics) in version 3.13.0. -- Added overload (3) for heterogeneous iterator+sentinel pairs (C++20 ranges support) in version 3.13.0. +- Extended overload (2) to accept heterogeneous iterator+sentinel pairs (C++20 ranges support) in version 3.13.0. !!! warning "Deprecation" diff --git a/docs/mkdocs/docs/api/basic_json/parse.md b/docs/mkdocs/docs/api/basic_json/parse.md index 3af405cb1..4565c8762 100644 --- a/docs/mkdocs/docs/api/basic_json/parse.md +++ b/docs/mkdocs/docs/api/basic_json/parse.md @@ -10,15 +10,7 @@ static basic_json parse(InputType&& i, const bool ignore_trailing_commas = false); // (2) -template -static basic_json parse(IteratorType first, IteratorType last, - const parser_callback_t cb = nullptr, - const bool allow_exceptions = true, - const bool ignore_comments = false, - const bool ignore_trailing_commas = false); - -// (3) -template +template static basic_json parse(IteratorType first, SentinelType last, const parser_callback_t cb = nullptr, const bool allow_exceptions = true, @@ -27,14 +19,11 @@ static basic_json parse(IteratorType first, SentinelType last, ``` 1. Deserialize from a compatible input. -2. Deserialize from a pair of character iterators (same type) +2. Deserialize from a pair of character iterators, or an iterator and a sentinel of a different type (C++20 ranges support) The `value_type` of the iterator must be an integral type with size of 1, 2, or 4 bytes, which will be interpreted - respectively as UTF-8, UTF-16, and UTF-32. -3. Deserialize from an iterator and a sentinel (different types, C++20 ranges support) - - The `value_type` of the iterator must be an integral type with size of 1, 2, or 4 bytes, which will be interpreted - respectively as UTF-8, UTF-16, and UTF-32. The sentinel type must be comparable to the iterator type with `operator!=`. + respectively as UTF-8, UTF-16, and UTF-32. If `SentinelType` differs from `IteratorType`, it must be comparable to + the iterator type with `operator!=`. ## Template parameters @@ -56,7 +45,7 @@ static basic_json parse(IteratorType first, SentinelType last, - a pair of pointers such as `ptr` and `ptr + len` `SentinelType` -: a sentinel type compatible with `IteratorType` (different from `IteratorType` and comparable via `operator!=`), for instance. +: defaults to `IteratorType`; may be a different type comparable to `IteratorType` via `operator!=`, for instance. - a custom sentinel type for C++20 ranges - `std::counted_iterator` with a different sentinel type @@ -256,7 +245,7 @@ Invalid Unicode escapes and unpaired surrogates in the input are reported as - Changed [runtime assertion](../../features/assertions.md) in case of `FILE*` null pointers to exception in version 3.12.0. - Added `ignore_trailing_commas` in version 3.13.0. - Extended container support (1) to include types with lvalue-only ADL `begin`/`end` (matching `std::begin`/`std::end` semantics) in version 3.13.0. -- Added overload (3) for heterogeneous iterator+sentinel pairs (C++20 ranges support) in version 3.13.0. +- Extended overload (2) to accept heterogeneous iterator+sentinel pairs (C++20 ranges support) in version 3.13.0. !!! warning "Deprecation" diff --git a/docs/mkdocs/docs/api/basic_json/sax_parse.md b/docs/mkdocs/docs/api/basic_json/sax_parse.md index d7da30311..606ab9bbe 100644 --- a/docs/mkdocs/docs/api/basic_json/sax_parse.md +++ b/docs/mkdocs/docs/api/basic_json/sax_parse.md @@ -11,16 +11,7 @@ static bool sax_parse(InputType&& i, const bool ignore_trailing_commas = false); // (2) -template -static bool sax_parse(IteratorType first, IteratorType last, - SAX* sax, - input_format_t format = input_format_t::json, - const bool strict = true, - const bool ignore_comments = false, - const bool ignore_trailing_commas = false); - -// (3) -template +template static bool sax_parse(IteratorType first, SentinelType last, SAX* sax, input_format_t format = input_format_t::json, @@ -32,14 +23,11 @@ static bool sax_parse(IteratorType first, SentinelType last, Read from input and generate SAX events 1. Read from a compatible input. -2. Read from a pair of character iterators (same type) +2. Read from a pair of character iterators, or an iterator and a sentinel of a different type (C++20 ranges support) The value_type of the iterator must be an integral type with a size of 1, 2, or 4 bytes, which will be interpreted - respectively as UTF-8, UTF-16, and UTF-32. -3. Read from an iterator and a sentinel (different types, C++20 ranges support) - - The value_type of the iterator must be an integral type with a size of 1, 2, or 4 bytes, which will be interpreted - respectively as UTF-8, UTF-16, and UTF-32. The sentinel type must be comparable to the iterator type with `operator!=`. + respectively as UTF-8, UTF-16, and UTF-32. If `SentinelType` differs from `IteratorType`, it must be comparable to + the iterator type with `operator!=`. The SAX event lister must follow the interface of [`json_sax`](../json_sax/index.md). @@ -56,11 +44,11 @@ The SAX event lister must follow the interface of [`json_sax`](../json_sax/index (as found via ADL or member functions, with semantics compatible to `std::begin` and `std::end`) `IteratorType` -: a compatible iterator type for overloads (2) and (3); a pair of character iterators whose `value_type` is an integral type +: a compatible iterator type for overload (2); a pair of character iterators whose `value_type` is an integral type with a size of 1, 2, or 4 bytes (interpreted respectively as UTF-8, UTF-16, and UTF-32) `SentinelType` -: a sentinel type compatible with `IteratorType` (different from `IteratorType` and comparable via `operator!=`) for overload (3) +: defaults to `IteratorType`; may be a different type comparable to `IteratorType` via `operator!=`, for overload (2) `SAX` : a class fulfilling the SAX event listener interface; see [`json_sax`](../json_sax/index.md) @@ -144,7 +132,7 @@ A UTF-8 byte order mark is silently ignored. - Ignoring comments via `ignore_comments` added in version 3.9.0. - Added `ignore_trailing_commas` in version 3.13.0. - Extended container support (1) to include types with lvalue-only ADL `begin`/`end` (matching `std::begin`/`std::end` semantics) in version 3.13.0. -- Added overload (3) for heterogeneous iterator+sentinel pairs (C++20 ranges support) in version 3.13.0. +- Extended overload (2) to accept heterogeneous iterator+sentinel pairs (C++20 ranges support) in version 3.13.0. !!! warning "Deprecation" diff --git a/include/nlohmann/detail/input/input_adapters.hpp b/include/nlohmann/detail/input/input_adapters.hpp index d646d228c..1ef8a6af7 100644 --- a/include/nlohmann/detail/input/input_adapters.hpp +++ b/include/nlohmann/detail/input/input_adapters.hpp @@ -491,10 +491,21 @@ struct can_compare_ne_reversed < IteratorType, SentinelType, : std::true_type {}; template -struct can_compare_ne : std::integral_constant < bool, +struct can_compare_ne_either_order : std::integral_constant < bool, can_compare_ne_impl::value || can_compare_ne_reversed::value > {}; +// std::nullptr_t is excluded explicitly: a literal `nullptr` passed as a +// trailing default argument (e.g. parse(s, nullptr, ...)) must never be +// mistaken for a sentinel, and some compilers (e.g. GCC 4.8) unreliably +// SFINAE the `operator!=` detection above for std::nullptr_t against +// container/string types, which would otherwise make such calls ambiguous +// with the compatible-input overload. +template +struct can_compare_ne : std::integral_constant < bool, + !std::is_same::value && + can_compare_ne_either_order::value > {}; + template struct is_iterator_of_multibyte { @@ -520,19 +531,12 @@ struct iterator_input_adapter_factory -typename iterator_input_adapter_factory::adapter_type input_adapter(IteratorType first, IteratorType last) -{ - using factory_type = iterator_input_adapter_factory; - return factory_type::create(first, last); -} - -// General purpose iterator-based input (iterator+sentinel pair with different types) -// Only enable for types that can be compared with != -template < typename IteratorType, typename SentinelType, +// General purpose iterator-based input (iterator+sentinel pair; SentinelType +// defaults to IteratorType for the common same-type case, but may differ for +// C++20 ranges-style iterator+sentinel pairs). Only enable for types that can +// be compared with !=. +template < typename IteratorType, typename SentinelType = IteratorType, typename = typename std::enable_if < - !std::is_same::value && can_compare_ne::value >::type > typename iterator_input_adapter_factory::adapter_type input_adapter(IteratorType first, SentinelType last) { diff --git a/include/nlohmann/json.hpp b/include/nlohmann/json.hpp index 65ab0113a..a460bb29f 100644 --- a/include/nlohmann/json.hpp +++ b/include/nlohmann/json.hpp @@ -4083,34 +4083,17 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec return result; } - /// @brief deserialize from a pair of character iterators + /// @brief deserialize from a pair of character iterators (or an iterator+sentinel pair, C++20 ranges support) /// @sa https://json.nlohmann.me/api/basic_json/parse/ - template - JSON_HEDLEY_WARN_UNUSED_RESULT - static basic_json parse(IteratorType first, - IteratorType last, - parser_callback_t cb = nullptr, - const bool allow_exceptions = true, - const bool ignore_comments = false, - const bool ignore_trailing_commas = false) - { - basic_json result; - parser(detail::input_adapter(std::move(first), std::move(last)), std::move(cb), allow_exceptions, ignore_comments, ignore_trailing_commas).parse(true, result); // cppcheck-suppress[accessMoved] - return result; - } - - /// @brief deserialize from an iterator+sentinel pair (C++20 ranges support) - /// @sa https://json.nlohmann.me/api/basic_json/parse/ - template + template::value, int> = 0> JSON_HEDLEY_WARN_UNUSED_RESULT static basic_json parse(IteratorType first, SentinelType last, parser_callback_t cb = nullptr, const bool allow_exceptions = true, const bool ignore_comments = false, - const bool ignore_trailing_commas = false, - typename std::enable_if < !std::is_same::value && - detail::can_compare_ne::value >::type* = nullptr) + const bool ignore_trailing_commas = false) { basic_json result; parser(detail::input_adapter(std::move(first), std::move(last)), std::move(cb), allow_exceptions, ignore_comments, ignore_trailing_commas).parse(true, result); // cppcheck-suppress[accessMoved] @@ -4140,24 +4123,13 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec return parser(detail::input_adapter(std::forward(i)), nullptr, false, ignore_comments, ignore_trailing_commas).accept(true); } - /// @brief check if the input is valid JSON + /// @brief check if the input is valid JSON (iterator pair, or iterator+sentinel pair for C++20 ranges support) /// @sa https://json.nlohmann.me/api/basic_json/accept/ - template - static bool accept(IteratorType first, IteratorType last, - const bool ignore_comments = false, - const bool ignore_trailing_commas = false) - { - return parser(detail::input_adapter(std::move(first), std::move(last)), nullptr, false, ignore_comments, ignore_trailing_commas).accept(true); - } - - /// @brief check if the input is valid JSON (sentinel version) - /// @sa https://json.nlohmann.me/api/basic_json/accept/ - template + template::value, int> = 0> static bool accept(IteratorType first, SentinelType last, const bool ignore_comments = false, - const bool ignore_trailing_commas = false, - typename std::enable_if < !std::is_same::value && - detail::can_compare_ne::value >::type* = nullptr) + const bool ignore_trailing_commas = false) { return parser(detail::input_adapter(std::move(first), std::move(last)), nullptr, false, ignore_comments, ignore_trailing_commas).accept(true); } @@ -4187,33 +4159,16 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec : detail::binary_reader(std::move(ia), format).sax_parse(format, sax, strict); } - /// @brief generate SAX events + /// @brief generate SAX events (iterator pair, or iterator+sentinel pair for C++20 ranges support) /// @sa https://json.nlohmann.me/api/basic_json/sax_parse/ - template - 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 ignore_comments = false, - const bool ignore_trailing_commas = false) - { - auto ia = detail::input_adapter(std::move(first), std::move(last)); - return format == input_format_t::json - ? parser(std::move(ia), nullptr, true, ignore_comments, ignore_trailing_commas).sax_parse(sax, strict) - : detail::binary_reader(std::move(ia), format).sax_parse(format, sax, strict); - } - - /// @brief generate SAX events (sentinel version) - /// @sa https://json.nlohmann.me/api/basic_json/sax_parse/ - template + template::value, int> = 0> JSON_HEDLEY_NON_NULL(3) static bool sax_parse(IteratorType first, SentinelType last, SAX* sax, input_format_t format = input_format_t::json, const bool strict = true, const bool ignore_comments = false, - const bool ignore_trailing_commas = false, - typename std::enable_if < !std::is_same::value && - detail::can_compare_ne::value >::type* = nullptr) + const bool ignore_trailing_commas = false) { auto ia = detail::input_adapter(std::move(first), std::move(last)); return format == input_format_t::json @@ -4509,32 +4464,15 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec return res ? result : basic_json(value_t::discarded); } - /// @brief create a JSON value from an input in CBOR format + /// @brief create a JSON value from an input in CBOR format (iterator pair, or iterator+sentinel pair for C++20 ranges support) /// @sa https://json.nlohmann.me/api/basic_json/from_cbor/ - template - JSON_HEDLEY_WARN_UNUSED_RESULT - static basic_json from_cbor(IteratorType first, IteratorType last, - const bool strict = true, - const bool allow_exceptions = true, - const cbor_tag_handler_t tag_handler = cbor_tag_handler_t::error) - { - basic_json result; - auto ia = detail::input_adapter(std::move(first), std::move(last)); - detail::json_sax_dom_parser sdp(result, allow_exceptions); - const bool res = binary_reader(std::move(ia), input_format_t::cbor).sax_parse(input_format_t::cbor, &sdp, strict, tag_handler); // cppcheck-suppress[accessMoved] - return res ? result : basic_json(value_t::discarded); - } - - /// @brief create a JSON value from an input in CBOR format (sentinel version) - /// @sa https://json.nlohmann.me/api/basic_json/from_cbor/ - template + template::value, int> = 0> JSON_HEDLEY_WARN_UNUSED_RESULT static basic_json from_cbor(IteratorType first, SentinelType last, const bool strict = true, const bool allow_exceptions = true, - const cbor_tag_handler_t tag_handler = cbor_tag_handler_t::error, - typename std::enable_if < !std::is_same::value && - detail::can_compare_ne::value >::type* = nullptr) + const cbor_tag_handler_t tag_handler = cbor_tag_handler_t::error) { basic_json result; auto ia = detail::input_adapter(std::move(first), std::move(last)); @@ -4584,30 +4522,14 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec return res ? result : basic_json(value_t::discarded); } - /// @brief create a JSON value from an input in MessagePack format + /// @brief create a JSON value from an input in MessagePack format (iterator pair, or iterator+sentinel pair for C++20 ranges support) /// @sa https://json.nlohmann.me/api/basic_json/from_msgpack/ - template - JSON_HEDLEY_WARN_UNUSED_RESULT - static basic_json from_msgpack(IteratorType first, IteratorType last, - const bool strict = true, - const bool allow_exceptions = true) - { - basic_json result; - auto ia = detail::input_adapter(std::move(first), std::move(last)); - detail::json_sax_dom_parser sdp(result, allow_exceptions); - const bool res = binary_reader(std::move(ia), input_format_t::msgpack).sax_parse(input_format_t::msgpack, &sdp, strict); // cppcheck-suppress[accessMoved] - return res ? result : basic_json(value_t::discarded); - } - - /// @brief create a JSON value from an input in MessagePack format (sentinel version) - /// @sa https://json.nlohmann.me/api/basic_json/from_msgpack/ - template + template::value, int> = 0> JSON_HEDLEY_WARN_UNUSED_RESULT static basic_json from_msgpack(IteratorType first, SentinelType last, const bool strict = true, - const bool allow_exceptions = true, - typename std::enable_if < !std::is_same::value && - detail::can_compare_ne::value >::type* = nullptr) + const bool allow_exceptions = true) { basic_json result; auto ia = detail::input_adapter(std::move(first), std::move(last)); @@ -4655,30 +4577,14 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec return res ? result : basic_json(value_t::discarded); } - /// @brief create a JSON value from an input in UBJSON format + /// @brief create a JSON value from an input in UBJSON format (iterator pair, or iterator+sentinel pair for C++20 ranges support) /// @sa https://json.nlohmann.me/api/basic_json/from_ubjson/ - template - JSON_HEDLEY_WARN_UNUSED_RESULT - static basic_json from_ubjson(IteratorType first, IteratorType last, - const bool strict = true, - const bool allow_exceptions = true) - { - basic_json result; - auto ia = detail::input_adapter(std::move(first), std::move(last)); - detail::json_sax_dom_parser sdp(result, allow_exceptions); - const bool res = binary_reader(std::move(ia), input_format_t::ubjson).sax_parse(input_format_t::ubjson, &sdp, strict); // cppcheck-suppress[accessMoved] - return res ? result : basic_json(value_t::discarded); - } - - /// @brief create a JSON value from an input in UBJSON format (sentinel version) - /// @sa https://json.nlohmann.me/api/basic_json/from_ubjson/ - template + template::value, int> = 0> JSON_HEDLEY_WARN_UNUSED_RESULT static basic_json from_ubjson(IteratorType first, SentinelType last, const bool strict = true, - const bool allow_exceptions = true, - typename std::enable_if < !std::is_same::value && - detail::can_compare_ne::value >::type* = nullptr) + const bool allow_exceptions = true) { basic_json result; auto ia = detail::input_adapter(std::move(first), std::move(last)); @@ -4726,30 +4632,14 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec return res ? result : basic_json(value_t::discarded); } - /// @brief create a JSON value from an input in BJData format + /// @brief create a JSON value from an input in BJData format (iterator pair, or iterator+sentinel pair for C++20 ranges support) /// @sa https://json.nlohmann.me/api/basic_json/from_bjdata/ - template - JSON_HEDLEY_WARN_UNUSED_RESULT - static basic_json from_bjdata(IteratorType first, IteratorType last, - const bool strict = true, - const bool allow_exceptions = true) - { - basic_json result; - auto ia = detail::input_adapter(std::move(first), std::move(last)); - detail::json_sax_dom_parser sdp(result, allow_exceptions); - const bool res = binary_reader(std::move(ia), input_format_t::bjdata).sax_parse(input_format_t::bjdata, &sdp, strict); // cppcheck-suppress[accessMoved] - return res ? result : basic_json(value_t::discarded); - } - - /// @brief create a JSON value from an input in BJData format (sentinel version) - /// @sa https://json.nlohmann.me/api/basic_json/from_bjdata/ - template + template::value, int> = 0> JSON_HEDLEY_WARN_UNUSED_RESULT static basic_json from_bjdata(IteratorType first, SentinelType last, const bool strict = true, - const bool allow_exceptions = true, - typename std::enable_if < !std::is_same::value && - detail::can_compare_ne::value >::type* = nullptr) + const bool allow_exceptions = true) { basic_json result; auto ia = detail::input_adapter(std::move(first), std::move(last)); @@ -4773,30 +4663,14 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec return res ? result : basic_json(value_t::discarded); } - /// @brief create a JSON value from an input in BSON format + /// @brief create a JSON value from an input in BSON format (iterator pair, or iterator+sentinel pair for C++20 ranges support) /// @sa https://json.nlohmann.me/api/basic_json/from_bson/ - template - JSON_HEDLEY_WARN_UNUSED_RESULT - static basic_json from_bson(IteratorType first, IteratorType last, - const bool strict = true, - const bool allow_exceptions = true) - { - basic_json result; - auto ia = detail::input_adapter(std::move(first), std::move(last)); - detail::json_sax_dom_parser sdp(result, allow_exceptions); - const bool res = binary_reader(std::move(ia), input_format_t::bson).sax_parse(input_format_t::bson, &sdp, strict); // cppcheck-suppress[accessMoved] - return res ? result : basic_json(value_t::discarded); - } - - /// @brief create a JSON value from an input in BSON format (sentinel version) - /// @sa https://json.nlohmann.me/api/basic_json/from_bson/ - template + template::value, int> = 0> JSON_HEDLEY_WARN_UNUSED_RESULT static basic_json from_bson(IteratorType first, SentinelType last, const bool strict = true, - const bool allow_exceptions = true, - typename std::enable_if < !std::is_same::value && - detail::can_compare_ne::value >::type* = nullptr) + const bool allow_exceptions = true) { basic_json result; auto ia = detail::input_adapter(std::move(first), std::move(last)); diff --git a/single_include/nlohmann/json.hpp b/single_include/nlohmann/json.hpp index 06cda9a69..d910badb8 100644 --- a/single_include/nlohmann/json.hpp +++ b/single_include/nlohmann/json.hpp @@ -7328,10 +7328,21 @@ struct can_compare_ne_reversed < IteratorType, SentinelType, : std::true_type {}; template -struct can_compare_ne : std::integral_constant < bool, +struct can_compare_ne_either_order : std::integral_constant < bool, can_compare_ne_impl::value || can_compare_ne_reversed::value > {}; +// std::nullptr_t is excluded explicitly: a literal `nullptr` passed as a +// trailing default argument (e.g. parse(s, nullptr, ...)) must never be +// mistaken for a sentinel, and some compilers (e.g. GCC 4.8) unreliably +// SFINAE the `operator!=` detection above for std::nullptr_t against +// container/string types, which would otherwise make such calls ambiguous +// with the compatible-input overload. +template +struct can_compare_ne : std::integral_constant < bool, + !std::is_same::value && + can_compare_ne_either_order::value > {}; + template struct is_iterator_of_multibyte { @@ -7357,19 +7368,12 @@ struct iterator_input_adapter_factory -typename iterator_input_adapter_factory::adapter_type input_adapter(IteratorType first, IteratorType last) -{ - using factory_type = iterator_input_adapter_factory; - return factory_type::create(first, last); -} - -// General purpose iterator-based input (iterator+sentinel pair with different types) -// Only enable for types that can be compared with != -template < typename IteratorType, typename SentinelType, +// General purpose iterator-based input (iterator+sentinel pair; SentinelType +// defaults to IteratorType for the common same-type case, but may differ for +// C++20 ranges-style iterator+sentinel pairs). Only enable for types that can +// be compared with !=. +template < typename IteratorType, typename SentinelType = IteratorType, typename = typename std::enable_if < - !std::is_same::value && can_compare_ne::value >::type > typename iterator_input_adapter_factory::adapter_type input_adapter(IteratorType first, SentinelType last) { @@ -24976,34 +24980,17 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec return result; } - /// @brief deserialize from a pair of character iterators + /// @brief deserialize from a pair of character iterators (or an iterator+sentinel pair, C++20 ranges support) /// @sa https://json.nlohmann.me/api/basic_json/parse/ - template - JSON_HEDLEY_WARN_UNUSED_RESULT - static basic_json parse(IteratorType first, - IteratorType last, - parser_callback_t cb = nullptr, - const bool allow_exceptions = true, - const bool ignore_comments = false, - const bool ignore_trailing_commas = false) - { - basic_json result; - parser(detail::input_adapter(std::move(first), std::move(last)), std::move(cb), allow_exceptions, ignore_comments, ignore_trailing_commas).parse(true, result); // cppcheck-suppress[accessMoved] - return result; - } - - /// @brief deserialize from an iterator+sentinel pair (C++20 ranges support) - /// @sa https://json.nlohmann.me/api/basic_json/parse/ - template + template::value, int> = 0> JSON_HEDLEY_WARN_UNUSED_RESULT static basic_json parse(IteratorType first, SentinelType last, parser_callback_t cb = nullptr, const bool allow_exceptions = true, const bool ignore_comments = false, - const bool ignore_trailing_commas = false, - typename std::enable_if < !std::is_same::value && - detail::can_compare_ne::value >::type* = nullptr) + const bool ignore_trailing_commas = false) { basic_json result; parser(detail::input_adapter(std::move(first), std::move(last)), std::move(cb), allow_exceptions, ignore_comments, ignore_trailing_commas).parse(true, result); // cppcheck-suppress[accessMoved] @@ -25033,24 +25020,13 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec return parser(detail::input_adapter(std::forward(i)), nullptr, false, ignore_comments, ignore_trailing_commas).accept(true); } - /// @brief check if the input is valid JSON + /// @brief check if the input is valid JSON (iterator pair, or iterator+sentinel pair for C++20 ranges support) /// @sa https://json.nlohmann.me/api/basic_json/accept/ - template - static bool accept(IteratorType first, IteratorType last, - const bool ignore_comments = false, - const bool ignore_trailing_commas = false) - { - return parser(detail::input_adapter(std::move(first), std::move(last)), nullptr, false, ignore_comments, ignore_trailing_commas).accept(true); - } - - /// @brief check if the input is valid JSON (sentinel version) - /// @sa https://json.nlohmann.me/api/basic_json/accept/ - template + template::value, int> = 0> static bool accept(IteratorType first, SentinelType last, const bool ignore_comments = false, - const bool ignore_trailing_commas = false, - typename std::enable_if < !std::is_same::value && - detail::can_compare_ne::value >::type* = nullptr) + const bool ignore_trailing_commas = false) { return parser(detail::input_adapter(std::move(first), std::move(last)), nullptr, false, ignore_comments, ignore_trailing_commas).accept(true); } @@ -25080,33 +25056,16 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec : detail::binary_reader(std::move(ia), format).sax_parse(format, sax, strict); } - /// @brief generate SAX events + /// @brief generate SAX events (iterator pair, or iterator+sentinel pair for C++20 ranges support) /// @sa https://json.nlohmann.me/api/basic_json/sax_parse/ - template - 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 ignore_comments = false, - const bool ignore_trailing_commas = false) - { - auto ia = detail::input_adapter(std::move(first), std::move(last)); - return format == input_format_t::json - ? parser(std::move(ia), nullptr, true, ignore_comments, ignore_trailing_commas).sax_parse(sax, strict) - : detail::binary_reader(std::move(ia), format).sax_parse(format, sax, strict); - } - - /// @brief generate SAX events (sentinel version) - /// @sa https://json.nlohmann.me/api/basic_json/sax_parse/ - template + template::value, int> = 0> JSON_HEDLEY_NON_NULL(3) static bool sax_parse(IteratorType first, SentinelType last, SAX* sax, input_format_t format = input_format_t::json, const bool strict = true, const bool ignore_comments = false, - const bool ignore_trailing_commas = false, - typename std::enable_if < !std::is_same::value && - detail::can_compare_ne::value >::type* = nullptr) + const bool ignore_trailing_commas = false) { auto ia = detail::input_adapter(std::move(first), std::move(last)); return format == input_format_t::json @@ -25402,32 +25361,15 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec return res ? result : basic_json(value_t::discarded); } - /// @brief create a JSON value from an input in CBOR format + /// @brief create a JSON value from an input in CBOR format (iterator pair, or iterator+sentinel pair for C++20 ranges support) /// @sa https://json.nlohmann.me/api/basic_json/from_cbor/ - template - JSON_HEDLEY_WARN_UNUSED_RESULT - static basic_json from_cbor(IteratorType first, IteratorType last, - const bool strict = true, - const bool allow_exceptions = true, - const cbor_tag_handler_t tag_handler = cbor_tag_handler_t::error) - { - basic_json result; - auto ia = detail::input_adapter(std::move(first), std::move(last)); - detail::json_sax_dom_parser sdp(result, allow_exceptions); - const bool res = binary_reader(std::move(ia), input_format_t::cbor).sax_parse(input_format_t::cbor, &sdp, strict, tag_handler); // cppcheck-suppress[accessMoved] - return res ? result : basic_json(value_t::discarded); - } - - /// @brief create a JSON value from an input in CBOR format (sentinel version) - /// @sa https://json.nlohmann.me/api/basic_json/from_cbor/ - template + template::value, int> = 0> JSON_HEDLEY_WARN_UNUSED_RESULT static basic_json from_cbor(IteratorType first, SentinelType last, const bool strict = true, const bool allow_exceptions = true, - const cbor_tag_handler_t tag_handler = cbor_tag_handler_t::error, - typename std::enable_if < !std::is_same::value && - detail::can_compare_ne::value >::type* = nullptr) + const cbor_tag_handler_t tag_handler = cbor_tag_handler_t::error) { basic_json result; auto ia = detail::input_adapter(std::move(first), std::move(last)); @@ -25477,30 +25419,14 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec return res ? result : basic_json(value_t::discarded); } - /// @brief create a JSON value from an input in MessagePack format + /// @brief create a JSON value from an input in MessagePack format (iterator pair, or iterator+sentinel pair for C++20 ranges support) /// @sa https://json.nlohmann.me/api/basic_json/from_msgpack/ - template - JSON_HEDLEY_WARN_UNUSED_RESULT - static basic_json from_msgpack(IteratorType first, IteratorType last, - const bool strict = true, - const bool allow_exceptions = true) - { - basic_json result; - auto ia = detail::input_adapter(std::move(first), std::move(last)); - detail::json_sax_dom_parser sdp(result, allow_exceptions); - const bool res = binary_reader(std::move(ia), input_format_t::msgpack).sax_parse(input_format_t::msgpack, &sdp, strict); // cppcheck-suppress[accessMoved] - return res ? result : basic_json(value_t::discarded); - } - - /// @brief create a JSON value from an input in MessagePack format (sentinel version) - /// @sa https://json.nlohmann.me/api/basic_json/from_msgpack/ - template + template::value, int> = 0> JSON_HEDLEY_WARN_UNUSED_RESULT static basic_json from_msgpack(IteratorType first, SentinelType last, const bool strict = true, - const bool allow_exceptions = true, - typename std::enable_if < !std::is_same::value && - detail::can_compare_ne::value >::type* = nullptr) + const bool allow_exceptions = true) { basic_json result; auto ia = detail::input_adapter(std::move(first), std::move(last)); @@ -25548,30 +25474,14 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec return res ? result : basic_json(value_t::discarded); } - /// @brief create a JSON value from an input in UBJSON format + /// @brief create a JSON value from an input in UBJSON format (iterator pair, or iterator+sentinel pair for C++20 ranges support) /// @sa https://json.nlohmann.me/api/basic_json/from_ubjson/ - template - JSON_HEDLEY_WARN_UNUSED_RESULT - static basic_json from_ubjson(IteratorType first, IteratorType last, - const bool strict = true, - const bool allow_exceptions = true) - { - basic_json result; - auto ia = detail::input_adapter(std::move(first), std::move(last)); - detail::json_sax_dom_parser sdp(result, allow_exceptions); - const bool res = binary_reader(std::move(ia), input_format_t::ubjson).sax_parse(input_format_t::ubjson, &sdp, strict); // cppcheck-suppress[accessMoved] - return res ? result : basic_json(value_t::discarded); - } - - /// @brief create a JSON value from an input in UBJSON format (sentinel version) - /// @sa https://json.nlohmann.me/api/basic_json/from_ubjson/ - template + template::value, int> = 0> JSON_HEDLEY_WARN_UNUSED_RESULT static basic_json from_ubjson(IteratorType first, SentinelType last, const bool strict = true, - const bool allow_exceptions = true, - typename std::enable_if < !std::is_same::value && - detail::can_compare_ne::value >::type* = nullptr) + const bool allow_exceptions = true) { basic_json result; auto ia = detail::input_adapter(std::move(first), std::move(last)); @@ -25619,30 +25529,14 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec return res ? result : basic_json(value_t::discarded); } - /// @brief create a JSON value from an input in BJData format + /// @brief create a JSON value from an input in BJData format (iterator pair, or iterator+sentinel pair for C++20 ranges support) /// @sa https://json.nlohmann.me/api/basic_json/from_bjdata/ - template - JSON_HEDLEY_WARN_UNUSED_RESULT - static basic_json from_bjdata(IteratorType first, IteratorType last, - const bool strict = true, - const bool allow_exceptions = true) - { - basic_json result; - auto ia = detail::input_adapter(std::move(first), std::move(last)); - detail::json_sax_dom_parser sdp(result, allow_exceptions); - const bool res = binary_reader(std::move(ia), input_format_t::bjdata).sax_parse(input_format_t::bjdata, &sdp, strict); // cppcheck-suppress[accessMoved] - return res ? result : basic_json(value_t::discarded); - } - - /// @brief create a JSON value from an input in BJData format (sentinel version) - /// @sa https://json.nlohmann.me/api/basic_json/from_bjdata/ - template + template::value, int> = 0> JSON_HEDLEY_WARN_UNUSED_RESULT static basic_json from_bjdata(IteratorType first, SentinelType last, const bool strict = true, - const bool allow_exceptions = true, - typename std::enable_if < !std::is_same::value && - detail::can_compare_ne::value >::type* = nullptr) + const bool allow_exceptions = true) { basic_json result; auto ia = detail::input_adapter(std::move(first), std::move(last)); @@ -25666,30 +25560,14 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec return res ? result : basic_json(value_t::discarded); } - /// @brief create a JSON value from an input in BSON format + /// @brief create a JSON value from an input in BSON format (iterator pair, or iterator+sentinel pair for C++20 ranges support) /// @sa https://json.nlohmann.me/api/basic_json/from_bson/ - template - JSON_HEDLEY_WARN_UNUSED_RESULT - static basic_json from_bson(IteratorType first, IteratorType last, - const bool strict = true, - const bool allow_exceptions = true) - { - basic_json result; - auto ia = detail::input_adapter(std::move(first), std::move(last)); - detail::json_sax_dom_parser sdp(result, allow_exceptions); - const bool res = binary_reader(std::move(ia), input_format_t::bson).sax_parse(input_format_t::bson, &sdp, strict); // cppcheck-suppress[accessMoved] - return res ? result : basic_json(value_t::discarded); - } - - /// @brief create a JSON value from an input in BSON format (sentinel version) - /// @sa https://json.nlohmann.me/api/basic_json/from_bson/ - template + template::value, int> = 0> JSON_HEDLEY_WARN_UNUSED_RESULT static basic_json from_bson(IteratorType first, SentinelType last, const bool strict = true, - const bool allow_exceptions = true, - typename std::enable_if < !std::is_same::value && - detail::can_compare_ne::value >::type* = nullptr) + const bool allow_exceptions = true) { basic_json result; auto ia = detail::input_adapter(std::move(first), std::move(last)); diff --git a/tests/src/unit-bson.cpp b/tests/src/unit-bson.cpp index 289f1f439..84b974b0f 100644 --- a/tests/src/unit-bson.cpp +++ b/tests/src/unit-bson.cpp @@ -1210,21 +1210,15 @@ TEST_CASE("BSON numerical data") TEST_CASE("Parse BSON directly from a file using iterator and sentinel") { - const json j = {{"key", "value"}, {"number", 42}}; - std::vector bson_bytes; - json::to_bson(j, bson_bytes); + std::string const filename = TEST_DATA_DIRECTORY "/json.org/1.json"; - { - std::ofstream file("test_bson_sentinel.bson", std::ios::binary); - file.write(reinterpret_cast(bson_bytes.data()), static_cast(bson_bytes.size())); - } + std::ifstream f_json(filename); + const json expected = json::parse(f_json); - std::ifstream file("test_bson_sentinel.bson", std::ios::binary); + std::ifstream file(filename + ".bson", std::ios::binary); std::istreambuf_iterator first(file); const json parsed = json::from_bson(first, utils::istreambuf_sentinel{}); - CHECK(parsed == j); - - static_cast(std::remove("test_bson_sentinel.bson")); + CHECK(parsed == expected); } TEST_CASE("BSON roundtrips" * doctest::skip())