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 - BOOST_CORE_STATIC_ASSERT((  
93 - detail::conversion_round_trips<  
94 - Context, bare_T, detail::value_from_conversion>::value));  
95   using bare_T = detail::remove_cvref<T>; 92   using bare_T = detail::remove_cvref<T>;
96   using cat = detail::value_from_category<Context, bare_T>; 93   using cat = detail::value_from_category<Context, bare_T>;
HITCBC 97   7056 detail::value_from_impl( cat(), jv, std::forward<T>(t), ctx ); 94   7056 detail::value_from_impl( cat(), jv, std::forward<T>(t), ctx );
HITCBC 98   7056 } 95   7056 }
99   96  
100   /** Overload 97   /** Overload
101   @param t 98   @param t
102   @param ctx 99   @param ctx
103   @param sp A storage pointer referring to the memory resource to use for the 100   @param sp A storage pointer referring to the memory resource to use for the
104   returned @ref value. 101   returned @ref value.
105   102  
106   @return Overloads **(2)** and **(4)** return `t` converted to @ref value. 103   @return Overloads **(2)** and **(4)** return `t` converted to @ref value.
107   Overloads **(1)** and **3** return `void` instead and pass their result via 104   Overloads **(1)** and **3** return `void` instead and pass their result via
108   the out parameter `jv`. 105   the out parameter `jv`.
109   */ 106   */
110   template< class T, class Context > 107   template< class T, class Context >
111   #ifndef BOOST_JSON_DOCS 108   #ifndef BOOST_JSON_DOCS
112   typename std::enable_if< 109   typename std::enable_if<
113   !std::is_same< detail::remove_cvref<Context>, storage_ptr >::value && 110   !std::is_same< detail::remove_cvref<Context>, storage_ptr >::value &&
114   !std::is_same< detail::remove_cvref<Context>, value >::value, 111   !std::is_same< detail::remove_cvref<Context>, value >::value,
115   value >::type 112   value >::type
116   #else 113   #else
117   value 114   value
118   #endif 115   #endif
HITCBC 119   7037 value_from( 116   7037 value_from(
120   T&& t, 117   T&& t,
121   Context const& ctx, 118   Context const& ctx,
122   storage_ptr sp = {}) 119   storage_ptr sp = {})
123   { 120   {
HITCBC 124   7037 value jv(std::move(sp)); 121   7037 value jv(std::move(sp));
HITCBC 125   7037 value_from( static_cast<T&&>(t), ctx, jv ); 122   7037 value_from( static_cast<T&&>(t), ctx, jv );
HITCBC 126   7037 return jv; 123   7037 return jv;
MISUBC 127   } 124   }
128   125  
129   /// Overload 126   /// Overload
130   template<class T> 127   template<class T>
131   void 128   void
HITCBC 132   19 value_from( 129   19 value_from(
133   T&& t, 130   T&& t,
134   value& jv) 131   value& jv)
135   { 132   {
HITCBC 136   19 value_from( static_cast<T&&>(t), detail::no_context(), jv ); 133   19 value_from( static_cast<T&&>(t), detail::no_context(), jv );
HITCBC 137   19 } 134   19 }
138   135  
139   /// Overload 136   /// Overload
140   template<class T> 137   template<class T>
141   value 138   value
HITCBC 142   297 value_from( 139   297 value_from(
143   T&& t, 140   T&& t,
144   storage_ptr sp = {}) 141   storage_ptr sp = {})
145   { 142   {
146   return value_from( 143   return value_from(
HITCBC 147   297 static_cast<T&&>(t), detail::no_context(), std::move(sp) ); 144   297 static_cast<T&&>(t), detail::no_context(), std::move(sp) );
148   } 145   }
149   /// @} 146   /// @}
150   147  
151   /** Determine if `T` can be converted to @ref value. 148   /** Determine if `T` can be converted to @ref value.
152   149  
153   If `T` can be converted to @ref value via a call to @ref value_from, the 150   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 151   static data member `value` is defined as `true`. Otherwise, `value` is
155   defined as `false`. 152   defined as `false`.
156   153  
157   @see @ref value_from. 154   @see @ref value_from.
158   */ 155   */
159   #ifdef BOOST_JSON_DOCS 156   #ifdef BOOST_JSON_DOCS
160   template<class T> 157   template<class T>
161   using has_value_from = __see_below__; 158   using has_value_from = __see_below__;
162   #else 159   #else
163   template<class T> 160   template<class T>
164   using has_value_from = detail::can_convert< 161   using has_value_from = detail::can_convert<
165   detail::remove_cvref<T>, detail::value_from_conversion>; 162   detail::remove_cvref<T>, detail::value_from_conversion>;
166   #endif 163   #endif
167   164  
168   } // namespace json 165   } // namespace json
169   } // namespace boost 166   } // namespace boost
170   167  
171   #endif 168   #endif