Jlm
Math.hpp
Go to the documentation of this file.
1 /*
2  * Copyright 2023 HÃ¥vard Krogstie <krogstie.havard@gmail.com>
3  * See COPYING for terms of redistribution.
4  */
5 
6 #ifndef JLM_UTIL_MATH_HPP
7 #define JLM_UTIL_MATH_HPP
8 
9 #include <type_traits>
10 
11 namespace jlm::util
12 {
13 
23 template<class T>
24 static constexpr int
25 log2Floor(T value)
26 {
27  static_assert(std::is_integral_v<T>, "T must be integral type");
28  if (value < 1)
29  return -1;
30 
31  return 1 + log2Floor(value >> 1);
32 }
33 
46 template<class T>
47 static constexpr T
49 {
50  // 2^0 == 1 is the lowest possible power of two
51  if (value <= 1)
52  return 1;
53 
54  return T(1) << (log2Floor(value - 1) + 1);
55 }
56 
70 template<class T>
71 static constexpr T
72 RoundUpToMultipleOf(T value, T multiple)
73 {
74  const auto miss = value % multiple;
75  if (miss < 0)
76  return value - miss;
77  if (miss == 0)
78  return value;
79  return value + multiple - miss;
80 }
81 
92 template<class T>
93 static constexpr int
95 {
96  using UnsignedT = std::make_unsigned_t<T>;
97  return log2Floor(static_cast<UnsignedT>(value)) + 1;
98 }
99 
105 template<class T>
106 static constexpr int
107 BitWidthOfEnum(T endValue)
108 {
109  static_assert(std::is_enum_v<T>, "BitWidthOfEnum only takes enums");
110 
111  using UnderlyingT = std::underlying_type_t<T>;
112 
113  // To appease gcc warnings, the returned bit width is large enough to hold the endValue as well,
114  // even if it is just a sentinel COUNT value
115  return BitsRequiredToRepresent(static_cast<UnderlyingT>(endValue));
116 }
117 
118 }
119 
120 #endif // JLM_UTIL_MATH_HPP
static constexpr T RoundUpToMultipleOf(T value, T multiple)
Definition: Math.hpp:72
static constexpr T RoundUpToPowerOf2(T value)
Definition: Math.hpp:48
static constexpr int BitsRequiredToRepresent(T value)
Definition: Math.hpp:94
static constexpr int BitWidthOfEnum(T endValue)
Definition: Math.hpp:107
static constexpr int log2Floor(T value)
Definition: Math.hpp:25