Skip to content

Commit f3cc2f3

Browse files
committed
more conversion docs
1 parent 10611ca commit f3cc2f3

3 files changed

Lines changed: 174 additions & 84 deletions

File tree

include/boost/json/conversion.hpp

Lines changed: 24 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -151,7 +151,7 @@ struct try_value_to_tag { };
151151
template<class T>
152152
struct is_string_like;
153153

154-
/** Conversion category for strings.
154+
/** Conversion category constant for strings.
155155
156156
String types are represented as JSON strings.
157157
@@ -221,7 +221,7 @@ using string_category = std::integral_constant<
221221
template<class T>
222222
struct is_path_like;
223223

224-
/** Conversion category for filesystem paths.
224+
/** Conversion category constant for filesystem paths.
225225
226226
Paths are represented in JSON as strings.
227227
@@ -301,7 +301,7 @@ using path_category = std::integral_constant<
301301
template<class T>
302302
struct is_sequence_like;
303303

304-
/** Conversion category for sequences.
304+
/** Conversion category constant for sequences.
305305
306306
Sequences are represented in JSON as arrays.
307307
@@ -386,7 +386,7 @@ using sequence_category = std::integral_constant<
386386
template<class T>
387387
struct is_map_like;
388388

389-
/** Conversion category for maps.
389+
/** Conversion category constant for maps.
390390
391391
Maps are represented in JSON as objects. Such representation limits this
392392
category to 1-to-1 maps (as opposed to 1-to-many e.g. @ref std::multimap)
@@ -470,7 +470,7 @@ using map_category = std::integral_constant<
470470
template<class T>
471471
struct is_tuple_like;
472472

473-
/** Conversion category for tuples.
473+
/** Conversion category constant for tuples.
474474
475475
Tuples are represented in JSON as arrays.
476476
@@ -528,7 +528,7 @@ struct is_null_like
528528
: std::false_type
529529
{ };
530530

531-
/** Conversion category for null types.
531+
/** Conversion category constant for null types.
532532
533533
Null types are represented in JSON as the `null` literal.
534534
@@ -607,7 +607,7 @@ using null_category = std::integral_constant<
607607
template<class T>
608608
struct is_described_class;
609609

610-
/** Conversion category for described classes.
610+
/** Conversion category constant for described classes.
611611
612612
Described classes are represented in JSON as objects with an element for
613613
each described data member. Described bases are flattened, that is members
@@ -687,7 +687,7 @@ using described_class_category = std::integral_constant<
687687
template<class T>
688688
struct is_described_enum;
689689

690-
/** Conversion category for described enums.
690+
/** Conversion category constant for described enums.
691691
692692
Described enums are serialized as strings when their value equals to a
693693
described enumerator, and as integers otherwise. The reverse operation
@@ -750,7 +750,7 @@ using described_enum_category = std::integral_constant<
750750
template<class T>
751751
struct is_variant_like;
752752

753-
/** Conversion category for variants.
753+
/** Conversion category constant for variants.
754754
755755
Variants are serialized the same way their active alternative is
756756
serialized. The opposite conversion selects the first alternative for which
@@ -815,7 +815,7 @@ using variant_category = std::integral_constant<
815815
template<class T>
816816
struct is_optional_like;
817817

818-
/** Conversion category for optionals.
818+
/** Conversion category constant for optionals.
819819
820820
Optionals are represented in JSON as `null` if not engaged (i.e. does not
821821
store a value), or as the stored type otherwise.
@@ -853,14 +853,21 @@ using optional_category = std::integral_constant<
853853
using unknown_category = std::integral_constant<
854854
conversion_category, conversion_category::unknown>;
855855

856-
/** Determines the category of conversion of a type.
856+
/** Overrides the category of conversion of a type.
857857
858-
Provides the member constant `value` that is equal to an enumerator of
859-
@ref conversion_category that represents the suitable conversion category
860-
of T. The primary template attempts to deduce the category.
858+
Specializations should provide the static member constant `value` that is
859+
equal to an enumerator of @ref conversion_category that represents the
860+
suitable conversion category of T in context `Ctx`.
861861
862-
Users can specialize the trait for their own types if the deduction fails.
863-
For example:
862+
The primary template's `value` is equal to @ref
863+
conversion_category::unknown.
864+
865+
Use `void` for `Ctx` (the default) if the category should apply regardless
866+
of context.
867+
868+
The third template parameter can be used for conditional specializations.
869+
870+
Usage example:
864871
865872
@code
866873
namespace boost {
@@ -874,7 +881,7 @@ using unknown_category = std::integral_constant<
874881
} // namespace json
875882
@endcode
876883
877-
@see @ref value_from, @ref value_to, \<\<Custom Conversions>>.
884+
@see \<\<Custom Conversions>>, @ref value_from, @ref value_to.
878885
*/
879886
template<class T, class Ctx = void, class Enable = void>
880887
struct use_category;

