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.h66
1 files changed, 66 insertions, 0 deletions
diff --git a/src/common/alignment.h b/src/common/alignment.h
index d94a2291f..88d5d3a65 100644
--- a/src/common/alignment.h
+++ b/src/common/alignment.h
@@ -3,6 +3,7 @@
3#pragma once 3#pragma once
4 4
5#include <cstddef> 5#include <cstddef>
6#include <memory>
6#include <type_traits> 7#include <type_traits>
7 8
8namespace Common { 9namespace Common {
@@ -20,6 +21,12 @@ constexpr T AlignDown(T value, std::size_t size) {
20} 21}
21 22
22template <typename T> 23template <typename T>
24constexpr T AlignBits(T value, std::size_t align) {
25 static_assert(std::is_unsigned_v<T>, "T must be an unsigned value.");
26 return static_cast<T>((value + ((1ULL << align) - 1)) >> align << align);
27}
28
29template <typename T>
23constexpr bool Is4KBAligned(T value) { 30constexpr bool Is4KBAligned(T value) {
24 static_assert(std::is_unsigned_v<T>, "T must be an unsigned value."); 31 static_assert(std::is_unsigned_v<T>, "T must be an unsigned value.");
25 return (value & 0xFFF) == 0; 32 return (value & 0xFFF) == 0;
@@ -31,4 +38,63 @@ constexpr bool IsWordAligned(T value) {
31 return (value & 0b11) == 0; 38 return (value & 0b11) == 0;
32} 39}
33 40
41template <typename T, std::size_t Align = 16>
42class AlignmentAllocator {
43public:
44 using value_type = T;
45 using size_type = std::size_t;
46 using difference_type = std::ptrdiff_t;
47
48 using pointer = T*;
49 using const_pointer = const T*;
50
51 using reference = T&;
52 using const_reference = const T&;
53
54public:
55 pointer address(reference r) noexcept {
56 return std::addressof(r);
57 }
58
59 const_pointer address(const_reference r) const noexcept {
60 return std::addressof(r);
61 }
62
63 pointer allocate(size_type n) {
64 return static_cast<pointer>(::operator new (n, std::align_val_t{Align}));
65 }
66
67 void deallocate(pointer p, size_type) {
68 ::operator delete (p, std::align_val_t{Align});
69 }
70
71 void construct(pointer p, const value_type& wert) {
72 new (p) value_type(wert);
73 }
74
75 void destroy(pointer p) {
76 p->~value_type();
77 }
78
79 size_type max_size() const noexcept {
80 return size_type(-1) / sizeof(value_type);
81 }
82
83 template <typename T2>
84 struct rebind {
85 using other = AlignmentAllocator<T2, Align>;
86 };
87
88 bool operator!=(const AlignmentAllocator<T, Align>& other) const noexcept {
89 return !(*this == other);
90 }
91
92 // Returns true if and only if storage allocated from *this
93 // can be deallocated from other, and vice versa.
94 // Always returns true for stateless allocators.
95 bool operator==(const AlignmentAllocator<T, Align>& other) const noexcept {
96 return true;
97 }
98};
99
34} // namespace Common 100} // namespace Common