[/
    Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com)

    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/cppalliance/json
]

[/-----------------------------------------------------------------------------]

[section Quick Look]

Here we highlight important features through example
code to help convey the style of the interface. We
begin by including the library header file which brings
all the symbols into scope. Alternatively, individual
headers may be included to obtain the declarations for
specific types:
```
#include <boost/json.hpp>
```

In order to link your program you will need to link with
a built library. Alternatively you can use the header-only
configuration simply by including this header file in any
['one] of your new or existing source files:
```
#include <boost/json/src.hpp>
```
[note
    Sample code and identifiers used throughout are written as if
    the following declarations are in effect:
    ```
    #include <boost/json.hpp>
    using namespace boost::json;
    ```
]

[/-----------------------------------------------------------------------------]

[h5 Values]

Say you want to recreate this JSON object in a container:
```
{
  "pi": 3.141,
  "happy": true,
  "name": "Boost",
  "nothing": null,
  "answer": {
    "everything": 42
  },
  "list": [1, 0, 2],
  "object": {
    "currency": "USD",
    "value": 42.99
  }
}
```

In this library the types __array__, __object__, and __string__
hold JSON arrays, objects, and strings respectively while the
type __value__ is a special variant which can hold any JSON
element. Here we construct an empty object and then insert
the elements above:

[doc_quick_look_1]

While keys are strings, the mapped type of objects and the element
type of arrays is a special type called __value__ which can hold
any JSON element, as seen in the previous assignments.
Instead of building the JSON document using a series of function calls,
we can build it in one statement using an initializer list:

[doc_quick_look_2]

When a __value__, __array__, or __object__ is assigned or constructed
from an initializer list, the creation of the new value happens only
once. This makes initializer lists equally efficient as using the other
ways to create a value. The types in this library are first-class,
supporting copy and move construction and assignment:

[doc_quick_look_3]

[/-----------------------------------------------------------------------------]

[h5 Allocators]

To permit custom memory allocation strategies, these containers all
allow construction with a __storage_ptr__ which is a smart pointer
to a __memory_resource__. The constructor signatures have the same
ordering as their `std` equivalents which use ['Allocator] parameters.
Once a container is constructed its memory resource can never change.
Here we create an array without performing any dynamic allocations:

[doc_quick_look_4]

The containers in this library enforce the invariant that every
element of the container will use the same memory resource:

[doc_quick_look_5]

When a library type is used as the element type of a pmr container;
that is, a container which uses a __polymorphic_allocator__, the
memory resource will automaticaly propagate to the type and all
of its children:

[doc_quick_look_6]

Up until now we have shown how values may be constructed from a
memory resource pointer, where ownership is not transferred. In this
case the caller is responsible for ensuring that the lifetime of the
resource is extended for the life of the container. Sometimes you want
the container to acquire shared ownership of the resource. This is
accomplished with __make_shared_resource__:

[doc_quick_look_7]

A counted memory resource will not be destroyed until every container
with shared ownership of the resource is destroyed.

[/-----------------------------------------------------------------------------]

[h5 Parsing]

JSON can be parsed into the value container in one step using a free
function. In the following snippet, a parse error is indicated by a
thrown exception:

[doc_quick_look_8]

Error codes are also possible:

[doc_quick_look_9]

By default, the parser is strict and only accepts JSON compliant with
the standard. However this behavior can be relaxed by filling out an
options structure enabling one or more extensions. Here we use a
static buffer and enable two non-standard extensions:

[doc_quick_look_10]

The parser in this library implements a
[@https://en.wikipedia.org/wiki/Online_algorithm ['streaming algorithm]];
it can process JSON piece-by-piece, without the requirement that the
entire input is available from the start.
The parser uses a temporary memory allocation to do its work. If
you plan on parsing multiple JSONs, for example in a network server,
keeping the same parser instance will allow re-use of this temporary
storage, improving performance.

[doc_quick_look_11]

With strategic use of the right memory resources, parser instance,
and calculated upper limits on buffer sizes, it is possible to parse
and examine JSON without ['any] dynamic memory allocations. This is
explored in more detail in a later section.

[/-----------------------------------------------------------------------------]

[h5 Serializing]

Simple free functions are provided for serializing a __value__
to a __std_string__ containing JSON:

[doc_quick_look_12]

The serializer in this library implements a
[@https://en.wikipedia.org/wiki/Online_algorithm ['streaming algorithm]];
it can output JSON a piece at a time, without the requirement that the
entire output area is allocated at once:

[doc_quick_look_13]

[/-----------------------------------------------------------------------------]

[h5 Value Conversion]

Given a user-defined type:

[doc_quick_look_14]

We can define a conversion from the user-defined type to a __value__
by defining an overload of `tag_invoke` in the same namespace. This
maps `customer` to a JSON object:

[doc_quick_look_15]

This allows us to use the library function __value_from__ to produce
a __value__ from our type:

[doc_quick_look_16]

The library knows what to do with standard containers.
Here we convert an array of customers to a value:

[doc_quick_look_17]

To go from JSON to a user-defined type we use __value_to__,
which uses another overload of `tag_invoke`. This converts a
JSON value to a `customer`. It throws an exception if the
contents of the value do not match what is expected:

[doc_quick_look_18]

The code above defines the convenience function `extract`,
which deduces the types of the struct members. This works,
but requires that the struct is __DefaultConstructible__.
An alternative is to construct the object directly, which
is a little more verbose but doesn't require default
construction:

[doc_quick_look_19]

Now we can construct customers from JSON:

[doc_quick_look_20]

The library's generic algorithms recognize when you are converting
a __value__ to a container which resembles an array or object, so
if you wanted to turn a JSON array into a vector of customers you
might write:

[doc_quick_look_21]

[/-----------------------------------------------------------------------------]

[endsect]
