diff options
| -rw-r--r-- | libcxx/include/__config | 6 | ||||
| -rw-r--r-- | libcxx/include/__type_traits/add_pointer.h | 4 | ||||
| -rw-r--r-- | libcxx/include/__type_traits/remove_pointer.h | 4 | ||||
| -rw-r--r-- | libcxx/test/std/utilities/meta/meta.trans/objc_support.pass.mm | 106 |
4 files changed, 116 insertions, 4 deletions
diff --git a/libcxx/include/__config b/libcxx/include/__config index 6790fb3..f531b1c 100644 --- a/libcxx/include/__config +++ b/libcxx/include/__config @@ -1259,6 +1259,12 @@ _LIBCPP_BEGIN_NAMESPACE_STD _LIBCPP_END_NAMESPACE_STD # define _LIBCPP_CTAD_SUPPORTED_FOR_TYPE(_ClassName) static_assert(true, "") #endif +// TODO(varconst): currently, there are bugs in Clang's intrinsics when handling Objective-C++ `id`, so don't use +// compiler intrinsics in the Objective-C++ mode. +# ifdef __OBJC__ +# define _LIBCPP_WORKAROUND_OBJCXX_COMPILER_INTRINSICS +# endif + #endif // __cplusplus #endif // _LIBCPP___CONFIG diff --git a/libcxx/include/__type_traits/add_pointer.h b/libcxx/include/__type_traits/add_pointer.h index 9f01086..1e74daf 100644 --- a/libcxx/include/__type_traits/add_pointer.h +++ b/libcxx/include/__type_traits/add_pointer.h @@ -22,7 +22,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD -#if __has_builtin(__add_pointer) +#if !defined(_LIBCPP_WORKAROUND_OBJCXX_COMPILER_INTRINSICS) && __has_builtin(__add_pointer) template <class _Tp> using __add_pointer_t = __add_pointer(_Tp); @@ -39,7 +39,7 @@ template <class _Tp> struct __add_pointer_impl<_Tp, false> template <class _Tp> using __add_pointer_t = typename __add_pointer_impl<_Tp>::type; -#endif // __has_builtin(__add_pointer) +#endif // !defined(_LIBCPP_WORKAROUND_OBJCXX_COMPILER_INTRINSICS) && __has_builtin(__add_pointer) template <class _Tp> struct add_pointer { diff --git a/libcxx/include/__type_traits/remove_pointer.h b/libcxx/include/__type_traits/remove_pointer.h index 6c02d25..8b3a9c7 100644 --- a/libcxx/include/__type_traits/remove_pointer.h +++ b/libcxx/include/__type_traits/remove_pointer.h @@ -17,7 +17,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD -#if __has_builtin(__remove_pointer) +#if !defined(_LIBCPP_WORKAROUND_OBJCXX_COMPILER_INTRINSICS) && __has_builtin(__remove_pointer) template <class _Tp> struct remove_pointer { using type _LIBCPP_NODEBUG = __remove_pointer(_Tp); @@ -34,7 +34,7 @@ template <class _Tp> struct _LIBCPP_TEMPLATE_VIS remove_pointer<_Tp* const volat template <class _Tp> using __remove_pointer_t = typename remove_pointer<_Tp>::type; -#endif // __has_builtin(__remove_pointer) +#endif // !defined(_LIBCPP_WORKAROUND_OBJCXX_COMPILER_INTRINSICS) && __has_builtin(__remove_pointer) #if _LIBCPP_STD_VER >= 14 template <class _Tp> using remove_pointer_t = __remove_pointer_t<_Tp>; diff --git a/libcxx/test/std/utilities/meta/meta.trans/objc_support.pass.mm b/libcxx/test/std/utilities/meta/meta.trans/objc_support.pass.mm new file mode 100644 index 0000000..e1fb119 --- /dev/null +++ b/libcxx/test/std/utilities/meta/meta.trans/objc_support.pass.mm @@ -0,0 +1,106 @@ +//===----------------------------------------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +// REQUIRES: objective-c++ + +// Simple test to check that type traits support Objective-C types. + +#include <type_traits> +#include "test_macros.h" + +@interface I; +@end + +// add_pointer +static_assert(std::is_same<std::add_pointer<id>::type, id*>::value, ""); +static_assert(std::is_same<std::add_pointer<I>::type, I*>::value, ""); + +// add_lvalue_reference +static_assert(std::is_same<std::add_lvalue_reference<id>::type, id&>::value, ""); +static_assert(std::is_same<std::add_lvalue_reference<I>::type, I&>::value, ""); + +// add_rvalue_reference +static_assert(std::is_same<std::add_rvalue_reference<id>::type, id&&>::value, ""); +static_assert(std::is_same<std::add_rvalue_reference<I>::type, I&&>::value, ""); + +// decay +static_assert(std::is_same<std::decay<id>::type, id>::value, ""); +static_assert(std::is_same<std::decay<I>::type, I>::value, ""); +static_assert(std::is_same<std::decay<id(&)[5]>::type, id*>::value, ""); + +// __libcpp_is_referenceable +LIBCPP_STATIC_ASSERT(std::__libcpp_is_referenceable<id>::value, ""); +LIBCPP_STATIC_ASSERT(std::__libcpp_is_referenceable<id*>::value, ""); +LIBCPP_STATIC_ASSERT(std::__libcpp_is_referenceable<id&>::value, ""); +LIBCPP_STATIC_ASSERT(std::__libcpp_is_referenceable<id&&>::value, ""); +LIBCPP_STATIC_ASSERT(std::__libcpp_is_referenceable<I>::value, ""); +LIBCPP_STATIC_ASSERT(std::__libcpp_is_referenceable<I*>::value, ""); +LIBCPP_STATIC_ASSERT(std::__libcpp_is_referenceable<I&>::value, ""); +LIBCPP_STATIC_ASSERT(std::__libcpp_is_referenceable<I&&>::value, ""); + +// remove_all_extents +static_assert(std::is_same<std::remove_all_extents<id>::type, id>::value, ""); +static_assert(std::is_same<std::remove_all_extents<id[5]>::type, id>::value, ""); +static_assert(std::is_same<std::remove_all_extents<id[5][10]>::type, id>::value, ""); +static_assert(std::is_same<std::remove_all_extents<I>::type, I>::value, ""); + +// remove_const +static_assert(std::is_same<std::remove_const<id>::type, id>::value, ""); +static_assert(std::is_same<std::remove_const<const id>::type, id>::value, ""); +static_assert(std::is_same<std::remove_const<I>::type, I>::value, ""); +static_assert(std::is_same<std::remove_const<const I>::type, I>::value, ""); + +// remove_cv +static_assert(std::is_same<std::remove_cv<id>::type, id>::value, ""); +static_assert(std::is_same<std::remove_cv<const volatile id>::type, id>::value, ""); +static_assert(std::is_same<std::remove_cv<I>::type, I>::value, ""); +static_assert(std::is_same<std::remove_cv<const volatile I>::type, I>::value, ""); + +#if TEST_STD_VER >= 20 +// remove_cvref +static_assert(std::is_same<std::remove_cvref<id>::type, id>::value, ""); +static_assert(std::is_same<std::remove_cvref<const volatile id&>::type, id>::value, ""); +static_assert(std::is_same<std::remove_cvref<const volatile id&&>::type, id>::value, ""); +static_assert(std::is_same<std::remove_cvref<I>::type, I>::value, ""); +static_assert(std::is_same<std::remove_cvref<const volatile I&>::type, I>::value, ""); +static_assert(std::is_same<std::remove_cvref<const volatile I&&>::type, I>::value, ""); +#endif + +// remove_extent +static_assert(std::is_same<std::remove_all_extents<id>::type, id>::value, ""); +static_assert(std::is_same<std::remove_all_extents<id[5]>::type, id>::value, ""); +static_assert(std::is_same<std::remove_all_extents<I>::type, I>::value, ""); + +// remove_pointer +static_assert(!std::is_same<std::remove_pointer<id>::type, id>::value, ""); +// The result of removing and re-adding pointer to `id` should be still `id`. +static_assert(std::is_same<std::remove_pointer<id>::type*, id>::value, ""); +static_assert(std::is_same<std::add_pointer<std::remove_pointer<id>::type>::type, id>::value, ""); +static_assert(std::is_same<std::remove_pointer<std::add_pointer<id>::type>::type, id>::value, ""); + +// remove_reference +static_assert(std::is_same<std::remove_reference<id>::type, id>::value, ""); +static_assert(std::is_same<std::remove_reference<id&>::type, id>::value, ""); +static_assert(std::is_same<std::remove_reference<const id&>::type, const id>::value, ""); +static_assert(std::is_same<std::remove_reference<id&&>::type, id>::value, ""); +static_assert(std::is_same<std::remove_reference<const id&&>::type, const id>::value, ""); +static_assert(std::is_same<std::remove_reference<I>::type, I>::value, ""); +static_assert(std::is_same<std::remove_reference<I&>::type, I>::value, ""); +static_assert(std::is_same<std::remove_reference<const I&>::type, const I>::value, ""); +static_assert(std::is_same<std::remove_reference<I&&>::type, I>::value, ""); +static_assert(std::is_same<std::remove_reference<const I&&>::type, const I>::value, ""); + +// remove_volatile +static_assert(std::is_same<std::remove_volatile<id>::type, id>::value, ""); +static_assert(std::is_same<std::remove_volatile<volatile id>::type, id>::value, ""); +static_assert(std::is_same<std::remove_volatile<I>::type, I>::value, ""); +static_assert(std::is_same<std::remove_volatile<volatile I>::type, I>::value, ""); + +int main(int, char**) { + return 0; +} |
