YSTest: exception.h 源文件

YSTest PreAlpha_b800_20170810 The YSLib Test Project

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

- 文件列表
- 文件成员

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