Path: blob/main/contrib/llvm-project/libcxx/include/__exception/nested_exception.h
35233 views
//===----------------------------------------------------------------------===//1//2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.3// See https://llvm.org/LICENSE.txt for license information.4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception5//6//===----------------------------------------------------------------------===//78#ifndef _LIBCPP___EXCEPTION_NESTED_EXCEPTION_H9#define _LIBCPP___EXCEPTION_NESTED_EXCEPTION_H1011#include <__config>12#include <__exception/exception_ptr.h>13#include <__memory/addressof.h>14#include <__type_traits/decay.h>15#include <__type_traits/is_base_of.h>16#include <__type_traits/is_class.h>17#include <__type_traits/is_constructible.h>18#include <__type_traits/is_convertible.h>19#include <__type_traits/is_final.h>20#include <__type_traits/is_polymorphic.h>21#include <__utility/forward.h>22#include <cstddef>2324#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)25# pragma GCC system_header26#endif2728namespace std { // purposefully not using versioning namespace2930class _LIBCPP_EXPORTED_FROM_ABI nested_exception {31exception_ptr __ptr_;3233public:34nested_exception() _NOEXCEPT;35_LIBCPP_HIDE_FROM_ABI nested_exception(const nested_exception&) _NOEXCEPT = default;36_LIBCPP_HIDE_FROM_ABI nested_exception& operator=(const nested_exception&) _NOEXCEPT = default;37virtual ~nested_exception() _NOEXCEPT;3839// access functions40_LIBCPP_NORETURN void rethrow_nested() const;41_LIBCPP_HIDE_FROM_ABI exception_ptr nested_ptr() const _NOEXCEPT { return __ptr_; }42};4344template <class _Tp>45struct __nested : public _Tp, public nested_exception {46_LIBCPP_HIDE_FROM_ABI explicit __nested(const _Tp& __t) : _Tp(__t) {}47};4849#ifndef _LIBCPP_HAS_NO_EXCEPTIONS50template <class _Tp, class _Up, bool>51struct __throw_with_nested;5253template <class _Tp, class _Up>54struct __throw_with_nested<_Tp, _Up, true> {55_LIBCPP_NORETURN static inline _LIBCPP_HIDE_FROM_ABI void __do_throw(_Tp&& __t) {56throw __nested<_Up>(std::forward<_Tp>(__t));57}58};5960template <class _Tp, class _Up>61struct __throw_with_nested<_Tp, _Up, false> {62_LIBCPP_NORETURN static inline _LIBCPP_HIDE_FROM_ABI void __do_throw(_Tp&& __t) { throw std::forward<_Tp>(__t); }63};64#endif6566template <class _Tp>67_LIBCPP_NORETURN _LIBCPP_HIDE_FROM_ABI void throw_with_nested(_Tp&& __t) {68#ifndef _LIBCPP_HAS_NO_EXCEPTIONS69using _Up = __decay_t<_Tp>;70static_assert(is_copy_constructible<_Up>::value, "type thrown must be CopyConstructible");71__throw_with_nested<_Tp,72_Up,73is_class<_Up>::value && !is_base_of<nested_exception, _Up>::value &&74!__libcpp_is_final<_Up>::value>::__do_throw(std::forward<_Tp>(__t));75#else76((void)__t);77// FIXME: Make this abort78#endif79}8081template <class _From, class _To>82struct __can_dynamic_cast83: _BoolConstant< is_polymorphic<_From>::value &&84(!is_base_of<_To, _From>::value || is_convertible<const _From*, const _To*>::value)> {};8586template <class _Ep, __enable_if_t< __can_dynamic_cast<_Ep, nested_exception>::value, int> = 0>87inline _LIBCPP_HIDE_FROM_ABI void rethrow_if_nested(const _Ep& __e) {88const nested_exception* __nep = dynamic_cast<const nested_exception*>(std::addressof(__e));89if (__nep)90__nep->rethrow_nested();91}9293template <class _Ep, __enable_if_t<!__can_dynamic_cast<_Ep, nested_exception>::value, int> = 0>94inline _LIBCPP_HIDE_FROM_ABI void rethrow_if_nested(const _Ep&) {}9596} // namespace std9798#endif // _LIBCPP___EXCEPTION_NESTED_EXCEPTION_H99100101