diff options
Diffstat (limited to 'common/almalloc.h')
-rw-r--r-- | common/almalloc.h | 37 |
1 files changed, 17 insertions, 20 deletions
diff --git a/common/almalloc.h b/common/almalloc.h index ac4ddfc2..b64b6b20 100644 --- a/common/almalloc.h +++ b/common/almalloc.h @@ -51,29 +51,23 @@ enum FamCount : size_t { }; \ gsl::owner<void*> operator new(size_t /*size*/, FamCount count) \ { \ - const auto align = std::align_val_t(alignof(T)); \ - return ::new(align) std::byte[T::Sizeof(count)]; \ + const auto alignment = std::align_val_t{alignof(T)}; \ + return ::operator new[](T::Sizeof(count), alignment); \ } \ - void *operator new[](size_t /*size*/) = delete; \ void operator delete(gsl::owner<void*> block, FamCount) noexcept \ - { \ - const auto align = std::align_val_t(alignof(T)); \ - ::operator delete[](static_cast<gsl::owner<std::byte*>>(block), align); \ - } \ + { ::operator delete[](block, std::align_val_t{alignof(T)}); } \ void operator delete(gsl::owner<void*> block) noexcept \ - { \ - const auto align = std::align_val_t(alignof(T)); \ - ::operator delete[](static_cast<gsl::owner<std::byte*>>(block), align); \ - } \ + { ::operator delete[](block, std::align_val_t{alignof(T)}); } \ + void *operator new[](size_t /*size*/) = delete; \ void operator delete[](void* /*block*/) = delete; namespace al { -template<typename T, std::size_t Align=alignof(T)> +template<typename T, std::size_t AlignV=alignof(T)> struct allocator { - static constexpr auto alignment = std::max(Align, alignof(T)); - static constexpr auto AlignVal = std::align_val_t(alignment); + static constexpr auto Alignment = std::max(AlignV, alignof(T)); + static constexpr auto AlignVal = std::align_val_t{Alignment}; using value_type = T; using reference = T&; @@ -86,25 +80,28 @@ struct allocator { template<typename U> struct rebind { - using other = allocator<U, Align>; + using other = std::enable_if_t<alignof(U) <= Alignment, allocator<U,Alignment>>; }; constexpr explicit allocator() noexcept = default; template<typename U, std::size_t N> - constexpr explicit allocator(const allocator<U,N>&) noexcept { } + constexpr explicit allocator(const allocator<U,N>&) noexcept + { static_assert(Alignment == allocator<U,N>::Alignment); } gsl::owner<T*> allocate(std::size_t n) { if(n > std::numeric_limits<std::size_t>::max()/sizeof(T)) throw std::bad_alloc(); - return reinterpret_cast<gsl::owner<T*>>(::new(AlignVal) std::byte[n*sizeof(T)]); + return static_cast<gsl::owner<T*>>(::operator new[](n*sizeof(T), AlignVal)); } void deallocate(gsl::owner<T*> p, std::size_t) noexcept - { ::operator delete[](reinterpret_cast<gsl::owner<std::byte*>>(p), AlignVal); } + { ::operator delete[](gsl::owner<void*>{p}, AlignVal); } }; template<typename T, std::size_t N, typename U, std::size_t M> -constexpr bool operator==(const allocator<T,N>&, const allocator<U,M>&) noexcept { return true; } +constexpr bool operator==(const allocator<T,N>&, const allocator<U,M>&) noexcept +{ return allocator<T,N>::Alignment == allocator<U,M>::Alignment; } template<typename T, std::size_t N, typename U, std::size_t M> -constexpr bool operator!=(const allocator<T,N>&, const allocator<U,M>&) noexcept { return false; } +constexpr bool operator!=(const allocator<T,N>&, const allocator<U,M>&) noexcept +{ return allocator<T,N>::Alignment != allocator<U,M>::Alignment; } template<typename T> |