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 27 template<class _Tp> 28 struct _LIBCPP_TEMPLATE_VIS is_destructible : _BoolConstant<__is_destructible(_Tp)> { }; 29 30 #if _LIBCPP_STD_VER > 14 31 template <class _Tp> 32 inline 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 44 template <class> 45 struct __is_destructible_apply { typedef int type; }; 46 47 template <typename _Tp> 48 struct __is_destructor_wellformed { 49 template <typename _Tp1> 50 static true_type __test ( 51 typename __is_destructible_apply<decltype(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 60 template <class _Tp, bool> 61 struct __destructible_imp; 62 63 template <class _Tp> 64 struct __destructible_imp<_Tp, false> 65 : public integral_constant<bool, 66 __is_destructor_wellformed<typename remove_all_extents<_Tp>::type>::value> {}; 67 68 template <class _Tp> 69 struct __destructible_imp<_Tp, true> 70 : public true_type {}; 71 72 template <class _Tp, bool> 73 struct __destructible_false; 74 75 template <class _Tp> 76 struct __destructible_false<_Tp, false> : public __destructible_imp<_Tp, is_reference<_Tp>::value> {}; 77 78 template <class _Tp> 79 struct __destructible_false<_Tp, true> : public false_type {}; 80 81 template <class _Tp> 82 struct is_destructible 83 : public __destructible_false<_Tp, is_function<_Tp>::value> {}; 84 85 template <class _Tp> 86 struct is_destructible<_Tp[]> 87 : public false_type {}; 88 89 template <> 90 struct is_destructible<void> 91 : public false_type {}; 92 93 #if _LIBCPP_STD_VER > 14 94 template <class _Tp> 95 inline 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