libstdc++
exception_ptr.h
Go to the documentation of this file.
1// Exception Handling support header (exception_ptr class) for -*- C++ -*-
2
3// Copyright (C) 2008-2024 Free Software Foundation, Inc.
4//
5// This file is part of GCC.
6//
7// GCC is free software; you can redistribute it and/or modify
8// it under the terms of the GNU General Public License as published by
9// the Free Software Foundation; either version 3, or (at your option)
10// any later version.
11//
12// GCC is distributed in the hope that it will be useful,
13// but WITHOUT ANY WARRANTY; without even the implied warranty of
14// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15// GNU General Public License for more details.
16//
17// Under Section 7 of GPL version 3, you are granted additional
18// permissions described in the GCC Runtime Library Exception, version
19// 3.1, as published by the Free Software Foundation.
20
21// You should have received a copy of the GNU General Public License and
22// a copy of the GCC Runtime Library Exception along with this program;
23// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
24// <http://www.gnu.org/licenses/>.
25
26/** @file bits/exception_ptr.h
27 * This is an internal header file, included by other library headers.
28 * Do not attempt to use it directly. @headername{exception}
29 */
30
31#ifndef _EXCEPTION_PTR_H
32#define _EXCEPTION_PTR_H
33
34#include <bits/c++config.h>
37#include <typeinfo>
38#include <new>
39
40#if __cplusplus >= 201103L
41# include <bits/move.h>
42#endif
43
44#ifdef _GLIBCXX_EH_PTR_RELOPS_COMPAT
45# define _GLIBCXX_EH_PTR_USED __attribute__((__used__))
46#else
47# define _GLIBCXX_EH_PTR_USED
48#endif
49
50extern "C++" {
51
52namespace std _GLIBCXX_VISIBILITY(default)
53{
54 class type_info;
55
56 /**
57 * @addtogroup exceptions
58 * @{
59 */
60
61 namespace __exception_ptr
62 {
63 class exception_ptr;
64 }
65
66 using __exception_ptr::exception_ptr;
67
68 /** Obtain an exception_ptr to the currently handled exception.
69 *
70 * If there is none, or the currently handled exception is foreign,
71 * return the null value.
72 *
73 * @since C++11
74 */
76
79
80 /// Throw the object pointed to by the exception_ptr.
81 void rethrow_exception(exception_ptr) __attribute__ ((__noreturn__));
82
84 {
85 using std::rethrow_exception; // So that ADL finds it.
86
87 /**
88 * @brief An opaque pointer to an arbitrary exception.
89 *
90 * The actual name of this type is unspecified, so the alias
91 * `std::exception_ptr` should be used to refer to it.
92 *
93 * @headerfile exception
94 * @since C++11 (but usable in C++98 as a GCC extension)
95 * @ingroup exceptions
96 */
98 {
99 void* _M_exception_object;
100
101 explicit exception_ptr(void* __e) _GLIBCXX_USE_NOEXCEPT;
102
103 void _M_addref() _GLIBCXX_USE_NOEXCEPT;
104 void _M_release() _GLIBCXX_USE_NOEXCEPT;
105
106 void *_M_get() const _GLIBCXX_NOEXCEPT __attribute__ ((__pure__));
107
110 template<typename _Ex>
112
113 public:
115
117
118#if __cplusplus >= 201103L
119 exception_ptr(nullptr_t) noexcept
120 : _M_exception_object(nullptr)
121 { }
122
124 : _M_exception_object(__o._M_exception_object)
125 { __o._M_exception_object = nullptr; }
126#endif
127
128#if (__cplusplus < 201103L) || defined (_GLIBCXX_EH_PTR_COMPAT)
129 typedef void (exception_ptr::*__safe_bool)();
130
131 // For construction from nullptr or 0.
133#endif
134
136 operator=(const exception_ptr&) _GLIBCXX_USE_NOEXCEPT;
137
138#if __cplusplus >= 201103L
140 operator=(exception_ptr&& __o) noexcept
141 {
142 exception_ptr(static_cast<exception_ptr&&>(__o)).swap(*this);
143 return *this;
144 }
145#endif
146
148
149 void
151
152#ifdef _GLIBCXX_EH_PTR_COMPAT
153 // Retained for compatibility with CXXABI_1.3.
155 bool operator!() const _GLIBCXX_USE_NOEXCEPT
157 operator __safe_bool() const _GLIBCXX_USE_NOEXCEPT;
158#endif
159
160#if __cplusplus >= 201103L
161 explicit operator bool() const noexcept
162 { return _M_exception_object; }
163#endif
164
165#if __cpp_impl_three_way_comparison >= 201907L \
166 && ! defined _GLIBCXX_EH_PTR_RELOPS_COMPAT
167 friend bool
168 operator==(const exception_ptr&, const exception_ptr&) noexcept = default;
169#else
170 friend _GLIBCXX_EH_PTR_USED bool
171 operator==(const exception_ptr& __x, const exception_ptr& __y)
173 { return __x._M_exception_object == __y._M_exception_object; }
174
175 friend _GLIBCXX_EH_PTR_USED bool
176 operator!=(const exception_ptr& __x, const exception_ptr& __y)
178 { return __x._M_exception_object != __y._M_exception_object; }
179#endif
180
181 const class std::type_info*
182 __cxa_exception_type() const _GLIBCXX_USE_NOEXCEPT
184 };
185
186 _GLIBCXX_EH_PTR_USED
187 inline
188 exception_ptr::exception_ptr() _GLIBCXX_USE_NOEXCEPT
189 : _M_exception_object(0)
190 { }
191
192 _GLIBCXX_EH_PTR_USED
193 inline
194 exception_ptr::exception_ptr(const exception_ptr& __other)
196 : _M_exception_object(__other._M_exception_object)
197 {
198 if (_M_exception_object)
199 _M_addref();
200 }
201
202 _GLIBCXX_EH_PTR_USED
203 inline
204 exception_ptr::~exception_ptr() _GLIBCXX_USE_NOEXCEPT
205 {
206 if (_M_exception_object)
207 _M_release();
208 }
209
210 _GLIBCXX_EH_PTR_USED
211 inline exception_ptr&
212 exception_ptr::operator=(const exception_ptr& __other) _GLIBCXX_USE_NOEXCEPT
213 {
214 exception_ptr(__other).swap(*this);
215 return *this;
216 }
217
218 _GLIBCXX_EH_PTR_USED
219 inline void
220 exception_ptr::swap(exception_ptr &__other) _GLIBCXX_USE_NOEXCEPT
221 {
222 void *__tmp = _M_exception_object;
223 _M_exception_object = __other._M_exception_object;
224 __other._M_exception_object = __tmp;
225 }
226
227 /// @relates exception_ptr
228 inline void
229 swap(exception_ptr& __lhs, exception_ptr& __rhs)
230 { __lhs.swap(__rhs); }
231
232 /// @cond undocumented
233 template<typename _Ex>
234 _GLIBCXX_CDTOR_CALLABI
235 inline void
236 __dest_thunk(void* __x)
237 { static_cast<_Ex*>(__x)->~_Ex(); }
238 /// @endcond
239
240 } // namespace __exception_ptr
241
242 using __exception_ptr::swap; // So that std::swap(exp1, exp2) finds it.
243
244 /// Obtain an exception_ptr pointing to a copy of the supplied object.
245#if (__cplusplus >= 201103L && __cpp_rtti) || __cpp_exceptions
246 template<typename _Ex>
247 exception_ptr
249 {
250#if __cplusplus >= 201103L && __cpp_rtti
251 using _Ex2 = typename decay<_Ex>::type;
252 void* __e = __cxxabiv1::__cxa_allocate_exception(sizeof(_Ex));
253 (void) __cxxabiv1::__cxa_init_primary_exception(
254 __e, const_cast<std::type_info*>(&typeid(_Ex)),
255 __exception_ptr::__dest_thunk<_Ex2>);
256 __try
257 {
258 ::new (__e) _Ex2(__ex);
259 return exception_ptr(__e);
260 }
261 __catch(...)
262 {
263 __cxxabiv1::__cxa_free_exception(__e);
264 return current_exception();
265 }
266#else
267 try
268 {
269 throw __ex;
270 }
271 catch(...)
272 {
273 return current_exception();
274 }
275#endif
276 }
277#else // no RTTI and no exceptions
278 // This is always_inline so the linker will never use this useless definition
279 // instead of a working one compiled with RTTI and/or exceptions enabled.
280 template<typename _Ex>
281 __attribute__ ((__always_inline__))
282 inline exception_ptr
283 make_exception_ptr(_Ex) _GLIBCXX_USE_NOEXCEPT
284 { return exception_ptr(); }
285#endif
286
287#undef _GLIBCXX_EH_PTR_USED
288
289 /// @} group exceptions
290} // namespace std
291
292} // extern "C++"
293
294#endif
exception_ptr current_exception() noexcept
exception_ptr make_exception_ptr(_Ex) noexcept
Obtain an exception_ptr pointing to a copy of the supplied object.
void rethrow_exception(exception_ptr)
Throw the object pointed to by the exception_ptr.
ISO C++ entities toplevel namespace is std.
Part of RTTI.
Definition typeinfo:92
An opaque pointer to an arbitrary exception.