File indexing completed on 2024-11-15 09:34:17
0001 #ifndef BOOST_THROW_EXCEPTION_HPP_INCLUDED
0002 #define BOOST_THROW_EXCEPTION_HPP_INCLUDED
0003
0004
0005
0006 #if defined(_MSC_VER) && (_MSC_VER >= 1020)
0007 # pragma once
0008 #endif
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021 #include <boost/exception/exception.hpp>
0022 #include <boost/assert/source_location.hpp>
0023 #include <boost/config.hpp>
0024 #include <boost/config/workaround.hpp>
0025 #include <exception>
0026 #include <utility>
0027 #include <cstddef>
0028 #if !defined(BOOST_NO_CXX11_HDR_TYPE_TRAITS)
0029 #include <type_traits>
0030 #endif
0031
0032 #if !defined( BOOST_EXCEPTION_DISABLE ) && defined( BOOST_BORLANDC ) && BOOST_WORKAROUND( BOOST_BORLANDC, BOOST_TESTED_AT(0x593) )
0033 # define BOOST_EXCEPTION_DISABLE
0034 #endif
0035
0036 namespace boost
0037 {
0038
0039 #if defined( BOOST_NO_EXCEPTIONS )
0040
0041 BOOST_NORETURN void throw_exception( std::exception const & e );
0042 BOOST_NORETURN void throw_exception( std::exception const & e, boost::source_location const & loc );
0043
0044 #endif
0045
0046
0047
0048 namespace detail
0049 {
0050
0051 typedef char (&wrapexcept_s1)[ 1 ];
0052 typedef char (&wrapexcept_s2)[ 2 ];
0053
0054 template<class T> wrapexcept_s1 wrapexcept_is_convertible( T* );
0055 template<class T> wrapexcept_s2 wrapexcept_is_convertible( void* );
0056
0057 template<class E, class B, std::size_t I = sizeof( wrapexcept_is_convertible<B>( static_cast< E* >( BOOST_NULLPTR ) ) ) > struct wrapexcept_add_base;
0058
0059 template<class E, class B> struct wrapexcept_add_base<E, B, 1>
0060 {
0061 struct type {};
0062 };
0063
0064 template<class E, class B> struct wrapexcept_add_base<E, B, 2>
0065 {
0066 typedef B type;
0067 };
0068
0069 }
0070
0071 template<class E> struct BOOST_SYMBOL_VISIBLE wrapexcept:
0072 public detail::wrapexcept_add_base<E, boost::exception_detail::clone_base>::type,
0073 public E,
0074 public detail::wrapexcept_add_base<E, boost::exception>::type
0075 {
0076 private:
0077
0078 struct deleter
0079 {
0080 wrapexcept * p_;
0081 ~deleter() { delete p_; }
0082 };
0083
0084 private:
0085
0086 void copy_from( void const* )
0087 {
0088 }
0089
0090 void copy_from( boost::exception const* p )
0091 {
0092 static_cast<boost::exception&>( *this ) = *p;
0093 }
0094
0095 public:
0096
0097 explicit wrapexcept( E const & e ): E( e )
0098 {
0099 copy_from( &e );
0100 }
0101
0102 explicit wrapexcept( E const & e, boost::source_location const & loc ): E( e )
0103 {
0104 copy_from( &e );
0105
0106 set_info( *this, throw_file( loc.file_name() ) );
0107 set_info( *this, throw_line( static_cast<int>( loc.line() ) ) );
0108 set_info( *this, throw_function( loc.function_name() ) );
0109 set_info( *this, throw_column( static_cast<int>( loc.column() ) ) );
0110 }
0111
0112 virtual boost::exception_detail::clone_base const * clone() const BOOST_OVERRIDE
0113 {
0114 wrapexcept * p = new wrapexcept( *this );
0115 deleter del = { p };
0116
0117 boost::exception_detail::copy_boost_exception( p, this );
0118
0119 del.p_ = BOOST_NULLPTR;
0120 return p;
0121 }
0122
0123 virtual void rethrow() const BOOST_OVERRIDE
0124 {
0125 #if defined( BOOST_NO_EXCEPTIONS )
0126
0127 boost::throw_exception( *this );
0128
0129 #else
0130
0131 throw *this;
0132
0133 #endif
0134 }
0135 };
0136
0137
0138
0139
0140 inline void throw_exception_assert_compatibility( std::exception const & ) {}
0141
0142
0143
0144 #if !defined( BOOST_NO_EXCEPTIONS )
0145
0146 #if defined( BOOST_EXCEPTION_DISABLE )
0147
0148 template<class E> BOOST_NORETURN void throw_exception( E const & e )
0149 {
0150 throw_exception_assert_compatibility( e );
0151 throw e;
0152 }
0153
0154 template<class E> BOOST_NORETURN void throw_exception( E const & e, boost::source_location const & )
0155 {
0156 throw_exception_assert_compatibility( e );
0157 throw e;
0158 }
0159
0160 #else
0161
0162 template<class E> BOOST_NORETURN void throw_exception( E const & e )
0163 {
0164 throw_exception_assert_compatibility( e );
0165 throw wrapexcept<E>( e );
0166 }
0167
0168 template<class E> BOOST_NORETURN void throw_exception( E const & e, boost::source_location const & loc )
0169 {
0170 throw_exception_assert_compatibility( e );
0171 throw wrapexcept<E>( e, loc );
0172 }
0173
0174 #endif
0175
0176 #endif
0177
0178 }
0179
0180
0181
0182 #define BOOST_THROW_EXCEPTION(x) ::boost::throw_exception(x, BOOST_CURRENT_LOCATION)
0183
0184 namespace boost
0185 {
0186
0187
0188
0189 namespace detail
0190 {
0191
0192 struct BOOST_SYMBOL_VISIBLE throw_location
0193 {
0194 boost::source_location location_;
0195
0196 explicit throw_location( boost::source_location const & loc ): location_( loc )
0197 {
0198 }
0199 };
0200
0201 template<class E> class BOOST_SYMBOL_VISIBLE with_throw_location: public E, public throw_location
0202 {
0203 public:
0204
0205 with_throw_location( E const & e, boost::source_location const & loc ): E( e ), throw_location( loc )
0206 {
0207 }
0208
0209 #if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
0210
0211 with_throw_location( E && e, boost::source_location const & loc ): E( std::move( e ) ), throw_location( loc )
0212 {
0213 }
0214
0215 #endif
0216 };
0217
0218 }
0219
0220 #if !defined(BOOST_NO_EXCEPTIONS)
0221
0222 #if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) && !defined(BOOST_NO_CXX11_HDR_TYPE_TRAITS)
0223
0224 template<class E> BOOST_NORETURN void throw_with_location( E && e, boost::source_location const & loc = BOOST_CURRENT_LOCATION )
0225 {
0226 throw_exception_assert_compatibility( e );
0227 throw detail::with_throw_location<typename std::decay<E>::type>( std::forward<E>( e ), loc );
0228 }
0229
0230 #else
0231
0232 template<class E> BOOST_NORETURN void throw_with_location( E const & e, boost::source_location const & loc = BOOST_CURRENT_LOCATION )
0233 {
0234 throw_exception_assert_compatibility( e );
0235 throw detail::with_throw_location<E>( e, loc );
0236 }
0237
0238 #endif
0239
0240 #else
0241
0242 template<class E> BOOST_NORETURN void throw_with_location( E const & e, boost::source_location const & loc = BOOST_CURRENT_LOCATION )
0243 {
0244 boost::throw_exception( e, loc );
0245 }
0246
0247 #endif
0248
0249
0250
0251 template<class E> boost::source_location get_throw_location( E const & e )
0252 {
0253 #if defined(BOOST_NO_RTTI)
0254
0255 (void)e;
0256 return boost::source_location();
0257
0258 #else
0259
0260 if( detail::throw_location const* pl = dynamic_cast< detail::throw_location const* >( &e ) )
0261 {
0262 return pl->location_;
0263 }
0264 else if( boost::exception const* px = dynamic_cast< boost::exception const* >( &e ) )
0265 {
0266 return exception_detail::get_exception_throw_location( *px );
0267 }
0268 else
0269 {
0270 return boost::source_location();
0271 }
0272
0273 #endif
0274 }
0275
0276 }
0277
0278 #endif