// -*- C++ -*- //===-------------------------- exception ---------------------------------===// // // The LLVM Compiler Infrastructure // // This file is dual licensed under the MIT and the University of Illinois Open // Source Licenses. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// #ifndef _LIBCPP_EXCEPTION #define _LIBCPP_EXCEPTION /* exception synopsis namespace std { class exception { public: exception() noexcept; exception(const exception&) noexcept; exception& operator=(const exception&) noexcept; virtual ~exception() noexcept; virtual const char* what() const noexcept; }; class bad_exception : public exception { public: bad_exception() noexcept; bad_exception(const bad_exception&) noexcept; bad_exception& operator=(const bad_exception&) noexcept; virtual ~bad_exception() noexcept; virtual const char* what() const noexcept; }; typedef void (*unexpected_handler)(); unexpected_handler set_unexpected(unexpected_handler f ) noexcept; unexpected_handler get_unexpected() noexcept; [[noreturn]] void unexpected(); typedef void (*terminate_handler)(); terminate_handler set_terminate(terminate_handler f ) noexcept; terminate_handler get_terminate() noexcept; [[noreturn]] void terminate() noexcept; bool uncaught_exception() noexcept; typedef unspecified exception_ptr; exception_ptr current_exception() noexcept; void rethrow_exception [[noreturn]] (exception_ptr p); template exception_ptr make_exception_ptr(E e) noexcept; class nested_exception { public: nested_exception() noexcept; nested_exception(const nested_exception&) noexcept = default; nested_exception& operator=(const nested_exception&) noexcept = default; virtual ~nested_exception() = default; // access functions [[noreturn]] void rethrow_nested() const; exception_ptr nested_ptr() const noexcept; }; template [[noreturn]] void throw_with_nested(T&& t); template void rethrow_if_nested(const E& e); } // std */ #include <__config> #include #include #pragma GCC system_header namespace std // purposefully not using versioning namespace { class _LIBCPP_EXCEPTION_ABI exception { public: _LIBCPP_INLINE_VISIBILITY exception() _NOEXCEPT {} virtual ~exception() _NOEXCEPT; virtual const char* what() const _NOEXCEPT; }; class _LIBCPP_EXCEPTION_ABI bad_exception : public exception { public: _LIBCPP_INLINE_VISIBILITY bad_exception() _NOEXCEPT {} virtual ~bad_exception() _NOEXCEPT; virtual const char* what() const _NOEXCEPT; }; typedef void (*unexpected_handler)(); _LIBCPP_VISIBLE unexpected_handler set_unexpected(unexpected_handler) _NOEXCEPT; _LIBCPP_VISIBLE unexpected_handler get_unexpected() _NOEXCEPT; _ATTRIBUTE(noreturn) _LIBCPP_VISIBLE void unexpected(); typedef void (*terminate_handler)(); _LIBCPP_VISIBLE terminate_handler set_terminate(terminate_handler) _NOEXCEPT; _LIBCPP_VISIBLE terminate_handler get_terminate() _NOEXCEPT; _ATTRIBUTE(noreturn) _LIBCPP_VISIBLE void terminate() _NOEXCEPT; _LIBCPP_VISIBLE bool uncaught_exception() _NOEXCEPT; class exception_ptr; exception_ptr current_exception() _NOEXCEPT; _ATTRIBUTE(noreturn) void rethrow_exception(exception_ptr); class _LIBCPP_VISIBLE exception_ptr { void* __ptr_; public: _LIBCPP_INLINE_VISIBILITY exception_ptr() _NOEXCEPT : __ptr_() {} _LIBCPP_INLINE_VISIBILITY exception_ptr(nullptr_t) _NOEXCEPT : __ptr_() {} exception_ptr(const exception_ptr&) _NOEXCEPT; exception_ptr& operator=(const exception_ptr&) _NOEXCEPT; ~exception_ptr() _NOEXCEPT; _LIBCPP_INLINE_VISIBILITY // explicit operator bool() const _NOEXCEPT {return __ptr_ != nullptr;} friend _LIBCPP_INLINE_VISIBILITY bool operator==(const exception_ptr& __x, const exception_ptr& __y) _NOEXCEPT {return __x.__ptr_ == __y.__ptr_;} friend _LIBCPP_INLINE_VISIBILITY bool operator!=(const exception_ptr& __x, const exception_ptr& __y) _NOEXCEPT {return !(__x == __y);} friend exception_ptr current_exception() _NOEXCEPT; _ATTRIBUTE(noreturn) friend void rethrow_exception(exception_ptr); }; template exception_ptr make_exception_ptr(_E __e) _NOEXCEPT { #ifndef _LIBCPP_NO_EXCEPTIONS try { throw __e; } catch (...) { return current_exception(); } #endif // _LIBCPP_NO_EXCEPTIONS } // nested_exception class _LIBCPP_EXCEPTION_ABI nested_exception { exception_ptr __ptr_; public: nested_exception() _NOEXCEPT; // nested_exception(const nested_exception&) noexcept = default; // nested_exception& operator=(const nested_exception&) noexcept = default; virtual ~nested_exception() _NOEXCEPT; // access functions _ATTRIBUTE(noreturn) void rethrow_nested() const; _LIBCPP_INLINE_VISIBILITY exception_ptr nested_ptr() const _NOEXCEPT {return __ptr_;} }; template struct __nested : public _Tp, public nested_exception { _LIBCPP_INLINE_VISIBILITY explicit __nested(const _Tp& __t) : _Tp(__t) {} }; template _ATTRIBUTE(noreturn) void #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES throw_with_nested(_Tp&& __t, typename enable_if< is_class::type>::value && !is_base_of::type>::value >::type* = 0) #else // _LIBCPP_HAS_NO_RVALUE_REFERENCES throw_with_nested (_Tp& __t, typename enable_if< is_class<_Tp>::value && !is_base_of::value >::type* = 0) #endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES { #ifndef _LIBCPP_NO_EXCEPTIONS throw __nested::type>(_STD::forward<_Tp>(__t)); #endif } template _ATTRIBUTE(noreturn) void #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES throw_with_nested(_Tp&& __t, typename enable_if< !is_class::type>::value || is_base_of::type>::value >::type* = 0) #else // _LIBCPP_HAS_NO_RVALUE_REFERENCES throw_with_nested (_Tp& __t, typename enable_if< !is_class<_Tp>::value || is_base_of::value >::type* = 0) #endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES { #ifndef _LIBCPP_NO_EXCEPTIONS throw _STD::forward<_Tp>(__t); #endif } template inline _LIBCPP_INLINE_VISIBILITY void rethrow_if_nested(const _E& __e, typename enable_if< is_polymorphic<_E>::value >::type* = 0) { const nested_exception* __nep = dynamic_cast(&__e); if (__nep) __nep->rethrow_nested(); } template inline _LIBCPP_INLINE_VISIBILITY void rethrow_if_nested(const _E& __e, typename enable_if< !is_polymorphic<_E>::value >::type* = 0) { } } // std #endif // _LIBCPP_EXCEPTION