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