mirror of
https://github.com/nlohmann/json.git
synced 2026-10-03 21:20:30 +00:00
deploy: 63c10a51fc
This commit is contained in:
File diff suppressed because one or more lines are too long
@@ -67,14 +67,29 @@ Positive integers are stored as `#!c std::uint64_t`, while negative integers are
|
||||
distinction is determined at parse time: if the JSON number has a leading minus sign, it uses signed integer storage;
|
||||
otherwise, it uses unsigned integer storage.
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
A["number literal"] --> B{"has a fraction (.) or exponent (e/E)?"}
|
||||
B -->|"yes"| F["number_float_t"]
|
||||
B -->|"no"| C{"has a leading minus sign?"}
|
||||
C -->|"yes"| D["try number_integer_t"]
|
||||
C -->|"no"| E["try number_unsigned_t"]
|
||||
D -->|"overflow"| F
|
||||
E -->|"overflow"| F
|
||||
```
|
||||
|
||||
!!! info "Notes"
|
||||
|
||||
- Numbers with a decimal digit or scientific notation are always stored as `#!c double`.
|
||||
- The number types can be changed, see [Template number types](#template-number-types).
|
||||
- As of version 3.9.1, the conversion is realized by
|
||||
- Integers are converted by the library's own digit parser. Floating-point numbers are converted with
|
||||
[`std::from_chars`](https://en.cppreference.com/w/cpp/utility/from_chars) if the library is compiled with C++17
|
||||
and the standard library supports it, then with an exact fast path for `#!c double` values with few significant
|
||||
digits, and otherwise with the locale-aware
|
||||
[`std::strtod`](https://en.cppreference.com/w/cpp/string/byte/strtof) (`std::strtof`/`std::strtold` for the
|
||||
other floating-point types). Before version 3.13.0, the conversion was realized by
|
||||
[`std::strtoull`](https://en.cppreference.com/w/cpp/string/byte/strtoul),
|
||||
[`std::strtoll`](https://en.cppreference.com/w/cpp/string/byte/strtol), and
|
||||
[`std::strtod`](https://en.cppreference.com/w/cpp/string/byte/strtof), respectively.
|
||||
[`std::strtoll`](https://en.cppreference.com/w/cpp/string/byte/strtol), and `std::strtod`, respectively.
|
||||
|
||||
!!! example "Examples"
|
||||
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -40,11 +40,22 @@ In the default [`json`](https://json.nlohmann.me/api/json/index.md) type, number
|
||||
|
||||
Positive integers are stored as `std::uint64_t`, while negative integers are stored as `std::int64_t`. This distinction is determined at parse time: if the JSON number has a leading minus sign, it uses signed integer storage; otherwise, it uses unsigned integer storage.
|
||||
|
||||
```
|
||||
flowchart TD
|
||||
A["number literal"] --> B{"has a fraction (.) or exponent (e/E)?"}
|
||||
B -->|"yes"| F["number_float_t"]
|
||||
B -->|"no"| C{"has a leading minus sign?"}
|
||||
C -->|"yes"| D["try number_integer_t"]
|
||||
C -->|"no"| E["try number_unsigned_t"]
|
||||
D -->|"overflow"| F
|
||||
E -->|"overflow"| F
|
||||
```
|
||||
|
||||
Notes
|
||||
|
||||
- Numbers with a decimal digit or scientific notation are always stored as `double`.
|
||||
- The number types can be changed, see [Template number types](#template-number-types).
|
||||
- As of version 3.9.1, the conversion is realized by [`std::strtoull`](https://en.cppreference.com/w/cpp/string/byte/strtoul), [`std::strtoll`](https://en.cppreference.com/w/cpp/string/byte/strtol), and [`std::strtod`](https://en.cppreference.com/w/cpp/string/byte/strtof), respectively.
|
||||
- Integers are converted by the library's own digit parser. Floating-point numbers are converted with [`std::from_chars`](https://en.cppreference.com/w/cpp/utility/from_chars) if the library is compiled with C++17 and the standard library supports it, then with an exact fast path for `double` values with few significant digits, and otherwise with the locale-aware [`std::strtod`](https://en.cppreference.com/w/cpp/string/byte/strtof) (`std::strtof`/`std::strtold` for the other floating-point types). Before version 3.13.0 unreleased, the conversion was realized by [`std::strtoull`](https://en.cppreference.com/w/cpp/string/byte/strtoul), [`std::strtoll`](https://en.cppreference.com/w/cpp/string/byte/strtol), and `std::strtod`, respectively.
|
||||
|
||||
Examples
|
||||
|
||||
|
||||
@@ -26,8 +26,9 @@ Requirements are split into two groups:
|
||||
diagnosed with dedicated error messages, and violating most of them results in a compiler error somewhere inside
|
||||
the library. Four violations are not caught at compile time at all:
|
||||
|
||||
- A [`StringType`](#stringtype) whose `data()` is not null-terminated compiles and silently misparses numbers,
|
||||
because the lexer hands the buffer to `#!cpp std::strtoull`/`#!cpp std::strtoll`/`#!cpp std::strtod`.
|
||||
- A [`StringType`](#stringtype) whose `data()` is not null-terminated compiles and can silently misparse
|
||||
floating-point numbers, because the lexer may hand the buffer to `#!cpp std::strtod`, which reads up to the
|
||||
terminating null character.
|
||||
- A stateful [`AllocatorType`](#allocatortype) compiles and silently ignores its state: allocation, deallocation,
|
||||
and [`get_allocator()`](../../api/basic_json/get_allocator.md) each use a different default-constructed instance.
|
||||
- The two [cross-specialization conversions](#cross-specialization-conversions) below. These abort on an assertion
|
||||
@@ -213,7 +214,7 @@ The library does not sort or de-duplicate keys itself; the behavior described in
|
||||
--8<-- "examples/custom_object_type.hpp"
|
||||
```
|
||||
|
||||
??? example "Compiling and using it"
|
||||
??? example "Example: use the custom `ObjectType`"
|
||||
|
||||
```cpp
|
||||
--8<-- "examples/custom_object_type.cpp"
|
||||
@@ -306,7 +307,7 @@ using array_t = ArrayType<basic_json, AllocatorType<basic_json>>;
|
||||
--8<-- "examples/custom_array_type.hpp"
|
||||
```
|
||||
|
||||
??? example "Compiling and using it"
|
||||
??? example "Example: use the custom `ArrayType`"
|
||||
|
||||
```cpp
|
||||
--8<-- "examples/custom_array_type.cpp"
|
||||
@@ -348,16 +349,16 @@ using array_t = ArrayType<basic_json, AllocatorType<basic_json>>;
|
||||
### Always required
|
||||
|
||||
- A member type `value_type` that is one byte wide and `char`-compatible. The library stores and processes UTF-8
|
||||
encoded `char` data and hands `data()` to `#!cpp std::strtoull`/`#!cpp std::strtoll`.
|
||||
encoded `char` data and passes `data()` to functions that take a `#!cpp const char*`, such as `#!cpp std::strtod`.
|
||||
`#!cpp std::wstring`, `#!cpp std::u16string`, and `#!cpp std::u32string` are **not** valid choices; see the FAQ on
|
||||
[wide string handling](../../home/faq.md#wide-string-handling).
|
||||
- Constructors: default, copy, move, from `#!cpp const char*` (which must not be `#!cpp explicit`), from
|
||||
`#!cpp (const char*, size_type)`, and from `#!cpp (size_type, char)`; and copy or move assignment.
|
||||
- Member functions `size()`, `clear()`, `resize(n, c)`, `data()`, `push_back(char)`, and `operator[]`
|
||||
(const and non-const, returning references). `c_str()` and `back()` are **not** required.
|
||||
- `data()` must return a pointer to a contiguous, **null-terminated** buffer -- the parser hands it to
|
||||
`#!cpp std::strtoull`. A type whose `data()` is not null-terminated does not fail to compile; it silently
|
||||
misparses numbers.
|
||||
- `data()` must return a pointer to a contiguous, **null-terminated** buffer -- the parser may hand it to
|
||||
`#!cpp std::strtod`, which reads up to the null character. A type whose `data()` is not null-terminated does not
|
||||
fail to compile; it can silently misparse floating-point numbers.
|
||||
- `append(const char*, size_type)`, used by [`dump`](../../api/basic_json/dump.md), and `append(const StringType&)`,
|
||||
used by the CBOR reader for indefinite-length strings. The library's internal string concatenation additionally has
|
||||
to append a `#!cpp char` and a `#!cpp const char*`; for each it selects between `append(arg)`, `#!cpp operator+=`,
|
||||
@@ -394,6 +395,7 @@ using array_t = ArrayType<basic_json, AllocatorType<basic_json>>;
|
||||
| [`to_bson`](../../api/basic_json/to_bson.md) | `find(value_type)` and `npos` |
|
||||
| [`parse`](../../api/basic_json/parse.md) from a `string_t` | the input adapters must accept it; otherwise pass a character range |
|
||||
| `#!cpp operator<<(std::ostream&, const json_pointer&)` | streamability to `#!cpp std::ostream` |
|
||||
| [`to_string`](../../api/basic_json/to_string.md) | conversion of `StringType` to `#!cpp std::string` (the function returns a `#!cpp std::string`) |
|
||||
| exception messages | `data()` and `size()`, or `begin()` and `end()` |
|
||||
|
||||
### Compatible types
|
||||
@@ -448,7 +450,7 @@ using array_t = ArrayType<basic_json, AllocatorType<basic_json>>;
|
||||
--8<-- "examples/custom_string_type.hpp"
|
||||
```
|
||||
|
||||
??? example "Compiling and using it"
|
||||
??? example "Example: use the custom `StringType`"
|
||||
|
||||
```cpp
|
||||
--8<-- "examples/custom_string_type.cpp"
|
||||
@@ -535,8 +537,9 @@ therefore silently changes parse results rather than raising an error. See
|
||||
|
||||
`NumberFloatType` must be one of `#!cpp float`, `#!cpp double`, or `#!cpp long double`:
|
||||
|
||||
- The [parser](../parsing/index.md) converts number literals with `#!cpp std::strtof`, `#!cpp std::strtod`, or
|
||||
`#!cpp std::strtold`; the library provides overloads for exactly these three types.
|
||||
- The [parser](../parsing/index.md) converts number literals with `#!cpp std::from_chars` or, as a fallback, with
|
||||
`#!cpp std::strtof`, `#!cpp std::strtod`, or `#!cpp std::strtold`; the library provides overloads for exactly these
|
||||
three types.
|
||||
- [`dump`](../../api/basic_json/dump.md) falls back to `#!cpp std::snprintf` with the `%g` and `%Lg` conversion
|
||||
specifiers, for which the library likewise provides only `#!cpp double` and `#!cpp long double` overloads
|
||||
(`#!cpp float` is promoted to `#!cpp double`).
|
||||
@@ -669,7 +672,7 @@ such a container to a `basic_json` value.
|
||||
--8<-- "examples/custom_binary_type.hpp"
|
||||
```
|
||||
|
||||
??? example "Compiling and using it"
|
||||
??? example "Example: use the custom `BinaryType`"
|
||||
|
||||
```cpp
|
||||
--8<-- "examples/custom_binary_type.cpp"
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -13,7 +13,7 @@ Requirements are not checked
|
||||
|
||||
Three requirements are checked with a `static_assert`: the array iterator category, the width of [`BinaryType`](#binarytype)'s `value_type`, and [`NumberUnsignedType`](#numberintegertype-and-numberunsignedtype) being at least as wide as [`NumberIntegerType`](#numberintegertype-and-numberunsignedtype). The rest are not diagnosed with dedicated error messages, and violating most of them results in a compiler error somewhere inside the library. Four violations are not caught at compile time at all:
|
||||
|
||||
- A [`StringType`](#stringtype) whose `data()` is not null-terminated compiles and silently misparses numbers, because the lexer hands the buffer to `std::strtoull`/`std::strtoll`/`std::strtod`.
|
||||
- A [`StringType`](#stringtype) whose `data()` is not null-terminated compiles and can silently misparse floating-point numbers, because the lexer may hand the buffer to `std::strtod`, which reads up to the terminating null character.
|
||||
- A stateful [`AllocatorType`](#allocatortype) compiles and silently ignores its state: allocation, deallocation, and [`get_allocator()`](https://json.nlohmann.me/api/basic_json/get_allocator/index.md) each use a different default-constructed instance.
|
||||
- The two [cross-specialization conversions](#cross-specialization-conversions) below. These abort on an assertion in a normal build, and only fail silently under `NDEBUG`.
|
||||
|
||||
@@ -287,7 +287,7 @@ class custom_object_type
|
||||
};
|
||||
```
|
||||
|
||||
Compiling and using it
|
||||
Example: use the custom `ObjectType`
|
||||
|
||||
```
|
||||
#include <iostream>
|
||||
@@ -549,7 +549,7 @@ class custom_array_type
|
||||
};
|
||||
```
|
||||
|
||||
Compiling and using it
|
||||
Example: use the custom `ArrayType`
|
||||
|
||||
```
|
||||
#include <iostream>
|
||||
@@ -608,10 +608,10 @@ true
|
||||
|
||||
### Always required
|
||||
|
||||
- A member type `value_type` that is one byte wide and `char`-compatible. The library stores and processes UTF-8 encoded `char` data and hands `data()` to `std::strtoull`/`std::strtoll`. `std::wstring`, `std::u16string`, and `std::u32string` are **not** valid choices; see the FAQ on [wide string handling](https://json.nlohmann.me/home/faq/#wide-string-handling).
|
||||
- A member type `value_type` that is one byte wide and `char`-compatible. The library stores and processes UTF-8 encoded `char` data and passes `data()` to functions that take a `const char*`, such as `std::strtod`. `std::wstring`, `std::u16string`, and `std::u32string` are **not** valid choices; see the FAQ on [wide string handling](https://json.nlohmann.me/home/faq/#wide-string-handling).
|
||||
- Constructors: default, copy, move, from `const char*` (which must not be `explicit`), from `(const char*, size_type)`, and from `(size_type, char)`; and copy or move assignment.
|
||||
- Member functions `size()`, `clear()`, `resize(n, c)`, `data()`, `push_back(char)`, and `operator[]` (const and non-const, returning references). `c_str()` and `back()` are **not** required.
|
||||
- `data()` must return a pointer to a contiguous, **null-terminated** buffer -- the parser hands it to `std::strtoull`. A type whose `data()` is not null-terminated does not fail to compile; it silently misparses numbers.
|
||||
- `data()` must return a pointer to a contiguous, **null-terminated** buffer -- the parser may hand it to `std::strtod`, which reads up to the null character. A type whose `data()` is not null-terminated does not fail to compile; it can silently misparse floating-point numbers.
|
||||
- `append(const char*, size_type)`, used by [`dump`](https://json.nlohmann.me/api/basic_json/dump/index.md), and `append(const StringType&)`, used by the CBOR reader for indefinite-length strings. The library's internal string concatenation additionally has to append a `char` and a `const char*`; for each it selects between `append(arg)`, `operator+=`, `append(first, last)`, and `append(data, size)`.
|
||||
- The comparison operator `==` against another `StringType`, and `<` for use as a key of the chosen [`ObjectType`](#objecttype) (with the default comparator, `std::less<>` must be able to compare two `StringType` values, and a `StringType` with the key types used for lookup). `!=` is never applied to a `StringType`, and `==` against `const char*` is resolved by the implicit `const char*` constructor.
|
||||
|
||||
@@ -636,6 +636,7 @@ true
|
||||
| [`to_bson`](https://json.nlohmann.me/api/basic_json/to_bson/index.md) | `find(value_type)` and `npos` |
|
||||
| [`parse`](https://json.nlohmann.me/api/basic_json/parse/index.md) from a `string_t` | the input adapters must accept it; otherwise pass a character range |
|
||||
| `operator<<(std::ostream&, const json_pointer&)` | streamability to `std::ostream` |
|
||||
| [`to_string`](https://json.nlohmann.me/api/basic_json/to_string/index.md) | conversion of `StringType` to `std::string` (the function returns a `std::string`) |
|
||||
| exception messages | `data()` and `size()`, or `begin()` and `end()` |
|
||||
|
||||
### Compatible types
|
||||
@@ -677,6 +678,7 @@ Reference implementation
|
||||
```
|
||||
#pragma once
|
||||
|
||||
#include <cstddef>
|
||||
#include <ostream>
|
||||
#include <string>
|
||||
|
||||
@@ -685,10 +687,10 @@ Reference implementation
|
||||
// and nothing more of std::string's interface.
|
||||
//
|
||||
// Covers the "Always required" members, the extras needed for the binary
|
||||
// formats, and the extras needed for JSON Pointer / flatten / unflatten /
|
||||
// diff. Extending it further (e.g. for std::hash<basic_json> or to_bson) is
|
||||
// a matter of adding the extra members listed in the "Required for other
|
||||
// functionality" table.
|
||||
// formats, JSON Pointer / flatten / unflatten, and the int_to_string overload
|
||||
// needed for diff and items. Extending it further (e.g. for
|
||||
// std::hash<basic_json> or to_bson) is a matter of adding the extra members
|
||||
// listed in the "Required for other functionality" table.
|
||||
//
|
||||
// See https://json.nlohmann.me/features/types/template_parameters/#stringtype
|
||||
class custom_string_type
|
||||
@@ -770,6 +772,11 @@ class custom_string_type
|
||||
data_.append(other.data_);
|
||||
return *this;
|
||||
}
|
||||
custom_string_type& operator+=(char c)
|
||||
{
|
||||
data_.push_back(c);
|
||||
return *this;
|
||||
}
|
||||
|
||||
size_type find_first_of(char c, size_type pos = 0) const
|
||||
{
|
||||
@@ -793,6 +800,12 @@ class custom_string_type
|
||||
return data_.end();
|
||||
}
|
||||
|
||||
// found by ADL; converts array indices to keys in diff and items
|
||||
friend void int_to_string(custom_string_type& target, std::size_t value)
|
||||
{
|
||||
target.data_ = std::to_string(value);
|
||||
}
|
||||
|
||||
friend bool operator==(const custom_string_type& lhs, const custom_string_type& rhs)
|
||||
{
|
||||
return lhs.data_ == rhs.data_;
|
||||
@@ -811,7 +824,7 @@ class custom_string_type
|
||||
};
|
||||
```
|
||||
|
||||
Compiling and using it
|
||||
Example: use the custom `StringType`
|
||||
|
||||
```
|
||||
#include <iostream>
|
||||
@@ -909,7 +922,7 @@ The number types influence what the parser accepts: an integer literal that does
|
||||
|
||||
`NumberFloatType` must be one of `float`, `double`, or `long double`:
|
||||
|
||||
- The [parser](https://json.nlohmann.me/features/parsing/index.md) converts number literals with `std::strtof`, `std::strtod`, or `std::strtold`; the library provides overloads for exactly these three types.
|
||||
- The [parser](https://json.nlohmann.me/features/parsing/index.md) converts number literals with `std::from_chars` or, as a fallback, with `std::strtof`, `std::strtod`, or `std::strtold`; the library provides overloads for exactly these three types.
|
||||
- [`dump`](https://json.nlohmann.me/api/basic_json/dump/index.md) falls back to `std::snprintf` with the `%g` and `%Lg` conversion specifiers, for which the library likewise provides only `double` and `long double` overloads (`float` is promoted to `double`).
|
||||
|
||||
If `std::numeric_limits<NumberFloatType>` describes an IEEE 754 binary32 or binary64 number, `dump` uses the Grisu2 algorithm, which produces the shortest representation that round-trips. Otherwise the `snprintf` fallback with `max_digits10` digits is used.
|
||||
@@ -1112,7 +1125,7 @@ class custom_binary_type
|
||||
};
|
||||
```
|
||||
|
||||
Compiling and using it
|
||||
Example: use the custom `BinaryType`
|
||||
|
||||
```
|
||||
#include <cstdint>
|
||||
|
||||
Reference in New Issue
Block a user