[libc-commits] [libc] Added support of fixed-points in ``is_signed`` and ``is_unsigned``. (PR #133371)
Abhinav Kumar via libc-commits
libc-commits at lists.llvm.org
Thu Mar 27 22:47:06 PDT 2025
https://github.com/kr-2003 created https://github.com/llvm/llvm-project/pull/133371
Fixes #133365
>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] 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
More information about the libc-commits
mailing list