Line data Source code
1 : //
2 : // Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com)
3 : // Copyright (c) 2020 Krystian Stasiowski (sdkrystian@gmail.com)
4 : // Copyright (c) 2022 Dmitry Arkhipov (grisumbras@gmail.com)
5 : //
6 : // Distributed under the Boost Software License, Version 1.0. (See accompanying
7 : // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
8 : //
9 : // Official repository: https://github.com/boostorg/json
10 : //
11 :
12 : #ifndef BOOST_JSON_VALUE_FROM_HPP
13 : #define BOOST_JSON_VALUE_FROM_HPP
14 :
15 : #include <boost/json/detail/value_from.hpp>
16 :
17 : namespace boost {
18 : namespace json {
19 :
20 : /** Convert an object of type `T` to @ref value.
21 :
22 : This function attempts to convert an object
23 : of type `T` to @ref value using
24 :
25 : @li one of @ref value's constructors,
26 :
27 : @li a library-provided generic conversion, or
28 :
29 : @li a user-provided overload of `tag_invoke`.
30 :
31 : Out of the box the function supports types satisfying
32 : <a href="https://en.cppreference.com/w/cpp/named_req/SequenceContainer"><em>SequenceContainer</em></a>,
33 : arrays, arithmetic types, `bool`, `std::tuple`, `std::pair`,
34 : `std::variant`, `std::optional`, `std::monostate`, and `std::nullopt_t`.
35 :
36 : Conversion of other types is done by calling an overload of `tag_invoke`
37 : found by argument-dependent lookup. Its signature should be similar to:
38 :
39 : @code
40 : template< class FullContext >
41 : void tag_invoke( value_from_tag, value&, T, const Context& , const FullContext& );
42 : @endcode
43 :
44 : or
45 :
46 : @code
47 : void tag_invoke( value_from_tag, value&, T, const Context& );
48 : @endcode
49 :
50 : or
51 :
52 : @code
53 : void tag_invoke( value_from_tag, value&, T );
54 : @endcode
55 :
56 : The overloads are checked for existence in that order and the first that
57 : matches will be selected. <br>
58 :
59 : The `ctx` argument can be used either as a tag type to provide conversions
60 : for third-party types, or to pass extra data to the conversion function.
61 :
62 : @par Exception Safety
63 : Strong guarantee.
64 :
65 : @tparam T The type of the object to convert.
66 :
67 : @tparam Context The type of context passed to the conversion function.
68 :
69 : @param t The object to convert.
70 :
71 : @param ctx Context passed to the conversion function.
72 :
73 : @param jv @ref value out parameter.
74 :
75 : @see @ref value_from_tag, @ref value_to,
76 : <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2019/p1895r0.pdf">
77 : tag_invoke: A general pattern for supporting customisable functions</a>
78 : */
79 : template< class T, class Context >
80 : void
81 7073 : value_from(
82 : T&& t,
83 : Context const& ctx,
84 : value& jv)
85 : {
86 : using Attrs = detail::value_from_attrs<Context, T>;
87 : BOOST_STATIC_ASSERT(detail::conversion_round_trips<
88 : Context,
89 : typename Attrs::representation,
90 : detail::value_from_conversion>::value);
91 :
92 7073 : detail::value_from_impl(
93 6558 : typename Attrs::category(),
94 : jv,
95 7055 : detail::to_representation<Context>( static_cast<T&&>(t) ),
96 : ctx );
97 7073 : }
98 :
99 : /** Convert an object of type `T` to @ref value.
100 :
101 : This function attempts to convert an object
102 : of type `T` to @ref value using
103 :
104 : @li one of @ref value's constructors,
105 :
106 : @li a library-provided generic conversion, or
107 :
108 : @li a user-provided overload of `tag_invoke`.
109 :
110 : Out of the box the function supports types satisfying
111 : <a href="https://en.cppreference.com/w/cpp/named_req/SequenceContainer"><em>SequenceContainer</em></a>,
112 : arrays, arithmetic types, `bool`, `std::tuple`, `std::pair`,
113 : `std::variant`, `std::optional`, `std::monostate`, and `std::nullopt_t`.
114 :
115 : Conversion of other types is done by calling an overload of `tag_invoke`
116 : found by argument-dependent lookup. Its signature should be similar to:
117 :
118 : @code
119 : template< class FullContext >
120 : void tag_invoke( value_from_tag, value&, T, const Context& , const FullContext& );
121 : @endcode
122 :
123 : or
124 :
125 : @code
126 : void tag_invoke( value_from_tag, value&, T, const Context& );
127 : @endcode
128 :
129 : or
130 :
131 : @code
132 : void tag_invoke( value_from_tag, value&, T );
133 : @endcode
134 :
135 : The overloads are checked for existence in that order and the first that
136 : matches will be selected. <br>
137 :
138 : A @ref value constructed with the @ref storage_ptr passed to
139 : @ref value_from is passed as the second argument to ensure that the memory
140 : resource is correctly propagated.
141 :
142 : @par Exception Safety
143 : Strong guarantee.
144 :
145 : @tparam T The type of the object to convert.
146 :
147 : @tparam Context The type of context passed to the conversion function.
148 :
149 : @returns `t` converted to @ref value.
150 :
151 : @param t The object to convert.
152 :
153 : @param ctx Context passed to the conversion function.
154 :
155 : @param sp A storage pointer referring to the memory resource
156 : to use for the returned @ref value. The default argument for this
157 : parameter is `{}`.
158 :
159 : @see @ref value_from_tag, @ref value_to,
160 : <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2019/p1895r0.pdf">
161 : tag_invoke: A general pattern for supporting customisable functions</a>
162 : */
163 : template< class T, class Context >
164 : #ifndef BOOST_JSON_DOCS
165 : typename std::enable_if<
166 : !std::is_same< detail::remove_cvref<Context>, storage_ptr >::value &&
167 : !std::is_same< detail::remove_cvref<Context>, value >::value,
168 : value >::type
169 : #else
170 : value
171 : #endif
172 7054 : value_from(
173 : T&& t,
174 : Context const& ctx,
175 : storage_ptr sp = {})
176 : {
177 7054 : value jv(std::move(sp));
178 7054 : value_from( static_cast<T&&>(t), ctx, jv );
179 7054 : return jv;
180 0 : }
181 :
182 : /** Convert an object of type `T` to @ref value.
183 :
184 : This function attempts to convert an object
185 : of type `T` to @ref value using
186 :
187 : @li one of @ref value's constructors,
188 :
189 : @li a library-provided generic conversion, or
190 :
191 : @li a user-provided overload of `tag_invoke`.
192 :
193 : Out of the box the function supports types satisfying
194 : <a href="https://en.cppreference.com/w/cpp/named_req/SequenceContainer"><em>SequenceContainer</em></a>,
195 : arrays, arithmetic types, `bool`, `std::tuple`, `std::pair`,
196 : `std::variant`, `std::optional`, `std::monostate`, and `std::nullopt_t`.
197 :
198 : Conversion of other types is done by calling an overload of `tag_invoke`
199 : found by argument-dependent lookup. Its signature should be similar to:
200 :
201 : @code
202 : void tag_invoke( value_from_tag, value&, T );
203 : @endcode
204 :
205 : @par Exception Safety
206 : Strong guarantee.
207 :
208 : @tparam T The type of the object to convert.
209 :
210 : @param t The object to convert.
211 :
212 : @param jv @ref value out parameter.
213 :
214 : @see @ref value_from_tag, @ref value_to,
215 : <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2019/p1895r0.pdf">
216 : tag_invoke: A general pattern for supporting customisable functions</a>
217 : */
218 : template<class T>
219 : void
220 19 : value_from(
221 : T&& t,
222 : value& jv)
223 : {
224 19 : value_from( static_cast<T&&>(t), detail::no_context(), jv );
225 19 : }
226 :
227 : /** Convert an object of type `T` to @ref value.
228 :
229 : This function attempts to convert an object
230 : of type `T` to @ref value using
231 :
232 : @li one of @ref value's constructors,
233 :
234 : @li a library-provided generic conversion, or
235 :
236 : @li a user-provided overload of `tag_invoke`.
237 :
238 : Out of the box the function supports types satisfying
239 : <a href="https://en.cppreference.com/w/cpp/named_req/SequenceContainer"><em>SequenceContainer</em></a>,
240 : arrays, arithmetic types, `bool`, `std::tuple`, `std::pair`,
241 : `std::variant`, `std::optional`, `std::monostate`, and `std::nullopt_t`.
242 :
243 : Conversion of other types is done by calling an overload of `tag_invoke`
244 : found by argument-dependent lookup. Its signature should be similar to:
245 :
246 : @code
247 : void tag_invoke( value_from_tag, value&, T );
248 : @endcode
249 :
250 : A @ref value constructed
251 : with the @ref storage_ptr passed to @ref value_from is
252 : passed as the second argument to ensure that the memory
253 : resource is correctly propagated.
254 :
255 : @par Exception Safety
256 : Strong guarantee.
257 :
258 : @tparam T The type of the object to convert.
259 :
260 : @returns `t` converted to @ref value.
261 :
262 : @param t The object to convert.
263 :
264 : @param sp A storage pointer referring to the memory resource
265 : to use for the returned @ref value. The default argument for this
266 : parameter is `{}`.
267 :
268 : @see @ref value_from_tag, @ref value_to,
269 : <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2019/p1895r0.pdf">
270 : tag_invoke: A general pattern for supporting customisable functions</a>
271 : */
272 : template<class T>
273 : value
274 161 : value_from(
275 : T&& t,
276 : storage_ptr sp = {})
277 : {
278 : return value_from(
279 161 : static_cast<T&&>(t), detail::no_context(), std::move(sp) );
280 : }
281 :
282 : /** Determine if `T` can be converted to @ref value.
283 :
284 : If `T` can be converted to @ref value via a
285 : call to @ref value_from, the static data member `value`
286 : is defined as `true`. Otherwise, `value` is
287 : defined as `false`.
288 :
289 : @see @ref value_from
290 : */
291 : #ifdef BOOST_JSON_DOCS
292 : template<class T>
293 : using has_value_from = __see_below__;
294 : #else
295 : template<class T>
296 : using has_value_from = detail::can_convert<
297 : detail::remove_cvref<T>, detail::value_from_conversion>;
298 : #endif
299 :
300 : } // namespace json
301 : } // namespace boost
302 :
303 : #endif
|