YSTest: exception.h 源文件

YSTest PreAlpha_b700_20160611 The YSLib Test Project

- 首页
- 相关页面
- 模块
- 命名空间
- 类
- 文件

- 文件列表
- 文件成员

libdefect/exception.h
浏览该文件的文档.
1 /*
2 © 2014-2015 FrankHB.
3
4 This file is part of the YSLib project, and may only be used,
5 modified, and distributed under the terms of the YSLib project
6 license, LICENSE.TXT. By continuing to use, modify, or distribute
7 this file you indicate that you have read the license and
8 understand and accept it fully.
9 */
10
28 #ifndef YB_INC_libdefect_exception_h_
29 #define YB_INC_libdefect_exception_h_ 1
30
31 #include <exception>
32
33 // NOTE: It is decided to only support G++ 4.6+. Thus the 'noexcept' and
34 // 'nullptr' can be used in C++11 mode then.
35 // NOTE: It seems there are no these 2 C++11 'get_*' routines before libstdc++
36 // 4.9. So here just adds them.
37 // NOTE: No exception propagation and nested exception supported by libstdc++
38 // when 'ATOMIC_INT_LOCK_FREE < 2'. This module is mainly for workaround it.
39 // See https://gcc.gnu.org/bugzilla/show_bug.cgi?id=58938.
40 // NOTE: It is initially intended to be binary-compatible with libstdc++ 4.8 +
41 // with '-std=c++11' enabled, except for deprecated std::copy_exception. (See
42 // LWG1170, also notes below for std::make_exception_ptr.)
43 // However, the implementation of nested exception in libstdc++ previous than
44 // 5.0 is not conforming to the formal standard, so 5.0 trunk code is adapted.
45 // See http://stackoverflow.com/questions/25324262/stdthrow-with-nested-expects-polymorphic-type-in-c11.
46 // See also https://gcc.gnu.org/bugzilla/show_bug.cgi?id=62154.
47 // NOTE: To avoid 'error: attributes are not allowed on a function-definition',
48 // '[[noreturn]]' or '__attribute__((__noreturn__))' can be used at front of,
49 // the function definition instead of '__attribute__((__noreturn__))' after a
50 // function declarator for. [[noreturn]] does not work on G++ earlier than 4.8.
51 // For compatibility reason this is not used.
52
53 #if defined(__GLIBCXX__) \
54 && (defined(__GXX_EXPERIMENTAL_CXX0X__) || __cplusplus >= 201103L) \
55 && __GNUC__ * 100 + __GNUC_MINOR__ < 409
56
57 # pragma GCC visibility push(default)
58
59 namespace std
60 {
61
62 terminate_handler
63 get_terminate() noexcept;
64
65 unexpected_handler
66 get_unexpected() noexcept;
67
68 } // namespacee std;
69
70 # pragma GCC visibility pop
71
72 #endif
73
74 #if defined(__GLIBCXX__) \
75 && (defined(__GXX_EXPERIMENTAL_CXX0X__) || __cplusplus >= 201103L) \
76 && ATOMIC_INT_LOCK_FREE < 2
77
78 # pragma GCC visibility push(default)
79
80 # include <bits/c++config.h>
81 # include <bits/exception_defines.h>
82
83 extern "C++"
84 {
85
86 namespace std
87 {
88
89 // NOTE: Following code is compatible with <bits/exception_ptr.h>.
90
91 class type_info;
92
93 namespace __exception_ptr
94 {
95
96 class exception_ptr;
97
98 } // namespace __exception_ptr;
99
100 using __exception_ptr::exception_ptr;
101
102 exception_ptr
103 current_exception() noexcept;
104
105 __attribute__((__noreturn__)) void
106 rethrow_exception(exception_ptr);
107
108 namespace __exception_ptr
109 {
110
111 class exception_ptr
112 {
113 void* _M_exception_object = {};
114
115 explicit
116 exception_ptr(void* __e) noexcept;
117
118 void
119 _M_addref() noexcept;
120
121 void
122 _M_release() noexcept;
123
124 void*
125 _M_get() const noexcept __attribute__((__pure__));
126
127 friend exception_ptr
128 std::current_exception() noexcept;
129
130 friend void
131 std::rethrow_exception(exception_ptr);
132
133 public:
134 exception_ptr() noexcept;
135 exception_ptr(const exception_ptr&) noexcept;
136 exception_ptr(nullptr_t) noexcept
137 : _M_exception_object()
138 {}
139 exception_ptr(exception_ptr&& __o) noexcept
140 : _M_exception_object(__o._M_exception_object)
141 {
142 __o._M_exception_object = {};
143 }
144 ~exception_ptr() noexcept;
145
146 # ifdef _GLIBCXX_EH_PTR_COMPAT
147 typedef void(exception_ptr::*__safe_bool)();
148
149 exception_ptr(__safe_bool) noexcept;
150 # endif
151
152 exception_ptr&
153 operator=(const exception_ptr&) noexcept;
154 exception_ptr&
155 operator=(exception_ptr&& __o) noexcept
156 {
157 exception_ptr(static_cast<exception_ptr&&>(__o)).swap(*this);
158 return *this;
159 }
160
161 void
162 swap(exception_ptr&) noexcept;
163
164 # ifdef _GLIBCXX_EH_PTR_COMPAT
165 // Retained for compatibility with CXXABI_1.3.
166 void
167 _M_safe_bool_dummy() noexcept __attribute__((__const__));
168
169 bool
170 operator!() const noexcept __attribute__((__pure__));
171
172 operator __safe_bool() const noexcept;
173 # endif
174
175 explicit
176 operator bool() const
177 {
178 return _M_exception_object;
179 }
180
181 friend bool
182 operator==(const exception_ptr&, const exception_ptr&)
183 noexcept __attribute__((__pure__));
184
185 const class std::type_info*
186 __cxa_exception_type() const noexcept
187 __attribute__((__pure__));
188 };
189
190 bool
191 operator==(const exception_ptr&, const exception_ptr&) noexcept
192 __attribute__((__pure__));
193
194 bool
195 operator!=(const exception_ptr&, const exception_ptr&) noexcept
196 __attribute__((__pure__));
197
198 inline void
199 swap(exception_ptr& __lhs, exception_ptr& __rhs)
200 {
201 __lhs.swap(__rhs);
202 }
203
204 } // namespace __exception_ptr;
205
206 // NOTE: See also https://gcc.gnu.org/bugzilla/show_bug.cgi?id=56905. Symbol for
207 // compatibility with experimental C++0x implementation is not supported.
208 template<typename _Ex>
209 exception_ptr
210 make_exception_ptr(_Ex __ex) noexcept
211 {
212 __try
213 {
214 # ifdef __EXCEPTIONS
215 throw __ex;
216 # endif
217 }
218 __catch(...)
219 {
220 return current_exception();
221 }
222 }
223
224 // NOTE: Following code is compatible with <bits/nested_exception.h>.
225
226 class nested_exception
227 {
228 exception_ptr _M_ptr;
229
230 public:
231 nested_exception() noexcept
232 : _M_ptr(current_exception())
233 {}
234 nested_exception(const nested_exception&) noexcept = default;
235 virtual
236 ~nested_exception() noexcept = default;
237
238 nested_exception&
239 operator=(const nested_exception&) noexcept = default;
240
241 __attribute__((__noreturn__)) void
242 rethrow_nested() const
243 {
244 if(_M_ptr)
245 rethrow_exception(_M_ptr);
246 std::terminate();
247 }
248
249 exception_ptr
250 nested_ptr() const noexcept
251 {
252 return _M_ptr;
253 }
254 };
255
256 template<typename _Except>
257 struct _Nested_exception : public _Except, public nested_exception
258 {
259 explicit
260 _Nested_exception(const _Except& __ex)
261 : _Except(__ex)
262 {}
263 explicit
264 _Nested_exception(_Except&& __ex)
265 : _Except(static_cast<_Except&&>(__ex))
266 {}
267 };
268
269 template<typename _Tp,
270 bool __with_nested = !__is_base_of(nested_exception, _Tp)>
271 struct _Throw_with_nested_impl
272 {
273 template<typename _Up>
274 __attribute__((__noreturn__)) static inline void
275 _S_throw(_Up&& __t)
276 {
277 throw _Nested_exception<_Tp>{static_cast<_Up&&>(__t)};
278 }
279 };
280
281 template<typename _Tp>
282 struct _Throw_with_nested_impl<_Tp, false>
283 {
284 template<typename _Up>
285 __attribute__((__noreturn__)) static inline void
286 _S_throw(_Up&& __t)
287 {
288 throw static_cast<_Up&&>(__t);
289 }
290 };
291
292
293 template<typename _Tp, bool = __is_class(_Tp)>
294 struct _Throw_with_nested_helper
295 : _Throw_with_nested_impl<_Tp>
296 {};
297
298 template<typename _Tp>
299 struct _Throw_with_nested_helper<_Tp, false>
300 : _Throw_with_nested_impl<_Tp, false>
301 {};
302
303 template<typename _Tp>
304 struct _Throw_with_nested_helper<_Tp&, false>
305 : _Throw_with_nested_helper<_Tp>
306 {};
307
308 template<typename _Tp>
309 struct _Throw_with_nested_helper<_Tp&&, false>
310 : _Throw_with_nested_helper<_Tp>
311 {};
312
313 template<typename _Tp>
314 __attribute__((__noreturn__)) inline void
315 throw_with_nested(_Tp&& __t)
316 {
317 _Throw_with_nested_helper<_Tp>::_S_throw(static_cast<_Tp&&>(__t));
318 }
319
320 template<typename _Tp, bool = __is_polymorphic(_Tp)>
321 struct _Rethrow_if_nested_impl
322 {
323 static void
324 _S_rethrow(const _Tp& __t)
325 {
326 if(const auto __tp = dynamic_cast<const nested_exception*>(&__t))
327 __tp->rethrow_nested();
328 }
329 };
330
331 template<typename _Tp>
332 struct _Rethrow_if_nested_impl<_Tp, false>
333 {
334 static void
335 _S_rethrow(const _Tp&)
336 {}
337 };
338
339 template<typename _Ex>
340 inline void
341 rethrow_if_nested(const _Ex& __ex)
342 {
343 _Rethrow_if_nested_impl<_Ex>::_S_rethrow(__ex);
344 }
345
346 } // namespace std;
347
348 } // extern "C++";
349
350 # pragma GCC visibility pop
351
352 #endif
353
354 #endif
355
ystdex::swap
void swap(container_adaptor< _tSeqCon > &x, container_adaptor< _tSeqCon > &y)
Definition: container.hpp:179
std
Definition: memory.hpp:1100
platform_ex::operator==
PDefH(void, EnsureNonNull, void *p) ImplExpr(p?void() boo operator==)(const COMPtr< _iCOM1 > &x, const COMPtr< _iCOM2 > &y) ynothrow
检查指针值，若为空则抛出 COMException 。
Definition: COM.h:330
platform::terminate
YB_NORETURN YF_API void terminate() ynothrow
异常终止函数。
Definition: YCommon.cpp:42
platform::bool
std::FILE *fp bool
Definition: FileIO.h:1187