* Fix container input_adapter SFINAE for lvalue-only ADL begin/end (#111) The container overload of json::parse(c) / accept(c) / sax_parse(c, ...) silently dropped from overload resolution for user types whose ADL begin(T&) / end(T&) accepted only non-const lvalue references (a legitimate pattern matching std::begin semantics). This was because the detection code used std::declval<ContainerType>() which synthesized an rvalue, and the rvalue failed to bind to lvalue-only ADL functions. Fix by making both the outer input_adapter(ContainerType&&) and the factory's create(ContainerType&&) forwarding references, preserving the caller's value category and constness via reference collapsing. This ensures detection (std::declval) and actual use (std::forward) always match without needing decay/remove_reference. - Rewrite input_adapters.hpp container overload with forwarding refs - Add regression tests for lvalue-only non-const ADL begin/end - Add regression test for rvalue containers (no breakage) - Update API docs (parse, accept, sax_parse, from_*) to clarify that begin/end must match std::begin/std::end semantics - Add version history notes for 3.13.0 - Regenerate amalgamation Second-order effect: binary_reader.hpp's internal call to input_adapter(number_vector) now deduces iterator vs const_iterator based on the lvalue; functionally harmless (iterator_input_adapter is iterator-type-agnostic), verified via unit-ubjson/unit-bjdata tests. Closes remaining limitation from #4354 / PR #5218 (todo 106). Signed-off-by: Niels Lohmann <mail@nlohmann.me> * Avoid strlen() in test container to fix Codacy CWE-126 flag Suppressing the strlen()-based CWE-126 warning with NOLINT/nosec comments only silenced clang-tidy and the standalone Flawfinder Action; Codacy's own analysis (which also flags this pattern and doesn't honor those suppression comments) still reported it as a new issue, plus flagged the near-duplicate begin/end pair as cloned code. Store the buffer's size explicitly in MyContainerNonConstADL instead of computing it via strlen() in end(), which removes the flagged pattern outright and also de-duplicates the struct from the existing MyContainer's char*-based begin/end pair. Signed-off-by: Niels Lohmann <mail@nlohmann.me> * Avoid trailing return type to satisfy clang-tidy fuchsia-trailing-return The forwarding-reference input_adapter(ContainerType&&) entry point was written with an auto/trailing-decltype return type, but this project's ci_clang_tidy job enables the fuchsia-trailing-return check as an error, which rejects it. The return type only depends on the template parameter ContainerType, not on the runtime parameter, so it can be written as an ordinary leading return type instead - no functional change. Signed-off-by: Niels Lohmann <mail@nlohmann.me> * Avoid C-style array in test to satisfy clang-tidy avoid-c-arrays clang-tidy's cppcoreguidelines/hicpp/modernize-avoid-c-arrays checks flagged the char raw_data[] declaration used to reproduce the lvalue-only non-const ADL begin/end scenario. Use std::string instead and take a mutable pointer via &raw_data[0], which is the standard way to get a non-const char* into a string's buffer under C++11 (std::string::data() only returns non-const in C++17 and later). Signed-off-by: Niels Lohmann <mail@nlohmann.me> --------- Signed-off-by: Niels Lohmann <mail@nlohmann.me>
3.9 KiB
nlohmann::basic_json::accept
// (1)
template<typename InputType>
static bool accept(InputType&& i,
const bool ignore_comments = false,
const bool ignore_trailing_commas = false);
// (2)
template<typename IteratorType>
static bool accept(IteratorType first, IteratorType last,
const bool ignore_comments = false,
const bool ignore_trailing_commas = false);
Checks whether the input is valid JSON.
-
Reads from a compatible input.
-
Reads from a pair of character iterators
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.
Unlike the parse() function, this function neither throws an exception in case of invalid JSON input
(i.e., a parse error) nor creates diagnostic information.
Template parameters
InputType- A compatible input, for instance:
- an
std::istreamobject - a
#!c FILEpointer (throws if null) - a C-style array of characters
- a pointer to a null-terminated string of single byte characters (throws if null)
- a
std::string - a container
objfor whichbegin(obj)andend(obj)produce a valid pair of iterators (as found via ADL or member functions, with semantics compatible tostd::beginandstd::end)
- an
IteratorType- a compatible iterator type, for instance.
- a pair of
std::string::iteratororstd::vector<std::uint8_t>::iterator - a pair of pointers such as
ptrandptr + len
- a pair of
Parameters
i(in)- Input to parse from.
ignore_comments(in)- whether comments should be ignored and treated like whitespace (
#!cpp true) or yield a parse error (#!cpp false); (optional,#!cpp falseby default) ignore_trailing_commas(in)- whether trailing commas in arrays or objects should be ignored and treated like whitespace (
#!cpp true) or yield a parse error (#!cpp false); (optional,#!cpp falseby default) first(in)- iterator to the start of the character range
last(in)- iterator to the end of the character range
Return value
Whether the input is valid JSON.
Exception safety
Strong guarantee: if an exception is thrown, there are no changes in the JSON value.
Exceptions
Throws parse_error.101 in case of an empty input like a null #!c FILE* or #!c char* pointer.
Complexity
Linear in the length of the input. The parser is a predictive LL(1) parser.
Notes
A UTF-8 byte order mark is silently ignored.
Examples
??? example
The example below demonstrates the `accept()` function reading from a string.
```cpp
--8<-- "examples/accept__string.cpp"
```
Output:
```json
--8<-- "examples/accept__string.output"
```
See also
- parse - deserialize from a compatible input
- sax_parse - parse input using the SAX interface
- operator>> - deserialize from stream
Version history
- Added in version 3.0.0.
- Ignoring comments via
ignore_commentsadded in version 3.9.0. - Changed runtime assertion in case of
FILE*null pointers to exception in version 3.12.0. - Added
ignore_trailing_commasin version 3.13.0. - Extended container support (1) to include types with lvalue-only ADL
begin/end(matchingstd::begin/std::endsemantics) in version 3.13.0.
!!! warning "Deprecation"
Overload (2) replaces calls to `accept` with a pair of iterators as their first parameter which has been
deprecated in version 3.8.0. This overload will be removed in version 4.0.0. Please replace all calls like
`#!cpp accept({ptr, ptr+len}, ...);` with `#!cpp accept(ptr, ptr+len, ...);`.
You should be warned by your compiler with a `-Wdeprecated-declarations` warning if you are using a deprecated
function.