SilentPatch/SilentPatchSA/PoolsSA.h
2017-12-22 00:13:16 +01:00

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