diff options
-rw-r--r-- | libcxx/include/type_traits | 10 | ||||
-rw-r--r-- | libcxx/test/libcxx/type_traits/is_pointer.arc.pass.mm | 64 |
2 files changed, 73 insertions, 1 deletions
diff --git a/libcxx/include/type_traits b/libcxx/include/type_traits index 2b79490941c..43faf275cff 100644 --- a/libcxx/include/type_traits +++ b/libcxx/include/type_traits @@ -785,8 +785,16 @@ _LIBCPP_INLINE_VAR _LIBCPP_CONSTEXPR bool is_array_v template <class _Tp> struct __libcpp_is_pointer : public false_type {}; template <class _Tp> struct __libcpp_is_pointer<_Tp*> : public true_type {}; +template <class _Tp> struct __libcpp_remove_objc_qualifiers { typedef _Tp type; }; +#if defined(_LIBCPP_HAS_OBJC_ARC) +template <class _Tp> struct __libcpp_remove_objc_qualifiers<_Tp __strong> { typedef _Tp type; }; +template <class _Tp> struct __libcpp_remove_objc_qualifiers<_Tp __weak> { typedef _Tp type; }; +template <class _Tp> struct __libcpp_remove_objc_qualifiers<_Tp __autoreleasing> { typedef _Tp type; }; +template <class _Tp> struct __libcpp_remove_objc_qualifiers<_Tp __unsafe_unretained> { typedef _Tp type; }; +#endif + template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_pointer - : public __libcpp_is_pointer<typename remove_cv<_Tp>::type> {}; + : public __libcpp_is_pointer<typename __libcpp_remove_objc_qualifiers<typename remove_cv<_Tp>::type>::type> {}; #if _LIBCPP_STD_VER > 14 && !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES) template <class _Tp> diff --git a/libcxx/test/libcxx/type_traits/is_pointer.arc.pass.mm b/libcxx/test/libcxx/type_traits/is_pointer.arc.pass.mm new file mode 100644 index 00000000000..1f4c5089af9 --- /dev/null +++ b/libcxx/test/libcxx/type_traits/is_pointer.arc.pass.mm @@ -0,0 +1,64 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// UNSUPPORTED: c++98, c++03 + +// <type_traits> + +// std::is_pointer + +// Test that we correctly handle Objective-C++ ARC qualifiers on pointers. + +#include <type_traits> + + +template <typename T> +void test_is_pointer() { + static_assert(std::is_pointer<T>::value, ""); + + static_assert(std::is_pointer<T __weak>::value, ""); + static_assert(std::is_pointer<T __strong>::value, ""); + static_assert(std::is_pointer<T __autoreleasing>::value, ""); + static_assert(std::is_pointer<T __unsafe_unretained>::value, ""); + + static_assert(std::is_pointer<T __weak const>::value, ""); + static_assert(std::is_pointer<T __strong const>::value, ""); + static_assert(std::is_pointer<T __autoreleasing const>::value, ""); + static_assert(std::is_pointer<T __unsafe_unretained const>::value, ""); + + static_assert(std::is_pointer<T __weak volatile>::value, ""); + static_assert(std::is_pointer<T __strong volatile>::value, ""); + static_assert(std::is_pointer<T __autoreleasing volatile>::value, ""); + static_assert(std::is_pointer<T __unsafe_unretained volatile>::value, ""); + + static_assert(std::is_pointer<T __weak const volatile>::value, ""); + static_assert(std::is_pointer<T __strong const volatile>::value, ""); + static_assert(std::is_pointer<T __autoreleasing const volatile>::value, ""); + static_assert(std::is_pointer<T __unsafe_unretained const volatile>::value, ""); +} + +@class Foo; + +int main(int, char**) { + test_is_pointer<id>(); + test_is_pointer<id const>(); + test_is_pointer<id volatile>(); + test_is_pointer<id const volatile>(); + + test_is_pointer<Foo*>(); + test_is_pointer<Foo const*>(); + test_is_pointer<Foo volatile*>(); + test_is_pointer<Foo const volatile*>(); + + test_is_pointer<void*>(); + test_is_pointer<void const*>(); + test_is_pointer<void volatile*>(); + test_is_pointer<void const volatile*>(); + + return 0; +} |