2template <
typename T, plUInt32 BlockSize, plBlockStorageType::Enum StorageType>
7 m_uiCurrentIndex = uiStartIndex;
8 m_uiEndIndex =
plMath::Max(uiStartIndex + uiCount, uiCount);
10 if (StorageType == plBlockStorageType::FreeList)
12 plUInt32 uiEndIndex =
plMath::Min(m_uiEndIndex, m_Storage.m_uiCount);
13 while (m_uiCurrentIndex < uiEndIndex && !m_Storage.m_UsedEntries.IsBitSet(m_uiCurrentIndex))
20template <
typename T, plUInt32 BlockSize, plBlockStorageType::Enum StorageType>
25 return m_Storage.m_Blocks[uiBlockIndex][uiInnerIndex];
28template <
typename T, plUInt32 BlockSize, plBlockStorageType::Enum StorageType>
31 return CurrentElement();
34template <
typename T, plUInt32 BlockSize, plBlockStorageType::Enum StorageType>
37 return &CurrentElement();
40template <
typename T, plUInt32 BlockSize, plBlockStorageType::Enum StorageType>
43 return &CurrentElement();
46template <
typename T, plUInt32 BlockSize, plBlockStorageType::Enum StorageType>
51 if (StorageType == plBlockStorageType::FreeList)
53 plUInt32 uiEndIndex =
plMath::Min(m_uiEndIndex, m_Storage.m_uiCount);
54 while (m_uiCurrentIndex < uiEndIndex && !m_Storage.m_UsedEntries.IsBitSet(m_uiCurrentIndex))
61template <
typename T, plUInt32 BlockSize, plBlockStorageType::Enum StorageType>
64 return m_uiCurrentIndex <
plMath::Min(m_uiEndIndex, m_Storage.m_uiCount);
67template <
typename T, plUInt32 BlockSize, plBlockStorageType::Enum StorageType>
75template <
typename T, plUInt32 BlockSize, plBlockStorageType::Enum StorageType>
78 : ConstIterator(storage, uiStartIndex, uiCount)
82template <
typename T, plUInt32 BlockSize, plBlockStorageType::Enum StorageType>
85 return this->CurrentElement();
88template <
typename T, plUInt32 BlockSize, plBlockStorageType::Enum StorageType>
91 return &(this->CurrentElement());
94template <
typename T, plUInt32 BlockSize, plBlockStorageType::Enum StorageType>
97 return &(this->CurrentElement());
102template <
typename T, plUInt32 BlockSize, plBlockStorageType::Enum StorageType>
105 : m_pBlockAllocator(pBlockAllocator)
106 , m_Blocks(pAllocator)
111template <
typename T, plUInt32 BlockSize, plBlockStorageType::Enum StorageType>
117template <
typename T, plUInt32 BlockSize, plBlockStorageType::Enum StorageType>
120 for (plUInt32 uiBlockIndex = 0; uiBlockIndex < m_Blocks.GetCount(); ++uiBlockIndex)
124 if (StorageType == plBlockStorageType::Compact)
130 for (plUInt32 uiInnerIndex = 0; uiInnerIndex < block.m_uiCount; ++uiInnerIndex)
133 if (m_UsedEntries.IsBitSet(uiIndex))
140 m_pBlockAllocator->DeallocateBlock(block);
146template <
typename T, plUInt32 BlockSize, plBlockStorageType::Enum StorageType>
149 T* pNewObject =
nullptr;
150 plUInt32 uiNewIndex = plInvalidIndex;
152 if (StorageType == plBlockStorageType::FreeList && m_uiFreelistStart != plInvalidIndex)
154 uiNewIndex = m_uiFreelistStart;
159 pNewObject = &(m_Blocks[uiBlockIndex][uiInnerIndex]);
161 m_uiFreelistStart = *
reinterpret_cast<plUInt32*
>(pNewObject);
167 if (m_Blocks.GetCount() > 0)
169 pBlock = &m_Blocks.PeekBack();
172 if (pBlock ==
nullptr || pBlock->IsFull())
174 m_Blocks.PushBack(m_pBlockAllocator->template AllocateBlock<T>());
175 pBlock = &m_Blocks.PeekBack();
178 pNewObject = pBlock->ReserveBack();
179 uiNewIndex = m_uiCount;
186 if (StorageType == plBlockStorageType::FreeList)
188 m_UsedEntries.SetCount(m_uiCount);
189 m_UsedEntries.SetBit(uiNewIndex);
195template <
typename T, plUInt32 BlockSize, plBlockStorageType::Enum StorageType>
199 Delete(pObject, pDummy);
202template <
typename T, plUInt32 BlockSize, plBlockStorageType::Enum StorageType>
208template <
typename T, plUInt32 BlockSize, plBlockStorageType::Enum StorageType>
214template <
typename T, plUInt32 BlockSize, plBlockStorageType::Enum StorageType>
216 plUInt32 uiStartIndex , plUInt32 uiCount )
218 return Iterator(*
this, uiStartIndex, uiCount);
221template <
typename T, plUInt32 BlockSize, plBlockStorageType::Enum StorageType>
223 plUInt32 uiStartIndex , plUInt32 uiCount )
const
225 return ConstIterator(*
this, uiStartIndex, uiCount);
228template <
typename T, plUInt32 BlockSize, plBlockStorageType::Enum StorageType>
232 T* pLast = lastBlock.PopBack();
235 if (pObject != pLast)
244 out_pMovedObject = pLast;
246 if (lastBlock.IsEmpty())
248 m_pBlockAllocator->DeallocateBlock(lastBlock);
253template <
typename T, plUInt32 BlockSize, plBlockStorageType::Enum StorageType>
256 plUInt32 uiIndex = plInvalidIndex;
257 for (plUInt32 uiBlockIndex = 0; uiBlockIndex < m_Blocks.GetCount(); ++uiBlockIndex)
259 std::ptrdiff_t diff = pObject - m_Blocks[uiBlockIndex].m_pData;
267 PL_ASSERT_DEV(uiIndex != plInvalidIndex,
"Invalid object {0} was not found in block storage.",
plArgP(pObject));
269 m_UsedEntries.ClearBit(uiIndex);
271 out_pMovedObject = pObject;
274 *
reinterpret_cast<plUInt32*
>(pObject) = m_uiFreelistStart;
275 m_uiFreelistStart = uiIndex;
Base class for all memory allocators.
Definition Allocator.h:23
Definition BlockStorage.h:20
Definition BlockStorage.h:45
Definition BlockStorage.h:17
A block allocator which can only allocates blocks of memory at once.
Definition LargeBlockAllocator.h:40
static void Construct(T *pDestination, size_t uiCount=1)
Constructs uiCount objects of type T in a raw buffer at pDestination.
static void Relocate(T *pDestination, T *pSource, size_t uiCount=1)
Moves objects of type T from pSource to pDestination.
static void Destruct(T *pDestination, size_t uiCount=1)
Destructs uiCount objects of type T at pDestination.
constexpr PL_ALWAYS_INLINE T Min(T f1, T f2)
Returns the smaller value, f1 or f2.
Definition Math_inl.h:27
constexpr PL_ALWAYS_INLINE T Max(T f1, T f2)
Returns the greater value, f1 or f2.
Definition Math_inl.h:39
Definition FormatStringArgs.h:76
This struct represents a block of type T, typically 4kb.
Definition LargeBlockAllocator.h:14
Type traits.
Definition TypeTraits.h:12