diff --git a/libc/src/__support/CPP/type_traits/is_signed.h b/libc/src/__support/CPP/type_traits/is_signed.h index 3f56fb38aabb0..2ddb43ac4ee3e 100644 --- a/libc/src/__support/CPP/type_traits/is_signed.h +++ b/libc/src/__support/CPP/type_traits/is_signed.h @@ -8,20 +8,43 @@ #ifndef LLVM_LIBC_SRC___SUPPORT_CPP_TYPE_TRAITS_IS_SIGNED_H #define LLVM_LIBC_SRC___SUPPORT_CPP_TYPE_TRAITS_IS_SIGNED_H +#include "include/llvm-libc-macros/stdfix-macros.h" #include "src/__support/CPP/type_traits/bool_constant.h" #include "src/__support/CPP/type_traits/is_arithmetic.h" +#include "src/__support/CPP/type_traits/is_same.h" +#include "src/__support/CPP/type_traits/remove_cv.h" #include "src/__support/macros/attributes.h" #include "src/__support/macros/config.h" namespace LIBC_NAMESPACE_DECL { namespace cpp { -// is_signed +#ifndef LIBC_COMPILER_HAS_FIXED_POINT template struct is_signed : bool_constant<(is_arithmetic_v && (T(-1) < T(0)))> { LIBC_INLINE constexpr operator bool() const { return is_signed::value; } LIBC_INLINE constexpr bool operator()() const { return is_signed::value; } }; +#else +template struct is_signed { +private: + template + LIBC_INLINE static constexpr bool __is_unqualified_any_of() { + return (... || is_same_v, Args>); + } + +public: + LIBC_INLINE_VAR static constexpr bool value = + (is_arithmetic_v && (T(-1) < T(0))) || + __is_unqualified_any_of(); + LIBC_INLINE constexpr operator bool() const { return is_signed::value; } + LIBC_INLINE constexpr bool operator()() const { return is_signed::value; } +}; +#endif // LIBC_COMPILER_HAS_FIXED_POINT + template LIBC_INLINE_VAR constexpr bool is_signed_v = is_signed::value; diff --git a/libc/src/__support/CPP/type_traits/is_unsigned.h b/libc/src/__support/CPP/type_traits/is_unsigned.h index eed519b1c067e..3ae6337ceb50a 100644 --- a/libc/src/__support/CPP/type_traits/is_unsigned.h +++ b/libc/src/__support/CPP/type_traits/is_unsigned.h @@ -8,20 +8,45 @@ #ifndef LLVM_LIBC_SRC___SUPPORT_CPP_TYPE_TRAITS_IS_UNSIGNED_H #define LLVM_LIBC_SRC___SUPPORT_CPP_TYPE_TRAITS_IS_UNSIGNED_H +#include "include/llvm-libc-macros/stdfix-macros.h" #include "src/__support/CPP/type_traits/bool_constant.h" #include "src/__support/CPP/type_traits/is_arithmetic.h" +#include "src/__support/CPP/type_traits/is_same.h" +#include "src/__support/CPP/type_traits/remove_cv.h" #include "src/__support/macros/attributes.h" #include "src/__support/macros/config.h" namespace LIBC_NAMESPACE_DECL { namespace cpp { -// is_unsigned +#ifndef LIBC_COMPILER_HAS_FIXED_POINT template struct is_unsigned : bool_constant<(is_arithmetic_v && (T(-1) > T(0)))> { LIBC_INLINE constexpr operator bool() const { return is_unsigned::value; } LIBC_INLINE constexpr bool operator()() const { return is_unsigned::value; } }; +#else +template struct is_unsigned { +private: + template + LIBC_INLINE static constexpr bool __is_unqualified_any_of() { + return (... || is_same_v, Args>); + } + +public: + LIBC_INLINE_VAR static constexpr bool value = + (is_arithmetic_v && (T(-1) > T(0))) || + __is_unqualified_any_of(); + LIBC_INLINE constexpr operator bool() const { return is_unsigned::value; } + LIBC_INLINE constexpr bool operator()() const { return is_unsigned::value; } +}; +#endif // LIBC_COMPILER_HAS_FIXED_POINT + template LIBC_INLINE_VAR constexpr bool is_unsigned_v = is_unsigned::value; diff --git a/libc/test/src/__support/CPP/type_traits_test.cpp b/libc/test/src/__support/CPP/type_traits_test.cpp index 4b3e48c6a6c0f..3a607ec286051 100644 --- a/libc/test/src/__support/CPP/type_traits_test.cpp +++ b/libc/test/src/__support/CPP/type_traits_test.cpp @@ -6,6 +6,7 @@ // //===----------------------------------------------------------------------===// +#include "include/llvm-libc-macros/stdfix-macros.h" #include "src/__support/CPP/type_traits.h" #include "src/__support/macros/config.h" #include "test/UnitTest/Test.h" @@ -409,7 +410,37 @@ TEST(LlvmLibcTypeTraitsTest, is_object) { // TODO is_scalar -// TODO is_signed +TEST(LlvmLibcTypeTraitsTest, is_signed) { + EXPECT_TRUE((is_signed_v)); + EXPECT_TRUE((is_signed_v)); + EXPECT_TRUE((is_signed_v)); + EXPECT_FALSE((is_signed_v)); + EXPECT_FALSE((is_signed_v)); + EXPECT_FALSE((is_signed_v)); + EXPECT_TRUE((is_signed_v)); + EXPECT_TRUE((is_signed_v)); + EXPECT_TRUE((is_signed_v)); + +#ifdef LIBC_COMPILER_HAS_FIXED_POINT + // for fixed point types + EXPECT_TRUE((is_signed_v)); + EXPECT_FALSE((is_signed_v)); + EXPECT_TRUE((is_signed_v)); + EXPECT_FALSE((is_signed_v)); + EXPECT_TRUE((is_signed_v)); + EXPECT_FALSE((is_signed_v)); + EXPECT_TRUE((is_signed_v)); + EXPECT_FALSE((is_signed_v)); + EXPECT_TRUE((is_signed_v)); + EXPECT_FALSE((is_signed_v)); + EXPECT_TRUE((is_signed_v)); + EXPECT_FALSE((is_signed_v)); + EXPECT_TRUE((is_signed_v)); + EXPECT_FALSE((is_signed_v)); + EXPECT_TRUE((is_signed_v)); + EXPECT_FALSE((is_signed_v)); +#endif +} // TODO is_trivially_constructible @@ -419,7 +450,37 @@ TEST(LlvmLibcTypeTraitsTest, is_object) { // TODO is_union -// TODO is_unsigned +TEST(LlvmLibcTypeTraitsTest, is_unsigned) { + EXPECT_FALSE((is_unsigned_v)); + EXPECT_FALSE((is_unsigned_v)); + EXPECT_FALSE((is_unsigned_v)); + EXPECT_TRUE((is_unsigned_v)); + EXPECT_TRUE((is_unsigned_v)); + EXPECT_TRUE((is_unsigned_v)); + EXPECT_FALSE((is_unsigned_v)); + EXPECT_FALSE((is_unsigned_v)); + EXPECT_FALSE((is_unsigned_v)); + +#ifdef LIBC_COMPILER_HAS_FIXED_POINT + // for fixed point types + EXPECT_FALSE((is_unsigned_v)); + EXPECT_TRUE((is_unsigned_v)); + EXPECT_FALSE((is_unsigned_v)); + EXPECT_TRUE((is_unsigned_v)); + EXPECT_FALSE((is_unsigned_v)); + EXPECT_TRUE((is_unsigned_v)); + EXPECT_FALSE((is_unsigned_v)); + EXPECT_TRUE((is_unsigned_v)); + EXPECT_FALSE((is_unsigned_v)); + EXPECT_TRUE((is_unsigned_v)); + EXPECT_FALSE((is_unsigned_v)); + EXPECT_TRUE((is_unsigned_v)); + EXPECT_FALSE((is_unsigned_v)); + EXPECT_TRUE((is_unsigned_v)); + EXPECT_FALSE((is_unsigned_v)); + EXPECT_TRUE((is_unsigned_v)); +#endif +} // TODO is_void