aboutsummaryrefslogtreecommitdiffstats
path: root/common/almalloc.h
diff options
context:
space:
mode:
Diffstat (limited to 'common/almalloc.h')
-rw-r--r--common/almalloc.h37
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>