include/boost/json/value_from.hpp

Lines changed: 40 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -20,43 +20,61 @@ namespace json {
2020

2121
/** Convert an object of type `T` to @ref value.
2222
23-
This function attempts to convert an object
24-
of type `T` to @ref value using
23+
This function attempts to convert an object of type `T` to @ref value using
2524
26-
@li one of @ref value's constructors,
25+
- one of @ref value's constructors,
26+
- a library-provided generic conversion, or
27+
- a user-provided overload of `tag_invoke`.
2728
28-
@li a library-provided generic conversion, or
29+
In order to perform the conversion the function selects an appropriate
30+
implementation based on the types `T` and `Context` (if provided).
2931
30-
@li a user-provided overload of `tag_invoke`.
32+
1. If `Context` is available and is not `std::tuple<C...>`
3133
32-
Out of the function supports default constructible types satisfying
33-
{req_SequenceContainer}, arrays, arithmetic types, `bool`, `std::tuple`,
34-
`std::pair`, `std::optional`, `std::variant`, `std::nullptr_t`, and structs
35-
and enums described using Boost.Describe.
34+
a. check if `use_category<T, Context>::value` is not
35+
@ref conversion_category::unknown; otherwise
3636
37-
Conversion of other types is done by calling an overload of `tag_invoke`
38-
found by argument-dependent lookup. Its signature should be similar to:
37+
b. check if a `tag_invoke` overload from the list below that takes a
38+
`Context const&` exists.
39+
40+
2. Otherwise, if `Context` is available, and is `std::tuple<C...>` repeat
41+
steps **1** and **2** recursively for every `C` until either
42+
step **1.a** or **1.b** succeeds for some `C`.
43+
44+
3. Failing that,
45+
46+
a. check if `use_category<T>::value` is not
47+
@ref conversion_category::unknown; otherwise
48+
49+
b. check if a `tag_invoke` overload from the list below that takes only
50+
2 parameters exists; otherwise
51+
52+
c. check if `T` is one of @ref value, @ref array, @ref object,
53+
or @ref string; otherwise
54+
55+
d. check if `T` matches one of the categories of types described in the
56+
table "Conversion categories" in \<\<Value Conversion>> section.
57+
58+
These steps determine both the appropriate category of conversion for `T`,
59+
and, if necessary, the effective context `C` that will be used for
60+
conversion. If the category is selected on steps **1.a**, **3.a**, **3.c**,
61+
or **3.d**, the library provides a suitable conversion implementation.
62+
If the category is selected on steps **2.b** or **3.b**, then a
63+
user-provided `tag_invoke` overload is used.
64+
65+
The overloads of `tag_invoke` that will be considered by this function
66+
are in the following list. Overloads that appear higher in the list have
67+
higher priority.
3968
4069
@code
4170
template< class FullContext >
4271
void tag_invoke( value_from_tag, value&, T, const Context&, const FullContext& );
43-
@endcode
44-
45-
or
4672
47-
@code
4873
void tag_invoke( value_from_tag, value&, T, const Context& );
49-
@endcode
5074
51-
or
52-
53-
@code
5475
void tag_invoke( value_from_tag, value&, T );
5576
@endcode
5677
57-
The overloads are checked for existence in that order and the first that
58-
matches will be selected. <br>
59-
6078
The `ctx` argument can be used either as a tag type to provide conversions
6179
for third-party types, or to pass extra data to the conversion function.
6280

0 commit comments

Comments
 (0)