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 >= 17 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 { 46 typedef int type; 47}; 48 49template <typename _Tp> 50struct __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 60template <class _Tp, bool> 61struct __destructible_imp; 62 63template <class _Tp> 64struct __destructible_imp<_Tp, false> 65 : public integral_constant<bool, __is_destructor_wellformed<__remove_all_extents_t<_Tp> >::value> {}; 66 67template <class _Tp> 68struct __destructible_imp<_Tp, true> : public true_type {}; 69 70template <class _Tp, bool> 71struct __destructible_false; 72 73template <class _Tp> 74struct __destructible_false<_Tp, false> : public __destructible_imp<_Tp, is_reference<_Tp>::value> {}; 75 76template <class _Tp> 77struct __destructible_false<_Tp, true> : public false_type {}; 78 79template <class _Tp> 80struct is_destructible : public __destructible_false<_Tp, is_function<_Tp>::value> {}; 81 82template <class _Tp> 83struct is_destructible<_Tp[]> : public false_type {}; 84 85template <> 86struct is_destructible<void> : public false_type {}; 87 88# if _LIBCPP_STD_VER >= 17 89template <class _Tp> 90inline 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