[libc++] Simplify the implementation of __is_referenceable (#130043)

The `__is_referenceable` builtin has been removed from Clang, since all
its uses have been replaced by builtins themselves. This trait only
exists for GCC compatibility and to word around some issues in the other
traits. The non-builtin implementation has been refactored to use
variable templates instead, making the implementation much simpler.
This commit is contained in:
Nikolas Klauser 2025-03-24 07:32:01 +01:00 committed by GitHub
parent 66531c998a
commit ddc62797c4
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
8 changed files with 211 additions and 223 deletions

View File

@ -25,7 +25,7 @@ using __add_lvalue_reference_t _LIBCPP_NODEBUG = __add_lvalue_reference(_Tp);
#else
template <class _Tp, bool = __libcpp_is_referenceable<_Tp>::value>
template <class _Tp, bool = __is_referenceable_v<_Tp>>
struct __add_lvalue_reference_impl {
using type _LIBCPP_NODEBUG = _Tp;
};

View File

@ -26,7 +26,7 @@ template <class _Tp>
using __add_pointer_t _LIBCPP_NODEBUG = __add_pointer(_Tp);
#else
template <class _Tp, bool = __libcpp_is_referenceable<_Tp>::value || is_void<_Tp>::value>
template <class _Tp, bool = __is_referenceable_v<_Tp> || is_void<_Tp>::value>
struct __add_pointer_impl {
using type _LIBCPP_NODEBUG = __libcpp_remove_reference_t<_Tp>*;
};

View File

@ -25,7 +25,7 @@ using __add_rvalue_reference_t _LIBCPP_NODEBUG = __add_rvalue_reference(_Tp);
#else
template <class _Tp, bool = __libcpp_is_referenceable<_Tp>::value>
template <class _Tp, bool = __is_referenceable_v<_Tp> >
struct __add_rvalue_reference_impl {
using type _LIBCPP_NODEBUG = _Tp;
};

View File

@ -55,7 +55,7 @@ private:
using _Up _LIBCPP_NODEBUG = __libcpp_remove_reference_t<_Tp>;
public:
using type _LIBCPP_NODEBUG = typename __decay<_Up, __libcpp_is_referenceable<_Up>::value>::type;
using type _LIBCPP_NODEBUG = typename __decay<_Up, __is_referenceable_v<_Up> >::type;
};
template <class _Tp>

View File

@ -10,8 +10,7 @@
#define _LIBCPP___TYPE_TRAITS_IS_REFERENCEABLE_H
#include <__config>
#include <__type_traits/integral_constant.h>
#include <__type_traits/is_same.h>
#include <__type_traits/void_t.h>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
@ -19,22 +18,11 @@
_LIBCPP_BEGIN_NAMESPACE_STD
#if __has_builtin(__is_referenceable)
template <class _Tp>
struct __libcpp_is_referenceable : integral_constant<bool, __is_referenceable(_Tp)> {};
#else
struct __libcpp_is_referenceable_impl {
template <class _Tp>
static _Tp& __test(int);
template <class _Tp>
static false_type __test(...);
};
template <class _Tp, class = void>
inline const bool __is_referenceable_v = false;
template <class _Tp>
struct __libcpp_is_referenceable
: integral_constant<bool, _IsNotSame<decltype(__libcpp_is_referenceable_impl::__test<_Tp>(0)), false_type>::value> {
};
#endif // __has_builtin(__is_referenceable)
inline const bool __is_referenceable_v<_Tp, __void_t<_Tp&> > = true;
_LIBCPP_END_NAMESPACE_STD

View File

