diff options
Diffstat (limited to 'libcxx/include/exception')
-rw-r--r-- | libcxx/include/exception | 78 |
1 files changed, 78 insertions, 0 deletions
diff --git a/libcxx/include/exception b/libcxx/include/exception index 82fdbb1a37c..600b54838b2 100644 --- a/libcxx/include/exception +++ b/libcxx/include/exception @@ -76,6 +76,7 @@ template <class E> void rethrow_if_nested(const E& e); #include <__config> #include <cstddef> +#include <type_traits> #pragma GCC system_header @@ -150,6 +151,83 @@ make_exception_ptr(_E __e) } } +// 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 +throw_with_nested (_Tp& __t, typename enable_if< + is_class<_Tp>::value && !is_base_of<nested_exception, _Tp>::value + >::type* = 0) +#endif +{ + throw __nested<typename remove_reference<_Tp>::type>(_STD::forward<_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 +throw_with_nested (_Tp& __t, typename enable_if< + !is_class<_Tp>::value || is_base_of<nested_exception, _Tp>::value + >::type* = 0) +#endif +{ + throw _STD::forward<_Tp>(__t); +} + +template <class _E> +inline +void +rethrow_if_nested(const _E& __e, typename enable_if< + !is_same<_E, nested_exception>::value && + is_convertible<_E*, nested_exception*>::value + >::type* = 0) +{ + static_cast<const nested_exception&>(__e).rethrow_nested(); +} + +template <class _E> +inline +void +rethrow_if_nested(const _E& __e, typename enable_if< + is_same<_E, nested_exception>::value || + !is_convertible<_E*, nested_exception*>::value + >::type* = 0) +{ +} + } // std #endif // _LIBCPP_EXCEPTION |