[/
    Copyright (c) 2022 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/cppalliance/json
]

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

The function template __value_from__ provides an interface to
construct a __value__ from a type `T`. The function template __value_to__
converts in the opposite direction, from a type `T` to __value__. Both support
a wide variety of different
[@https://en.cppreference.com/w/cpp/language/types fundamental types], such
as `int` or `double`, standard library types, such as `std::string` or
`std::vector<T>`, and can be extended to support user-defined types.

[snippet_conv_1]

For the type `T`, the appropriate conversion approach is chosen from the
following list of categories. The first matching category is selected.

[table Conversion categories
[[Category of T] [Comment] [`value_from` behavior] [`value_to` behavior]]
[
    [Custom conversion]
    []
    [Custom behavior.]
    [Custom behavior.]
][
    [Boost.JSON container]
    []
    [The result is equal to the input value.]
    [The result is equal to the input value.]
][
    [`bool`]
    []
    [The result is equal to the input value.]
    [The result is equal to the input value.]
][
    [[@https://en.cppreference.com/w/cpp/types/is_arithmetic Arithmetic type]]
    []
    [The result is a number equal to input and has the type

* `std::int64_t`, if `T` is a signed integer'; or

* `std::uint64_t`, if `T` is an unsigned integer; or

* `double` otherwise.

    ]
    [The result is created via __value_to_number__.]
][
    [Type satisfying __is_null_like__]
    [Intended for types like __std_monostate__.]
    [The result is a null value.]
    [The result is default-constructed.]
][
    [Type satisfying __is_string_like__]
    [A sequence of `char`s, e.g. `std::string`.]
    [The result is a __string__.]
    [The result is constructed from a __string_view__.]
][
    [Type satisfying __is_map_like__]
    [A one-to-one mapping (e.g. `std::map`) with string-like keys.]
    [The result is an __object__.]
    [The result is default-constructed, and elements are `insert`-ed at the
        end.]
][
    [Type satisfying __is_sequence_like__]
    [A sequence of elements, e.g. `std::vector`.]
    [The result is an __array__.]
    [The result is default-constructed, and elements are `insert`-ed at the
        end.]
][
    [Type satisfying __is_tuple_like__]
    [A heterogenous sequence with fixed size, e.g. `std::tuple` and
        `std::pair`.]
    [The result is an __array__.]
    [The result is constructed with the array elements as constructor
        arguments.]
][
    [Type satisfying __is_described_class__]
    []
    [The result is an __object__ with described members' names as keys.]
    [The result is default-constructed and described members are assigned
        corresponding values.]
][
    [Type satisfying __is_described_enum__]
    []
    [If the input value is equal to one of the described enumerators, the
        result is a __string__, containing its name. Otherwise it's equal
        to the input value converted to its underlying type.]
    [The result is the described enumerator, corresponding to the input
        __string__.]
]]

For composite types (sequences, tuples, described classes, etc.) conversion of
contained objects is applied recursively. For example:

[snippet_conv_recursive]

Here, the map is converted into an __object__, since it matches
__is_map_like__. Each of its keys is converted into a __string__, as
`std::string` matches __is_string_like__, and each of its values is converted
into an __array__, as `std::pair` matches __is_tuple_like__. Finally, elements
of pairs are converted into a `std::int64_t` number and a `bool`.
