aboutsummaryrefslogtreecommitdiffstats
path: root/common
diff options
context:
space:
mode:
authorChris Robinson <[email protected]>2018-11-18 01:33:26 -0800
committerChris Robinson <[email protected]>2018-11-18 01:33:26 -0800
commit4dc8f44d00c435924e5918fb8e06f926ecc4035b (patch)
tree674fc836e1d344f6a9ef5b15eeb90b9eb4533395 /common
parentd7cc9b912b71b17d6cd1bb9726673b79a4c0173a (diff)
Move the alignment-aware allocator and vector to headers
Diffstat (limited to 'common')
-rw-r--r--common/almalloc.h38
1 files changed, 38 insertions, 0 deletions
diff --git a/common/almalloc.h b/common/almalloc.h
index ad48db8b..ccaa6a98 100644
--- a/common/almalloc.h
+++ b/common/almalloc.h
@@ -3,6 +3,9 @@
#include <stddef.h>
+#include <memory>
+#include <limits>
+
/* Minimum alignment required by posix_memalign. */
#define DEF_ALIGN sizeof(void*)
@@ -28,4 +31,39 @@ int al_is_sane_alignment_allocator(void) noexcept;
} \
void operator delete(void *block) noexcept { al_free(block); }
+namespace al {
+
+template<typename T, size_t alignment=DEF_ALIGN>
+struct allocator : public std::allocator<T> {
+ using size_type = size_t;
+ using pointer = T*;
+ using const_pointer = const T*;
+
+ template<typename U>
+ struct rebind {
+ using other = allocator<U, alignment>;
+ };
+
+ pointer allocate(size_type n, const void* = nullptr)
+ {
+ if(n > std::numeric_limits<size_t>::max() / sizeof(T))
+ throw std::bad_alloc();
+
+ void *ret{al_malloc(alignment, n*sizeof(T))};
+ if(!ret) throw std::bad_alloc();
+ return static_cast<pointer>(ret);
+ }
+
+ void deallocate(pointer p, size_type)
+ { al_free(p); }
+
+ allocator() : std::allocator<T>() { }
+ allocator(const allocator &a) : std::allocator<T>(a) { }
+ template<class U>
+ allocator(const allocator<U,alignment> &a) : std::allocator<T>(a)
+ { }
+};
+
+} // namespace al
+
#endif /* AL_MALLOC_H */