1*bb722a7dSDimitry Andric //===-- A self contained equivalent of std::limits --------------*- C++ -*-===// 2*bb722a7dSDimitry Andric // 3*bb722a7dSDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4*bb722a7dSDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 5*bb722a7dSDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6*bb722a7dSDimitry Andric // 7*bb722a7dSDimitry Andric //===----------------------------------------------------------------------===// 8*bb722a7dSDimitry Andric 9*bb722a7dSDimitry Andric #ifndef LLVM_LIBC_SRC___SUPPORT_CPP_LIMITS_H 10*bb722a7dSDimitry Andric #define LLVM_LIBC_SRC___SUPPORT_CPP_LIMITS_H 11*bb722a7dSDimitry Andric 12*bb722a7dSDimitry Andric #include "hdr/limits_macros.h" // CHAR_BIT 13*bb722a7dSDimitry Andric #include "src/__support/CPP/type_traits/is_integral.h" 14*bb722a7dSDimitry Andric #include "src/__support/CPP/type_traits/is_signed.h" 15*bb722a7dSDimitry Andric #include "src/__support/macros/attributes.h" // LIBC_INLINE 16*bb722a7dSDimitry Andric #include "src/__support/macros/config.h" 17*bb722a7dSDimitry Andric #include "src/__support/macros/properties/types.h" // LIBC_TYPES_HAS_INT128 18*bb722a7dSDimitry Andric 19*bb722a7dSDimitry Andric namespace LIBC_NAMESPACE_DECL { 20*bb722a7dSDimitry Andric namespace cpp { 21*bb722a7dSDimitry Andric 22*bb722a7dSDimitry Andric namespace internal { 23*bb722a7dSDimitry Andric 24*bb722a7dSDimitry Andric template <typename T, T min_value, T max_value> struct integer_impl { 25*bb722a7dSDimitry Andric static_assert(cpp::is_integral_v<T>); maxinteger_impl26*bb722a7dSDimitry Andric LIBC_INLINE static constexpr T max() { return max_value; } mininteger_impl27*bb722a7dSDimitry Andric LIBC_INLINE static constexpr T min() { return min_value; } 28*bb722a7dSDimitry Andric LIBC_INLINE_VAR static constexpr int digits = 29*bb722a7dSDimitry Andric CHAR_BIT * sizeof(T) - cpp::is_signed_v<T>; 30*bb722a7dSDimitry Andric }; 31*bb722a7dSDimitry Andric 32*bb722a7dSDimitry Andric } // namespace internal 33*bb722a7dSDimitry Andric 34*bb722a7dSDimitry Andric template <class T> struct numeric_limits {}; 35*bb722a7dSDimitry Andric 36*bb722a7dSDimitry Andric // TODO: Add numeric_limits specializations as needed for new types. 37*bb722a7dSDimitry Andric template <> 38*bb722a7dSDimitry Andric struct numeric_limits<short> 39*bb722a7dSDimitry Andric : public internal::integer_impl<short, SHRT_MIN, SHRT_MAX> {}; 40*bb722a7dSDimitry Andric 41*bb722a7dSDimitry Andric template <> 42*bb722a7dSDimitry Andric struct numeric_limits<unsigned short> 43*bb722a7dSDimitry Andric : public internal::integer_impl<unsigned short, 0, USHRT_MAX> {}; 44*bb722a7dSDimitry Andric 45*bb722a7dSDimitry Andric template <> 46*bb722a7dSDimitry Andric struct numeric_limits<int> 47*bb722a7dSDimitry Andric : public internal::integer_impl<int, INT_MIN, INT_MAX> {}; 48*bb722a7dSDimitry Andric 49*bb722a7dSDimitry Andric template <> 50*bb722a7dSDimitry Andric struct numeric_limits<unsigned int> 51*bb722a7dSDimitry Andric : public internal::integer_impl<unsigned int, 0, UINT_MAX> {}; 52*bb722a7dSDimitry Andric 53*bb722a7dSDimitry Andric template <> 54*bb722a7dSDimitry Andric struct numeric_limits<long> 55*bb722a7dSDimitry Andric : public internal::integer_impl<long, LONG_MIN, LONG_MAX> {}; 56*bb722a7dSDimitry Andric 57*bb722a7dSDimitry Andric template <> 58*bb722a7dSDimitry Andric struct numeric_limits<unsigned long> 59*bb722a7dSDimitry Andric : public internal::integer_impl<unsigned long, 0, ULONG_MAX> {}; 60*bb722a7dSDimitry Andric 61*bb722a7dSDimitry Andric template <> 62*bb722a7dSDimitry Andric struct numeric_limits<long long> 63*bb722a7dSDimitry Andric : public internal::integer_impl<long long, LLONG_MIN, LLONG_MAX> {}; 64*bb722a7dSDimitry Andric 65*bb722a7dSDimitry Andric template <> 66*bb722a7dSDimitry Andric struct numeric_limits<unsigned long long> 67*bb722a7dSDimitry Andric : public internal::integer_impl<unsigned long long, 0, ULLONG_MAX> {}; 68*bb722a7dSDimitry Andric 69*bb722a7dSDimitry Andric template <> 70*bb722a7dSDimitry Andric struct numeric_limits<char> 71*bb722a7dSDimitry Andric : public internal::integer_impl<char, CHAR_MIN, CHAR_MAX> {}; 72*bb722a7dSDimitry Andric 73*bb722a7dSDimitry Andric template <> 74*bb722a7dSDimitry Andric struct numeric_limits<signed char> 75*bb722a7dSDimitry Andric : public internal::integer_impl<signed char, SCHAR_MIN, SCHAR_MAX> {}; 76*bb722a7dSDimitry Andric 77*bb722a7dSDimitry Andric template <> 78*bb722a7dSDimitry Andric struct numeric_limits<unsigned char> 79*bb722a7dSDimitry Andric : public internal::integer_impl<unsigned char, 0, UCHAR_MAX> {}; 80*bb722a7dSDimitry Andric 81*bb722a7dSDimitry Andric #ifdef LIBC_TYPES_HAS_INT128 82*bb722a7dSDimitry Andric // On platform where UInt128 resolves to __uint128_t, this specialization 83*bb722a7dSDimitry Andric // provides the limits of UInt128. 84*bb722a7dSDimitry Andric template <> 85*bb722a7dSDimitry Andric struct numeric_limits<__uint128_t> 86*bb722a7dSDimitry Andric : public internal::integer_impl<__uint128_t, 0, ~__uint128_t(0)> {}; 87*bb722a7dSDimitry Andric #endif 88*bb722a7dSDimitry Andric 89*bb722a7dSDimitry Andric } // namespace cpp 90*bb722a7dSDimitry Andric } // namespace LIBC_NAMESPACE_DECL 91*bb722a7dSDimitry Andric 92*bb722a7dSDimitry Andric #endif // LLVM_LIBC_SRC___SUPPORT_CPP_LIMITS_H 93