diff options
author | Chris Robinson <[email protected]> | 2018-11-18 01:33:26 -0800 |
---|---|---|
committer | Chris Robinson <[email protected]> | 2018-11-18 01:33:26 -0800 |
commit | 4dc8f44d00c435924e5918fb8e06f926ecc4035b (patch) | |
tree | 674fc836e1d344f6a9ef5b15eeb90b9eb4533395 /common | |
parent | d7cc9b912b71b17d6cd1bb9726673b79a4c0173a (diff) |
Move the alignment-aware allocator and vector to headers
Diffstat (limited to 'common')
-rw-r--r-- | common/almalloc.h | 38 |
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 */ |