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