mirror of
https://github.com/boostorg/json.git
synced 2026-01-28 07:12:20 +00:00
273 lines
8.1 KiB
Plaintext
273 lines
8.1 KiB
Plaintext
////
|
|
Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com)
|
|
Copyright (c) 2025 Dmitry Arkhipov (grisumbras@yandex.ru)
|
|
|
|
Distributed under the Boost Software License, Version 1.0. (See accompanying
|
|
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
|
|
|
Official repository: https://github.com/boostorg/json
|
|
////
|
|
|
|
[#dom_value]
|
|
= `value`
|
|
JSON documents are represented in memory as instances of <<ref_value>>: a
|
|
{req_Regular} type which satisfies {req_DefaultConstructible},
|
|
{req_CopyConstructible}, {req_CopyAssignable}, {req_MoveConstructible},
|
|
{req_MoveAssignable}, and many of the requirements of allocator-aware
|
|
containers. It is implemented as a
|
|
https://en.wikipedia.org/wiki/Tagged_union[__variant__] internally, and can
|
|
dynamically store any of the six defined JSON value types:
|
|
|
|
* **null**: A
|
|
https://en.cppreference.com/w/cpp/utility/variant/monostate[__monostate__]
|
|
value, equivalent to `nullptr`.
|
|
|
|
* **boolean**: A boolean: either `true` or `false`.
|
|
|
|
* **number**: An integral or floating point value.
|
|
|
|
* **string**: A sequence of zero or more Unicode characters,
|
|
similar to {std_string}.
|
|
|
|
* **array**: An ordered list of values, like {std_vector}.
|
|
|
|
* **object**: A collection of name/value pairs, also known as an
|
|
https://en.wikipedia.org/wiki/Associative_array[__associative array__].
|
|
|
|
== Working With Values
|
|
A <<ref_value>> constructed from `nullptr` or default constructed represents
|
|
a null JSON element:
|
|
|
|
[source]
|
|
----
|
|
include::../../../test/snippets.cpp[tag=snippet_value_1,indent=0]
|
|
----
|
|
|
|
The member function <<ref_value_kind,`value::kind`>> may be used to query the
|
|
kind stored in the value. Alternatively, member functions like
|
|
<<ref_value_is_object,`value::is_object`>>
|
|
<<ref_value_is_number,`value::is_number`>> may be used to check whether or not
|
|
the value is a particular kind:
|
|
|
|
[source]
|
|
----
|
|
include::../../../test/snippets.cpp[tag=snippet_value_2,indent=0]
|
|
----
|
|
|
|
Functions like <<ref_value_if_object,`value::if_object`>> actually return
|
|
a pointer to the object if the value is an object, otherwise they return null.
|
|
This allows them to be used both in boolean contexts as above, and in
|
|
assignments or conditional expressions to capture the value of the pointer:
|
|
|
|
[source]
|
|
----
|
|
include::../../../test/snippets.cpp[tag=snippet_value_3,indent=0]
|
|
----
|
|
|
|
After a <<ref_value>> is constructed, its kind can change depending on what is
|
|
assigned to it, or by calling functions such as
|
|
<<ref_value_emplace_array,`value::emplace_array`>> or
|
|
<<ref_value_emplace_bool,`value::emplace_bool`>>. If the assignment is
|
|
successful, in other words it completes without any exceptions then the value
|
|
is replaced. Otherwise, the value is unchanged. All operations which can fail
|
|
to modify a value offer the strong exception safety guarantee.
|
|
|
|
[source]
|
|
----
|
|
include::../../../test/snippets.cpp[tag=snippet_value_4,indent=0]
|
|
----
|
|
|
|
The following table shows all of the ways to determine and access the contents
|
|
of a <<ref_value>>:
|
|
|
|
.<<ref_value>> Accessors
|
|
[%autowidth,cols=8]
|
|
|===
|
|
|Kind
|
|
|Representation
|
|
|Emplacement
|
|
|Kind Test
|
|
|Pointer Access
|
|
|`result` Access
|
|
|Checked Access
|
|
|Unchecked Access
|
|
|
|
|<<ref_kind,`kind::array`>>
|
|
|<<ref_array>>
|
|
|<<ref_value_emplace_array>>
|
|
|<<ref_value_is_array>>
|
|
|<<ref_value_if_array>>
|
|
|<<ref_value_try_as_array>>
|
|
|<<ref_value_as_array>>
|
|
|<<ref_value_get_array>>
|
|
|
|
|<<ref_kind,`kind::object`>>
|
|
|<<ref_object>>
|
|
|<<ref_value_emplace_object>>
|
|
|<<ref_value_is_object>>
|
|
|<<ref_value_if_object>>
|
|
|<<ref_value_try_as_object>>
|
|
|<<ref_value_as_object>>
|
|
|<<ref_value_get_object>>
|
|
|
|
|<<ref_kind,`kind::string`>>
|
|
|<<ref_string>>
|
|
|<<ref_value_emplace_string>>
|
|
|<<ref_value_is_string>>
|
|
|<<ref_value_if_string>>
|
|
|<<ref_value_try_as_string>>
|
|
|<<ref_value_as_string>>
|
|
|<<ref_value_get_string>>
|
|
|
|
|<<ref_kind,`kind::int64`>>
|
|
|https://en.cppreference.com/w/cpp/types/integer[`std::int64_t`]
|
|
|<<ref_value_emplace_int64>>
|
|
|<<ref_value_is_int64>>
|
|
|<<ref_value_if_int64>>
|
|
|<<ref_value_try_as_int64>>
|
|
|<<ref_value_as_int64>>
|
|
|<<ref_value_get_int64>>
|
|
|
|
|<<ref_kind,`kind::uint64`>>
|
|
|https://en.cppreference.com/w/cpp/types/integer[`std::uint64_t`]
|
|
|<<ref_value_emplace_uint64>>
|
|
|<<ref_value_is_uint64>>
|
|
|<<ref_value_if_uint64>>
|
|
|<<ref_value_try_as_uint64>>
|
|
|<<ref_value_as_uint64>>
|
|
|<<ref_value_get_uint64>>
|
|
|
|
|<<ref_kind,`kind::double_`>>
|
|
|https://en.cppreference.com/w/cpp/language/types[`double`]
|
|
|<<ref_value_emplace_double>>
|
|
|<<ref_value_is_double>>
|
|
|<<ref_value_if_double>>
|
|
|<<ref_value_try_as_double>>
|
|
|<<ref_value_as_double>>
|
|
|<<ref_value_get_double>>
|
|
|
|
|<<ref_kind,`kind::bool_`>>
|
|
|https://en.cppreference.com/w/cpp/language/types[`bool`]
|
|
|<<ref_value_emplace_bool>>
|
|
|<<ref_value_is_bool>>
|
|
|<<ref_value_if_bool>>
|
|
|<<ref_value_try_as_bool>>
|
|
|<<ref_value_as_bool>>
|
|
|<<ref_value_get_bool>>
|
|
|
|
|<<ref_kind,`kind::null`>>
|
|
|https://en.cppreference.com/w/cpp/language/nullptr[`std::nullptr_t`]
|
|
|<<ref_value_emplace_null>>
|
|
|<<ref_value_is_null>>
|
|
^|—
|
|
|<<ref_value_try_as_null>>
|
|
^|—
|
|
^|—
|
|
|
|
|===
|
|
|
|
The emplace members of <<ref_value>> return a typed reference to the underlying
|
|
representation. For example, the call to
|
|
<<ref_value_emplace_string,`value::emplace_string`>> in the previous example
|
|
returns a <<ref_string,`string&`>>. This table shows the underlying type for
|
|
each kind:
|
|
|
|
|===
|
|
|Kind|Type|Description
|
|
|
|
| <<ref_kind,`kind::object`>>
|
|
| <<ref_object>>
|
|
| An associative array of string keys mapping to <<ref_value>> elements with an
|
|
interface similar to {std_unordered_map}, that remembers insertion order.
|
|
|
|
| <<ref_kind,`kind::array`>>
|
|
| <<ref_array>>
|
|
| An ordered list of <<ref_value>> elements with an interface similar to
|
|
{std_vector}.
|
|
|
|
| <<ref_kind,`kind::string`>>
|
|
| <<ref_string>>
|
|
| A https://en.wikipedia.org/wiki/UTF-8[__UTF-8__] encoded
|
|
https://en.wikipedia.org/wiki/Unicode[Unicode]
|
|
https://en.wikipedia.org/wiki/String_(computer_science)[string] of characters
|
|
with an interface similar to {std_string}.
|
|
|
|
| <<ref_kind,`kind::int64`>>
|
|
| `std::int64_t`
|
|
| A 64 bit signed integer.
|
|
|
|
| <<ref_kind,`kind::uint64`>>
|
|
| `std::uint64_t`
|
|
| A 64 bit unsigned integer.
|
|
|
|
| <<ref_kind,`kind::double_`>>
|
|
| `double`
|
|
| A `double` holding a floating-point value.
|
|
|
|
| <<ref_kind,`kind::bool_`>>
|
|
| https://en.cppreference.com/w/cpp/keyword/bool[`bool`]
|
|
| A `bool` holding `true` or `false`.
|
|
|
|
| <<ref_kind,`kind::null`>>
|
|
^| —
|
|
| A monostate value representing null.
|
|
|===
|
|
|
|
The return value from emplace can be used to perform assignment or to capture a
|
|
reference to the underlying element for later inspection or modification:
|
|
|
|
[source]
|
|
----
|
|
include::../../../test/snippets.cpp[tag=snippet_value_5,indent=0]
|
|
----
|
|
|
|
If the <<ref_kind>> of a <<ref_value>> is known, functions such as
|
|
<<ref_value_as_bool,`value::as_bool`>> or
|
|
<<ref_value_as_string,`value::as_string`>> may be used to obtain a reference to
|
|
the underlying representation without changing the existing value:
|
|
|
|
[source]
|
|
----
|
|
include::../../../test/snippets.cpp[tag=snippet_value_6,indent=0]
|
|
----
|
|
|
|
However, as shown above these functions throw an exception if the kind in the
|
|
<<ref_value>> does not match the kind denoted by the function signature. This
|
|
can be used as a concise form of validation: access values as if they were the
|
|
right type, but handle the resulting exception indicating if the schema of the
|
|
JSON is not valid.
|
|
|
|
We can query a value for its underlying representation of a particular kind in
|
|
a way that does not throw exceptions by requesting a pointer which may be null,
|
|
instead of a reference. Here we use <<ref_value_if_string,`value::if_string`>>
|
|
to conditionally perform an assignment without using exceptions:
|
|
|
|
[source]
|
|
----
|
|
include::../../../test/snippets.cpp[tag=snippet_value_7,indent=0]
|
|
----
|
|
|
|
[TIP]
|
|
====
|
|
If the value's kind is known statically, a reference to the underlying
|
|
representation may be obtained by dereferencing the pointer without checking.
|
|
This avoids the code overhead of the possible exception when using, for example
|
|
<<ref_value_as_string,`value::as_string`>>:
|
|
|
|
[source]
|
|
----
|
|
include::../../../test/snippets.cpp[tag=snippet_value_8,indent=0]
|
|
----
|
|
====
|
|
|
|
Functions returning {ref_result} allow you to use both approaches:
|
|
|
|
[source]
|
|
----
|
|
include::../../../test/snippets.cpp[tag=snippet_value_9,indent=0]
|
|
----
|
|
|
|
=== Formatted Output
|
|
When a <<ref_value>> is formatted to a {std_ostream}, the result is serialized
|
|
JSON as if by calling <<ref_serialize>>.
|