system_error 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641
  1. // <system_error> -*- C++ -*-
  2. // Copyright (C) 2007-2023 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. #include <bits/requires_hosted.h> // OS-dependent
  27. #if __cplusplus < 201103L
  28. # include <bits/c++0x_warning.h>
  29. #else
  30. #include <bits/c++config.h>
  31. #include <bits/error_constants.h>
  32. #include <iosfwd>
  33. #include <stdexcept>
  34. #if __cplusplus > 201703L
  35. # include <compare>
  36. #endif
  37. namespace std _GLIBCXX_VISIBILITY(default)
  38. {
  39. _GLIBCXX_BEGIN_NAMESPACE_VERSION
  40. /** @addtogroup diagnostics
  41. * @{
  42. */
  43. class error_code;
  44. class error_condition;
  45. class system_error;
  46. /// is_error_code_enum
  47. template<typename _Tp>
  48. struct is_error_code_enum : public false_type { };
  49. /// is_error_condition_enum
  50. template<typename _Tp>
  51. struct is_error_condition_enum : public false_type { };
  52. template<>
  53. struct is_error_condition_enum<errc>
  54. : public true_type { };
  55. #if __cplusplus > 201402L
  56. template <typename _Tp>
  57. inline constexpr bool is_error_code_enum_v =
  58. is_error_code_enum<_Tp>::value;
  59. template <typename _Tp>
  60. inline constexpr bool is_error_condition_enum_v =
  61. is_error_condition_enum<_Tp>::value;
  62. #endif // C++17
  63. /// @}
  64. _GLIBCXX_BEGIN_INLINE_ABI_NAMESPACE(_V2)
  65. /** @addtogroup diagnostics
  66. * @{
  67. */
  68. /** Abstract base class for types defining a category of error codes.
  69. *
  70. * An error category defines a context that gives meaning to the integer
  71. * stored in an `error_code` or `error_condition` object. For example,
  72. * the standard `errno` constants such a `EINVAL` and `ENOMEM` are
  73. * associated with the "generic" category and other OS-specific error
  74. * numbers are associated with the "system" category, but a user-defined
  75. * category might give different meanings to the same numerical values.
  76. *
  77. * A user-defined category can override the `equivalent` member functions
  78. * to define correspondence between errors in different categories.
  79. * For example, a category for errors from disk I/O could consider some
  80. * of its error numbers equivalent to ENOSPC and ENOENT in the generic
  81. * category.
  82. *
  83. * @headerfile system_error
  84. * @since C++11
  85. */
  86. class error_category
  87. {
  88. public:
  89. constexpr error_category() noexcept = default;
  90. virtual ~error_category();
  91. error_category(const error_category&) = delete;
  92. error_category& operator=(const error_category&) = delete;
  93. /// A string that identifies the error category.
  94. virtual const char*
  95. name() const noexcept = 0;
  96. // We need two different virtual functions here, one returning a
  97. // COW string and one returning an SSO string. Their positions in the
  98. // vtable must be consistent for dynamic dispatch to work, but which one
  99. // the name "message()" finds depends on which ABI the caller is using.
  100. #if _GLIBCXX_USE_CXX11_ABI
  101. private:
  102. _GLIBCXX_DEFAULT_ABI_TAG
  103. virtual __cow_string
  104. _M_message(int) const;
  105. public:
  106. /// A description of the error condition corresponding to the number.
  107. _GLIBCXX_DEFAULT_ABI_TAG
  108. virtual string
  109. message(int) const = 0;
  110. #else
  111. virtual string
  112. message(int) const = 0;
  113. private:
  114. virtual __sso_string
  115. _M_message(int) const;
  116. #endif
  117. public:
  118. /// Return an error_condition corresponding to `i` in this category.
  119. virtual error_condition
  120. default_error_condition(int __i) const noexcept;
  121. /// Test whether `cond` corresponds to `i` for this category.
  122. virtual bool
  123. equivalent(int __i, const error_condition& __cond) const noexcept;
  124. /// Test whether `code` corresponds to `i` for this category.
  125. virtual bool
  126. equivalent(const error_code& __code, int __i) const noexcept;
  127. /// An error_category only compares equal to itself.
  128. [[__nodiscard__]]
  129. bool
  130. operator==(const error_category& __other) const noexcept
  131. { return this == &__other; }
  132. /// Ordered comparison that defines a total order for error categories.
  133. #if __cpp_lib_three_way_comparison
  134. [[nodiscard]]
  135. strong_ordering
  136. operator<=>(const error_category& __rhs) const noexcept
  137. { return std::compare_three_way()(this, &__rhs); }
  138. #else
  139. bool
  140. operator<(const error_category& __other) const noexcept
  141. { return less<const error_category*>()(this, &__other); }
  142. bool
  143. operator!=(const error_category& __other) const noexcept
  144. { return this != &__other; }
  145. #endif
  146. };
  147. // DR 890.
  148. /// Error category for `errno` error codes.
  149. [[__nodiscard__, __gnu__::__const__]]
  150. const error_category&
  151. generic_category() noexcept;
  152. /// Error category for other error codes defined by the OS.
  153. [[__nodiscard__, __gnu__::__const__]]
  154. const error_category&
  155. system_category() noexcept;
  156. /// @}
  157. _GLIBCXX_END_INLINE_ABI_NAMESPACE(_V2)
  158. /** @addtogroup diagnostics
  159. * @{
  160. */
  161. namespace __adl_only
  162. {
  163. void make_error_code() = delete;
  164. void make_error_condition() = delete;
  165. }
  166. /** Class error_code
  167. *
  168. * This class is a value type storing an integer error number and a
  169. * category that gives meaning to the error number. Typically this is done
  170. * close the the point where the error happens, to capture the original
  171. * error value.
  172. *
  173. * An `error_code` object can be used to store the original error value
  174. * emitted by some subsystem, with a category relevant to the subsystem.
  175. * For example, errors from POSIX library functions can be represented by
  176. * an `errno` value and the "generic" category, but errors from an HTTP
  177. * library might be represented by an HTTP response status code (e.g. 404)
  178. * and a custom category defined by the library.
  179. *
  180. * @headerfile system_error
  181. * @since C++11
  182. */
  183. class error_code
  184. {
  185. template<typename _ErrorCodeEnum>
  186. using _Check
  187. = __enable_if_t<is_error_code_enum<_ErrorCodeEnum>::value>;
  188. public:
  189. error_code() noexcept
  190. : _M_value(0), _M_cat(&system_category()) { }
  191. error_code(int __v, const error_category& __cat) noexcept
  192. : _M_value(__v), _M_cat(&__cat) { }
  193. /// Initialize with a user-defined type, by calling make_error_code.
  194. template<typename _ErrorCodeEnum,
  195. typename = _Check<_ErrorCodeEnum>>
  196. error_code(_ErrorCodeEnum __e) noexcept
  197. {
  198. using __adl_only::make_error_code;
  199. *this = make_error_code(__e);
  200. }
  201. error_code(const error_code&) = default;
  202. error_code& operator=(const error_code&) = default;
  203. void
  204. assign(int __v, const error_category& __cat) noexcept
  205. {
  206. _M_value = __v;
  207. _M_cat = &__cat;
  208. }
  209. void
  210. clear() noexcept
  211. { assign(0, system_category()); }
  212. /// The error value.
  213. [[__nodiscard__]]
  214. int
  215. value() const noexcept { return _M_value; }
  216. /// The error category that this error belongs to.
  217. [[__nodiscard__]]
  218. const error_category&
  219. category() const noexcept { return *_M_cat; }
  220. /// An `error_condition` for this error's category and value.
  221. error_condition
  222. default_error_condition() const noexcept;
  223. /// The category's description of the value.
  224. _GLIBCXX_DEFAULT_ABI_TAG
  225. string
  226. message() const
  227. { return category().message(value()); }
  228. /// Test whether `value()` is non-zero.
  229. [[__nodiscard__]]
  230. explicit operator bool() const noexcept
  231. { return _M_value != 0; }
  232. // DR 804.
  233. private:
  234. int _M_value;
  235. const error_category* _M_cat;
  236. };
  237. // C++11 19.5.2.5 non-member functions
  238. /** Create an `error_code` representing a standard `errc` condition.
  239. *
  240. * The `std::errc` constants correspond to `errno` macros and so use the
  241. * generic category.
  242. *
  243. * @relates error_code
  244. * @since C++11
  245. */
  246. [[__nodiscard__]]
  247. inline error_code
  248. make_error_code(errc __e) noexcept
  249. { return error_code(static_cast<int>(__e), generic_category()); }
  250. /** Ordered comparison for std::error_code.
  251. *
  252. * This defines a total order by comparing the categories, and then
  253. * if they are equal comparing the values.
  254. *
  255. * @relates error_code
  256. * @since C++11
  257. */
  258. #if __cpp_lib_three_way_comparison
  259. [[nodiscard]]
  260. inline strong_ordering
  261. operator<=>(const error_code& __lhs, const error_code& __rhs) noexcept
  262. {
  263. if (auto __c = __lhs.category() <=> __rhs.category(); __c != 0)
  264. return __c;
  265. return __lhs.value() <=> __rhs.value();
  266. }
  267. #else
  268. inline bool
  269. operator<(const error_code& __lhs, const error_code& __rhs) noexcept
  270. {
  271. return (__lhs.category() < __rhs.category()
  272. || (__lhs.category() == __rhs.category()
  273. && __lhs.value() < __rhs.value()));
  274. }
  275. #endif
  276. /** Write a std::error_code to an ostream.
  277. *
  278. * @relates error_code
  279. * @since C++11
  280. */
  281. template<typename _CharT, typename _Traits>
  282. basic_ostream<_CharT, _Traits>&
  283. operator<<(basic_ostream<_CharT, _Traits>& __os, const error_code& __e)
  284. { return (__os << __e.category().name() << ':' << __e.value()); }
  285. /** Class error_condition
  286. *
  287. * This class represents error conditions that may be visible at an API
  288. * boundary. Different `error_code` values that can occur within a library
  289. * or module might map to the same `error_condition`.
  290. *
  291. * An `error_condition` represents something that the program can test for,
  292. * and subsequently take appropriate action.
  293. *
  294. * @headerfile system_error
  295. * @since C++11
  296. */
  297. class error_condition
  298. {
  299. template<typename _ErrorConditionEnum>
  300. using _Check
  301. = __enable_if_t<is_error_condition_enum<_ErrorConditionEnum>::value>;
  302. public:
  303. /// Initialize with a zero (no error) value and the generic category.
  304. error_condition() noexcept
  305. : _M_value(0), _M_cat(&generic_category()) { }
  306. /// Initialize with the specified value and category.
  307. error_condition(int __v, const error_category& __cat) noexcept
  308. : _M_value(__v), _M_cat(&__cat) { }
  309. /// Initialize with a user-defined type, by calling make_error_condition.
  310. template<typename _ErrorConditionEnum,
  311. typename = _Check<_ErrorConditionEnum>>
  312. error_condition(_ErrorConditionEnum __e) noexcept
  313. {
  314. using __adl_only::make_error_condition;
  315. *this = make_error_condition(__e);
  316. }
  317. error_condition(const error_condition&) = default;
  318. error_condition& operator=(const error_condition&) = default;
  319. /// Set the value and category.
  320. void
  321. assign(int __v, const error_category& __cat) noexcept
  322. {
  323. _M_value = __v;
  324. _M_cat = &__cat;
  325. }
  326. /// Reset the value and category to the default-constructed state.
  327. void
  328. clear() noexcept
  329. { assign(0, generic_category()); }
  330. // C++11 19.5.3.4 observers
  331. /// The error value.
  332. [[__nodiscard__]]
  333. int
  334. value() const noexcept { return _M_value; }
  335. /// The error category that this error belongs to.
  336. [[__nodiscard__]]
  337. const error_category&
  338. category() const noexcept { return *_M_cat; }
  339. /// The category's description of the value.
  340. _GLIBCXX_DEFAULT_ABI_TAG
  341. string
  342. message() const
  343. { return category().message(value()); }
  344. /// Test whether `value()` is non-zero.
  345. [[__nodiscard__]]
  346. explicit operator bool() const noexcept
  347. { return _M_value != 0; }
  348. // DR 804.
  349. private:
  350. int _M_value;
  351. const error_category* _M_cat;
  352. };
  353. // C++11 19.5.3.5 non-member functions
  354. /** Create an `error_condition` representing a standard `errc` condition.
  355. *
  356. * The `std::errc` constants correspond to `errno` macros and so use the
  357. * generic category.
  358. *
  359. * @relates error_condition
  360. * @since C++11
  361. */
  362. [[__nodiscard__]]
  363. inline error_condition
  364. make_error_condition(errc __e) noexcept
  365. { return error_condition(static_cast<int>(__e), generic_category()); }
  366. // C++11 19.5.4 Comparison operators
  367. /** Equality comparison for std::error_code.
  368. *
  369. * Returns true only if they have the same category and the same value.
  370. *
  371. * @relates error_condition
  372. * @since C++11
  373. */
  374. [[__nodiscard__]]
  375. inline bool
  376. operator==(const error_code& __lhs, const error_code& __rhs) noexcept
  377. {
  378. return __lhs.category() == __rhs.category()
  379. && __lhs.value() == __rhs.value();
  380. }
  381. /** Equality comparison for std::error_code and std::error_condition.
  382. *
  383. * Uses each category's `equivalent` member function to check whether
  384. * the values correspond to an equivalent error in that category.
  385. *
  386. * @relates error_condition
  387. * @since C++11
  388. */
  389. [[__nodiscard__]]
  390. inline bool
  391. operator==(const error_code& __lhs, const error_condition& __rhs) noexcept
  392. {
  393. return __lhs.category().equivalent(__lhs.value(), __rhs)
  394. || __rhs.category().equivalent(__lhs, __rhs.value());
  395. }
  396. /** Equality comparison for std::error_condition.
  397. *
  398. * Returns true only if they have the same category and the same value.
  399. *
  400. * @relates error_condition
  401. * @since C++11
  402. */
  403. [[__nodiscard__]]
  404. inline bool
  405. operator==(const error_condition& __lhs,
  406. const error_condition& __rhs) noexcept
  407. {
  408. return __lhs.category() == __rhs.category()
  409. && __lhs.value() == __rhs.value();
  410. }
  411. /** Ordered comparison for std::error_condition.
  412. *
  413. * This defines a total order by comparing the categories, and then
  414. * if they are equal comparing the values.
  415. *
  416. * @relates error_condition
  417. * @since C++11
  418. */
  419. #if __cpp_lib_three_way_comparison
  420. [[nodiscard]]
  421. inline strong_ordering
  422. operator<=>(const error_condition& __lhs,
  423. const error_condition& __rhs) noexcept
  424. {
  425. if (auto __c = __lhs.category() <=> __rhs.category(); __c != 0)
  426. return __c;
  427. return __lhs.value() <=> __rhs.value();
  428. }
  429. #else
  430. inline bool
  431. operator<(const error_condition& __lhs,
  432. const error_condition& __rhs) noexcept
  433. {
  434. return (__lhs.category() < __rhs.category()
  435. || (__lhs.category() == __rhs.category()
  436. && __lhs.value() < __rhs.value()));
  437. }
  438. /// @relates error_condition
  439. inline bool
  440. operator==(const error_condition& __lhs, const error_code& __rhs) noexcept
  441. {
  442. return (__rhs.category().equivalent(__rhs.value(), __lhs)
  443. || __lhs.category().equivalent(__rhs, __lhs.value()));
  444. }
  445. /// @relates error_code
  446. inline bool
  447. operator!=(const error_code& __lhs, const error_code& __rhs) noexcept
  448. { return !(__lhs == __rhs); }
  449. /// @relates error_code
  450. inline bool
  451. operator!=(const error_code& __lhs, const error_condition& __rhs) noexcept
  452. { return !(__lhs == __rhs); }
  453. /// @relates error_condition
  454. inline bool
  455. operator!=(const error_condition& __lhs, const error_code& __rhs) noexcept
  456. { return !(__lhs == __rhs); }
  457. /// @relates error_condition
  458. inline bool
  459. operator!=(const error_condition& __lhs,
  460. const error_condition& __rhs) noexcept
  461. { return !(__lhs == __rhs); }
  462. #endif // three_way_comparison
  463. /// @}
  464. /**
  465. * @brief An exception type that includes an `error_code` value.
  466. *
  467. * Typically used to report errors from the operating system and other
  468. * low-level APIs.
  469. *
  470. * @headerfile system_error
  471. * @since C++11
  472. * @ingroup exceptions
  473. */
  474. class system_error : public std::runtime_error
  475. {
  476. private:
  477. error_code _M_code;
  478. public:
  479. system_error(error_code __ec = error_code())
  480. : runtime_error(__ec.message()), _M_code(__ec) { }
  481. system_error(error_code __ec, const string& __what)
  482. : runtime_error(__what + (": " + __ec.message())), _M_code(__ec) { }
  483. system_error(error_code __ec, const char* __what)
  484. : runtime_error(__what + (": " + __ec.message())), _M_code(__ec) { }
  485. system_error(int __v, const error_category& __ecat, const char* __what)
  486. : system_error(error_code(__v, __ecat), __what) { }
  487. system_error(int __v, const error_category& __ecat)
  488. : runtime_error(error_code(__v, __ecat).message()),
  489. _M_code(__v, __ecat) { }
  490. system_error(int __v, const error_category& __ecat, const string& __what)
  491. : runtime_error(__what + (": " + error_code(__v, __ecat).message())),
  492. _M_code(__v, __ecat) { }
  493. #if __cplusplus >= 201103L
  494. system_error (const system_error &) = default;
  495. system_error &operator= (const system_error &) = default;
  496. #endif
  497. virtual ~system_error() noexcept;
  498. const error_code&
  499. code() const noexcept { return _M_code; }
  500. };
  501. _GLIBCXX_END_NAMESPACE_VERSION
  502. } // namespace
  503. #include <bits/functional_hash.h>
  504. namespace std _GLIBCXX_VISIBILITY(default)
  505. {
  506. _GLIBCXX_BEGIN_NAMESPACE_VERSION
  507. #ifndef _GLIBCXX_COMPATIBILITY_CXX0X
  508. // DR 1182.
  509. /// std::hash specialization for error_code.
  510. /// @relates error_code
  511. template<>
  512. struct hash<error_code>
  513. : public __hash_base<size_t, error_code>
  514. {
  515. size_t
  516. operator()(const error_code& __e) const noexcept
  517. {
  518. const size_t __tmp = std::_Hash_impl::hash(__e.value());
  519. return std::_Hash_impl::__hash_combine(&__e.category(), __tmp);
  520. }
  521. };
  522. #endif // _GLIBCXX_COMPATIBILITY_CXX0X
  523. #if __cplusplus >= 201703L
  524. // DR 2686.
  525. /// std::hash specialization for error_condition.
  526. /// @relates error_condition
  527. template<>
  528. struct hash<error_condition>
  529. : public __hash_base<size_t, error_condition>
  530. {
  531. size_t
  532. operator()(const error_condition& __e) const noexcept
  533. {
  534. const size_t __tmp = std::_Hash_impl::hash(__e.value());
  535. return std::_Hash_impl::__hash_combine(&__e.category(), __tmp);
  536. }
  537. };
  538. #endif
  539. _GLIBCXX_END_NAMESPACE_VERSION
  540. } // namespace
  541. #endif // C++11
  542. #endif // _GLIBCXX_SYSTEM_ERROR