conversion.hpp
9.45 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
//
// 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/boostorg/json
//
#ifndef BOOST_JSON_CONVERSION_HPP
#define BOOST_JSON_CONVERSION_HPP
#include <boost/json/detail/config.hpp>
#include <type_traits>
BOOST_JSON_NS_BEGIN
/** Customization point tag.
This tag type is used by the function
@ref value_from to select overloads
of `tag_invoke`.
@note This type is empty; it has no members.
@see @ref value_from, @ref value_to, @ref value_to_tag,
<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2019/p1895r0.pdf">
tag_invoke: A general pattern for supporting customisable functions</a>
*/
struct value_from_tag { };
/** Customization point tag type.
This tag type is used by the function
@ref value_to to select overloads
of `tag_invoke`.
@note This type is empty; it has no members.
@see @ref value_from, @ref value_from_tag, @ref value_to,
<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2019/p1895r0.pdf">
tag_invoke: A general pattern for supporting customisable functions</a>
*/
template<class T>
struct value_to_tag { };
/** Customization point tag type.
This tag type is used by the function
@ref try_value_to to select overloads
of `tag_invoke`.
@note This type is empty; it has no members.
@see @ref value_to, @ref value_to_tag
<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2019/p1895r0.pdf">
tag_invoke: A general pattern for supporting customisable functions</a>
*/
template<class T>
struct try_value_to_tag { };
/** Determine if `T` can be treated like a string during conversions.
Provides the member constant `value` that is equal to `true`, if `T` is
convertible to @ref string_view. Otherwise, `value` is equal to `false`.
<br>
Users can specialize the trait for their own types if they don't want them
to be treated like strings. For example:
@code
namespace boost {
namespace json {
template <>
struct is_string_like<your::string> : std::false_type
{ };
} // namespace boost
} // namespace json
@endcode
@par Types satisfying the trait
@ref string,
@ref string_view,
<a href="https://en.cppreference.com/w/cpp/string/basic_string"><tt>std::string</tt></a>,
<a href="https://en.cppreference.com/w/cpp/string/basic_string_view"><tt>std::string_view</tt></a>.
@see @ref value_from, @ref value_to
*/
template<class T>
struct is_string_like;
/** Determine if `T` can be treated like a sequence during conversions.
Given `t`, a glvalue of type `T`, if
@li given `It`, the type denoted by `decltype(std::begin(t))`,
<tt>std::iterator_traits<It>::iterator_category</tt> is well-formed and
denotes a type; and
@li `decltype(std::end(t))` also denotes the type `It`;
then the trait provides the member constant `value` that is equal to
`true`. Otherwise, `value` is equal to `false`.<br>
Users can specialize the trait for their own types if they don't want them
to be treated like sequences. For example:
@code
namespace boost {
namespace json {
template <>
struct is_sequence_like<your::container> : std::false_type
{ };
} // namespace boost
} // namespace json
@endcode
@par Types satisfying the trait
Any <a href="https://en.cppreference.com/w/cpp/named_req/SequenceContainer"><em>SequenceContainer</em></a>,
array types.
@see @ref value_from, @ref value_to
*/
template<class T>
struct is_sequence_like;
/** Determine if `T` can be treated like a 1-to-1 mapping during
conversions.
Given `t`, a glvalue of type `T`, if
@li <tt>is_sequence_like<T>::value</tt> is `true`; and
@li given type `It` denoting `decltype(std::begin(t))`, and types `K`
and `M`, <tt>std::iterator_traits<It>::value_type</tt> denotes
`std::pair<K, M>`; and
@li <tt>std::is_string_like<K>::value</tt> is `true`; and
@li given `v`, a glvalue of type `V`, and `E`, the type denoted by
`decltype(t.emplace(v))`,
<tt>std::is_tuple_like<E>::value</tt> is `true`;
then the trait provides the member constant `value`
that is equal to `true`. Otherwise, `value` is equal to `false`.<br>
Users can specialize the trait for their own types if they don't want them
to be treated like mappings. For example:
@code
namespace boost {
namespace json {
template <>
struct is_map_like<your::map> : std::false_type
{ };
} // namespace boost
} // namespace json
@endcode
@note
The restriction for `t.emplace()` return type ensures that the container
does not accept duplicate keys.
@par Types satisfying the trait
<a href="https://en.cppreference.com/w/cpp/container/map"><tt>std::map</tt></a>,
<a href="https://en.cppreference.com/w/cpp/container/unordered_map"><tt>std::unordered_map</tt></a>.
@see @ref value_from, @ref value_to
*/
template<class T>
struct is_map_like;
/** Determine if `T` can be treated like a tuple during conversions.
Provides the member constant `value` that is equal to `true`, if
<tt>std::tuple_size<T>::value</tt> is a positive number. Otherwise, `value`
is equal to `false`.<br>
Users can specialize the trait for their own types if they don't want them
to be treated like tuples. For example:
@code
namespace boost {
namespace json {
template <>
struct is_tuple_like<your::tuple> : std::false_type
{ };
} // namespace boost
} // namespace json
@endcode
@par Types satisfying the trait
<a href="https://en.cppreference.com/w/cpp/utility/tuple"><tt>std::tuple</tt></a>,
<a href="https://en.cppreference.com/w/cpp/utility/pair"><tt>std::pair</tt></a>.
@see @ref value_from, @ref value_to
*/
template<class T>
struct is_tuple_like;
/** Determine if `T` can be treated like null during conversions.
Primary template instantiations provide the member constant `value` that is
equal to `false`. Users can specialize the trait for their own types if
they **do** want them to be treated as nulls. For example:
@code
namespace boost {
namespace json {
template <>
struct is_null_like<your::null_type> : std::true_type
{ };
} // namespace boost
} // namespace json
@endcode
@par Types satisfying the trait
<a href="https://en.cppreference.com/w/cpp/types/nullptr_t"><tt>std::nullptr_t</tt></a>.
@see @ref value_from, @ref value_to
*/
template<class T>
struct is_null_like
: std::false_type
{ };
/** Determine if `T` should be treated as a described class
Described classes are serialised as objects with an element for each
described public data member. A described class should not have described
bases or non-public members.<br>
Or more formally, given `L`, a class template
of the form `template<class...> struct L {};`, if
@li <tt>boost::describe::has_members<T, boost::describe::mod_public>::value</tt> is `true`; and
@li `boost::describe::describe_members<T, boost::describe::mod_private | boost::describe::mod_protected>` denotes `L<>`; and
@li `boost::describe::describe_bases<T, boost::describe::mod_any_access>` denotes `L<>`; and
@li <tt>std::is_union<T>::value</tt> is `false`;
then the trait provides the member constant `value`
that is equal to `true`. Otherwise, `value` is equal to `false`.<br>
Users can specialize the trait for their own types if they don't want them
to be treated as described classes. For example:
@code
namespace boost {
namespace json {
template <>
struct is_described_class<your::described_class> : std::false_type
{ };
} // namespace boost
} // namespace json
@endcode
Users can also specialize the trait for their own types _with_ described
bases to enable this conversion implementation. In this case the class will
be serialized in a flattened way, that is members of bases will be
serialized as direct elements of the object, and no nested objects will be
created for bases.
@see <a href="https://www.boost.org/doc/libs/develop/libs/describe/doc/html/describe.html">Boost.Describe</a>.
*/
template<class T>
struct is_described_class;
/** Determine if `T` should be treated as a described enum
Described enums are serialised as strings when their value equals to a
described enumerator, and as integers otherwise. The reverse operation
does not convert numbers to enums values, though, and instead produces
an error.<br>
If <tt>boost::describe::has_describe_enumerators<T>::value</tt> is `true`,
then the trait provides the member constant `value`
that is equal to `true`. Otherwise, `value` is equal to `false`.<br>
Users can specialize the trait for their own enums if they don't want them
to be treated as described enums. For example:
@code
namespace boost {
namespace json {
template <>
struct is_described_enum<your::described_enum> : std::false_type
{ };
} // namespace boost
} // namespace json
@endcode
@see <a href="https://www.boost.org/doc/libs/develop/libs/describe/doc/html/describe.html">Boost.Describe</a>.
*/
template<class T>
struct is_described_enum;
BOOST_JSON_NS_END
#include <boost/json/impl/conversion.hpp>
#endif // BOOST_JSON_CONVERSION_HPP