xref: /dflybsd-src/contrib/gcc-8.0/libstdc++-v3/libsupc++/exception_ptr.h (revision 95059079af47f9a66a175f374f2da1a5020e3255)
138fd1498Szrj // Exception Handling support header (exception_ptr class) for -*- C++ -*-
238fd1498Szrj 
338fd1498Szrj // Copyright (C) 2008-2018 Free Software Foundation, Inc.
438fd1498Szrj //
538fd1498Szrj // This file is part of GCC.
638fd1498Szrj //
738fd1498Szrj // GCC is free software; you can redistribute it and/or modify
838fd1498Szrj // it under the terms of the GNU General Public License as published by
938fd1498Szrj // the Free Software Foundation; either version 3, or (at your option)
1038fd1498Szrj // any later version.
1138fd1498Szrj //
1238fd1498Szrj // GCC is distributed in the hope that it will be useful,
1338fd1498Szrj // but WITHOUT ANY WARRANTY; without even the implied warranty of
1438fd1498Szrj // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
1538fd1498Szrj // GNU General Public License for more details.
1638fd1498Szrj //
1738fd1498Szrj // Under Section 7 of GPL version 3, you are granted additional
1838fd1498Szrj // permissions described in the GCC Runtime Library Exception, version
1938fd1498Szrj // 3.1, as published by the Free Software Foundation.
2038fd1498Szrj 
2138fd1498Szrj // You should have received a copy of the GNU General Public License and
2238fd1498Szrj // a copy of the GCC Runtime Library Exception along with this program;
2338fd1498Szrj // see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
2438fd1498Szrj // <http://www.gnu.org/licenses/>.
2538fd1498Szrj 
2638fd1498Szrj /** @file bits/exception_ptr.h
2738fd1498Szrj  *  This is an internal header file, included by other library headers.
2838fd1498Szrj  *  Do not attempt to use it directly. @headername{exception}
2938fd1498Szrj  */
3038fd1498Szrj 
3138fd1498Szrj #ifndef _EXCEPTION_PTR_H
3238fd1498Szrj #define _EXCEPTION_PTR_H
3338fd1498Szrj 
3438fd1498Szrj #pragma GCC visibility push(default)
3538fd1498Szrj 
3638fd1498Szrj #include <bits/c++config.h>
3738fd1498Szrj #include <bits/exception_defines.h>
3838fd1498Szrj #include <bits/cxxabi_init_exception.h>
3938fd1498Szrj #include <typeinfo>
4038fd1498Szrj #include <new>
4138fd1498Szrj 
4238fd1498Szrj extern "C++" {
4338fd1498Szrj 
4438fd1498Szrj namespace std
4538fd1498Szrj {
4638fd1498Szrj   class type_info;
4738fd1498Szrj 
4838fd1498Szrj   /**
4938fd1498Szrj    * @addtogroup exceptions
5038fd1498Szrj    * @{
5138fd1498Szrj    */
5238fd1498Szrj   namespace __exception_ptr
5338fd1498Szrj   {
5438fd1498Szrj     class exception_ptr;
5538fd1498Szrj   }
5638fd1498Szrj 
5738fd1498Szrj   using __exception_ptr::exception_ptr;
5838fd1498Szrj 
5938fd1498Szrj   /** Obtain an exception_ptr to the currently handled exception. If there
6038fd1498Szrj    *  is none, or the currently handled exception is foreign, return the null
6138fd1498Szrj    *  value.
6238fd1498Szrj    */
6338fd1498Szrj   exception_ptr current_exception() _GLIBCXX_USE_NOEXCEPT;
6438fd1498Szrj 
6538fd1498Szrj   template<typename _Ex>
6638fd1498Szrj   exception_ptr make_exception_ptr(_Ex) _GLIBCXX_USE_NOEXCEPT;
6738fd1498Szrj 
6838fd1498Szrj   /// Throw the object pointed to by the exception_ptr.
6938fd1498Szrj   void rethrow_exception(exception_ptr) __attribute__ ((__noreturn__));
7038fd1498Szrj 
7138fd1498Szrj   namespace __exception_ptr
7238fd1498Szrj   {
7338fd1498Szrj     using std::rethrow_exception;
7438fd1498Szrj 
7538fd1498Szrj     /**
7638fd1498Szrj      *  @brief An opaque pointer to an arbitrary exception.
7738fd1498Szrj      *  @ingroup exceptions
7838fd1498Szrj      */
7938fd1498Szrj     class exception_ptr
8038fd1498Szrj     {
8138fd1498Szrj       void* _M_exception_object;
8238fd1498Szrj 
8338fd1498Szrj       explicit exception_ptr(void* __e) _GLIBCXX_USE_NOEXCEPT;
8438fd1498Szrj 
8538fd1498Szrj       void _M_addref() _GLIBCXX_USE_NOEXCEPT;
8638fd1498Szrj       void _M_release() _GLIBCXX_USE_NOEXCEPT;
8738fd1498Szrj 
8838fd1498Szrj       void *_M_get() const _GLIBCXX_NOEXCEPT __attribute__ ((__pure__));
8938fd1498Szrj 
9038fd1498Szrj       friend exception_ptr std::current_exception() _GLIBCXX_USE_NOEXCEPT;
9138fd1498Szrj       friend void std::rethrow_exception(exception_ptr);
9238fd1498Szrj       template<typename _Ex>
9338fd1498Szrj       friend exception_ptr std::make_exception_ptr(_Ex) _GLIBCXX_USE_NOEXCEPT;
9438fd1498Szrj 
9538fd1498Szrj     public:
9638fd1498Szrj       exception_ptr() _GLIBCXX_USE_NOEXCEPT;
9738fd1498Szrj 
9838fd1498Szrj       exception_ptr(const exception_ptr&) _GLIBCXX_USE_NOEXCEPT;
9938fd1498Szrj 
10038fd1498Szrj #if __cplusplus >= 201103L
exception_ptr(nullptr_t)10138fd1498Szrj       exception_ptr(nullptr_t) noexcept
10238fd1498Szrj       : _M_exception_object(0)
10338fd1498Szrj       { }
10438fd1498Szrj 
exception_ptr(exception_ptr && __o)10538fd1498Szrj       exception_ptr(exception_ptr&& __o) noexcept
10638fd1498Szrj       : _M_exception_object(__o._M_exception_object)
10738fd1498Szrj       { __o._M_exception_object = 0; }
10838fd1498Szrj #endif
10938fd1498Szrj 
11038fd1498Szrj #if (__cplusplus < 201103L) || defined (_GLIBCXX_EH_PTR_COMPAT)
11138fd1498Szrj       typedef void (exception_ptr::*__safe_bool)();
11238fd1498Szrj 
11338fd1498Szrj       // For construction from nullptr or 0.
11438fd1498Szrj       exception_ptr(__safe_bool) _GLIBCXX_USE_NOEXCEPT;
11538fd1498Szrj #endif
11638fd1498Szrj 
11738fd1498Szrj       exception_ptr&
11838fd1498Szrj       operator=(const exception_ptr&) _GLIBCXX_USE_NOEXCEPT;
11938fd1498Szrj 
12038fd1498Szrj #if __cplusplus >= 201103L
12138fd1498Szrj       exception_ptr&
12238fd1498Szrj       operator=(exception_ptr&& __o) noexcept
12338fd1498Szrj       {
12438fd1498Szrj         exception_ptr(static_cast<exception_ptr&&>(__o)).swap(*this);
12538fd1498Szrj         return *this;
12638fd1498Szrj       }
12738fd1498Szrj #endif
12838fd1498Szrj 
12938fd1498Szrj       ~exception_ptr() _GLIBCXX_USE_NOEXCEPT;
13038fd1498Szrj 
13138fd1498Szrj       void
13238fd1498Szrj       swap(exception_ptr&) _GLIBCXX_USE_NOEXCEPT;
13338fd1498Szrj 
13438fd1498Szrj #ifdef _GLIBCXX_EH_PTR_COMPAT
13538fd1498Szrj       // Retained for compatibility with CXXABI_1.3.
13638fd1498Szrj       void _M_safe_bool_dummy() _GLIBCXX_USE_NOEXCEPT
13738fd1498Szrj 	__attribute__ ((__const__));
13838fd1498Szrj       bool operator!() const _GLIBCXX_USE_NOEXCEPT
13938fd1498Szrj 	__attribute__ ((__pure__));
14038fd1498Szrj       operator __safe_bool() const _GLIBCXX_USE_NOEXCEPT;
14138fd1498Szrj #endif
14238fd1498Szrj 
14338fd1498Szrj #if __cplusplus >= 201103L
14438fd1498Szrj       explicit operator bool() const
14538fd1498Szrj       { return _M_exception_object; }
14638fd1498Szrj #endif
14738fd1498Szrj 
14838fd1498Szrj       friend bool
14938fd1498Szrj       operator==(const exception_ptr&, const exception_ptr&)
15038fd1498Szrj 	_GLIBCXX_USE_NOEXCEPT __attribute__ ((__pure__));
15138fd1498Szrj 
15238fd1498Szrj       const class std::type_info*
15338fd1498Szrj       __cxa_exception_type() const _GLIBCXX_USE_NOEXCEPT
15438fd1498Szrj 	__attribute__ ((__pure__));
15538fd1498Szrj     };
15638fd1498Szrj 
15738fd1498Szrj     bool
15838fd1498Szrj     operator==(const exception_ptr&, const exception_ptr&)
15938fd1498Szrj       _GLIBCXX_USE_NOEXCEPT __attribute__ ((__pure__));
16038fd1498Szrj 
16138fd1498Szrj     bool
16238fd1498Szrj     operator!=(const exception_ptr&, const exception_ptr&)
16338fd1498Szrj       _GLIBCXX_USE_NOEXCEPT __attribute__ ((__pure__));
16438fd1498Szrj 
16538fd1498Szrj     inline void
swap(exception_ptr & __lhs,exception_ptr & __rhs)16638fd1498Szrj     swap(exception_ptr& __lhs, exception_ptr& __rhs)
16738fd1498Szrj     { __lhs.swap(__rhs); }
16838fd1498Szrj 
16938fd1498Szrj     template<typename _Ex>
17038fd1498Szrj       inline void
__dest_thunk(void * __x)17138fd1498Szrj       __dest_thunk(void* __x)
17238fd1498Szrj       { static_cast<_Ex*>(__x)->~_Ex(); }
17338fd1498Szrj 
17438fd1498Szrj   } // namespace __exception_ptr
17538fd1498Szrj 
17638fd1498Szrj   /// Obtain an exception_ptr pointing to a copy of the supplied object.
17738fd1498Szrj   template<typename _Ex>
17838fd1498Szrj     exception_ptr
make_exception_ptr(_Ex __ex)17938fd1498Szrj     make_exception_ptr(_Ex __ex) _GLIBCXX_USE_NOEXCEPT
18038fd1498Szrj     {
181*58e805e6Szrj #if __cpp_exceptions && __cpp_rtti && !_GLIBCXX_HAVE_CDTOR_CALLABI
18238fd1498Szrj       void* __e = __cxxabiv1::__cxa_allocate_exception(sizeof(_Ex));
18338fd1498Szrj       (void) __cxxabiv1::__cxa_init_primary_exception(
18438fd1498Szrj 	  __e, const_cast<std::type_info*>(&typeid(__ex)),
18538fd1498Szrj 	  __exception_ptr::__dest_thunk<_Ex>);
186*58e805e6Szrj       try
187*58e805e6Szrj 	{
18838fd1498Szrj           ::new (__e) _Ex(__ex);
18938fd1498Szrj           return exception_ptr(__e);
190*58e805e6Szrj 	}
191*58e805e6Szrj       catch(...)
192*58e805e6Szrj 	{
193*58e805e6Szrj 	  __cxxabiv1::__cxa_free_exception(__e);
194*58e805e6Szrj 	  return current_exception();
195*58e805e6Szrj 	}
196*58e805e6Szrj #elif __cpp_exceptions
197*58e805e6Szrj       try
198*58e805e6Szrj 	{
19938fd1498Szrj           throw __ex;
20038fd1498Szrj 	}
20138fd1498Szrj       catch(...)
20238fd1498Szrj 	{
20338fd1498Szrj 	  return current_exception();
20438fd1498Szrj 	}
205*58e805e6Szrj #else // no RTTI and no exceptions
20638fd1498Szrj       return exception_ptr();
20738fd1498Szrj #endif
20838fd1498Szrj     }
20938fd1498Szrj 
21038fd1498Szrj   // @} group exceptions
21138fd1498Szrj } // namespace std
21238fd1498Szrj 
21338fd1498Szrj } // extern "C++"
21438fd1498Szrj 
21538fd1498Szrj #pragma GCC visibility pop
21638fd1498Szrj 
21738fd1498Szrj #endif
218