result_for.hpp 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146
  1. //
  2. // Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com)
  3. // Copyright (c) 2024 Dmitry Arkhipov (grisumbras@yandex.ru)
  4. //
  5. // Distributed under the Boost Software License, Version 1.0. (See accompanying
  6. // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  7. //
  8. // Official repository: https://github.com/boostorg/json
  9. //
  10. #ifndef BOOST_JSON_RESULT_FOR_HPP
  11. #define BOOST_JSON_RESULT_FOR_HPP
  12. #include <boost/json/detail/config.hpp>
  13. #include <boost/json/fwd.hpp>
  14. #include <boost/assert/source_location.hpp>
  15. #include <boost/system/result.hpp>
  16. namespace boost {
  17. namespace json {
  18. /**
  19. Helper trait that returns @ref result
  20. The primary template is an incomplete type. The library provides a partial
  21. specialisation `result_for<T1, value>`, that has nested type alias `type`
  22. that aliases the type `result<T1>`.
  23. The purpose of this trait is to let users provide non-throwing conversions
  24. for their types without creating a physical dependency on Boost.Json. For
  25. example:
  26. @code
  27. namespace boost
  28. {
  29. namespace json
  30. {
  31. template<class T>
  32. struct value_to_tag;
  33. template<class T1, class T2>
  34. struct result_for;
  35. }
  36. }
  37. namespace mine
  38. {
  39. class my_class;
  40. ...
  41. template<class JsonValue>
  42. boost::json::result_for<my_class, JsonValue>
  43. tag_invoke(boost::json::try_value_to_tag<my_class>, const JsonValue& jv)
  44. { ... }
  45. }
  46. @endcode
  47. @see @ref try_value_to, @ref try_value_to_tag
  48. */
  49. template <class T1, class T2>
  50. struct result_for;
  51. /** Create @ref result storing a portable error code
  52. This function constructs a `boost::system::result<T>` that stores
  53. `boost::system::error_code` with `value()` equal to `e` and `category()`
  54. equal to `boost::system::generic_category()`. <br>
  55. The main use for this function is in implementation of functions returning
  56. @ref result, without including `boost/json/system_error.hpp` or even
  57. `<system_error>`. In particular, it may be useful for customizations of
  58. @ref try_value_to without creating a physical dependency on Boost.JSON.
  59. For example:
  60. @code
  61. #include <cerrno>
  62. #include <boost/assert/source_location.hpp>
  63. namespace boost
  64. {
  65. namespace json
  66. {
  67. class value;
  68. template<class T>
  69. struct try_value_to_tag;
  70. template<class T1, class T2>
  71. struct result_for;
  72. template <class T>
  73. typename result_for<T, value>::type
  74. result_from_errno(int e, boost::source_location const* loc) noexcept
  75. }
  76. }
  77. namespace mine
  78. {
  79. class my_class;
  80. ...
  81. template<class JsonValue>
  82. boost::json::result_for<my_class, JsonValue>
  83. tag_invoke(boost::json::try_value_to_tag<my_class>, const JsonValue& jv)
  84. {
  85. BOOST_STATIC_CONSTEXPR boost::source_location loc = BOOST_CURRENT_LOCATION;
  86. if( !jv.is_null() )
  87. return boost::json::result_from_errno<my_class>(EINVAL, &loc);
  88. return my_class();
  89. }
  90. }
  91. @endcode
  92. @par Exception Safety
  93. Does not throw exceptions.
  94. @tparam T The value type of returned `result`.
  95. @param e The error value.
  96. @param loc The error location.
  97. @returns `boost::system::error_code` with `value()` equal to `e` and
  98. `category()` equal to `boost::system::generic_category()`.
  99. @see @ref try_value_to_tag, @ref try_value_to, @ref result_for,
  100. <a href="https://www.boost.org/doc/libs/develop/libs/system/doc/html/system.html#ref_generic_category">
  101. `boost::system::generic_category`</a>,
  102. <a href="https://www.boost.org/doc/libs/master/libs/assert/doc/html/assert.html#source_location_support">
  103. `boost::source_location`</a>.
  104. */
  105. template <class T>
  106. typename result_for<T, value>::type
  107. result_from_errno(int e, boost::source_location const* loc) noexcept
  108. {
  109. system::error_code ec(e, system::generic_category(), loc);
  110. return {system::in_place_error, ec};
  111. }
  112. } // namespace json
  113. } // namespace boost
  114. #endif // BOOST_JSON_RESULT_FOR_HPP