status_error.hpp 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141
  1. /* Proposed SG14 status_code
  2. (C) 2018 - 2022 Niall Douglas <http://www.nedproductions.biz/> (5 commits)
  3. File Created: Feb 2018
  4. Licensed under the Apache License, Version 2.0 (the "License");
  5. you may not use this file except in compliance with the License.
  6. You may obtain a copy of the License in the accompanying file
  7. Licence.txt or at
  8. http://www.apache.org/licenses/LICENSE-2.0
  9. Unless required by applicable law or agreed to in writing, software
  10. distributed under the License is distributed on an "AS IS" BASIS,
  11. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. See the License for the specific language governing permissions and
  13. limitations under the License.
  14. Distributed under the Boost Software License, Version 1.0.
  15. (See accompanying file Licence.txt or copy at
  16. http://www.boost.org/LICENSE_1_0.txt)
  17. */
  18. #ifndef BOOST_OUTCOME_SYSTEM_ERROR2_STATUS_ERROR_HPP
  19. #define BOOST_OUTCOME_SYSTEM_ERROR2_STATUS_ERROR_HPP
  20. #include "status_code.hpp"
  21. #include <exception> // for std::exception
  22. BOOST_OUTCOME_SYSTEM_ERROR2_NAMESPACE_BEGIN
  23. /*! Exception type representing a thrown status_code
  24. */
  25. template <class DomainType> class status_error;
  26. /*! The erased type edition of status_error.
  27. */
  28. template <> class status_error<void> : public std::exception
  29. {
  30. protected:
  31. //! Constructs an instance. Not publicly available.
  32. status_error() = default;
  33. //! Copy constructor. Not publicly available
  34. status_error(const status_error &) = default;
  35. //! Move constructor. Not publicly available
  36. status_error(status_error &&) = default;
  37. //! Copy assignment. Not publicly available
  38. status_error &operator=(const status_error &) = default;
  39. //! Move assignment. Not publicly available
  40. status_error &operator=(status_error &&) = default;
  41. //! Destructor. Not publicly available.
  42. ~status_error() override = default;
  43. virtual const status_code<void> &_do_code() const noexcept = 0;
  44. public:
  45. //! The type of the status domain
  46. using domain_type = void;
  47. //! The type of the status code
  48. using status_code_type = status_code<void>;
  49. public:
  50. //! The erased status code which generated this exception instance.
  51. const status_code<void> &code() const noexcept { return _do_code(); }
  52. };
  53. /*! Exception type representing a thrown status_code
  54. */
  55. template <class DomainType> class status_error : public status_error<void>
  56. {
  57. status_code<DomainType> _code;
  58. typename DomainType::string_ref _msgref;
  59. virtual const status_code<void> &_do_code() const noexcept override final { return _code; }
  60. public:
  61. //! The type of the status domain
  62. using domain_type = DomainType;
  63. //! The type of the status code
  64. using status_code_type = status_code<DomainType>;
  65. //! Constructs an instance
  66. explicit status_error(status_code<DomainType> code)
  67. : _code(static_cast<status_code<DomainType> &&>(code))
  68. , _msgref(_code.message())
  69. {
  70. }
  71. //! Return an explanatory string
  72. virtual const char *what() const noexcept override { return _msgref.c_str(); } // NOLINT
  73. //! Returns a reference to the code
  74. const status_code_type &code() const & { return _code; }
  75. //! Returns a reference to the code
  76. status_code_type &code() & { return _code; }
  77. //! Returns a reference to the code
  78. const status_code_type &&code() const && { return _code; }
  79. //! Returns a reference to the code
  80. status_code_type &&code() && { return _code; }
  81. };
  82. /*! Exception type representing a thrown erased status_code
  83. */
  84. template <class ErasedType> class status_error<detail::erased<ErasedType>> : public status_error<void>
  85. {
  86. status_code<detail::erased<ErasedType>> _code;
  87. typename status_code_domain::string_ref _msgref;
  88. virtual const status_code<detail::erased<ErasedType>> &_do_code() const noexcept override final { return _code; }
  89. public:
  90. //! The type of the status domain
  91. using domain_type = void;
  92. //! The type of the status code
  93. using status_code_type = status_code<detail::erased<ErasedType>>;
  94. //! Constructs an instance
  95. explicit status_error(status_code<detail::erased<ErasedType>> code)
  96. : _code(static_cast<status_code<detail::erased<ErasedType>> &&>(code))
  97. , _msgref(_code.message())
  98. {
  99. }
  100. //! Return an explanatory string
  101. virtual const char *what() const noexcept override { return _msgref.c_str(); } // NOLINT
  102. //! Returns a reference to the code
  103. const status_code_type &code() const & { return _code; }
  104. //! Returns a reference to the code
  105. status_code_type &code() & { return _code; }
  106. //! Returns a reference to the code
  107. const status_code_type &&code() const && { return _code; }
  108. //! Returns a reference to the code
  109. status_code_type &&code() && { return _code; }
  110. };
  111. BOOST_OUTCOME_SYSTEM_ERROR2_NAMESPACE_END
  112. #endif