Boost.JSON Logo

PrevUpHomeNext

Using Values

JSON documents are stored in memory using instances of value: a SemiRegular type which satisfies DefaultConstructible and Copyable. These instances are implemented as a tagged union, and can dynamically store any of the six defined JSON value types:

Working With Values

A default constructed value and a value constructed from nullptr produces a null JSON element:

value jv1;
value jv2( nullptr );

The member function value::kind may be used to query the kind stored in the value. Alternatively, member functions like value::is_object or value::is_number may be used to check whether or not the value is a particular kind:

value jv( kind::object );
assert( jv.kind() == kind::object );
assert( jv.is_object() );
assert( ! jv.is_number() );

After a value is constructed, its kind can change depending on what is assigned to it, or by calling functions like value::emplace_array or value::emplace_bool. In all cases, the previous contents of the value are destroyed:

value jv;
jv = value( kind::array )
assert( jv.is_array() );
jv.emplace_string();
assert( jv.is_string() );

Table 1. value Accessors


The emplace members of value return a suitably typed reference to the underlying container representing the kind. For example, the call to value::emplace_string above returns a string&. The library provides a suitable type for each possible value of kind (except for nulls). This table shows the types corresponding to each kind:

Kind

Type

Description

kind::object

object

An associative array of string keys mapping to value elements with an interface similar to std::unordered_map, that remembers insertion order.

kind::array

array

An ordered list of value elements with an interface similar to std::vector.

kind::string

string

A UTF-8 encoded Unicode string of characters with an interface similar to std::string.

kind::number

long long, unsigned long long, double

A type representing an integral or floating point number.

kind::boolean

bool

A bool holding true or false.

kind::null

A monostate value representing null.

We can use the emplace return value to perform an assignment or to capture a reference to the underlying representation for later inspection or modification:

value jv;
jv.emplace_string() = "Hello, world!";

number& num = jv.emplace_number(); // changes to kind::number
num = 1;

If the kind of a value is already known, functions such as value::as_bool or value::as_string may be used to obtain a reference to the underlying representation without changing the existing value:

value jv( kind::bool );
jv.as_bool() = true;

jv.as_string() = "Hello, world!"; // throws system_error !!

However, as shown above these functions throw an exception if the kind in the value does not match the kind implied 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 value::if_string to conditionally perform an assignment without using exceptions:

value jv( kind::string );
if(auto ptr = jv.if_string())
    *ptr = "Hello, world!";
[Tip] 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 value::as_string:

value jv( kind::string );

*jv.if_string() = "Hello, world!";

// The compiler's static analysis can see that
// a null pointer is never dereferenced above.

PrevUpHomeNext