[libc-commits] [libc] [libc] Added support for fixed-points in ``is_signed`` and ``is_unsigned``. (PR #133371)

Abhinav Kumar via libc-commits libc-commits at lists.llvm.org
Sun Mar 30 19:30:10 PDT 2025


https://github.com/kr-2003 updated https://github.com/llvm/llvm-project/pull/133371

>From d967f431f9382ab80dc034450251ea8c32fa1537 Mon Sep 17 00:00:00 2001
From: kr-2003 <kumar.kr.abhinav at gmail.com>
Date: Fri, 28 Mar 2025 11:13:44 +0530
Subject: [PATCH 1/9] added support of fixed-points in is_signed and
 is_unsigned

---
 .../src/__support/CPP/type_traits/is_signed.h | 69 ++++++++++++++++++-
 .../__support/CPP/type_traits/is_unsigned.h   | 69 ++++++++++++++++++-
 .../src/__support/CPP/type_traits_test.cpp    | 61 +++++++++++++++-
 3 files changed, 193 insertions(+), 6 deletions(-)

diff --git a/libc/src/__support/CPP/type_traits/is_signed.h b/libc/src/__support/CPP/type_traits/is_signed.h
index 3f56fb38aabb0..699b017eda183 100644
--- a/libc/src/__support/CPP/type_traits/is_signed.h
+++ b/libc/src/__support/CPP/type_traits/is_signed.h
@@ -8,20 +8,85 @@
 #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_fixed_point.h"
 #include "src/__support/macros/attributes.h"
 #include "src/__support/macros/config.h"
 
 namespace LIBC_NAMESPACE_DECL {
 namespace cpp {
 
-// is_signed
+// Primary template: handles arithmetic and signed fixed-point types
 template <typename T>
-struct is_signed : bool_constant<(is_arithmetic_v<T> && (T(-1) < T(0)))> {
+struct is_signed : bool_constant<((is_fixed_point_v<T> || is_arithmetic_v<T>) && (T(-1) < T(0)))> {
   LIBC_INLINE constexpr operator bool() const { return is_signed::value; }
   LIBC_INLINE constexpr bool operator()() const { return is_signed::value; }
 };
+
+// Specializations for unsigned fixed-point types
+template <>
+struct is_signed<unsigned short fract> : bool_constant<false> {
+  LIBC_INLINE constexpr operator bool() const { return is_signed::value; }
+  LIBC_INLINE constexpr bool operator()() const { return is_signed::value; }
+};
+template <>
+struct is_signed<unsigned fract> : bool_constant<false> {
+  LIBC_INLINE constexpr operator bool() const { return is_signed::value; }
+  LIBC_INLINE constexpr bool operator()() const { return is_signed::value; }
+};
+template <>
+struct is_signed<unsigned long fract> : bool_constant<false> {
+  LIBC_INLINE constexpr operator bool() const { return is_signed::value; }
+  LIBC_INLINE constexpr bool operator()() const { return is_signed::value; }
+};
+template <>
+struct is_signed<unsigned short accum> : bool_constant<false> {
+  LIBC_INLINE constexpr operator bool() const { return is_signed::value; }
+  LIBC_INLINE constexpr bool operator()() const { return is_signed::value; }
+};
+template <>
+struct is_signed<unsigned accum> : bool_constant<false> {
+  LIBC_INLINE constexpr operator bool() const { return is_signed::value; }
+  LIBC_INLINE constexpr bool operator()() const { return is_signed::value; }
+};
+template <>
+struct is_signed<unsigned long accum> : bool_constant<false> {
+  LIBC_INLINE constexpr operator bool() const { return is_signed::value; }
+  LIBC_INLINE constexpr bool operator()() const { return is_signed::value; }
+};
+template <>
+struct is_signed<unsigned short sat fract> : bool_constant<false> {
+  LIBC_INLINE constexpr operator bool() const { return is_signed::value; }
+  LIBC_INLINE constexpr bool operator()() const { return is_signed::value; }
+};
+template <>
+struct is_signed<unsigned sat fract> : bool_constant<false> {
+  LIBC_INLINE constexpr operator bool() const { return is_signed::value; }
+  LIBC_INLINE constexpr bool operator()() const { return is_signed::value; }
+};
+template <>
+struct is_signed<unsigned long sat fract> : bool_constant<false> {
+  LIBC_INLINE constexpr operator bool() const { return is_signed::value; }
+  LIBC_INLINE constexpr bool operator()() const { return is_signed::value; }
+};
+template <>
+struct is_signed<unsigned short sat accum> : bool_constant<false> {
+  LIBC_INLINE constexpr operator bool() const { return is_signed::value; }
+  LIBC_INLINE constexpr bool operator()() const { return is_signed::value; }
+};
+template <>
+struct is_signed<unsigned sat accum> : bool_constant<false> {
+  LIBC_INLINE constexpr operator bool() const { return is_signed::value; }
+  LIBC_INLINE constexpr bool operator()() const { return is_signed::value; }
+};
+template <>
+struct is_signed<unsigned long sat accum> : bool_constant<false> {
+  LIBC_INLINE constexpr operator bool() const { return is_signed::value; }
+  LIBC_INLINE constexpr bool operator()() const { return is_signed::value; }
+};
+
 template <typename T>
 LIBC_INLINE_VAR constexpr bool is_signed_v = is_signed<T>::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..58cd3f0f598a9 100644
--- a/libc/src/__support/CPP/type_traits/is_unsigned.h
+++ b/libc/src/__support/CPP/type_traits/is_unsigned.h
@@ -8,20 +8,85 @@
 #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_fixed_point.h"
 #include "src/__support/macros/attributes.h"
 #include "src/__support/macros/config.h"
 
 namespace LIBC_NAMESPACE_DECL {
 namespace cpp {
 
-// is_unsigned
+// Primary template: handles arithmetic and signed fixed-point types
 template <typename T>
-struct is_unsigned : bool_constant<(is_arithmetic_v<T> && (T(-1) > T(0)))> {
+struct is_unsigned : bool_constant<((is_fixed_point_v<T> || is_arithmetic_v<T>) && (T(-1) > T(0)))> {
   LIBC_INLINE constexpr operator bool() const { return is_unsigned::value; }
   LIBC_INLINE constexpr bool operator()() const { return is_unsigned::value; }
 };
+
+// Specializations for unsigned fixed-point types
+template <>
+struct is_unsigned<unsigned short fract> : bool_constant<true> {
+  LIBC_INLINE constexpr operator bool() const { return is_unsigned::value; }
+  LIBC_INLINE constexpr bool operator()() const { return is_unsigned::value; }
+};
+template <>
+struct is_unsigned<unsigned fract> : bool_constant<true> {
+  LIBC_INLINE constexpr operator bool() const { return is_unsigned::value; }
+  LIBC_INLINE constexpr bool operator()() const { return is_unsigned::value; }
+};
+template <>
+struct is_unsigned<unsigned long fract> : bool_constant<true> {
+  LIBC_INLINE constexpr operator bool() const { return is_unsigned::value; }
+  LIBC_INLINE constexpr bool operator()() const { return is_unsigned::value; }
+};
+template <>
+struct is_unsigned<unsigned short accum> : bool_constant<true> {
+  LIBC_INLINE constexpr operator bool() const { return is_unsigned::value; }
+  LIBC_INLINE constexpr bool operator()() const { return is_unsigned::value; }
+};
+template <>
+struct is_unsigned<unsigned accum> : bool_constant<true> {
+  LIBC_INLINE constexpr operator bool() const { return is_unsigned::value; }
+  LIBC_INLINE constexpr bool operator()() const { return is_unsigned::value; }
+};
+template <>
+struct is_unsigned<unsigned long accum> : bool_constant<true> {
+  LIBC_INLINE constexpr operator bool() const { return is_unsigned::value; }
+  LIBC_INLINE constexpr bool operator()() const { return is_unsigned::value; }
+};
+template <>
+struct is_unsigned<unsigned short sat fract> : bool_constant<true> {
+  LIBC_INLINE constexpr operator bool() const { return is_unsigned::value; }
+  LIBC_INLINE constexpr bool operator()() const { return is_unsigned::value; }
+};
+template <>
+struct is_unsigned<unsigned sat fract> : bool_constant<true> {
+  LIBC_INLINE constexpr operator bool() const { return is_unsigned::value; }
+  LIBC_INLINE constexpr bool operator()() const { return is_unsigned::value; }
+};
+template <>
+struct is_unsigned<unsigned long sat fract> : bool_constant<true> {
+  LIBC_INLINE constexpr operator bool() const { return is_unsigned::value; }
+  LIBC_INLINE constexpr bool operator()() const { return is_unsigned::value; }
+};
+template <>
+struct is_unsigned<unsigned short sat accum> : bool_constant<true> {
+  LIBC_INLINE constexpr operator bool() const { return is_unsigned::value; }
+  LIBC_INLINE constexpr bool operator()() const { return is_unsigned::value; }
+};
+template <>
+struct is_unsigned<unsigned sat accum> : bool_constant<true> {
+  LIBC_INLINE constexpr operator bool() const { return is_unsigned::value; }
+  LIBC_INLINE constexpr bool operator()() const { return is_unsigned::value; }
+};
+template <>
+struct is_unsigned<unsigned long sat accum> : bool_constant<true> {
+  LIBC_INLINE constexpr operator bool() const { return is_unsigned::value; }
+  LIBC_INLINE constexpr bool operator()() const { return is_unsigned::value; }
+};
+
 template <typename T>
 LIBC_INLINE_VAR constexpr bool is_unsigned_v = is_unsigned<T>::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..338705efa5e80 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,35 @@ TEST(LlvmLibcTypeTraitsTest, is_object) {
 
 // TODO is_scalar
 
-// TODO is_signed
+TEST(LlvmLibcTypeTraitsTest, is_signed) {
+  EXPECT_TRUE((is_signed_v<int>));
+  EXPECT_TRUE((is_signed_v<long>));
+  EXPECT_TRUE((is_signed_v<long long>));
+  EXPECT_FALSE((is_signed_v<unsigned int>));
+  EXPECT_FALSE((is_signed_v<unsigned long>));
+  EXPECT_FALSE((is_signed_v<unsigned long long>));
+  EXPECT_TRUE((is_signed_v<float>));
+  EXPECT_TRUE((is_signed_v<double>));
+  EXPECT_TRUE((is_signed_v<long double>));
+
+  // for fixed point types
+  EXPECT_TRUE((is_signed_v<fract>));
+  EXPECT_FALSE((is_signed_v<unsigned fract>));
+  EXPECT_TRUE((is_signed_v<accum>));
+  EXPECT_FALSE((is_signed_v<unsigned accum>));
+  EXPECT_TRUE((is_signed_v<sat fract>));
+  EXPECT_FALSE((is_signed_v<unsigned sat fract>));
+  EXPECT_TRUE((is_signed_v<sat accum>));
+  EXPECT_FALSE((is_signed_v<unsigned sat accum>));
+  EXPECT_TRUE((is_signed_v<short fract>));
+  EXPECT_FALSE((is_signed_v<unsigned short fract>));
+  EXPECT_TRUE((is_signed_v<short accum>));
+  EXPECT_FALSE((is_signed_v<unsigned short accum>));
+  EXPECT_TRUE((is_signed_v<long fract>));
+  EXPECT_FALSE((is_signed_v<unsigned long fract>));
+  EXPECT_TRUE((is_signed_v<long accum>));
+  EXPECT_FALSE((is_signed_v<unsigned long accum>));
+}
 
 // TODO is_trivially_constructible
 
@@ -419,7 +448,35 @@ TEST(LlvmLibcTypeTraitsTest, is_object) {
 
 // TODO is_union
 
-// TODO is_unsigned
+TEST(LlvmLibcTypeTraitsTest, is_unsigned) {
+  EXPECT_FALSE((is_unsigned_v<int>));
+  EXPECT_FALSE((is_unsigned_v<long>));
+  EXPECT_FALSE((is_unsigned_v<long long>));
+  EXPECT_TRUE((is_unsigned_v<unsigned int>));
+  EXPECT_TRUE((is_unsigned_v<unsigned long>));
+  EXPECT_TRUE((is_unsigned_v<unsigned long long>));
+  EXPECT_FALSE((is_unsigned_v<float>));
+  EXPECT_FALSE((is_unsigned_v<double>));
+  EXPECT_FALSE((is_unsigned_v<long double>));
+
+  // for fixed point types
+  EXPECT_FALSE((is_unsigned_v<fract>));
+  EXPECT_TRUE((is_unsigned_v<unsigned fract>));
+  EXPECT_FALSE((is_unsigned_v<accum>));
+  EXPECT_TRUE((is_unsigned_v<unsigned accum>));
+  EXPECT_FALSE((is_unsigned_v<sat fract>));
+  EXPECT_TRUE((is_unsigned_v<unsigned sat fract>));
+  EXPECT_FALSE((is_unsigned_v<sat accum>));
+  EXPECT_TRUE((is_unsigned_v<unsigned sat accum>));
+  EXPECT_FALSE((is_unsigned_v<short fract>));
+  EXPECT_TRUE((is_unsigned_v<unsigned short fract>));
+  EXPECT_FALSE((is_unsigned_v<short accum>));
+  EXPECT_TRUE((is_unsigned_v<unsigned short accum>));
+  EXPECT_FALSE((is_unsigned_v<long fract>));
+  EXPECT_TRUE((is_unsigned_v<unsigned long fract>));
+  EXPECT_FALSE((is_unsigned_v<long accum>));
+  EXPECT_TRUE((is_unsigned_v<unsigned long accum>));
+}
 
 // TODO is_void
 

>From b778f8f31eb7d2fe571d33216ad29ac2e861ff19 Mon Sep 17 00:00:00 2001
From: kr-2003 <kumar.kr.abhinav at gmail.com>
Date: Fri, 28 Mar 2025 11:26:28 +0530
Subject: [PATCH 2/9] minor changes

---
 .../src/__support/CPP/type_traits/is_signed.h | 24 +++++++++----------
 .../__support/CPP/type_traits/is_unsigned.h   | 12 +++++-----
 2 files changed, 18 insertions(+), 18 deletions(-)

diff --git a/libc/src/__support/CPP/type_traits/is_signed.h b/libc/src/__support/CPP/type_traits/is_signed.h
index 699b017eda183..7299ac4314658 100644
--- a/libc/src/__support/CPP/type_traits/is_signed.h
+++ b/libc/src/__support/CPP/type_traits/is_signed.h
@@ -27,62 +27,62 @@ struct is_signed : bool_constant<((is_fixed_point_v<T> || is_arithmetic_v<T>) &&
 
 // Specializations for unsigned fixed-point types
 template <>
-struct is_signed<unsigned short fract> : bool_constant<false> {
+struct is_signed<unsigned short _Fract> : bool_constant<false> {
   LIBC_INLINE constexpr operator bool() const { return is_signed::value; }
   LIBC_INLINE constexpr bool operator()() const { return is_signed::value; }
 };
 template <>
-struct is_signed<unsigned fract> : bool_constant<false> {
+struct is_signed<unsigned _Fract> : bool_constant<false> {
   LIBC_INLINE constexpr operator bool() const { return is_signed::value; }
   LIBC_INLINE constexpr bool operator()() const { return is_signed::value; }
 };
 template <>
-struct is_signed<unsigned long fract> : bool_constant<false> {
+struct is_signed<unsigned long _Fract> : bool_constant<false> {
   LIBC_INLINE constexpr operator bool() const { return is_signed::value; }
   LIBC_INLINE constexpr bool operator()() const { return is_signed::value; }
 };
 template <>
-struct is_signed<unsigned short accum> : bool_constant<false> {
+struct is_signed<unsigned short _Accum> : bool_constant<false> {
   LIBC_INLINE constexpr operator bool() const { return is_signed::value; }
   LIBC_INLINE constexpr bool operator()() const { return is_signed::value; }
 };
 template <>
-struct is_signed<unsigned accum> : bool_constant<false> {
+struct is_signed<unsigned _Accum> : bool_constant<false> {
   LIBC_INLINE constexpr operator bool() const { return is_signed::value; }
   LIBC_INLINE constexpr bool operator()() const { return is_signed::value; }
 };
 template <>
-struct is_signed<unsigned long accum> : bool_constant<false> {
+struct is_signed<unsigned long _Accum> : bool_constant<false> {
   LIBC_INLINE constexpr operator bool() const { return is_signed::value; }
   LIBC_INLINE constexpr bool operator()() const { return is_signed::value; }
 };
 template <>
-struct is_signed<unsigned short sat fract> : bool_constant<false> {
+struct is_signed<unsigned short sat _Fract> : bool_constant<false> {
   LIBC_INLINE constexpr operator bool() const { return is_signed::value; }
   LIBC_INLINE constexpr bool operator()() const { return is_signed::value; }
 };
 template <>
-struct is_signed<unsigned sat fract> : bool_constant<false> {
+struct is_signed<unsigned sat _Fract> : bool_constant<false> {
   LIBC_INLINE constexpr operator bool() const { return is_signed::value; }
   LIBC_INLINE constexpr bool operator()() const { return is_signed::value; }
 };
 template <>
-struct is_signed<unsigned long sat fract> : bool_constant<false> {
+struct is_signed<unsigned long sat _Fract> : bool_constant<false> {
   LIBC_INLINE constexpr operator bool() const { return is_signed::value; }
   LIBC_INLINE constexpr bool operator()() const { return is_signed::value; }
 };
 template <>
-struct is_signed<unsigned short sat accum> : bool_constant<false> {
+struct is_signed<unsigned short sat _Accum> : bool_constant<false> {
   LIBC_INLINE constexpr operator bool() const { return is_signed::value; }
   LIBC_INLINE constexpr bool operator()() const { return is_signed::value; }
 };
 template <>
-struct is_signed<unsigned sat accum> : bool_constant<false> {
+struct is_signed<unsigned sat _Accum> : bool_constant<false> {
   LIBC_INLINE constexpr operator bool() const { return is_signed::value; }
   LIBC_INLINE constexpr bool operator()() const { return is_signed::value; }
 };
 template <>
-struct is_signed<unsigned long sat accum> : bool_constant<false> {
+struct is_signed<unsigned long sat _Accum> : bool_constant<false> {
   LIBC_INLINE constexpr operator bool() const { return is_signed::value; }
   LIBC_INLINE constexpr bool operator()() const { return 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 58cd3f0f598a9..86ac5a89502aa 100644
--- a/libc/src/__support/CPP/type_traits/is_unsigned.h
+++ b/libc/src/__support/CPP/type_traits/is_unsigned.h
@@ -27,17 +27,17 @@ struct is_unsigned : bool_constant<((is_fixed_point_v<T> || is_arithmetic_v<T>)
 
 // Specializations for unsigned fixed-point types
 template <>
-struct is_unsigned<unsigned short fract> : bool_constant<true> {
+struct is_unsigned<unsigned short _Fract> : bool_constant<true> {
   LIBC_INLINE constexpr operator bool() const { return is_unsigned::value; }
   LIBC_INLINE constexpr bool operator()() const { return is_unsigned::value; }
 };
 template <>
-struct is_unsigned<unsigned fract> : bool_constant<true> {
+struct is_unsigned<unsigned _Fract> : bool_constant<true> {
   LIBC_INLINE constexpr operator bool() const { return is_unsigned::value; }
   LIBC_INLINE constexpr bool operator()() const { return is_unsigned::value; }
 };
 template <>
-struct is_unsigned<unsigned long fract> : bool_constant<true> {
+struct is_unsigned<unsigned long _Fract> : bool_constant<true> {
   LIBC_INLINE constexpr operator bool() const { return is_unsigned::value; }
   LIBC_INLINE constexpr bool operator()() const { return is_unsigned::value; }
 };
@@ -57,17 +57,17 @@ struct is_unsigned<unsigned long accum> : bool_constant<true> {
   LIBC_INLINE constexpr bool operator()() const { return is_unsigned::value; }
 };
 template <>
-struct is_unsigned<unsigned short sat fract> : bool_constant<true> {
+struct is_unsigned<unsigned short sat _Fract> : bool_constant<true> {
   LIBC_INLINE constexpr operator bool() const { return is_unsigned::value; }
   LIBC_INLINE constexpr bool operator()() const { return is_unsigned::value; }
 };
 template <>
-struct is_unsigned<unsigned sat fract> : bool_constant<true> {
+struct is_unsigned<unsigned sat _Fract> : bool_constant<true> {
   LIBC_INLINE constexpr operator bool() const { return is_unsigned::value; }
   LIBC_INLINE constexpr bool operator()() const { return is_unsigned::value; }
 };
 template <>
-struct is_unsigned<unsigned long sat fract> : bool_constant<true> {
+struct is_unsigned<unsigned long sat _Fract> : bool_constant<true> {
   LIBC_INLINE constexpr operator bool() const { return is_unsigned::value; }
   LIBC_INLINE constexpr bool operator()() const { return is_unsigned::value; }
 };

>From aac912f1b393eabc3bf595eb6c3224f2715640e8 Mon Sep 17 00:00:00 2001
From: kr-2003 <kumar.kr.abhinav at gmail.com>
Date: Fri, 28 Mar 2025 11:34:02 +0530
Subject: [PATCH 3/9] removed redundant headers

---
 libc/src/__support/CPP/type_traits/is_signed.h   | 1 -
 libc/src/__support/CPP/type_traits/is_unsigned.h | 1 -
 2 files changed, 2 deletions(-)

diff --git a/libc/src/__support/CPP/type_traits/is_signed.h b/libc/src/__support/CPP/type_traits/is_signed.h
index 7299ac4314658..771fc542492c1 100644
--- a/libc/src/__support/CPP/type_traits/is_signed.h
+++ b/libc/src/__support/CPP/type_traits/is_signed.h
@@ -8,7 +8,6 @@
 #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_fixed_point.h"
diff --git a/libc/src/__support/CPP/type_traits/is_unsigned.h b/libc/src/__support/CPP/type_traits/is_unsigned.h
index 86ac5a89502aa..7a491185940b7 100644
--- a/libc/src/__support/CPP/type_traits/is_unsigned.h
+++ b/libc/src/__support/CPP/type_traits/is_unsigned.h
@@ -8,7 +8,6 @@
 #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_fixed_point.h"

>From dc3a4d5fa598909a280f6f46ba4bcc8406e702e5 Mon Sep 17 00:00:00 2001
From: kr-2003 <kumar.kr.abhinav at gmail.com>
Date: Fri, 28 Mar 2025 11:50:17 +0530
Subject: [PATCH 4/9] minor changes

---
 libc/src/__support/CPP/type_traits/is_signed.h   | 2 ++
 libc/src/__support/CPP/type_traits/is_unsigned.h | 2 ++
 libc/test/src/__support/CPP/type_traits_test.cpp | 4 ++++
 3 files changed, 8 insertions(+)

diff --git a/libc/src/__support/CPP/type_traits/is_signed.h b/libc/src/__support/CPP/type_traits/is_signed.h
index 771fc542492c1..2623b761419e9 100644
--- a/libc/src/__support/CPP/type_traits/is_signed.h
+++ b/libc/src/__support/CPP/type_traits/is_signed.h
@@ -24,6 +24,7 @@ struct is_signed : bool_constant<((is_fixed_point_v<T> || is_arithmetic_v<T>) &&
   LIBC_INLINE constexpr bool operator()() const { return is_signed::value; }
 };
 
+#ifdef LIBC_COMPILER_HAS_FIXED_POINT
 // Specializations for unsigned fixed-point types
 template <>
 struct is_signed<unsigned short _Fract> : bool_constant<false> {
@@ -85,6 +86,7 @@ struct is_signed<unsigned long sat _Accum> : bool_constant<false> {
   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 <typename T>
 LIBC_INLINE_VAR constexpr bool is_signed_v = is_signed<T>::value;
diff --git a/libc/src/__support/CPP/type_traits/is_unsigned.h b/libc/src/__support/CPP/type_traits/is_unsigned.h
index 7a491185940b7..be5327abadb7f 100644
--- a/libc/src/__support/CPP/type_traits/is_unsigned.h
+++ b/libc/src/__support/CPP/type_traits/is_unsigned.h
@@ -24,6 +24,7 @@ struct is_unsigned : bool_constant<((is_fixed_point_v<T> || is_arithmetic_v<T>)
   LIBC_INLINE constexpr bool operator()() const { return is_unsigned::value; }
 };
 
+#ifdef LIBC_COMPILER_HAS_FIXED_POINT
 // Specializations for unsigned fixed-point types
 template <>
 struct is_unsigned<unsigned short _Fract> : bool_constant<true> {
@@ -85,6 +86,7 @@ struct is_unsigned<unsigned long sat accum> : bool_constant<true> {
   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 <typename T>
 LIBC_INLINE_VAR constexpr bool is_unsigned_v = is_unsigned<T>::value;
diff --git a/libc/test/src/__support/CPP/type_traits_test.cpp b/libc/test/src/__support/CPP/type_traits_test.cpp
index 338705efa5e80..e62482349a56e 100644
--- a/libc/test/src/__support/CPP/type_traits_test.cpp
+++ b/libc/test/src/__support/CPP/type_traits_test.cpp
@@ -421,6 +421,7 @@ TEST(LlvmLibcTypeTraitsTest, is_signed) {
   EXPECT_TRUE((is_signed_v<double>));
   EXPECT_TRUE((is_signed_v<long double>));
 
+  #ifdef LIBC_COMPILER_HAS_FIXED_POINT
   // for fixed point types
   EXPECT_TRUE((is_signed_v<fract>));
   EXPECT_FALSE((is_signed_v<unsigned fract>));
@@ -438,6 +439,7 @@ TEST(LlvmLibcTypeTraitsTest, is_signed) {
   EXPECT_FALSE((is_signed_v<unsigned long fract>));
   EXPECT_TRUE((is_signed_v<long accum>));
   EXPECT_FALSE((is_signed_v<unsigned long accum>));
+  #endif
 }
 
 // TODO is_trivially_constructible
@@ -459,6 +461,7 @@ TEST(LlvmLibcTypeTraitsTest, is_unsigned) {
   EXPECT_FALSE((is_unsigned_v<double>));
   EXPECT_FALSE((is_unsigned_v<long double>));
 
+  #ifdef LIBC_COMPILER_HAS_FIXED_POINT
   // for fixed point types
   EXPECT_FALSE((is_unsigned_v<fract>));
   EXPECT_TRUE((is_unsigned_v<unsigned fract>));
@@ -476,6 +479,7 @@ TEST(LlvmLibcTypeTraitsTest, is_unsigned) {
   EXPECT_TRUE((is_unsigned_v<unsigned long fract>));
   EXPECT_FALSE((is_unsigned_v<long accum>));
   EXPECT_TRUE((is_unsigned_v<unsigned long accum>));
+  #endif
 }
 
 // TODO is_void

>From b8356795a2377648784cd385dcfd8b8c793dfa28 Mon Sep 17 00:00:00 2001
From: kr-2003 <kumar.kr.abhinav at gmail.com>
Date: Fri, 28 Mar 2025 11:57:26 +0530
Subject: [PATCH 5/9] clang formatting

---
 libc/test/src/__support/CPP/type_traits_test.cpp | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/libc/test/src/__support/CPP/type_traits_test.cpp b/libc/test/src/__support/CPP/type_traits_test.cpp
index e62482349a56e..3a607ec286051 100644
--- a/libc/test/src/__support/CPP/type_traits_test.cpp
+++ b/libc/test/src/__support/CPP/type_traits_test.cpp
@@ -421,7 +421,7 @@ TEST(LlvmLibcTypeTraitsTest, is_signed) {
   EXPECT_TRUE((is_signed_v<double>));
   EXPECT_TRUE((is_signed_v<long double>));
 
-  #ifdef LIBC_COMPILER_HAS_FIXED_POINT
+#ifdef LIBC_COMPILER_HAS_FIXED_POINT
   // for fixed point types
   EXPECT_TRUE((is_signed_v<fract>));
   EXPECT_FALSE((is_signed_v<unsigned fract>));
@@ -439,7 +439,7 @@ TEST(LlvmLibcTypeTraitsTest, is_signed) {
   EXPECT_FALSE((is_signed_v<unsigned long fract>));
   EXPECT_TRUE((is_signed_v<long accum>));
   EXPECT_FALSE((is_signed_v<unsigned long accum>));
-  #endif
+#endif
 }
 
 // TODO is_trivially_constructible
@@ -461,7 +461,7 @@ TEST(LlvmLibcTypeTraitsTest, is_unsigned) {
   EXPECT_FALSE((is_unsigned_v<double>));
   EXPECT_FALSE((is_unsigned_v<long double>));
 
-  #ifdef LIBC_COMPILER_HAS_FIXED_POINT
+#ifdef LIBC_COMPILER_HAS_FIXED_POINT
   // for fixed point types
   EXPECT_FALSE((is_unsigned_v<fract>));
   EXPECT_TRUE((is_unsigned_v<unsigned fract>));
@@ -479,7 +479,7 @@ TEST(LlvmLibcTypeTraitsTest, is_unsigned) {
   EXPECT_TRUE((is_unsigned_v<unsigned long fract>));
   EXPECT_FALSE((is_unsigned_v<long accum>));
   EXPECT_TRUE((is_unsigned_v<unsigned long accum>));
-  #endif
+#endif
 }
 
 // TODO is_void

>From a81375a81ad9435074c98999670c16a979817c1e Mon Sep 17 00:00:00 2001
From: kr-2003 <kumar.kr.abhinav at gmail.com>
Date: Fri, 28 Mar 2025 12:09:26 +0530
Subject: [PATCH 6/9] clang formatter

---
 .../src/__support/CPP/type_traits/is_signed.h | 39 +++++++------------
 .../__support/CPP/type_traits/is_unsigned.h   | 37 +++++++-----------
 2 files changed, 28 insertions(+), 48 deletions(-)

diff --git a/libc/src/__support/CPP/type_traits/is_signed.h b/libc/src/__support/CPP/type_traits/is_signed.h
index 2623b761419e9..1e06a4ad6df85 100644
--- a/libc/src/__support/CPP/type_traits/is_signed.h
+++ b/libc/src/__support/CPP/type_traits/is_signed.h
@@ -19,70 +19,59 @@ namespace cpp {
 
 // Primary template: handles arithmetic and signed fixed-point types
 template <typename T>
-struct is_signed : bool_constant<((is_fixed_point_v<T> || is_arithmetic_v<T>) && (T(-1) < T(0)))> {
+struct is_signed : bool_constant<((is_fixed_point_v<T> || is_arithmetic_v<T>) &&
+                                  (T(-1) < T(0)))> {
   LIBC_INLINE constexpr operator bool() const { return is_signed::value; }
   LIBC_INLINE constexpr bool operator()() const { return is_signed::value; }
 };
 
 #ifdef LIBC_COMPILER_HAS_FIXED_POINT
 // Specializations for unsigned fixed-point types
-template <>
-struct is_signed<unsigned short _Fract> : bool_constant<false> {
+template <> struct is_signed<unsigned short _Fract> : bool_constant<false> {
   LIBC_INLINE constexpr operator bool() const { return is_signed::value; }
   LIBC_INLINE constexpr bool operator()() const { return is_signed::value; }
 };
-template <>
-struct is_signed<unsigned _Fract> : bool_constant<false> {
+template <> struct is_signed<unsigned _Fract> : bool_constant<false> {
   LIBC_INLINE constexpr operator bool() const { return is_signed::value; }
   LIBC_INLINE constexpr bool operator()() const { return is_signed::value; }
 };
-template <>
-struct is_signed<unsigned long _Fract> : bool_constant<false> {
+template <> struct is_signed<unsigned long _Fract> : bool_constant<false> {
   LIBC_INLINE constexpr operator bool() const { return is_signed::value; }
   LIBC_INLINE constexpr bool operator()() const { return is_signed::value; }
 };
-template <>
-struct is_signed<unsigned short _Accum> : bool_constant<false> {
+template <> struct is_signed<unsigned short _Accum> : bool_constant<false> {
   LIBC_INLINE constexpr operator bool() const { return is_signed::value; }
   LIBC_INLINE constexpr bool operator()() const { return is_signed::value; }
 };
-template <>
-struct is_signed<unsigned _Accum> : bool_constant<false> {
+template <> struct is_signed<unsigned _Accum> : bool_constant<false> {
   LIBC_INLINE constexpr operator bool() const { return is_signed::value; }
   LIBC_INLINE constexpr bool operator()() const { return is_signed::value; }
 };
-template <>
-struct is_signed<unsigned long _Accum> : bool_constant<false> {
+template <> struct is_signed<unsigned long _Accum> : bool_constant<false> {
   LIBC_INLINE constexpr operator bool() const { return is_signed::value; }
   LIBC_INLINE constexpr bool operator()() const { return is_signed::value; }
 };
-template <>
-struct is_signed<unsigned short sat _Fract> : bool_constant<false> {
+template <> struct is_signed<unsigned short sat _Fract> : bool_constant<false> {
   LIBC_INLINE constexpr operator bool() const { return is_signed::value; }
   LIBC_INLINE constexpr bool operator()() const { return is_signed::value; }
 };
-template <>
-struct is_signed<unsigned sat _Fract> : bool_constant<false> {
+template <> struct is_signed<unsigned sat _Fract> : bool_constant<false> {
   LIBC_INLINE constexpr operator bool() const { return is_signed::value; }
   LIBC_INLINE constexpr bool operator()() const { return is_signed::value; }
 };
-template <>
-struct is_signed<unsigned long sat _Fract> : bool_constant<false> {
+template <> struct is_signed<unsigned long sat _Fract> : bool_constant<false> {
   LIBC_INLINE constexpr operator bool() const { return is_signed::value; }
   LIBC_INLINE constexpr bool operator()() const { return is_signed::value; }
 };
-template <>
-struct is_signed<unsigned short sat _Accum> : bool_constant<false> {
+template <> struct is_signed<unsigned short sat _Accum> : bool_constant<false> {
   LIBC_INLINE constexpr operator bool() const { return is_signed::value; }
   LIBC_INLINE constexpr bool operator()() const { return is_signed::value; }
 };
-template <>
-struct is_signed<unsigned sat _Accum> : bool_constant<false> {
+template <> struct is_signed<unsigned sat _Accum> : bool_constant<false> {
   LIBC_INLINE constexpr operator bool() const { return is_signed::value; }
   LIBC_INLINE constexpr bool operator()() const { return is_signed::value; }
 };
-template <>
-struct is_signed<unsigned long sat _Accum> : bool_constant<false> {
+template <> struct is_signed<unsigned long sat _Accum> : bool_constant<false> {
   LIBC_INLINE constexpr operator bool() const { return is_signed::value; }
   LIBC_INLINE constexpr bool operator()() const { return 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 be5327abadb7f..3740539b10149 100644
--- a/libc/src/__support/CPP/type_traits/is_unsigned.h
+++ b/libc/src/__support/CPP/type_traits/is_unsigned.h
@@ -19,40 +19,36 @@ namespace cpp {
 
 // Primary template: handles arithmetic and signed fixed-point types
 template <typename T>
-struct is_unsigned : bool_constant<((is_fixed_point_v<T> || is_arithmetic_v<T>) && (T(-1) > T(0)))> {
+struct is_unsigned
+    : bool_constant<((is_fixed_point_v<T> || is_arithmetic_v<T>) &&
+                     (T(-1) > T(0)))> {
   LIBC_INLINE constexpr operator bool() const { return is_unsigned::value; }
   LIBC_INLINE constexpr bool operator()() const { return is_unsigned::value; }
 };
 
 #ifdef LIBC_COMPILER_HAS_FIXED_POINT
 // Specializations for unsigned fixed-point types
-template <>
-struct is_unsigned<unsigned short _Fract> : bool_constant<true> {
+template <> struct is_unsigned<unsigned short _Fract> : bool_constant<true> {
   LIBC_INLINE constexpr operator bool() const { return is_unsigned::value; }
   LIBC_INLINE constexpr bool operator()() const { return is_unsigned::value; }
 };
-template <>
-struct is_unsigned<unsigned _Fract> : bool_constant<true> {
+template <> struct is_unsigned<unsigned _Fract> : bool_constant<true> {
   LIBC_INLINE constexpr operator bool() const { return is_unsigned::value; }
   LIBC_INLINE constexpr bool operator()() const { return is_unsigned::value; }
 };
-template <>
-struct is_unsigned<unsigned long _Fract> : bool_constant<true> {
+template <> struct is_unsigned<unsigned long _Fract> : bool_constant<true> {
   LIBC_INLINE constexpr operator bool() const { return is_unsigned::value; }
   LIBC_INLINE constexpr bool operator()() const { return is_unsigned::value; }
 };
-template <>
-struct is_unsigned<unsigned short accum> : bool_constant<true> {
+template <> struct is_unsigned<unsigned short accum> : bool_constant<true> {
   LIBC_INLINE constexpr operator bool() const { return is_unsigned::value; }
   LIBC_INLINE constexpr bool operator()() const { return is_unsigned::value; }
 };
-template <>
-struct is_unsigned<unsigned accum> : bool_constant<true> {
+template <> struct is_unsigned<unsigned accum> : bool_constant<true> {
   LIBC_INLINE constexpr operator bool() const { return is_unsigned::value; }
   LIBC_INLINE constexpr bool operator()() const { return is_unsigned::value; }
 };
-template <>
-struct is_unsigned<unsigned long accum> : bool_constant<true> {
+template <> struct is_unsigned<unsigned long accum> : bool_constant<true> {
   LIBC_INLINE constexpr operator bool() const { return is_unsigned::value; }
   LIBC_INLINE constexpr bool operator()() const { return is_unsigned::value; }
 };
@@ -61,28 +57,23 @@ struct is_unsigned<unsigned short sat _Fract> : bool_constant<true> {
   LIBC_INLINE constexpr operator bool() const { return is_unsigned::value; }
   LIBC_INLINE constexpr bool operator()() const { return is_unsigned::value; }
 };
-template <>
-struct is_unsigned<unsigned sat _Fract> : bool_constant<true> {
+template <> struct is_unsigned<unsigned sat _Fract> : bool_constant<true> {
   LIBC_INLINE constexpr operator bool() const { return is_unsigned::value; }
   LIBC_INLINE constexpr bool operator()() const { return is_unsigned::value; }
 };
-template <>
-struct is_unsigned<unsigned long sat _Fract> : bool_constant<true> {
+template <> struct is_unsigned<unsigned long sat _Fract> : bool_constant<true> {
   LIBC_INLINE constexpr operator bool() const { return is_unsigned::value; }
   LIBC_INLINE constexpr bool operator()() const { return is_unsigned::value; }
 };
-template <>
-struct is_unsigned<unsigned short sat accum> : bool_constant<true> {
+template <> struct is_unsigned<unsigned short sat accum> : bool_constant<true> {
   LIBC_INLINE constexpr operator bool() const { return is_unsigned::value; }
   LIBC_INLINE constexpr bool operator()() const { return is_unsigned::value; }
 };
-template <>
-struct is_unsigned<unsigned sat accum> : bool_constant<true> {
+template <> struct is_unsigned<unsigned sat accum> : bool_constant<true> {
   LIBC_INLINE constexpr operator bool() const { return is_unsigned::value; }
   LIBC_INLINE constexpr bool operator()() const { return is_unsigned::value; }
 };
-template <>
-struct is_unsigned<unsigned long sat accum> : bool_constant<true> {
+template <> struct is_unsigned<unsigned long sat accum> : bool_constant<true> {
   LIBC_INLINE constexpr operator bool() const { return is_unsigned::value; }
   LIBC_INLINE constexpr bool operator()() const { return is_unsigned::value; }
 };

>From ce28db0cd870e6800d1650ab3c3bbd8e921e0c1a Mon Sep 17 00:00:00 2001
From: kr-2003 <kumar.kr.abhinav at gmail.com>
Date: Fri, 28 Mar 2025 21:18:39 +0530
Subject: [PATCH 7/9] added all fixed-points explicitly

---
 .../src/__support/CPP/type_traits/is_signed.h | 79 +++++++-----------
 .../__support/CPP/type_traits/is_unsigned.h   | 81 +++++++------------
 2 files changed, 60 insertions(+), 100 deletions(-)

diff --git a/libc/src/__support/CPP/type_traits/is_signed.h b/libc/src/__support/CPP/type_traits/is_signed.h
index 1e06a4ad6df85..74ea4126e371a 100644
--- a/libc/src/__support/CPP/type_traits/is_signed.h
+++ b/libc/src/__support/CPP/type_traits/is_signed.h
@@ -8,6 +8,7 @@
 #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_fixed_point.h"
@@ -19,62 +20,42 @@ namespace cpp {
 
 // Primary template: handles arithmetic and signed fixed-point types
 template <typename T>
-struct is_signed : bool_constant<((is_fixed_point_v<T> || is_arithmetic_v<T>) &&
-                                  (T(-1) < T(0)))> {
+struct is_signed : bool_constant<(is_arithmetic_v<T> && (T(-1) < T(0)))> {
   LIBC_INLINE constexpr operator bool() const { return is_signed::value; }
   LIBC_INLINE constexpr bool operator()() const { return is_signed::value; }
 };
 
 #ifdef LIBC_COMPILER_HAS_FIXED_POINT
 // Specializations for unsigned fixed-point types
-template <> struct is_signed<unsigned short _Fract> : bool_constant<false> {
-  LIBC_INLINE constexpr operator bool() const { return is_signed::value; }
-  LIBC_INLINE constexpr bool operator()() const { return is_signed::value; }
-};
-template <> struct is_signed<unsigned _Fract> : bool_constant<false> {
-  LIBC_INLINE constexpr operator bool() const { return is_signed::value; }
-  LIBC_INLINE constexpr bool operator()() const { return is_signed::value; }
-};
-template <> struct is_signed<unsigned long _Fract> : bool_constant<false> {
-  LIBC_INLINE constexpr operator bool() const { return is_signed::value; }
-  LIBC_INLINE constexpr bool operator()() const { return is_signed::value; }
-};
-template <> struct is_signed<unsigned short _Accum> : bool_constant<false> {
-  LIBC_INLINE constexpr operator bool() const { return is_signed::value; }
-  LIBC_INLINE constexpr bool operator()() const { return is_signed::value; }
-};
-template <> struct is_signed<unsigned _Accum> : bool_constant<false> {
-  LIBC_INLINE constexpr operator bool() const { return is_signed::value; }
-  LIBC_INLINE constexpr bool operator()() const { return is_signed::value; }
-};
-template <> struct is_signed<unsigned long _Accum> : bool_constant<false> {
-  LIBC_INLINE constexpr operator bool() const { return is_signed::value; }
-  LIBC_INLINE constexpr bool operator()() const { return is_signed::value; }
-};
-template <> struct is_signed<unsigned short sat _Fract> : bool_constant<false> {
-  LIBC_INLINE constexpr operator bool() const { return is_signed::value; }
-  LIBC_INLINE constexpr bool operator()() const { return is_signed::value; }
-};
-template <> struct is_signed<unsigned sat _Fract> : bool_constant<false> {
-  LIBC_INLINE constexpr operator bool() const { return is_signed::value; }
-  LIBC_INLINE constexpr bool operator()() const { return is_signed::value; }
-};
-template <> struct is_signed<unsigned long sat _Fract> : bool_constant<false> {
-  LIBC_INLINE constexpr operator bool() const { return is_signed::value; }
-  LIBC_INLINE constexpr bool operator()() const { return is_signed::value; }
-};
-template <> struct is_signed<unsigned short sat _Accum> : bool_constant<false> {
-  LIBC_INLINE constexpr operator bool() const { return is_signed::value; }
-  LIBC_INLINE constexpr bool operator()() const { return is_signed::value; }
-};
-template <> struct is_signed<unsigned sat _Accum> : bool_constant<false> {
-  LIBC_INLINE constexpr operator bool() const { return is_signed::value; }
-  LIBC_INLINE constexpr bool operator()() const { return is_signed::value; }
-};
-template <> struct is_signed<unsigned long sat _Accum> : bool_constant<false> {
-  LIBC_INLINE constexpr operator bool() const { return is_signed::value; }
-  LIBC_INLINE constexpr bool operator()() const { return is_signed::value; }
+template <typename T, bool IsSigned>
+struct fixed_point_is_signed : bool_constant<IsSigned> {
+  LIBC_INLINE constexpr operator bool() const { return fixed_point_is_signed::value; }
+  LIBC_INLINE constexpr bool operator()() const { return fixed_point_is_signed::value; }
 };
+template <> struct is_signed<fract> : fixed_point_is_signed<fract, true> {};
+template <> struct is_signed<unsigned short fract> : fixed_point_is_signed<unsigned short fract, false> {};
+template <> struct is_signed<unsigned fract> : fixed_point_is_signed<unsigned fract, false> {};
+template <> struct is_signed<unsigned long fract> : fixed_point_is_signed<unsigned long fract, false> {};
+template <> struct is_signed<short fract> : fixed_point_is_signed<short fract, true> {};
+template <> struct is_signed<long fract> : fixed_point_is_signed<long fract, true> {};
+template <> struct is_signed<accum> : fixed_point_is_signed<accum, true> {};
+template <> struct is_signed<unsigned short accum> : fixed_point_is_signed<unsigned short accum, false> {};
+template <> struct is_signed<unsigned accum> : fixed_point_is_signed<unsigned accum, false> {};
+template <> struct is_signed<unsigned long accum> : fixed_point_is_signed<unsigned long accum, false> {};
+template <> struct is_signed<short accum> : fixed_point_is_signed<short accum, true> {};
+template <> struct is_signed<long accum> : fixed_point_is_signed<long accum, true> {};
+template <> struct is_signed<sat fract> : fixed_point_is_signed<sat fract, true> {};
+template <> struct is_signed<unsigned short sat fract> : fixed_point_is_signed<unsigned short sat fract, false> {};
+template <> struct is_signed<unsigned sat fract> : fixed_point_is_signed<unsigned sat fract, false> {};
+template <> struct is_signed<unsigned long sat fract> : fixed_point_is_signed<unsigned long sat fract, false> {};
+template <> struct is_signed<short sat fract> : fixed_point_is_signed<short sat fract, true> {};
+template <> struct is_signed<long sat fract> : fixed_point_is_signed<long sat fract, true> {};
+template <> struct is_signed<sat accum> : fixed_point_is_signed<sat accum, true> {};
+template <> struct is_signed<unsigned short sat accum> : fixed_point_is_signed<unsigned short sat accum, false> {};
+template <> struct is_signed<unsigned sat accum> : fixed_point_is_signed<unsigned sat accum, false> {};
+template <> struct is_signed<unsigned long sat accum> : fixed_point_is_signed<unsigned long sat accum, false> {};
+template <> struct is_signed<short sat accum> : fixed_point_is_signed<short sat accum, true> {};
+template <> struct is_signed<long sat accum> : fixed_point_is_signed<long sat accum, true> {};
 #endif // LIBC_COMPILER_HAS_FIXED_POINT
 
 template <typename T>
diff --git a/libc/src/__support/CPP/type_traits/is_unsigned.h b/libc/src/__support/CPP/type_traits/is_unsigned.h
index 3740539b10149..63f1abd65ab8d 100644
--- a/libc/src/__support/CPP/type_traits/is_unsigned.h
+++ b/libc/src/__support/CPP/type_traits/is_unsigned.h
@@ -8,6 +8,7 @@
 #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_fixed_point.h"
@@ -19,64 +20,42 @@ namespace cpp {
 
 // Primary template: handles arithmetic and signed fixed-point types
 template <typename T>
-struct is_unsigned
-    : bool_constant<((is_fixed_point_v<T> || is_arithmetic_v<T>) &&
-                     (T(-1) > T(0)))> {
+struct is_unsigned : bool_constant<(is_arithmetic_v<T> && (T(-1) > T(0)))> {
   LIBC_INLINE constexpr operator bool() const { return is_unsigned::value; }
   LIBC_INLINE constexpr bool operator()() const { return is_unsigned::value; }
 };
 
 #ifdef LIBC_COMPILER_HAS_FIXED_POINT
 // Specializations for unsigned fixed-point types
-template <> struct is_unsigned<unsigned short _Fract> : bool_constant<true> {
-  LIBC_INLINE constexpr operator bool() const { return is_unsigned::value; }
-  LIBC_INLINE constexpr bool operator()() const { return is_unsigned::value; }
-};
-template <> struct is_unsigned<unsigned _Fract> : bool_constant<true> {
-  LIBC_INLINE constexpr operator bool() const { return is_unsigned::value; }
-  LIBC_INLINE constexpr bool operator()() const { return is_unsigned::value; }
-};
-template <> struct is_unsigned<unsigned long _Fract> : bool_constant<true> {
-  LIBC_INLINE constexpr operator bool() const { return is_unsigned::value; }
-  LIBC_INLINE constexpr bool operator()() const { return is_unsigned::value; }
-};
-template <> struct is_unsigned<unsigned short accum> : bool_constant<true> {
-  LIBC_INLINE constexpr operator bool() const { return is_unsigned::value; }
-  LIBC_INLINE constexpr bool operator()() const { return is_unsigned::value; }
-};
-template <> struct is_unsigned<unsigned accum> : bool_constant<true> {
-  LIBC_INLINE constexpr operator bool() const { return is_unsigned::value; }
-  LIBC_INLINE constexpr bool operator()() const { return is_unsigned::value; }
-};
-template <> struct is_unsigned<unsigned long accum> : bool_constant<true> {
-  LIBC_INLINE constexpr operator bool() const { return is_unsigned::value; }
-  LIBC_INLINE constexpr bool operator()() const { return is_unsigned::value; }
-};
-template <>
-struct is_unsigned<unsigned short sat _Fract> : bool_constant<true> {
-  LIBC_INLINE constexpr operator bool() const { return is_unsigned::value; }
-  LIBC_INLINE constexpr bool operator()() const { return is_unsigned::value; }
-};
-template <> struct is_unsigned<unsigned sat _Fract> : bool_constant<true> {
-  LIBC_INLINE constexpr operator bool() const { return is_unsigned::value; }
-  LIBC_INLINE constexpr bool operator()() const { return is_unsigned::value; }
-};
-template <> struct is_unsigned<unsigned long sat _Fract> : bool_constant<true> {
-  LIBC_INLINE constexpr operator bool() const { return is_unsigned::value; }
-  LIBC_INLINE constexpr bool operator()() const { return is_unsigned::value; }
-};
-template <> struct is_unsigned<unsigned short sat accum> : bool_constant<true> {
-  LIBC_INLINE constexpr operator bool() const { return is_unsigned::value; }
-  LIBC_INLINE constexpr bool operator()() const { return is_unsigned::value; }
-};
-template <> struct is_unsigned<unsigned sat accum> : bool_constant<true> {
-  LIBC_INLINE constexpr operator bool() const { return is_unsigned::value; }
-  LIBC_INLINE constexpr bool operator()() const { return is_unsigned::value; }
-};
-template <> struct is_unsigned<unsigned long sat accum> : bool_constant<true> {
-  LIBC_INLINE constexpr operator bool() const { return is_unsigned::value; }
-  LIBC_INLINE constexpr bool operator()() const { return is_unsigned::value; }
+template <typename T, bool IsUnsigned>
+struct fixed_point_is_unsigned : bool_constant<IsUnsigned> {
+  LIBC_INLINE constexpr operator bool() const { return fixed_point_is_unsigned::value; }
+  LIBC_INLINE constexpr bool operator()() const { return fixed_point_is_unsigned::value; }
 };
+template <> struct is_unsigned<fract> : fixed_point_is_unsigned<fract, false> {};
+template <> struct is_unsigned<unsigned short fract> : fixed_point_is_unsigned<unsigned short fract, true> {};
+template <> struct is_unsigned<unsigned fract> : fixed_point_is_unsigned<unsigned fract, true> {};
+template <> struct is_unsigned<unsigned long fract> : fixed_point_is_unsigned<unsigned long fract, true> {};
+template <> struct is_unsigned<short fract> : fixed_point_is_unsigned<short fract, false> {};
+template <> struct is_unsigned<long fract> : fixed_point_is_unsigned<long fract, false> {};
+template <> struct is_unsigned<accum> : fixed_point_is_unsigned<accum, false> {};
+template <> struct is_unsigned<unsigned short accum> : fixed_point_is_unsigned<unsigned short accum, true> {};
+template <> struct is_unsigned<unsigned accum> : fixed_point_is_unsigned<unsigned accum, true> {};
+template <> struct is_unsigned<unsigned long accum> : fixed_point_is_unsigned<unsigned long accum, true> {};
+template <> struct is_unsigned<short accum> : fixed_point_is_unsigned<short accum, false> {};
+template <> struct is_unsigned<long accum> : fixed_point_is_unsigned<long accum, false> {};
+template <> struct is_unsigned<sat fract> : fixed_point_is_unsigned<sat fract, false> {};
+template <> struct is_unsigned<unsigned short sat fract> : fixed_point_is_unsigned<unsigned short sat fract, true> {};
+template <> struct is_unsigned<unsigned sat fract> : fixed_point_is_unsigned<unsigned sat fract, true> {};
+template <> struct is_unsigned<unsigned long sat fract> : fixed_point_is_unsigned<unsigned long sat fract, true> {};
+template <> struct is_unsigned<short sat fract> : fixed_point_is_unsigned<short sat fract, false> {};
+template <> struct is_unsigned<long sat fract> : fixed_point_is_unsigned<long sat fract, false> {};
+template <> struct is_unsigned<sat accum> : fixed_point_is_unsigned<sat accum, false> {};
+template <> struct is_unsigned<unsigned short sat accum> : fixed_point_is_unsigned<unsigned short sat accum, true> {};
+template <> struct is_unsigned<unsigned sat accum> : fixed_point_is_unsigned<unsigned sat accum, true> {};
+template <> struct is_unsigned<unsigned long sat accum> : fixed_point_is_unsigned<unsigned long sat accum, true> {};
+template <> struct is_unsigned<short sat accum> : fixed_point_is_unsigned<short sat accum, false> {};
+template <> struct is_unsigned<long sat accum> : fixed_point_is_unsigned<long sat accum, false> {};
 #endif // LIBC_COMPILER_HAS_FIXED_POINT
 
 template <typename T>

>From 5d0229bdf203ec24e60269c28c0c9274020b7fd4 Mon Sep 17 00:00:00 2001
From: kr-2003 <kumar.kr.abhinav at gmail.com>
Date: Fri, 28 Mar 2025 21:23:16 +0530
Subject: [PATCH 8/9] added all fixed-points explicitly

---
 .../src/__support/CPP/type_traits/is_signed.h | 90 ++++++++++++-----
 .../__support/CPP/type_traits/is_unsigned.h   | 98 ++++++++++++++-----
 2 files changed, 138 insertions(+), 50 deletions(-)

diff --git a/libc/src/__support/CPP/type_traits/is_signed.h b/libc/src/__support/CPP/type_traits/is_signed.h
index 74ea4126e371a..9b763aa0bec5d 100644
--- a/libc/src/__support/CPP/type_traits/is_signed.h
+++ b/libc/src/__support/CPP/type_traits/is_signed.h
@@ -29,33 +29,75 @@ struct is_signed : bool_constant<(is_arithmetic_v<T> && (T(-1) < T(0)))> {
 // Specializations for unsigned fixed-point types
 template <typename T, bool IsSigned>
 struct fixed_point_is_signed : bool_constant<IsSigned> {
-  LIBC_INLINE constexpr operator bool() const { return fixed_point_is_signed::value; }
-  LIBC_INLINE constexpr bool operator()() const { return fixed_point_is_signed::value; }
+  LIBC_INLINE constexpr operator bool() const {
+    return fixed_point_is_signed::value;
+  }
+  LIBC_INLINE constexpr bool operator()() const {
+    return fixed_point_is_signed::value;
+  }
 };
 template <> struct is_signed<fract> : fixed_point_is_signed<fract, true> {};
-template <> struct is_signed<unsigned short fract> : fixed_point_is_signed<unsigned short fract, false> {};
-template <> struct is_signed<unsigned fract> : fixed_point_is_signed<unsigned fract, false> {};
-template <> struct is_signed<unsigned long fract> : fixed_point_is_signed<unsigned long fract, false> {};
-template <> struct is_signed<short fract> : fixed_point_is_signed<short fract, true> {};
-template <> struct is_signed<long fract> : fixed_point_is_signed<long fract, true> {};
+template <>
+struct is_signed<unsigned short fract>
+    : fixed_point_is_signed<unsigned short fract, false> {};
+template <>
+struct is_signed<unsigned fract>
+    : fixed_point_is_signed<unsigned fract, false> {};
+template <>
+struct is_signed<unsigned long fract>
+    : fixed_point_is_signed<unsigned long fract, false> {};
+template <>
+struct is_signed<short fract> : fixed_point_is_signed<short fract, true> {};
+template <>
+struct is_signed<long fract> : fixed_point_is_signed<long fract, true> {};
 template <> struct is_signed<accum> : fixed_point_is_signed<accum, true> {};
-template <> struct is_signed<unsigned short accum> : fixed_point_is_signed<unsigned short accum, false> {};
-template <> struct is_signed<unsigned accum> : fixed_point_is_signed<unsigned accum, false> {};
-template <> struct is_signed<unsigned long accum> : fixed_point_is_signed<unsigned long accum, false> {};
-template <> struct is_signed<short accum> : fixed_point_is_signed<short accum, true> {};
-template <> struct is_signed<long accum> : fixed_point_is_signed<long accum, true> {};
-template <> struct is_signed<sat fract> : fixed_point_is_signed<sat fract, true> {};
-template <> struct is_signed<unsigned short sat fract> : fixed_point_is_signed<unsigned short sat fract, false> {};
-template <> struct is_signed<unsigned sat fract> : fixed_point_is_signed<unsigned sat fract, false> {};
-template <> struct is_signed<unsigned long sat fract> : fixed_point_is_signed<unsigned long sat fract, false> {};
-template <> struct is_signed<short sat fract> : fixed_point_is_signed<short sat fract, true> {};
-template <> struct is_signed<long sat fract> : fixed_point_is_signed<long sat fract, true> {};
-template <> struct is_signed<sat accum> : fixed_point_is_signed<sat accum, true> {};
-template <> struct is_signed<unsigned short sat accum> : fixed_point_is_signed<unsigned short sat accum, false> {};
-template <> struct is_signed<unsigned sat accum> : fixed_point_is_signed<unsigned sat accum, false> {};
-template <> struct is_signed<unsigned long sat accum> : fixed_point_is_signed<unsigned long sat accum, false> {};
-template <> struct is_signed<short sat accum> : fixed_point_is_signed<short sat accum, true> {};
-template <> struct is_signed<long sat accum> : fixed_point_is_signed<long sat accum, true> {};
+template <>
+struct is_signed<unsigned short accum>
+    : fixed_point_is_signed<unsigned short accum, false> {};
+template <>
+struct is_signed<unsigned accum>
+    : fixed_point_is_signed<unsigned accum, false> {};
+template <>
+struct is_signed<unsigned long accum>
+    : fixed_point_is_signed<unsigned long accum, false> {};
+template <>
+struct is_signed<short accum> : fixed_point_is_signed<short accum, true> {};
+template <>
+struct is_signed<long accum> : fixed_point_is_signed<long accum, true> {};
+template <>
+struct is_signed<sat fract> : fixed_point_is_signed<sat fract, true> {};
+template <>
+struct is_signed<unsigned short sat fract>
+    : fixed_point_is_signed<unsigned short sat fract, false> {};
+template <>
+struct is_signed<unsigned sat fract>
+    : fixed_point_is_signed<unsigned sat fract, false> {};
+template <>
+struct is_signed<unsigned long sat fract>
+    : fixed_point_is_signed<unsigned long sat fract, false> {};
+template <>
+struct is_signed<short sat fract>
+    : fixed_point_is_signed<short sat fract, true> {};
+template <>
+struct is_signed<long sat fract> : fixed_point_is_signed<long sat fract, true> {
+};
+template <>
+struct is_signed<sat accum> : fixed_point_is_signed<sat accum, true> {};
+template <>
+struct is_signed<unsigned short sat accum>
+    : fixed_point_is_signed<unsigned short sat accum, false> {};
+template <>
+struct is_signed<unsigned sat accum>
+    : fixed_point_is_signed<unsigned sat accum, false> {};
+template <>
+struct is_signed<unsigned long sat accum>
+    : fixed_point_is_signed<unsigned long sat accum, false> {};
+template <>
+struct is_signed<short sat accum>
+    : fixed_point_is_signed<short sat accum, true> {};
+template <>
+struct is_signed<long sat accum> : fixed_point_is_signed<long sat accum, true> {
+};
 #endif // LIBC_COMPILER_HAS_FIXED_POINT
 
 template <typename T>
diff --git a/libc/src/__support/CPP/type_traits/is_unsigned.h b/libc/src/__support/CPP/type_traits/is_unsigned.h
index 63f1abd65ab8d..a4de8ca683a30 100644
--- a/libc/src/__support/CPP/type_traits/is_unsigned.h
+++ b/libc/src/__support/CPP/type_traits/is_unsigned.h
@@ -29,33 +29,79 @@ struct is_unsigned : bool_constant<(is_arithmetic_v<T> && (T(-1) > T(0)))> {
 // Specializations for unsigned fixed-point types
 template <typename T, bool IsUnsigned>
 struct fixed_point_is_unsigned : bool_constant<IsUnsigned> {
-  LIBC_INLINE constexpr operator bool() const { return fixed_point_is_unsigned::value; }
-  LIBC_INLINE constexpr bool operator()() const { return fixed_point_is_unsigned::value; }
+  LIBC_INLINE constexpr operator bool() const {
+    return fixed_point_is_unsigned::value;
+  }
+  LIBC_INLINE constexpr bool operator()() const {
+    return fixed_point_is_unsigned::value;
+  }
 };
-template <> struct is_unsigned<fract> : fixed_point_is_unsigned<fract, false> {};
-template <> struct is_unsigned<unsigned short fract> : fixed_point_is_unsigned<unsigned short fract, true> {};
-template <> struct is_unsigned<unsigned fract> : fixed_point_is_unsigned<unsigned fract, true> {};
-template <> struct is_unsigned<unsigned long fract> : fixed_point_is_unsigned<unsigned long fract, true> {};
-template <> struct is_unsigned<short fract> : fixed_point_is_unsigned<short fract, false> {};
-template <> struct is_unsigned<long fract> : fixed_point_is_unsigned<long fract, false> {};
-template <> struct is_unsigned<accum> : fixed_point_is_unsigned<accum, false> {};
-template <> struct is_unsigned<unsigned short accum> : fixed_point_is_unsigned<unsigned short accum, true> {};
-template <> struct is_unsigned<unsigned accum> : fixed_point_is_unsigned<unsigned accum, true> {};
-template <> struct is_unsigned<unsigned long accum> : fixed_point_is_unsigned<unsigned long accum, true> {};
-template <> struct is_unsigned<short accum> : fixed_point_is_unsigned<short accum, false> {};
-template <> struct is_unsigned<long accum> : fixed_point_is_unsigned<long accum, false> {};
-template <> struct is_unsigned<sat fract> : fixed_point_is_unsigned<sat fract, false> {};
-template <> struct is_unsigned<unsigned short sat fract> : fixed_point_is_unsigned<unsigned short sat fract, true> {};
-template <> struct is_unsigned<unsigned sat fract> : fixed_point_is_unsigned<unsigned sat fract, true> {};
-template <> struct is_unsigned<unsigned long sat fract> : fixed_point_is_unsigned<unsigned long sat fract, true> {};
-template <> struct is_unsigned<short sat fract> : fixed_point_is_unsigned<short sat fract, false> {};
-template <> struct is_unsigned<long sat fract> : fixed_point_is_unsigned<long sat fract, false> {};
-template <> struct is_unsigned<sat accum> : fixed_point_is_unsigned<sat accum, false> {};
-template <> struct is_unsigned<unsigned short sat accum> : fixed_point_is_unsigned<unsigned short sat accum, true> {};
-template <> struct is_unsigned<unsigned sat accum> : fixed_point_is_unsigned<unsigned sat accum, true> {};
-template <> struct is_unsigned<unsigned long sat accum> : fixed_point_is_unsigned<unsigned long sat accum, true> {};
-template <> struct is_unsigned<short sat accum> : fixed_point_is_unsigned<short sat accum, false> {};
-template <> struct is_unsigned<long sat accum> : fixed_point_is_unsigned<long sat accum, false> {};
+template <>
+struct is_unsigned<fract> : fixed_point_is_unsigned<fract, false> {};
+template <>
+struct is_unsigned<unsigned short fract>
+    : fixed_point_is_unsigned<unsigned short fract, true> {};
+template <>
+struct is_unsigned<unsigned fract>
+    : fixed_point_is_unsigned<unsigned fract, true> {};
+template <>
+struct is_unsigned<unsigned long fract>
+    : fixed_point_is_unsigned<unsigned long fract, true> {};
+template <>
+struct is_unsigned<short fract> : fixed_point_is_unsigned<short fract, false> {
+};
+template <>
+struct is_unsigned<long fract> : fixed_point_is_unsigned<long fract, false> {};
+template <>
+struct is_unsigned<accum> : fixed_point_is_unsigned<accum, false> {};
+template <>
+struct is_unsigned<unsigned short accum>
+    : fixed_point_is_unsigned<unsigned short accum, true> {};
+template <>
+struct is_unsigned<unsigned accum>
+    : fixed_point_is_unsigned<unsigned accum, true> {};
+template <>
+struct is_unsigned<unsigned long accum>
+    : fixed_point_is_unsigned<unsigned long accum, true> {};
+template <>
+struct is_unsigned<short accum> : fixed_point_is_unsigned<short accum, false> {
+};
+template <>
+struct is_unsigned<long accum> : fixed_point_is_unsigned<long accum, false> {};
+template <>
+struct is_unsigned<sat fract> : fixed_point_is_unsigned<sat fract, false> {};
+template <>
+struct is_unsigned<unsigned short sat fract>
+    : fixed_point_is_unsigned<unsigned short sat fract, true> {};
+template <>
+struct is_unsigned<unsigned sat fract>
+    : fixed_point_is_unsigned<unsigned sat fract, true> {};
+template <>
+struct is_unsigned<unsigned long sat fract>
+    : fixed_point_is_unsigned<unsigned long sat fract, true> {};
+template <>
+struct is_unsigned<short sat fract>
+    : fixed_point_is_unsigned<short sat fract, false> {};
+template <>
+struct is_unsigned<long sat fract>
+    : fixed_point_is_unsigned<long sat fract, false> {};
+template <>
+struct is_unsigned<sat accum> : fixed_point_is_unsigned<sat accum, false> {};
+template <>
+struct is_unsigned<unsigned short sat accum>
+    : fixed_point_is_unsigned<unsigned short sat accum, true> {};
+template <>
+struct is_unsigned<unsigned sat accum>
+    : fixed_point_is_unsigned<unsigned sat accum, true> {};
+template <>
+struct is_unsigned<unsigned long sat accum>
+    : fixed_point_is_unsigned<unsigned long sat accum, true> {};
+template <>
+struct is_unsigned<short sat accum>
+    : fixed_point_is_unsigned<short sat accum, false> {};
+template <>
+struct is_unsigned<long sat accum>
+    : fixed_point_is_unsigned<long sat accum, false> {};
 #endif // LIBC_COMPILER_HAS_FIXED_POINT
 
 template <typename T>

>From b448b38f726751c7ea74d18635c02591650cffb0 Mon Sep 17 00:00:00 2001
From: kr-2003 <kumar.kr.abhinav at gmail.com>
Date: Mon, 31 Mar 2025 07:59:51 +0530
Subject: [PATCH 9/9] changed the design pattern

---
 .../src/__support/CPP/type_traits/is_signed.h | 93 ++++-------------
 .../__support/CPP/type_traits/is_unsigned.h   | 99 ++++---------------
 2 files changed, 40 insertions(+), 152 deletions(-)

diff --git a/libc/src/__support/CPP/type_traits/is_signed.h b/libc/src/__support/CPP/type_traits/is_signed.h
index 9b763aa0bec5d..2ddb43ac4ee3e 100644
--- a/libc/src/__support/CPP/type_traits/is_signed.h
+++ b/libc/src/__support/CPP/type_traits/is_signed.h
@@ -11,92 +11,37 @@
 #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_fixed_point.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 {
 
-// Primary template: handles arithmetic and signed fixed-point types
+#ifndef LIBC_COMPILER_HAS_FIXED_POINT
 template <typename T>
 struct is_signed : bool_constant<(is_arithmetic_v<T> && (T(-1) < T(0)))> {
   LIBC_INLINE constexpr operator bool() const { return is_signed::value; }
   LIBC_INLINE constexpr bool operator()() const { return is_signed::value; }
 };
-
-#ifdef LIBC_COMPILER_HAS_FIXED_POINT
-// Specializations for unsigned fixed-point types
-template <typename T, bool IsSigned>
-struct fixed_point_is_signed : bool_constant<IsSigned> {
-  LIBC_INLINE constexpr operator bool() const {
-    return fixed_point_is_signed::value;
-  }
-  LIBC_INLINE constexpr bool operator()() const {
-    return fixed_point_is_signed::value;
+#else
+template <typename T> struct is_signed {
+private:
+  template <typename Head, typename... Args>
+  LIBC_INLINE static constexpr bool __is_unqualified_any_of() {
+    return (... || is_same_v<remove_cv_t<Head>, Args>);
   }
-};
-template <> struct is_signed<fract> : fixed_point_is_signed<fract, true> {};
-template <>
-struct is_signed<unsigned short fract>
-    : fixed_point_is_signed<unsigned short fract, false> {};
-template <>
-struct is_signed<unsigned fract>
-    : fixed_point_is_signed<unsigned fract, false> {};
-template <>
-struct is_signed<unsigned long fract>
-    : fixed_point_is_signed<unsigned long fract, false> {};
-template <>
-struct is_signed<short fract> : fixed_point_is_signed<short fract, true> {};
-template <>
-struct is_signed<long fract> : fixed_point_is_signed<long fract, true> {};
-template <> struct is_signed<accum> : fixed_point_is_signed<accum, true> {};
-template <>
-struct is_signed<unsigned short accum>
-    : fixed_point_is_signed<unsigned short accum, false> {};
-template <>
-struct is_signed<unsigned accum>
-    : fixed_point_is_signed<unsigned accum, false> {};
-template <>
-struct is_signed<unsigned long accum>
-    : fixed_point_is_signed<unsigned long accum, false> {};
-template <>
-struct is_signed<short accum> : fixed_point_is_signed<short accum, true> {};
-template <>
-struct is_signed<long accum> : fixed_point_is_signed<long accum, true> {};
-template <>
-struct is_signed<sat fract> : fixed_point_is_signed<sat fract, true> {};
-template <>
-struct is_signed<unsigned short sat fract>
-    : fixed_point_is_signed<unsigned short sat fract, false> {};
-template <>
-struct is_signed<unsigned sat fract>
-    : fixed_point_is_signed<unsigned sat fract, false> {};
-template <>
-struct is_signed<unsigned long sat fract>
-    : fixed_point_is_signed<unsigned long sat fract, false> {};
-template <>
-struct is_signed<short sat fract>
-    : fixed_point_is_signed<short sat fract, true> {};
-template <>
-struct is_signed<long sat fract> : fixed_point_is_signed<long sat fract, true> {
-};
-template <>
-struct is_signed<sat accum> : fixed_point_is_signed<sat accum, true> {};
-template <>
-struct is_signed<unsigned short sat accum>
-    : fixed_point_is_signed<unsigned short sat accum, false> {};
-template <>
-struct is_signed<unsigned sat accum>
-    : fixed_point_is_signed<unsigned sat accum, false> {};
-template <>
-struct is_signed<unsigned long sat accum>
-    : fixed_point_is_signed<unsigned long sat accum, false> {};
-template <>
-struct is_signed<short sat accum>
-    : fixed_point_is_signed<short sat accum, true> {};
-template <>
-struct is_signed<long sat accum> : fixed_point_is_signed<long sat accum, true> {
+
+public:
+  LIBC_INLINE_VAR static constexpr bool value =
+      (is_arithmetic_v<T> && (T(-1) < T(0))) ||
+      __is_unqualified_any_of<T, short fract, fract, long fract, short accum,
+                              accum, long accum, short sat fract, sat fract,
+                              long sat fract, short sat accum, sat accum,
+                              long sat accum>();
+  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
 
diff --git a/libc/src/__support/CPP/type_traits/is_unsigned.h b/libc/src/__support/CPP/type_traits/is_unsigned.h
index a4de8ca683a30..3ae6337ceb50a 100644
--- a/libc/src/__support/CPP/type_traits/is_unsigned.h
+++ b/libc/src/__support/CPP/type_traits/is_unsigned.h
@@ -11,97 +11,40 @@
 #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_fixed_point.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 {
 
-// Primary template: handles arithmetic and signed fixed-point types
+#ifndef LIBC_COMPILER_HAS_FIXED_POINT
 template <typename T>
 struct is_unsigned : bool_constant<(is_arithmetic_v<T> && (T(-1) > T(0)))> {
   LIBC_INLINE constexpr operator bool() const { return is_unsigned::value; }
   LIBC_INLINE constexpr bool operator()() const { return is_unsigned::value; }
 };
-
-#ifdef LIBC_COMPILER_HAS_FIXED_POINT
-// Specializations for unsigned fixed-point types
-template <typename T, bool IsUnsigned>
-struct fixed_point_is_unsigned : bool_constant<IsUnsigned> {
-  LIBC_INLINE constexpr operator bool() const {
-    return fixed_point_is_unsigned::value;
-  }
-  LIBC_INLINE constexpr bool operator()() const {
-    return fixed_point_is_unsigned::value;
+#else
+template <typename T> struct is_unsigned {
+private:
+  template <typename Head, typename... Args>
+  LIBC_INLINE static constexpr bool __is_unqualified_any_of() {
+    return (... || is_same_v<remove_cv_t<Head>, Args>);
   }
+
+public:
+  LIBC_INLINE_VAR static constexpr bool value =
+      (is_arithmetic_v<T> && (T(-1) > T(0))) ||
+      __is_unqualified_any_of<T, unsigned short fract, unsigned fract,
+                              unsigned long fract, unsigned short accum,
+                              unsigned accum, unsigned long accum,
+                              unsigned short sat fract, unsigned sat fract,
+                              unsigned long sat fract, unsigned short sat accum,
+                              unsigned sat accum, unsigned long sat accum>();
+  LIBC_INLINE constexpr operator bool() const { return is_unsigned::value; }
+  LIBC_INLINE constexpr bool operator()() const { return is_unsigned::value; }
 };
-template <>
-struct is_unsigned<fract> : fixed_point_is_unsigned<fract, false> {};
-template <>
-struct is_unsigned<unsigned short fract>
-    : fixed_point_is_unsigned<unsigned short fract, true> {};
-template <>
-struct is_unsigned<unsigned fract>
-    : fixed_point_is_unsigned<unsigned fract, true> {};
-template <>
-struct is_unsigned<unsigned long fract>
-    : fixed_point_is_unsigned<unsigned long fract, true> {};
-template <>
-struct is_unsigned<short fract> : fixed_point_is_unsigned<short fract, false> {
-};
-template <>
-struct is_unsigned<long fract> : fixed_point_is_unsigned<long fract, false> {};
-template <>
-struct is_unsigned<accum> : fixed_point_is_unsigned<accum, false> {};
-template <>
-struct is_unsigned<unsigned short accum>
-    : fixed_point_is_unsigned<unsigned short accum, true> {};
-template <>
-struct is_unsigned<unsigned accum>
-    : fixed_point_is_unsigned<unsigned accum, true> {};
-template <>
-struct is_unsigned<unsigned long accum>
-    : fixed_point_is_unsigned<unsigned long accum, true> {};
-template <>
-struct is_unsigned<short accum> : fixed_point_is_unsigned<short accum, false> {
-};
-template <>
-struct is_unsigned<long accum> : fixed_point_is_unsigned<long accum, false> {};
-template <>
-struct is_unsigned<sat fract> : fixed_point_is_unsigned<sat fract, false> {};
-template <>
-struct is_unsigned<unsigned short sat fract>
-    : fixed_point_is_unsigned<unsigned short sat fract, true> {};
-template <>
-struct is_unsigned<unsigned sat fract>
-    : fixed_point_is_unsigned<unsigned sat fract, true> {};
-template <>
-struct is_unsigned<unsigned long sat fract>
-    : fixed_point_is_unsigned<unsigned long sat fract, true> {};
-template <>
-struct is_unsigned<short sat fract>
-    : fixed_point_is_unsigned<short sat fract, false> {};
-template <>
-struct is_unsigned<long sat fract>
-    : fixed_point_is_unsigned<long sat fract, false> {};
-template <>
-struct is_unsigned<sat accum> : fixed_point_is_unsigned<sat accum, false> {};
-template <>
-struct is_unsigned<unsigned short sat accum>
-    : fixed_point_is_unsigned<unsigned short sat accum, true> {};
-template <>
-struct is_unsigned<unsigned sat accum>
-    : fixed_point_is_unsigned<unsigned sat accum, true> {};
-template <>
-struct is_unsigned<unsigned long sat accum>
-    : fixed_point_is_unsigned<unsigned long sat accum, true> {};
-template <>
-struct is_unsigned<short sat accum>
-    : fixed_point_is_unsigned<short sat accum, false> {};
-template <>
-struct is_unsigned<long sat accum>
-    : fixed_point_is_unsigned<long sat accum, false> {};
 #endif // LIBC_COMPILER_HAS_FIXED_POINT
 
 template <typename T>



More information about the libc-commits mailing list