forked from OSchip/llvm-project
[libcxx][type_traits] add tests for is_signed and is_unsigned
In previous versions of clang, __is_signed and __is_unsigned builtins did not correspond to is_signed and is_unsigned behaviour for enums. The builtins were fixed in D67897 and D98104. * Disable the fast path of is_unsigned for clang versions < 13 * Add more tests for is_signed, is_unsigned and is_arithmetic Differential Revision: https://reviews.llvm.org/D97283
This commit is contained in:
parent
440f6bdf34
commit
64595f9b84
|
@ -1451,7 +1451,8 @@ _LIBCPP_INLINE_VAR _LIBCPP_CONSTEXPR bool is_signed_v
|
|||
|
||||
// is_unsigned
|
||||
|
||||
#if __has_keyword(__is_unsigned)
|
||||
// Before clang 13, __is_unsigned returned true for enums with signed underlying type
|
||||
#if __has_keyword(__is_unsigned) && _LIBCPP_CLANG_VER >= 1300
|
||||
|
||||
template<class _Tp>
|
||||
struct _LIBCPP_TEMPLATE_VIS is_unsigned : _BoolConstant<__is_unsigned(_Tp)> { };
|
||||
|
@ -1461,7 +1462,7 @@ template <class _Tp>
|
|||
_LIBCPP_INLINE_VAR _LIBCPP_CONSTEXPR bool is_unsigned_v = __is_unsigned(_Tp);
|
||||
#endif
|
||||
|
||||
#else // __has_keyword(__is_unsigned)
|
||||
#else // __has_keyword(__is_unsigned) && _LIBCPP_CLANG_VER >= 1300
|
||||
|
||||
template <class _Tp, bool = is_integral<_Tp>::value>
|
||||
struct __libcpp_is_unsigned_impl : public _LIBCPP_BOOL_CONSTANT(_Tp(0) < _Tp(-1)) {};
|
||||
|
@ -1482,7 +1483,7 @@ _LIBCPP_INLINE_VAR _LIBCPP_CONSTEXPR bool is_unsigned_v
|
|||
= is_unsigned<_Tp>::value;
|
||||
#endif
|
||||
|
||||
#endif // __has_keyword(__is_unsigned)
|
||||
#endif // __has_keyword(__is_unsigned) && _LIBCPP_CLANG_VER >= 1300
|
||||
|
||||
// rank
|
||||
|
||||
|
|
|
@ -69,6 +69,12 @@ class Abstract
|
|||
|
||||
enum Enum {zero, one};
|
||||
|
||||
enum EnumSigned : int { two };
|
||||
|
||||
enum EnumUnsigned : unsigned { three };
|
||||
|
||||
enum class EnumClass { zero, one };
|
||||
|
||||
typedef void (*FunctionPtr)();
|
||||
|
||||
|
||||
|
@ -97,6 +103,9 @@ int main(int, char**)
|
|||
test_is_not_arithmetic<char[]>();
|
||||
test_is_not_arithmetic<Union>();
|
||||
test_is_not_arithmetic<Enum>();
|
||||
test_is_not_arithmetic<EnumSigned>();
|
||||
test_is_not_arithmetic<EnumUnsigned>();
|
||||
test_is_not_arithmetic<EnumClass>();
|
||||
test_is_not_arithmetic<FunctionPtr>();
|
||||
test_is_not_arithmetic<Empty>();
|
||||
test_is_not_arithmetic<incomplete_type>();
|
||||
|
|
|
@ -51,21 +51,73 @@ public:
|
|||
|
||||
struct A; // incomplete
|
||||
|
||||
class incomplete_type;
|
||||
|
||||
class Empty {};
|
||||
|
||||
class NotEmpty {
|
||||
virtual ~NotEmpty();
|
||||
};
|
||||
|
||||
union Union {};
|
||||
|
||||
struct bit_zero {
|
||||
int : 0;
|
||||
};
|
||||
|
||||
class Abstract {
|
||||
virtual ~Abstract() = 0;
|
||||
};
|
||||
|
||||
enum Enum { zero, one };
|
||||
|
||||
enum EnumSigned : int { two };
|
||||
|
||||
enum EnumUnsigned : unsigned { three };
|
||||
|
||||
enum class EnumClass { zero, one };
|
||||
|
||||
typedef void (*FunctionPtr)();
|
||||
|
||||
int main(int, char**)
|
||||
{
|
||||
test_is_not_signed<void>();
|
||||
test_is_not_signed<int&>();
|
||||
test_is_not_signed<Class>();
|
||||
test_is_not_signed<int*>();
|
||||
test_is_not_signed<const int*>();
|
||||
test_is_not_signed<char[3]>();
|
||||
test_is_not_signed<char[]>();
|
||||
test_is_not_signed<bool>();
|
||||
test_is_not_signed<unsigned>();
|
||||
test_is_not_signed<A>();
|
||||
// Cases where !is_arithmetic implies !is_signed
|
||||
test_is_not_signed<std::nullptr_t>();
|
||||
test_is_not_signed<void>();
|
||||
test_is_not_signed<int&>();
|
||||
test_is_not_signed<int&&>();
|
||||
test_is_not_signed<Class>();
|
||||
test_is_not_signed<int*>();
|
||||
test_is_not_signed<const int*>();
|
||||
test_is_not_signed<char[3]>();
|
||||
test_is_not_signed<char[]>();
|
||||
test_is_not_signed<Union>();
|
||||
test_is_not_signed<Enum>();
|
||||
test_is_not_signed<EnumSigned>();
|
||||
test_is_not_signed<EnumUnsigned>();
|
||||
test_is_not_signed<EnumClass>();
|
||||
test_is_not_signed<FunctionPtr>();
|
||||
test_is_not_signed<Empty>();
|
||||
test_is_not_signed<incomplete_type>();
|
||||
test_is_not_signed<A>();
|
||||
test_is_not_signed<bit_zero>();
|
||||
test_is_not_signed<NotEmpty>();
|
||||
test_is_not_signed<Abstract>();
|
||||
|
||||
test_is_signed<int>();
|
||||
test_is_signed<double>();
|
||||
test_is_signed<signed char>();
|
||||
test_is_signed<short>();
|
||||
test_is_signed<int>();
|
||||
test_is_signed<long>();
|
||||
test_is_signed<float>();
|
||||
test_is_signed<double>();
|
||||
|
||||
test_is_not_signed<unsigned char>();
|
||||
test_is_not_signed<unsigned short>();
|
||||
test_is_not_signed<unsigned int>();
|
||||
test_is_not_signed<unsigned long>();
|
||||
|
||||
test_is_not_signed<bool>();
|
||||
test_is_not_signed<unsigned>();
|
||||
|
||||
#ifndef _LIBCPP_HAS_NO_INT128
|
||||
test_is_signed<__int128_t>();
|
||||
|
|
|
@ -51,21 +51,73 @@ public:
|
|||
|
||||
struct A; // incomplete
|
||||
|
||||
class incomplete_type;
|
||||
|
||||
class Empty {};
|
||||
|
||||
class NotEmpty {
|
||||
virtual ~NotEmpty();
|
||||
};
|
||||
|
||||
union Union {};
|
||||
|
||||
struct bit_zero {
|
||||
int : 0;
|
||||
};
|
||||
|
||||
class Abstract {
|
||||
virtual ~Abstract() = 0;
|
||||
};
|
||||
|
||||
enum Enum { zero, one };
|
||||
|
||||
enum EnumSigned : int { two };
|
||||
|
||||
enum EnumUnsigned : unsigned { three };
|
||||
|
||||
enum class EnumClass { zero, one };
|
||||
|
||||
typedef void (*FunctionPtr)();
|
||||
|
||||
int main(int, char**)
|
||||
{
|
||||
test_is_not_unsigned<void>();
|
||||
test_is_not_unsigned<int&>();
|
||||
test_is_not_unsigned<Class>();
|
||||
test_is_not_unsigned<int*>();
|
||||
test_is_not_unsigned<const int*>();
|
||||
test_is_not_unsigned<char[3]>();
|
||||
test_is_not_unsigned<char[]>();
|
||||
test_is_not_unsigned<int>();
|
||||
test_is_not_unsigned<double>();
|
||||
test_is_not_unsigned<A>();
|
||||
// Cases where !is_arithmetic implies !is_unsigned
|
||||
test_is_not_unsigned<std::nullptr_t>();
|
||||
test_is_not_unsigned<void>();
|
||||
test_is_not_unsigned<int&>();
|
||||
test_is_not_unsigned<int&&>();
|
||||
test_is_not_unsigned<Class>();
|
||||
test_is_not_unsigned<int*>();
|
||||
test_is_not_unsigned<const int*>();
|
||||
test_is_not_unsigned<char[3]>();
|
||||
test_is_not_unsigned<char[]>();
|
||||
test_is_not_unsigned<Union>();
|
||||
test_is_not_unsigned<Enum>();
|
||||
test_is_not_unsigned<EnumSigned>();
|
||||
test_is_not_unsigned<EnumUnsigned>();
|
||||
test_is_not_unsigned<EnumClass>();
|
||||
test_is_not_unsigned<FunctionPtr>();
|
||||
test_is_not_unsigned<Empty>();
|
||||
test_is_not_unsigned<incomplete_type>();
|
||||
test_is_not_unsigned<A>();
|
||||
test_is_not_unsigned<bit_zero>();
|
||||
test_is_not_unsigned<NotEmpty>();
|
||||
test_is_not_unsigned<Abstract>();
|
||||
|
||||
test_is_unsigned<bool>();
|
||||
test_is_unsigned<unsigned>();
|
||||
test_is_not_unsigned<signed char>();
|
||||
test_is_not_unsigned<short>();
|
||||
test_is_not_unsigned<int>();
|
||||
test_is_not_unsigned<long>();
|
||||
test_is_not_unsigned<float>();
|
||||
test_is_not_unsigned<double>();
|
||||
|
||||
test_is_unsigned<unsigned char>();
|
||||
test_is_unsigned<unsigned short>();
|
||||
test_is_unsigned<unsigned int>();
|
||||
test_is_unsigned<unsigned long>();
|
||||
|
||||
test_is_unsigned<bool>();
|
||||
test_is_unsigned<unsigned>();
|
||||
|
||||
#ifndef _LIBCPP_HAS_NO_INT128
|
||||
test_is_unsigned<__uint128_t>();
|
||||
|
|
Loading…
Reference in New Issue