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