1 #ifndef BOOST_THROW_EXCEPTION_HPP_INCLUDED
2 #define BOOST_THROW_EXCEPTION_HPP_INCLUDED
4 // MS compatible compilers support #pragma once
6 #if defined(_MSC_VER) && (_MSC_VER >= 1020)
10 // boost/throw_exception.hpp
12 // Copyright (c) 2002, 2018-2022 Peter Dimov
13 // Copyright (c) 2008-2009 Emil Dotchevski and Reverge Studios, Inc.
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)
19 // http://www.boost.org/libs/throw_exception
21 #include <boost/exception/exception.hpp>
22 #include <boost/assert/source_location.hpp>
23 #include <boost/config.hpp>
24 #include <boost/config/workaround.hpp>
28 #if !defined(BOOST_NO_CXX11_HDR_TYPE_TRAITS)
29 #include <type_traits>
32 #if !defined( BOOST_EXCEPTION_DISABLE ) && defined( BOOST_BORLANDC ) && BOOST_WORKAROUND( BOOST_BORLANDC, BOOST_TESTED_AT(0x593) )
33 # define BOOST_EXCEPTION_DISABLE
39 #if defined( BOOST_NO_EXCEPTIONS )
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
46 // boost::wrapexcept<E>
51 typedef char (&wrapexcept_s1)[ 1 ];
52 typedef char (&wrapexcept_s2)[ 2 ];
54 template<class T> wrapexcept_s1 wrapexcept_is_convertible( T* );
55 template<class T> wrapexcept_s2 wrapexcept_is_convertible( void* );
57 template<class E, class B, std::size_t I = sizeof( wrapexcept_is_convertible<B>( static_cast< E* >( BOOST_NULLPTR ) ) ) > struct wrapexcept_add_base;
59 template<class E, class B> struct wrapexcept_add_base<E, B, 1>
64 template<class E, class B> struct wrapexcept_add_base<E, B, 2>
71 template<class E> struct BOOST_SYMBOL_VISIBLE wrapexcept:
72 public detail::wrapexcept_add_base<E, boost::exception_detail::clone_base>::type,
74 public detail::wrapexcept_add_base<E, boost::exception>::type
81 ~deleter() { delete p_; }
86 void copy_from( void const* )
90 void copy_from( boost::exception const* p )
92 static_cast<boost::exception&>( *this ) = *p;
97 explicit wrapexcept( E const & e ): E( e )
102 explicit wrapexcept( E const & e, boost::source_location const & loc ): E( e )
106 set_info( *this, throw_file( loc.file_name() ) );
107 set_info( *this, throw_line( loc.line() ) );
108 set_info( *this, throw_function( loc.function_name() ) );
109 set_info( *this, throw_column( loc.column() ) );
112 virtual boost::exception_detail::clone_base const * clone() const BOOST_OVERRIDE
114 wrapexcept * p = new wrapexcept( *this );
117 boost::exception_detail::copy_boost_exception( p, this );
119 del.p_ = BOOST_NULLPTR;
123 virtual void rethrow() const BOOST_OVERRIDE
125 #if defined( BOOST_NO_EXCEPTIONS )
127 boost::throw_exception( *this );
137 // All boost exceptions are required to derive from std::exception,
138 // to ensure compatibility with BOOST_NO_EXCEPTIONS.
140 inline void throw_exception_assert_compatibility( std::exception const & ) {}
142 // boost::throw_exception
144 #if !defined( BOOST_NO_EXCEPTIONS )
146 #if defined( BOOST_EXCEPTION_DISABLE )
148 template<class E> BOOST_NORETURN void throw_exception( E const & e )
150 throw_exception_assert_compatibility( e );
154 template<class E> BOOST_NORETURN void throw_exception( E const & e, boost::source_location const & )
156 throw_exception_assert_compatibility( e );
160 #else // defined( BOOST_EXCEPTION_DISABLE )
162 template<class E> BOOST_NORETURN void throw_exception( E const & e )
164 throw_exception_assert_compatibility( e );
165 throw wrapexcept<E>( e );
168 template<class E> BOOST_NORETURN void throw_exception( E const & e, boost::source_location const & loc )
170 throw_exception_assert_compatibility( e );
171 throw wrapexcept<E>( e, loc );
174 #endif // defined( BOOST_EXCEPTION_DISABLE )
176 #endif // !defined( BOOST_NO_EXCEPTIONS )
180 // BOOST_THROW_EXCEPTION
182 #define BOOST_THROW_EXCEPTION(x) ::boost::throw_exception(x, BOOST_CURRENT_LOCATION)
187 // throw_with_location
192 struct BOOST_SYMBOL_VISIBLE throw_location
194 boost::source_location location_;
196 explicit throw_location( boost::source_location const & loc ): location_( loc )
201 template<class E> class BOOST_SYMBOL_VISIBLE with_throw_location: public E, public throw_location
205 with_throw_location( E const & e, boost::source_location const & loc ): E( e ), throw_location( loc )
209 #if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
211 with_throw_location( E && e, boost::source_location const & loc ): E( std::move( e ) ), throw_location( loc )
218 } // namespace detail
220 #if !defined(BOOST_NO_EXCEPTIONS)
222 #if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) && !defined(BOOST_NO_CXX11_HDR_TYPE_TRAITS)
224 template<class E> BOOST_NORETURN void throw_with_location( E && e, boost::source_location const & loc = BOOST_CURRENT_LOCATION )
226 throw_exception_assert_compatibility( e );
227 throw detail::with_throw_location<typename std::decay<E>::type>( std::forward<E>( e ), loc );
232 template<class E> BOOST_NORETURN void throw_with_location( E const & e, boost::source_location const & loc = BOOST_CURRENT_LOCATION )
234 throw_exception_assert_compatibility( e );
235 throw detail::with_throw_location<E>( e, loc );
242 template<class E> BOOST_NORETURN void throw_with_location( E const & e, boost::source_location const & loc = BOOST_CURRENT_LOCATION )
244 boost::throw_exception( e, loc );
249 // get_throw_location
251 template<class E> boost::source_location get_throw_location( E const & e )
253 #if defined(BOOST_NO_RTTI)
256 return boost::source_location();
260 if( detail::throw_location const* pl = dynamic_cast< detail::throw_location const* >( &e ) )
262 return pl->location_;
264 else if( boost::exception const* px = dynamic_cast< boost::exception const* >( &e ) )
266 return exception_detail::get_exception_throw_location( *px );
270 return boost::source_location();
278 #endif // #ifndef BOOST_THROW_EXCEPTION_HPP_INCLUDED