Add boost::throw_with_location
This commit is contained in:
parent
7b314a2184
commit
c5dfcc3dd4
|
@ -7,10 +7,9 @@
|
|||
# pragma once
|
||||
#endif
|
||||
|
||||
//
|
||||
// boost/throw_exception.hpp
|
||||
//
|
||||
// Copyright (c) 2002, 2018, 2019 Peter Dimov
|
||||
// Copyright (c) 2002, 2018-2022 Peter Dimov
|
||||
// Copyright (c) 2008-2009 Emil Dotchevski and Reverge Studios, Inc.
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
|
@ -18,14 +17,17 @@
|
|||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
// http://www.boost.org/libs/throw_exception
|
||||
//
|
||||
|
||||
#include <boost/exception/exception.hpp>
|
||||
#include <boost/assert/source_location.hpp>
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/config/workaround.hpp>
|
||||
#include <exception>
|
||||
#include <utility>
|
||||
#include <cstddef>
|
||||
#if !defined(BOOST_NO_CXX11_HDR_TYPE_TRAITS)
|
||||
#include <type_traits>
|
||||
#endif
|
||||
|
||||
#if !defined( BOOST_EXCEPTION_DISABLE ) && defined( BOOST_BORLANDC ) && BOOST_WORKAROUND( BOOST_BORLANDC, BOOST_TESTED_AT(0x593) )
|
||||
# define BOOST_EXCEPTION_DISABLE
|
||||
|
@ -178,4 +180,87 @@ template<class E> BOOST_NORETURN void throw_exception( E const & e, boost::sourc
|
|||
|
||||
#define BOOST_THROW_EXCEPTION(x) ::boost::throw_exception(x, BOOST_CURRENT_LOCATION)
|
||||
|
||||
namespace boost
|
||||
{
|
||||
|
||||
// throw_with_location
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
struct BOOST_SYMBOL_VISIBLE throw_location
|
||||
{
|
||||
boost::source_location location_;
|
||||
|
||||
explicit throw_location( boost::source_location const & loc ): location_( loc )
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
template<class E> class BOOST_SYMBOL_VISIBLE with_throw_location: public E, public throw_location
|
||||
{
|
||||
public:
|
||||
|
||||
with_throw_location( E const & e, boost::source_location const & loc ): E( e ), throw_location( loc )
|
||||
{
|
||||
}
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
|
||||
|
||||
with_throw_location( E && e, boost::source_location const & loc ): E( std::move( e ) ), throw_location( loc )
|
||||
{
|
||||
}
|
||||
|
||||
#endif
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
#if !defined(BOOST_NO_EXCEPTIONS)
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) && !defined(BOOST_NO_CXX11_HDR_TYPE_TRAITS)
|
||||
|
||||
template<class E> BOOST_NORETURN void throw_with_location( E && e, boost::source_location const & loc = BOOST_CURRENT_LOCATION )
|
||||
{
|
||||
throw_exception_assert_compatibility( e );
|
||||
throw detail::with_throw_location<typename std::decay<E>::type>( std::forward<E>( e ), loc );
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
template<class E> BOOST_NORETURN void throw_with_location( E const & e, boost::source_location const & loc = BOOST_CURRENT_LOCATION )
|
||||
{
|
||||
throw_exception_assert_compatibility( e );
|
||||
throw detail::with_throw_location<E>( e, loc );
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#else
|
||||
|
||||
template<class E> BOOST_NORETURN void throw_with_location( E const & e, boost::source_location const & loc = BOOST_CURRENT_LOCATION )
|
||||
{
|
||||
boost::throw_exception( e, loc );
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
// 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::throw_location const* p = dynamic_cast< detail::throw_location const* >( &e );
|
||||
return p? p->location_: boost::source_location();
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#endif // #ifndef BOOST_THROW_EXCEPTION_HPP_INCLUDED
|
||||
|
|
|
@ -31,9 +31,10 @@ run throw_exception_test5.cpp ;
|
|||
lib lib1_throw : lib1_throw.cpp : <define>LIB1_SOURCE=1 <link>shared:<define>LIB1_DYN_LINK=1 : : <link>shared:<define>LIB1_DYN_LINK=1 ;
|
||||
lib lib2_throw : lib2_throw.cpp : <define>LIB2_SOURCE=1 <link>shared:<define>LIB2_DYN_LINK=1 : : <link>shared:<define>LIB2_DYN_LINK=1 ;
|
||||
lib lib3_throw : lib3_throw.cpp : <define>LIB3_SOURCE=1 <link>shared:<define>LIB3_DYN_LINK=1 : : <link>shared:<define>LIB3_DYN_LINK=1 ;
|
||||
lib lib4_throw : lib4_throw.cpp : <define>LIB4_SOURCE=1 <link>shared:<define>LIB4_DYN_LINK=1 : : <link>shared:<define>LIB4_DYN_LINK=1 ;
|
||||
|
||||
run throw_from_library_test.cpp lib1_throw lib2_throw lib3_throw : : : <link>static : throw_from_library_static ;
|
||||
run throw_from_library_test.cpp lib1_throw lib2_throw lib3_throw : : : <link>shared : throw_from_library_shared ;
|
||||
run throw_from_library_test.cpp lib1_throw lib2_throw lib3_throw lib4_throw : : : <link>static : throw_from_library_static ;
|
||||
run throw_from_library_test.cpp lib1_throw lib2_throw lib3_throw lib4_throw : : : <link>shared : throw_from_library_shared ;
|
||||
|
||||
run throw_exception_nx_test.cpp : : : <exception-handling>off ;
|
||||
run throw_exception_nx_test2.cpp : : : <exception-handling>off ;
|
||||
|
@ -44,3 +45,9 @@ run make_exception_ptr_test2.cpp ;
|
|||
|
||||
run make_exception_ptr_nx_test.cpp : : : <exception-handling>off ;
|
||||
run make_exception_ptr_nx_test2.cpp : : : <exception-handling>off ;
|
||||
|
||||
run throw_with_location_test.cpp ;
|
||||
run throw_with_location_test2.cpp ;
|
||||
run throw_with_location_test3.cpp ;
|
||||
|
||||
run throw_with_location_nx_test.cpp : : : <exception-handling>off ;
|
||||
|
|
|
@ -0,0 +1,14 @@
|
|||
// Copyright 2018, 2022 Peter Dimov
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
//
|
||||
// See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
#include "lib4_throw.hpp"
|
||||
#include <boost/throw_exception.hpp>
|
||||
|
||||
void lib4::f()
|
||||
{
|
||||
boost::throw_with_location( lib4::exception() );
|
||||
}
|
|
@ -0,0 +1,35 @@
|
|||
#ifndef LIB4_THROW_HPP_INCLUDED
|
||||
#define LIB4_THROW_HPP_INCLUDED
|
||||
|
||||
// Copyright 2018, 2022 Peter Dimov
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
//
|
||||
// See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
#include <boost/config.hpp>
|
||||
#include <exception>
|
||||
|
||||
#if defined(LIB4_DYN_LINK)
|
||||
# if defined(LIB4_SOURCE)
|
||||
# define LIB4_DECL BOOST_SYMBOL_EXPORT
|
||||
# else
|
||||
# define LIB4_DECL BOOST_SYMBOL_IMPORT
|
||||
# endif
|
||||
#else
|
||||
# define LIB4_DECL
|
||||
#endif
|
||||
|
||||
namespace lib4
|
||||
{
|
||||
|
||||
struct BOOST_SYMBOL_VISIBLE exception: public std::exception
|
||||
{
|
||||
};
|
||||
|
||||
LIB4_DECL void f();
|
||||
|
||||
} // namespace lib4
|
||||
|
||||
#endif // #ifndef LIB4_THROW_HPP_INCLUDED
|
|
@ -20,6 +20,7 @@
|
|||
#include "lib1_throw.hpp"
|
||||
#include "lib2_throw.hpp"
|
||||
#include "lib3_throw.hpp"
|
||||
#include "lib4_throw.hpp"
|
||||
#include <boost/exception/exception.hpp>
|
||||
#include <boost/exception_ptr.hpp>
|
||||
#include <boost/exception/get_error_info.hpp>
|
||||
|
@ -30,6 +31,7 @@ void test_catch_by_type()
|
|||
BOOST_TEST_THROWS( lib1::f(), lib1::exception );
|
||||
BOOST_TEST_THROWS( lib2::f(), lib2::exception );
|
||||
BOOST_TEST_THROWS( lib3::f(), lib3::exception );
|
||||
BOOST_TEST_THROWS( lib4::f(), lib4::exception );
|
||||
}
|
||||
|
||||
void test_catch_by_exception()
|
||||
|
@ -78,6 +80,25 @@ void test_throw_line()
|
|||
BOOST_TEST( line != 0 );
|
||||
BOOST_TEST_EQ( *line, 13 );
|
||||
}
|
||||
catch( ... )
|
||||
{
|
||||
BOOST_ERROR( "lib3::f failed to throw boost::exception" );
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
lib4::f();
|
||||
}
|
||||
catch( std::exception const & x )
|
||||
{
|
||||
boost::source_location loc = boost::get_throw_location( x );
|
||||
|
||||
BOOST_TEST_NE( loc.line(), 0 );
|
||||
}
|
||||
catch( ... )
|
||||
{
|
||||
BOOST_ERROR( "lib4::f failed to throw std::exception" );
|
||||
}
|
||||
}
|
||||
|
||||
int main()
|
||||
|
|
|
@ -0,0 +1,30 @@
|
|||
// Copyright 2019, 2022 Peter Dimov
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// http://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
# pragma warning(disable: 4702) // unreachable code
|
||||
# pragma warning(disable: 4577) // noexcept used without /EHsc
|
||||
# pragma warning(disable: 4530) // C++ exception handler used
|
||||
#endif
|
||||
|
||||
#include <boost/throw_exception.hpp>
|
||||
#include <cstdlib>
|
||||
|
||||
class my_exception: public std::exception {};
|
||||
|
||||
int main()
|
||||
{
|
||||
boost::throw_with_location( my_exception() );
|
||||
return 1;
|
||||
}
|
||||
|
||||
namespace boost
|
||||
{
|
||||
|
||||
void throw_exception( std::exception const &, boost::source_location const & )
|
||||
{
|
||||
std::exit( 0 );
|
||||
}
|
||||
|
||||
} // namespace boost
|
|
@ -0,0 +1,22 @@
|
|||
// Copyright 2022 Peter Dimov
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// https://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
#include <boost/throw_exception.hpp>
|
||||
#include <boost/core/lightweight_test.hpp>
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
# pragma warning(disable: 4702) // unreachable code
|
||||
#endif
|
||||
|
||||
class my_exception: public std::exception
|
||||
{
|
||||
};
|
||||
|
||||
int main()
|
||||
{
|
||||
BOOST_TEST_THROWS( boost::throw_with_location( my_exception() ), my_exception );
|
||||
BOOST_TEST_THROWS( boost::throw_with_location( my_exception() ), std::exception );
|
||||
|
||||
return boost::report_errors();
|
||||
}
|
|
@ -0,0 +1,64 @@
|
|||
// Copyright 2022 Peter Dimov
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// https://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
#include <boost/throw_exception.hpp>
|
||||
#include <boost/core/lightweight_test.hpp>
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
# pragma warning(disable: 4702) // unreachable code
|
||||
#endif
|
||||
|
||||
class my_exception: public std::exception
|
||||
{
|
||||
};
|
||||
|
||||
int main()
|
||||
{
|
||||
try
|
||||
{
|
||||
boost::throw_with_location( my_exception() );
|
||||
|
||||
BOOST_ERROR( "boost::throw_with_location failed to throw" );
|
||||
}
|
||||
catch( std::exception const & x )
|
||||
{
|
||||
boost::source_location loc = boost::get_throw_location( x );
|
||||
|
||||
// When not supplied explicitly, the source location is best effort.
|
||||
// It should be the location of the throw_with_location call on
|
||||
// recent compilers, but that's not guaranteed for every compiler.
|
||||
// So we can't be more specific in testing it.
|
||||
|
||||
BOOST_TEST_CSTR_NE( loc.file_name(), "" );
|
||||
BOOST_TEST_NE( loc.line(), 0 );
|
||||
}
|
||||
catch( ... )
|
||||
{
|
||||
BOOST_ERROR( "boost::throw_with_location failed to throw std::exception" );
|
||||
}
|
||||
|
||||
boost::source_location location = BOOST_CURRENT_LOCATION;
|
||||
|
||||
try
|
||||
{
|
||||
boost::throw_with_location( my_exception(), location );
|
||||
|
||||
BOOST_ERROR( "boost::throw_with_location failed to throw" );
|
||||
}
|
||||
catch( std::exception const & x )
|
||||
{
|
||||
boost::source_location loc = boost::get_throw_location( x );
|
||||
|
||||
BOOST_TEST_CSTR_EQ( loc.file_name(), location.file_name() );
|
||||
BOOST_TEST_CSTR_EQ( loc.function_name(), location.function_name() );
|
||||
BOOST_TEST_EQ( loc.line(), location.line() );
|
||||
BOOST_TEST_EQ( loc.column(), location.column() );
|
||||
}
|
||||
catch( ... )
|
||||
{
|
||||
BOOST_ERROR( "boost::throw_with_location failed to throw std::exception" );
|
||||
}
|
||||
|
||||
return boost::report_errors();
|
||||
}
|
|
@ -0,0 +1,33 @@
|
|||
// Copyright 2022 Peter Dimov
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// https://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
#include <boost/throw_exception.hpp>
|
||||
#include <boost/core/lightweight_test.hpp>
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
# pragma warning(disable: 4702) // unreachable code
|
||||
#endif
|
||||
|
||||
class my_exception: public std::exception
|
||||
{
|
||||
};
|
||||
|
||||
int main()
|
||||
{
|
||||
try
|
||||
{
|
||||
throw my_exception();
|
||||
}
|
||||
catch( std::exception const & x )
|
||||
{
|
||||
boost::source_location loc = boost::get_throw_location( x );
|
||||
|
||||
BOOST_TEST_CSTR_EQ( loc.file_name(), "" );
|
||||
BOOST_TEST_CSTR_EQ( loc.function_name(), "" );
|
||||
BOOST_TEST_EQ( loc.line(), 0 );
|
||||
BOOST_TEST_EQ( loc.column(), 0 );
|
||||
}
|
||||
|
||||
return boost::report_errors();
|
||||
}
|
Loading…
Reference in New Issue