exception revision 300770
1227825Stheraven// -*- C++ -*- 2227825Stheraven//===-------------------------- exception ---------------------------------===// 3227825Stheraven// 4227825Stheraven// The LLVM Compiler Infrastructure 5227825Stheraven// 6227825Stheraven// This file is dual licensed under the MIT and the University of Illinois Open 7227825Stheraven// Source Licenses. See LICENSE.TXT for details. 8227825Stheraven// 9227825Stheraven//===----------------------------------------------------------------------===// 10227825Stheraven 11227825Stheraven#ifndef _LIBCPP_EXCEPTION 12227825Stheraven#define _LIBCPP_EXCEPTION 13227825Stheraven 14227825Stheraven/* 15227825Stheraven exception synopsis 16227825Stheraven 17227825Stheravennamespace std 18227825Stheraven{ 19227825Stheraven 20227825Stheravenclass exception 21227825Stheraven{ 22227825Stheravenpublic: 23227825Stheraven exception() noexcept; 24227825Stheraven exception(const exception&) noexcept; 25227825Stheraven exception& operator=(const exception&) noexcept; 26227825Stheraven virtual ~exception() noexcept; 27227825Stheraven virtual const char* what() const noexcept; 28227825Stheraven}; 29227825Stheraven 30227825Stheravenclass bad_exception 31227825Stheraven : public exception 32227825Stheraven{ 33227825Stheravenpublic: 34227825Stheraven bad_exception() noexcept; 35227825Stheraven bad_exception(const bad_exception&) noexcept; 36227825Stheraven bad_exception& operator=(const bad_exception&) noexcept; 37227825Stheraven virtual ~bad_exception() noexcept; 38227825Stheraven virtual const char* what() const noexcept; 39227825Stheraven}; 40227825Stheraven 41227825Stheraventypedef void (*unexpected_handler)(); 42227825Stheravenunexpected_handler set_unexpected(unexpected_handler f ) noexcept; 43227825Stheravenunexpected_handler get_unexpected() noexcept; 44227825Stheraven[[noreturn]] void unexpected(); 45227825Stheraven 46227825Stheraventypedef void (*terminate_handler)(); 47227825Stheraventerminate_handler set_terminate(terminate_handler f ) noexcept; 48227825Stheraventerminate_handler get_terminate() noexcept; 49227825Stheraven[[noreturn]] void terminate() noexcept; 50227825Stheraven 51288943Sdimbool uncaught_exception() noexcept; 52288943Sdimint uncaught_exceptions() noexcept; // C++17 53227825Stheraven 54227825Stheraventypedef unspecified exception_ptr; 55227825Stheraven 56227825Stheravenexception_ptr current_exception() noexcept; 57227825Stheravenvoid rethrow_exception [[noreturn]] (exception_ptr p); 58227825Stheraventemplate<class E> exception_ptr make_exception_ptr(E e) noexcept; 59227825Stheraven 60227825Stheravenclass nested_exception 61227825Stheraven{ 62227825Stheravenpublic: 63227825Stheraven nested_exception() noexcept; 64227825Stheraven nested_exception(const nested_exception&) noexcept = default; 65227825Stheraven nested_exception& operator=(const nested_exception&) noexcept = default; 66227825Stheraven virtual ~nested_exception() = default; 67227825Stheraven 68227825Stheraven // access functions 69227825Stheraven [[noreturn]] void rethrow_nested() const; 70227825Stheraven exception_ptr nested_ptr() const noexcept; 71227825Stheraven}; 72227825Stheraven 73227825Stheraventemplate <class T> [[noreturn]] void throw_with_nested(T&& t); 74227825Stheraventemplate <class E> void rethrow_if_nested(const E& e); 75227825Stheraven 76227825Stheraven} // std 77227825Stheraven 78227825Stheraven*/ 79227825Stheraven 80227825Stheraven#include <__config> 81227825Stheraven#include <cstddef> 82227825Stheraven#include <type_traits> 83227825Stheraven 84227825Stheraven#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) 85227825Stheraven#pragma GCC system_header 86227825Stheraven#endif 87227825Stheraven 88227825Stheravennamespace std // purposefully not using versioning namespace 89227825Stheraven{ 90227825Stheraven 91227825Stheravenclass _LIBCPP_EXCEPTION_ABI exception 92227825Stheraven{ 93227825Stheravenpublic: 94227825Stheraven _LIBCPP_INLINE_VISIBILITY exception() _NOEXCEPT {} 95227825Stheraven virtual ~exception() _NOEXCEPT; 96227825Stheraven virtual const char* what() const _NOEXCEPT; 97227825Stheraven}; 98227825Stheraven 99227825Stheravenclass _LIBCPP_EXCEPTION_ABI bad_exception 100227825Stheraven : public exception 101227825Stheraven{ 102227825Stheravenpublic: 103227825Stheraven _LIBCPP_INLINE_VISIBILITY bad_exception() _NOEXCEPT {} 104227825Stheraven virtual ~bad_exception() _NOEXCEPT; 105227825Stheraven virtual const char* what() const _NOEXCEPT; 106227825Stheraven}; 107227825Stheraven 108227825Stheraventypedef void (*unexpected_handler)(); 109249989Sdim_LIBCPP_FUNC_VIS unexpected_handler set_unexpected(unexpected_handler) _NOEXCEPT; 110249989Sdim_LIBCPP_FUNC_VIS unexpected_handler get_unexpected() _NOEXCEPT; 111249989Sdim_LIBCPP_NORETURN _LIBCPP_FUNC_VIS void unexpected(); 112227825Stheraven 113227825Stheraventypedef void (*terminate_handler)(); 114249989Sdim_LIBCPP_FUNC_VIS terminate_handler set_terminate(terminate_handler) _NOEXCEPT; 115249989Sdim_LIBCPP_FUNC_VIS terminate_handler get_terminate() _NOEXCEPT; 116249989Sdim_LIBCPP_NORETURN _LIBCPP_FUNC_VIS void terminate() _NOEXCEPT; 117227825Stheraven 118249989Sdim_LIBCPP_FUNC_VIS bool uncaught_exception() _NOEXCEPT; 119288943Sdim_LIBCPP_FUNC_VIS int uncaught_exceptions() _NOEXCEPT; 120227825Stheraven 121249989Sdimclass _LIBCPP_TYPE_VIS exception_ptr; 122227825Stheraven 123261272Sdim_LIBCPP_FUNC_VIS exception_ptr current_exception() _NOEXCEPT; 124261272Sdim_LIBCPP_NORETURN _LIBCPP_FUNC_VIS void rethrow_exception(exception_ptr); 125227825Stheraven 126249989Sdimclass _LIBCPP_TYPE_VIS exception_ptr 127227825Stheraven{ 128227825Stheraven void* __ptr_; 129227825Stheravenpublic: 130227825Stheraven _LIBCPP_INLINE_VISIBILITY exception_ptr() _NOEXCEPT : __ptr_() {} 131227825Stheraven _LIBCPP_INLINE_VISIBILITY exception_ptr(nullptr_t) _NOEXCEPT : __ptr_() {} 132227825Stheraven exception_ptr(const exception_ptr&) _NOEXCEPT; 133227825Stheraven exception_ptr& operator=(const exception_ptr&) _NOEXCEPT; 134227825Stheraven ~exception_ptr() _NOEXCEPT; 135227825Stheraven 136227825Stheraven _LIBCPP_INLINE_VISIBILITY 137232924Stheraven _LIBCPP_EXPLICIT 138227825Stheraven operator bool() const _NOEXCEPT {return __ptr_ != nullptr;} 139227825Stheraven 140227825Stheraven friend _LIBCPP_INLINE_VISIBILITY 141227825Stheraven bool operator==(const exception_ptr& __x, const exception_ptr& __y) _NOEXCEPT 142227825Stheraven {return __x.__ptr_ == __y.__ptr_;} 143227825Stheraven friend _LIBCPP_INLINE_VISIBILITY 144227825Stheraven bool operator!=(const exception_ptr& __x, const exception_ptr& __y) _NOEXCEPT 145227825Stheraven {return !(__x == __y);} 146227825Stheraven 147261272Sdim friend _LIBCPP_FUNC_VIS exception_ptr current_exception() _NOEXCEPT; 148261272Sdim friend _LIBCPP_FUNC_VIS void rethrow_exception(exception_ptr); 149227825Stheraven}; 150227825Stheraven 151232924Stheraventemplate<class _Ep> 152227825Stheravenexception_ptr 153232924Stheravenmake_exception_ptr(_Ep __e) _NOEXCEPT 154227825Stheraven{ 155227825Stheraven#ifndef _LIBCPP_NO_EXCEPTIONS 156227825Stheraven try 157227825Stheraven { 158227825Stheraven throw __e; 159227825Stheraven } 160227825Stheraven catch (...) 161227825Stheraven { 162227825Stheraven return current_exception(); 163227825Stheraven } 164227825Stheraven#endif // _LIBCPP_NO_EXCEPTIONS 165227825Stheraven} 166227825Stheraven 167227825Stheraven// nested_exception 168227825Stheraven 169227825Stheravenclass _LIBCPP_EXCEPTION_ABI nested_exception 170227825Stheraven{ 171227825Stheraven exception_ptr __ptr_; 172227825Stheravenpublic: 173227825Stheraven nested_exception() _NOEXCEPT; 174227825Stheraven// nested_exception(const nested_exception&) noexcept = default; 175227825Stheraven// nested_exception& operator=(const nested_exception&) noexcept = default; 176227825Stheraven virtual ~nested_exception() _NOEXCEPT; 177227825Stheraven 178227825Stheraven // access functions 179241900Sdim _LIBCPP_NORETURN void rethrow_nested() const; 180227825Stheraven _LIBCPP_INLINE_VISIBILITY exception_ptr nested_ptr() const _NOEXCEPT {return __ptr_;} 181227825Stheraven}; 182227825Stheraven 183227825Stheraventemplate <class _Tp> 184227825Stheravenstruct __nested 185227825Stheraven : public _Tp, 186227825Stheraven public nested_exception 187227825Stheraven{ 188227825Stheraven _LIBCPP_INLINE_VISIBILITY explicit __nested(const _Tp& __t) : _Tp(__t) {} 189227825Stheraven}; 190227825Stheraven 191227825Stheraventemplate <class _Tp> 192241900Sdim_LIBCPP_NORETURN 193227825Stheravenvoid 194227825Stheraven#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES 195227825Stheraventhrow_with_nested(_Tp&& __t, typename enable_if< 196227825Stheraven is_class<typename remove_reference<_Tp>::type>::value && 197227825Stheraven !is_base_of<nested_exception, typename remove_reference<_Tp>::type>::value 198288943Sdim && !__libcpp_is_final<typename remove_reference<_Tp>::type>::value 199227825Stheraven >::type* = 0) 200227825Stheraven#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES 201227825Stheraventhrow_with_nested (_Tp& __t, typename enable_if< 202227825Stheraven is_class<_Tp>::value && !is_base_of<nested_exception, _Tp>::value 203227825Stheraven >::type* = 0) 204227825Stheraven#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES 205227825Stheraven{ 206227825Stheraven#ifndef _LIBCPP_NO_EXCEPTIONS 207227825Stheraven throw __nested<typename remove_reference<_Tp>::type>(_VSTD::forward<_Tp>(__t)); 208227825Stheraven#endif 209227825Stheraven} 210227825Stheraven 211227825Stheraventemplate <class _Tp> 212241900Sdim_LIBCPP_NORETURN 213227825Stheravenvoid 214227825Stheraven#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES 215227825Stheraventhrow_with_nested(_Tp&& __t, typename enable_if< 216227825Stheraven !is_class<typename remove_reference<_Tp>::type>::value || 217227825Stheraven is_base_of<nested_exception, typename remove_reference<_Tp>::type>::value 218288943Sdim || __libcpp_is_final<typename remove_reference<_Tp>::type>::value 219227825Stheraven >::type* = 0) 220227825Stheraven#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES 221227825Stheraventhrow_with_nested (_Tp& __t, typename enable_if< 222227825Stheraven !is_class<_Tp>::value || is_base_of<nested_exception, _Tp>::value 223227825Stheraven >::type* = 0) 224227825Stheraven#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES 225227825Stheraven{ 226227825Stheraven#ifndef _LIBCPP_NO_EXCEPTIONS 227227825Stheraven throw _VSTD::forward<_Tp>(__t); 228227825Stheraven#endif 229227825Stheraven} 230227825Stheraven 231232924Stheraventemplate <class _Ep> 232227825Stheraveninline _LIBCPP_INLINE_VISIBILITY 233227825Stheravenvoid 234232924Stheravenrethrow_if_nested(const _Ep& __e, typename enable_if< 235232924Stheraven is_polymorphic<_Ep>::value 236227825Stheraven >::type* = 0) 237227825Stheraven{ 238300770Sdim const nested_exception* __nep = dynamic_cast<const nested_exception*>(_VSTD::addressof(__e)); 239227825Stheraven if (__nep) 240227825Stheraven __nep->rethrow_nested(); 241227825Stheraven} 242227825Stheraven 243232924Stheraventemplate <class _Ep> 244227825Stheraveninline _LIBCPP_INLINE_VISIBILITY 245227825Stheravenvoid 246232924Stheravenrethrow_if_nested(const _Ep&, typename enable_if< 247232924Stheraven !is_polymorphic<_Ep>::value 248227825Stheraven >::type* = 0) 249227825Stheraven{ 250227825Stheraven} 251227825Stheraven 252227825Stheraven} // std 253227825Stheraven 254227825Stheraven#endif // _LIBCPP_EXCEPTION 255