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 6970 : value_from(
82 : T&& t,
83 : Context const& ctx,
84 : value& jv)
85 : {
86 : using bare_T = detail::remove_cvref<T>;
87 : BOOST_STATIC_ASSERT(detail::conversion_round_trips<
88 : Context, bare_T, detail::value_from_conversion>::value);
89 : using cat = detail::value_from_category<Context, bare_T>;
90 6970 : detail::value_from_impl( cat(), jv, std::forward<T>(t), ctx );
91 6970 : }
92 :
93 : /** Convert an object of type `T` to @ref value.
94 :
95 : This function attempts to convert an object
96 : of type `T` to @ref value using
97 :
98 : @li one of @ref value's constructors,
99 :
100 : @li a library-provided generic conversion, or
101 :
102 : @li a user-provided overload of `tag_invoke`.
103 :
104 : Out of the box the function supports types satisfying
105 : <a href="https://en.cppreference.com/w/cpp/named_req/SequenceContainer"><em>SequenceContainer</em></a>,
106 : arrays, arithmetic types, `bool`, `std::tuple`, `std::pair`,
107 : `std::variant`, `std::optional`, `std::monostate`, and `std::nullopt_t`.
108 :
109 : Conversion of other types is done by calling an overload of `tag_invoke`
110 : found by argument-dependent lookup. Its signature should be similar to:
111 :
112 : @code
113 : template< class FullContext >
114 : void tag_invoke( value_from_tag, value&, T, const Context& , const FullContext& );
115 : @endcode
116 :
117 : or
118 :
119 : @code
120 : void tag_invoke( value_from_tag, value&, T, const Context& );
121 : @endcode
122 :
123 : or
124 :
125 : @code
126 : void tag_invoke( value_from_tag, value&, T );
127 : @endcode
128 :
129 : The overloads are checked for existence in that order and the first that
130 : matches will be selected. <br>
131 :
132 : A @ref value constructed with the @ref storage_ptr passed to
133 : @ref value_from is passed as the second argument to ensure that the memory
134 : resource is correctly propagated.
135 :
136 : @par Exception Safety
137 : Strong guarantee.
138 :
139 : @tparam T The type of the object to convert.
140 :
141 : @tparam Context The type of context passed to the conversion function.
142 :
143 : @returns `t` converted to @ref value.
144 :
145 : @param t The object to convert.
146 :
147 : @param ctx Context passed to the conversion function.
148 :
149 : @param sp A storage pointer referring to the memory resource
150 : to use for the returned @ref value. The default argument for this
151 : parameter is `{}`.
152 :
153 : @see @ref value_from_tag, @ref value_to,
154 : <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2019/p1895r0.pdf">
155 : tag_invoke: A general pattern for supporting customisable functions</a>
156 : */
157 : template< class T, class Context >
158 : #ifndef BOOST_JSON_DOCS
159 : typename std::enable_if<
160 : !std::is_same< detail::remove_cvref<Context>, storage_ptr >::value &&
161 : !std::is_same< detail::remove_cvref<Context>, value >::value,
162 : value >::type
163 : #else
164 : value
165 : #endif
166 6951 : value_from(
167 : T&& t,
168 : Context const& ctx,
169 : storage_ptr sp = {})
170 : {
171 6951 : value jv(std::move(sp));
172 6951 : value_from( static_cast<T&&>(t), ctx, jv );
173 6951 : return jv;
174 0 : }
175 :
176 : /** Convert an object of type `T` to @ref value.
177 :
178 : This function attempts to convert an object
179 : of type `T` to @ref value using
180 :
181 : @li one of @ref value's constructors,
182 :
183 : @li a library-provided generic conversion, or
184 :
185 : @li a user-provided overload of `tag_invoke`.
186 :
187 : Out of the box the function supports types satisfying
188 : <a href="https://en.cppreference.com/w/cpp/named_req/SequenceContainer"><em>SequenceContainer</em></a>,
189 : arrays, arithmetic types, `bool`, `std::tuple`, `std::pair`,
190 : `std::variant`, `std::optional`, `std::monostate`, and `std::nullopt_t`.
191 :
192 : Conversion of other types is done by calling an overload of `tag_invoke`
193 : found by argument-dependent lookup. Its signature should be similar to:
194 :
195 : @code
196 : void tag_invoke( value_from_tag, value&, T );
197 : @endcode
198 :
199 : @par Exception Safety
200 : Strong guarantee.
201 :
202 : @tparam T The type of the object to convert.
203 :
204 : @param t The object to convert.
205 :
206 : @param jv @ref value out parameter.
207 :
208 : @see @ref value_from_tag, @ref value_to,
209 : <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2019/p1895r0.pdf">
210 : tag_invoke: A general pattern for supporting customisable functions</a>
211 : */
212 : template<class T>
213 : void
214 19 : value_from(
215 : T&& t,
216 : value& jv)
217 : {
218 19 : value_from( static_cast<T&&>(t), detail::no_context(), jv );
219 19 : }
220 :
221 : /** Convert an object of type `T` to @ref value.
222 :
223 : This function attempts to convert an object
224 : of type `T` to @ref value using
225 :
226 : @li one of @ref value's constructors,
227 :
228 : @li a library-provided generic conversion, or
229 :
230 : @li a user-provided overload of `tag_invoke`.
231 :
232 : Out of the box the function supports types satisfying
233 : <a href="https://en.cppreference.com/w/cpp/named_req/SequenceContainer"><em>SequenceContainer</em></a>,
234 : arrays, arithmetic types, `bool`, `std::tuple`, `std::pair`,
235 : `std::variant`, `std::optional`, `std::monostate`, and `std::nullopt_t`.
236 :
237 : Conversion of other types is done by calling an overload of `tag_invoke`
238 : found by argument-dependent lookup. Its signature should be similar to:
239 :
240 : @code
241 : void tag_invoke( value_from_tag, value&, T );
242 : @endcode
243 :
244 : A @ref value constructed
245 : with the @ref storage_ptr passed to @ref value_from is
246 : passed as the second argument to ensure that the memory
247 : resource is correctly propagated.
248 :
249 : @par Exception Safety
250 : Strong guarantee.
251 :
252 : @tparam T The type of the object to convert.
253 :
254 : @returns `t` converted to @ref value.
255 :
256 : @param t The object to convert.
257 :
258 : @param sp A storage pointer referring to the memory resource
259 : to use for the returned @ref value. The default argument for this
260 : parameter is `{}`.
261 :
262 : @see @ref value_from_tag, @ref value_to,
263 : <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2019/p1895r0.pdf">
264 : tag_invoke: A general pattern for supporting customisable functions</a>
265 : */
266 : template<class T>
267 : value
268 222 : value_from(
269 : T&& t,
270 : storage_ptr sp = {})
271 : {
272 : return value_from(
273 222 : static_cast<T&&>(t), detail::no_context(), std::move(sp) );
274 : }
275 :
276 : /** Determine if `T` can be converted to @ref value.
277 :
278 : If `T` can be converted to @ref value via a
279 : call to @ref value_from, the static data member `value`
280 : is defined as `true`. Otherwise, `value` is
281 : defined as `false`.
282 :
283 : @see @ref value_from
284 : */
285 : #ifdef BOOST_JSON_DOCS
286 : template<class T>
287 : using has_value_from = __see_below__;
288 : #else
289 : template<class T>
290 : using has_value_from = detail::can_convert<
291 : detail::remove_cvref<T>, detail::value_from_conversion>;
292 : #endif
293 :
294 : } // namespace json
295 : } // namespace boost
296 :
297 : #endif
|