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 >= 17 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 { 46 typedef int type; 47 }; 48 49 template <typename _Tp> 50 struct __is_destructor_wellformed { 51 template <typename _Tp1> 52 static true_type __test(typename __is_destructible_apply<decltype(std::declval<_Tp1&>().~_Tp1())>::type); 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, __is_destructor_wellformed<__remove_all_extents_t<_Tp> >::value> {}; 66 67 template <class _Tp> 68 struct __destructible_imp<_Tp, true> : public true_type {}; 69 70 template <class _Tp, bool> 71 struct __destructible_false; 72 73 template <class _Tp> 74 struct __destructible_false<_Tp, false> : public __destructible_imp<_Tp, is_reference<_Tp>::value> {}; 75 76 template <class _Tp> 77 struct __destructible_false<_Tp, true> : public false_type {}; 78 79 template <class _Tp> 80 struct is_destructible : public __destructible_false<_Tp, is_function<_Tp>::value> {}; 81 82 template <class _Tp> 83 struct is_destructible<_Tp[]> : public false_type {}; 84 85 template <> 86 struct is_destructible<void> : public false_type {}; 87 88 # if _LIBCPP_STD_VER >= 17 89 template <class _Tp> 90 inline constexpr bool is_destructible_v = is_destructible<_Tp>::value; 91 # endif 92 93 #endif // __has_builtin(__is_destructible) 94 95 _LIBCPP_END_NAMESPACE_STD 96 97 #endif // _LIBCPP___TYPE_TRAITS_IS_DESTRUCTIBLE_H 98