1 //===-- A self contained equivalent of std::limits --------------*- C++ -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 #ifndef LLVM_LIBC_SRC_SUPPORT_CPP_LIMITS_H
10 #define LLVM_LIBC_SRC_SUPPORT_CPP_LIMITS_H
11 
12 #include "UInt.h"
13 
14 #include <limits.h>
15 
16 namespace __llvm_libc {
17 namespace cpp {
18 
19 template <class T> class NumericLimits {
20 public:
21   static constexpr T max();
22   static constexpr T min();
23 };
24 
25 // TODO: Add NumericLimits specializations as needed for new types.
26 
27 template <> class NumericLimits<int> {
28 public:
max()29   static constexpr int max() { return INT_MAX; }
min()30   static constexpr int min() { return INT_MIN; }
31 };
32 template <> class NumericLimits<unsigned int> {
33 public:
max()34   static constexpr unsigned int max() { return UINT_MAX; }
min()35   static constexpr unsigned int min() { return 0; }
36 };
37 template <> class NumericLimits<long> {
38 public:
max()39   static constexpr long max() { return LONG_MAX; }
min()40   static constexpr long min() { return LONG_MIN; }
41 };
42 template <> class NumericLimits<unsigned long> {
43 public:
max()44   static constexpr unsigned long max() { return ULONG_MAX; }
min()45   static constexpr unsigned long min() { return 0; }
46 };
47 template <> class NumericLimits<long long> {
48 public:
max()49   static constexpr long long max() { return LLONG_MAX; }
min()50   static constexpr long long min() { return LLONG_MIN; }
51 };
52 template <> class NumericLimits<unsigned long long> {
53 public:
max()54   static constexpr unsigned long long max() { return ULLONG_MAX; }
min()55   static constexpr unsigned long long min() { return 0; }
56 };
57 template <> class NumericLimits<short> {
58 public:
max()59   static constexpr short max() { return SHRT_MAX; }
min()60   static constexpr short min() { return SHRT_MIN; }
61 };
62 template <> class NumericLimits<unsigned short> {
63 public:
max()64   static constexpr unsigned short max() { return USHRT_MAX; }
min()65   static constexpr unsigned short min() { return 0; }
66 };
67 template <> class NumericLimits<char> {
68 public:
max()69   static constexpr char max() { return CHAR_MAX; }
min()70   static constexpr char min() { return CHAR_MIN; }
71 };
72 template <> class NumericLimits<unsigned char> {
73 public:
max()74   static constexpr unsigned char max() { return UCHAR_MAX; }
min()75   static constexpr unsigned char min() { return 0; }
76 };
77 // This specialization enables two things:
78 // 1. On platforms where UInt128 resolves to UInt<128>, this specialization
79 //    provides limits of UInt128.
80 // 2. On platforms where UInt128 resolves to __uint128_t, this specialization
81 //    allows us to unittest UInt<128>.
82 template <> class NumericLimits<UInt<128>> {
83 public:
max()84   static constexpr UInt<128> max() { return ~UInt<128>(0); }
min()85   static constexpr UInt<128> min() { return 0; }
86 };
87 #ifdef __SIZEOF_INT128__
88 // On platform where UInt128 resolves to __uint128_t, this specialization
89 // provides the limits of UInt128.
90 template <> class NumericLimits<__uint128_t> {
91 public:
max()92   static constexpr __uint128_t max() { return ~__uint128_t(0); }
min()93   static constexpr __uint128_t min() { return 0; }
94 };
95 #endif
96 
97 } // namespace cpp
98 } // namespace __llvm_libc
99 
100 #endif // LLVM_LIBC_SRC_SUPPORT_CPP_LIMITS_H
101