value_to.hpp 10.0 KB

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