throw_exception.hpp 9.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296
  1. //////////////////////////////////////////////////////////////////////////////
  2. //
  3. // (C) Copyright Ion Gaztanaga 2012-2013. Distributed under the Boost
  4. // Software License, Version 1.0. (See accompanying file
  5. // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  6. //
  7. // See http://www.boost.org/libs/container for documentation.
  8. //
  9. //////////////////////////////////////////////////////////////////////////////
  10. #ifndef BOOST_CONTAINER_THROW_EXCEPTION_HPP
  11. #define BOOST_CONTAINER_THROW_EXCEPTION_HPP
  12. #ifndef BOOST_CONFIG_HPP
  13. # include <boost/config.hpp>
  14. #endif
  15. #if defined(BOOST_HAS_PRAGMA_ONCE)
  16. # pragma once
  17. #endif
  18. #include <boost/container/detail/config_begin.hpp>
  19. #include <boost/container/detail/workaround.hpp>
  20. #include <boost/core/ignore_unused.hpp>
  21. #ifndef BOOST_NO_EXCEPTIONS
  22. #include <exception> //for std exception base
  23. # if defined(BOOST_CONTAINER_USE_STD_EXCEPTIONS)
  24. #include <stdexcept> //for std::out_of_range, std::length_error, std::logic_error, std::runtime_error
  25. #include <string> //for implicit std::string conversion
  26. #include <new> //for std::bad_alloc
  27. namespace boost {
  28. namespace container {
  29. typedef std::bad_alloc bad_alloc_t;
  30. typedef std::out_of_range out_of_range_t;
  31. typedef std::length_error length_error_t;
  32. typedef std::logic_error logic_error_t;
  33. typedef std::runtime_error runtime_error_t;
  34. }} //namespace boost::container
  35. # else //!BOOST_CONTAINER_USE_STD_EXCEPTIONS
  36. namespace boost {
  37. namespace container {
  38. class BOOST_SYMBOL_VISIBLE exception
  39. : public ::std::exception
  40. {
  41. typedef ::std::exception std_exception_t;
  42. public:
  43. //msg must be a static string (guaranteed by callers)
  44. explicit exception(const char *msg)
  45. : std_exception_t(), m_msg(msg)
  46. {}
  47. virtual const char *what() const BOOST_NOEXCEPT_OR_NOTHROW BOOST_OVERRIDE
  48. { return m_msg ? m_msg : "unknown boost::container exception"; }
  49. private:
  50. const char *m_msg;
  51. };
  52. class BOOST_SYMBOL_VISIBLE bad_alloc
  53. : public exception
  54. {
  55. public:
  56. bad_alloc()
  57. : exception("boost::container::bad_alloc thrown")
  58. {}
  59. };
  60. typedef bad_alloc bad_alloc_t;
  61. class BOOST_SYMBOL_VISIBLE out_of_range
  62. : public exception
  63. {
  64. public:
  65. explicit out_of_range(const char *msg)
  66. : exception(msg)
  67. {}
  68. };
  69. typedef out_of_range out_of_range_t;
  70. class BOOST_SYMBOL_VISIBLE length_error
  71. : public exception
  72. {
  73. public:
  74. explicit length_error(const char *msg)
  75. : exception(msg)
  76. {}
  77. };
  78. typedef out_of_range length_error_t;
  79. class BOOST_SYMBOL_VISIBLE logic_error
  80. : public exception
  81. {
  82. public:
  83. explicit logic_error(const char *msg)
  84. : exception(msg)
  85. {}
  86. };
  87. typedef logic_error logic_error_t;
  88. class BOOST_SYMBOL_VISIBLE runtime_error
  89. : public exception
  90. {
  91. public:
  92. explicit runtime_error(const char *msg)
  93. : exception(msg)
  94. {}
  95. };
  96. typedef runtime_error runtime_error_t;
  97. } // namespace boost {
  98. } // namespace container {
  99. # endif
  100. #else
  101. #include <boost/assert.hpp>
  102. #include <cstdlib> //for std::abort
  103. #endif
  104. namespace boost {
  105. namespace container {
  106. #if defined(BOOST_CONTAINER_USER_DEFINED_THROW_CALLBACKS)
  107. //The user must provide definitions for the following functions
  108. BOOST_NORETURN void throw_bad_alloc();
  109. BOOST_NORETURN void throw_out_of_range(const char* str);
  110. BOOST_NORETURN void throw_length_error(const char* str);
  111. BOOST_NORETURN void throw_logic_error(const char* str);
  112. BOOST_NORETURN void throw_runtime_error(const char* str);
  113. #elif defined(BOOST_NO_EXCEPTIONS)
  114. BOOST_NORETURN inline void throw_bad_alloc()
  115. {
  116. BOOST_ASSERT(!"boost::container bad_alloc thrown");
  117. std::abort();
  118. }
  119. BOOST_NORETURN inline void throw_out_of_range(const char* str)
  120. {
  121. boost::ignore_unused(str);
  122. BOOST_ASSERT_MSG(!"boost::container out_of_range thrown", str);
  123. std::abort();
  124. }
  125. BOOST_NORETURN inline void throw_length_error(const char* str)
  126. {
  127. boost::ignore_unused(str);
  128. BOOST_ASSERT_MSG(!"boost::container length_error thrown", str);
  129. std::abort();
  130. }
  131. BOOST_NORETURN inline void throw_logic_error(const char* str)
  132. {
  133. boost::ignore_unused(str);
  134. BOOST_ASSERT_MSG(!"boost::container logic_error thrown", str);
  135. std::abort();
  136. }
  137. BOOST_NORETURN inline void throw_runtime_error(const char* str)
  138. {
  139. boost::ignore_unused(str);
  140. BOOST_ASSERT_MSG(!"boost::container runtime_error thrown", str);
  141. std::abort();
  142. }
  143. #else //defined(BOOST_NO_EXCEPTIONS)
  144. //! Exception callback called by Boost.Container when fails to allocate the requested storage space.
  145. //! <ul>
  146. //! <li>If BOOST_NO_EXCEPTIONS is NOT defined and BOOST_CONTAINER_USE_STD_EXCEPTIONS is NOT defined
  147. //! <code>boost::container::bad_alloc(str)</code> is thrown.</li>
  148. //!
  149. //! <li>If BOOST_NO_EXCEPTIONS is NOT defined and BOOST_CONTAINER_USE_STD_EXCEPTIONS is defined
  150. //! <code>std::bad_alloc(str)</code> is thrown.</li>
  151. //!
  152. //! <li>If BOOST_NO_EXCEPTIONS is defined and BOOST_CONTAINER_USER_DEFINED_THROW_CALLBACKS
  153. //! is NOT defined <code>BOOST_ASSERT(!"boost::container bad_alloc thrown")</code> is called
  154. //! and <code>std::abort()</code> if the former returns.</li>
  155. //!
  156. //! <li>If BOOST_NO_EXCEPTIONS and BOOST_CONTAINER_USER_DEFINED_THROW_CALLBACKS are defined
  157. //! the user must provide an implementation and the function should not return.</li>
  158. //! </ul>
  159. BOOST_NORETURN inline void throw_bad_alloc()
  160. {
  161. throw bad_alloc_t();
  162. }
  163. //! Exception callback called by Boost.Container to signal arguments out of range.
  164. //! <ul>
  165. //! <li>If BOOST_NO_EXCEPTIONS is NOT defined and BOOST_CONTAINER_USE_STD_EXCEPTIONS is NOT defined
  166. //! <code>boost::container::out_of_range(str)</code> is thrown.</li>
  167. //!
  168. //! <li>If BOOST_NO_EXCEPTIONS is NOT defined and BOOST_CONTAINER_USE_STD_EXCEPTIONS is defined
  169. //! <code>std::out_of_range(str)</code> is thrown.</li>
  170. //!
  171. //! <li>If BOOST_NO_EXCEPTIONS is defined and BOOST_CONTAINER_USER_DEFINED_THROW_CALLBACKS
  172. //! is NOT defined <code>BOOST_ASSERT_MSG(!"boost::container out_of_range thrown", str)</code> is called
  173. //! and <code>std::abort()</code> if the former returns.</li>
  174. //!
  175. //! <li>If BOOST_NO_EXCEPTIONS and BOOST_CONTAINER_USER_DEFINED_THROW_CALLBACKS are defined
  176. //! the user must provide an implementation and the function should not return.</li>
  177. //! </ul>
  178. BOOST_NORETURN inline void throw_out_of_range(const char* str)
  179. {
  180. throw out_of_range_t(str);
  181. }
  182. //! Exception callback called by Boost.Container to signal errors resizing.
  183. //! <ul>
  184. //!
  185. //! <li>If BOOST_NO_EXCEPTIONS is NOT defined and BOOST_CONTAINER_USE_STD_EXCEPTIONS is NOT defined
  186. //! <code>boost::container::length_error(str)</code> is thrown.</li>
  187. //!
  188. //! <li>If BOOST_NO_EXCEPTIONS is NOT defined and BOOST_CONTAINER_USE_STD_EXCEPTIONS is defined
  189. //! <code>std::length_error(str)</code> is thrown.</li>
  190. //!
  191. //! <li>If BOOST_NO_EXCEPTIONS is defined and BOOST_CONTAINER_USER_DEFINED_THROW_CALLBACKS
  192. //! is NOT defined <code>BOOST_ASSERT_MSG(!"boost::container length_error thrown", str)</code> is called
  193. //! and <code>std::abort()</code> if the former returns.</li>
  194. //!
  195. //! <li>If BOOST_NO_EXCEPTIONS and BOOST_CONTAINER_USER_DEFINED_THROW_CALLBACKS are defined
  196. //! the user must provide an implementation and the function should not return.</li>
  197. //! </ul>
  198. BOOST_NORETURN inline void throw_length_error(const char* str)
  199. {
  200. throw length_error_t(str);
  201. }
  202. //! Exception callback called by Boost.Container to report errors in the internal logical
  203. //! of the program, such as violation of logical preconditions or class invariants.
  204. //! <ul>
  205. //!
  206. //! <li>If BOOST_NO_EXCEPTIONS is NOT defined and BOOST_CONTAINER_USE_STD_EXCEPTIONS is NOT defined
  207. //! <code>boost::container::logic_error(str)</code> is thrown.</li>
  208. //!
  209. //! <li>If BOOST_NO_EXCEPTIONS is NOT defined and BOOST_CONTAINER_USE_STD_EXCEPTIONS is defined
  210. //! <code>std::logic_error(str)</code> is thrown.</li>
  211. //!
  212. //! <li>If BOOST_NO_EXCEPTIONS is defined and BOOST_CONTAINER_USER_DEFINED_THROW_CALLBACKS
  213. //! is NOT defined <code>BOOST_ASSERT_MSG(!"boost::container logic_error thrown", str)</code> is called
  214. //! and <code>std::abort()</code> if the former returns.</li>
  215. //!
  216. //! <li>If BOOST_NO_EXCEPTIONS and BOOST_CONTAINER_USER_DEFINED_THROW_CALLBACKS are defined
  217. //! the user must provide an implementation and the function should not return.</li>
  218. //! </ul>
  219. BOOST_NORETURN inline void throw_logic_error(const char* str)
  220. {
  221. throw logic_error_t(str);
  222. }
  223. //! Exception callback called by Boost.Container to report errors that can only be detected during runtime.
  224. //! <ul>
  225. //! <li>If BOOST_NO_EXCEPTIONS is NOT defined and BOOST_CONTAINER_USE_STD_EXCEPTIONS is NOT defined
  226. //! <code>boost::container::runtime_error(str)</code> is thrown.</li>
  227. //!
  228. //! <li>If BOOST_NO_EXCEPTIONS is NOT defined and BOOST_CONTAINER_USE_STD_EXCEPTIONS is defined
  229. //! <code>std::runtime_error(str)</code> is thrown.</li>
  230. //!
  231. //! <li>If BOOST_NO_EXCEPTIONS is defined and BOOST_CONTAINER_USER_DEFINED_THROW_CALLBACKS
  232. //! is NOT defined <code>BOOST_ASSERT_MSG(!"boost::container runtime_error thrown", str)</code> is called
  233. //! and <code>std::abort()</code> if the former returns.</li>
  234. //!
  235. //! <li>If BOOST_NO_EXCEPTIONS and BOOST_CONTAINER_USER_DEFINED_THROW_CALLBACKS are defined
  236. //! the user must provide an implementation and the function should not return.</li>
  237. //! </ul>
  238. BOOST_NORETURN inline void throw_runtime_error(const char* str)
  239. {
  240. throw runtime_error_t(str);
  241. }
  242. #endif
  243. }} //namespace boost { namespace container {
  244. #include <boost/container/detail/config_end.hpp>
  245. #endif //#ifndef BOOST_CONTAINER_THROW_EXCEPTION_HPP