summaryrefslogtreecommitdiff
path: root/src/common/alignment.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/common/alignment.h')
-rw-r--r--src/common/alignment.h37
1 files changed, 33 insertions, 4 deletions
diff --git a/src/common/alignment.h b/src/common/alignment.h
index fa715d497..fc5c26898 100644
--- a/src/common/alignment.h
+++ b/src/common/alignment.h
@@ -3,6 +3,7 @@
3 3
4#pragma once 4#pragma once
5 5
6#include <bit>
6#include <cstddef> 7#include <cstddef>
7#include <new> 8#include <new>
8#include <type_traits> 9#include <type_traits>
@@ -10,8 +11,10 @@
10namespace Common { 11namespace Common {
11 12
12template <typename T> 13template <typename T>
13 requires std::is_unsigned_v<T> 14 requires std::is_integral_v<T>
14[[nodiscard]] constexpr T AlignUp(T value, size_t size) { 15[[nodiscard]] constexpr T AlignUp(T value_, size_t size) {
16 using U = typename std::make_unsigned_t<T>;
17 auto value{static_cast<U>(value_)};
15 auto mod{static_cast<T>(value % size)}; 18 auto mod{static_cast<T>(value % size)};
16 value -= mod; 19 value -= mod;
17 return static_cast<T>(mod == T{0} ? value : value + size); 20 return static_cast<T>(mod == T{0} ? value : value + size);
@@ -24,8 +27,10 @@ template <typename T>
24} 27}
25 28
26template <typename T> 29template <typename T>
27 requires std::is_unsigned_v<T> 30 requires std::is_integral_v<T>
28[[nodiscard]] constexpr T AlignDown(T value, size_t size) { 31[[nodiscard]] constexpr T AlignDown(T value_, size_t size) {
32 using U = typename std::make_unsigned_t<T>;
33 const auto value{static_cast<U>(value_)};
29 return static_cast<T>(value - value % size); 34 return static_cast<T>(value - value % size);
30} 35}
31 36
@@ -55,6 +60,30 @@ template <typename T, typename U>
55 return (x + (y - 1)) / y; 60 return (x + (y - 1)) / y;
56} 61}
57 62
63template <typename T>
64 requires std::is_integral_v<T>
65[[nodiscard]] constexpr T LeastSignificantOneBit(T x) {
66 return x & ~(x - 1);
67}
68
69template <typename T>
70 requires std::is_integral_v<T>
71[[nodiscard]] constexpr T ResetLeastSignificantOneBit(T x) {
72 return x & (x - 1);
73}
74
75template <typename T>
76 requires std::is_integral_v<T>
77[[nodiscard]] constexpr bool IsPowerOfTwo(T x) {
78 return x > 0 && ResetLeastSignificantOneBit(x) == 0;
79}
80
81template <typename T>
82 requires std::is_integral_v<T>
83[[nodiscard]] constexpr T FloorPowerOfTwo(T x) {
84 return T{1} << (sizeof(T) * 8 - std::countl_zero(x) - 1);
85}
86
58template <typename T, size_t Align = 16> 87template <typename T, size_t Align = 16>
59class AlignmentAllocator { 88class AlignmentAllocator {
60public: 89public: