|  | Home | Libraries | People | FAQ | More | 
        JSON documents are represented in memory as instances of value: a Regular
        type which satisfies DefaultConstructible,
        CopyConstructible,
        CopyAssignable,
        MoveConstructible,
        MoveAssignable,
        and many of the requirements of allocator-aware containers. It is implemented
        as a variant
        internally, and can dynamically store any of the six defined JSON value types:
      
nullptr.
          true or false.
          std::string.
          std::vector.
          
        A value
        constructed from nullptr or
        default constructed represents a null JSON element:
      
value jv1; value jv2( nullptr ); assert( jv1.is_null() ); assert( jv2.is_null() );
        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( object_kind ); assert( jv.kind() == kind::object ); assert( jv.is_object() ); assert( ! jv.is_number() );
        Functions like 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:
      
value jv( object_kind ); if( auto p = jv.if_object() ) return p->size();
        After a value
        is constructed, its kind can change depending on what is assigned to it,
        or by calling functions such as value::emplace_array or 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.
      
value jv; jv = value( array_kind ); assert( jv.is_array() ); jv.emplace_string(); assert( jv.is_string() );
        The following table shows all of the ways to determine and access the contents
        of a value:
      
Table 1.2. value
        Accessors
| Kind | Representation | Emplacement | Kind Test | Pointer Access | Checked Access | Unchecked Access | 
|---|---|---|---|---|---|---|
| --- | --- | --- | 
        The emplace members of value return a typed reference to
        the underlying representation. For example, the call to value::emplace_string in the previous example
        returns a string&. This table shows the underlying
        type for each kind:
      
| Kind | Type | Description | 
|---|---|---|
| 
                  An associative array of string keys mapping to  | ||
| 
                  An ordered list of  | ||
| 
                  A UTF-8
                  encoded Unicode
                  string
                  of characters with an interface similar to  | ||
| 
                   | A 64 bit signed integer. | |
| 
                   | A 64 bit unsigned integer. | |
| 
                   | 
                  A  | |
| 
                  A  | ||
| --- | 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:
value jv; jv.emplace_string() = "Hello, world!"; int64_t& num = jv.emplace_int64(); num = 1; assert( jv.is_int64() );
        If the kind
        of a value
        is 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( true ); jv.as_bool() = true; jv.as_string() = "Hello, world!"; // throws an exception
        However, as shown above these functions throw an exception if the kind in
        the 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 value::if_string to conditionally perform
        an assignment without using exceptions:
      
value jv( string_kind ); if( string* str = jv.if_string() ) *str = "Hello, world!";
| ![[Tip]](../../../../../../doc/src/images/tip.png) | 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 jv( string_kind ); // The compiler's static analysis can see that // a null pointer is never dereferenced. *jv.if_string() = "Hello, world!"; | 
        When a value
        is formatted to a std::ostream,
        the result is serialized JSON as if by calling serialize.