summaryrefslogtreecommitdiffstats
path: root/src/common/alignment.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/common/alignment.h')
-rw-r--r--src/common/alignment.h60
1 files changed, 60 insertions, 0 deletions
diff --git a/src/common/alignment.h b/src/common/alignment.h
index 617b14d9b..88d5d3a65 100644
--- a/src/common/alignment.h
+++ b/src/common/alignment.h
@@ -3,6 +3,7 @@
#pragma once
#include <cstddef>
+#include <memory>
#include <type_traits>
namespace Common {
@@ -37,4 +38,63 @@ constexpr bool IsWordAligned(T value) {
return (value & 0b11) == 0;
}
+template <typename T, std::size_t Align = 16>
+class AlignmentAllocator {
+public:
+ using value_type = T;
+ using size_type = std::size_t;
+ using difference_type = std::ptrdiff_t;
+
+ using pointer = T*;
+ using const_pointer = const T*;
+
+ using reference = T&;
+ using const_reference = const T&;
+
+public:
+ pointer address(reference r) noexcept {
+ return std::addressof(r);
+ }
+
+ const_pointer address(const_reference r) const noexcept {
+ return std::addressof(r);
+ }
+
+ pointer allocate(size_type n) {
+ return static_cast<pointer>(::operator new (n, std::align_val_t{Align}));
+ }
+
+ void deallocate(pointer p, size_type) {
+ ::operator delete (p, std::align_val_t{Align});
+ }
+
+ void construct(pointer p, const value_type& wert) {
+ new (p) value_type(wert);
+ }
+
+ void destroy(pointer p) {
+ p->~value_type();
+ }
+
+ size_type max_size() const noexcept {
+ return size_type(-1) / sizeof(value_type);
+ }
+
+ template <typename T2>
+ struct rebind {
+ using other = AlignmentAllocator<T2, Align>;
+ };
+
+ bool operator!=(const AlignmentAllocator<T, Align>& other) const noexcept {
+ return !(*this == other);
+ }
+
+ // Returns true if and only if storage allocated from *this
+ // can be deallocated from other, and vice versa.
+ // Always returns true for stateless allocators.
+ bool operator==(const AlignmentAllocator<T, Align>& other) const noexcept {
+ return true;
+ }
+};
+
} // namespace Common