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-exception 6// 7//===----------------------------------------------------------------------===// 8 9#ifndef _LIBCPP___TYPE_TRAITS_IS_DESTRUCTIBLE_H 10#define _LIBCPP___TYPE_TRAITS_IS_DESTRUCTIBLE_H 11 12#include <__config> 13#include <__type_traits/integral_constant.h> 14#include <__type_traits/is_function.h> 15#include <__type_traits/is_reference.h> 16#include <__type_traits/remove_all_extents.h> 17#include <__utility/declval.h> 18 19#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) 20# pragma GCC system_header 21#endif 22 23_LIBCPP_BEGIN_NAMESPACE_STD 24 25#if __has_builtin(__is_destructible) 26 27template<class _Tp> 28struct _LIBCPP_TEMPLATE_VIS is_destructible : _BoolConstant<__is_destructible(_Tp)> { }; 29 30#if _LIBCPP_STD_VER > 14 31template <class _Tp> 32inline constexpr bool is_destructible_v = __is_destructible(_Tp); 33#endif 34 35#else // __has_builtin(__is_destructible) 36 37// if it's a reference, return true 38// if it's a function, return false 39// if it's void, return false 40// if it's an array of unknown bound, return false 41// Otherwise, return "declval<_Up&>().~_Up()" is well-formed 42// where _Up is remove_all_extents<_Tp>::type 43 44template <class> 45struct __is_destructible_apply { typedef int type; }; 46 47template <typename _Tp> 48struct __is_destructor_wellformed { 49 template <typename _Tp1> 50 static true_type __test ( 51 typename __is_destructible_apply<decltype(std::declval<_Tp1&>().~_Tp1())>::type 52 ); 53 54 template <typename _Tp1> 55 static false_type __test (...); 56 57 static const bool value = decltype(__test<_Tp>(12))::value; 58}; 59 60template <class _Tp, bool> 61struct __destructible_imp; 62 63template <class _Tp> 64struct __destructible_imp<_Tp, false> 65 : public integral_constant<bool, 66 __is_destructor_wellformed<__remove_all_extents_t<_Tp> >::value> {}; 67 68template <class _Tp> 69struct __destructible_imp<_Tp, true> 70 : public true_type {}; 71 72template <class _Tp, bool> 73struct __destructible_false; 74 75template <class _Tp> 76struct __destructible_false<_Tp, false> : public __destructible_imp<_Tp, is_reference<_Tp>::value> {}; 77 78template <class _Tp> 79struct __destructible_false<_Tp, true> : public false_type {}; 80 81template <class _Tp> 82struct is_destructible 83 : public __destructible_false<_Tp, is_function<_Tp>::value> {}; 84 85template <class _Tp> 86struct is_destructible<_Tp[]> 87 : public false_type {}; 88 89template <> 90struct is_destructible<void> 91 : public false_type {}; 92 93#if _LIBCPP_STD_VER > 14 94template <class _Tp> 95inline constexpr bool is_destructible_v = is_destructible<_Tp>::value; 96#endif 97 98#endif // __has_builtin(__is_destructible) 99 100_LIBCPP_END_NAMESPACE_STD 101 102#endif // _LIBCPP___TYPE_TRAITS_IS_DESTRUCTIBLE_H 103