Move wrapexcept's source location to a non-polymorphic, detail base class; add boost::get_throw_location

This commit is contained in:
Peter Dimov
2022-01-26 07:10:38 +02:00
parent f1419ae6de
commit 7d804d72b8

View File

@ -41,18 +41,11 @@ BOOST_NORETURN void throw_exception( std::exception const & e, boost::source_loc
#endif #endif
// has_throw_location
struct has_throw_location
{
virtual boost::source_location location() const BOOST_NOEXCEPT = 0;
};
// wrapexcept<E>
namespace detail namespace detail
{ {
// wrapexcept_add_base
typedef char (&wrapexcept_s1)[ 1 ]; typedef char (&wrapexcept_s1)[ 1 ];
typedef char (&wrapexcept_s2)[ 2 ]; typedef char (&wrapexcept_s2)[ 2 ];
@ -71,8 +64,20 @@ template<class E, class B> struct wrapexcept_add_base<E, B, 2>
typedef B type; typedef B type;
}; };
// wrapexcept_location
struct wrapexcept_location
{
wrapexcept_location() {}
explicit wrapexcept_location( boost::source_location const& loc ): loc_( loc ) {}
boost::source_location const loc_;
};
} // namespace detail } // namespace detail
// wrapexcept<E>
#if !defined(BOOST_NO_CXX11_HDR_EXCEPTION) #if !defined(BOOST_NO_CXX11_HDR_EXCEPTION)
template<class E, int cxxstd = 11> struct BOOST_SYMBOL_VISIBLE wrapexcept; template<class E, int cxxstd = 11> struct BOOST_SYMBOL_VISIBLE wrapexcept;
@ -88,7 +93,8 @@ template<class E, int cxxstd = 98> struct BOOST_SYMBOL_VISIBLE wrapexcept;
template<class E> struct BOOST_SYMBOL_VISIBLE wrapexcept<E, 98>: template<class E> struct BOOST_SYMBOL_VISIBLE wrapexcept<E, 98>:
public detail::wrapexcept_add_base<E, boost::exception_detail::clone_base>::type, public detail::wrapexcept_add_base<E, boost::exception_detail::clone_base>::type,
public E, public E,
public detail::wrapexcept_add_base<E, boost::exception>::type public detail::wrapexcept_add_base<E, boost::exception>::type,
public detail::wrapexcept_location
{ {
private: private:
@ -116,7 +122,7 @@ public:
copy_from( &e ); copy_from( &e );
} }
explicit wrapexcept( E const & e, boost::source_location const & loc ): E( e ) explicit wrapexcept( E const & e, boost::source_location const & loc ): E( e ), detail::wrapexcept_location( loc )
{ {
copy_from( &e ); copy_from( &e );
@ -154,12 +160,8 @@ public:
template<class E> struct BOOST_SYMBOL_VISIBLE wrapexcept<E, 11>: template<class E> struct BOOST_SYMBOL_VISIBLE wrapexcept<E, 11>:
public E, public E,
public has_throw_location public detail::wrapexcept_location
{ {
private:
boost::source_location loc_;
private: private:
void copy_from( void const* ) void copy_from( void const* )
@ -187,7 +189,7 @@ public:
copy_from( &e ); copy_from( &e );
} }
explicit wrapexcept( E const & e, boost::source_location const & loc ): E( e ), loc_( loc ) explicit wrapexcept( E const & e, boost::source_location const & loc ): E( e ), detail::wrapexcept_location( loc )
{ {
copy_from( &e ); copy_from( &e );
@ -257,6 +259,22 @@ template<class E> BOOST_NORETURN void throw_exception( E const & e, boost::sourc
#endif // !defined( BOOST_NO_EXCEPTIONS ) #endif // !defined( BOOST_NO_EXCEPTIONS )
// get_throw_location
template<class E> boost::source_location get_throw_location( E const& e )
{
#if defined(BOOST_NO_RTTI)
return boost::source_location();
#else
detail::wrapexcept_location const* p = dynamic_cast< detail::wrapexcept_location const* >( &e );
return p? p->loc_: boost::source_location();
#endif
}
} // namespace boost } // namespace boost
// BOOST_THROW_EXCEPTION // BOOST_THROW_EXCEPTION