14684ddb6SLionel Sambuc// -*- C++ -*- 24684ddb6SLionel Sambuc//===-------------------------- exception ---------------------------------===// 34684ddb6SLionel Sambuc// 44684ddb6SLionel Sambuc// The LLVM Compiler Infrastructure 54684ddb6SLionel Sambuc// 64684ddb6SLionel Sambuc// This file is dual licensed under the MIT and the University of Illinois Open 74684ddb6SLionel Sambuc// Source Licenses. See LICENSE.TXT for details. 84684ddb6SLionel Sambuc// 94684ddb6SLionel Sambuc//===----------------------------------------------------------------------===// 104684ddb6SLionel Sambuc 114684ddb6SLionel Sambuc#ifndef _LIBCPP_EXCEPTION 124684ddb6SLionel Sambuc#define _LIBCPP_EXCEPTION 134684ddb6SLionel Sambuc 144684ddb6SLionel Sambuc/* 154684ddb6SLionel Sambuc exception synopsis 164684ddb6SLionel Sambuc 174684ddb6SLionel Sambucnamespace std 184684ddb6SLionel Sambuc{ 194684ddb6SLionel Sambuc 204684ddb6SLionel Sambucclass exception 214684ddb6SLionel Sambuc{ 224684ddb6SLionel Sambucpublic: 234684ddb6SLionel Sambuc exception() noexcept; 244684ddb6SLionel Sambuc exception(const exception&) noexcept; 254684ddb6SLionel Sambuc exception& operator=(const exception&) noexcept; 264684ddb6SLionel Sambuc virtual ~exception() noexcept; 274684ddb6SLionel Sambuc virtual const char* what() const noexcept; 284684ddb6SLionel Sambuc}; 294684ddb6SLionel Sambuc 304684ddb6SLionel Sambucclass bad_exception 314684ddb6SLionel Sambuc : public exception 324684ddb6SLionel Sambuc{ 334684ddb6SLionel Sambucpublic: 344684ddb6SLionel Sambuc bad_exception() noexcept; 354684ddb6SLionel Sambuc bad_exception(const bad_exception&) noexcept; 364684ddb6SLionel Sambuc bad_exception& operator=(const bad_exception&) noexcept; 374684ddb6SLionel Sambuc virtual ~bad_exception() noexcept; 384684ddb6SLionel Sambuc virtual const char* what() const noexcept; 394684ddb6SLionel Sambuc}; 404684ddb6SLionel Sambuc 414684ddb6SLionel Sambuctypedef void (*unexpected_handler)(); 424684ddb6SLionel Sambucunexpected_handler set_unexpected(unexpected_handler f ) noexcept; 434684ddb6SLionel Sambucunexpected_handler get_unexpected() noexcept; 444684ddb6SLionel Sambuc[[noreturn]] void unexpected(); 454684ddb6SLionel Sambuc 464684ddb6SLionel Sambuctypedef void (*terminate_handler)(); 474684ddb6SLionel Sambucterminate_handler set_terminate(terminate_handler f ) noexcept; 484684ddb6SLionel Sambucterminate_handler get_terminate() noexcept; 494684ddb6SLionel Sambuc[[noreturn]] void terminate() noexcept; 504684ddb6SLionel Sambuc 514684ddb6SLionel Sambucbool uncaught_exception() noexcept; 52*0a6a1f1dSLionel Sambucint uncaught_exceptions() noexcept; // C++17 534684ddb6SLionel Sambuc 544684ddb6SLionel Sambuctypedef unspecified exception_ptr; 554684ddb6SLionel Sambuc 564684ddb6SLionel Sambucexception_ptr current_exception() noexcept; 574684ddb6SLionel Sambucvoid rethrow_exception [[noreturn]] (exception_ptr p); 584684ddb6SLionel Sambuctemplate<class E> exception_ptr make_exception_ptr(E e) noexcept; 594684ddb6SLionel Sambuc 604684ddb6SLionel Sambucclass nested_exception 614684ddb6SLionel Sambuc{ 624684ddb6SLionel Sambucpublic: 634684ddb6SLionel Sambuc nested_exception() noexcept; 644684ddb6SLionel Sambuc nested_exception(const nested_exception&) noexcept = default; 654684ddb6SLionel Sambuc nested_exception& operator=(const nested_exception&) noexcept = default; 664684ddb6SLionel Sambuc virtual ~nested_exception() = default; 674684ddb6SLionel Sambuc 684684ddb6SLionel Sambuc // access functions 694684ddb6SLionel Sambuc [[noreturn]] void rethrow_nested() const; 704684ddb6SLionel Sambuc exception_ptr nested_ptr() const noexcept; 714684ddb6SLionel Sambuc}; 724684ddb6SLionel Sambuc 734684ddb6SLionel Sambuctemplate <class T> [[noreturn]] void throw_with_nested(T&& t); 744684ddb6SLionel Sambuctemplate <class E> void rethrow_if_nested(const E& e); 754684ddb6SLionel Sambuc 764684ddb6SLionel Sambuc} // std 774684ddb6SLionel Sambuc 784684ddb6SLionel Sambuc*/ 794684ddb6SLionel Sambuc 804684ddb6SLionel Sambuc#include <__config> 814684ddb6SLionel Sambuc#include <cstddef> 824684ddb6SLionel Sambuc#include <type_traits> 834684ddb6SLionel Sambuc 844684ddb6SLionel Sambuc#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) 854684ddb6SLionel Sambuc#pragma GCC system_header 864684ddb6SLionel Sambuc#endif 874684ddb6SLionel Sambuc 884684ddb6SLionel Sambucnamespace std // purposefully not using versioning namespace 894684ddb6SLionel Sambuc{ 904684ddb6SLionel Sambuc 914684ddb6SLionel Sambucclass _LIBCPP_EXCEPTION_ABI exception 924684ddb6SLionel Sambuc{ 934684ddb6SLionel Sambucpublic: 944684ddb6SLionel Sambuc _LIBCPP_INLINE_VISIBILITY exception() _NOEXCEPT {} 954684ddb6SLionel Sambuc virtual ~exception() _NOEXCEPT; 964684ddb6SLionel Sambuc virtual const char* what() const _NOEXCEPT; 974684ddb6SLionel Sambuc}; 984684ddb6SLionel Sambuc 994684ddb6SLionel Sambucclass _LIBCPP_EXCEPTION_ABI bad_exception 1004684ddb6SLionel Sambuc : public exception 1014684ddb6SLionel Sambuc{ 1024684ddb6SLionel Sambucpublic: 1034684ddb6SLionel Sambuc _LIBCPP_INLINE_VISIBILITY bad_exception() _NOEXCEPT {} 1044684ddb6SLionel Sambuc virtual ~bad_exception() _NOEXCEPT; 1054684ddb6SLionel Sambuc virtual const char* what() const _NOEXCEPT; 1064684ddb6SLionel Sambuc}; 1074684ddb6SLionel Sambuc 1084684ddb6SLionel Sambuctypedef void (*unexpected_handler)(); 1094684ddb6SLionel Sambuc_LIBCPP_FUNC_VIS unexpected_handler set_unexpected(unexpected_handler) _NOEXCEPT; 1104684ddb6SLionel Sambuc_LIBCPP_FUNC_VIS unexpected_handler get_unexpected() _NOEXCEPT; 1114684ddb6SLionel Sambuc_LIBCPP_NORETURN _LIBCPP_FUNC_VIS void unexpected(); 1124684ddb6SLionel Sambuc 1134684ddb6SLionel Sambuctypedef void (*terminate_handler)(); 1144684ddb6SLionel Sambuc_LIBCPP_FUNC_VIS terminate_handler set_terminate(terminate_handler) _NOEXCEPT; 1154684ddb6SLionel Sambuc_LIBCPP_FUNC_VIS terminate_handler get_terminate() _NOEXCEPT; 1164684ddb6SLionel Sambuc_LIBCPP_NORETURN _LIBCPP_FUNC_VIS void terminate() _NOEXCEPT; 1174684ddb6SLionel Sambuc 1184684ddb6SLionel Sambuc_LIBCPP_FUNC_VIS bool uncaught_exception() _NOEXCEPT; 119*0a6a1f1dSLionel Sambuc_LIBCPP_FUNC_VIS int uncaught_exceptions() _NOEXCEPT; 1204684ddb6SLionel Sambuc 1214684ddb6SLionel Sambucclass _LIBCPP_TYPE_VIS exception_ptr; 1224684ddb6SLionel Sambuc 1234684ddb6SLionel Sambuc_LIBCPP_FUNC_VIS exception_ptr current_exception() _NOEXCEPT; 1244684ddb6SLionel Sambuc_LIBCPP_NORETURN _LIBCPP_FUNC_VIS void rethrow_exception(exception_ptr); 1254684ddb6SLionel Sambuc 1264684ddb6SLionel Sambucclass _LIBCPP_TYPE_VIS exception_ptr 1274684ddb6SLionel Sambuc{ 1284684ddb6SLionel Sambuc void* __ptr_; 1294684ddb6SLionel Sambucpublic: 1304684ddb6SLionel Sambuc _LIBCPP_INLINE_VISIBILITY exception_ptr() _NOEXCEPT : __ptr_() {} 1314684ddb6SLionel Sambuc _LIBCPP_INLINE_VISIBILITY exception_ptr(nullptr_t) _NOEXCEPT : __ptr_() {} 1324684ddb6SLionel Sambuc exception_ptr(const exception_ptr&) _NOEXCEPT; 1334684ddb6SLionel Sambuc exception_ptr& operator=(const exception_ptr&) _NOEXCEPT; 1344684ddb6SLionel Sambuc ~exception_ptr() _NOEXCEPT; 1354684ddb6SLionel Sambuc 1364684ddb6SLionel Sambuc _LIBCPP_INLINE_VISIBILITY 1374684ddb6SLionel Sambuc _LIBCPP_EXPLICIT 1384684ddb6SLionel Sambuc operator bool() const _NOEXCEPT {return __ptr_ != nullptr;} 1394684ddb6SLionel Sambuc 1404684ddb6SLionel Sambuc friend _LIBCPP_INLINE_VISIBILITY 1414684ddb6SLionel Sambuc bool operator==(const exception_ptr& __x, const exception_ptr& __y) _NOEXCEPT 1424684ddb6SLionel Sambuc {return __x.__ptr_ == __y.__ptr_;} 1434684ddb6SLionel Sambuc friend _LIBCPP_INLINE_VISIBILITY 1444684ddb6SLionel Sambuc bool operator!=(const exception_ptr& __x, const exception_ptr& __y) _NOEXCEPT 1454684ddb6SLionel Sambuc {return !(__x == __y);} 1464684ddb6SLionel Sambuc 1474684ddb6SLionel Sambuc friend _LIBCPP_FUNC_VIS exception_ptr current_exception() _NOEXCEPT; 1484684ddb6SLionel Sambuc friend _LIBCPP_FUNC_VIS void rethrow_exception(exception_ptr); 1494684ddb6SLionel Sambuc}; 1504684ddb6SLionel Sambuc 1514684ddb6SLionel Sambuctemplate<class _Ep> 1524684ddb6SLionel Sambucexception_ptr 1534684ddb6SLionel Sambucmake_exception_ptr(_Ep __e) _NOEXCEPT 1544684ddb6SLionel Sambuc{ 1554684ddb6SLionel Sambuc#ifndef _LIBCPP_NO_EXCEPTIONS 1564684ddb6SLionel Sambuc try 1574684ddb6SLionel Sambuc { 1584684ddb6SLionel Sambuc throw __e; 1594684ddb6SLionel Sambuc } 1604684ddb6SLionel Sambuc catch (...) 1614684ddb6SLionel Sambuc { 1624684ddb6SLionel Sambuc return current_exception(); 1634684ddb6SLionel Sambuc } 1644684ddb6SLionel Sambuc#endif // _LIBCPP_NO_EXCEPTIONS 1654684ddb6SLionel Sambuc} 1664684ddb6SLionel Sambuc 1674684ddb6SLionel Sambuc// nested_exception 1684684ddb6SLionel Sambuc 1694684ddb6SLionel Sambucclass _LIBCPP_EXCEPTION_ABI nested_exception 1704684ddb6SLionel Sambuc{ 1714684ddb6SLionel Sambuc exception_ptr __ptr_; 1724684ddb6SLionel Sambucpublic: 1734684ddb6SLionel Sambuc nested_exception() _NOEXCEPT; 1744684ddb6SLionel Sambuc// nested_exception(const nested_exception&) noexcept = default; 1754684ddb6SLionel Sambuc// nested_exception& operator=(const nested_exception&) noexcept = default; 1764684ddb6SLionel Sambuc virtual ~nested_exception() _NOEXCEPT; 1774684ddb6SLionel Sambuc 1784684ddb6SLionel Sambuc // access functions 1794684ddb6SLionel Sambuc _LIBCPP_NORETURN void rethrow_nested() const; 1804684ddb6SLionel Sambuc _LIBCPP_INLINE_VISIBILITY exception_ptr nested_ptr() const _NOEXCEPT {return __ptr_;} 1814684ddb6SLionel Sambuc}; 1824684ddb6SLionel Sambuc 1834684ddb6SLionel Sambuctemplate <class _Tp> 1844684ddb6SLionel Sambucstruct __nested 1854684ddb6SLionel Sambuc : public _Tp, 1864684ddb6SLionel Sambuc public nested_exception 1874684ddb6SLionel Sambuc{ 1884684ddb6SLionel Sambuc _LIBCPP_INLINE_VISIBILITY explicit __nested(const _Tp& __t) : _Tp(__t) {} 1894684ddb6SLionel Sambuc}; 1904684ddb6SLionel Sambuc 1914684ddb6SLionel Sambuctemplate <class _Tp> 1924684ddb6SLionel Sambuc_LIBCPP_NORETURN 1934684ddb6SLionel Sambucvoid 1944684ddb6SLionel Sambuc#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES 1954684ddb6SLionel Sambucthrow_with_nested(_Tp&& __t, typename enable_if< 1964684ddb6SLionel Sambuc is_class<typename remove_reference<_Tp>::type>::value && 1974684ddb6SLionel Sambuc !is_base_of<nested_exception, typename remove_reference<_Tp>::type>::value 198*0a6a1f1dSLionel Sambuc && !__libcpp_is_final<typename remove_reference<_Tp>::type>::value 1994684ddb6SLionel Sambuc >::type* = 0) 2004684ddb6SLionel Sambuc#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES 2014684ddb6SLionel Sambucthrow_with_nested (_Tp& __t, typename enable_if< 2024684ddb6SLionel Sambuc is_class<_Tp>::value && !is_base_of<nested_exception, _Tp>::value 2034684ddb6SLionel Sambuc >::type* = 0) 2044684ddb6SLionel Sambuc#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES 2054684ddb6SLionel Sambuc{ 2064684ddb6SLionel Sambuc#ifndef _LIBCPP_NO_EXCEPTIONS 2074684ddb6SLionel Sambuc throw __nested<typename remove_reference<_Tp>::type>(_VSTD::forward<_Tp>(__t)); 2084684ddb6SLionel Sambuc#endif 2094684ddb6SLionel Sambuc} 2104684ddb6SLionel Sambuc 2114684ddb6SLionel Sambuctemplate <class _Tp> 2124684ddb6SLionel Sambuc_LIBCPP_NORETURN 2134684ddb6SLionel Sambucvoid 2144684ddb6SLionel Sambuc#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES 2154684ddb6SLionel Sambucthrow_with_nested(_Tp&& __t, typename enable_if< 2164684ddb6SLionel Sambuc !is_class<typename remove_reference<_Tp>::type>::value || 2174684ddb6SLionel Sambuc is_base_of<nested_exception, typename remove_reference<_Tp>::type>::value 218*0a6a1f1dSLionel Sambuc || __libcpp_is_final<typename remove_reference<_Tp>::type>::value 2194684ddb6SLionel Sambuc >::type* = 0) 2204684ddb6SLionel Sambuc#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES 2214684ddb6SLionel Sambucthrow_with_nested (_Tp& __t, typename enable_if< 2224684ddb6SLionel Sambuc !is_class<_Tp>::value || is_base_of<nested_exception, _Tp>::value 2234684ddb6SLionel Sambuc >::type* = 0) 2244684ddb6SLionel Sambuc#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES 2254684ddb6SLionel Sambuc{ 2264684ddb6SLionel Sambuc#ifndef _LIBCPP_NO_EXCEPTIONS 2274684ddb6SLionel Sambuc throw _VSTD::forward<_Tp>(__t); 2284684ddb6SLionel Sambuc#endif 2294684ddb6SLionel Sambuc} 2304684ddb6SLionel Sambuc 2314684ddb6SLionel Sambuctemplate <class _Ep> 2324684ddb6SLionel Sambucinline _LIBCPP_INLINE_VISIBILITY 2334684ddb6SLionel Sambucvoid 2344684ddb6SLionel Sambucrethrow_if_nested(const _Ep& __e, typename enable_if< 2354684ddb6SLionel Sambuc is_polymorphic<_Ep>::value 2364684ddb6SLionel Sambuc >::type* = 0) 2374684ddb6SLionel Sambuc{ 2384684ddb6SLionel Sambuc const nested_exception* __nep = dynamic_cast<const nested_exception*>(&__e); 2394684ddb6SLionel Sambuc if (__nep) 2404684ddb6SLionel Sambuc __nep->rethrow_nested(); 2414684ddb6SLionel Sambuc} 2424684ddb6SLionel Sambuc 2434684ddb6SLionel Sambuctemplate <class _Ep> 2444684ddb6SLionel Sambucinline _LIBCPP_INLINE_VISIBILITY 2454684ddb6SLionel Sambucvoid 2464684ddb6SLionel Sambucrethrow_if_nested(const _Ep&, typename enable_if< 2474684ddb6SLionel Sambuc !is_polymorphic<_Ep>::value 2484684ddb6SLionel Sambuc >::type* = 0) 2494684ddb6SLionel Sambuc{ 2504684ddb6SLionel Sambuc} 2514684ddb6SLionel Sambuc 2524684ddb6SLionel Sambuc} // std 2534684ddb6SLionel Sambuc 2544684ddb6SLionel Sambuc#endif // _LIBCPP_EXCEPTION 255