GCC Code Coverage Report


Directory: libs/json/include/boost/json/
File: value_from.hpp
Date: 2026-01-06 06:25:57
Exec Total Coverage
Lines: 12 13 92.3%
Functions: 426 432 98.6%
Branches: 4 4 100.0%

Line Branch Exec Source
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/core/detail/static_assert.hpp>
16 #include <boost/json/detail/value_from.hpp>
17
18 namespace boost {
19 namespace json {
20
21 /** Convert an object of type `T` to @ref value.
22
23 This function attempts to convert an object
24 of type `T` to @ref value using
25
26 @li one of @ref value's constructors,
27
28 @li a library-provided generic conversion, or
29
30 @li a user-provided overload of `tag_invoke`.
31
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.
36
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:
39
40 @code
41 template< class FullContext >
42 void tag_invoke( value_from_tag, value&, T, const Context&, const FullContext& );
43 @endcode
44
45 or
46
47 @code
48 void tag_invoke( value_from_tag, value&, T, const Context& );
49 @endcode
50
51 or
52
53 @code
54 void tag_invoke( value_from_tag, value&, T );
55 @endcode
56
57 The overloads are checked for existence in that order and the first that
58 matches will be selected. <br>
59
60 The `ctx` argument can be used either as a tag type to provide conversions
61 for third-party types, or to pass extra data to the conversion function.
62
63 Overloads **(2)** and **(4)** construct their return value using the
64 @ref storage_ptr `sp`, which ensures that the memory resource is correctly
65 propagated.
66
67 @par Exception Safety
68 Strong guarantee.
69
70 @tparam T The type of the object to convert.
71
72 @tparam Context The type of context passed to the conversion function.
73
74 @param t The object to convert.
75
76 @param ctx Context passed to the conversion function.
77
78 @param jv @ref value out parameter.
79
80 @see @ref value_from_tag, @ref value_to,
81 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2019/p1895r0.pdf">
82 tag_invoke: A general pattern for supporting customisable functions</a>
83 */
84 /// @{
85 template< class T, class Context >
86 void
87 13940 value_from(
88 T&& t,
89 Context const& ctx,
90 value& jv)
91 {
92 using bare_T = detail::remove_cvref<T>;
93 BOOST_CORE_STATIC_ASSERT((
94 detail::conversion_round_trips<
95 Context, bare_T, detail::value_from_conversion>::value));
96 using cat = detail::value_from_category<Context, bare_T>;
97
1/1
✓ Branch 2 taken 24 times.
13940 detail::value_from_impl( cat(), jv, std::forward<T>(t), ctx );
98 13940 }
99
100 /** Overload
101 @param t
102 @param ctx
103 @param sp A storage pointer referring to the memory resource to use for the
104 returned @ref value.
105
106 @return Overloads **(2)** and **(4)** return `t` converted to @ref value.
107 Overloads **(1)** and **3** return `void` instead and pass their result via
108 the out parameter `jv`.
109 */
110 template< class T, class Context >
111 #ifndef BOOST_JSON_DOCS
112 typename std::enable_if<
113 !std::is_same< detail::remove_cvref<Context>, storage_ptr >::value &&
114 !std::is_same< detail::remove_cvref<Context>, value >::value,
115 value >::type
116 #else
117 value
118 #endif
119 13902 value_from(
120 T&& t,
121 Context const& ctx,
122 storage_ptr sp = {})
123 {
124 13902 value jv(std::move(sp));
125
1/1
✓ Branch 1 taken 6951 times.
13902 value_from( static_cast<T&&>(t), ctx, jv );
126 13902 return jv;
127 }
128
129 /// Overload
130 template<class T>
131 void
132 38 value_from(
133 T&& t,
134 value& jv)
135 {
136
1/1
✓ Branch 1 taken 19 times.
38 value_from( static_cast<T&&>(t), detail::no_context(), jv );
137 38 }
138
139 /// Overload
140 template<class T>
141 value
142 222 value_from(
143 T&& t,
144 storage_ptr sp = {})
145 {
146 return value_from(
147
1/1
✓ Branch 3 taken 1 times.
222 static_cast<T&&>(t), detail::no_context(), std::move(sp) );
148 }
149 /// @}
150
151 /** Determine if `T` can be converted to @ref value.
152
153 If `T` can be converted to @ref value via a call to @ref value_from, the
154 static data member `value` is defined as `true`. Otherwise, `value` is
155 defined as `false`.
156
157 @see @ref value_from.
158 */
159 #ifdef BOOST_JSON_DOCS
160 template<class T>
161 using has_value_from = __see_below__;
162 #else
163 template<class T>
164 using has_value_from = detail::can_convert<
165 detail::remove_cvref<T>, detail::value_from_conversion>;
166 #endif
167
168 } // namespace json
169 } // namespace boost
170
171 #endif
172