diff options
-rw-r--r-- | common/almalloc.h | 78 |
1 files changed, 73 insertions, 5 deletions
diff --git a/common/almalloc.h b/common/almalloc.h index 0d77c46d..74aa4afe 100644 --- a/common/almalloc.h +++ b/common/almalloc.h @@ -39,6 +39,8 @@ int al_is_sane_alignment_allocator(void) noexcept; namespace al { +#define REQUIRES(...) typename std::enable_if<(__VA_ARGS__),int>::type = 0 + template<typename T, size_t alignment=alignof(T)> struct allocator : public std::allocator<T> { using size_type = size_t; @@ -85,6 +87,73 @@ inline T* assume_aligned(T *ptr) noexcept #endif } +template<typename T> +inline void destroy_at(T *ptr) { ptr->~T(); } + +template<typename T> +inline void destroy(T first, const T end) +{ + while(first != end) + { + destroy_at(std::addressof(*first)); + ++first; + } +} + +template<typename T, typename N, REQUIRES(std::is_integral<N>::value)> +inline T destroy_n(T first, N count) +{ + if(count != 0) + { + do { + destroy_at(std::addressof(*first)); + ++first; + } while(--count); + } + return first; +} + + +template<typename T> +inline void uninitialized_default_construct(T first, const T last) +{ + using ValueT = typename std::iterator_traits<T>::value_type; + T current{first}; + try { + while(current != last) + { + ::new (static_cast<void*>(std::addressof(*current))) ValueT; + ++current; + } + } + catch(...) { + destroy(first, current); + throw; + } +} + +template<typename T, typename N, REQUIRES(std::is_integral<N>::value)> +inline T uninitialized_default_construct_n(T first, N count) +{ + using ValueT = typename std::iterator_traits<T>::value_type; + T current{first}; + if(count != 0) + { + try { + do { + ::new (static_cast<void*>(std::addressof(*current))) ValueT; + ++current; + } while(--count); + } + catch(...) { + destroy(first, current); + throw; + } + } + return current; +} + + /* std::make_unique was added with C++14, so until we rely on that, make our * own version. */ @@ -109,12 +178,9 @@ struct FlexArray { } FlexArray(size_t size) : mSize{size} - { new (mArray) T[mSize]; } + { uninitialized_default_construct_n(mArray, mSize); } ~FlexArray() - { - for(size_t i{0u};i < mSize;++i) - mArray[i].~T(); - } + { destroy_n(mArray, mSize); } FlexArray(const FlexArray&) = delete; FlexArray& operator=(const FlexArray&) = delete; @@ -143,6 +209,8 @@ struct FlexArray { DEF_PLACE_NEWDEL() }; +#undef REQUIRES + } // namespace al #endif /* AL_MALLOC_H */ |