forked from boostorg/throw_exception
Add throw_column to boost::exception, make get_throw_location work for it
This commit is contained in:
@ -6,6 +6,7 @@
|
|||||||
#ifndef BOOST_EXCEPTION_274DA366004E11DCB1DDFE2E56D89593
|
#ifndef BOOST_EXCEPTION_274DA366004E11DCB1DDFE2E56D89593
|
||||||
#define BOOST_EXCEPTION_274DA366004E11DCB1DDFE2E56D89593
|
#define BOOST_EXCEPTION_274DA366004E11DCB1DDFE2E56D89593
|
||||||
|
|
||||||
|
#include <boost/assert/source_location.hpp>
|
||||||
#include <boost/config.hpp>
|
#include <boost/config.hpp>
|
||||||
#include <exception>
|
#include <exception>
|
||||||
|
|
||||||
@ -107,6 +108,7 @@ boost
|
|||||||
typedef error_info<struct throw_function_,char const *> throw_function;
|
typedef error_info<struct throw_function_,char const *> throw_function;
|
||||||
typedef error_info<struct throw_file_,char const *> throw_file;
|
typedef error_info<struct throw_file_,char const *> throw_file;
|
||||||
typedef error_info<struct throw_line_,int> throw_line;
|
typedef error_info<struct throw_line_,int> throw_line;
|
||||||
|
typedef error_info<struct throw_column_,int> throw_column;
|
||||||
|
|
||||||
template <>
|
template <>
|
||||||
class
|
class
|
||||||
@ -150,6 +152,20 @@ boost
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template <>
|
||||||
|
class
|
||||||
|
error_info<throw_column_,int>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
typedef int value_type;
|
||||||
|
value_type v_;
|
||||||
|
explicit
|
||||||
|
error_info( value_type v ):
|
||||||
|
v_(v)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
class
|
class
|
||||||
BOOST_SYMBOL_VISIBLE
|
BOOST_SYMBOL_VISIBLE
|
||||||
exception;
|
exception;
|
||||||
@ -189,6 +205,9 @@ boost
|
|||||||
template <>
|
template <>
|
||||||
struct get_info<throw_line>;
|
struct get_info<throw_line>;
|
||||||
|
|
||||||
|
template <>
|
||||||
|
struct get_info<throw_column>;
|
||||||
|
|
||||||
template <class>
|
template <class>
|
||||||
struct set_info_rv;
|
struct set_info_rv;
|
||||||
|
|
||||||
@ -201,6 +220,9 @@ boost
|
|||||||
template <>
|
template <>
|
||||||
struct set_info_rv<throw_line>;
|
struct set_info_rv<throw_line>;
|
||||||
|
|
||||||
|
template <>
|
||||||
|
struct set_info_rv<throw_column>;
|
||||||
|
|
||||||
char const * get_diagnostic_information( exception const &, char const * );
|
char const * get_diagnostic_information( exception const &, char const * );
|
||||||
|
|
||||||
void copy_boost_exception( exception *, exception const * );
|
void copy_boost_exception( exception *, exception const * );
|
||||||
@ -216,6 +238,11 @@ boost
|
|||||||
|
|
||||||
template <class E>
|
template <class E>
|
||||||
E const & set_info( E const &, throw_line const & );
|
E const & set_info( E const &, throw_line const & );
|
||||||
|
|
||||||
|
template <class E>
|
||||||
|
E const & set_info( E const &, throw_column const & );
|
||||||
|
|
||||||
|
boost::source_location get_exception_throw_location( exception const & );
|
||||||
}
|
}
|
||||||
|
|
||||||
class
|
class
|
||||||
@ -233,7 +260,8 @@ boost
|
|||||||
exception():
|
exception():
|
||||||
throw_function_(0),
|
throw_function_(0),
|
||||||
throw_file_(0),
|
throw_file_(0),
|
||||||
throw_line_(-1)
|
throw_line_(-1),
|
||||||
|
throw_column_(-1)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -244,7 +272,8 @@ boost
|
|||||||
data_(x.data_),
|
data_(x.data_),
|
||||||
throw_function_(x.throw_function_),
|
throw_function_(x.throw_function_),
|
||||||
throw_file_(x.throw_file_),
|
throw_file_(x.throw_file_),
|
||||||
throw_line_(x.throw_line_)
|
throw_line_(x.throw_line_),
|
||||||
|
throw_column_(x.throw_column_)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@ -269,27 +298,35 @@ boost
|
|||||||
template <class E>
|
template <class E>
|
||||||
friend E const & exception_detail::set_info( E const &, throw_line const & );
|
friend E const & exception_detail::set_info( E const &, throw_line const & );
|
||||||
|
|
||||||
|
template <class E>
|
||||||
|
friend E const & exception_detail::set_info( E const &, throw_column const & );
|
||||||
|
|
||||||
template <class E,class Tag,class T>
|
template <class E,class Tag,class T>
|
||||||
friend E const & exception_detail::set_info( E const &, error_info<Tag,T> const & );
|
friend E const & exception_detail::set_info( E const &, error_info<Tag,T> const & );
|
||||||
|
|
||||||
friend char const * exception_detail::get_diagnostic_information( exception const &, char const * );
|
friend char const * exception_detail::get_diagnostic_information( exception const &, char const * );
|
||||||
|
|
||||||
|
friend boost::source_location exception_detail::get_exception_throw_location( exception const & );
|
||||||
|
|
||||||
template <class>
|
template <class>
|
||||||
friend struct exception_detail::get_info;
|
friend struct exception_detail::get_info;
|
||||||
friend struct exception_detail::get_info<throw_function>;
|
friend struct exception_detail::get_info<throw_function>;
|
||||||
friend struct exception_detail::get_info<throw_file>;
|
friend struct exception_detail::get_info<throw_file>;
|
||||||
friend struct exception_detail::get_info<throw_line>;
|
friend struct exception_detail::get_info<throw_line>;
|
||||||
|
friend struct exception_detail::get_info<throw_column>;
|
||||||
template <class>
|
template <class>
|
||||||
friend struct exception_detail::set_info_rv;
|
friend struct exception_detail::set_info_rv;
|
||||||
friend struct exception_detail::set_info_rv<throw_function>;
|
friend struct exception_detail::set_info_rv<throw_function>;
|
||||||
friend struct exception_detail::set_info_rv<throw_file>;
|
friend struct exception_detail::set_info_rv<throw_file>;
|
||||||
friend struct exception_detail::set_info_rv<throw_line>;
|
friend struct exception_detail::set_info_rv<throw_line>;
|
||||||
|
friend struct exception_detail::set_info_rv<throw_column>;
|
||||||
friend void exception_detail::copy_boost_exception( exception *, exception const * );
|
friend void exception_detail::copy_boost_exception( exception *, exception const * );
|
||||||
#endif
|
#endif
|
||||||
mutable exception_detail::refcount_ptr<exception_detail::error_info_container> data_;
|
mutable exception_detail::refcount_ptr<exception_detail::error_info_container> data_;
|
||||||
mutable char const * throw_function_;
|
mutable char const * throw_function_;
|
||||||
mutable char const * throw_file_;
|
mutable char const * throw_file_;
|
||||||
mutable int throw_line_;
|
mutable int throw_line_;
|
||||||
|
mutable int throw_column_;
|
||||||
};
|
};
|
||||||
|
|
||||||
inline
|
inline
|
||||||
@ -324,6 +361,42 @@ boost
|
|||||||
x.throw_line_=y.v_;
|
x.throw_line_=y.v_;
|
||||||
return x;
|
return x;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <class E>
|
||||||
|
E const &
|
||||||
|
set_info( E const & x, throw_column const & y )
|
||||||
|
{
|
||||||
|
x.throw_column_=y.v_;
|
||||||
|
return x;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
|
||||||
|
|
||||||
|
template <>
|
||||||
|
struct
|
||||||
|
set_info_rv<throw_column>
|
||||||
|
{
|
||||||
|
template <class E>
|
||||||
|
static
|
||||||
|
E const &
|
||||||
|
set( E const & x, throw_column && y )
|
||||||
|
{
|
||||||
|
x.throw_column_=y.v_;
|
||||||
|
return x;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
inline boost::source_location get_exception_throw_location( exception const & x )
|
||||||
|
{
|
||||||
|
return boost::source_location(
|
||||||
|
x.throw_file_? x.throw_file_: "",
|
||||||
|
x.throw_line_ >= 0? x.throw_line_: 0,
|
||||||
|
x.throw_function_? x.throw_function_: "",
|
||||||
|
x.throw_column_ >= 0? x.throw_column_: 0
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////
|
||||||
@ -423,6 +496,7 @@ boost
|
|||||||
a->throw_file_ = b->throw_file_;
|
a->throw_file_ = b->throw_file_;
|
||||||
a->throw_line_ = b->throw_line_;
|
a->throw_line_ = b->throw_line_;
|
||||||
a->throw_function_ = b->throw_function_;
|
a->throw_function_ = b->throw_function_;
|
||||||
|
a->throw_column_ = b->throw_column_;
|
||||||
a->data_ = data;
|
a->data_ = data;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -106,6 +106,7 @@ public:
|
|||||||
set_info( *this, throw_file( loc.file_name() ) );
|
set_info( *this, throw_file( loc.file_name() ) );
|
||||||
set_info( *this, throw_line( loc.line() ) );
|
set_info( *this, throw_line( loc.line() ) );
|
||||||
set_info( *this, throw_function( loc.function_name() ) );
|
set_info( *this, throw_function( loc.function_name() ) );
|
||||||
|
set_info( *this, throw_column( loc.column() ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual boost::exception_detail::clone_base const * clone() const BOOST_OVERRIDE
|
virtual boost::exception_detail::clone_base const * clone() const BOOST_OVERRIDE
|
||||||
@ -256,8 +257,18 @@ template<class E> boost::source_location get_throw_location( E const & e )
|
|||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
detail::throw_location const* p = dynamic_cast< detail::throw_location const* >( &e );
|
if( detail::throw_location const* pl = dynamic_cast< detail::throw_location const* >( &e ) )
|
||||||
return p? p->location_: boost::source_location();
|
{
|
||||||
|
return pl->location_;
|
||||||
|
}
|
||||||
|
else if( boost::exception const* px = dynamic_cast< boost::exception const* >( &e ) )
|
||||||
|
{
|
||||||
|
return exception_detail::get_exception_throw_location( *px );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return boost::source_location();
|
||||||
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
@ -49,6 +49,7 @@ run make_exception_ptr_nx_test2.cpp : : : <exception-handling>off ;
|
|||||||
run throw_with_location_test.cpp ;
|
run throw_with_location_test.cpp ;
|
||||||
run throw_with_location_test2.cpp ;
|
run throw_with_location_test2.cpp ;
|
||||||
run throw_with_location_test3.cpp ;
|
run throw_with_location_test3.cpp ;
|
||||||
|
run throw_with_location_test4.cpp ;
|
||||||
|
|
||||||
run throw_with_location_nx_test.cpp : : : <exception-handling>off ;
|
run throw_with_location_nx_test.cpp : : : <exception-handling>off ;
|
||||||
|
|
||||||
|
41
test/throw_with_location_test4.cpp
Normal file
41
test/throw_with_location_test4.cpp
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
// 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::source_location location = BOOST_CURRENT_LOCATION;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
boost::throw_exception( my_exception(), location );
|
||||||
|
|
||||||
|
BOOST_ERROR( "boost::throw_exception 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_exception failed to throw std::exception" );
|
||||||
|
}
|
||||||
|
|
||||||
|
return boost::report_errors();
|
||||||
|
}
|
Reference in New Issue
Block a user