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 BOOST_EXCEPTION_1A590226753311DD9E4CCF6156D89593
7 #define BOOST_EXCEPTION_1A590226753311DD9E4CCF6156D89593
8 
9 #include <boost/config.hpp>
10 #include <boost/exception/exception.hpp>
11 #include <boost/exception/detail/error_info_impl.hpp>
12 #include <boost/exception/detail/type_info.hpp>
13 #include <boost/exception/detail/shared_ptr.hpp>
14 #include <boost/assert.hpp>
15 
16 #ifndef BOOST_EXCEPTION_ENABLE_WARNINGS
17 #if __GNUC__*100+__GNUC_MINOR__>301
18 #pragma GCC system_header
19 #endif
20 #ifdef __clang__
21 #pragma clang system_header
22 #endif
23 #ifdef _MSC_VER
24 #pragma warning(push,1)
25 #endif
26 #endif
27 
28 namespace
29 boost
30     {
31     namespace
32     exception_detail
33         {
34         template <class ErrorInfo>
35         struct
36         get_info
37             {
38             static
39             typename ErrorInfo::value_type *
getboost::exception_detail::get_info40             get( exception const & x )
41                 {
42                 if( exception_detail::error_info_container * c=x.data_.get() )
43                     if( shared_ptr<exception_detail::error_info_base> eib = c->get(BOOST_EXCEPTION_STATIC_TYPEID(ErrorInfo)) )
44                         {
45 #ifndef BOOST_NO_RTTI
46                         BOOST_ASSERT( 0!=dynamic_cast<ErrorInfo *>(eib.get()) );
47 #endif
48                         ErrorInfo * w = static_cast<ErrorInfo *>(eib.get());
49                         return &w->value();
50                         }
51                 return 0;
52                 }
53             };
54 
55         template <>
56         struct
57         get_info<throw_function>
58             {
59             static
60             char const * *
getboost::exception_detail::get_info61             get( exception const & x )
62                 {
63                 return x.throw_function_ ? &x.throw_function_ : 0;
64                 }
65             };
66 
67         template <>
68         struct
69         get_info<throw_file>
70             {
71             static
72             char const * *
getboost::exception_detail::get_info73             get( exception const & x )
74                 {
75                 return x.throw_file_ ? &x.throw_file_ : 0;
76                 }
77             };
78 
79         template <>
80         struct
81         get_info<throw_line>
82             {
83             static
84             int *
getboost::exception_detail::get_info85             get( exception const & x )
86                 {
87                 return x.throw_line_!=-1 ? &x.throw_line_ : 0;
88                 }
89             };
90 
91         template <class T,class R>
92         struct
93         get_error_info_return_type
94             {
95             typedef R * type;
96             };
97 
98         template <class T,class R>
99         struct
100         get_error_info_return_type<T const,R>
101             {
102             typedef R const * type;
103             };
104         }
105 
106 #ifdef BOOST_NO_RTTI
107     template <class ErrorInfo>
108     inline
109     typename ErrorInfo::value_type const *
get_error_info(boost::exception const & x)110     get_error_info( boost::exception const & x )
111         {
112         return exception_detail::get_info<ErrorInfo>::get(x);
113         }
114     template <class ErrorInfo>
115     inline
116     typename ErrorInfo::value_type *
get_error_info(boost::exception & x)117     get_error_info( boost::exception & x )
118         {
119         return exception_detail::get_info<ErrorInfo>::get(x);
120         }
121 #else
122     template <class ErrorInfo,class E>
123     inline
124     typename exception_detail::get_error_info_return_type<E,typename ErrorInfo::value_type>::type
get_error_info(E & some_exception)125     get_error_info( E & some_exception )
126         {
127         if( exception const * x = dynamic_cast<exception const *>(&some_exception) )
128             return exception_detail::get_info<ErrorInfo>::get(*x);
129         else
130             return 0;
131         }
132 #endif
133     }
134 
135 #if defined(_MSC_VER) && !defined(BOOST_EXCEPTION_ENABLE_WARNINGS)
136 #pragma warning(pop)
137 #endif
138 #endif
139