#pragma once #include #include #include #include #include /// Base class for hkArray (a std::vector-like container). // FIXME: incomplete template class hkArrayBase { public: HK_DECLARE_CLASS_ALLOCATOR(hkArrayBase) enum : unsigned int { CAPACITY_MASK = 0x3FFFFFFF, FLAG_MASK = 0xC0000000, DONT_DEALLOCATE_FLAG = 0x80000000, }; HK_FORCE_INLINE hkArrayBase(); // NOLINTNEXTLINE(cppcoreguidelines-pro-type-member-init) explicit hkArrayBase(hkFinishLoadedObjectFlag f) {} HK_FORCE_INLINE ~hkArrayBase(); hkArrayBase(const hkArrayBase&) = delete; auto operator=(const hkArrayBase&) = delete; HK_FORCE_INLINE int getSize() const; HK_FORCE_INLINE int getCapacity() const; HK_FORCE_INLINE int getCapacityAndFlags() const; HK_FORCE_INLINE hkBool isEmpty() const; HK_FORCE_INLINE void clear(); HK_FORCE_INLINE void _clearAndDeallocate(hkMemoryAllocator& allocator); protected: T* m_data; int m_size; int m_capacityAndFlags; }; /// A dynamically resizable array, similar to std::vector. // FIXME: incomplete template class hkArray : public hkArrayBase { public: using AllocatorType = Allocator; HK_FORCE_INLINE hkArray() = default; explicit hkArray(hkFinishLoadedObjectFlag f) : hkArrayBase(f) {} HK_FORCE_INLINE ~hkArray() { clearAndDeallocate(); } HK_FORCE_INLINE hkArray& operator=(const hkArrayBase& other); HK_FORCE_INLINE hkArray& operator=(const hkArray& other); HK_FORCE_INLINE void clearAndDeallocate(); protected: HK_FORCE_INLINE hkArray(const hkArray& other); }; template inline hkArrayBase::hkArrayBase() : m_data(nullptr), m_size(0), m_capacityAndFlags(DONT_DEALLOCATE_FLAG) {} template inline hkArrayBase::~hkArrayBase() { // Assert non-POD element destruction } template inline int hkArrayBase::getSize() const { return m_size; } template inline int hkArrayBase::getCapacity() const { return m_capacityAndFlags & static_cast(CAPACITY_MASK); } template inline int hkArrayBase::getCapacityAndFlags() const { return m_capacityAndFlags; } template inline hkBool hkArrayBase::isEmpty() const { return m_size == 0; } template inline void hkArrayBase::clear() { hkArrayUtil::destruct(m_data, m_size); m_size = 0; } template inline void hkArrayBase::_clearAndDeallocate(hkMemoryAllocator& allocator) { clear(); if ((m_capacityAndFlags & DONT_DEALLOCATE_FLAG) == 0) { const int SIZE_ELEM = hkSizeOfTypeOrVoid::val; int numBytes = getCapacity() * SIZE_ELEM; void* storage = const_cast*>(m_data); allocator.bufFree(storage, numBytes); } m_data = nullptr; m_capacityAndFlags = DONT_DEALLOCATE_FLAG; } template inline void hkArray::clearAndDeallocate() { this->_clearAndDeallocate(AllocatorType().get()); }