value_to.hpp 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175
  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. T tag_invoke( value_to_tag<T>, value );
  30. @endcode
  31. The object returned by the function call is
  32. returned by @ref value_to as the result of the
  33. conversion.
  34. @par Constraints
  35. @code
  36. ! std::is_reference< T >::value
  37. @endcode
  38. @par Exception Safety
  39. Strong guarantee.
  40. @tparam T The type to convert to.
  41. @returns `jv` converted to `T`.
  42. @param jv The @ref value to convert.
  43. @see @ref value_to_tag, @ref value_from,
  44. <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2019/p1895r0.pdf">
  45. tag_invoke: A general pattern for supporting customisable functions</a>
  46. */
  47. template<class T>
  48. T
  49. value_to(const value& jv)
  50. {
  51. BOOST_STATIC_ASSERT(! std::is_reference<T>::value);
  52. using bare_T = detail::remove_cvref<T>;
  53. BOOST_STATIC_ASSERT(detail::conversion_round_trips<
  54. bare_T, detail::value_to_conversion>::value);
  55. using impl = detail::value_to_implementation<bare_T>;
  56. return detail::value_to_impl(value_to_tag<bare_T>(), jv, impl());
  57. }
  58. /** Convert a @ref value to a @ref result of `T`.
  59. This function attempts to convert a @ref value
  60. to `result<T>` using
  61. @li one of @ref value's accessors, or
  62. @li a library-provided generic conversion, or
  63. @li a user-provided overload of `tag_invoke`.
  64. Out of the box the function supports types satisfying
  65. <a href="https://en.cppreference.com/w/cpp/named_req/SequenceContainer"><em>SequenceContainer</em></a>,
  66. arrays, arithmetic types, `bool`, `std::tuple`, `std::pair`,
  67. `std::variant`, `std::optional`, `std::monostate`, and `std::nullopt_t`.
  68. Conversion of other types is done by calling an overload of `tag_invoke`
  69. found by argument-dependent lookup. Its signature should be similar to:
  70. @code
  71. result<T> tag_invoke( try_value_to_tag<T>, value const& );
  72. @endcode
  73. If an error occurs during conversion, the result will store the error code
  74. associated with the error. If an exception is thrown, the function will
  75. attempt to retrieve the associated error code and return it, otherwise it
  76. will return `error::exception`.
  77. @par Constraints
  78. @code
  79. ! std::is_reference< T >::value
  80. @endcode
  81. @par Exception Safety
  82. Strong guarantee.
  83. @tparam T The type to convert to.
  84. @param jv The @ref value to convert.
  85. @returns `jv` converted to `result<T>`.
  86. @see @ref value_to_tag, @ref value_to, @ref value_from,
  87. <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2019/p1895r0.pdf">
  88. tag_invoke: A general pattern for supporting customisable functions</a>
  89. */
  90. template<class T>
  91. typename result_for<T, value>::type
  92. try_value_to(const value& jv)
  93. {
  94. BOOST_STATIC_ASSERT(! std::is_reference<T>::value);
  95. using bare_T = detail::remove_cvref<T>;
  96. BOOST_STATIC_ASSERT(detail::conversion_round_trips<
  97. bare_T, detail::value_to_conversion>::value);
  98. using impl = detail::value_to_implementation<bare_T>;
  99. return detail::value_to_impl(
  100. try_value_to_tag<bare_T>(), jv, impl());
  101. }
  102. /** Convert a @ref value to an object of type `T`.
  103. This overload is **deleted** and participates in overload resolution only
  104. when `U` is not @ref value. The overload exists to prevent unintented
  105. creation of temporary @ref value instances, e.g.
  106. @code
  107. auto flag = value_to<bool>(true);
  108. @endcode
  109. */
  110. template<class T, class U
  111. #ifndef BOOST_JSON_DOCS
  112. , class = typename std::enable_if<!std::is_same<U, value>::value>::type
  113. #endif
  114. >
  115. T
  116. value_to(U const& jv) = delete;
  117. /** Determine a @ref value can be converted to `T`.
  118. If @ref value can be converted to `T` via a
  119. call to @ref value_to, the static data member `value`
  120. is defined as `true`. Otherwise, `value` is
  121. defined as `false`.
  122. @see @ref value_to
  123. */
  124. #ifdef BOOST_JSON_DOCS
  125. template<class T>
  126. using has_value_to = __see_below__;
  127. #else
  128. template<class T>
  129. using has_value_to = detail::can_convert<
  130. detail::remove_cvref<T>, detail::value_to_conversion>;
  131. #endif
  132. } // namespace json
  133. } // namespace boost
  134. #endif