1//===-- A self contained equivalent of <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 "hdr/limits_macros.h" // CHAR_BIT
13#include "src/__support/CPP/type_traits/is_integral.h"
14#include "src/__support/CPP/type_traits/is_signed.h"
15#include "src/__support/macros/attributes.h" // LIBC_INLINE
16
17namespace LIBC_NAMESPACE_DECL {
18namespace cpp {
19
20namespace internal {
21
22template <typename T, bool is_integral> struct numeric_limits_impl {};
23
24template <typename T> struct numeric_limits_impl<T, true> {
25 LIBC_INLINE_VAR static constexpr bool is_signed = T(-1) < T(0);
26
27 LIBC_INLINE_VAR static constexpr int digits =
28 (CHAR_BIT * sizeof(T)) - is_signed;
29
30 LIBC_INLINE static constexpr T min() {
31 if constexpr (is_signed) {
32 return T(T(1) << digits);
33 } else {
34 return 0;
35 }
36 }
37
38 LIBC_INLINE static constexpr T max() {
39 if constexpr (is_signed) {
40 return T(T(~0) ^ min());
41 } else {
42 return T(~0);
43 }
44 }
45};
46
47} // namespace internal
48
49template <typename T>
50struct numeric_limits
51 : public internal::numeric_limits_impl<T, is_integral_v<T>> {};
52
53} // namespace cpp
54} // namespace LIBC_NAMESPACE_DECL
55
56#endif // LLVM_LIBC_SRC___SUPPORT_CPP_LIMITS_H
57