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 of type `T` to @ref value using
24 - of type `T` to @ref value using  
25   24  
26 - @li one of @ref value's constructors, 25 + - one of @ref value's constructors,
  26 + - a library-provided generic conversion, or
  27 + - a user-provided overload of `tag_invoke`.
27   28  
28 - @li a library-provided generic conversion, or 29 + In order to perform the conversion the function selects an appropriate
  30 + implementation based on the types `T` and `Context` (if provided).
29   31  
30 - @li a user-provided overload of `tag_invoke`. 32 + 1. If `Context` is available and is not `std::tuple<C...>`
31   33  
32 - Out of the function supports default constructible types satisfying 34 + a. check if `use_category<T, Context>::value` is not
33 - {req_SequenceContainer}, arrays, arithmetic types, `bool`, `std::tuple`, 35 + @ref conversion_category::unknown; otherwise
34 - `std::pair`, `std::optional`, `std::variant`, `std::nullptr_t`, and structs  
35 - and enums described using Boost.Describe.  
36   36  
37 - Conversion of other types is done by calling an overload of `tag_invoke` 37 + b. check if a `tag_invoke` overload from the list below that takes a
38 - found by argument-dependent lookup. Its signature should be similar to: 38 + `Context const&` exists.
  39 +
  40 + 2. Otherwise, if `Context` is available, and is `std::tuple<C...>` repeat
  41 + steps **1** and **2** recursively for every `C` until either
  42 + step **1.a** or **1.b** succeeds for some `C`.
  43 +
  44 + 3. Failing that,
  45 +
  46 + a. check if `use_category<T>::value` is not
  47 + @ref conversion_category::unknown; otherwise
  48 +
  49 + b. check if a `tag_invoke` overload from the list below that takes only
  50 + 2 parameters exists; otherwise
  51 +
  52 + c. check if `T` is one of @ref value, @ref array, @ref object,
  53 + or @ref string; otherwise
  54 +
  55 + d. check if `T` matches one of the categories of types described in the
  56 + table "Conversion categories" in \<\<Value Conversion>> section.
  57 +
  58 + These steps determine both the appropriate category of conversion for `T`,
  59 + and, if necessary, the effective context `C` that will be used for
  60 + conversion. If the category is selected on steps **1.a**, **3.a**, **3.c**,
  61 + or **3.d**, the library provides a suitable conversion implementation.
  62 + If the category is selected on steps **2.b** or **3.b**, then a
  63 + user-provided `tag_invoke` overload is used.
  64 +
  65 + The overloads of `tag_invoke` that will be considered by this function
  66 + are in the following list. Overloads that appear higher in the list have
  67 + higher priority.
