32 using const_pointer =
const T*;
34 using const_reference =
const T&;
35 using size_type = std::size_t;
36 using difference_type = std::ptrdiff_t;
50 constexpr pointer allocate(size_type n, [[maybe_unused]] std::allocator_traits<
allocator<void>>::const_pointer hint =
nullptr) {
51 static_assert(
sizeof(T) != 0,
"cannot allocate incomplete types");
52 static_assert((
alignof(T) & (
alignof(T) - 1)) == 0,
"alignof(T) must be a power of 2");
54 if (n > max_size()) [[unlikely]] {
55 if (n >
static_cast<size_type
>(-1) /
sizeof(T)) {
56 PLUGIFY_ASSERT(
false,
"plg::allocator::allocate(): bad array new length", std::bad_array_new_length);
58 PLUGIFY_ASSERT(
false,
"plg::allocator::allocate(): too big", std::bad_alloc);
61 pointer ret =
nullptr;
62 if (std::is_constant_evaluated()) {
65 size_type size = n *
sizeof(T);
66 if constexpr (
alignof(T) >
alignof(std::max_align_t)) {
67 size_type aligned_size = (size + (
alignof(T) - 1)) & ~(
alignof(T) - 1);
68 ret =
static_cast<T*
>(aligned_allocate(
alignof(T), aligned_size));
70 ret =
static_cast<T*
>(std::malloc(size));
74 PLUGIFY_ASSERT(
false,
"plg::allocator::allocate(): bad allocation", std::bad_alloc);
82 constexpr void deallocate(pointer p, [[maybe_unused]] size_type n) {
83 if (std::is_constant_evaluated()) {
86 std::free(
static_cast<void*
>(p));
91 constexpr size_type max_size() noexcept {
92#if __PTRDIFF_MAX__ < __SIZE_MAX__
93 return static_cast<size_type
>(__PTRDIFF_MAX__) /
sizeof(T);
95 return static_cast<size_type
>(-1) /
sizeof(T);
99 PLUGIFY_FORCE_INLINE
void* aligned_allocate(size_type alignment, size_type size) {
100#if PLUGIFY_COMPILER_MSVC
101 return _aligned_malloc(size, alignment);
103 return std::aligned_alloc(alignment, size);