100.00% Lines (9/9) 100.00% Functions (4/4)
TLA Baseline Branch
Line Hits Code Line Hits Code
1   // 1   //
2   // Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com) 2   // Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com)
3   // Copyright (c) 2020 Krystian Stasiowski (sdkrystian@gmail.com) 3   // Copyright (c) 2020 Krystian Stasiowski (sdkrystian@gmail.com)
4   // Copyright (c) 2022 Dmitry Arkhipov (grisumbras@gmail.com) 4   // Copyright (c) 2022 Dmitry Arkhipov (grisumbras@gmail.com)
5   // 5   //
6   // Distributed under the Boost Software License, Version 1.0. (See accompanying 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) 7   // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
8   // 8   //
9   // Official repository: https://github.com/boostorg/json 9   // Official repository: https://github.com/boostorg/json
10   // 10   //
11   11  
12   #ifndef BOOST_JSON_VALUE_TO_HPP 12   #ifndef BOOST_JSON_VALUE_TO_HPP
13   #define BOOST_JSON_VALUE_TO_HPP 13   #define BOOST_JSON_VALUE_TO_HPP
14   14  
15   #include <boost/core/detail/static_assert.hpp> 15   #include <boost/core/detail/static_assert.hpp>
16   #include <boost/json/detail/value_to.hpp> 16   #include <boost/json/detail/value_to.hpp>
17   17  
18   namespace boost { 18   namespace boost {
19   namespace json { 19   namespace json {
20   20  
21   /** Convert a @ref value to an object of type `T`. 21   /** Convert a @ref value to an object of type `T`.
22   22  
23   This function attempts to convert a @ref value 23   This function attempts to convert a @ref value
24   to `T` using 24   to `T` using
25   25  
26   @li one of @ref value's accessors, or 26   @li one of @ref value's accessors, or
27   @li a library-provided generic conversion, or 27   @li a library-provided generic conversion, or
28   @li a user-provided overload of `tag_invoke`. 28   @li a user-provided overload of `tag_invoke`.
29   29  
30   Out of the box the function supports default constructible types satisfying 30   Out of the box the function supports default constructible types satisfying
31   {req_SequenceContainer}, arrays, arithmetic types, `bool`, `std::tuple`, 31   {req_SequenceContainer}, arrays, arithmetic types, `bool`, `std::tuple`,
32   `std::pair`, `std::optional`, `std::variant`, `std::nullptr_t`, and structs 32   `std::pair`, `std::optional`, `std::variant`, `std::nullptr_t`, and structs
33   and enums described using Boost.Describe. 33   and enums described using Boost.Describe.
34   34  
35   Conversion of other types is done by calling an overload of `tag_invoke` 35   Conversion of other types is done by calling an overload of `tag_invoke`
36   found by argument-dependent lookup. Its signature should be similar to: 36   found by argument-dependent lookup. Its signature should be similar to:
37   37  
38   @code 38   @code
39   template< class FullContext > 39   template< class FullContext >
40   T tag_invoke( value_to_tag<T>, const value&, const Context& , const FullContext& ); 40   T tag_invoke( value_to_tag<T>, const value&, const Context& , const FullContext& );
41   @endcode 41   @endcode
42   42  
43   or 43   or
44   44  
45   @code 45   @code
46   T tag_invoke( value_to_tag<T>, const value&, const Context& ); 46   T tag_invoke( value_to_tag<T>, const value&, const Context& );
47   @endcode 47   @endcode
48   48  
49   or 49   or
50   50  
51   @code 51   @code
52   result<T> tag_invoke( value_to_tag<T>, const value& ); 52   result<T> tag_invoke( value_to_tag<T>, const value& );
53   @endcode 53   @endcode
54   54  
55   The overloads are checked for existence in that order and the first that 55   The overloads are checked for existence in that order and the first that
56   matches will be selected. 56   matches will be selected.
57   57  
58   The object returned by the function call is returned by @ref value_to as 58   The object returned by the function call is returned by @ref value_to as
59   the result of the conversion. 59   the result of the conversion.
60   60  
61   The `ctx` argument can be used either as a tag type to provide conversions 61   The `ctx` argument can be used either as a tag type to provide conversions
62   for third-party types, or to pass extra data to the conversion function. 62   for third-party types, or to pass extra data to the conversion function.
63   63  
64   Overload **(3)** is **deleted** and participates in overload resolution 64   Overload **(3)** is **deleted** and participates in overload resolution
65   only when `U` is not @ref value. The overload exists to prevent unintented 65   only when `U` is not @ref value. The overload exists to prevent unintented
66   creation of temporary @ref value instances, e.g. 66   creation of temporary @ref value instances, e.g.
67   67  
68   @code 68   @code
69   auto flag = value_to<bool>(true); 69   auto flag = value_to<bool>(true);
70   @endcode 70   @endcode
71   71  
72   @par Constraints 72   @par Constraints
73   @code 73   @code
74   ! std::is_reference< T >::value 74   ! std::is_reference< T >::value
75   @endcode 75   @endcode
76   76  
77   @par Exception Safety 77   @par Exception Safety
78   Strong guarantee. 78   Strong guarantee.
79   79  
80   @tparam T The type to convert to. 80   @tparam T The type to convert to.
81   81  
82   @tparam Context The type of context passed to the conversion function. 82   @tparam Context The type of context passed to the conversion function.
83   83  
84   @returns `jv` converted to `result<T>`. 84   @returns `jv` converted to `result<T>`.
85   85  
86   @param jv The @ref value to convert. 86   @param jv The @ref value to convert.
87   87  
88   @param ctx Context passed to the conversion function. 88   @param ctx Context passed to the conversion function.
89   89  
90   @see @ref value_to_tag, @ref value_from, 90   @see @ref value_to_tag, @ref value_from,
91   <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2019/p1895r0.pdf"> 91   <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2019/p1895r0.pdf">
92   tag_invoke: A general pattern for supporting customisable functions</a> 92   tag_invoke: A general pattern for supporting customisable functions</a>
93   93  
94   @{ 94   @{
95   */ 95   */
96   template< class T, class Context > 96   template< class T, class Context >
97   T 97   T
HITCBC 98   410 value_to( value const& jv, Context const& ctx ) 98   410 value_to( value const& jv, Context const& ctx )
99   { 99   {
100   BOOST_CORE_STATIC_ASSERT( ! std::is_reference<T>::value ); 100   BOOST_CORE_STATIC_ASSERT( ! std::is_reference<T>::value );
101 - BOOST_CORE_STATIC_ASSERT((  
102 - detail::conversion_round_trips<  
103 - Context, bare_T, detail::value_to_conversion>::value));  
104   using bare_T = detail::remove_cvref<T>; 101   using bare_T = detail::remove_cvref<T>;
105   using cat = detail::value_to_category<Context, bare_T>; 102   using cat = detail::value_to_category<Context, bare_T>;
HITCBC 106   410 return detail::value_to_impl( cat(), value_to_tag<bare_T>(), jv, ctx ); 103   410 return detail::value_to_impl( cat(), value_to_tag<bare_T>(), jv, ctx );
107   } 104   }
108   105  
109   /// Overload 106   /// Overload
110   template<class T> 107   template<class T>
111   T 108   T
HITCBC 112   131 value_to(const value& jv) 109   131 value_to(const value& jv)
113   { 110   {
HITCBC 114   192 return value_to<T>( jv, detail::no_context() ); 111   192 return value_to<T>( jv, detail::no_context() );
115   } 112   }
116   113  
117   /// Overload 114   /// Overload
118   template<class T, class U 115   template<class T, class U
119   #ifndef BOOST_JSON_DOCS 116   #ifndef BOOST_JSON_DOCS
120   , class = typename std::enable_if<!std::is_same<U, value>::value>::type 117   , class = typename std::enable_if<!std::is_same<U, value>::value>::type
121   #endif 118   #endif
122   > 119   >
123   T 120   T
124   value_to(U const& jv) = delete; 121   value_to(U const& jv) = delete;
125   /// @} 122   /// @}
126   123  
127   /** Convert a @ref value to a @ref boost::system::result. 124   /** Convert a @ref value to a @ref boost::system::result.
128   125  
129   This function attempts to convert a @ref value to `result<T>` using 126   This function attempts to convert a @ref value to `result<T>` using
130   127  
131   @li one of @ref value's accessors, or 128   @li one of @ref value's accessors, or
132   @li a library-provided generic conversion, or 129   @li a library-provided generic conversion, or
133   @li a user-provided overload of `tag_invoke`. 130   @li a user-provided overload of `tag_invoke`.
134   131  
135   Out of the box the function supports default constructible types satisfying 132   Out of the box the function supports default constructible types satisfying
136   {req_SequenceContainer}, arrays, arithmetic types, `bool`, `std::tuple`, 133   {req_SequenceContainer}, arrays, arithmetic types, `bool`, `std::tuple`,
137   `std::pair`, `std::optional`, `std::variant`, `std::nullptr_t`, and structs 134   `std::pair`, `std::optional`, `std::variant`, `std::nullptr_t`, and structs
138   and enums described using Boost.Describe. 135   and enums described using Boost.Describe.
139   136  
140   Conversion of other types is done by calling an overload of `tag_invoke` 137   Conversion of other types is done by calling an overload of `tag_invoke`
141   found by argument-dependent lookup. Its signature should be similar to: 138   found by argument-dependent lookup. Its signature should be similar to:
142   139  
143   @code 140   @code
144   template< class FullContext > 141   template< class FullContext >
145   result<T> tag_invoke( try_value_to_tag<T>, const value&, const Context& , const FullContext& ); 142   result<T> tag_invoke( try_value_to_tag<T>, const value&, const Context& , const FullContext& );
146   @endcode 143   @endcode
147   144  
148   or 145   or
149   146  
150   @code 147   @code
151   result<T> tag_invoke( try_value_to_tag<T>, const value&, const Context& ); 148   result<T> tag_invoke( try_value_to_tag<T>, const value&, const Context& );
152   @endcode 149   @endcode
153   150  
154   or 151   or
155   152  
156   @code 153   @code
157   result<T> tag_invoke( try_value_to_tag<T>, const value& ); 154   result<T> tag_invoke( try_value_to_tag<T>, const value& );
158   @endcode 155   @endcode
159   156  
160   The overloads are checked for existence in that order and the first that 157   The overloads are checked for existence in that order and the first that
161   matches will be selected. 158   matches will be selected.
162   159  
163   If an error occurs during conversion, the result will store the error code 160   If an error occurs during conversion, the result will store the error code
164   associated with the error. If an exception is thrown, the function will 161   associated with the error. If an exception is thrown, the function will
165   attempt to retrieve the associated error code and return it, otherwise it 162   attempt to retrieve the associated error code and return it, otherwise it
166   will return `error::exception`, unless the exception type is 163   will return `error::exception`, unless the exception type is
167   @ref std::bad_alloc, which will be allowed to propagate. 164   @ref std::bad_alloc, which will be allowed to propagate.
168   165  
169   The `ctx` argument can be used either as a tag type to provide conversions 166   The `ctx` argument can be used either as a tag type to provide conversions
170   for third-party types, or to pass extra data to the conversion function. 167   for third-party types, or to pass extra data to the conversion function.
171   168  
172   @par Constraints 169   @par Constraints
173   @code 170   @code
174   ! std::is_reference< T >::value 171   ! std::is_reference< T >::value
175   @endcode 172   @endcode
176   173  
177   @par Exception Safety 174   @par Exception Safety
178   Strong guarantee. 175   Strong guarantee.
179   176  
180   @tparam T The type to convert to. 177   @tparam T The type to convert to.
181   @tparam Context The type of context passed to the conversion function. 178   @tparam Context The type of context passed to the conversion function.
182   179  
183   @param jv The @ref value to convert. 180   @param jv The @ref value to convert.
184   @param ctx Context passed to the conversion function. 181   @param ctx Context passed to the conversion function.
185   182  
186   @returns `jv` converted to `result<T>`. 183   @returns `jv` converted to `result<T>`.
187   184  
188   @see @ref value_to_tag, @ref value_to, @ref value_from, 185   @see @ref value_to_tag, @ref value_to, @ref value_from,
189   [tag_invoke: A general pattern for supporting customisable functions](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2019/p1895r0.pdf). 186   [tag_invoke: A general pattern for supporting customisable functions](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2019/p1895r0.pdf).
190   187  
191   @{ 188   @{
192   */ 189   */
193   template< class T, class Context > 190   template< class T, class Context >
194   typename result_for<T, value>::type 191   typename result_for<T, value>::type
HITCBC 195   3763 try_value_to( value const& jv, Context const& ctx ) 192   3763 try_value_to( value const& jv, Context const& ctx )
196   { 193   {
197   BOOST_CORE_STATIC_ASSERT( ! std::is_reference<T>::value ); 194   BOOST_CORE_STATIC_ASSERT( ! std::is_reference<T>::value );
198 - BOOST_CORE_STATIC_ASSERT((  
199 - detail::conversion_round_trips<  
200 - Context, bare_T, detail::value_to_conversion>::value));  
201   using bare_T = detail::remove_cvref<T>; 195   using bare_T = detail::remove_cvref<T>;
202   using cat = detail::value_to_category<Context, bare_T>; 196   using cat = detail::value_to_category<Context, bare_T>;
HITCBC 203   3573 return detail::value_to_impl( 197   3573 return detail::value_to_impl(
HITCBC 204   3757 cat(), try_value_to_tag<bare_T>(), jv, ctx ); 198   3757 cat(), try_value_to_tag<bare_T>(), jv, ctx );
205   } 199   }
206   200  
207   /// Overload 201   /// Overload
208   template<class T> 202   template<class T>
209   typename result_for<T, value>::type 203   typename result_for<T, value>::type
HITCBC 210   130 try_value_to(const value& jv) 204   130 try_value_to(const value& jv)
211   { 205   {
HITCBC 212   163 return try_value_to<T>( jv, detail::no_context() ); 206   163 return try_value_to<T>( jv, detail::no_context() );
213   } 207   }
214   /// @} 208   /// @}
215   209  
216   /** Determine if a @ref value can be converted to `T`. 210   /** Determine if a @ref value can be converted to `T`.
217   211  
218   If @ref value can be converted to `T` via a 212   If @ref value can be converted to `T` via a
219   call to @ref value_to, the static data member `value` 213   call to @ref value_to, the static data member `value`
220   is defined as `true`. Otherwise, `value` is 214   is defined as `true`. Otherwise, `value` is
221   defined as `false`. 215   defined as `false`.
222   216  
223   @see @ref value_to 217   @see @ref value_to
224   */ 218   */
225   #ifdef BOOST_JSON_DOCS 219   #ifdef BOOST_JSON_DOCS
226   template<class T> 220   template<class T>
227   using has_value_to = __see_below__; 221   using has_value_to = __see_below__;
228   #else 222   #else
229   template<class T> 223   template<class T>
230   using has_value_to = detail::can_convert< 224   using has_value_to = detail::can_convert<
231   detail::remove_cvref<T>, detail::value_to_conversion>; 225   detail::remove_cvref<T>, detail::value_to_conversion>;
232   #endif 226   #endif
233   227  
234   } // namespace json 228   } // namespace json
235   } // namespace boost 229   } // namespace boost
236   230  
237   #endif 231   #endif