@ -0,0 +1,192 @@
//===----------------------------------------------------------------------===//
//
// 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
//
//===----------------------------------------------------------------------===//
//
// __is_referenceable_v<Tp>
//
// [defns.referenceable] defines "a referenceable type" as:
// An object type, a function type that does not have cv-qualifiers
// or a ref-qualifier, or a reference type.
//
// XFAIL: FROZEN-CXX03-HEADERS-FIXME
#include <type_traits>
#include <cassert>
#include "test_macros.h"
struct Foo {};
static_assert((!std::__is_referenceable_v<void>), "");
static_assert((std::__is_referenceable_v<int>), "");
static_assert((std::__is_referenceable_v<int[3]>), "");
static_assert((std::__is_referenceable_v<int[]>), "");
static_assert((std::__is_referenceable_v<int&>), "");
static_assert((std::__is_referenceable_v<const int&>), "");
static_assert((std::__is_referenceable_v<int*>), "");
static_assert((std::__is_referenceable_v<const int*>), "");
static_assert((std::__is_referenceable_v<Foo>), "");
static_assert((std::__is_referenceable_v<const Foo>), "");
static_assert((std::__is_referenceable_v<Foo&>), "");
static_assert((std::__is_referenceable_v<const Foo&>), "");
#if TEST_STD_VER >= 11
static_assert((std::__is_referenceable_v<Foo&&>), "");
static_assert((std::__is_referenceable_v<const Foo&&>), "");
#endif
static_assert((std::__is_referenceable_v<int __attribute__((__vector_size__(8)))>), "");
static_assert((std::__is_referenceable_v<const int __attribute__((__vector_size__(8)))>), "");
static_assert((std::__is_referenceable_v<float __attribute__((__vector_size__(16)))>), "");
static_assert((std::__is_referenceable_v<const float __attribute__((__vector_size__(16)))>), "");
// Functions without cv-qualifiers are referenceable
static_assert((std::__is_referenceable_v<void()>), "");
#if TEST_STD_VER >= 11
static_assert((!std::__is_referenceable_v<void() const>), "");
static_assert((!std::__is_referenceable_v<void() &>), "");
static_assert((!std::__is_referenceable_v<void() const&>), "");
static_assert((!std::__is_referenceable_v<void() &&>), "");
static_assert((!std::__is_referenceable_v<void() const&&>), "");
#endif
static_assert((std::__is_referenceable_v<void(int)>), "");
#if TEST_STD_VER >= 11
static_assert((!std::__is_referenceable_v<void(int) const>), "");
static_assert((!std::__is_referenceable_v<void(int) &>), "");
static_assert((!std::__is_referenceable_v<void(int) const&>), "");
static_assert((!std::__is_referenceable_v<void(int) &&>), "");
static_assert((!std::__is_referenceable_v<void(int) const&&>), "");
#endif
static_assert((std::__is_referenceable_v<void(int, float)>), "");
#if TEST_STD_VER >= 11
static_assert((!std::__is_referenceable_v<void(int, float) const>), "");
static_assert((!std::__is_referenceable_v<void(int, float) &>), "");
static_assert((!std::__is_referenceable_v<void(int, float) const&>), "");
static_assert((!std::__is_referenceable_v<void(int, float) &&>), "");
static_assert((!std::__is_referenceable_v<void(int, float) const&&>), "");
#endif
static_assert((std::__is_referenceable_v<void(int, float, Foo&)>), "");
#if TEST_STD_VER >= 11
static_assert((!std::__is_referenceable_v<void(int, float, Foo&) const>), "");
static_assert((!std::__is_referenceable_v<void(int, float, Foo&) &>), "");
static_assert((!std::__is_referenceable_v<void(int, float, Foo&) const&>), "");
static_assert((!std::__is_referenceable_v<void(int, float, Foo&) &&>), "");
static_assert((!std::__is_referenceable_v<void(int, float, Foo&) const&&>), "");
#endif
static_assert((std::__is_referenceable_v<void(...)>), "");
#if TEST_STD_VER >= 11
static_assert((!std::__is_referenceable_v<void(...) const>), "");
static_assert((!std::__is_referenceable_v<void(...) &>), "");
static_assert((!std::__is_referenceable_v<void(...) const&>), "");
static_assert((!std::__is_referenceable_v<void(...) &&>), "");
static_assert((!std::__is_referenceable_v<void(...) const&&>), "");
#endif
static_assert((std::__is_referenceable_v<void(int, ...)>), "");
#if TEST_STD_VER >= 11
static_assert((!std::__is_referenceable_v<void(int, ...) const>), "");
static_assert((!std::__is_referenceable_v<void(int, ...) &>), "");
static_assert((!std::__is_referenceable_v<void(int, ...) const&>), "");
static_assert((!std::__is_referenceable_v<void(int, ...) &&>), "");
static_assert((!std::__is_referenceable_v<void(int, ...) const&&>), "");
#endif
static_assert((std::__is_referenceable_v<void(int, float, ...)>), "");
#if TEST_STD_VER >= 11
static_assert((!std::__is_referenceable_v<void(int, float, ...) const>), "");
static_assert((!std::__is_referenceable_v<void(int, float, ...) &>), "");
static_assert((!std::__is_referenceable_v<void(int, float, ...) const&>), "");
static_assert((!std::__is_referenceable_v<void(int, float, ...) &&>), "");
static_assert((!std::__is_referenceable_v<void(int, float, ...) const&&>), "");
#endif
static_assert((std::__is_referenceable_v<void(int, float, Foo&, ...)>), "");
#if TEST_STD_VER >= 11
static_assert((!std::__is_referenceable_v<void(int, float, Foo&, ...) const>), "");
static_assert((!std::__is_referenceable_v<void(int, float, Foo&, ...) &>), "");
static_assert((!std::__is_referenceable_v<void(int, float, Foo&, ...) const&>), "");
static_assert((!std::__is_referenceable_v<void(int, float, Foo&, ...) &&>), "");
static_assert((!std::__is_referenceable_v<void(int, float, Foo&, ...) const&&>), "");
#endif
// member functions with or without cv-qualifiers are referenceable
static_assert((std::__is_referenceable_v<void (Foo::*)()>), "");
static_assert((std::__is_referenceable_v<void (Foo::*)() const>), "");
#if TEST_STD_VER >= 11
static_assert((std::__is_referenceable_v<void (Foo::*)() &>), "");
static_assert((std::__is_referenceable_v<void (Foo::*)() const&>), "");
static_assert((std::__is_referenceable_v<void (Foo::*)() &&>), "");
static_assert((std::__is_referenceable_v<void (Foo::*)() const&&>), "");
#endif
static_assert((std::__is_referenceable_v<void (Foo::*)(int)>), "");
static_assert((std::__is_referenceable_v<void (Foo::*)(int) const>), "");
#if TEST_STD_VER >= 11
static_assert((std::__is_referenceable_v<void (Foo::*)(int) &>), "");
static_assert((std::__is_referenceable_v<void (Foo::*)(int) const&>), "");
static_assert((std::__is_referenceable_v<void (Foo::*)(int) &&>), "");
static_assert((std::__is_referenceable_v<void (Foo::*)(int) const&&>), "");
#endif
static_assert((std::__is_referenceable_v<void (Foo::*)(int, float)>), "");
static_assert((std::__is_referenceable_v<void (Foo::*)(int, float) const>), "");
#if TEST_STD_VER >= 11
static_assert((std::__is_referenceable_v<void (Foo::*)(int, float) &>), "");
static_assert((std::__is_referenceable_v<void (Foo::*)(int, float) const&>), "");
static_assert((std::__is_referenceable_v<void (Foo::*)(int, float) &&>), "");
static_assert((std::__is_referenceable_v<void (Foo::*)(int, float) const&&>), "");
#endif
static_assert((std::__is_referenceable_v<void (Foo::*)(int, float, Foo&)>), "");
static_assert((std::__is_referenceable_v<void (Foo::*)(int, float, Foo&) const>), "");
#if TEST_STD_VER >= 11
static_assert((std::__is_referenceable_v<void (Foo::*)(int, float, Foo&) &>), "");
static_assert((std::__is_referenceable_v<void (Foo::*)(int, float, Foo&) const&>), "");
static_assert((std::__is_referenceable_v<void (Foo::*)(int, float, Foo&) &&>), "");
static_assert((std::__is_referenceable_v<void (Foo::*)(int, float, Foo&) const&&>), "");
#endif
static_assert((std::__is_referenceable_v<void (Foo::*)(...)>), "");
static_assert((std::__is_referenceable_v<void (Foo::*)(...) const>), "");
#if TEST_STD_VER >= 11
static_assert((std::__is_referenceable_v<void (Foo::*)(...) &>), "");
static_assert((std::__is_referenceable_v<void (Foo::*)(...) const&>), "");
static_assert((std::__is_referenceable_v<void (Foo::*)(...) &&>), "");
static_assert((std::__is_referenceable_v<void (Foo::*)(...) const&&>), "");
#endif
static_assert((std::__is_referenceable_v<void (Foo::*)(int, ...)>), "");
static_assert((std::__is_referenceable_v<void (Foo::*)(int, ...) const>), "");
#if TEST_STD_VER >= 11
static_assert((std::__is_referenceable_v<void (Foo::*)(int, ...) &>), "");
static_assert((std::__is_referenceable_v<void (Foo::*)(int, ...) const&>), "");
static_assert((std::__is_referenceable_v<void (Foo::*)(int, ...) &&>), "");
static_assert((std::__is_referenceable_v<void (Foo::*)(int, ...) const&&>), "");
#endif
static_assert((std::__is_referenceable_v<void (Foo::*)(int, float, ...)>), "");
static_assert((std::__is_referenceable_v<void (Foo::*)(int, float, ...) const>), "");
#if TEST_STD_VER >= 11
static_assert((std::__is_referenceable_v<void (Foo::*)(int, float, ...) &>), "");
static_assert((std::__is_referenceable_v<void (Foo::*)(int, float, ...) const&>), "");
static_assert((std::__is_referenceable_v<void (Foo::*)(int, float, ...) &&>), "");
static_assert((std::__is_referenceable_v<void (Foo::*)(int, float, ...) const&&>), "");
#endif
static_assert((std::__is_referenceable_v<void (Foo::*)(int, float, Foo&, ...)>), "");
static_assert((std::__is_referenceable_v<void (Foo::*)(int, float, Foo&, ...) const>), "");
#if TEST_STD_VER >= 11
static_assert((std::__is_referenceable_v<void (Foo::*)(int, float, Foo&, ...) &>), "");
static_assert((std::__is_referenceable_v<void (Foo::*)(int, float, Foo&, ...) const&>), "");
static_assert((std::__is_referenceable_v<void (Foo::*)(int, float, Foo&, ...) &&>), "");
static_assert((std::__is_referenceable_v<void (Foo::*)(int, float, Foo&, ...) const&&>), "");
#endif

