1// -*- C++ -*- 2//===-------------------------- exception ---------------------------------===// 3// 4// The LLVM Compiler Infrastructure 5// 6// This file is dual licensed under the MIT and the University of Illinois Open 7// Source Licenses. See LICENSE.TXT for details. 8// 9//===----------------------------------------------------------------------===// 10 11#ifndef _LIBCPP_EXCEPTION 12#define _LIBCPP_EXCEPTION 13 14/* 15 exception synopsis 16 17namespace std 18{ 19 20class exception 21{ 22public: 23 exception() noexcept; 24 exception(const exception&) noexcept; 25 exception& operator=(const exception&) noexcept; 26 virtual ~exception() noexcept; 27 virtual const char* what() const noexcept; 28}; 29 30class bad_exception 31 : public exception 32{ 33public: 34 bad_exception() noexcept; 35 bad_exception(const bad_exception&) noexcept; 36 bad_exception& operator=(const bad_exception&) noexcept; 37 virtual ~bad_exception() noexcept; 38 virtual const char* what() const noexcept; 39}; 40 41typedef void (*unexpected_handler)(); 42unexpected_handler set_unexpected(unexpected_handler f ) noexcept; 43unexpected_handler get_unexpected() noexcept; 44[[noreturn]] void unexpected(); 45 46typedef void (*terminate_handler)(); 47terminate_handler set_terminate(terminate_handler f ) noexcept; 48terminate_handler get_terminate() noexcept; 49[[noreturn]] void terminate() noexcept; 50 51bool uncaught_exception() noexcept; 52 53typedef unspecified exception_ptr; 54 55exception_ptr current_exception() noexcept; 56void rethrow_exception [[noreturn]] (exception_ptr p); 57template<class E> exception_ptr make_exception_ptr(E e) noexcept; 58 59class nested_exception 60{ 61public: 62 nested_exception() noexcept; 63 nested_exception(const nested_exception&) noexcept = default; 64 nested_exception& operator=(const nested_exception&) noexcept = default; 65 virtual ~nested_exception() = default; 66 67 // access functions 68 [[noreturn]] void rethrow_nested() const; 69 exception_ptr nested_ptr() const noexcept; 70}; 71 72template <class T> [[noreturn]] void throw_with_nested(T&& t); 73template <class E> void rethrow_if_nested(const E& e); 74 75} // std 76 77*/ 78 79#include <__config> 80#include <cstddef> 81#include <type_traits> 82 83#pragma GCC system_header 84 85namespace std // purposefully not using versioning namespace 86{ 87 88class _LIBCPP_EXCEPTION_ABI exception 89{ 90public: 91 _LIBCPP_INLINE_VISIBILITY exception() _NOEXCEPT {} 92 virtual ~exception() _NOEXCEPT; 93 virtual const char* what() const _NOEXCEPT; 94}; 95 96class _LIBCPP_EXCEPTION_ABI bad_exception 97 : public exception 98{ 99public: 100 _LIBCPP_INLINE_VISIBILITY bad_exception() _NOEXCEPT {} 101 virtual ~bad_exception() _NOEXCEPT; 102 virtual const char* what() const _NOEXCEPT; 103}; 104 105typedef void (*unexpected_handler)(); 106_LIBCPP_VISIBLE unexpected_handler set_unexpected(unexpected_handler) _NOEXCEPT; 107_LIBCPP_VISIBLE unexpected_handler get_unexpected() _NOEXCEPT; 108_ATTRIBUTE(noreturn) _LIBCPP_VISIBLE void unexpected(); 109 110typedef void (*terminate_handler)(); 111_LIBCPP_VISIBLE terminate_handler set_terminate(terminate_handler) _NOEXCEPT; 112_LIBCPP_VISIBLE terminate_handler get_terminate() _NOEXCEPT; 113_ATTRIBUTE(noreturn) _LIBCPP_VISIBLE void terminate() _NOEXCEPT; 114 115_LIBCPP_VISIBLE bool uncaught_exception() _NOEXCEPT; 116 117class exception_ptr; 118 119exception_ptr current_exception() _NOEXCEPT; 120_ATTRIBUTE(noreturn) void rethrow_exception(exception_ptr); 121 122class _LIBCPP_VISIBLE exception_ptr 123{ 124 void* __ptr_; 125public: 126 _LIBCPP_INLINE_VISIBILITY exception_ptr() _NOEXCEPT : __ptr_() {} 127 _LIBCPP_INLINE_VISIBILITY exception_ptr(nullptr_t) _NOEXCEPT : __ptr_() {} 128 exception_ptr(const exception_ptr&) _NOEXCEPT; 129 exception_ptr& operator=(const exception_ptr&) _NOEXCEPT; 130 ~exception_ptr() _NOEXCEPT; 131 132 _LIBCPP_INLINE_VISIBILITY 133 // explicit 134 operator bool() const _NOEXCEPT {return __ptr_ != nullptr;} 135 136 friend _LIBCPP_INLINE_VISIBILITY 137 bool operator==(const exception_ptr& __x, const exception_ptr& __y) _NOEXCEPT 138 {return __x.__ptr_ == __y.__ptr_;} 139 friend _LIBCPP_INLINE_VISIBILITY 140 bool operator!=(const exception_ptr& __x, const exception_ptr& __y) _NOEXCEPT 141 {return !(__x == __y);} 142 143 friend exception_ptr current_exception() _NOEXCEPT; 144 _ATTRIBUTE(noreturn) friend void rethrow_exception(exception_ptr); 145}; 146 147template<class _E> 148exception_ptr 149make_exception_ptr(_E __e) _NOEXCEPT 150{ 151#ifndef _LIBCPP_NO_EXCEPTIONS 152 try 153 { 154 throw __e; 155 } 156 catch (...) 157 { 158 return current_exception(); 159 } 160#endif // _LIBCPP_NO_EXCEPTIONS 161} 162 163// nested_exception 164 165class _LIBCPP_EXCEPTION_ABI nested_exception 166{ 167 exception_ptr __ptr_; 168public: 169 nested_exception() _NOEXCEPT; 170// nested_exception(const nested_exception&) noexcept = default; 171// nested_exception& operator=(const nested_exception&) noexcept = default; 172 virtual ~nested_exception() _NOEXCEPT; 173 174 // access functions 175 _ATTRIBUTE(noreturn) void rethrow_nested() const; 176 _LIBCPP_INLINE_VISIBILITY exception_ptr nested_ptr() const _NOEXCEPT {return __ptr_;} 177}; 178 179template <class _Tp> 180struct __nested 181 : public _Tp, 182 public nested_exception 183{ 184 _LIBCPP_INLINE_VISIBILITY explicit __nested(const _Tp& __t) : _Tp(__t) {} 185}; 186 187template <class _Tp> 188_ATTRIBUTE(noreturn) 189void 190#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES 191throw_with_nested(_Tp&& __t, typename enable_if< 192 is_class<typename remove_reference<_Tp>::type>::value && 193 !is_base_of<nested_exception, typename remove_reference<_Tp>::type>::value 194 >::type* = 0) 195#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES 196throw_with_nested (_Tp& __t, typename enable_if< 197 is_class<_Tp>::value && !is_base_of<nested_exception, _Tp>::value 198 >::type* = 0) 199#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES 200{ 201#ifndef _LIBCPP_NO_EXCEPTIONS 202 throw __nested<typename remove_reference<_Tp>::type>(_VSTD::forward<_Tp>(__t)); 203#endif 204} 205 206template <class _Tp> 207_ATTRIBUTE(noreturn) 208void 209#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES 210throw_with_nested(_Tp&& __t, typename enable_if< 211 !is_class<typename remove_reference<_Tp>::type>::value || 212 is_base_of<nested_exception, typename remove_reference<_Tp>::type>::value 213 >::type* = 0) 214#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES 215throw_with_nested (_Tp& __t, typename enable_if< 216 !is_class<_Tp>::value || is_base_of<nested_exception, _Tp>::value 217 >::type* = 0) 218#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES 219{ 220#ifndef _LIBCPP_NO_EXCEPTIONS 221 throw _VSTD::forward<_Tp>(__t); 222#endif 223} 224 225template <class _E> 226inline _LIBCPP_INLINE_VISIBILITY 227void 228rethrow_if_nested(const _E& __e, typename enable_if< 229 is_polymorphic<_E>::value 230 >::type* = 0) 231{ 232 const nested_exception* __nep = dynamic_cast<const nested_exception*>(&__e); 233 if (__nep) 234 __nep->rethrow_nested(); 235} 236 237template <class _E> 238inline _LIBCPP_INLINE_VISIBILITY 239void 240rethrow_if_nested(const _E& __e, typename enable_if< 241 !is_polymorphic<_E>::value 242 >::type* = 0) 243{ 244} 245 246} // std 247 248#endif // _LIBCPP_EXCEPTION 249