LCOV - code coverage report
Current view: top level - usr/include/boost/exception/detail - exception_ptr.hpp (source / functions) Hit Total Coverage
Test: ROSE Lines: 0 29 0.0 %
Date: 2022-12-08 13:48:47 Functions: 0 37 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : //Copyright (c) 2006-2009 Emil Dotchevski and Reverge Studios, Inc.
       2             : 
       3             : //Distributed under the Boost Software License, Version 1.0. (See accompanying
       4             : //file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
       5             : 
       6             : #ifndef UUID_618474C2DE1511DEB74A388C56D89593
       7             : #define UUID_618474C2DE1511DEB74A388C56D89593
       8             : 
       9             : #include <boost/config.hpp>
      10             : #ifdef BOOST_NO_EXCEPTIONS
      11             : #error This header requires exception handling to be enabled.
      12             : #endif
      13             : #include <boost/exception/exception.hpp>
      14             : #include <boost/exception/info.hpp>
      15             : #include <boost/exception/diagnostic_information.hpp>
      16             : #include <boost/exception/detail/clone_current_exception.hpp>
      17             : #include <boost/exception/detail/type_info.hpp>
      18             : #ifndef BOOST_NO_RTTI
      19             : #include <boost/core/demangle.hpp>
      20             : #endif
      21             : #include <boost/shared_ptr.hpp>
      22             : #include <stdexcept>
      23             : #include <new>
      24             : #include <ios>
      25             : #include <stdlib.h>
      26             : 
      27             : #if (__GNUC__*100+__GNUC_MINOR__>301) && !defined(BOOST_EXCEPTION_ENABLE_WARNINGS)
      28             : #pragma GCC system_header
      29             : #endif
      30             : #if defined(_MSC_VER) && !defined(BOOST_EXCEPTION_ENABLE_WARNINGS)
      31             : #pragma warning(push,1)
      32             : #endif
      33             : 
      34             : namespace
      35             : boost
      36             :     {
      37             :     class exception_ptr;
      38             :     BOOST_NORETURN void rethrow_exception( exception_ptr const & );
      39             :     exception_ptr current_exception();
      40             : 
      41             :     class
      42           0 :     exception_ptr
      43             :         {
      44             :         typedef boost::shared_ptr<exception_detail::clone_base const> impl;
      45             :         impl ptr_;
      46             :         friend void rethrow_exception( exception_ptr const & );
      47             :         typedef exception_detail::clone_base const * (impl::*unspecified_bool_type)() const;
      48             :         public:
      49             :         exception_ptr()
      50             :             {
      51             :             }
      52             :         explicit
      53           0 :         exception_ptr( impl const & ptr ):
      54           0 :             ptr_(ptr)
      55             :             {
      56             :             }
      57             :         bool
      58             :         operator==( exception_ptr const & other ) const
      59             :             {
      60             :             return ptr_==other.ptr_;
      61             :             }
      62             :         bool
      63             :         operator!=( exception_ptr const & other ) const
      64             :             {
      65             :             return ptr_!=other.ptr_;
      66             :             }
      67           0 :         operator unspecified_bool_type() const
      68             :             {
      69           0 :             return ptr_?&impl::get:0;
      70             :             }
      71             :         };
      72             : 
      73             :     template <class T>
      74             :     inline
      75             :     exception_ptr
      76             :     copy_exception( T const & e )
      77             :         {
      78             :         try
      79             :             {
      80             :             throw enable_current_exception(e);
      81             :             }
      82             :         catch(
      83             :         ... )
      84             :             {
      85             :             return current_exception();
      86             :             }
      87             :         }
      88             : 
      89             : #ifndef BOOST_NO_RTTI
      90             :     typedef error_info<struct tag_original_exception_type,std::type_info const *> original_exception_type;
      91             : 
      92             :     inline
      93             :     std::string
      94           0 :     to_string( original_exception_type const & x )
      95             :         {
      96           0 :         return core::demangle(x.value()->name());
      97             :         }
      98             : #endif
      99             : 
     100             :     namespace
     101             :     exception_detail
     102             :         {
     103             :         struct
     104           0 :         bad_alloc_:
     105             :             boost::exception,
     106             :             std::bad_alloc
     107             :                 {
     108           0 :                 ~bad_alloc_() BOOST_NOEXCEPT_OR_NOTHROW { }
     109             :                 };
     110             : 
     111             :         struct
     112           0 :         bad_exception_:
     113             :             boost::exception,
     114             :             std::bad_exception
     115             :                 {
     116           0 :                 ~bad_exception_() BOOST_NOEXCEPT_OR_NOTHROW { }
     117             :                 };
     118             : 
     119             :         template <class Exception>
     120             :         exception_ptr
     121           0 :         get_static_exception_object()
     122             :             {
     123           0 :             Exception ba;
     124           0 :             exception_detail::clone_impl<Exception> c(ba);
     125             : #ifndef BOOST_EXCEPTION_DISABLE
     126           0 :             c <<
     127           0 :                 throw_function(BOOST_CURRENT_FUNCTION) <<
     128           0 :                 throw_file(__FILE__) <<
     129             :                 throw_line(__LINE__);
     130             : #endif
     131           0 :             static exception_ptr ep(shared_ptr<exception_detail::clone_base const>(new exception_detail::clone_impl<Exception>(c)));
     132           0 :             return ep;
     133             :             }
     134             : 
     135             :         template <class Exception>
     136             :         struct
     137             :         exception_ptr_static_exception_object
     138             :             {
     139             :             static exception_ptr const e;
     140             :             };
     141             : 
     142             :         template <class Exception>
     143             :         exception_ptr const
     144             :         exception_ptr_static_exception_object<Exception>::
     145             :         e = get_static_exception_object<Exception>();
     146             :         }
     147             : 
     148             : #if defined(__GNUC__)
     149             : # if (__GNUC__ == 4 && __GNUC_MINOR__ >= 1) || (__GNUC__ > 4)
     150             : #  pragma GCC visibility push (default)
     151             : # endif
     152             : #endif
     153             :     class
     154           0 :     unknown_exception:
     155             :         public boost::exception,
     156             :         public std::exception
     157             :         {
     158             :         public:
     159             : 
     160             :         unknown_exception()
     161             :             {
     162             :             }
     163             : 
     164             :         explicit
     165             :         unknown_exception( std::exception const & e )
     166             :             {
     167             :             add_original_type(e);
     168             :             }
     169             : 
     170             :         explicit
     171             :         unknown_exception( boost::exception const & e ):
     172             :             boost::exception(e)
     173             :             {
     174             :             add_original_type(e);
     175             :             }
     176             : 
     177           0 :         ~unknown_exception() BOOST_NOEXCEPT_OR_NOTHROW
     178           0 :             {
     179           0 :             }
     180             : 
     181             :         private:
     182             : 
     183             :         template <class E>
     184             :         void
     185             :         add_original_type( E const & e )
     186             :             {
     187             : #ifndef BOOST_NO_RTTI
     188             :             (*this) << original_exception_type(&typeid(e));
     189             : #endif
     190             :             }
     191             :         };
     192             : #if defined(__GNUC__)
     193             : # if (__GNUC__ == 4 && __GNUC_MINOR__ >= 1) || (__GNUC__ > 4)
     194             : #  pragma GCC visibility pop
     195             : # endif
     196             : #endif
     197             : 
     198             :     namespace
     199             :     exception_detail
     200             :         {
     201             :         template <class T>
     202             :         class
     203             :         current_exception_std_exception_wrapper:
     204             :             public T,
     205             :             public boost::exception
     206             :             {
     207             :             public:
     208             : 
     209             :             explicit
     210             :             current_exception_std_exception_wrapper( T const & e1 ):
     211             :                 T(e1)
     212             :                 {
     213             :                 add_original_type(e1);
     214             :                 }
     215             : 
     216             :             current_exception_std_exception_wrapper( T const & e1, boost::exception const & e2 ):
     217             :                 T(e1),
     218             :                 boost::exception(e2)
     219             :                 {
     220             :                 add_original_type(e1);
     221             :                 }
     222             : 
     223           0 :             ~current_exception_std_exception_wrapper() BOOST_NOEXCEPT_OR_NOTHROW
     224             :                 {
     225           0 :                 }
     226             : 
     227             :             private:
     228             : 
     229             :             template <class E>
     230             :             void
     231             :             add_original_type( E const & e )
     232             :                 {
     233             : #ifndef BOOST_NO_RTTI
     234             :                 (*this) << original_exception_type(&typeid(e));
     235             : #endif
     236             :                 }
     237             :             };
     238             : 
     239             : #ifdef BOOST_NO_RTTI
     240             :         template <class T>
     241             :         boost::exception const *
     242             :         get_boost_exception( T const * )
     243             :             {
     244             :             try
     245             :                 {
     246             :                 throw;
     247             :                 }
     248             :             catch(
     249             :             boost::exception & x )
     250             :                 {
     251             :                 return &x;
     252             :                 }
     253             :             catch(...)
     254             :                 {
     255             :                 return 0;
     256             :                 }
     257             :             }
     258             : #else
     259             :         template <class T>
     260             :         boost::exception const *
     261             :         get_boost_exception( T const * x )
     262             :             {
     263             :             return dynamic_cast<boost::exception const *>(x);
     264             :             }
     265             : #endif
     266             : 
     267             :         template <class T>
     268             :         inline
     269             :         exception_ptr
     270             :         current_exception_std_exception( T const & e1 )
     271             :             {
     272             :             if( boost::exception const * e2 = get_boost_exception(&e1) )
     273             :                 return boost::copy_exception(current_exception_std_exception_wrapper<T>(e1,*e2));
     274             :             else
     275             :                 return boost::copy_exception(current_exception_std_exception_wrapper<T>(e1));
     276             :             }
     277             : 
     278             :         inline
     279             :         exception_ptr
     280             :         current_exception_unknown_exception()
     281             :             {
     282             :             return boost::copy_exception(unknown_exception());
     283             :             }
     284             : 
     285             :         inline
     286             :         exception_ptr
     287             :         current_exception_unknown_boost_exception( boost::exception const & e )
     288             :             {
     289             :             return boost::copy_exception(unknown_exception(e));
     290             :             }
     291             : 
     292             :         inline
     293             :         exception_ptr
     294             :         current_exception_unknown_std_exception( std::exception const & e )
     295             :             {
     296             :             if( boost::exception const * be = get_boost_exception(&e) )
     297             :                 return current_exception_unknown_boost_exception(*be);
     298             :             else
     299             :                 return boost::copy_exception(unknown_exception(e));
     300             :             }
     301             : 
     302             :         inline
     303             :         exception_ptr
     304             :         current_exception_impl()
     305             :             {
     306             :             exception_detail::clone_base const * e=0;
     307             :             switch(
     308             :             exception_detail::clone_current_exception(e) )
     309             :                 {
     310             :                 case exception_detail::clone_current_exception_result::
     311             :                 success:
     312             :                     {
     313             :                     BOOST_ASSERT(e!=0);
     314             :                     return exception_ptr(shared_ptr<exception_detail::clone_base const>(e));
     315             :                     }
     316             :                 case exception_detail::clone_current_exception_result::
     317             :                 bad_alloc:
     318             :                     {
     319             :                     BOOST_ASSERT(!e);
     320             :                     return exception_detail::exception_ptr_static_exception_object<bad_alloc_>::e;
     321             :                     }
     322             :                 case exception_detail::clone_current_exception_result::
     323             :                 bad_exception:
     324             :                     {
     325             :                     BOOST_ASSERT(!e);
     326             :                     return exception_detail::exception_ptr_static_exception_object<bad_exception_>::e;
     327             :                     }
     328             :                 default:
     329             :                     BOOST_ASSERT(0);
     330             :                 case exception_detail::clone_current_exception_result::
     331             :                 not_supported:
     332             :                     {
     333             :                     BOOST_ASSERT(!e);
     334             :                     try
     335             :                         {
     336             :                         throw;
     337             :                         }
     338             :                     catch(
     339             :                     exception_detail::clone_base & e )
     340             :                         {
     341             :                         return exception_ptr(shared_ptr<exception_detail::clone_base const>(e.clone()));
     342             :                         }
     343             :                     catch(
     344             :                     std::domain_error & e )
     345             :                         {
     346             :                         return exception_detail::current_exception_std_exception(e);
     347             :                         }
     348             :                     catch(
     349             :                     std::invalid_argument & e )
     350             :                         {
     351             :                         return exception_detail::current_exception_std_exception(e);
     352             :                         }
     353             :                     catch(
     354             :                     std::length_error & e )
     355             :                         {
     356             :                         return exception_detail::current_exception_std_exception(e);
     357             :                         }
     358             :                     catch(
     359             :                     std::out_of_range & e )
     360             :                         {
     361             :                         return exception_detail::current_exception_std_exception(e);
     362             :                         }
     363             :                     catch(
     364             :                     std::logic_error & e )
     365             :                         {
     366             :                         return exception_detail::current_exception_std_exception(e);
     367             :                         }
     368             :                     catch(
     369             :                     std::range_error & e )
     370             :                         {
     371             :                         return exception_detail::current_exception_std_exception(e);
     372             :                         }
     373             :                     catch(
     374             :                     std::overflow_error & e )
     375             :                         {
     376             :                         return exception_detail::current_exception_std_exception(e);
     377             :                         }
     378             :                     catch(
     379             :                     std::underflow_error & e )
     380             :                         {
     381             :                         return exception_detail::current_exception_std_exception(e);
     382             :                         }
     383             :                     catch(
     384             :                     std::ios_base::failure & e )
     385             :                         {
     386             :                         return exception_detail::current_exception_std_exception(e);
     387             :                         }
     388             :                     catch(
     389             :                     std::runtime_error & e )
     390             :                         {
     391             :                         return exception_detail::current_exception_std_exception(e);
     392             :                         }
     393             :                     catch(
     394             :                     std::bad_alloc & e )
     395             :                         {
     396             :                         return exception_detail::current_exception_std_exception(e);
     397             :                         }
     398             :         #ifndef BOOST_NO_TYPEID
     399             :                     catch(
     400             :                     std::bad_cast & e )
     401             :                         {
     402             :                         return exception_detail::current_exception_std_exception(e);
     403             :                         }
     404             :                     catch(
     405             :                     std::bad_typeid & e )
     406             :                         {
     407             :                         return exception_detail::current_exception_std_exception(e);
     408             :                         }
     409             :         #endif
     410             :                     catch(
     411             :                     std::bad_exception & e )
     412             :                         {
     413             :                         return exception_detail::current_exception_std_exception(e);
     414             :                         }
     415             :                     catch(
     416             :                     std::exception & e )
     417             :                         {
     418             :                         return exception_detail::current_exception_unknown_std_exception(e);
     419             :                         }
     420             :                     catch(
     421             :                     boost::exception & e )
     422             :                         {
     423             :                         return exception_detail::current_exception_unknown_boost_exception(e);
     424             :                         }
     425             :                     catch(
     426             :                     ... )
     427             :                         {
     428             :                         return exception_detail::current_exception_unknown_exception();
     429             :                         }
     430             :                     }
     431             :                 }
     432             :             }
     433             :         }
     434             : 
     435             :     inline
     436             :     exception_ptr
     437             :     current_exception()
     438             :         {
     439             :         exception_ptr ret;
     440             :         try
     441             :             {
     442             :             ret=exception_detail::current_exception_impl();
     443             :             }
     444             :         catch(
     445             :         std::bad_alloc & )
     446             :             {
     447             :             ret=exception_detail::exception_ptr_static_exception_object<exception_detail::bad_alloc_>::e;
     448             :             }
     449             :         catch(
     450             :         ... )
     451             :             {
     452             :             ret=exception_detail::exception_ptr_static_exception_object<exception_detail::bad_exception_>::e;
     453             :             }
     454             :         BOOST_ASSERT(ret);
     455             :         return ret;
     456             :         }
     457             : 
     458             :     BOOST_NORETURN
     459             :     inline
     460             :     void
     461           0 :     rethrow_exception( exception_ptr const & p )
     462             :         {
     463           0 :         BOOST_ASSERT(p);
     464           0 :         p.ptr_->rethrow();
     465           0 :         BOOST_ASSERT(0);
     466             :         #if defined(UNDER_CE)
     467             :             // some CE platforms don't define ::abort()
     468             :             exit(-1);
     469             :         #else
     470             :             abort();
     471             :         #endif
     472             :         }
     473             : 
     474             :     inline
     475             :     std::string
     476             :     diagnostic_information( exception_ptr const & p, bool verbose=true )
     477             :         {
     478             :         if( p )
     479             :             try
     480             :                 {
     481             :                 rethrow_exception(p);
     482             :                 }
     483             :             catch(
     484             :             ... )
     485             :                 {
     486             :                 return current_exception_diagnostic_information(verbose);
     487             :                 }
     488             :         return "<empty>";
     489             :         }
     490             : 
     491             :     inline
     492             :     std::string
     493             :     to_string( exception_ptr const & p )
     494             :         {
     495             :         std::string s='\n'+diagnostic_information(p);
     496             :         std::string padding("  ");
     497             :         std::string r;
     498             :         bool f=false;
     499             :         for( std::string::const_iterator i=s.begin(),e=s.end(); i!=e; ++i )
     500             :             {
     501             :             if( f )
     502             :                 r+=padding;
     503             :             char c=*i;
     504             :             r+=c;
     505             :             f=(c=='\n');
     506             :             }
     507             :         return r;
     508             :         }
     509             :     }
     510             : 
     511             : #if defined(_MSC_VER) && !defined(BOOST_EXCEPTION_ENABLE_WARNINGS)
     512             : #pragma warning(pop)
     513             : #endif
     514             : #endif

Generated by: LCOV version 1.14