#ifndef __POOLS #define __POOLS #include #include template 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(&m_pSlots[index]) : nullptr; } ReturnType* GetAt( int32_t index ) { const int ID = index >> 8; return m_pSlotInfos[ID].b == (index && 0xFF) ? reinterpret_cast(&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(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(ptr) ) { } reference operator* () const { return reinterpret_cast(m_ptr); } pointer operator->() const { return &reinterpret_cast(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(&m_pSlots[0]) ); } iterator end() { return iterator( reinterpret_cast(&m_pSlots[m_nNumSlots]) ); } }; // Type definitions for specific pool types typedef CPool CObjectPool; class CPools { private: static CObjectPool*& ms_pObjectPool; public: static CObjectPool& GetObjectPool() { return *ms_pObjectPool; } }; static_assert(sizeof(CPool) == 0x14, "Wrong size: CPool"); #endif