Line data Source code
1 : #ifndef BOOST_THROW_EXCEPTION_HPP_INCLUDED
2 : #define BOOST_THROW_EXCEPTION_HPP_INCLUDED
3 :
4 : // MS compatible compilers support #pragma once
5 :
6 : #if defined(_MSC_VER) && (_MSC_VER >= 1020)
7 : # pragma once
8 : #endif
9 :
10 : // boost/throw_exception.hpp
11 : //
12 : // Copyright (c) 2002, 2018-2022 Peter Dimov
13 : // Copyright (c) 2008-2009 Emil Dotchevski and Reverge Studios, Inc.
14 : //
15 : // Distributed under the Boost Software License, Version 1.0. (See
16 : // accompanying file LICENSE_1_0.txt or copy at
17 : // http://www.boost.org/LICENSE_1_0.txt)
18 : //
19 : // http://www.boost.org/libs/throw_exception
20 :
21 : #include <boost/exception/exception.hpp>
22 : #include <boost/assert/source_location.hpp>
23 : #include <boost/config.hpp>
24 : #include <boost/config/workaround.hpp>
25 : #include <exception>
26 : #include <utility>
27 : #include <cstddef>
28 : #if !defined(BOOST_NO_CXX11_HDR_TYPE_TRAITS)
29 : #include <type_traits>
30 : #endif
31 :
32 : #if !defined( BOOST_EXCEPTION_DISABLE ) && defined( BOOST_BORLANDC ) && BOOST_WORKAROUND( BOOST_BORLANDC, BOOST_TESTED_AT(0x593) )
33 : # define BOOST_EXCEPTION_DISABLE
34 : #endif
35 :
36 : namespace boost
37 : {
38 :
39 : #if defined( BOOST_NO_EXCEPTIONS )
40 :
41 : BOOST_NORETURN void throw_exception( std::exception const & e ); // user defined
42 : BOOST_NORETURN void throw_exception( std::exception const & e, boost::source_location const & loc ); // user defined
43 :
44 : #endif
45 :
46 : // boost::wrapexcept<E>
47 :
48 : namespace detail
49 : {
50 :
51 : typedef char (&wrapexcept_s1)[ 1 ];
52 : typedef char (&wrapexcept_s2)[ 2 ];
53 :
54 : template<class T> wrapexcept_s1 wrapexcept_is_convertible( T* );
55 : template<class T> wrapexcept_s2 wrapexcept_is_convertible( void* );
56 :
57 : template<class E, class B, std::size_t I = sizeof( wrapexcept_is_convertible<B>( static_cast< E* >( BOOST_NULLPTR ) ) ) > struct wrapexcept_add_base;
58 :
59 : template<class E, class B> struct wrapexcept_add_base<E, B, 1>
60 : {
61 : struct type {};
62 : };
63 :
64 : template<class E, class B> struct wrapexcept_add_base<E, B, 2>
65 : {
66 : typedef B type;
67 : };
68 :
69 : } // namespace detail
70 :
71 0 : template<class E> struct BOOST_SYMBOL_VISIBLE wrapexcept:
72 : public detail::wrapexcept_add_base<E, boost::exception_detail::clone_base>::type,
73 : public E,
74 : public detail::wrapexcept_add_base<E, boost::exception>::type
75 : {
76 : private:
77 :
78 : struct deleter
79 : {
80 : wrapexcept * p_;
81 0 : ~deleter() { delete p_; }
82 : };
83 :
84 : private:
85 :
86 6 : void copy_from( void const* )
87 : {
88 6 : }
89 :
90 : void copy_from( boost::exception const* p )
91 : {
92 : static_cast<boost::exception&>( *this ) = *p;
93 : }
94 :
95 : public:
96 :
97 24 : explicit wrapexcept( E const & e ): E( e )
98 18 : {
99 6 : copy_from( &e );
100 12 : }
101 :
102 : explicit wrapexcept( E const & e, boost::source_location const & loc ): E( e )
103 : {
104 : copy_from( &e );
105 :
106 : set_info( *this, throw_file( loc.file_name() ) );
107 : set_info( *this, throw_line( static_cast<int>( loc.line() ) ) );
108 : set_info( *this, throw_function( loc.function_name() ) );
109 : set_info( *this, throw_column( static_cast<int>( loc.column() ) ) );
110 : }
111 :
112 0 : virtual boost::exception_detail::clone_base const * clone() const BOOST_OVERRIDE
113 : {
114 0 : wrapexcept * p = new wrapexcept( *this );
115 0 : deleter del = { p };
116 :
117 0 : boost::exception_detail::copy_boost_exception( p, this );
118 :
119 0 : del.p_ = BOOST_NULLPTR;
120 0 : return p;
121 0 : }
122 :
123 0 : virtual void rethrow() const BOOST_OVERRIDE
124 : {
125 : #if defined( BOOST_NO_EXCEPTIONS )
126 :
127 : boost::throw_exception( *this );
128 :
129 : #else
130 :
131 0 : throw *this;
132 :
133 : #endif
134 0 : }
135 : };
136 :
137 : // All boost exceptions are required to derive from std::exception,
138 : // to ensure compatibility with BOOST_NO_EXCEPTIONS.
139 :
140 6 : inline void throw_exception_assert_compatibility( std::exception const & ) {}
141 :
142 : // boost::throw_exception
143 :
144 : #if !defined( BOOST_NO_EXCEPTIONS )
145 :
146 : #if defined( BOOST_EXCEPTION_DISABLE )
147 :
148 : template<class E> BOOST_NORETURN void throw_exception( E const & e )
149 : {
150 : throw_exception_assert_compatibility( e );
151 : throw e;
152 : }
153 :
154 : template<class E> BOOST_NORETURN void throw_exception( E const & e, boost::source_location const & )
155 : {
156 : throw_exception_assert_compatibility( e );
157 : throw e;
158 : }
159 :
160 : #else // defined( BOOST_EXCEPTION_DISABLE )
161 :
162 6 : template<class E> BOOST_NORETURN void throw_exception( E const & e )
163 : {
164 6 : throw_exception_assert_compatibility( e );
165 6 : throw wrapexcept<E>( e );
166 0 : }
167 :
168 : template<class E> BOOST_NORETURN void throw_exception( E const & e, boost::source_location const & loc )
169 : {
170 : throw_exception_assert_compatibility( e );
171 : throw wrapexcept<E>( e, loc );
172 : }
173 :
174 : #endif // defined( BOOST_EXCEPTION_DISABLE )
175 :
176 : #endif // !defined( BOOST_NO_EXCEPTIONS )
177 :
178 : } // namespace boost
179 :
180 : // BOOST_THROW_EXCEPTION
181 :
182 : #define BOOST_THROW_EXCEPTION(x) ::boost::throw_exception(x, BOOST_CURRENT_LOCATION)
183 :
184 : namespace boost
185 : {
186 :
187 : // throw_with_location
188 :
189 : namespace detail
190 : {
191 :
192 : struct BOOST_SYMBOL_VISIBLE throw_location
193 : {
194 : boost::source_location location_;
195 :
196 : explicit throw_location( boost::source_location const & loc ): location_( loc )
197 : {
198 : }
199 : };
200 :
201 : template<class E> class BOOST_SYMBOL_VISIBLE with_throw_location: public E, public throw_location
202 : {
203 : public:
204 :
205 : with_throw_location( E const & e, boost::source_location const & loc ): E( e ), throw_location( loc )
206 : {
207 : }
208 :
209 : #if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
210 :
211 : with_throw_location( E && e, boost::source_location const & loc ): E( std::move( e ) ), throw_location( loc )
212 : {
213 : }
214 :
215 : #endif
216 : };
217 :
218 : } // namespace detail
219 :
220 : #if !defined(BOOST_NO_EXCEPTIONS)
221 :
222 : #if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) && !defined(BOOST_NO_CXX11_HDR_TYPE_TRAITS)
223 :
224 : template<class E> BOOST_NORETURN void throw_with_location( E && e, boost::source_location const & loc = BOOST_CURRENT_LOCATION )
225 : {
226 : throw_exception_assert_compatibility( e );
227 : throw detail::with_throw_location<typename std::decay<E>::type>( std::forward<E>( e ), loc );
228 : }
229 :
230 : #else
231 :
232 : template<class E> BOOST_NORETURN void throw_with_location( E const & e, boost::source_location const & loc = BOOST_CURRENT_LOCATION )
233 : {
234 : throw_exception_assert_compatibility( e );
235 : throw detail::with_throw_location<E>( e, loc );
236 : }
237 :
238 : #endif
239 :
240 : #else
241 :
242 : template<class E> BOOST_NORETURN void throw_with_location( E const & e, boost::source_location const & loc = BOOST_CURRENT_LOCATION )
243 : {
244 : boost::throw_exception( e, loc );
245 : }
246 :
247 : #endif
248 :
249 : // get_throw_location
250 :
251 : template<class E> boost::source_location get_throw_location( E const & e )
252 : {
253 : #if defined(BOOST_NO_RTTI)
254 :
255 : (void)e;
256 : return boost::source_location();
257 :
258 : #else
259 :
260 : if( detail::throw_location const* pl = dynamic_cast< detail::throw_location const* >( &e ) )
261 : {
262 : return pl->location_;
263 : }
264 : else if( boost::exception const* px = dynamic_cast< boost::exception const* >( &e ) )
265 : {
266 : return exception_detail::get_exception_throw_location( *px );
267 : }
268 : else
269 : {
270 : return boost::source_location();
271 : }
272 :
273 : #endif
274 : }
275 :
276 : } // namespace boost
277 :
278 : #endif // #ifndef BOOST_THROW_EXCEPTION_HPP_INCLUDED
|