9 #ifndef EAGINE_MEMORY_STACK_ALLOC_HPP
10 #define EAGINE_MEMORY_STACK_ALLOC_HPP
12 #include "../assert.hpp"
14 #include <type_traits>
16 namespace eagine::memory {
23 class base_stack_allocator :
public block_owner {
38 using const_pointer = const T*;
40 using const_reference = const T&;
42 using difference_type = std::ptrdiff_t;
44 base_stack_allocator(base_stack_allocator&& tmp) noexcept;
45 base_stack_allocator(const base_stack_allocator&) = delete;
46 auto operator=(base_stack_allocator&& tmp) = delete;
47 auto operator=(const base_stack_allocator&) = delete;
49 base_stack_allocator() noexcept = default;
53 base_stack_allocator(const
block& blk) noexcept;
55 ~base_stack_allocator() noexcept;
57 auto max_size() const noexcept -> size_type {
58 return _available().size();
65 auto allocated_size() const noexcept -> size_type {
66 return _allocated().size();
69 auto contains(
const owned_block& b)
const noexcept -> bool;
70 auto has_allocated(
const owned_block& b)
const noexcept -> tribool;
72 auto allocate(size_type n) noexcept -> owned_block;
74 auto truncate(owned_block&& b, size_type nn) noexcept -> owned_block;
76 void deallocate(owned_block&& b) noexcept;
79 const base_stack_allocator& a,
80 const base_stack_allocator& b) noexcept {
81 if((a._btm == b._btm) && (a._top == b._top)) {
82 EAGINE_ASSERT(a._pos == b._pos);
83 EAGINE_ASSERT(a._min == b._min);
84 EAGINE_ASSERT(a._dif == b._dif);
94 template <
typename Policy = default_
byte_allocator_policy>
95 class stack_byte_allocator_only
96 :
public byte_allocator_impl<Policy, stack_byte_allocator_only> {
98 base_stack_allocator<byte> _alloc;
104 stack_byte_allocator_only(stack_byte_allocator_only&&) noexcept = default;
105 stack_byte_allocator_only(const stack_byte_allocator_only&) = delete;
106 auto operator=(stack_byte_allocator_only&&) = delete;
107 auto operator=(const stack_byte_allocator_only&) = delete;
109 ~stack_byte_allocator_only() noexcept override = default;
111 stack_byte_allocator_only(const
block& blk)
114 auto equal(byte_allocator* a)
const noexcept ->
bool override;
116 auto max_size(size_type) noexcept -> size_type
override {
117 return _alloc.max_size();
121 return _alloc.allocated();
124 auto has_allocated(
const owned_block& b,
span_size_t) noexcept
125 -> tribool
override {
126 return _alloc.has_allocated(b);
129 auto allocate(size_type n, size_type a) noexcept -> owned_block
override;
131 void deallocate(owned_block&& b, size_type) noexcept
override;
136 template <
typename Policy = default_
byte_allocator_policy>
137 class stack_byte_allocator
138 :
public byte_allocator_impl<Policy, stack_byte_allocator> {
140 base_stack_allocator<byte> _alloc;
146 stack_byte_allocator(stack_byte_allocator&&) noexcept = default;
147 stack_byte_allocator(const stack_byte_allocator&) = delete;
148 auto operator=(stack_byte_allocator&&) = delete;
149 auto operator=(const stack_byte_allocator&) = delete;
150 ~stack_byte_allocator() noexcept = default;
152 stack_byte_allocator(const
block& blk)
155 auto equal(byte_allocator* a)
const noexcept ->
bool override;
157 auto max_size(size_type a) noexcept -> size_type
override {
158 return _alloc.max_size() > a ? _alloc.max_size() - a : 0;
161 auto has_allocated(
const owned_block& b,
span_size_t) noexcept
162 -> tribool
override {
163 return _alloc.has_allocated(b);
166 auto allocate(size_type n, size_type a) noexcept -> owned_block
override;
168 void deallocate(owned_block&& b, size_type) noexcept
override;
173 template <
typename Policy = default_
byte_allocator_policy>
174 class stack_aligned_byte_allocator
175 :
public byte_allocator_impl<Policy, stack_aligned_byte_allocator> {
179 base_stack_allocator<byte> _alloc;
180 using _this_class = stack_aligned_byte_allocator;
186 stack_aligned_byte_allocator(_this_class&&) noexcept = default;
187 stack_aligned_byte_allocator(const _this_class&) = delete;
188 auto operator=(stack_aligned_byte_allocator&&) = delete;
189 auto operator=(const stack_aligned_byte_allocator&) = delete;
191 ~stack_aligned_byte_allocator() noexcept = default;
195 , _alloc(blk, _align) {}
197 auto equal(byte_allocator* a)
const noexcept ->
bool override;
199 auto max_size(size_type) noexcept -> size_type
override {
200 return _alloc.max_size();
203 auto has_allocated(
const owned_block& b,
span_size_t) noexcept
206 auto allocate(size_type n, size_type a) noexcept -> owned_block
override;
208 void deallocate(owned_block&& b, size_type a) noexcept
override;
210 auto _own_end_misalign(_this_class* p)
const noexcept ->
span_size_t;
212 auto accomodate_self() noexcept -> byte_allocator*;
214 void eject_self() noexcept override;
219 #include <eagine/memory/stack_alloc.inl>
221 #endif // EAGINE_MEMORY_STACK_ALLOC_HPP