json/doc/mkdocs/docs/api/basic_json/basic_json.md

395 lines
14 KiB
Markdown
Raw Normal View History

2020-08-12 19:41:59 +08:00
# basic_json::basic_json
```cpp
// 1
basic_json(const value_t v);
// 2
basic_json(std::nullptr_t = nullptr) noexcept;
// 3
template<typename CompatibleType>
basic_json(CompatibleType&& val) noexcept(noexcept(
JSONSerializer<U>::to_json(std::declval<basic_json_t&>(),
std::forward<CompatibleType>(val))));
// 4
template<typename BasicJsonType>
basic_json(const BasicJsonType& val);
// 5
basic_json(initializer_list_t init,
bool type_deduction = true,
value_t manual_type = value_t::array);
// 6
basic_json(size_type cnt, const basic_json& val);
// 7
basic_json(iterator first, iterator last);
basic_json(const_iterator first, const_iterator last);
// 8
basic_json(const basic_json& other);
// 9
basic_json(basic_json&& other) noexcept;
```
1. Create an empty JSON value with a given type. The value will be default initialized with an empty value which depends
on the type:
Value type | initial value
----------- | -------------
null | `#!json null`
boolean | `#!json false`
string | `#!json ""`
number | `#!json 0`
object | `#!json {}`
array | `#!json []`
binary | empty array
2. Create a `#!json null` JSON value. It either takes a null pointer as parameter (explicitly creating `#!json null`)
or no parameter (implicitly creating `#!json null`). The passed null pointer itself is not read -- it is only used to
choose the right constructor.
3. This is a "catch all" constructor for all compatible JSON types; that is, types for which a `to_json()` method
exists. The constructor forwards the parameter `val` to that method (to `json_serializer<U>::to_json` method with
`U = uncvref_t<CompatibleType>`, to be exact).
Template type `CompatibleType` includes, but is not limited to, the following types:
- **arrays**: [`array_t`](array_t.md) and all kinds of compatible containers such as `std::vector`, `std::deque`,
`std::list`, `std::forward_list`, `std::array`, `std::valarray`, `std::set`, `std::unordered_set`, `std::multiset`,
and `std::unordered_multiset` with a `value_type` from which a `basic_json` value can be constructed.
- **objects**: [`object_t`](object_t.md) and all kinds of compatible associative containers such as `std::map`,
`std::unordered_map`, `std::multimap`, and `std::unordered_multimap` with a `key_type` compatible to `string_t`
and a `value_type` from which a `basic_json` value can be constructed.
- **strings**: `string_t`, string literals, and all compatible string containers can be used.
- **numbers**: [`number_integer_t`](number_integer_t.md), [`number_unsigned_t`](number_unsigned_t.md),
[`number_float_t`](number_float_t.md), and all convertible number types such as `int`, `size_t`, `int64_t`, `float`
or `double` can be used.
- **boolean**: `boolean_t` / `bool` can be used.
- **binary**: `binary_t` / `std::vector<uint8_t>` may be used; unfortunately because string literals cannot be
distinguished from binary character arrays by the C++ type system, all types compatible with `const char*` will be
directed to the string constructor instead. This is both for backwards compatibility, and due to the fact that a
binary type is not a standard JSON type.
See the examples below.
4. This is a constructor for existing `basic_json` types. It does not hijack copy/move constructors, since the parameter
has different template arguments than the current ones.
The constructor tries to convert the internal `m_value` of the parameter.
5. Creates a JSON value of type array or object from the passed initializer list `init`. In case `type_deduction` is
`#!cpp true` (default), the type of the JSON value to be created is deducted from the initializer list `init`
according to the following rules:
1. If the list is empty, an empty JSON object value `{}` is created.
2. If the list consists of pairs whose first element is a string, a JSON object value is created where the first
elements of the pairs are treated as keys and the second elements are as values.
3. In all other cases, an array is created.
The rules aim to create the best fit between a C++ initializer list and JSON values. The rationale is as follows:
1. The empty initializer list is written as `#!cpp {}` which is exactly an empty JSON object.
2. C++ has no way of describing mapped types other than to list a list of pairs. As JSON requires that keys must be
of type string, rule 2 is the weakest constraint one can pose on initializer lists to interpret them as an
object.
3. In all other cases, the initializer list could not be interpreted as JSON object type, so interpreting it as JSON
array type is safe.
With the rules described above, the following JSON values cannot be expressed by an initializer list:
- the empty array (`#!json []`): use `array(initializer_list_t)` with an empty initializer list in this case
- arrays whose elements satisfy rule 2: use `array(initializer_list_t)` with the same initializer list in this case
6. Constructs a JSON array value by creating `cnt` copies of a passed value. In case `cnt` is `0`, an empty array is
created.
7. Constructs the JSON value with the contents of the range `[first, last)`. The semantics depends on the different
types a JSON value can have:
- In case of a `#!json null` type, [invalid_iterator.206](../../home/exceptions.md#jsonexceptioninvalid_iterator206)
is thrown.
- In case of other primitive types (number, boolean, or string), `first` must be `begin()` and `last` must be
`end()`. In this case, the value is copied. Otherwise,
[`invalid_iterator.204`](../../home/exceptions.md#jsonexceptioninvalid_iterator204) is thrown.
- In case of structured types (array, object), the constructor behaves as similar versions for `std::vector` or
`std::map`; that is, a JSON array or object is constructed from the values in the range.
8. Creates a copy of a given JSON value.
9. Move constructor. Constructs a JSON value with the contents of the given value `other` using move semantics. It
"steals" the resources from `other` and leaves it as JSON `#!json null` value.
## Template parameters
`CompatibleType`
: a type such that:
- `CompatibleType` is not derived from `std::istream`,
- `CompatibleType` is not `basic_json` (to avoid hijacking copy/move constructors),
- `CompatibleType` is not a different `basic_json` type (i.e. with different template arguments)
- `CompatibleType` is not a `basic_json` nested type (e.g., `json_pointer`, `iterator`, etc.)
- `json_serializer<U>` (with `U = uncvref_t<CompatibleType>`) has a `to_json(basic_json_t&, CompatibleType&&)`
method
`BasicJsonType`:
: a type such that:
- `BasicJsonType` is a `basic_json` type.
- `BasicJsonType` has different template arguments than `basic_json_t`.
## Parameters
`v` (in)
: the type of the value to create
`val` (in)
: the value to be forwarded to the respective constructor
`init` (in)
: initializer list with JSON values
`type_deduction` (in)
: internal parameter; when set to `#!cpp true`, the type of the JSON value is deducted from the initializer list
`init`; when set to `#!cpp false`, the type provided via `manual_type` is forced. This mode is used by the functions
`array(initializer_list_t)` and `object(initializer_list_t)`.
`manual_type` (in)
: internal parameter; when `type_deduction` is set to `#!cpp false`, the created JSON value will use the provided type
(only `value_t::array` and `value_t::object` are valid); when `type_deduction` is set to `#!cpp true`, this
parameter has no effect
`cnt` (in)
: the number of JSON copies of `val` to create
`first` (in)
: begin of the range to copy from (included)
`last` (in)
: end of the range to copy from (excluded)
`other` (in)
: the JSON value to copy/move
## Exceptions
1. /
2. The function does not throw exceptions.
3. /
4. /
5. The function can throw the following exceptions:
- Throws [`type_error.301`](../../home/exceptions.md#jsonexceptiontype_error301) if `type_deduction` is
`#!cpp false`, `manual_type` is `value_t::object`, but `init` contains an element which is not a pair whose first
element is a string. In this case, the constructor could not create an object. If `type_deduction` would have been
`#!cpp true`, an array would have been created. See `object(initializer_list_t)` for an example.
6. /
7. The function can throw the following exceptions:
- Throws [`invalid_iterator.201`](../../home/exceptions.md#jsonexceptioninvalid_iterator201) if iterators `first`
and `last` are not compatible (i.e., do not belong to the same JSON value). In this case, the range
`[first, last)` is undefined.
- Throws [`invalid_iterator.204`](../../home/exceptions.md#jsonexceptioninvalid_iterator204) if iterators `first`
and `last` belong to a primitive type (number, boolean, or string), but `first` does not point to the first
element any more. In this case, the range `[first, last)` is undefined. See example code below.
- Throws [`invalid_iterator.206`](../../home/exceptions.md#jsonexceptioninvalid_iterator206) if iterators `first`
and `last` belong to a `#!json null` value. In this case, the range `[first, last)` is undefined.
8. /
9. The function does not throw exceptions.
## Exception safety
1. Strong guarantee: if an exception is thrown, there are no changes to any JSON value.
2. No-throw guarantee: this constructor never throws exceptions.
3. Depends on the called constructor. For types directly supported by the library (i.e., all types for which no
`to_json()` function was provided), strong guarantee holds: if an exception is thrown, there are no changes to any
JSON value.
4. Depends on the called constructor. For types directly supported by the library (i.e., all types for which no
`to_json()` function was provided), strong guarantee holds: if an exception is thrown, there are no changes to any
JSON value.
5. Strong guarantee: if an exception is thrown, there are no changes to any JSON value.
6. Strong guarantee: if an exception is thrown, there are no changes to any JSON value.
7. Strong guarantee: if an exception is thrown, there are no changes to any JSON value.
8. Strong guarantee: if an exception is thrown, there are no changes to any JSON value.
9. No-throw guarantee: this constructor never throws exceptions.
## Complexity
1. Constant.
2. Constant.
3. Usually linear in the size of the passed `val`, also depending on the implementation of the called `to_json()`
method.
4. Usually linear in the size of the passed `val`, also depending on the implementation of the called `to_json()`
method.
5. Linear in the size of the initializer list `init`.
6. Linear in `cnt`.
7. Linear in distance between `first` and `last`.
8. Linear in the size of `other`.
9. Constant.
## Notes
- Overload 5:
!!! note
When used without parentheses around an empty initializer list, `basic_json()` is called instead of this
function, yielding the JSON `#!json null` value.
- Overload 7:
!!! info "Preconditions"
- Iterators `first` and `last` must be initialized. **This precondition is enforced with an assertion (see
warning).** If assertions are switched off, a violation of this precondition yields undefined behavior.
- Range `[first, last)` is valid. Usually, this precondition cannot be checked efficiently. Only certain edge
cases are detected; see the description of the exceptions above. A violation of this precondition yields
undefined behavior.
!!! warning
A precondition is enforced with a runtime assertion that will result in calling `std::abort` if this
precondition is not met. Assertions can be disabled by defining `NDEBUG` at compile time. See
<https://en.cppreference.com/w/cpp/error/assert> for more information.
- Overload 8:
!!! info "Postcondition"
`#!cpp *this == other`
- Overload 9:
!!! info "Postconditions"
- `#!cpp `*this` has the same value as `other` before the call.
- `other` is a JSON `#!json null` value
## Example
??? example
The following code shows the constructor for different `value_t` values.
```cpp
--8<-- "examples/basic_json__value_t.cpp"
```
Output:
```json
--8<-- "examples/basic_json__value_t.output"
```
??? example
The following code shows the constructor with and without a null pointer parameter.
```cpp
--8<-- "examples/basic_json__nullptr_t.cpp"
```
Output:
```json
--8<-- "examples/basic_json__nullptr_t.output"
```
??? example
The following code shows the constructor with several compatible types.
```cpp
--8<-- "examples/basic_json__CompatibleType.cpp"
```
Output:
```json
--8<-- "examples/basic_json__CompatibleType.output"
```
??? example
The example below shows how JSON values are created from initializer lists.
```cpp
--8<-- "examples/basic_json__list_init_t.cpp"
```
Output:
```json
--8<-- "examples/basic_json__list_init_t.output"
```
??? example
The following code shows examples for creating arrays with several copies of a given value.
```cpp
--8<-- "examples/basic_json__size_type_basic_json.cpp"
```
Output:
```json
--8<-- "examples/basic_json__size_type_basic_json.output"
```
??? example
The example below shows several ways to create JSON values by specifying a subrange with iterators.
```cpp
--8<-- "examples/basic_json__InputIt_InputIt.cpp"
```
Output:
```json
--8<-- "examples/basic_json__InputIt_InputIt.output"
```
??? example
The following code shows an example for the copy constructor.
```cpp
--8<-- "examples/basic_json__basic_json.cpp"
```
Output:
```json
--8<-- "examples/basic_json__basic_json.output"
```
??? example
The code below shows the move constructor explicitly called via `std::move`.
```cpp
--8<-- "examples/basic_json__moveconstructor.cpp"
```
Output:
```json
--8<-- "examples/basic_json__moveconstructor.output"
```
## Version history
1. Since version 1.0.0.
2. Since version 1.0.0.
3. Since version 2.1.0.
4. Since version 3.2.0.
5. Since version 1.0.0.
6. Since version 1.0.0.
7. Since version 1.0.0.
8. Since version 1.0.0.
9. Since version 1.0.0.