Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030 #ifndef _GLIBCXX_NESTED_EXCEPTION_H
00031 #define _GLIBCXX_NESTED_EXCEPTION_H 1
00032
00033 #pragma GCC visibility push(default)
00034
00035 #ifndef __GXX_EXPERIMENTAL_CXX0X__
00036 # include <bits/c++0x_warning.h>
00037 #else
00038
00039 #include <bits/c++config.h>
00040
00041 #if !defined(_GLIBCXX_ATOMIC_BUILTINS_4)
00042 # error This platform does not support exception propagation.
00043 #endif
00044
00045 extern "C++" {
00046
00047 namespace std
00048 {
00049
00050
00051
00052
00053
00054
00055 class nested_exception
00056 {
00057 exception_ptr _M_ptr;
00058
00059 public:
00060 nested_exception() throw() : _M_ptr(current_exception()) { }
00061
00062 nested_exception(const nested_exception&) = default;
00063
00064 nested_exception& operator=(const nested_exception&) = default;
00065
00066 inline virtual ~nested_exception();
00067
00068 void
00069 rethrow_nested() const __attribute__ ((__noreturn__))
00070 { rethrow_exception(_M_ptr); }
00071
00072 exception_ptr
00073 nested_ptr() const
00074 { return _M_ptr; }
00075 };
00076
00077 inline nested_exception::~nested_exception() = default;
00078
00079 template<typename _Except>
00080 struct _Nested_exception : public _Except, public nested_exception
00081 {
00082 explicit _Nested_exception(_Except&& __ex)
00083 : _Except(static_cast<_Except&&>(__ex))
00084 { }
00085 };
00086
00087 template<typename _Ex>
00088 struct __get_nested_helper
00089 {
00090 static const nested_exception*
00091 _S_get(const _Ex& __ex)
00092 { return dynamic_cast<const nested_exception*>(&__ex); }
00093 };
00094
00095 template<typename _Ex>
00096 struct __get_nested_helper<_Ex*>
00097 {
00098 static const nested_exception*
00099 _S_get(const _Ex* __ex)
00100 { return dynamic_cast<const nested_exception*>(__ex); }
00101 };
00102
00103 template<typename _Ex>
00104 inline const nested_exception*
00105 __get_nested_exception(const _Ex& __ex)
00106 { return __get_nested_helper<_Ex>::_S_get(__ex); }
00107
00108 template<typename _Ex>
00109 void
00110 __throw_with_nested(_Ex&&, const nested_exception* = 0)
00111 __attribute__ ((__noreturn__));
00112
00113 template<typename _Ex>
00114 void
00115 __throw_with_nested(_Ex&&, ...) __attribute__ ((__noreturn__));
00116
00117
00118
00119
00120 template<typename _Ex>
00121 inline void
00122 __throw_with_nested(_Ex&& __ex, const nested_exception* = 0)
00123 { throw __ex; }
00124
00125 template<typename _Ex>
00126 inline void
00127 __throw_with_nested(_Ex&& __ex, ...)
00128 { throw _Nested_exception<_Ex>(static_cast<_Ex&&>(__ex)); }
00129
00130 template<typename _Ex>
00131 void
00132 throw_with_nested(_Ex __ex) __attribute__ ((__noreturn__));
00133
00134
00135
00136 template<typename _Ex>
00137 inline void
00138 throw_with_nested(_Ex __ex)
00139 {
00140 if (__get_nested_exception(__ex))
00141 throw __ex;
00142 __throw_with_nested(static_cast<_Ex&&>(__ex), &__ex);
00143 }
00144
00145
00146 template<typename _Ex>
00147 inline void
00148 rethrow_if_nested(const _Ex& __ex)
00149 {
00150 if (const nested_exception* __nested = __get_nested_exception(__ex))
00151 __nested->rethrow_nested();
00152 }
00153
00154
00155 inline void
00156 rethrow_if_nested(const nested_exception& __ex)
00157 { __ex.rethrow_nested(); }
00158
00159
00160 }
00161
00162 }
00163
00164 #endif // __GXX_EXPERIMENTAL_CXX0X__
00165
00166 #pragma GCC visibility pop
00167
00168 #endif // _GLIBCXX_NESTED_EXCEPTION_H