nested_exception.h
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 <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 virtual ~nested_exception() = default;
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 template<typename _Except>
00078 struct _Nested_exception : public _Except, public nested_exception
00079 {
00080 explicit _Nested_exception(_Except&& __ex)
00081 : _Except(static_cast<_Except&&>(__ex))
00082 { }
00083 };
00084
00085 template<typename _Ex>
00086 struct __get_nested_helper
00087 {
00088 static const nested_exception*
00089 _S_get(const _Ex& __ex)
00090 { return dynamic_cast<const nested_exception*>(&__ex); }
00091 };
00092
00093 template<typename _Ex>
00094 struct __get_nested_helper<_Ex*>
00095 {
00096 static const nested_exception*
00097 _S_get(const _Ex* __ex)
00098 { return dynamic_cast<const nested_exception*>(__ex); }
00099 };
00100
00101 template<typename _Ex>
00102 inline const nested_exception*
00103 __get_nested_exception(const _Ex& __ex)
00104 { return __get_nested_helper<_Ex>::_S_get(__ex); }
00105
00106 template<typename _Ex>
00107 void
00108 __throw_with_nested(_Ex&&, const nested_exception* = 0)
00109 __attribute__ ((__noreturn__));
00110
00111 template<typename _Ex>
00112 void
00113 __throw_with_nested(_Ex&&, ...) __attribute__ ((__noreturn__));
00114
00115
00116
00117
00118 template<typename _Ex>
00119 inline void
00120 __throw_with_nested(_Ex&& __ex, const nested_exception* = 0)
00121 { throw __ex; }
00122
00123 template<typename _Ex>
00124 inline void
00125 __throw_with_nested(_Ex&& __ex, ...)
00126 { throw _Nested_exception<_Ex>(static_cast<_Ex&&>(__ex)); }
00127
00128 template<typename _Ex>
00129 void
00130 throw_with_nested(_Ex __ex) __attribute__ ((__noreturn__));
00131
00132
00133
00134 template<typename _Ex>
00135 inline void
00136 throw_with_nested(_Ex __ex)
00137 {
00138 if (__get_nested_exception(__ex))
00139 throw __ex;
00140 __throw_with_nested(static_cast<_Ex&&>(__ex), &__ex);
00141 }
00142
00143
00144 template<typename _Ex>
00145 inline void
00146 rethrow_if_nested(const _Ex& __ex)
00147 {
00148 if (const nested_exception* __nested = __get_nested_exception(__ex))
00149 __nested->rethrow_nested();
00150 }
00151
00152
00153 inline void
00154 rethrow_if_nested(const nested_exception& __ex)
00155 { __ex.rethrow_nested(); }
00156
00157
00158 }
00159
00160 }
00161
00162 #endif // __GXX_EXPERIMENTAL_CXX0X__
00163
00164 #pragma GCC visibility pop
00165
00166 #endif // _GLIBCXX_NESTED_EXCEPTION_H