[libc-commits] [libc] 8b25381 - [libc] Add the digits property to numeric_limits (#73926)

via libc-commits libc-commits at lists.llvm.org
Thu Nov 30 04:35:01 PST 2023


Author: Guillaume Chatelet
Date: 2023-11-30T13:34:55+01:00
New Revision: 8b25381bb6221dcfd2295aa2fd819f5b97704ca1

URL: https://github.com/llvm/llvm-project/commit/8b25381bb6221dcfd2295aa2fd819f5b97704ca1
DIFF: https://github.com/llvm/llvm-project/commit/8b25381bb6221dcfd2295aa2fd819f5b97704ca1.diff

LOG: [libc] Add the digits property to numeric_limits (#73926)

Added: 
    

Modified: 
    libc/src/__support/CPP/CMakeLists.txt
    libc/src/__support/CPP/limits.h
    utils/bazel/llvm-project-overlay/libc/BUILD.bazel

Removed: 
    


################################################################################
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..e92ad00f80e0379 100644
--- a/libc/src/__support/CPP/limits.h
+++ b/libc/src/__support/CPP/limits.h
@@ -9,9 +9,11 @@
 #ifndef LLVM_LIBC_SRC___SUPPORT_CPP_LIMITS_H
 #define LLVM_LIBC_SRC___SUPPORT_CPP_LIMITS_H
 
+#include "src/__support/CPP/type_traits/is_integral.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 +26,71 @@ 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 integer_impl {
+  static_assert(cpp::is_integral_v<T>);
+  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::integer_impl<short, SHRT_MIN, SHRT_MAX> {};
+
+template <>
+struct numeric_limits<unsigned short>
+    : public internal::integer_impl<unsigned short, 0, USHRT_MAX> {};
+
+template <>
+struct numeric_limits<int>
+    : public internal::integer_impl<int, INT_MIN, INT_MAX> {};
+
+template <>
+struct numeric_limits<unsigned int>
+    : public internal::integer_impl<unsigned int, 0, UINT_MAX> {};
+
+template <>
+struct numeric_limits<long>
+    : public internal::integer_impl<long, LONG_MIN, LONG_MAX> {};
+
+template <>
+struct numeric_limits<unsigned long>
+    : public internal::integer_impl<unsigned long, 0, ULONG_MAX> {};
+
+template <>
+struct numeric_limits<long long>
+    : public internal::integer_impl<long long, LLONG_MIN, LLONG_MAX> {};
+
+template <>
+struct numeric_limits<unsigned long long>
+    : public internal::integer_impl<unsigned long long, 0, ULLONG_MAX> {};
+
+template <>
+struct numeric_limits<char>
+    : public internal::integer_impl<char, CHAR_MIN, CHAR_MAX> {};
+
+template <>
+struct numeric_limits<signed char>
+    : public internal::integer_impl<signed char, SCHAR_MIN, SCHAR_MAX> {};
+
+template <>
+struct numeric_limits<unsigned char>
+    : public internal::integer_impl<unsigned char, 0, UCHAR_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 <> 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; }
-};
 #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::integer_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 860efbca1768853..2a88ad881b05107 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",
     ],
 )


        


More information about the libc-commits mailing list