object

A value stores an instance of object as the underlying representation for a JSON object. Instances of the object type are associative containers holding key and value pairs, where the key is a string_view and the mapped type is a value. These containers are modelled after standard maps with these properties:

  • The elements are stored contiguously as instances of key_value_pair.

  • Iterators are ordinary pointers, and may become invalidated on insertions and removals.

  • The order of insertions is preserved, as long as there are no removals.

  • All inserted values will use the same memory_resource as the container itself.

An empty object may be constructed without incurring any memory allocations using the default memory resource. A storage_ptr can also be explicitly specified:

object obj1; // empty object, uses the default memory resource

object obj2( make_shared_resource<monotonic_resource>() ); // empty object, uses a counted monotonic resource

Initializer lists consisting of two-element key value pairs can be used to construct objects with initial contents. These constructors may allocate memory and throw:

object obj( {{"key1", "value1" }, { "key2", 42 }, { "key3", false }} );

Alternatively, elements may be inserted after construction:

object obj;

obj.emplace( "key1", "value1" );
obj.emplace( "key2", 42 );
obj.emplace( "key3", false );

Similar to the std counterpart, elements may be accessed directly by their key with bounds checking using object::at, or without bounds checking using object::operator[] which creates a null element if the key does not already exist:

object obj;

obj["key1"] = "value1";
obj["key2"] = 42;
obj["key3"] = false;

// The following line throws system_error, since the key does not exist
obj.at( "key4" );

Internally, the container computes a hash table over the keys so that the complexity of lookups is in constant time, on average.

Unlike traditional node based containers like std::set, there is no guarantee of reference stability or iterator stability on insertions and erasures.

For example:

object obj{{"arr", {1, 11}}};
value& arr = obj.at("arr");
obj.emplace("added", "value"); // invalidates arr

Using arr after adding another value to obj results in undefined behavior.

For the complete listing of all available member functions and nested types, see the reference page for object.

As with std::pair, the key_value_pair type can be used with structured bindings in C++17. Specializations of std::tuple_size, std::tuple_element, and overloads of get are all provided for this purpose.

Formatted Output

When an object is formatted to a std::ostream, the result is a valid JSON. That is, the object will be output with curly braces and a comma separated list of key/value pairs, as per the JSON specification.