View File

@ -1,194 +0,0 @@
//===----------------------------------------------------------------------===//
//
// 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
//
//===----------------------------------------------------------------------===//
//
// __libcpp_is_referenceable<Tp>
//
// [defns.referenceable] defines "a referenceable type" as:
// An object type, a function type that does not have cv-qualifiers
// or a ref-qualifier, or a reference type.
//
#include <type_traits>
#include <cassert>
#include "test_macros.h"
struct Foo {};
static_assert((!std::__libcpp_is_referenceable<void>::value), "");
static_assert((std::__libcpp_is_referenceable<int>::value), "");
static_assert((std::__libcpp_is_referenceable<int[3]>::value), "");
static_assert((std::__libcpp_is_referenceable<int[]>::value), "");
static_assert((std::__libcpp_is_referenceable<int&>::value), "");
static_assert((std::__libcpp_is_referenceable<const int&>::value), "");
static_assert((std::__libcpp_is_referenceable<int*>::value), "");
static_assert((std::__libcpp_is_referenceable<const int*>::value), "");
static_assert((std::__libcpp_is_referenceable<Foo>::value), "");
static_assert((std::__libcpp_is_referenceable<const Foo>::value), "");
static_assert((std::__libcpp_is_referenceable<Foo&>::value), "");
static_assert((std::__libcpp_is_referenceable<const Foo&>::value), "");
#if TEST_STD_VER >= 11
static_assert((std::__libcpp_is_referenceable<Foo&&>::value), "");
static_assert((std::__libcpp_is_referenceable<const Foo&&>::value), "");
#endif
static_assert((std::__libcpp_is_referenceable<int __attribute__((__vector_size__(8)))>::value), "");
static_assert((std::__libcpp_is_referenceable<const int __attribute__((__vector_size__(8)))>::value), "");
static_assert((std::__libcpp_is_referenceable<float __attribute__((__vector_size__(16)))>::value), "");
static_assert((std::__libcpp_is_referenceable<const float __attribute__((__vector_size__(16)))>::value), "");
// Functions without cv-qualifiers are referenceable
static_assert((std::__libcpp_is_referenceable<void()>::value), "");
#if TEST_STD_VER >= 11
static_assert((!std::__libcpp_is_referenceable<void() const>::value), "");
static_assert((!std::__libcpp_is_referenceable<void() &>::value), "");
static_assert((!std::__libcpp_is_referenceable<void() const&>::value), "");
static_assert((!std::__libcpp_is_referenceable<void() &&>::value), "");
static_assert((!std::__libcpp_is_referenceable<void() const&&>::value), "");
#endif
static_assert((std::__libcpp_is_referenceable<void(int)>::value), "");
#if TEST_STD_VER >= 11
static_assert((!std::__libcpp_is_referenceable<void(int) const>::value), "");
static_assert((!std::__libcpp_is_referenceable<void(int) &>::value), "");
static_assert((!std::__libcpp_is_referenceable<void(int) const&>::value), "");
static_assert((!std::__libcpp_is_referenceable<void(int) &&>::value), "");
static_assert((!std::__libcpp_is_referenceable<void(int) const&&>::value), "");
#endif
static_assert((std::__libcpp_is_referenceable<void(int, float)>::value), "");
#if TEST_STD_VER >= 11
static_assert((!std::__libcpp_is_referenceable<void(int, float) const>::value), "");
static_assert((!std::__libcpp_is_referenceable<void(int, float) &>::value), "");
static_assert((!std::__libcpp_is_referenceable<void(int, float) const&>::value), "");
static_assert((!std::__libcpp_is_referenceable<void(int, float) &&>::value), "");
static_assert((!std::__libcpp_is_referenceable<void(int, float) const&&>::value), "");
#endif
static_assert((std::__libcpp_is_referenceable<void(int, float, Foo&)>::value), "");
#if TEST_STD_VER >= 11
static_assert((!std::__libcpp_is_referenceable<void(int, float, Foo&) const>::value), "");
static_assert((!std::__libcpp_is_referenceable<void(int, float, Foo&) &>::value), "");
static_assert((!std::__libcpp_is_referenceable<void(int, float, Foo&) const&>::value), "");
static_assert((!std::__libcpp_is_referenceable<void(int, float, Foo&) &&>::value), "");
static_assert((!std::__libcpp_is_referenceable<void(int, float, Foo&) const&&>::value), "");
#endif
static_assert((std::__libcpp_is_referenceable<void(...)>::value), "");
#if TEST_STD_VER >= 11
static_assert((!std::__libcpp_is_referenceable<void(...) const>::value), "");
static_assert((!std::__libcpp_is_referenceable<void(...) &>::value), "");
static_assert((!std::__libcpp_is_referenceable<void(...) const&>::value), "");
static_assert((!std::__libcpp_is_referenceable<void(...) &&>::value), "");
static_assert((!std::__libcpp_is_referenceable<void(...) const&&>::value), "");
#endif
static_assert((std::__libcpp_is_referenceable<void(int, ...)>::value), "");
#if TEST_STD_VER >= 11
static_assert((!std::__libcpp_is_referenceable<void(int, ...) const>::value), "");
static_assert((!std::__libcpp_is_referenceable<void(int, ...) &>::value), "");
static_assert((!std::__libcpp_is_referenceable<void(int, ...) const&>::value), "");
static_assert((!std::__libcpp_is_referenceable<void(int, ...) &&>::value), "");
static_assert((!std::__libcpp_is_referenceable<void(int, ...) const&&>::value), "");
#endif
static_assert((std::__libcpp_is_referenceable<void(int, float, ...)>::value), "");
#if TEST_STD_VER >= 11
static_assert((!std::__libcpp_is_referenceable<void(int, float, ...) const>::value), "");
static_assert((!std::__libcpp_is_referenceable<void(int, float, ...) &>::value), "");
static_assert((!std::__libcpp_is_referenceable<void(int, float, ...) const&>::value), "");
static_assert((!std::__libcpp_is_referenceable<void(int, float, ...) &&>::value), "");
static_assert((!std::__libcpp_is_referenceable<void(int, float, ...) const&&>::value), "");
#endif
static_assert((std::__libcpp_is_referenceable<void(int, float, Foo&, ...)>::value), "");
#if TEST_STD_VER >= 11
static_assert((!std::__libcpp_is_referenceable<void(int, float, Foo&, ...) const>::value), "");
static_assert((!std::__libcpp_is_referenceable<void(int, float, Foo&, ...) &>::value), "");
static_assert((!std::__libcpp_is_referenceable<void(int, float, Foo&, ...) const&>::value), "");
static_assert((!std::__libcpp_is_referenceable<void(int, float, Foo&, ...) &&>::value), "");
static_assert((!std::__libcpp_is_referenceable<void(int, float, Foo&, ...) const&&>::value), "");
#endif
// member functions with or without cv-qualifiers are referenceable
static_assert((std::__libcpp_is_referenceable<void (Foo::*)()>::value), "");
static_assert((std::__libcpp_is_referenceable<void (Foo::*)() const>::value), "");
#if TEST_STD_VER >= 11
static_assert((std::__libcpp_is_referenceable<void (Foo::*)() &>::value), "");
static_assert((std::__libcpp_is_referenceable<void (Foo::*)() const&>::value), "");
static_assert((std::__libcpp_is_referenceable<void (Foo::*)() &&>::value), "");
static_assert((std::__libcpp_is_referenceable<void (Foo::*)() const&&>::value), "");
#endif
static_assert((std::__libcpp_is_referenceable<void (Foo::*)(int)>::value), "");
static_assert((std::__libcpp_is_referenceable<void (Foo::*)(int) const>::value), "");
#if TEST_STD_VER >= 11
static_assert((std::__libcpp_is_referenceable<void (Foo::*)(int) &>::value), "");
static_assert((std::__libcpp_is_referenceable<void (Foo::*)(int) const&>::value), "");
static_assert((std::__libcpp_is_referenceable<void (Foo::*)(int) &&>::value), "");
static_assert((std::__libcpp_is_referenceable<void (Foo::*)(int) const&&>::value), "");
#endif
static_assert((std::__libcpp_is_referenceable<void (Foo::*)(int, float)>::value), "");
static_assert((std::__libcpp_is_referenceable<void (Foo::*)(int, float) const>::value), "");
#if TEST_STD_VER >= 11
static_assert((std::__libcpp_is_referenceable<void (Foo::*)(int, float) &>::value), "");
static_assert((std::__libcpp_is_referenceable<void (Foo::*)(int, float) const&>::value), "");
static_assert((std::__libcpp_is_referenceable<void (Foo::*)(int, float) &&>::value), "");
static_assert((std::__libcpp_is_referenceable<void (Foo::*)(int, float) const&&>::value), "");
#endif
static_assert((std::__libcpp_is_referenceable<void (Foo::*)(int, float, Foo&)>::value), "");
static_assert((std::__libcpp_is_referenceable<void (Foo::*)(int, float, Foo&) const>::value), "");
#if TEST_STD_VER >= 11
static_assert((std::__libcpp_is_referenceable<void (Foo::*)(int, float, Foo&) &>::value), "");
static_assert((std::__libcpp_is_referenceable<void (Foo::*)(int, float, Foo&) const&>::value), "");
static_assert((std::__libcpp_is_referenceable<void (Foo::*)(int, float, Foo&) &&>::value), "");
static_assert((std::__libcpp_is_referenceable<void (Foo::*)(int, float, Foo&) const&&>::value), "");
#endif
static_assert((std::__libcpp_is_referenceable<void (Foo::*)(...)>::value), "");
static_assert((std::__libcpp_is_referenceable<void (Foo::*)(...) const>::value), "");
#if TEST_STD_VER >= 11
static_assert((std::__libcpp_is_referenceable<void (Foo::*)(...) &>::value), "");
static_assert((std::__libcpp_is_referenceable<void (Foo::*)(...) const&>::value), "");
static_assert((std::__libcpp_is_referenceable<void (Foo::*)(...) &&>::value), "");
static_assert((std::__libcpp_is_referenceable<void (Foo::*)(...) const&&>::value), "");
#endif
static_assert((std::__libcpp_is_referenceable<void (Foo::*)(int, ...)>::value), "");
static_assert((std::__libcpp_is_referenceable<void (Foo::*)(int, ...) const>::value), "");
#if TEST_STD_VER >= 11
static_assert((std::__libcpp_is_referenceable<void (Foo::*)(int, ...) &>::value), "");
static_assert((std::__libcpp_is_referenceable<void (Foo::*)(int, ...) const&>::value), "");
static_assert((std::__libcpp_is_referenceable<void (Foo::*)(int, ...) &&>::value), "");
static_assert((std::__libcpp_is_referenceable<void (Foo::*)(int, ...) const&&>::value), "");
#endif
static_assert((std::__libcpp_is_referenceable<void (Foo::*)(int, float, ...)>::value), "");
static_assert((std::__libcpp_is_referenceable<void (Foo::*)(int, float, ...) const>::value), "");
#if TEST_STD_VER >= 11
static_assert((std::__libcpp_is_referenceable<void (Foo::*)(int, float, ...) &>::value), "");
static_assert((std::__libcpp_is_referenceable<void (Foo::*)(int, float, ...) const&>::value), "");
static_assert((std::__libcpp_is_referenceable<void (Foo::*)(int, float, ...) &&>::value), "");
static_assert((std::__libcpp_is_referenceable<void (Foo::*)(int, float, ...) const&&>::value), "");
#endif
static_assert((std::__libcpp_is_referenceable<void (Foo::*)(int, float, Foo&, ...)>::value), "");
static_assert((std::__libcpp_is_referenceable<void (Foo::*)(int, float, Foo&, ...) const>::value), "");
#if TEST_STD_VER >= 11
static_assert((std::__libcpp_is_referenceable<void (Foo::*)(int, float, Foo&, ...) &>::value), "");
static_assert((std::__libcpp_is_referenceable<void (Foo::*)(int, float, Foo&, ...) const&>::value), "");
static_assert((std::__libcpp_is_referenceable<void (Foo::*)(int, float, Foo&, ...) &&>::value), "");
static_assert((std::__libcpp_is_referenceable<void (Foo::*)(int, float, Foo&, ...) const&&>::value), "");
#endif
int main(int, char**) {
return 0;
}

View File

@ -10,6 +10,8 @@
// Simple test to check that type traits support Objective-C types.
// XFAIL: FROZEN-CXX03-HEADERS-FIXME
#include <type_traits>
#include "test_macros.h"
@ -33,15 +35,15 @@ 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, "");
// __is_referenceable_v
LIBCPP_STATIC_ASSERT(std::__is_referenceable_v<id>, "");
LIBCPP_STATIC_ASSERT(std::__is_referenceable_v<id*>, "");
LIBCPP_STATIC_ASSERT(std::__is_referenceable_v<id&>, "");
LIBCPP_STATIC_ASSERT(std::__is_referenceable_v<id&&>, "");
LIBCPP_STATIC_ASSERT(std::__is_referenceable_v<I>, "");
LIBCPP_STATIC_ASSERT(std::__is_referenceable_v<I*>, "");
LIBCPP_STATIC_ASSERT(std::__is_referenceable_v<I&>, "");
LIBCPP_STATIC_ASSERT(std::__is_referenceable_v<I&&>, "");
// remove_all_extents
static_assert(std::is_same<std::remove_all_extents<id>::type, id>::value, "");