brintos

brintos / llvm-project-archived public Read only

0
0
Text · 3.6 KiB · 6079994 Raw
100 lines · c
1//===----------------------------------------------------------------------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8 9#ifndef _LIBCPP___CXX03___EXCEPTION_NESTED_EXCEPTION_H10#define _LIBCPP___CXX03___EXCEPTION_NESTED_EXCEPTION_H11 12#include <__cxx03/__config>13#include <__cxx03/__exception/exception_ptr.h>14#include <__cxx03/__memory/addressof.h>15#include <__cxx03/__type_traits/decay.h>16#include <__cxx03/__type_traits/is_base_of.h>17#include <__cxx03/__type_traits/is_class.h>18#include <__cxx03/__type_traits/is_constructible.h>19#include <__cxx03/__type_traits/is_convertible.h>20#include <__cxx03/__type_traits/is_final.h>21#include <__cxx03/__type_traits/is_polymorphic.h>22#include <__cxx03/__utility/forward.h>23#include <__cxx03/cstddef>24 25#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)26#  pragma GCC system_header27#endif28 29namespace std { // purposefully not using versioning namespace30 31class _LIBCPP_EXPORTED_FROM_ABI nested_exception {32  exception_ptr __ptr_;33 34public:35  nested_exception() _NOEXCEPT;36  _LIBCPP_HIDE_FROM_ABI nested_exception(const nested_exception&) _NOEXCEPT            = default;37  _LIBCPP_HIDE_FROM_ABI nested_exception& operator=(const nested_exception&) _NOEXCEPT = default;38  virtual ~nested_exception() _NOEXCEPT;39 40  // access functions41  _LIBCPP_NORETURN void rethrow_nested() const;42  _LIBCPP_HIDE_FROM_ABI exception_ptr nested_ptr() const _NOEXCEPT { return __ptr_; }43};44 45template <class _Tp>46struct __nested : public _Tp, public nested_exception {47  _LIBCPP_HIDE_FROM_ABI explicit __nested(const _Tp& __t) : _Tp(__t) {}48};49 50#ifndef _LIBCPP_HAS_NO_EXCEPTIONS51template <class _Tp, class _Up, bool>52struct __throw_with_nested;53 54template <class _Tp, class _Up>55struct __throw_with_nested<_Tp, _Up, true> {56  _LIBCPP_NORETURN static inline _LIBCPP_HIDE_FROM_ABI void __do_throw(_Tp&& __t) {57    throw __nested<_Up>(std::forward<_Tp>(__t));58  }59};60 61template <class _Tp, class _Up>62struct __throw_with_nested<_Tp, _Up, false> {63  _LIBCPP_NORETURN static inline _LIBCPP_HIDE_FROM_ABI void __do_throw(_Tp&& __t) { throw std::forward<_Tp>(__t); }64};65#endif66 67template <class _Tp>68_LIBCPP_NORETURN _LIBCPP_HIDE_FROM_ABI void throw_with_nested(_Tp&& __t) {69#ifndef _LIBCPP_HAS_NO_EXCEPTIONS70  using _Up = __decay_t<_Tp>;71  static_assert(is_copy_constructible<_Up>::value, "type thrown must be CopyConstructible");72  __throw_with_nested<_Tp,73                      _Up,74                      is_class<_Up>::value && !is_base_of<nested_exception, _Up>::value &&75                          !__libcpp_is_final<_Up>::value>::__do_throw(std::forward<_Tp>(__t));76#else77  ((void)__t);78  // FIXME: Make this abort79#endif80}81 82template <class _From, class _To>83struct __can_dynamic_cast84    : _BoolConstant< is_polymorphic<_From>::value &&85                     (!is_base_of<_To, _From>::value || is_convertible<const _From*, const _To*>::value)> {};86 87template <class _Ep, __enable_if_t< __can_dynamic_cast<_Ep, nested_exception>::value, int> = 0>88inline _LIBCPP_HIDE_FROM_ABI void rethrow_if_nested(const _Ep& __e) {89  const nested_exception* __nep = dynamic_cast<const nested_exception*>(std::addressof(__e));90  if (__nep)91    __nep->rethrow_nested();92}93 94template <class _Ep, __enable_if_t<!__can_dynamic_cast<_Ep, nested_exception>::value, int> = 0>95inline _LIBCPP_HIDE_FROM_ABI void rethrow_if_nested(const _Ep&) {}96 97} // namespace std98 99#endif // _LIBCPP___CXX03___EXCEPTION_NESTED_EXCEPTION_H100