39   68  
40   @code 69   @code
41   template< class FullContext > 70   template< class FullContext >
42 - @endcode  
43 -  
44 - or  
45   void tag_invoke( value_from_tag, value&, T, const Context&, const FullContext& ); 71   void tag_invoke( value_from_tag, value&, T, const Context&, const FullContext& );
46 - @code  
47   72  
48 - @endcode  
49 -  
50 - or  
51   void tag_invoke( value_from_tag, value&, T, const Context& ); 73   void tag_invoke( value_from_tag, value&, T, const Context& );
52 - @code  
53   74  
54   void tag_invoke( value_from_tag, value&, T ); 75   void tag_invoke( value_from_tag, value&, T );
55   @endcode 76   @endcode
56 - The overloads are checked for existence in that order and the first that  
57 - matches will be selected. <br>  
58 -  
59   77  
60   The `ctx` argument can be used either as a tag type to provide conversions 78   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. 79   for third-party types, or to pass extra data to the conversion function.
62   80  
63   Overloads **(2)** and **(4)** construct their return value using the 81   Overloads **(2)** and **(4)** construct their return value using the
64   @ref storage_ptr `sp`, which ensures that the memory resource is correctly 82   @ref storage_ptr `sp`, which ensures that the memory resource is correctly
65   propagated. 83   propagated.
66   84  
67   @par Exception Safety 85   @par Exception Safety
68   Strong guarantee. 86   Strong guarantee.
69   87  
70   @tparam T The type of the object to convert. 88   @tparam T The type of the object to convert.
71   89  
72   @tparam Context The type of context passed to the conversion function. 90   @tparam Context The type of context passed to the conversion function.
73   91  
74   @param t The object to convert. 92   @param t The object to convert.
75   93  
76   @param ctx Context passed to the conversion function. 94   @param ctx Context passed to the conversion function.
77   95  
78   @param jv @ref value out parameter. 96   @param jv @ref value out parameter.
79   97  
80   @see @ref value_from_tag, @ref value_to, 98   @see @ref value_from_tag, @ref value_to,
81   <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2019/p1895r0.pdf"> 99   <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> 100   tag_invoke: A general pattern for supporting customisable functions</a>
83   */ 101   */
84   /// @{ 102   /// @{
85   template< class T, class Context > 103   template< class T, class Context >
86   void 104   void
HITCBC 87   7056 value_from( 105   7056 value_from(
88   T&& t, 106   T&& t,
89   Context const& ctx, 107   Context const& ctx,
90   value& jv) 108   value& jv)
91   { 109   {
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>; 110   using bare_T = detail::remove_cvref<T>;
96   using cat = detail::value_from_category<Context, bare_T>; 111   using cat = detail::value_from_category<Context, bare_T>;
HITCBC 97   7056 detail::value_from_impl( cat(), jv, std::forward<T>(t), ctx ); 112   7056 detail::value_from_impl( cat(), jv, std::forward<T>(t), ctx );
HITCBC 98   7056 } 113   7056 }
99   114  
100   /** Overload 115   /** Overload
101   @param t 116   @param t
102   @param ctx 117   @param ctx
103   @param sp A storage pointer referring to the memory resource to use for the 118   @param sp A storage pointer referring to the memory resource to use for the
104   returned @ref value. 119   returned @ref value.
105   120  
106   @return Overloads **(2)** and **(4)** return `t` converted to @ref value. 121   @return Overloads **(2)** and **(4)** return `t` converted to @ref value.
107   Overloads **(1)** and **3** return `void` instead and pass their result via 122   Overloads **(1)** and **3** return `void` instead and pass their result via
108   the out parameter `jv`. 123   the out parameter `jv`.
109   */ 124   */
110   template< class T, class Context > 125   template< class T, class Context >
111   #ifndef BOOST_JSON_DOCS 126   #ifndef BOOST_JSON_DOCS
112   typename std::enable_if< 127   typename std::enable_if<
113   !std::is_same< detail::remove_cvref<Context>, storage_ptr >::value && 128   !std::is_same< detail::remove_cvref<Context>, storage_ptr >::value &&
114   !std::is_same< detail::remove_cvref<Context>, value >::value, 129   !std::is_same< detail::remove_cvref<Context>, value >::value,
115   value >::type 130   value >::type
116   #else 131   #else
117   value 132   value
118   #endif 133   #endif
HITCBC 119   7037 value_from( 134   7037 value_from(
120   T&& t, 135   T&& t,
121   Context const& ctx, 136   Context const& ctx,
122   storage_ptr sp = {}) 137   storage_ptr sp = {})
123   { 138   {
HITCBC 124   7037 value jv(std::move(sp)); 139   7037 value jv(std::move(sp));
HITCBC 125   7037 value_from( static_cast<T&&>(t), ctx, jv ); 140   7037 value_from( static_cast<T&&>(t), ctx, jv );
HITCBC 126   7037 return jv; 141   7037 return jv;
MISUBC 127   } 142   }
128   143  
129   /// Overload 144   /// Overload
130   template<class T> 145   template<class T>
131   void 146   void
HITCBC 132   19 value_from( 147   19 value_from(
133   T&& t, 148   T&& t,
134   value& jv) 149   value& jv)
135   { 150   {
HITCBC 136   19 value_from( static_cast<T&&>(t), detail::no_context(), jv ); 151   19 value_from( static_cast<T&&>(t), detail::no_context(), jv );
HITCBC 137   19 } 152   19 }
138   153  
139   /// Overload 154   /// Overload
140   template<class T> 155   template<class T>
141   value 156   value
HITCBC 142   297 value_from( 157   297 value_from(
143   T&& t, 158   T&& t,
144   storage_ptr sp = {}) 159   storage_ptr sp = {})
145   { 160   {
146   return value_from( 161   return value_from(
HITCBC 147   297 static_cast<T&&>(t), detail::no_context(), std::move(sp) ); 162   297 static_cast<T&&>(t), detail::no_context(), std::move(sp) );
148   } 163   }
149   /// @} 164   /// @}
150   165  
151   /** Determine if `T` can be converted to @ref value. 166   /** Determine if `T` can be converted to @ref value.
152   167  
153   If `T` can be converted to @ref value via a call to @ref value_from, the 168   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 169   static data member `value` is defined as `true`. Otherwise, `value` is
155   defined as `false`. 170   defined as `false`.
156   171  
157   @see @ref value_from. 172   @see @ref value_from.
158   */ 173   */
159   #ifdef BOOST_JSON_DOCS 174   #ifdef BOOST_JSON_DOCS
160   template<class T> 175   template<class T>
161   using has_value_from = __see_below__; 176   using has_value_from = __see_below__;
162   #else 177   #else
163   template<class T> 178   template<class T>
164   using has_value_from = detail::can_convert< 179   using has_value_from = detail::can_convert<
165   detail::remove_cvref<T>, detail::value_from_conversion>; 180   detail::remove_cvref<T>, detail::value_from_conversion>;
166   #endif 181   #endif
167   182  
168   } // namespace json 183   } // namespace json
169   } // namespace boost 184   } // namespace boost
170   185  
171   #endif 186   #endif