10b57cec5SDimitry Andric// -*- C++ -*- 2349cc55cSDimitry Andric//===----------------------------------------------------------------------===// 30b57cec5SDimitry Andric// 40b57cec5SDimitry Andric// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 50b57cec5SDimitry Andric// See https://llvm.org/LICENSE.txt for license information. 60b57cec5SDimitry Andric// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 70b57cec5SDimitry Andric// 80b57cec5SDimitry Andric//===----------------------------------------------------------------------===// 90b57cec5SDimitry Andric 100b57cec5SDimitry Andric#ifndef _LIBCPP_EXCEPTION 110b57cec5SDimitry Andric#define _LIBCPP_EXCEPTION 120b57cec5SDimitry Andric 130b57cec5SDimitry Andric/* 140b57cec5SDimitry Andric exception synopsis 150b57cec5SDimitry Andric 160b57cec5SDimitry Andricnamespace std 170b57cec5SDimitry Andric{ 180b57cec5SDimitry Andric 190b57cec5SDimitry Andricclass exception 200b57cec5SDimitry Andric{ 210b57cec5SDimitry Andricpublic: 220b57cec5SDimitry Andric exception() noexcept; 230b57cec5SDimitry Andric exception(const exception&) noexcept; 240b57cec5SDimitry Andric exception& operator=(const exception&) noexcept; 250b57cec5SDimitry Andric virtual ~exception() noexcept; 260b57cec5SDimitry Andric virtual const char* what() const noexcept; 270b57cec5SDimitry Andric}; 280b57cec5SDimitry Andric 290b57cec5SDimitry Andricclass bad_exception 300b57cec5SDimitry Andric : public exception 310b57cec5SDimitry Andric{ 320b57cec5SDimitry Andricpublic: 330b57cec5SDimitry Andric bad_exception() noexcept; 340b57cec5SDimitry Andric bad_exception(const bad_exception&) noexcept; 350b57cec5SDimitry Andric bad_exception& operator=(const bad_exception&) noexcept; 360b57cec5SDimitry Andric virtual ~bad_exception() noexcept; 370b57cec5SDimitry Andric virtual const char* what() const noexcept; 380b57cec5SDimitry Andric}; 390b57cec5SDimitry Andric 400b57cec5SDimitry Andrictypedef void (*unexpected_handler)(); 410b57cec5SDimitry Andricunexpected_handler set_unexpected(unexpected_handler f ) noexcept; 420b57cec5SDimitry Andricunexpected_handler get_unexpected() noexcept; 430b57cec5SDimitry Andric[[noreturn]] void unexpected(); 440b57cec5SDimitry Andric 450b57cec5SDimitry Andrictypedef void (*terminate_handler)(); 460b57cec5SDimitry Andricterminate_handler set_terminate(terminate_handler f ) noexcept; 470b57cec5SDimitry Andricterminate_handler get_terminate() noexcept; 480b57cec5SDimitry Andric[[noreturn]] void terminate() noexcept; 490b57cec5SDimitry Andric 500b57cec5SDimitry Andricbool uncaught_exception() noexcept; 510b57cec5SDimitry Andricint uncaught_exceptions() noexcept; // C++17 520b57cec5SDimitry Andric 530b57cec5SDimitry Andrictypedef unspecified exception_ptr; 540b57cec5SDimitry Andric 550b57cec5SDimitry Andricexception_ptr current_exception() noexcept; 560b57cec5SDimitry Andricvoid rethrow_exception [[noreturn]] (exception_ptr p); 570b57cec5SDimitry Andrictemplate<class E> exception_ptr make_exception_ptr(E e) noexcept; 580b57cec5SDimitry Andric 590b57cec5SDimitry Andricclass nested_exception 600b57cec5SDimitry Andric{ 610b57cec5SDimitry Andricpublic: 620b57cec5SDimitry Andric nested_exception() noexcept; 630b57cec5SDimitry Andric nested_exception(const nested_exception&) noexcept = default; 640b57cec5SDimitry Andric nested_exception& operator=(const nested_exception&) noexcept = default; 650b57cec5SDimitry Andric virtual ~nested_exception() = default; 660b57cec5SDimitry Andric 670b57cec5SDimitry Andric // access functions 680b57cec5SDimitry Andric [[noreturn]] void rethrow_nested() const; 690b57cec5SDimitry Andric exception_ptr nested_ptr() const noexcept; 700b57cec5SDimitry Andric}; 710b57cec5SDimitry Andric 720b57cec5SDimitry Andrictemplate <class T> [[noreturn]] void throw_with_nested(T&& t); 730b57cec5SDimitry Andrictemplate <class E> void rethrow_if_nested(const E& e); 740b57cec5SDimitry Andric 750b57cec5SDimitry Andric} // std 760b57cec5SDimitry Andric 770b57cec5SDimitry Andric*/ 780b57cec5SDimitry Andric 7981ad6265SDimitry Andric#include <__assert> // all public C++ headers provide the assertion handler 80e8d8bef9SDimitry Andric#include <__availability> 81fe6060f1SDimitry Andric#include <__config> 82fe6060f1SDimitry Andric#include <__memory/addressof.h> 83*bdd1243dSDimitry Andric#include <__type_traits/decay.h> 84*bdd1243dSDimitry Andric#include <__type_traits/is_base_of.h> 85*bdd1243dSDimitry Andric#include <__type_traits/is_class.h> 86*bdd1243dSDimitry Andric#include <__type_traits/is_convertible.h> 87*bdd1243dSDimitry Andric#include <__type_traits/is_copy_constructible.h> 88*bdd1243dSDimitry Andric#include <__type_traits/is_final.h> 89*bdd1243dSDimitry Andric#include <__type_traits/is_polymorphic.h> 900b57cec5SDimitry Andric#include <cstddef> 910b57cec5SDimitry Andric#include <cstdlib> 920b57cec5SDimitry Andric#include <version> 930b57cec5SDimitry Andric 94*bdd1243dSDimitry Andric// <vcruntime_exception.h> defines its own std::exception and std::bad_exception types, 95*bdd1243dSDimitry Andric// which we use in order to be ABI-compatible with other STLs on Windows. 960b57cec5SDimitry Andric#if defined(_LIBCPP_ABI_VCRUNTIME) 970b57cec5SDimitry Andric# include <vcruntime_exception.h> 980b57cec5SDimitry Andric#endif 990b57cec5SDimitry Andric 1000b57cec5SDimitry Andric#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) 1010b57cec5SDimitry Andric# pragma GCC system_header 1020b57cec5SDimitry Andric#endif 1030b57cec5SDimitry Andric 1040b57cec5SDimitry Andricnamespace std // purposefully not using versioning namespace 1050b57cec5SDimitry Andric{ 1060b57cec5SDimitry Andric 107*bdd1243dSDimitry Andric#if defined(_LIBCPP_ABI_VCRUNTIME) && (!defined(_HAS_EXCEPTIONS) || _HAS_EXCEPTIONS != 0) 108*bdd1243dSDimitry Andric// The std::exception class was already included above, but we're explicit about this condition here for clarity. 109*bdd1243dSDimitry Andric 110*bdd1243dSDimitry Andric#elif defined(_LIBCPP_ABI_VCRUNTIME) && _HAS_EXCEPTIONS == 0 111*bdd1243dSDimitry Andric// However, <vcruntime_exception.h> does not define std::exception and std::bad_exception 112*bdd1243dSDimitry Andric// when _HAS_EXCEPTIONS == 0. 113*bdd1243dSDimitry Andric// 114*bdd1243dSDimitry Andric// Since libc++ still wants to provide the std::exception hierarchy even when _HAS_EXCEPTIONS == 0 115*bdd1243dSDimitry Andric// (after all those are simply types like any other), we define an ABI-compatible version 116*bdd1243dSDimitry Andric// of the VCRuntime std::exception and std::bad_exception types in that mode. 117*bdd1243dSDimitry Andric 118*bdd1243dSDimitry Andricstruct __std_exception_data { 119*bdd1243dSDimitry Andric char const* _What; 120*bdd1243dSDimitry Andric bool _DoFree; 121*bdd1243dSDimitry Andric}; 122*bdd1243dSDimitry Andric 123*bdd1243dSDimitry Andricclass exception { // base of all library exceptions 124*bdd1243dSDimitry Andricpublic: 125*bdd1243dSDimitry Andric exception() _NOEXCEPT : __data_() {} 126*bdd1243dSDimitry Andric 127*bdd1243dSDimitry Andric explicit exception(char const* __message) _NOEXCEPT : __data_() { 128*bdd1243dSDimitry Andric __data_._What = __message; 129*bdd1243dSDimitry Andric __data_._DoFree = true; 130*bdd1243dSDimitry Andric } 131*bdd1243dSDimitry Andric 132*bdd1243dSDimitry Andric exception(exception const&) _NOEXCEPT {} 133*bdd1243dSDimitry Andric 134*bdd1243dSDimitry Andric exception& operator=(exception const&) _NOEXCEPT { return *this; } 135*bdd1243dSDimitry Andric 136*bdd1243dSDimitry Andric virtual ~exception() _NOEXCEPT {} 137*bdd1243dSDimitry Andric 138*bdd1243dSDimitry Andric virtual char const* what() const _NOEXCEPT { return __data_._What ? __data_._What : "Unknown exception"; } 139*bdd1243dSDimitry Andric 140*bdd1243dSDimitry Andricprivate: 141*bdd1243dSDimitry Andric __std_exception_data __data_; 142*bdd1243dSDimitry Andric}; 143*bdd1243dSDimitry Andric 144*bdd1243dSDimitry Andricclass bad_exception : public exception { 145*bdd1243dSDimitry Andricpublic: 146*bdd1243dSDimitry Andric bad_exception() _NOEXCEPT : exception("bad exception") {} 147*bdd1243dSDimitry Andric}; 148*bdd1243dSDimitry Andric 149*bdd1243dSDimitry Andric#else // !defined(_LIBCPP_ABI_VCRUNTIME) 150*bdd1243dSDimitry Andric// On all other platforms, we define our own std::exception and std::bad_exception types 151*bdd1243dSDimitry Andric// regardless of whether exceptions are turned on as a language feature. 152*bdd1243dSDimitry Andric 153*bdd1243dSDimitry Andricclass _LIBCPP_EXCEPTION_ABI exception { 1540b57cec5SDimitry Andricpublic: 1550b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY exception() _NOEXCEPT {} 1569ec406dcSDimitry Andric _LIBCPP_INLINE_VISIBILITY exception(const exception&) _NOEXCEPT = default; 1579ec406dcSDimitry Andric 1580b57cec5SDimitry Andric virtual ~exception() _NOEXCEPT; 1590b57cec5SDimitry Andric virtual const char* what() const _NOEXCEPT; 1600b57cec5SDimitry Andric}; 1610b57cec5SDimitry Andric 162*bdd1243dSDimitry Andricclass _LIBCPP_EXCEPTION_ABI bad_exception : public exception { 1630b57cec5SDimitry Andricpublic: 1640b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY bad_exception() _NOEXCEPT {} 165*bdd1243dSDimitry Andric ~bad_exception() _NOEXCEPT override; 166*bdd1243dSDimitry Andric const char* what() const _NOEXCEPT override; 1670b57cec5SDimitry Andric}; 1680b57cec5SDimitry Andric#endif // !_LIBCPP_ABI_VCRUNTIME 1690b57cec5SDimitry Andric 1700b57cec5SDimitry Andric#if _LIBCPP_STD_VER <= 14 \ 1710b57cec5SDimitry Andric || defined(_LIBCPP_ENABLE_CXX17_REMOVED_UNEXPECTED_FUNCTIONS) \ 1720b57cec5SDimitry Andric || defined(_LIBCPP_BUILDING_LIBRARY) 1730b57cec5SDimitry Andrictypedef void (*unexpected_handler)(); 1740b57cec5SDimitry Andric_LIBCPP_FUNC_VIS unexpected_handler set_unexpected(unexpected_handler) _NOEXCEPT; 1750b57cec5SDimitry Andric_LIBCPP_FUNC_VIS unexpected_handler get_unexpected() _NOEXCEPT; 1760b57cec5SDimitry Andric_LIBCPP_NORETURN _LIBCPP_FUNC_VIS void unexpected(); 1770b57cec5SDimitry Andric#endif 1780b57cec5SDimitry Andric 1790b57cec5SDimitry Andrictypedef void (*terminate_handler)(); 1800b57cec5SDimitry Andric_LIBCPP_FUNC_VIS terminate_handler set_terminate(terminate_handler) _NOEXCEPT; 1810b57cec5SDimitry Andric_LIBCPP_FUNC_VIS terminate_handler get_terminate() _NOEXCEPT; 1820b57cec5SDimitry Andric_LIBCPP_NORETURN _LIBCPP_FUNC_VIS void terminate() _NOEXCEPT; 1830b57cec5SDimitry Andric 1840b57cec5SDimitry Andric_LIBCPP_FUNC_VIS bool uncaught_exception() _NOEXCEPT; 1850b57cec5SDimitry Andric_LIBCPP_FUNC_VIS _LIBCPP_AVAILABILITY_UNCAUGHT_EXCEPTIONS int uncaught_exceptions() _NOEXCEPT; 1860b57cec5SDimitry Andric 1870b57cec5SDimitry Andricclass _LIBCPP_TYPE_VIS exception_ptr; 1880b57cec5SDimitry Andric 1890b57cec5SDimitry Andric_LIBCPP_FUNC_VIS exception_ptr current_exception() _NOEXCEPT; 1900b57cec5SDimitry Andric_LIBCPP_NORETURN _LIBCPP_FUNC_VIS void rethrow_exception(exception_ptr); 1910b57cec5SDimitry Andric 1920b57cec5SDimitry Andric#ifndef _LIBCPP_ABI_MICROSOFT 1930b57cec5SDimitry Andric 1940b57cec5SDimitry Andricclass _LIBCPP_TYPE_VIS exception_ptr 1950b57cec5SDimitry Andric{ 1960b57cec5SDimitry Andric void* __ptr_; 1970b57cec5SDimitry Andricpublic: 1980b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY exception_ptr() _NOEXCEPT : __ptr_() {} 1990b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY exception_ptr(nullptr_t) _NOEXCEPT : __ptr_() {} 2000b57cec5SDimitry Andric 2010b57cec5SDimitry Andric exception_ptr(const exception_ptr&) _NOEXCEPT; 2020b57cec5SDimitry Andric exception_ptr& operator=(const exception_ptr&) _NOEXCEPT; 2030b57cec5SDimitry Andric ~exception_ptr() _NOEXCEPT; 2040b57cec5SDimitry Andric 205fe6060f1SDimitry Andric _LIBCPP_INLINE_VISIBILITY explicit operator bool() const _NOEXCEPT 2060b57cec5SDimitry Andric {return __ptr_ != nullptr;} 2070b57cec5SDimitry Andric 2080b57cec5SDimitry Andric friend _LIBCPP_INLINE_VISIBILITY 2090b57cec5SDimitry Andric bool operator==(const exception_ptr& __x, const exception_ptr& __y) _NOEXCEPT 2100b57cec5SDimitry Andric {return __x.__ptr_ == __y.__ptr_;} 2110b57cec5SDimitry Andric 2120b57cec5SDimitry Andric friend _LIBCPP_INLINE_VISIBILITY 2130b57cec5SDimitry Andric bool operator!=(const exception_ptr& __x, const exception_ptr& __y) _NOEXCEPT 2140b57cec5SDimitry Andric {return !(__x == __y);} 2150b57cec5SDimitry Andric 2160b57cec5SDimitry Andric friend _LIBCPP_FUNC_VIS exception_ptr current_exception() _NOEXCEPT; 2170b57cec5SDimitry Andric friend _LIBCPP_FUNC_VIS void rethrow_exception(exception_ptr); 2180b57cec5SDimitry Andric}; 2190b57cec5SDimitry Andric 2200b57cec5SDimitry Andrictemplate<class _Ep> 2210b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY exception_ptr 2220b57cec5SDimitry Andricmake_exception_ptr(_Ep __e) _NOEXCEPT 2230b57cec5SDimitry Andric{ 2240b57cec5SDimitry Andric#ifndef _LIBCPP_NO_EXCEPTIONS 2250b57cec5SDimitry Andric try 2260b57cec5SDimitry Andric { 2270b57cec5SDimitry Andric throw __e; 2280b57cec5SDimitry Andric } 2290b57cec5SDimitry Andric catch (...) 2300b57cec5SDimitry Andric { 2310b57cec5SDimitry Andric return current_exception(); 2320b57cec5SDimitry Andric } 2330b57cec5SDimitry Andric#else 2340b57cec5SDimitry Andric ((void)__e); 2350b57cec5SDimitry Andric _VSTD::abort(); 2360b57cec5SDimitry Andric#endif 2370b57cec5SDimitry Andric} 2380b57cec5SDimitry Andric 2390b57cec5SDimitry Andric#else // _LIBCPP_ABI_MICROSOFT 2400b57cec5SDimitry Andric 2410b57cec5SDimitry Andricclass _LIBCPP_TYPE_VIS exception_ptr 2420b57cec5SDimitry Andric{ 24381ad6265SDimitry Andric_LIBCPP_DIAGNOSTIC_PUSH 24481ad6265SDimitry Andric_LIBCPP_CLANG_DIAGNOSTIC_IGNORED("-Wunused-private-field") 2450b57cec5SDimitry Andric void* __ptr1_; 2460b57cec5SDimitry Andric void* __ptr2_; 24781ad6265SDimitry Andric_LIBCPP_DIAGNOSTIC_POP 2480b57cec5SDimitry Andricpublic: 2490b57cec5SDimitry Andric exception_ptr() _NOEXCEPT; 2500b57cec5SDimitry Andric exception_ptr(nullptr_t) _NOEXCEPT; 2510b57cec5SDimitry Andric exception_ptr(const exception_ptr& __other) _NOEXCEPT; 2520b57cec5SDimitry Andric exception_ptr& operator=(const exception_ptr& __other) _NOEXCEPT; 2530b57cec5SDimitry Andric exception_ptr& operator=(nullptr_t) _NOEXCEPT; 2540b57cec5SDimitry Andric ~exception_ptr() _NOEXCEPT; 255fe6060f1SDimitry Andric explicit operator bool() const _NOEXCEPT; 2560b57cec5SDimitry Andric}; 2570b57cec5SDimitry Andric 2580b57cec5SDimitry Andric_LIBCPP_FUNC_VIS 2590b57cec5SDimitry Andricbool operator==(const exception_ptr& __x, const exception_ptr& __y) _NOEXCEPT; 2600b57cec5SDimitry Andric 2610b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY 2620b57cec5SDimitry Andricbool operator!=(const exception_ptr& __x, const exception_ptr& __y) _NOEXCEPT 2630b57cec5SDimitry Andric {return !(__x == __y);} 2640b57cec5SDimitry Andric 2650b57cec5SDimitry Andric_LIBCPP_FUNC_VIS void swap(exception_ptr&, exception_ptr&) _NOEXCEPT; 2660b57cec5SDimitry Andric 2670b57cec5SDimitry Andric_LIBCPP_FUNC_VIS exception_ptr __copy_exception_ptr(void *__except, const void* __ptr); 2680b57cec5SDimitry Andric_LIBCPP_FUNC_VIS exception_ptr current_exception() _NOEXCEPT; 269753f127fSDimitry Andric_LIBCPP_NORETURN _LIBCPP_FUNC_VIS void rethrow_exception(exception_ptr); 2700b57cec5SDimitry Andric 2710b57cec5SDimitry Andric// This is a built-in template function which automagically extracts the required 2720b57cec5SDimitry Andric// information. 2730b57cec5SDimitry Andrictemplate <class _E> void *__GetExceptionInfo(_E); 2740b57cec5SDimitry Andric 2750b57cec5SDimitry Andrictemplate<class _Ep> 2760b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY exception_ptr 2770b57cec5SDimitry Andricmake_exception_ptr(_Ep __e) _NOEXCEPT 2780b57cec5SDimitry Andric{ 2790b57cec5SDimitry Andric return __copy_exception_ptr(_VSTD::addressof(__e), __GetExceptionInfo(__e)); 2800b57cec5SDimitry Andric} 2810b57cec5SDimitry Andric 2820b57cec5SDimitry Andric#endif // _LIBCPP_ABI_MICROSOFT 2830b57cec5SDimitry Andric// nested_exception 2840b57cec5SDimitry Andric 2850b57cec5SDimitry Andricclass _LIBCPP_EXCEPTION_ABI nested_exception 2860b57cec5SDimitry Andric{ 2870b57cec5SDimitry Andric exception_ptr __ptr_; 2880b57cec5SDimitry Andricpublic: 2890b57cec5SDimitry Andric nested_exception() _NOEXCEPT; 2900b57cec5SDimitry Andric// nested_exception(const nested_exception&) noexcept = default; 2910b57cec5SDimitry Andric// nested_exception& operator=(const nested_exception&) noexcept = default; 2920b57cec5SDimitry Andric virtual ~nested_exception() _NOEXCEPT; 2930b57cec5SDimitry Andric 2940b57cec5SDimitry Andric // access functions 2950b57cec5SDimitry Andric _LIBCPP_NORETURN void rethrow_nested() const; 2960b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY exception_ptr nested_ptr() const _NOEXCEPT {return __ptr_;} 2970b57cec5SDimitry Andric}; 2980b57cec5SDimitry Andric 2990b57cec5SDimitry Andrictemplate <class _Tp> 3000b57cec5SDimitry Andricstruct __nested 3010b57cec5SDimitry Andric : public _Tp, 3020b57cec5SDimitry Andric public nested_exception 3030b57cec5SDimitry Andric{ 3040b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY explicit __nested(const _Tp& __t) : _Tp(__t) {} 3050b57cec5SDimitry Andric}; 3060b57cec5SDimitry Andric 3070b57cec5SDimitry Andric#ifndef _LIBCPP_NO_EXCEPTIONS 3080b57cec5SDimitry Andrictemplate <class _Tp, class _Up, bool> 3090b57cec5SDimitry Andricstruct __throw_with_nested; 3100b57cec5SDimitry Andric 3110b57cec5SDimitry Andrictemplate <class _Tp, class _Up> 3120b57cec5SDimitry Andricstruct __throw_with_nested<_Tp, _Up, true> { 3130b57cec5SDimitry Andric _LIBCPP_NORETURN static inline _LIBCPP_INLINE_VISIBILITY void 3140b57cec5SDimitry Andric __do_throw(_Tp&& __t) 3150b57cec5SDimitry Andric { 316fe6060f1SDimitry Andric throw __nested<_Up>(static_cast<_Tp&&>(__t)); 3170b57cec5SDimitry Andric } 3180b57cec5SDimitry Andric}; 3190b57cec5SDimitry Andric 3200b57cec5SDimitry Andrictemplate <class _Tp, class _Up> 3210b57cec5SDimitry Andricstruct __throw_with_nested<_Tp, _Up, false> { 3220b57cec5SDimitry Andric _LIBCPP_NORETURN static inline _LIBCPP_INLINE_VISIBILITY void 3230b57cec5SDimitry Andric#ifndef _LIBCPP_CXX03_LANG 3240b57cec5SDimitry Andric __do_throw(_Tp&& __t) 3250b57cec5SDimitry Andric#else 3260b57cec5SDimitry Andric __do_throw (_Tp& __t) 3270b57cec5SDimitry Andric#endif // _LIBCPP_CXX03_LANG 3280b57cec5SDimitry Andric { 329fe6060f1SDimitry Andric throw static_cast<_Tp&&>(__t); 3300b57cec5SDimitry Andric } 3310b57cec5SDimitry Andric}; 3320b57cec5SDimitry Andric#endif 3330b57cec5SDimitry Andric 3340b57cec5SDimitry Andrictemplate <class _Tp> 335*bdd1243dSDimitry Andric_LIBCPP_NORETURN _LIBCPP_HIDE_FROM_ABI 3360b57cec5SDimitry Andricvoid 3370b57cec5SDimitry Andricthrow_with_nested(_Tp&& __t) 3380b57cec5SDimitry Andric{ 3390b57cec5SDimitry Andric#ifndef _LIBCPP_NO_EXCEPTIONS 3400b57cec5SDimitry Andric typedef typename decay<_Tp>::type _Up; 3410b57cec5SDimitry Andric static_assert( is_copy_constructible<_Up>::value, "type thrown must be CopyConstructible"); 3420b57cec5SDimitry Andric __throw_with_nested<_Tp, _Up, 3430b57cec5SDimitry Andric is_class<_Up>::value && 3440b57cec5SDimitry Andric !is_base_of<nested_exception, _Up>::value && 3450b57cec5SDimitry Andric !__libcpp_is_final<_Up>::value>:: 346fe6060f1SDimitry Andric __do_throw(static_cast<_Tp&&>(__t)); 3470b57cec5SDimitry Andric#else 3480b57cec5SDimitry Andric ((void)__t); 3490b57cec5SDimitry Andric // FIXME: Make this abort 3500b57cec5SDimitry Andric#endif 3510b57cec5SDimitry Andric} 3520b57cec5SDimitry Andric 3530b57cec5SDimitry Andrictemplate <class _From, class _To> 35481ad6265SDimitry Andricstruct __can_dynamic_cast : _BoolConstant< 3550b57cec5SDimitry Andric is_polymorphic<_From>::value && 3560b57cec5SDimitry Andric (!is_base_of<_To, _From>::value || 35781ad6265SDimitry Andric is_convertible<const _From*, const _To*>::value)> {}; 3580b57cec5SDimitry Andric 3590b57cec5SDimitry Andrictemplate <class _Ep> 3600b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY 3610b57cec5SDimitry Andricvoid 3620b57cec5SDimitry Andricrethrow_if_nested(const _Ep& __e, 363753f127fSDimitry Andric __enable_if_t< __can_dynamic_cast<_Ep, nested_exception>::value>* = 0) 3640b57cec5SDimitry Andric{ 3650b57cec5SDimitry Andric const nested_exception* __nep = dynamic_cast<const nested_exception*>(_VSTD::addressof(__e)); 3660b57cec5SDimitry Andric if (__nep) 3670b57cec5SDimitry Andric __nep->rethrow_nested(); 3680b57cec5SDimitry Andric} 3690b57cec5SDimitry Andric 3700b57cec5SDimitry Andrictemplate <class _Ep> 3710b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY 3720b57cec5SDimitry Andricvoid 3730b57cec5SDimitry Andricrethrow_if_nested(const _Ep&, 374753f127fSDimitry Andric __enable_if_t<!__can_dynamic_cast<_Ep, nested_exception>::value>* = 0) 3750b57cec5SDimitry Andric{ 3760b57cec5SDimitry Andric} 3770b57cec5SDimitry Andric 3780eae32dcSDimitry Andric} // namespace std 3790b57cec5SDimitry Andric 380*bdd1243dSDimitry Andric#if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20 381*bdd1243dSDimitry Andric# include <type_traits> 382*bdd1243dSDimitry Andric#endif 383*bdd1243dSDimitry Andric 3840b57cec5SDimitry Andric#endif // _LIBCPP_EXCEPTION 385