14 template<typename T
> using owner
= T
;
18 #define DISABLE_ALLOC \
19 void *operator new(size_t) = delete; \
20 void *operator new[](size_t) = delete; \
21 void operator delete(void*) noexcept = delete; \
22 void operator delete[](void*) noexcept = delete;
25 enum FamCount
: size_t { };
27 #define DEF_FAM_NEWDEL(T, FamMem) \
28 static constexpr size_t Sizeof(size_t count) noexcept \
30 static_assert(&Sizeof == &T::Sizeof, \
31 "Incorrect container type specified"); \
32 return std::max(decltype(FamMem)::Sizeof(count, offsetof(T, FamMem)), \
36 gsl::owner<void*> operator new(size_t /*size*/, FamCount count) \
38 const auto alignment = std::align_val_t{alignof(T)}; \
39 return ::operator new[](T::Sizeof(count), alignment); \
41 void operator delete(gsl::owner<void*> block, FamCount) noexcept \
42 { ::operator delete[](block, std::align_val_t{alignof(T)}); } \
43 void operator delete(gsl::owner<void*> block) noexcept \
44 { ::operator delete[](block, std::align_val_t{alignof(T)}); } \
45 void *operator new[](size_t /*size*/) = delete; \
46 void operator delete[](void* /*block*/) = delete;
51 template<typename T
, std::size_t AlignV
=alignof(T
)>
53 static constexpr auto Alignment
= std::max(AlignV
, alignof(T
));
54 static constexpr auto AlignVal
= std::align_val_t
{Alignment
};
56 using value_type
= std::remove_cv_t
<std::remove_reference_t
<T
>>;
57 using reference
= value_type
&;
58 using const_reference
= const value_type
&;
59 using pointer
= value_type
*;
60 using const_pointer
= const value_type
*;
61 using size_type
= std::size_t;
62 using difference_type
= std::ptrdiff_t;
63 using is_always_equal
= std::true_type
;
65 template<typename U
, std::enable_if_t
<alignof(U
) <= Alignment
,bool> = true>
67 using other
= allocator
<U
,Alignment
>;
70 constexpr explicit allocator() noexcept
= default;
71 template<typename U
, std::size_t N
>
72 constexpr explicit allocator(const allocator
<U
,N
>&) noexcept
73 { static_assert(Alignment
== allocator
<U
,N
>::Alignment
); }
75 gsl::owner
<T
*> allocate(std::size_t n
)
77 if(n
> std::numeric_limits
<std::size_t>::max()/sizeof(T
)) throw std::bad_alloc();
78 return static_cast<gsl::owner
<T
*>>(::operator new[](n
*sizeof(T
), AlignVal
));
80 void deallocate(gsl::owner
<T
*> p
, std::size_t) noexcept
81 { ::operator delete[](gsl::owner
<void*>{p
}, AlignVal
); }
83 template<typename T
, std::size_t N
, typename U
, std::size_t M
>
84 constexpr bool operator==(const allocator
<T
,N
>&, const allocator
<U
,M
>&) noexcept
85 { return allocator
<T
,N
>::Alignment
== allocator
<U
,M
>::Alignment
; }
86 template<typename T
, std::size_t N
, typename U
, std::size_t M
>
87 constexpr bool operator!=(const allocator
<T
,N
>&, const allocator
<U
,M
>&) noexcept
88 { return allocator
<T
,N
>::Alignment
!= allocator
<U
,M
>::Alignment
; }
91 #ifdef __cpp_lib_to_address
92 using std::to_address
;
95 constexpr T
*to_address(T
*p
) noexcept
97 static_assert(!std::is_function
<T
>::value
, "Can't be a function type");
102 constexpr auto to_address(const T
&p
) noexcept
104 return ::al::to_address(p
.operator->());
108 template<typename T
, typename
...Args
>
109 constexpr T
* construct_at(T
*ptr
, Args
&& ...args
)
110 noexcept(std::is_nothrow_constructible_v
<T
, Args
...>)
112 /* NOLINTBEGIN(cppcoreguidelines-owning-memory) construct_at doesn't
113 * necessarily handle the address from an owner, while placement new
116 return ::new(static_cast<void*>(ptr
)) T
{std::forward
<Args
>(args
)...};
117 /* NOLINTEND(cppcoreguidelines-owning-memory) */
121 template<typename SP
, typename PT
, typename
...Args
>
123 static_assert(!std::is_same_v
<PT
,void*>);
126 std::variant
<PT
,void*> mPtr
{};
129 out_ptr_t(SP
&res
) : mRes
{res
} { }
132 auto set_res
= [this](auto &ptr
)
133 { mRes
.reset(static_cast<PT
>(ptr
)); };
134 std::visit(set_res
, mPtr
);
136 out_ptr_t(const out_ptr_t
&) = delete;
137 out_ptr_t
& operator=(const out_ptr_t
&) = delete;
139 operator PT
*() noexcept
140 { return &std::get
<PT
>(mPtr
); }
142 operator void**() noexcept
143 { return &mPtr
.template emplace
<void*>(); }
146 template<typename T
=void, typename SP
, typename
...Args
>
147 auto out_ptr(SP
&res
)
149 using ptype
= typename
SP::element_type
*;
150 return out_ptr_t
<SP
,ptype
>{res
};
155 #endif /* AL_MALLOC_H */