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() throw(); 24 exception(const exception&) throw(); 25 exception& operator=(const exception&) throw(); 26 virtual ~exception() throw(); 27 virtual const char* what() const throw(); 28}; 29 30class bad_exception 31 : public exception 32{ 33public: 34 bad_exception() throw(); 35 bad_exception(const bad_exception&) throw(); 36 bad_exception& operator=(const bad_exception&) throw(); 37 virtual ~bad_exception() throw(); 38 virtual const char* what() const throw(); 39}; 40 41typedef void (*unexpected_handler)(); 42unexpected_handler set_unexpected(unexpected_handler f ) throw(); 43unexpected_handler get_unexpected() throw(); 44void unexpected [[noreturn]] (); 45 46typedef void (*terminate_handler)(); 47terminate_handler set_terminate(terminate_handler f ) throw(); 48terminate_handler get_terminate() throw(); 49void terminate [[noreturn]] (); 50 51bool uncaught_exception() throw(); 52 53typedef unspecified exception_ptr; 54 55exception_ptr current_exception(); 56void rethrow_exception [[noreturn]] (exception_ptr p); 57template<class E> exception_ptr make_exception_ptr(E e); 58 59class nested_exception 60{ 61public: 62 nested_exception() throw(); 63 nested_exception(const nested_exception&) throw() = default; 64 nested_exception& operator=(const nested_exception&) throw() = default; 65 virtual ~nested_exception() = default; 66 67 // access functions 68 void rethrow_nested [[noreturn]] () const; 69 exception_ptr nested_ptr() const; 70}; 71 72template <class T> void throw_with_nested [[noreturn]] (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() throw() {} 92 virtual ~exception() throw(); 93 virtual const char* what() const throw(); 94}; 95 96class _LIBCPP_EXCEPTION_ABI bad_exception 97 : public exception 98{ 99public: 100 _LIBCPP_INLINE_VISIBILITY bad_exception() throw() {} 101 virtual ~bad_exception() throw(); 102 virtual const char* what() const throw(); 103}; 104 105typedef void (*unexpected_handler)(); 106_LIBCPP_VISIBLE unexpected_handler set_unexpected(unexpected_handler) throw(); 107_LIBCPP_VISIBLE unexpected_handler get_unexpected() throw(); 108_LIBCPP_VISIBLE void unexpected(); 109 110typedef void (*terminate_handler)(); 111_LIBCPP_VISIBLE terminate_handler set_terminate(terminate_handler) throw(); 112_LIBCPP_VISIBLE terminate_handler get_terminate() throw(); 113_LIBCPP_VISIBLE void terminate() __attribute__((__noreturn__)); 114 115_LIBCPP_VISIBLE bool uncaught_exception() throw(); 116 117class exception_ptr; 118 119exception_ptr current_exception(); 120void rethrow_exception(exception_ptr); // noreturn 121 122class _LIBCPP_VISIBLE exception_ptr 123{ 124 void* __ptr_; 125public: 126 _LIBCPP_INLINE_VISIBILITY exception_ptr() : __ptr_() {} 127 _LIBCPP_INLINE_VISIBILITY exception_ptr(nullptr_t) : __ptr_() {} 128 exception_ptr(const exception_ptr&); 129 exception_ptr& operator=(const exception_ptr&); 130 ~exception_ptr(); 131 132 _LIBCPP_INLINE_VISIBILITY 133 // explicit 134 operator bool() const {return __ptr_ != nullptr;} 135 136 friend _LIBCPP_INLINE_VISIBILITY 137 bool operator==(const exception_ptr& __x, const exception_ptr& __y) 138 {return __x.__ptr_ == __y.__ptr_;} 139 friend _LIBCPP_INLINE_VISIBILITY 140 bool operator!=(const exception_ptr& __x, const exception_ptr& __y) 141 {return !(__x == __y);} 142 143 friend exception_ptr current_exception(); 144 friend void rethrow_exception(exception_ptr); // noreturn 145}; 146 147template<class _E> 148exception_ptr 149make_exception_ptr(_E __e) 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(); 170// nested_exception(const nested_exception&) throw() = default; 171// nested_exception& operator=(const nested_exception&) throw() = default; 172 virtual ~nested_exception(); 173 174 // access functions 175 void rethrow_nested /*[[noreturn]]*/ () const; 176 _LIBCPP_INLINE_VISIBILITY exception_ptr nested_ptr() const {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> 188void 189#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES 190throw_with_nested /*[[noreturn]]*/ (_Tp&& __t, typename enable_if< 191 is_class<typename remove_reference<_Tp>::type>::value && 192 !is_base_of<nested_exception, typename remove_reference<_Tp>::type>::value 193 >::type* = 0) 194#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES 195throw_with_nested (_Tp& __t, typename enable_if< 196 is_class<_Tp>::value && !is_base_of<nested_exception, _Tp>::value 197 >::type* = 0) 198#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES 199{ 200#ifndef _LIBCPP_NO_EXCEPTIONS 201 throw __nested<typename remove_reference<_Tp>::type>(_STD::forward<_Tp>(__t)); 202#endif 203} 204 205template <class _Tp> 206void 207#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES 208throw_with_nested /*[[noreturn]]*/ (_Tp&& __t, typename enable_if< 209 !is_class<typename remove_reference<_Tp>::type>::value || 210 is_base_of<nested_exception, typename remove_reference<_Tp>::type>::value 211 >::type* = 0) 212#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES 213throw_with_nested (_Tp& __t, typename enable_if< 214 !is_class<_Tp>::value || is_base_of<nested_exception, _Tp>::value 215 >::type* = 0) 216#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES 217{ 218#ifndef _LIBCPP_NO_EXCEPTIONS 219 throw _STD::forward<_Tp>(__t); 220#endif 221} 222 223template <class _E> 224inline _LIBCPP_INLINE_VISIBILITY 225void 226rethrow_if_nested(const _E& __e, typename enable_if< 227 is_polymorphic<_E>::value 228 >::type* = 0) 229{ 230 const nested_exception* __nep = dynamic_cast<const nested_exception*>(&__e); 231 if (__nep) 232 __nep->rethrow_nested(); 233} 234 235template <class _E> 236inline _LIBCPP_INLINE_VISIBILITY 237void 238rethrow_if_nested(const _E& __e, typename enable_if< 239 !is_polymorphic<_E>::value 240 >::type* = 0) 241{ 242} 243 244} // std 245 246#endif // _LIBCPP_EXCEPTION 247