* Add BON8 support Add to_bon8/from_bon8 and input_format_t::bon8 for BON8, a binary format that uses the byte values that cannot begin a UTF-8 character as type markers, so strings need no length prefix. It is the most compact of the supported binary formats on the benchmark files. The reader is non-recursive like the other binary readers. A string ends at the first byte that cannot continue it, so the reader hands the one or two bytes it reads past a string back to the value that follows. The writer produces the canonical representation of the specification, except for NFC normalization; its output is identical to that of the reference implementation (HikoGUI) on all files of the test data. The round-trip tests need the .bon8 files of json_test_data 3.2.0. Signed-off-by: Niels Lohmann <mail@nlohmann.me> * Address review comments - Reuse detail::validate_one_utf8 to check strings in to_bon8; the error now names the first byte of the invalid sequence. - Document that to_bon8 leaves bytes in the output adapter on an exception, and that string_open is only an output of write_bon8_marker. - Explain why the pushback buffer of the BON8 reader cannot overflow. Signed-off-by: Niels Lohmann <mail@nlohmann.me> * Select the BON8 float prefix by type get_bon8_float_prefix only depends on the type of its argument, so make the type a template parameter instead of passing an unused value. Signed-off-by: Niels Lohmann <mail@nlohmann.me> * Rename a test variable that Flawfinder mistakes for read() Signed-off-by: Niels Lohmann <mail@nlohmann.me> * Fix the BON8 CI failures - compare the float in write_bon8_float with number_float_t constants, so GCC does not warn about a float-to-double conversion - mark check_bon8_utf8's context as used when exceptions are disabled - choose the compact float prefix in a helper rather than with nested conditional operators (clang-tidy) - use auto for the cast in the BON8 integer reader (clang-tidy) - write the int32 minimum test values as long long literals (MSVC C4146) Signed-off-by: Niels Lohmann <mail@nlohmann.me> * Amalgamate Signed-off-by: Niels Lohmann <mail@nlohmann.me> * Read BON8 strings in bulk from contiguous input - copy the valid UTF-8 of a string in one step when the input is contiguous (twitter.json is read in 1.68 instead of 2.52 ms, jeopardy.json in 196 instead of 297 ms, close to CBOR and MessagePack) - share the new valid_utf8_prefix() with the writer's UTF-8 check, which now skips ASCII 8 bytes at a time - let the fuzzer check that contiguous and stream input give the same value or error, and test both paths in the unit tests - clarify that a second 0xFF after a string is an empty string Signed-off-by: Niels Lohmann <mail@nlohmann.me> * Link the BON8 functions from the other binary format pages Signed-off-by: Niels Lohmann <mail@nlohmann.me> * Name the bulk scan flag after the input, not BON8 Signed-off-by: Niels Lohmann <mail@nlohmann.me> * Read BSON keys in bulk from contiguous input BSON keys (and array indices) are C-style strings, which were read byte by byte. For contiguous input they are now read up to their \x00-byte in one step, using the same bulk_scan flag as BON8 strings: twitter.json is read in 1.46 instead of 2.01 ms, citm_catalog.json in 2.93 instead of 3.33 ms, jeopardy.json in 182 instead of 207 ms. canada.json, whose keys are almost all one-digit array indices, takes 2 % longer. Signed-off-by: Niels Lohmann <mail@nlohmann.me> * Fix the BON8 CI failures of the bulk-read tests - skip the contiguous-versus-stream tests of BON8 strings and BSON keys when exceptions are disabled: they catch the parse errors of invalid input, and without exceptions the library aborts instead - use static_cast for the int64 test value (google-readability-casting) Signed-off-by: Niels Lohmann <mail@nlohmann.me> * Move the explicit basic_json instantiation into its own test file Linking test-regression3_cpp20 with clang and MinGW failed with "relocation truncated to fit: IMAGE_REL_AMD64_REL32 against `.rdata'", as test-regression2 did before #5511. The explicit instantiation of basic_json<> for #4825 compiles every member function, including the BON8 reader and writer, into that object, and it was already close to the limit (2,226,104 bytes on develop, 2,234,960 with BON8; clang -O1, C++20). Give the instantiation a file of its own: unit-regression3 is now 1,594,736 bytes and unit-explicit_instantiation 1,095,064. The new file mentions JSON_HAS_CPP_17 and JSON_HAS_CPP_20 so it keeps being built for the C++17 standard the regression was about. Signed-off-by: Niels Lohmann <mail@nlohmann.me> * Convert the bytes of the BON8 test strings explicitly The str() helper constructed a std::string from a byte range, which converts each unsigned char implicitly; -fsanitize=integer reports that for bytes of 0x80 and above (ci_test_clang_sanitizer). Signed-off-by: Niels Lohmann <mail@nlohmann.me> --------- Signed-off-by: Niels Lohmann <mail@nlohmann.me>
18 KiB
nlohmann::basic_json
Defined in header <nlohmann/json.hpp>
template<
template<typename U, typename V, typename... Args> class ObjectType = std::map,
template<typename U, typename... Args> class ArrayType = std::vector,
class StringType = std::string,
class BooleanType = bool,
class NumberIntegerType = std::int64_t,
class NumberUnsignedType = std::uint64_t,
class NumberFloatType = double,
template<typename U> class AllocatorType = std::allocator,
template<typename T, typename SFINAE = void> class JSONSerializer = adl_serializer,
class BinaryType = std::vector<std::uint8_t>,
class CustomBaseClass = void
>
class basic_json;
Template parameters
| Template parameter | Description | Derived type |
|---|---|---|
ObjectType |
type for JSON objects | object_t |
ArrayType |
type for JSON arrays | array_t |
StringType |
type for JSON strings and object keys | string_t |
BooleanType |
type for JSON booleans | boolean_t |
NumberIntegerType |
type for JSON integer numbers | number_integer_t |
NumberUnsignedType |
type for JSON unsigned integer numbers | number_unsigned_t |
NumberFloatType |
type for JSON floating-point numbers | number_float_t |
AllocatorType |
type of the allocator to use | |
JSONSerializer |
the serializer to resolve internal calls to to_json() and from_json() |
json_serializer |
BinaryType |
type for binary arrays | binary_t |
CustomBaseClass |
extension point for user code | json_base_class_t |
The library imposes a number of requirements on these types that are not expressed as C++ concepts, such as the
container operations object_t and array_t must provide, or the fact that StringType must be char-based. They
are collected in Template Parameter Requirements.
Specializations
- json - default specialization
- ordered_json - a specialization that maintains the insertion order of object keys
Iterator invalidation
All operations that add values to an array (push_back , operator+=,
emplace_back, insert, and operator[] for a non-existing
index) can yield a reallocation, in which case all iterators (including the end() iterator) and all
references to the elements are invalidated.
For ordered_json, also all operations that add a value to an object
(push_back, operator+=, emplace, insert,
update, and operator[] for a non-existing key) can yield a reallocation, in
which case all iterators (including the end() iterator) and all references to the elements are invalidated.
Requirements
The class satisfies the following concept requirements:
Basic
- DefaultConstructible: JSON values can be default-constructed. The result will be a JSON null value.
- MoveConstructible: A JSON value can be constructed from an rvalue argument.
- CopyConstructible: A JSON value can be copy-constructed from an lvalue expression.
- MoveAssignable: A JSON value can be assigned from an rvalue argument.
- CopyAssignable: A JSON value can be copy-assigned from an lvalue expression.
- Destructible: JSON values can be destructed.
Layout
- StandardLayoutType: JSON values have standard layout: All non-static data members are private and standard layout types, the class has no virtual functions or (virtual) base classes.
Library-wide
- EqualityComparable: JSON values can be compared with
==, seeoperator==. - LessThanComparable: JSON values can be compared with
<, seeoperator<. - Swappable: Any JSON lvalue or rvalue of can be swapped with
any lvalue or rvalue of other compatible types, using unqualified function
swap. - NullablePointer: JSON values can be compared against
std::nullptr_tobjects which are used to model thenullvalue.
Container
- Container: JSON values can be used like STL containers and provide iterator access.
- ReversibleContainer: JSON values can be used like STL containers and provide reverse iterator access.
Member types
- adl_serializer - the default serializer
- value_t - the JSON type enumeration
- json_pointer - JSON Pointer implementation
- json_serializer - type of the serializer to for conversions from/to JSON
- error_handler_t - type to choose behavior on decoding errors
- cbor_tag_handler_t - type to choose how to handle CBOR tags
- initializer_list_t - type for initializer lists of
basic_jsonvalues - input_format_t - type to choose the format to parse
- json_sax_t - type for SAX events
Exceptions
- exception - general exception of the
basic_jsonclass- parse_error - exception indicating a parse error
- invalid_iterator - exception indicating errors with iterators
- type_error - exception indicating executing a member function with a wrong type
- out_of_range - exception indicating access out of the defined range
- other_error - exception indicating other library errors
Container types
| Type | Definition |
|---|---|
value_type |
#!cpp basic_json |
reference |
#!cpp value_type& |
const_reference |
#!cpp const value_type& |
difference_type |
#!cpp std::ptrdiff_t |
size_type |
#!cpp std::size_t |
allocator_type |
#!cpp AllocatorType<basic_json> |
pointer |
#!cpp std::allocator_traits<allocator_type>::pointer |
const_pointer |
#!cpp std::allocator_traits<allocator_type>::const_pointer |
iterator |
LegacyBidirectionalIterator |
const_iterator |
constant LegacyBidirectionalIterator |
reverse_iterator |
reverse iterator, derived from iterator |
const_reverse_iterator |
reverse iterator, derived from const_iterator |
iteration_proxy |
helper type for items function |
JSON value data types
- array_t - type for arrays
- binary_t - type for binary arrays
- boolean_t - type for booleans
- default_object_comparator_t - default comparator for objects
- number_float_t - type for numbers (floating-point)
- number_integer_t - type for numbers (integer)
- number_unsigned_t - type for numbers (unsigned)
- object_comparator_t - comparator for objects
- object_t - type for objects
- string_t - type for strings
Parser callback
- parse_event_t - parser event types
- parser_callback_t - per-element parser callback type
Member functions
- (constructor)
- (destructor)
- operator= - copy assignment
- array (static) - explicitly create an array
- binary (static) - explicitly create a binary array
- object (static) - explicitly create an object
Object inspection
Functions to inspect the type of a JSON value.
- type - return the type of the JSON value
- operator value_t - return the type of the JSON value
- type_name - return the type as string
- is_primitive - return whether the type is primitive
- is_structured - return whether the type is structured
- is_null - return whether the value is null
- is_boolean - return whether the value is a boolean
- is_number - return whether the value is a number
- is_number_integer - return whether the value is an integer number
- is_number_unsigned - return whether the value is an unsigned integer number
- is_number_float - return whether the value is a floating-point number
- is_object - return whether the value is an object
- is_array - return whether the value is an array
- is_string - return whether the value is a string
- is_binary - return whether the value is a binary array
- is_discarded - return whether the value is discarded
Optional functions to access the diagnostic positions.
- start_pos - return the start position of the value
- end_pos - return the one past the end position of the value
Value access
Direct access to the stored value of a JSON value.
- get - get a value
- get_to - get a value and write it to a destination
- get_ptr - get a pointer value
- get_ref - get a reference value
- operator ValueType - get a value
- get_binary - get a binary value
Element access
Access to the JSON value
- at - access specified element with bounds checking
- operator[] - access specified element
- value - access specified object element with default value
- front - access the first element
- back - access the last element
Lookup
- find - find an element in a JSON object
- count - returns the number of occurrences of a key in a JSON object
- contains - check the existence of an element in a JSON object
Iterators
- begin - returns an iterator to the first element
- cbegin - returns a const iterator to the first element
- end - returns an iterator to one past the last element
- cend - returns a const iterator to one past the last element
- rbegin - returns an iterator to the reverse-beginning
- rend - returns an iterator to the reverse-end
- crbegin - returns a const iterator to the reverse-beginning
- crend - returns a const iterator to the reverse-end
- items - wrapper to access iterator member functions in range-based for
Capacity
- empty - checks whether the container is empty
- size - returns the number of elements
- max_size - returns the maximum possible number of elements
Modifiers
- clear - clears the contents
- push_back - add a value to an array/object
- operator+= - add a value to an array/object
- emplace_back - add a value to an array
- emplace - add a value to an object if a key does not exist
- erase - remove elements
- insert - inserts elements
- update - updates a JSON object from another object, overwriting existing keys
- swap - exchanges the values
Lexicographical comparison operators
- operator== - comparison: equal
- operator!= - comparison: not equal
- operator< - comparison: less than
- operator> - comparison: greater than
- operator<= - comparison: less than or equal
- operator>= - comparison: greater than or equal
- operator<=> - comparison: 3-way
Serialization / Dumping
- dump - serialization
Deserialization / Parsing
- parse (static) - deserialize from a compatible input
- accept (static) - check if the input is valid JSON
- sax_parse (static) - generate SAX events
JSON Pointer functions
JSON Patch functions
- patch - applies a JSON patch
- patch_inplace - applies a JSON patch in place
- diff (static) - creates a diff as a JSON patch
JSON Merge Patch functions
- merge_patch - applies a JSON Merge Patch
Static functions
- meta - returns version information on the library
- get_allocator - returns the allocator associated with the container
Binary formats
- from_bjdata (static) - create a JSON value from an input in BJData format
- from_bon8 (static) - create a JSON value from an input in BON8 format
- from_bson (static) - create a JSON value from an input in BSON format
- from_cbor (static) - create a JSON value from an input in CBOR format
- from_msgpack (static) - create a JSON value from an input in MessagePack format
- from_ubjson (static) - create a JSON value from an input in UBJSON format
- to_bjdata (static) - create a BJData serialization of a given JSON value
- to_bon8 (static) - create a BON8 serialization of a given JSON value
- to_bson (static) - create a BSON serialization of a given JSON value
- to_cbor (static) - create a CBOR serialization of a given JSON value
- to_msgpack (static) - create a MessagePack serialization of a given JSON value
- to_ubjson (static) - create a UBJSON serialization of a given JSON value
Non-member functions
- operator<<(std::ostream&) - serialize to stream
- operator>>(std::istream&) - deserialize from stream
- to_string - user-defined
to_stringfunction for JSON values - format_as - user-defined
format_asfunction for JSON values (fmt support)
Literals
- operator""_json - user-defined string literal for JSON values
Helper classes
- std::formatter<basic_json> - make JSON values formattable with
std::format - std::hash<basic_json> - return a hash value for a JSON object
- std::swap<basic_json> - exchanges the values of two JSON objects
Examples
??? example
The example shows how the library is used.
```cpp
--8<-- "examples/README.cpp"
```
Output:
```json
--8<-- "examples/README.output"
```
See also
Version history
- Added in version 1.0.0.