19#include "pw_allocator/block/poisonable.h"
20#include "pw_allocator/config.h"
21#include "pw_allocator/hardening.h"
22#include "pw_allocator/layout.h"
23#include "pw_assert/assert.h"
24#include "pw_bytes/alignment.h"
26namespace pw::allocator::internal {
54template <
typename Derived,
typename BlockType_,
typename ItemType_>
57 using BlockType = BlockType_;
58 using ItemType = ItemType_;
61 if constexpr (is_poisonable_v<BlockType>) {
62 static_assert(BlockType::kPoisonOffset >=
sizeof(ItemType),
63 "Block type does not reserve sufficient space for an item");
68 constexpr bool empty()
const {
return derived()->items_.empty(); }
85 [[nodiscard]]
bool Add(BlockType& block) {
86 if (block.InnerSize() <
sizeof(ItemType)) {
89 if constexpr (Hardening::kIncludesDebugChecks) {
90 PW_ASSERT(block.InnerSize() <= max_inner_size_);
91 PW_ASSERT(IsAlignedAs<ItemType>(block.UsableSpace()));
93 derived()->DoAdd(block);
101 return empty() ? nullptr : derived()->DoRemoveAny();
108 [[nodiscard]]
bool Remove(BlockType& block) {
109 return block.InnerSize() >=
sizeof(ItemType) && derived()->DoRemove(block);
120 return derived()->DoRemoveCompatible(layout);
124 void Clear() { derived()->items_.clear(); }
137 template <
typename Iterator,
typename Predicate>
140 Predicate predicate) {
141 Iterator prev = before_first;
142 Iterator iter = prev;
144 for (; iter != last; ++iter) {
145 if (predicate(*iter)) {
158 return [layout](ItemType& item) {
159 auto* block = BlockType::FromUsableSpace(&item);
160 return block->CanAlloc(layout).ok();
166 template <
typename Iterator>
168 return iter != last ? BlockType::FromUsableSpace(&(*iter)) :
nullptr;
173 template <
typename Iterator>
186 return *(std::launder(
reinterpret_cast<ItemType*
>(block.UsableSpace())));
190 constexpr Derived* derived() {
return static_cast<Derived*
>(
this); }
191 constexpr const Derived* derived()
const {
192 return static_cast<const Derived*
>(
this);
196 size_t max_inner_size_ = std::numeric_limits<size_t>::max();
constexpr void set_max_inner_size(size_t max_inner_size)
Definition: base.h:76
constexpr BlockType * GetBlockFromIterator(Iterator iter, Iterator last)
Definition: base.h:167
bool Remove(BlockType &block)
Definition: base.h:108
constexpr size_t max_inner_size() const
Returns the configured maximum inner size for blocks in this bucket.
Definition: base.h:71
BlockType * RemoveAny()
Definition: base.h:100
static auto MakeCanAllocPredicate(Layout layout)
Definition: base.h:157
constexpr BlockType * GetBlockFromPrev(Iterator prev, Iterator last)
Definition: base.h:174
void Clear()
Removes all blocks from this bucket.
Definition: base.h:124
static ItemType & GetItemFrom(BlockType &block)
Definition: base.h:185
bool Add(BlockType &block)
Definition: base.h:85
static Iterator FindPrevIf(Iterator before_first, Iterator last, Predicate predicate)
Definition: base.h:138
constexpr bool empty() const
Returns whether this buckets contains any free blocks.
Definition: base.h:68
BlockType * RemoveCompatible(Layout layout)
Definition: base.h:119