Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[libc] Add the digit property to numeric_limits #73926

Merged
merged 3 commits into from
Nov 30, 2023

Conversation

gchatelet
Copy link
Contributor

No description provided.

@llvmbot
Copy link
Collaborator

llvmbot commented Nov 30, 2023

@llvm/pr-subscribers-libc

Author: Guillaume Chatelet (gchatelet)

Changes

Full diff: https://github.com/llvm/llvm-project/pull/73926.diff

3 Files Affected:

  • (modified) libc/src/__support/CPP/CMakeLists.txt (+2)
  • (modified) libc/src/__support/CPP/limits.h (+59-63)
  • (modified) utils/bazel/llvm-project-overlay/libc/BUILD.bazel (+1)
diff --git a/libc/src/__support/CPP/CMakeLists.txt b/libc/src/__support/CPP/CMakeLists.txt
index 10bcebf9b04f61d..6a81717fd0ec513 100644
--- a/libc/src/__support/CPP/CMakeLists.txt
+++ b/libc/src/__support/CPP/CMakeLists.txt
@@ -45,6 +45,8 @@ add_header_library(
   limits
   HDRS
     limits.h
+  DEPENDS
+    .type_traits
 )
 
 add_header_library(
diff --git a/libc/src/__support/CPP/limits.h b/libc/src/__support/CPP/limits.h
index b1a1203df79674a..3126b38ec48e612 100644
--- a/libc/src/__support/CPP/limits.h
+++ b/libc/src/__support/CPP/limits.h
@@ -9,9 +9,10 @@
 #ifndef LLVM_LIBC_SRC___SUPPORT_CPP_LIMITS_H
 #define LLVM_LIBC_SRC___SUPPORT_CPP_LIMITS_H
 
+#include "src/__support/CPP/type_traits/is_signed.h"
 #include "src/__support/macros/attributes.h" // LIBC_INLINE
 
-#include <limits.h>
+#include <limits.h> // CHAR_BIT
 
 namespace LIBC_NAMESPACE {
 namespace cpp {
@@ -24,77 +25,72 @@ constexpr long long LLONG_MIN = 1LL << (LLONG_BIT_WIDTH - 1);
 constexpr unsigned long long ULLONG_MAX = ~0ULL;
 #endif
 
-template <class T> class numeric_limits {
-public:
-  LIBC_INLINE static constexpr T max();
-  LIBC_INLINE static constexpr T min();
+namespace internal {
+
+template <typename T, T min_value, T max_value> struct numeric_limits_impl {
+  LIBC_INLINE static constexpr T max() { return max_value; }
+  LIBC_INLINE static constexpr T min() { return min_value; }
+  LIBC_INLINE_VAR static constexpr int digits =
+      CHAR_BIT * sizeof(T) - cpp::is_signed_v<T>;
 };
 
+} // namespace internal
+
+template <class T> struct numeric_limits {};
+
 // TODO: Add numeric_limits specializations as needed for new types.
+template <>
+struct numeric_limits<short>
+    : public internal::numeric_limits_impl<short, SHRT_MIN, SHRT_MAX> {};
 
-template <> class numeric_limits<int> {
-public:
-  LIBC_INLINE static constexpr int max() { return INT_MAX; }
-  LIBC_INLINE static constexpr int min() { return INT_MIN; }
-};
-template <> class numeric_limits<unsigned int> {
-public:
-  LIBC_INLINE static constexpr unsigned int max() { return UINT_MAX; }
-  LIBC_INLINE static constexpr unsigned int min() { return 0; }
-};
-template <> class numeric_limits<long> {
-public:
-  LIBC_INLINE static constexpr long max() { return LONG_MAX; }
-  LIBC_INLINE static constexpr long min() { return LONG_MIN; }
-};
-template <> class numeric_limits<unsigned long> {
-public:
-  LIBC_INLINE static constexpr unsigned long max() { return ULONG_MAX; }
-  LIBC_INLINE static constexpr unsigned long min() { return 0; }
-};
-template <> class numeric_limits<long long> {
-public:
-  LIBC_INLINE static constexpr long long max() { return LLONG_MAX; }
-  LIBC_INLINE static constexpr long long min() { return LLONG_MIN; }
-};
-template <> class numeric_limits<unsigned long long> {
-public:
-  LIBC_INLINE static constexpr unsigned long long max() { return ULLONG_MAX; }
-  LIBC_INLINE static constexpr unsigned long long min() { return 0; }
-};
-template <> class numeric_limits<short> {
-public:
-  LIBC_INLINE static constexpr short max() { return SHRT_MAX; }
-  LIBC_INLINE static constexpr short min() { return SHRT_MIN; }
-};
-template <> class numeric_limits<unsigned short> {
-public:
-  LIBC_INLINE static constexpr unsigned short max() { return USHRT_MAX; }
-  LIBC_INLINE static constexpr unsigned short min() { return 0; }
-};
-template <> class numeric_limits<char> {
-public:
-  LIBC_INLINE static constexpr char max() { return CHAR_MAX; }
-  LIBC_INLINE static constexpr char min() { return CHAR_MIN; }
-};
-template <> class numeric_limits<signed char> {
-public:
-  LIBC_INLINE static constexpr signed char max() { return SCHAR_MAX; }
-  LIBC_INLINE static constexpr signed char min() { return SCHAR_MIN; }
+template <>
+struct numeric_limits<unsigned short>
+    : public internal::numeric_limits_impl<unsigned short, 0, USHRT_MAX> {};
+
+template <>
+struct numeric_limits<int>
+    : public internal::numeric_limits_impl<int, INT_MIN, INT_MAX> {};
+
+template <>
+struct numeric_limits<unsigned int>
+    : public internal::numeric_limits_impl<unsigned int, 0, UINT_MAX> {};
+
+template <>
+struct numeric_limits<long>
+    : public internal::numeric_limits_impl<long, LONG_MIN, LONG_MAX> {};
+
+template <>
+struct numeric_limits<unsigned long>
+    : public internal::numeric_limits_impl<unsigned long, 0, ULONG_MAX> {};
+
+template <>
+struct numeric_limits<long long>
+    : public internal::numeric_limits_impl<long long, LLONG_MIN, LLONG_MAX> {};
+
+template <>
+struct numeric_limits<unsigned long long>
+    : public internal::numeric_limits_impl<unsigned long long, 0, ULLONG_MAX> {
 };
-template <> class numeric_limits<unsigned char> {
-public:
-  LIBC_INLINE static constexpr unsigned char max() { return UCHAR_MAX; }
-  LIBC_INLINE static constexpr unsigned char min() { return 0; }
+
+template <>
+struct numeric_limits<char>
+    : public internal::numeric_limits_impl<char, CHAR_MIN, CHAR_MAX> {};
+
+template <>
+struct numeric_limits<signed char>
+    : public internal::numeric_limits_impl<signed char, SCHAR_MIN, SCHAR_MAX> {
 };
+
+template <>
+struct numeric_limits<unsigned char>
+    : public internal::numeric_limits_impl<unsigned char, 0, UCHAR_MAX> {};
+
 #ifdef __SIZEOF_INT128__
 // On platform where UInt128 resolves to __uint128_t, this specialization
 // provides the limits of UInt128.
-template <> class numeric_limits<__uint128_t> {
-public:
-  LIBC_INLINE static constexpr __uint128_t max() { return ~__uint128_t(0); }
-  LIBC_INLINE static constexpr __uint128_t min() { return 0; }
-};
+template <>
+struct numeric_limits<__uint128_t>
+    : public internal::numeric_limits_impl<__uint128_t, 0, ~__uint128_t(0)> {};
 #endif
 
 } // namespace cpp
diff --git a/utils/bazel/llvm-project-overlay/libc/BUILD.bazel b/utils/bazel/llvm-project-overlay/libc/BUILD.bazel
index ffb2652ed1419d0..365fbd1cbc4d7b4 100644
--- a/utils/bazel/llvm-project-overlay/libc/BUILD.bazel
+++ b/utils/bazel/llvm-project-overlay/libc/BUILD.bazel
@@ -206,6 +206,7 @@ libc_support_library(
     name = "__support_cpp_limits",
     hdrs = ["src/__support/CPP/limits.h"],
     deps = [
+        "__support_cpp_type_traits",
         "__support_macros_attributes",
     ],
 )

Copy link

github-actions bot commented Nov 30, 2023

✅ With the latest revision this PR passed the C/C++ code formatter.

@gchatelet gchatelet merged commit 8b25381 into llvm:main Nov 30, 2023
3 checks passed
@gchatelet gchatelet deleted the add_digits_to_numeric_limits branch November 30, 2023 12:35
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants