Add throw_column to boost::exception, make get_throw_location work for it

This commit is contained in:
Peter Dimov
2022-02-16 13:45:54 +02:00
parent e14f6ed69e
commit 26f3ce3c5c
4 changed files with 131 additions and 4 deletions

View File

@ -6,6 +6,7 @@
#ifndef BOOST_EXCEPTION_274DA366004E11DCB1DDFE2E56D89593
#define BOOST_EXCEPTION_274DA366004E11DCB1DDFE2E56D89593
#include <boost/assert/source_location.hpp>
#include <boost/config.hpp>
#include <exception>
@ -107,6 +108,7 @@ boost
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_line_,int> throw_line;
typedef error_info<struct throw_column_,int> throw_column;
template <>
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
BOOST_SYMBOL_VISIBLE
exception;
@ -189,6 +205,9 @@ boost
template <>
struct get_info<throw_line>;
template <>
struct get_info<throw_column>;
template <class>
struct set_info_rv;
@ -201,6 +220,9 @@ boost
template <>
struct set_info_rv<throw_line>;
template <>
struct set_info_rv<throw_column>;
char const * get_diagnostic_information( exception const &, char const * );
void copy_boost_exception( exception *, exception const * );
@ -216,6 +238,11 @@ boost
template <class E>
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
@ -233,7 +260,8 @@ boost
exception():
throw_function_(0),
throw_file_(0),
throw_line_(-1)
throw_line_(-1),
throw_column_(-1)
{
}
@ -244,7 +272,8 @@ boost
data_(x.data_),
throw_function_(x.throw_function_),
throw_file_(x.throw_file_),
throw_line_(x.throw_line_)
throw_line_(x.throw_line_),
throw_column_(x.throw_column_)
{
}
#endif
@ -269,27 +298,35 @@ boost
template <class E>
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>
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 boost::source_location exception_detail::get_exception_throw_location( exception const & );
template <class>
friend struct exception_detail::get_info;
friend struct exception_detail::get_info<throw_function>;
friend struct exception_detail::get_info<throw_file>;
friend struct exception_detail::get_info<throw_line>;
friend struct exception_detail::get_info<throw_column>;
template <class>
friend struct exception_detail::set_info_rv;
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_line>;
friend struct exception_detail::set_info_rv<throw_column>;
friend void exception_detail::copy_boost_exception( exception *, exception const * );
#endif
mutable exception_detail::refcount_ptr<exception_detail::error_info_container> data_;
mutable char const * throw_function_;
mutable char const * throw_file_;
mutable int throw_line_;
mutable int throw_column_;
};
inline
@ -324,6 +361,42 @@ boost
x.throw_line_=y.v_;
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_line_ = b->throw_line_;
a->throw_function_ = b->throw_function_;
a->throw_column_ = b->throw_column_;
a->data_ = data;
}

View File

@ -106,6 +106,7 @@ public:
set_info( *this, throw_file( loc.file_name() ) );
set_info( *this, throw_line( loc.line() ) );
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
@ -256,8 +257,18 @@ template<class E> boost::source_location get_throw_location( E const & e )
#else
detail::throw_location const* p = dynamic_cast< detail::throw_location const* >( &e );
return p? p->location_: boost::source_location();
if( detail::throw_location const* pl = dynamic_cast< detail::throw_location const* >( &e ) )
{
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
}

View File

@ -49,6 +49,7 @@ 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_test4.cpp ;
run throw_with_location_nx_test.cpp : : : <exception-handling>off ;

View 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();
}