YSTest: exception.h 源文件

YSTest PreAlpha_b900_20201012 The YSLib Test Project

libdefect/exception.h
浏览该文件的文档.
1 /*
2 © 2014-2015, 2017-2019 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 // NOTE: This implementation may need libatomic with G++ on platform without
54 // native atomic builtins support (e.g. ARMv5).
55
56 // XXX: What is the exact Clang++ version?
57 #if defined(__GLIBCXX__) \
58 && (defined(__GXX_EXPERIMENTAL_CXX0X__) || __cplusplus >= 201103L) \
59 && __GNUC__ * 100 + __GNUC_MINOR__ < 409 && !defined(__clang__)
60
61 # pragma GCC visibility push(default)
62
63 namespace std
64 {
65
66 terminate_handler
67 get_terminate() noexcept;
68
69 unexpected_handler
70 get_unexpected() noexcept;
71
72 } // namespacee std;
73
74 # pragma GCC visibility pop
75
76 #endif
77
78 // NOTE: See https://gcc.gnu.org/bugzilla/show_bug.cgi?id=58938.
79 // XXX: The version is significant since Clang++ does not following the
80 // version number of GCC reliably.
81 #if defined(__GLIBCXX__) && __GLIBCXX__ < 20170718 \
82 && (defined(__GXX_EXPERIMENTAL_CXX0X__) || __cplusplus >= 201103L) \
83 && (ATOMIC_INT_LOCK_FREE < 2 && __GNUC__ < 7)
84
85 # pragma GCC visibility push(default)
86
87 # include <bits/c++config.h>
88 # include <bits/exception_defines.h>
89
90 extern "C++"
91 {
92
93 namespace std
94 {
95
96 // NOTE: The following code is compatible with <bits/exception_ptr.h>.
97
98 class type_info;
99
100 namespace __exception_ptr
101 {
102
103 class exception_ptr;
104
105 } // namespace __exception_ptr;
106
107 using __exception_ptr::exception_ptr;
108
109 exception_ptr
110 current_exception() noexcept;
111
112 __attribute__((__noreturn__)) void
113 rethrow_exception(exception_ptr);
114
115 namespace __exception_ptr
116 {
117
118 class exception_ptr
119 {
120 void* _M_exception_object = {};
121
122 explicit
123 exception_ptr(void*) noexcept;
124
125 void
126 _M_addref() noexcept;
127
128 void
129 _M_release() noexcept;
130
131 void*
132 _M_get() const noexcept __attribute__((__pure__));
133
134 friend exception_ptr
135 std::current_exception() noexcept;
136
137 friend void
138 std::rethrow_exception(exception_ptr);
139
140 public:
141 exception_ptr() noexcept;
142 exception_ptr(const exception_ptr&) noexcept;
143 exception_ptr(nullptr_t) noexcept
144 : _M_exception_object()
145 {}
146 exception_ptr(exception_ptr&& __o) noexcept
147 : _M_exception_object(__o._M_exception_object)
148 {
149 __o._M_exception_object = {};
150 }
151 ~exception_ptr() noexcept;
152
153 # ifdef _GLIBCXX_EH_PTR_COMPAT
154 typedef void(exception_ptr::*__safe_bool)();
155
156 exception_ptr(__safe_bool) noexcept;
157 # endif
158
159 exception_ptr&
160 operator=(const exception_ptr&) noexcept;
161 exception_ptr&
162 operator=(exception_ptr&& __o) noexcept
163 {
164 exception_ptr(static_cast<exception_ptr&&>(__o)).swap(*this);
165 return *this;
166 }
167
168 void
169 swap(exception_ptr&) noexcept;
170
171 # ifdef _GLIBCXX_EH_PTR_COMPAT
172 // Retained for compatibility with CXXABI_1.3.
173 void
174 _M_safe_bool_dummy() noexcept __attribute__((__const__));
175
176 bool
177 operator!() const noexcept __attribute__((__pure__));
178
179 operator __safe_bool() const noexcept;
180 # endif
181
182 explicit
183 operator bool() const
184 {
185 return _M_exception_object;
186 }
187
188 friend bool
189 operator==(const exception_ptr&, const exception_ptr&)
190 noexcept __attribute__((__pure__));
191
192 const class std::type_info*
193 __cxa_exception_type() const noexcept
194 __attribute__((__pure__));
195 };
196
197 bool
198 operator==(const exception_ptr&, const exception_ptr&) noexcept
199 __attribute__((__pure__));
200
201 bool
202 operator!=(const exception_ptr&, const exception_ptr&) noexcept
203 __attribute__((__pure__));
204
205 inline void
206 swap(exception_ptr& __lhs, exception_ptr& __rhs)
207 {
208 __lhs.swap(__rhs);
209 }
210
211 } // namespace __exception_ptr;
212
213 // NOTE: See also https://gcc.gnu.org/bugzilla/show_bug.cgi?id=56905. Symbol for
214 // compatibility with experimental C++0x implementation is not supported.
215 template<typename _Ex>
216 exception_ptr
217 make_exception_ptr(_Ex __ex) noexcept
218 {
219 __try
220 {
221 # ifdef __EXCEPTIONS
222 throw __ex;
223 # endif
224 }
225 __catch(...)
226 {
227 return current_exception();
228 }
229 }
230
231 // NOTE: The following code is compatible with <bits/nested_exception.h>.
232
233 class nested_exception
234 {
235 exception_ptr _M_ptr;
236
237 public:
238 nested_exception() noexcept
239 : _M_ptr(current_exception())
240 {}
241 nested_exception(const nested_exception&) noexcept = default;
242 virtual
243 ~nested_exception() noexcept = default;
244
245 nested_exception&
246 operator=(const nested_exception&) noexcept = default;
247
248 __attribute__((__noreturn__)) void
249 rethrow_nested() const
250 {
251 if(_M_ptr)
252 rethrow_exception(_M_ptr);
253 std::terminate();
254 }
255
256 exception_ptr
257 nested_ptr() const noexcept
258 {
259 return _M_ptr;
260 }
261 };
262
263 template<typename _Except>
264 struct _Nested_exception : public _Except, public nested_exception
265 {
266 explicit
267 _Nested_exception(const _Except& __ex)
268 : _Except(__ex)
269 {}
270 explicit
271 _Nested_exception(_Except&& __ex)
272 : _Except(static_cast<_Except&&>(__ex))
273 {}
274 };
275
276 template<typename _Tp,
277 bool __with_nested = !__is_base_of(nested_exception, _Tp)>
278 struct _Throw_with_nested_impl
279 {
280 template<typename _Up>
281 __attribute__((__noreturn__)) static inline void
282 _S_throw(_Up&& __t)
283 {
284 throw _Nested_exception<_Tp>{static_cast<_Up&&>(__t)};
285 }
286 };
287
288 template<typename _Tp>
289 struct _Throw_with_nested_impl<_Tp, false>
290 {
291 template<typename _Up>
292 __attribute__((__noreturn__)) static inline void
293 _S_throw(_Up&& __t)
294 {
295 throw static_cast<_Up&&>(__t);
296 }
297 };
298
299
300 template<typename _Tp, bool = __is_class(_Tp)>
301 struct _Throw_with_nested_helper
302 : _Throw_with_nested_impl<_Tp>
303 {};
304
305 template<typename _Tp>
306 struct _Throw_with_nested_helper<_Tp, false>
307 : _Throw_with_nested_impl<_Tp, false>
308 {};
309
310 template<typename _Tp>
311 struct _Throw_with_nested_helper<_Tp&, false>
312 : _Throw_with_nested_helper<_Tp>
313 {};
314
315 template<typename _Tp>
316 struct _Throw_with_nested_helper<_Tp&&, false>
317 : _Throw_with_nested_helper<_Tp>
318 {};
319
320 template<typename _Tp>
321 __attribute__((__noreturn__)) inline void
322 throw_with_nested(_Tp&& __t)
323 {
324 _Throw_with_nested_helper<_Tp>::_S_throw(static_cast<_Tp&&>(__t));
325 }
326
327 template<typename _Tp, bool = __is_polymorphic(_Tp)>
328 struct _Rethrow_if_nested_impl
329 {
330 static void
331 _S_rethrow(const _Tp& __t)
332 {
333 if(const auto __tp = dynamic_cast<const nested_exception*>(&__t))
334 __tp->rethrow_nested();
335 }
336 };
337
338 template<typename _Tp>
339 struct _Rethrow_if_nested_impl<_Tp, false>
340 {
341 static void
342 _S_rethrow(const _Tp&)
343 {}
344 };
345
346 template<typename _Ex>
347 inline void
348 rethrow_if_nested(const _Ex& __ex)
349 {
350 _Rethrow_if_nested_impl<_Ex>::_S_rethrow(__ex);
351 }
352
353 } // namespace std;
354
355 } // extern "C++";
356
357 # pragma GCC visibility pop
358
359 #endif
360
361 #endif
362
ystdex::cpp2017::swap
void swap(optional< _type > &x, optional< _type > &y)
Definition: optional.h:888
platform::terminate
YB_NORETURN YF_API void terminate() ynothrow
终止函数。
Definition: YCommon.cpp:48
std
Definition: optional.h:982
operator==
PDefH(void, EnsureNonNull, void *p) ImplExpr(p ? void() boo operator==)(const COMPtr< _iCOM1 > &x, const COMPtr< _iCOM2 > &y) ynothrow
检查指针值，若为空则抛出 COMException 。
Definition: Win32/include/YCLib/COM.h:328
const
const Decapsulate const Decapsulate &y ynothrow ContextNode &ctx const
Definition: NPLA1Forms.cpp:1629
platform::bool
YB_ATTR_nodiscard std::FILE *fp bool
Definition: FileIO.h:1271