value_from.hpp 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297
  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. #ifndef BOOST_JSON_VALUE_FROM_HPP
  12. #define BOOST_JSON_VALUE_FROM_HPP
  13. #include <boost/json/detail/value_from.hpp>
  14. namespace boost {
  15. namespace json {
  16. /** Convert an object of type `T` to @ref value.
  17. This function attempts to convert an object
  18. of type `T` to @ref value using
  19. @li one of @ref value's constructors,
  20. @li a library-provided generic conversion, or
  21. @li a user-provided overload of `tag_invoke`.
  22. Out of the box the function supports types satisfying
  23. <a href="https://en.cppreference.com/w/cpp/named_req/SequenceContainer"><em>SequenceContainer</em></a>,
  24. arrays, arithmetic types, `bool`, `std::tuple`, `std::pair`,
  25. `std::variant`, `std::optional`, `std::monostate`, and `std::nullopt_t`.
  26. Conversion of other types is done by calling an overload of `tag_invoke`
  27. found by argument-dependent lookup. Its signature should be similar to:
  28. @code
  29. template< class FullContext >
  30. void tag_invoke( value_from_tag, value&, T, const Context& , const FullContext& );
  31. @endcode
  32. or
  33. @code
  34. void tag_invoke( value_from_tag, value&, T, const Context& );
  35. @endcode
  36. or
  37. @code
  38. void tag_invoke( value_from_tag, value&, T );
  39. @endcode
  40. The overloads are checked for existence in that order and the first that
  41. matches will be selected. <br>
  42. The `ctx` argument can be used either as a tag type to provide conversions
  43. for third-party types, or to pass extra data to the conversion function.
  44. @par Exception Safety
  45. Strong guarantee.
  46. @tparam T The type of the object to convert.
  47. @tparam Context The type of context passed to the conversion function.
  48. @param t The object to convert.
  49. @param ctx Context passed to the conversion function.
  50. @param jv @ref value out parameter.
  51. @see @ref value_from_tag, @ref value_to,
  52. <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2019/p1895r0.pdf">
  53. tag_invoke: A general pattern for supporting customisable functions</a>
  54. */
  55. template< class T, class Context >
  56. void
  57. value_from(
  58. T&& t,
  59. Context const& ctx,
  60. value& jv)
  61. {
  62. using bare_T = detail::remove_cvref<T>;
  63. BOOST_STATIC_ASSERT(detail::conversion_round_trips<
  64. Context, bare_T, detail::value_from_conversion>::value);
  65. using cat = detail::value_from_category<Context, bare_T>;
  66. detail::value_from_impl( cat(), jv, std::forward<T>(t), ctx );
  67. }
  68. /** Convert an object of type `T` to @ref value.
  69. This function attempts to convert an object
  70. of type `T` to @ref value using
  71. @li one of @ref value's constructors,
  72. @li a library-provided generic conversion, or
  73. @li a user-provided overload of `tag_invoke`.
  74. Out of the box the function supports types satisfying
  75. <a href="https://en.cppreference.com/w/cpp/named_req/SequenceContainer"><em>SequenceContainer</em></a>,
  76. arrays, arithmetic types, `bool`, `std::tuple`, `std::pair`,
  77. `std::variant`, `std::optional`, `std::monostate`, and `std::nullopt_t`.
  78. Conversion of other types is done by calling an overload of `tag_invoke`
  79. found by argument-dependent lookup. Its signature should be similar to:
  80. @code
  81. template< class FullContext >
  82. void tag_invoke( value_from_tag, value&, T, const Context& , const FullContext& );
  83. @endcode
  84. or
  85. @code
  86. void tag_invoke( value_from_tag, value&, T, const Context& );
  87. @endcode
  88. or
  89. @code
  90. void tag_invoke( value_from_tag, value&, T );
  91. @endcode
  92. The overloads are checked for existence in that order and the first that
  93. matches will be selected. <br>
  94. A @ref value constructed with the @ref storage_ptr passed to
  95. @ref value_from is passed as the second argument to ensure that the memory
  96. resource is correctly propagated.
  97. @par Exception Safety
  98. Strong guarantee.
  99. @tparam T The type of the object to convert.
  100. @tparam Context The type of context passed to the conversion function.
  101. @returns `t` converted to @ref value.
  102. @param t The object to convert.
  103. @param ctx Context passed to the conversion function.
  104. @param sp A storage pointer referring to the memory resource
  105. to use for the returned @ref value. The default argument for this
  106. parameter is `{}`.
  107. @see @ref value_from_tag, @ref value_to,
  108. <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2019/p1895r0.pdf">
  109. tag_invoke: A general pattern for supporting customisable functions</a>
  110. */
  111. template< class T, class Context >
  112. #ifndef BOOST_JSON_DOCS
  113. typename std::enable_if<
  114. !std::is_same< detail::remove_cvref<Context>, storage_ptr >::value &&
  115. !std::is_same< detail::remove_cvref<Context>, value >::value,
  116. value >::type
  117. #else
  118. value
  119. #endif
  120. value_from(
  121. T&& t,
  122. Context const& ctx,
  123. storage_ptr sp = {})
  124. {
  125. value jv(std::move(sp));
  126. value_from( static_cast<T&&>(t), ctx, jv );
  127. return jv;
  128. }
  129. /** Convert an object of type `T` to @ref value.
  130. This function attempts to convert an object
  131. of type `T` to @ref value using
  132. @li one of @ref value's constructors,
  133. @li a library-provided generic conversion, or
  134. @li a user-provided overload of `tag_invoke`.
  135. Out of the box the function supports types satisfying
  136. <a href="https://en.cppreference.com/w/cpp/named_req/SequenceContainer"><em>SequenceContainer</em></a>,
  137. arrays, arithmetic types, `bool`, `std::tuple`, `std::pair`,
  138. `std::variant`, `std::optional`, `std::monostate`, and `std::nullopt_t`.
  139. Conversion of other types is done by calling an overload of `tag_invoke`
  140. found by argument-dependent lookup. Its signature should be similar to:
  141. @code
  142. void tag_invoke( value_from_tag, value&, T );
  143. @endcode
  144. @par Exception Safety
  145. Strong guarantee.
  146. @tparam T The type of the object to convert.
  147. @param t The object to convert.
  148. @param jv @ref value out parameter.
  149. @see @ref value_from_tag, @ref value_to,
  150. <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2019/p1895r0.pdf">
  151. tag_invoke: A general pattern for supporting customisable functions</a>
  152. */
  153. template<class T>
  154. void
  155. value_from(
  156. T&& t,
  157. value& jv)
  158. {
  159. value_from( static_cast<T&&>(t), detail::no_context(), jv );
  160. }
  161. /** Convert an object of type `T` to @ref value.
  162. This function attempts to convert an object
  163. of type `T` to @ref value using
  164. @li one of @ref value's constructors,
  165. @li a library-provided generic conversion, or
  166. @li a user-provided overload of `tag_invoke`.
  167. Out of the box the function supports types satisfying
  168. <a href="https://en.cppreference.com/w/cpp/named_req/SequenceContainer"><em>SequenceContainer</em></a>,
  169. arrays, arithmetic types, `bool`, `std::tuple`, `std::pair`,
  170. `std::variant`, `std::optional`, `std::monostate`, and `std::nullopt_t`.
  171. Conversion of other types is done by calling an overload of `tag_invoke`
  172. found by argument-dependent lookup. Its signature should be similar to:
  173. @code
  174. void tag_invoke( value_from_tag, value&, T );
  175. @endcode
  176. A @ref value constructed
  177. with the @ref storage_ptr passed to @ref value_from is
  178. passed as the second argument to ensure that the memory
  179. resource is correctly propagated.
  180. @par Exception Safety
  181. Strong guarantee.
  182. @tparam T The type of the object to convert.
  183. @returns `t` converted to @ref value.
  184. @param t The object to convert.
  185. @param sp A storage pointer referring to the memory resource
  186. to use for the returned @ref value. The default argument for this
  187. parameter is `{}`.
  188. @see @ref value_from_tag, @ref value_to,
  189. <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2019/p1895r0.pdf">
  190. tag_invoke: A general pattern for supporting customisable functions</a>
  191. */
  192. template<class T>
  193. value
  194. value_from(
  195. T&& t,
  196. storage_ptr sp = {})
  197. {
  198. return value_from(
  199. static_cast<T&&>(t), detail::no_context(), std::move(sp) );
  200. }
  201. /** Determine if `T` can be converted to @ref value.
  202. If `T` can be converted to @ref value via a
  203. call to @ref value_from, the static data member `value`
  204. is defined as `true`. Otherwise, `value` is
  205. defined as `false`.
  206. @see @ref value_from
  207. */
  208. #ifdef BOOST_JSON_DOCS
  209. template<class T>
  210. using has_value_from = __see_below__;
  211. #else
  212. template<class T>
  213. using has_value_from = detail::can_convert<
  214. detail::remove_cvref<T>, detail::value_from_conversion>;
  215. #endif
  216. } // namespace json
  217. } // namespace boost
  218. #endif