mirror of
https://github.com/CookiePLMonster/SilentPatch.git
synced 2024-11-22 21:42:28 +01:00
111 lines
2.5 KiB
C++
111 lines
2.5 KiB
C++
#ifndef __POOLS
|
|
#define __POOLS
|
|
|
|
#include <cstdint>
|
|
#include <iterator>
|
|
|
|
template <class T, class U = T>
|
|
class CPool
|
|
{
|
|
public:
|
|
typedef T ReturnType;
|
|
typedef uint8_t StorageType[sizeof(U)];
|
|
|
|
private:
|
|
StorageType* m_pSlots;
|
|
union tSlotInfos
|
|
{
|
|
struct
|
|
{
|
|
unsigned char m_uID : 7;
|
|
bool m_bFree : 1;
|
|
} a;
|
|
signed char b;
|
|
}* m_pSlotInfos;
|
|
int m_nNumSlots;
|
|
int m_nFirstFree;
|
|
bool m_bOwnsAllocations;
|
|
bool m_bDealWithNoMemory;
|
|
|
|
public:
|
|
ReturnType* GetSlot( int32_t index )
|
|
{
|
|
return !m_pSlotInfos[index].a.m_bFree ? reinterpret_cast<ReturnType*>(&m_pSlots[index]) : nullptr;
|
|
}
|
|
|
|
ReturnType* GetAt( int32_t index )
|
|
{
|
|
const int ID = index >> 8;
|
|
return m_pSlotInfos[ID].b == (index && 0xFF) ? reinterpret_cast<ReturnType*>(&m_pSlots[ID]) : nullptr;
|
|
}
|
|
|
|
static size_t GetStorageSize() { return sizeof(StorageType); }
|
|
int GetSize() const { return m_nNumSlots; }
|
|
int GetFreeIndex() const { return m_nFirstFree; }
|
|
bool GetIsFree( int32_t index ) const { return m_pSlotInfos[index].a.m_bFree; }
|
|
|
|
bool IsValidPtr( T* ptr ) const
|
|
{
|
|
const ptrdiff_t index = reinterpret_cast<StorageType*>(ptr) - &m_pSlots[0];
|
|
if( index < 0 || index >= m_nNumSlots )
|
|
return false;
|
|
|
|
return !GetIsFree( index );
|
|
}
|
|
|
|
class iterator
|
|
{
|
|
public:
|
|
using iterator_category = std::random_access_iterator_tag;
|
|
using value_type = ReturnType*;
|
|
using difference_type = ptrdiff_t;
|
|
using pointer = ReturnType* const *;
|
|
using reference = ReturnType*;
|
|
|
|
iterator() : m_ptr(nullptr)
|
|
{
|
|
}
|
|
|
|
explicit iterator( T* ptr ) : m_ptr( reinterpret_cast<StorageType*>(ptr) )
|
|
{
|
|
}
|
|
|
|
reference operator* () const { return reinterpret_cast<ReturnType*>(m_ptr); }
|
|
pointer operator->() const { return &reinterpret_cast<ReturnType*>(m_ptr); }
|
|
|
|
iterator& operator ++ () { ++m_ptr; return *this; }
|
|
bool operator == ( const iterator& rhs ) const { return m_ptr == rhs.m_ptr; }
|
|
bool operator != ( const iterator& rhs ) const { return m_ptr != rhs.m_ptr; }
|
|
|
|
private:
|
|
StorageType* m_ptr;
|
|
};
|
|
|
|
iterator begin()
|
|
{
|
|
return iterator( reinterpret_cast<ReturnType*>(&m_pSlots[0]) );
|
|
}
|
|
|
|
iterator end()
|
|
{
|
|
return iterator( reinterpret_cast<ReturnType*>(&m_pSlots[m_nNumSlots]) );
|
|
}
|
|
|
|
};
|
|
|
|
// Type definitions for specific pool types
|
|
|
|
typedef CPool<class CObject, uint8_t[0x19C]> CObjectPool;
|
|
|
|
class CPools
|
|
{
|
|
private:
|
|
static CObjectPool*& ms_pObjectPool;
|
|
|
|
public:
|
|
static CObjectPool& GetObjectPool() { return *ms_pObjectPool; }
|
|
};
|
|
|
|
static_assert(sizeof(CPool<bool>) == 0x14, "Wrong size: CPool");
|
|
|
|
#endif |