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