| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213 | //Copyright (c) 2006-2010 Emil Dotchevski and Reverge Studios, Inc.//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)#ifndef BOOST_EXCEPTION_0552D49838DD11DD90146B8956D89593#define BOOST_EXCEPTION_0552D49838DD11DD90146B8956D89593#include <boost/config.hpp>#include <boost/exception/get_error_info.hpp>#include <boost/exception/info.hpp>#include <boost/utility/enable_if.hpp>#ifndef BOOST_NO_RTTI#include <boost/core/demangle.hpp>#endif#include <exception>#include <sstream>#include <string>#ifndef BOOST_NO_EXCEPTIONS#include <boost/exception/current_exception_cast.hpp>#endif#ifndef BOOST_EXCEPTION_ENABLE_WARNINGS#if __GNUC__*100+__GNUC_MINOR__>301#pragma GCC system_header#endif#ifdef __clang__#pragma clang system_header#endif#ifdef _MSC_VER#pragma warning(push,1)#endif#endif#ifndef BOOST_NO_EXCEPTIONSnamespaceboost    {    namespace    exception_detail        {        std::string diagnostic_information_impl( boost::exception const *, std::exception const *, bool, bool );        }    inline    std::string    current_exception_diagnostic_information( bool verbose=true)        {        boost::exception const * be=current_exception_cast<boost::exception const>();        std::exception const * se=current_exception_cast<std::exception const>();        if( be || se )            return exception_detail::diagnostic_information_impl(be,se,true,verbose);#if defined(__GLIBCXX__) && __cplusplus >= 201103L && !defined(BOOST_NO_RTTI)        else if (auto* p=std::current_exception().__cxa_exception_type())            return "Dynamic exception type: "+boost::core::demangle(p->name());#endif        else            return "No diagnostic information available.";        }    }#endifnamespaceboost    {    namespace    exception_detail        {        inline        exception const *        get_boost_exception( exception const * e )            {            return e;            }        inline        exception const *        get_boost_exception( ... )            {            return 0;            }        inline        std::exception const *        get_std_exception( std::exception const * e )            {            return e;            }        inline        std::exception const *        get_std_exception( ... )            {            return 0;            }        inline        char const *        get_diagnostic_information( exception const & x, char const * header )            {#ifndef BOOST_NO_EXCEPTIONS            try                {#endif                error_info_container * c=x.data_.get();                if( !c )                    x.data_.adopt(c=new exception_detail::error_info_container_impl);                char const * di=c->diagnostic_information(header);                BOOST_ASSERT(di!=0);                return di;#ifndef BOOST_NO_EXCEPTIONS                }            catch(...)                {                return 0;                }#endif            }        inline        std::string        diagnostic_information_impl( boost::exception const * be, std::exception const * se, bool with_what, bool verbose )            {            if( !be && !se )                return "Unknown exception.";#ifndef BOOST_NO_RTTI            if( !be )                be=dynamic_cast<boost::exception const *>(se);            if( !se )                se=dynamic_cast<std::exception const *>(be);#endif            char const * wh=0;            if( with_what && se )                {                wh=se->what();                if( be && exception_detail::get_diagnostic_information(*be,0)==wh )                    return wh;                }            std::ostringstream tmp;            if( be && verbose )                {                char const * const * f=get_error_info<throw_file>(*be);                int const * l=get_error_info<throw_line>(*be);                char const * const * fn=get_error_info<throw_function>(*be);                if( !f && !l && !fn )                    tmp << "Throw location unknown (consider using BOOST_THROW_EXCEPTION)\n";                else                    {                    if( f )                        {                        tmp << *f;                        if( int const * l=get_error_info<throw_line>(*be) )                            tmp << '(' << *l << "): ";                        }                    tmp << "Throw in function ";                    if( char const * const * fn=get_error_info<throw_function>(*be) )                        tmp << *fn;                    else                        tmp << "(unknown)";                    tmp << '\n';                    }                }#ifndef BOOST_NO_RTTI            if ( verbose )                tmp << std::string("Dynamic exception type: ") <<                    core::demangle((be?(BOOST_EXCEPTION_DYNAMIC_TYPEID(*be)):(BOOST_EXCEPTION_DYNAMIC_TYPEID(*se))).type_->name()) << '\n';#endif            if( with_what && se && verbose )                tmp << "std::exception::what: " << (wh ? wh : "(null)") << '\n';            if( be )                if( char const * s=exception_detail::get_diagnostic_information(*be,tmp.str().c_str()) )                    if( *s )                        return std::string(s);            return tmp.str();            }        }    template <class T>    std::string    diagnostic_information( T const & e, bool verbose=true )        {        return exception_detail::diagnostic_information_impl(exception_detail::get_boost_exception(&e),exception_detail::get_std_exception(&e),true,verbose);        }    inline    char const *    diagnostic_information_what( exception const & e, bool verbose=true ) BOOST_NOEXCEPT_OR_NOTHROW        {        char const * w=0;#ifndef BOOST_NO_EXCEPTIONS        try            {#endif            (void) exception_detail::diagnostic_information_impl(&e,0,false,verbose);            if( char const * di=exception_detail::get_diagnostic_information(e,0) )                return di;            else                return "Failed to produce boost::diagnostic_information_what()";#ifndef BOOST_NO_EXCEPTIONS            }        catch(        ... )            {            }#endif        return w;        }    }#if defined(_MSC_VER) && !defined(BOOST_EXCEPTION_ENABLE_WARNINGS)#pragma warning(pop)#endif#endif
 |