init
This commit is contained in:
@@ -0,0 +1,336 @@
|
||||
#pragma once
|
||||
#include <cstddef>
|
||||
#include "..\utlmemory\utlmemory.h"
|
||||
|
||||
|
||||
template <class T, class A = CUtlMemory<T>>
|
||||
class CUtlVector
|
||||
{
|
||||
using CAllocator = A;
|
||||
|
||||
public:
|
||||
explicit CUtlVector(const int nGrowSize = 0, const int nInitialCapacity = 0) :
|
||||
memory(nGrowSize, nInitialCapacity), nSize(0), pElements(memory.Base()) { }
|
||||
|
||||
CUtlVector(T* pMemory, const int nInitialCapacity, const int nInitialCount = 0) :
|
||||
memory(pMemory, nInitialCapacity), nSize(nInitialCount), pElements(memory.Base()) { }
|
||||
|
||||
CUtlVector(const CUtlVector&) = delete;
|
||||
|
||||
~CUtlVector()
|
||||
{
|
||||
Purge();
|
||||
}
|
||||
|
||||
CUtlVector& operator=(const CUtlVector& vecOther)
|
||||
{
|
||||
debug(&vecOther != this);
|
||||
|
||||
const int nSourceCount = vecOther.Count();
|
||||
SetCount(nSourceCount);
|
||||
|
||||
for (int i = 0; i < nSourceCount; i++)
|
||||
(*this)[i] = vecOther[i];
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
[[nodiscard]] T& operator[](const int nIndex)
|
||||
{
|
||||
debug(IsValidIndex(nIndex));
|
||||
return memory[nIndex];
|
||||
}
|
||||
|
||||
[[nodiscard]] const T& operator[](const int nIndex) const
|
||||
{
|
||||
debug(IsValidIndex(nIndex));
|
||||
return memory[nIndex];
|
||||
}
|
||||
|
||||
[[nodiscard]] T& Element2(int nIndex) const
|
||||
{
|
||||
debug(IsValidIndex(nIndex));
|
||||
return memory[nIndex];
|
||||
}
|
||||
[[nodiscard]] T& Element(const int nIndex)
|
||||
{
|
||||
debug(IsValidIndex(nIndex));
|
||||
return memory[nIndex];
|
||||
}
|
||||
|
||||
[[nodiscard]] const T& Element(const int nIndex) const
|
||||
{
|
||||
debug(IsValidIndex(nIndex));
|
||||
return memory[nIndex];
|
||||
}
|
||||
|
||||
[[nodiscard]] T* Base()
|
||||
{
|
||||
return memory.Base();
|
||||
}
|
||||
|
||||
[[nodiscard]] const T* Base() const
|
||||
{
|
||||
return memory.Base();
|
||||
}
|
||||
|
||||
[[nodiscard]] int Count() const
|
||||
{
|
||||
return nSize;
|
||||
}
|
||||
|
||||
[[nodiscard]] int& Size()
|
||||
{
|
||||
return nSize;
|
||||
}
|
||||
|
||||
[[nodiscard]] bool IsValidIndex(const int nIndex) const
|
||||
{
|
||||
return (nIndex >= 0) && (nIndex < nSize);
|
||||
}
|
||||
|
||||
void CopyFromArray(const T* pArraySource, int nArraySize)
|
||||
{
|
||||
|
||||
debug(memory.Base() == nullptr || pArraySource == nullptr || begin() >= (pArraySource + nArraySize) || pArraySource >= end());
|
||||
|
||||
|
||||
SetCount(nArraySize);
|
||||
|
||||
for (int i = 0; i < nArraySize; i++)
|
||||
(*this)[i] = pArraySource[i];
|
||||
}
|
||||
|
||||
void GrowVector(const int nCount = 1)
|
||||
{
|
||||
if (nSize + nCount > memory.AllocationCount())
|
||||
memory.Grow(nSize + nCount - memory.AllocationCount());
|
||||
|
||||
nSize += nCount;
|
||||
pElements = memory.Base();
|
||||
}
|
||||
|
||||
void EnsureCapacity(int nCapacity)
|
||||
{
|
||||
memory.EnsureCapacity(nCapacity);
|
||||
pElements = memory.Base();
|
||||
}
|
||||
|
||||
void Purge()
|
||||
{
|
||||
RemoveAll();
|
||||
memory.Purge();
|
||||
pElements = memory.Base();
|
||||
}
|
||||
|
||||
void ShiftElementsRight(const int nElement, const int nShift = 1)
|
||||
{
|
||||
debug(IsValidIndex(nElement) || nSize == 0 || nShift == 0);
|
||||
|
||||
if (const int nToMove = nSize - nElement - nShift; nToMove > 0 && nShift > 0)
|
||||
memmove(&Element(nElement + nShift), &Element(nElement), nToMove * sizeof(T));
|
||||
}
|
||||
|
||||
void ShiftElementsLeft(const int nElement, const int nShift = 1)
|
||||
{
|
||||
debug(IsValidIndex(nElement) || nSize == 0 || nShift == 0);
|
||||
|
||||
if (const int nToMove = nSize - nElement - nShift; nToMove > 0 && nShift > 0)
|
||||
memmove(&Element(nElement), &Element(nElement + nShift), nToMove * sizeof(T));
|
||||
}
|
||||
|
||||
int AddToHead()
|
||||
{
|
||||
return InsertBefore(0);
|
||||
}
|
||||
|
||||
int AddToHead(const T& source)
|
||||
{
|
||||
// can't insert something that's in the list. reallocation may hose us
|
||||
debug(memory.Base() == nullptr || &source < begin() || &source >= end());
|
||||
return InsertBefore(0, source);
|
||||
}
|
||||
|
||||
int AddMultipleToHead(const int nCount)
|
||||
{
|
||||
return InsertMultipleBefore(0, nCount);
|
||||
}
|
||||
|
||||
int AddToTail()
|
||||
{
|
||||
return InsertBefore(nSize);
|
||||
}
|
||||
|
||||
int AddToTail(const T& source)
|
||||
{
|
||||
// can't insert something that's in the list. reallocation may hose us
|
||||
debug(memory.Base() == nullptr || &source < begin() || &source >= end());
|
||||
return InsertBefore(nSize, source);
|
||||
}
|
||||
|
||||
int AddMultipleToTail(const int nCount)
|
||||
{
|
||||
return InsertMultipleBefore(nSize, nCount);
|
||||
}
|
||||
|
||||
void SetCount(const int nCount)
|
||||
{
|
||||
RemoveAll();
|
||||
AddMultipleToTail(nCount);
|
||||
}
|
||||
|
||||
int InsertBefore(const int nElement)
|
||||
{
|
||||
// can insert at the end
|
||||
debug(nElement == nSize || IsValidIndex(nElement));
|
||||
|
||||
GrowVector();
|
||||
ShiftElementsRight(nElement);
|
||||
new (&Element(nElement)) T;
|
||||
return nElement;
|
||||
}
|
||||
|
||||
int InsertMultipleBefore(const int nElement, const int nCount)
|
||||
{
|
||||
if (nCount == 0)
|
||||
return nElement;
|
||||
|
||||
|
||||
debug(nElement == nSize || IsValidIndex(nElement));
|
||||
|
||||
GrowVector(nCount);
|
||||
ShiftElementsRight(nElement, nCount);
|
||||
|
||||
|
||||
for (int i = 0; i < nElement; ++i)
|
||||
new (&Element(nElement + i)) T;
|
||||
|
||||
return nElement;
|
||||
}
|
||||
|
||||
int InsertBefore(const int nElement, const T& source)
|
||||
{
|
||||
|
||||
debug(memory.Base() == nullptr || &source < begin() || &source >= end());
|
||||
|
||||
debug(nElement == nSize || IsValidIndex(nElement));
|
||||
|
||||
GrowVector();
|
||||
ShiftElementsRight(nElement);
|
||||
new (&Element(nElement)) T(source);
|
||||
return nElement;
|
||||
}
|
||||
|
||||
int InsertMultipleBefore(const int nElement, const int nCount, const T* pSource)
|
||||
{
|
||||
if (nCount == 0)
|
||||
return nElement;
|
||||
|
||||
debug(nElement == nSize || IsValidIndex(nElement));
|
||||
|
||||
GrowVector(nCount);
|
||||
ShiftElementsRight(nElement, nCount);
|
||||
|
||||
if (pSource == nullptr)
|
||||
{
|
||||
for (int i = 0; i < nCount; ++i)
|
||||
new (&Element(nElement + i)) T;
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int i = 0; i < nCount; i++)
|
||||
new (&Element(nElement)) T(pSource[i]);
|
||||
}
|
||||
|
||||
return nElement;
|
||||
}
|
||||
|
||||
[[nodiscard]] int Find(const T& source) const
|
||||
{
|
||||
for (int i = 0; i < nSize; ++i)
|
||||
{
|
||||
if (Element(i) == source)
|
||||
return i;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
bool FindAndRemove(const T& source)
|
||||
{
|
||||
if (const int nElement = Find(source); nElement != -1)
|
||||
{
|
||||
Remove(nElement);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void Remove(const int nElement)
|
||||
{
|
||||
(&Element(nElement))->~T();
|
||||
ShiftElementsLeft(nElement);
|
||||
--nSize;
|
||||
}
|
||||
|
||||
void RemoveAll()
|
||||
{
|
||||
for (int i = nSize; --i >= 0;)
|
||||
(&Element(i))->~T();
|
||||
|
||||
nSize = 0;
|
||||
}
|
||||
|
||||
[[nodiscard]] auto begin() noexcept
|
||||
{
|
||||
return memory.Base();
|
||||
}
|
||||
|
||||
[[nodiscard]] auto end() noexcept
|
||||
{
|
||||
return memory.Base() + nSize;
|
||||
}
|
||||
|
||||
[[nodiscard]] auto begin() const noexcept
|
||||
{
|
||||
return memory.Base();
|
||||
}
|
||||
|
||||
[[nodiscard]] auto end() const noexcept
|
||||
{
|
||||
return memory.Base() + nSize;
|
||||
}
|
||||
|
||||
protected:
|
||||
int nSize;
|
||||
CAllocator memory;
|
||||
T* pElements;
|
||||
};
|
||||
|
||||
template <class T>
|
||||
class CUtlVectorAligned : public CUtlVector<T, CUtlMemoryAligned<T, alignof(T)>>
|
||||
{
|
||||
};
|
||||
|
||||
|
||||
template <class T, std::size_t MAX_SIZE>
|
||||
class CUtlVectorFixed : public CUtlVector<T, CUtlMemoryFixed<T, MAX_SIZE>>
|
||||
{
|
||||
using CBaseClass = CUtlVector<T, CUtlMemoryFixed<T, MAX_SIZE>>;
|
||||
|
||||
public:
|
||||
explicit CUtlVectorFixed(int nGrowSize = 0, int nInitialCapacity = 0) :
|
||||
CBaseClass(nGrowSize, nInitialCapacity) { }
|
||||
|
||||
CUtlVectorFixed(T* pMemory, int nElements) :
|
||||
CBaseClass(pMemory, nElements) { }
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
class C_NetworkUtlVectorBase
|
||||
{
|
||||
public:
|
||||
std::uint32_t nSize;
|
||||
T* pElements;
|
||||
};
|
||||
Reference in New Issue
Block a user