system_error.hpp 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225
  1. //
  2. // Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com)
  3. // Copyright (c) 2022 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_SYSTEM_ERROR_HPP
  11. #define BOOST_JSON_SYSTEM_ERROR_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/error_code.hpp>
  16. #include <boost/system/result.hpp>
  17. #include <boost/system/system_error.hpp>
  18. namespace boost {
  19. namespace json {
  20. /// The type of error code used by the library.
  21. using error_code = boost::system::error_code;
  22. /// The type of error category used by the library.
  23. using error_category = boost::system::error_category;
  24. /// The type of error condition used by the library.
  25. using error_condition = boost::system::error_condition;
  26. /// The type of system error thrown by the library.
  27. using system_error = boost::system::system_error;
  28. /** The type of result returned by library functions
  29. This is an alias template used as the return type for functions that can
  30. either return a value, or fail with an error code. This is a brief
  31. synopsis of the type:
  32. @par Declaration
  33. @code
  34. template< class T >
  35. class result
  36. {
  37. public:
  38. // Return true if the result contains an error
  39. constexpr bool has_error() const noexcept;
  40. // These two return true if the result contains a value
  41. constexpr bool has_value() const noexcept;
  42. constexpr explicit operator bool() const noexcept;
  43. // Return the value or throw an exception if has_value() == false
  44. constexpr T& value();
  45. constexpr T const& value() const;
  46. // Return the value, assuming the result contains it
  47. constexpr T& operator*();
  48. constexpr T const& operator*() const;
  49. // Return the error, which is default constructed if has_error() == false
  50. constexpr error_code error() const noexcept;
  51. ...more
  52. };
  53. @endcode
  54. @par Usage
  55. Given the function @ref try_value_to with this signature:
  56. @code
  57. template< class T>
  58. result< T > try_value_to( const value& jv );
  59. @endcode
  60. The following statement captures the value in a variable upon success,
  61. otherwise throws:
  62. @code
  63. int n = try_value_to<int>( jv ).value();
  64. @endcode
  65. This statement captures the result in a variable and inspects the error
  66. condition:
  67. @code
  68. result< int > r = try_value_to<int>( jv );
  69. if( r )
  70. std::cout << *r;
  71. else
  72. std::cout << r.error();
  73. @endcode
  74. @note For a full synopsis of the type, please see the corresponding
  75. documentation in Boost.System.
  76. @tparam T The type of value held by the result.
  77. */
  78. template< class T >
  79. using result = boost::system::result<T>;
  80. /**
  81. Helper trait that returns @ref result
  82. The primary template is an incomplete type. The library provides a partial
  83. specialisation `result_for<T1, value>`, that has nested type alias `type`
  84. that aliases the type `result<T1>`.
  85. The purpose of this trait is to let users provide non-throwing conversions
  86. for their types without creating a physical dependency on Boost.Json. For
  87. example:
  88. @code
  89. namespace boost
  90. {
  91. namespace json
  92. {
  93. template<class T>
  94. struct value_to_tag;
  95. template<class T1, class T2>
  96. struct result_for;
  97. }
  98. }
  99. namespace mine
  100. {
  101. class my_class;
  102. ...
  103. template<class JsonValue>
  104. boost::json::result_for<my_class, JsonValue>
  105. tag_invoke(boost::json::try_value_to_tag<my_class>, const JsonValue& jv)
  106. { ... }
  107. }
  108. @endcode
  109. @see @ref try_value_to, @ref try_value_to_tag
  110. */
  111. template <class T1, class T2>
  112. struct result_for;
  113. /** Create @ref result storing a portable error code
  114. This function constructs a `result<T>` that stores @ref error_code with
  115. `value()` equal to `e` and `category()` equal to
  116. `boost::system::generic_category()`. <br>
  117. The main use for this function is in implementation of functions returning
  118. @ref result, without including `boost/json/system_error.hpp` or even
  119. `<system_error>`. In particular, it may be useful for customizations of
  120. @ref try_value_to without creating a physical dependency on Boost.JSON.
  121. For example:
  122. @code
  123. #include <cerrno>
  124. #include <boost/assert/source_location.hpp>
  125. namespace boost
  126. {
  127. namespace json
  128. {
  129. class value;
  130. template<class T>
  131. struct try_value_to_tag;
  132. template<class T1, class T2>
  133. struct result_for;
  134. template <class T>
  135. typename result_for<T, value>::type
  136. result_from_errno(int e, boost::source_location const* loc) noexcept
  137. }
  138. }
  139. namespace mine
  140. {
  141. class my_class;
  142. ...
  143. template<class JsonValue>
  144. boost::json::result_for<my_class, JsonValue>
  145. tag_invoke(boost::json::try_value_to_tag<my_class>, const JsonValue& jv)
  146. {
  147. BOOST_STATIC_CONSTEXPR boost::source_location loc = BOOST_CURRENT_LOCATION;
  148. if( !jv.is_null() )
  149. return boost::json::result_from_errno<my_class>(EINVAL, &loc);
  150. return my_class();
  151. }
  152. }
  153. @endcode
  154. @par Exception Safety
  155. Does not throw exceptions.
  156. @tparam T The value type of returned `result`.
  157. @param e The error value.
  158. @param loc The error location.
  159. @returns @ref error_code with `value()` equal to `e` and `category()` equal
  160. to `boost::system::generic_category()`.
  161. @see @ref try_value_to_tag, @ref try_value_to, @ref result_for,
  162. <a href="https://www.boost.org/doc/libs/develop/libs/system/doc/html/system.html#ref_generic_category">
  163. `boost::system::generic_category`</a>,
  164. <a href="https://www.boost.org/doc/libs/master/libs/assert/doc/html/assert.html#source_location_support">
  165. `boost::source_location`</a>.
  166. */
  167. template <class T>
  168. typename result_for<T, value>::type
  169. result_from_errno(int e, boost::source_location const* loc) noexcept
  170. {
  171. error_code ec(e, system::generic_category(), loc);
  172. return {system::in_place_error, ec};
  173. }
  174. } // namespace json
  175. } // namespace boost
  176. #endif