system_error 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419
  1. // <system_error> -*- C++ -*-
  2. // Copyright (C) 2007-2018 Free Software Foundation, Inc.
  3. //
  4. // This file is part of the GNU ISO C++ Library. This library is free
  5. // software; you can redistribute it and/or modify it under the
  6. // terms of the GNU General Public License as published by the
  7. // Free Software Foundation; either version 3, or (at your option)
  8. // any later version.
  9. // This library is distributed in the hope that it will be useful,
  10. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. // GNU General Public License for more details.
  13. // Under Section 7 of GPL version 3, you are granted additional
  14. // permissions described in the GCC Runtime Library Exception, version
  15. // 3.1, as published by the Free Software Foundation.
  16. // You should have received a copy of the GNU General Public License and
  17. // a copy of the GCC Runtime Library Exception along with this program;
  18. // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
  19. // <http://www.gnu.org/licenses/>.
  20. /** @file include/system_error
  21. * This is a Standard C++ Library header.
  22. */
  23. #ifndef _GLIBCXX_SYSTEM_ERROR
  24. #define _GLIBCXX_SYSTEM_ERROR 1
  25. #pragma GCC system_header
  26. #if __cplusplus < 201103L
  27. # include <bits/c++0x_warning.h>
  28. #else
  29. #include <bits/c++config.h>
  30. #include <bits/error_constants.h>
  31. #include <iosfwd>
  32. #include <stdexcept>
  33. namespace std _GLIBCXX_VISIBILITY(default)
  34. {
  35. _GLIBCXX_BEGIN_NAMESPACE_VERSION
  36. class error_code;
  37. class error_condition;
  38. class system_error;
  39. /// is_error_code_enum
  40. template<typename _Tp>
  41. struct is_error_code_enum : public false_type { };
  42. /// is_error_condition_enum
  43. template<typename _Tp>
  44. struct is_error_condition_enum : public false_type { };
  45. template<>
  46. struct is_error_condition_enum<errc>
  47. : public true_type { };
  48. #if __cplusplus > 201402L
  49. template <typename _Tp>
  50. inline constexpr bool is_error_code_enum_v =
  51. is_error_code_enum<_Tp>::value;
  52. template <typename _Tp>
  53. inline constexpr bool is_error_condition_enum_v =
  54. is_error_condition_enum<_Tp>::value;
  55. #endif // C++17
  56. inline namespace _V2 {
  57. /// error_category
  58. class error_category
  59. {
  60. public:
  61. constexpr error_category() noexcept = default;
  62. virtual ~error_category();
  63. error_category(const error_category&) = delete;
  64. error_category& operator=(const error_category&) = delete;
  65. virtual const char*
  66. name() const noexcept = 0;
  67. // We need two different virtual functions here, one returning a
  68. // COW string and one returning an SSO string. Their positions in the
  69. // vtable must be consistent for dynamic dispatch to work, but which one
  70. // the name "message()" finds depends on which ABI the caller is using.
  71. #if _GLIBCXX_USE_CXX11_ABI
  72. private:
  73. _GLIBCXX_DEFAULT_ABI_TAG
  74. virtual __cow_string
  75. _M_message(int) const;
  76. public:
  77. _GLIBCXX_DEFAULT_ABI_TAG
  78. virtual string
  79. message(int) const = 0;
  80. #else
  81. virtual string
  82. message(int) const = 0;
  83. private:
  84. virtual __sso_string
  85. _M_message(int) const;
  86. #endif
  87. public:
  88. virtual error_condition
  89. default_error_condition(int __i) const noexcept;
  90. virtual bool
  91. equivalent(int __i, const error_condition& __cond) const noexcept;
  92. virtual bool
  93. equivalent(const error_code& __code, int __i) const noexcept;
  94. bool
  95. operator<(const error_category& __other) const noexcept
  96. { return less<const error_category*>()(this, &__other); }
  97. bool
  98. operator==(const error_category& __other) const noexcept
  99. { return this == &__other; }
  100. bool
  101. operator!=(const error_category& __other) const noexcept
  102. { return this != &__other; }
  103. };
  104. // DR 890.
  105. _GLIBCXX_CONST const error_category& system_category() noexcept;
  106. _GLIBCXX_CONST const error_category& generic_category() noexcept;
  107. } // end inline namespace
  108. error_code make_error_code(errc) noexcept;
  109. template<typename _Tp>
  110. struct hash;
  111. /// error_code
  112. // Implementation-specific error identification
  113. struct error_code
  114. {
  115. error_code() noexcept
  116. : _M_value(0), _M_cat(&system_category()) { }
  117. error_code(int __v, const error_category& __cat) noexcept
  118. : _M_value(__v), _M_cat(&__cat) { }
  119. template<typename _ErrorCodeEnum, typename = typename
  120. enable_if<is_error_code_enum<_ErrorCodeEnum>::value>::type>
  121. error_code(_ErrorCodeEnum __e) noexcept
  122. { *this = make_error_code(__e); }
  123. void
  124. assign(int __v, const error_category& __cat) noexcept
  125. {
  126. _M_value = __v;
  127. _M_cat = &__cat;
  128. }
  129. void
  130. clear() noexcept
  131. { assign(0, system_category()); }
  132. // DR 804.
  133. template<typename _ErrorCodeEnum>
  134. typename enable_if<is_error_code_enum<_ErrorCodeEnum>::value,
  135. error_code&>::type
  136. operator=(_ErrorCodeEnum __e) noexcept
  137. { return *this = make_error_code(__e); }
  138. int
  139. value() const noexcept { return _M_value; }
  140. const error_category&
  141. category() const noexcept { return *_M_cat; }
  142. error_condition
  143. default_error_condition() const noexcept;
  144. _GLIBCXX_DEFAULT_ABI_TAG
  145. string
  146. message() const
  147. { return category().message(value()); }
  148. explicit operator bool() const noexcept
  149. { return _M_value != 0; }
  150. // DR 804.
  151. private:
  152. friend class hash<error_code>;
  153. int _M_value;
  154. const error_category* _M_cat;
  155. };
  156. // 19.4.2.6 non-member functions
  157. inline error_code
  158. make_error_code(errc __e) noexcept
  159. { return error_code(static_cast<int>(__e), generic_category()); }
  160. inline bool
  161. operator<(const error_code& __lhs, const error_code& __rhs) noexcept
  162. {
  163. return (__lhs.category() < __rhs.category()
  164. || (__lhs.category() == __rhs.category()
  165. && __lhs.value() < __rhs.value()));
  166. }
  167. template<typename _CharT, typename _Traits>
  168. basic_ostream<_CharT, _Traits>&
  169. operator<<(basic_ostream<_CharT, _Traits>& __os, const error_code& __e)
  170. { return (__os << __e.category().name() << ':' << __e.value()); }
  171. error_condition make_error_condition(errc) noexcept;
  172. /// error_condition
  173. // Portable error identification
  174. struct error_condition
  175. {
  176. error_condition() noexcept
  177. : _M_value(0), _M_cat(&generic_category()) { }
  178. error_condition(int __v, const error_category& __cat) noexcept
  179. : _M_value(__v), _M_cat(&__cat) { }
  180. template<typename _ErrorConditionEnum, typename = typename
  181. enable_if<is_error_condition_enum<_ErrorConditionEnum>::value>::type>
  182. error_condition(_ErrorConditionEnum __e) noexcept
  183. { *this = make_error_condition(__e); }
  184. void
  185. assign(int __v, const error_category& __cat) noexcept
  186. {
  187. _M_value = __v;
  188. _M_cat = &__cat;
  189. }
  190. // DR 804.
  191. template<typename _ErrorConditionEnum>
  192. typename enable_if<is_error_condition_enum
  193. <_ErrorConditionEnum>::value, error_condition&>::type
  194. operator=(_ErrorConditionEnum __e) noexcept
  195. { return *this = make_error_condition(__e); }
  196. void
  197. clear() noexcept
  198. { assign(0, generic_category()); }
  199. // 19.4.3.4 observers
  200. int
  201. value() const noexcept { return _M_value; }
  202. const error_category&
  203. category() const noexcept { return *_M_cat; }
  204. _GLIBCXX_DEFAULT_ABI_TAG
  205. string
  206. message() const
  207. { return category().message(value()); }
  208. explicit operator bool() const noexcept
  209. { return _M_value != 0; }
  210. // DR 804.
  211. private:
  212. int _M_value;
  213. const error_category* _M_cat;
  214. };
  215. // 19.4.3.6 non-member functions
  216. inline error_condition
  217. make_error_condition(errc __e) noexcept
  218. { return error_condition(static_cast<int>(__e), generic_category()); }
  219. inline bool
  220. operator<(const error_condition& __lhs,
  221. const error_condition& __rhs) noexcept
  222. {
  223. return (__lhs.category() < __rhs.category()
  224. || (__lhs.category() == __rhs.category()
  225. && __lhs.value() < __rhs.value()));
  226. }
  227. // 19.4.4 Comparison operators
  228. inline bool
  229. operator==(const error_code& __lhs, const error_code& __rhs) noexcept
  230. { return (__lhs.category() == __rhs.category()
  231. && __lhs.value() == __rhs.value()); }
  232. inline bool
  233. operator==(const error_code& __lhs, const error_condition& __rhs) noexcept
  234. {
  235. return (__lhs.category().equivalent(__lhs.value(), __rhs)
  236. || __rhs.category().equivalent(__lhs, __rhs.value()));
  237. }
  238. inline bool
  239. operator==(const error_condition& __lhs, const error_code& __rhs) noexcept
  240. {
  241. return (__rhs.category().equivalent(__rhs.value(), __lhs)
  242. || __lhs.category().equivalent(__rhs, __lhs.value()));
  243. }
  244. inline bool
  245. operator==(const error_condition& __lhs,
  246. const error_condition& __rhs) noexcept
  247. {
  248. return (__lhs.category() == __rhs.category()
  249. && __lhs.value() == __rhs.value());
  250. }
  251. inline bool
  252. operator!=(const error_code& __lhs, const error_code& __rhs) noexcept
  253. { return !(__lhs == __rhs); }
  254. inline bool
  255. operator!=(const error_code& __lhs, const error_condition& __rhs) noexcept
  256. { return !(__lhs == __rhs); }
  257. inline bool
  258. operator!=(const error_condition& __lhs, const error_code& __rhs) noexcept
  259. { return !(__lhs == __rhs); }
  260. inline bool
  261. operator!=(const error_condition& __lhs,
  262. const error_condition& __rhs) noexcept
  263. { return !(__lhs == __rhs); }
  264. /**
  265. * @brief Thrown to indicate error code of underlying system.
  266. *
  267. * @ingroup exceptions
  268. */
  269. class system_error : public std::runtime_error
  270. {
  271. private:
  272. error_code _M_code;
  273. public:
  274. system_error(error_code __ec = error_code())
  275. : runtime_error(__ec.message()), _M_code(__ec) { }
  276. system_error(error_code __ec, const string& __what)
  277. : runtime_error(__what + ": " + __ec.message()), _M_code(__ec) { }
  278. system_error(error_code __ec, const char* __what)
  279. : runtime_error(__what + (": " + __ec.message())), _M_code(__ec) { }
  280. system_error(int __v, const error_category& __ecat, const char* __what)
  281. : system_error(error_code(__v, __ecat), __what) { }
  282. system_error(int __v, const error_category& __ecat)
  283. : runtime_error(error_code(__v, __ecat).message()),
  284. _M_code(__v, __ecat) { }
  285. system_error(int __v, const error_category& __ecat, const string& __what)
  286. : runtime_error(__what + ": " + error_code(__v, __ecat).message()),
  287. _M_code(__v, __ecat) { }
  288. virtual ~system_error() noexcept;
  289. const error_code&
  290. code() const noexcept { return _M_code; }
  291. };
  292. _GLIBCXX_END_NAMESPACE_VERSION
  293. } // namespace
  294. #include <bits/functional_hash.h>
  295. namespace std _GLIBCXX_VISIBILITY(default)
  296. {
  297. _GLIBCXX_BEGIN_NAMESPACE_VERSION
  298. #ifndef _GLIBCXX_COMPATIBILITY_CXX0X
  299. // DR 1182.
  300. /// std::hash specialization for error_code.
  301. template<>
  302. struct hash<error_code>
  303. : public __hash_base<size_t, error_code>
  304. {
  305. size_t
  306. operator()(const error_code& __e) const noexcept
  307. {
  308. const size_t __tmp = std::_Hash_impl::hash(__e._M_value);
  309. return std::_Hash_impl::__hash_combine(__e._M_cat, __tmp);
  310. }
  311. };
  312. #endif // _GLIBCXX_COMPATIBILITY_CXX0X
  313. #if __cplusplus > 201402L
  314. // DR 2686.
  315. /// std::hash specialization for error_condition.
  316. template<>
  317. struct hash<error_condition>
  318. : public __hash_base<size_t, error_condition>
  319. {
  320. size_t
  321. operator()(const error_condition& __e) const noexcept
  322. {
  323. const size_t __tmp = std::_Hash_impl::hash(__e.value());
  324. return std::_Hash_impl::__hash_combine(__e.category(), __tmp);
  325. }
  326. };
  327. #endif
  328. _GLIBCXX_END_NAMESPACE_VERSION
  329. } // namespace
  330. #endif // C++11
  331. #endif // _GLIBCXX_SYSTEM_ERROR