throw_exception.hpp 9.7 KB

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