fixed review on stableVector.
This commit is contained in:
@@ -56,6 +56,7 @@ namespace OpenVulkano
|
|||||||
{
|
{
|
||||||
if (m_occupiedIndices[i])
|
if (m_occupiedIndices[i])
|
||||||
{
|
{
|
||||||
|
m_occupiedIndices[i] = false;
|
||||||
m_data[i].~T();
|
m_data[i].~T();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -65,7 +66,7 @@ namespace OpenVulkano
|
|||||||
|
|
||||||
size_t GetRealIndex(size_t reqIndex)
|
size_t GetRealIndex(size_t reqIndex)
|
||||||
{
|
{
|
||||||
if (m_gapCount == 0 || reqIndex == 0)
|
if (m_gapCount == 0)
|
||||||
{
|
{
|
||||||
return reqIndex;
|
return reqIndex;
|
||||||
}
|
}
|
||||||
@@ -79,27 +80,7 @@ namespace OpenVulkano
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return reqIndex + gapCount;
|
for (size_t i = reqIndex + gapCount; i < m_capacity; i++)
|
||||||
}
|
|
||||||
|
|
||||||
T& GetAlignedData(size_t index)
|
|
||||||
{
|
|
||||||
size_t realIndex = GetRealIndex(index);
|
|
||||||
|
|
||||||
for (size_t i = realIndex; i < m_capacity; i++)
|
|
||||||
{
|
|
||||||
if (m_occupiedIndices[i])
|
|
||||||
{
|
|
||||||
return m_data[i];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
throw std::out_of_range("Index out of range");
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t GetLastOccupiedIndex()
|
|
||||||
{
|
|
||||||
for (size_t i = m_capacity - 1; i >= 0; i--)
|
|
||||||
{
|
{
|
||||||
if (m_occupiedIndices[i])
|
if (m_occupiedIndices[i])
|
||||||
{
|
{
|
||||||
@@ -107,20 +88,22 @@ namespace OpenVulkano
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return reqIndex + gapCount;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
public:
|
public:
|
||||||
class Iterator
|
class Iterator
|
||||||
{
|
{
|
||||||
|
friend class StableVector<T>;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Iterator(VectorChunk* chunk, size_t index) : m_chunk(chunk), m_index(index) {}
|
Iterator(VectorChunk* chunk, size_t index) : m_chunk(chunk), m_index(index) {}
|
||||||
|
|
||||||
T& operator*()
|
T& operator*()
|
||||||
{
|
{
|
||||||
auto realIndex = m_chunk->GetRealIndex(m_index);
|
auto realIndex = m_chunk->GetRealIndex(m_index);
|
||||||
return m_chunk->GetAlignedData(realIndex);
|
return m_chunk->m_data[realIndex];
|
||||||
}
|
}
|
||||||
|
|
||||||
T* operator->() { return &operator*(); }
|
T* operator->() { return &operator*(); }
|
||||||
@@ -176,10 +159,7 @@ namespace OpenVulkano
|
|||||||
|
|
||||||
bool operator!=(const Iterator& other) const { return !(*this == other); }
|
bool operator!=(const Iterator& other) const { return !(*this == other); }
|
||||||
|
|
||||||
std::streamsize GetIndex() const { return m_chunk->GetRealIndex(m_index); }
|
private:
|
||||||
VectorChunk* GetChunk() const { return m_chunk; }
|
|
||||||
|
|
||||||
protected:
|
|
||||||
void MoveToNextChunk()
|
void MoveToNextChunk()
|
||||||
{
|
{
|
||||||
while (m_chunk && m_index >= m_chunk->m_size)
|
while (m_chunk && m_index >= m_chunk->m_size)
|
||||||
@@ -198,20 +178,16 @@ namespace OpenVulkano
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::streamsize GetIteratorIndex() const { return m_chunk->GetRealIndex(m_index); }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
VectorChunk* m_chunk;
|
VectorChunk* m_chunk;
|
||||||
std::streamsize m_index;
|
std::streamsize m_index;
|
||||||
};
|
};
|
||||||
|
|
||||||
public:
|
public:
|
||||||
StableVector() : m_firstChunk(nullptr), m_lastChunk(nullptr), m_size(0), m_capacity(0)
|
StableVector(size_t size = DEFAULT_CHUNK_SIZE)
|
||||||
{
|
: m_firstChunk(nullptr), m_lastChunk(nullptr), m_size(0), m_capacity(0)
|
||||||
m_firstChunk = Grow(DEFAULT_CHUNK_SIZE);
|
|
||||||
m_lastChunk = m_firstChunk;
|
|
||||||
m_capacity = DEFAULT_CHUNK_SIZE;
|
|
||||||
}
|
|
||||||
|
|
||||||
StableVector(size_t size) : m_firstChunk(nullptr), m_lastChunk(nullptr), m_size(0), m_capacity(0)
|
|
||||||
{
|
{
|
||||||
m_firstChunk = Grow(size);
|
m_firstChunk = Grow(size);
|
||||||
m_lastChunk = m_firstChunk;
|
m_lastChunk = m_firstChunk;
|
||||||
@@ -219,12 +195,8 @@ namespace OpenVulkano
|
|||||||
}
|
}
|
||||||
|
|
||||||
StableVector(size_t size, const T& value)
|
StableVector(size_t size, const T& value)
|
||||||
: m_firstChunk(nullptr), m_lastChunk(nullptr), m_size(0), m_capacity(0)
|
: StableVector(size), m_firstChunk(nullptr), m_lastChunk(nullptr), m_size(0), m_capacity(0)
|
||||||
{
|
{
|
||||||
m_firstChunk = Grow(size);
|
|
||||||
m_lastChunk = m_firstChunk;
|
|
||||||
m_capacity = size;
|
|
||||||
|
|
||||||
for (size_t i = 0; i < size; i++)
|
for (size_t i = 0; i < size; i++)
|
||||||
{
|
{
|
||||||
PushBack(value);
|
PushBack(value);
|
||||||
@@ -232,12 +204,8 @@ namespace OpenVulkano
|
|||||||
}
|
}
|
||||||
|
|
||||||
StableVector(std::initializer_list<T> list)
|
StableVector(std::initializer_list<T> list)
|
||||||
: m_firstChunk(nullptr), m_lastChunk(nullptr), m_size(0), m_capacity(0)
|
: StableVector(list.size), m_firstChunk(nullptr), m_lastChunk(nullptr), m_size(0), m_capacity(0)
|
||||||
{
|
{
|
||||||
m_firstChunk = Grow(list.size());
|
|
||||||
m_lastChunk = m_firstChunk;
|
|
||||||
m_capacity = list.size();
|
|
||||||
|
|
||||||
for (const T& value: list)
|
for (const T& value: list)
|
||||||
{
|
{
|
||||||
PushBack(value);
|
PushBack(value);
|
||||||
@@ -245,12 +213,8 @@ namespace OpenVulkano
|
|||||||
}
|
}
|
||||||
|
|
||||||
StableVector(const StableVector<T>& copy)
|
StableVector(const StableVector<T>& copy)
|
||||||
: m_firstChunk(nullptr), m_lastChunk(nullptr), m_size(0), m_capacity(0)
|
: StableVector(copy.m_size), m_firstChunk(nullptr), m_lastChunk(nullptr), m_size(0), m_capacity(0)
|
||||||
{
|
{
|
||||||
m_firstChunk = Grow(copy.m_capacity); // One big chunk to make Stable contiguous.
|
|
||||||
m_lastChunk = m_firstChunk;
|
|
||||||
m_capacity = copy.m_capacity;
|
|
||||||
|
|
||||||
for (size_t i = 0; i < copy.Size(); i++)
|
for (size_t i = 0; i < copy.Size(); i++)
|
||||||
{
|
{
|
||||||
PushBack(copy.At(i));
|
PushBack(copy.At(i));
|
||||||
@@ -273,12 +237,14 @@ namespace OpenVulkano
|
|||||||
|
|
||||||
~StableVector()
|
~StableVector()
|
||||||
{
|
{
|
||||||
|
// Destroy everything left
|
||||||
VectorChunk* currentChunk = m_firstChunk;
|
VectorChunk* currentChunk = m_firstChunk;
|
||||||
while (currentChunk)
|
while (currentChunk)
|
||||||
{
|
{
|
||||||
VectorChunk* temp = currentChunk;
|
VectorChunk* temp = currentChunk;
|
||||||
currentChunk = currentChunk->m_next;
|
currentChunk = currentChunk->m_next;
|
||||||
delete temp;
|
temp->~VectorChunk();
|
||||||
|
::operator delete(temp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -312,8 +278,8 @@ namespace OpenVulkano
|
|||||||
|
|
||||||
m_lastChunk->m_data[m_lastChunk->m_nextIndex - 1].~T();
|
m_lastChunk->m_data[m_lastChunk->m_nextIndex - 1].~T();
|
||||||
m_lastChunk->m_occupiedIndices[m_lastChunk->m_nextIndex - 1] = false;
|
m_lastChunk->m_occupiedIndices[m_lastChunk->m_nextIndex - 1] = false;
|
||||||
m_lastChunk->m_nextIndex--;
|
|
||||||
m_lastChunk->m_size--;
|
m_lastChunk->m_size--;
|
||||||
|
m_lastChunk->m_gapCount++;
|
||||||
m_size--;
|
m_size--;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -324,7 +290,7 @@ namespace OpenVulkano
|
|||||||
throw std::out_of_range("Index out of range");
|
throw std::out_of_range("Index out of range");
|
||||||
}
|
}
|
||||||
|
|
||||||
return m_lastChunk->m_data[m_lastChunk->GetLastOccupiedIndex()];
|
return m_lastChunk->m_data[m_lastChunk->m_nextIndex - 1];
|
||||||
}
|
}
|
||||||
|
|
||||||
constexpr T& Front() const
|
constexpr T& Front() const
|
||||||
@@ -351,26 +317,24 @@ namespace OpenVulkano
|
|||||||
throw std::out_of_range("Index out of range");
|
throw std::out_of_range("Index out of range");
|
||||||
}
|
}
|
||||||
|
|
||||||
handle.first->m_data[realIndex].~T();
|
Delete(realIndex, handle.first);
|
||||||
handle.first->m_occupiedIndices[realIndex] = false;
|
|
||||||
handle.first->m_size--;
|
|
||||||
handle.first->m_gapCount++;
|
|
||||||
m_size--;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Remove(const Iterator& it)
|
void Remove(const Iterator& it)
|
||||||
{
|
{
|
||||||
it.GetChunk()->m_data[it.GetIndex()].~T();
|
if (it.m_chunk == nullptr)
|
||||||
it.GetChunk()->m_occupiedIndices[it.GetIndex()] = false;
|
{
|
||||||
it.GetChunk()->m_size--;
|
throw std::out_of_range("Index out of range");
|
||||||
it.GetChunk()->m_gapCount++;
|
}
|
||||||
m_size--;
|
|
||||||
|
Delete(it.GetIteratorIndex(), it.m_chunk);
|
||||||
}
|
}
|
||||||
|
|
||||||
T& operator[](size_t index) noexcept
|
T& operator[](size_t index) noexcept
|
||||||
{
|
{
|
||||||
auto handle = FindChunk(index);
|
auto handle = FindChunk(index);
|
||||||
return handle.first->GetAlignedData(handle.second);
|
size_t realIndex = handle.first->GetRealIndex(handle.second);
|
||||||
|
return handle.first->m_data[realIndex];
|
||||||
}
|
}
|
||||||
|
|
||||||
T& At(size_t index)
|
T& At(size_t index)
|
||||||
@@ -383,20 +347,30 @@ namespace OpenVulkano
|
|||||||
return operator[](index);
|
return operator[](index);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Clear()
|
void Clear()
|
||||||
{
|
{
|
||||||
VectorChunk* currentChunk = m_firstChunk;
|
// Get the first chunk's cap
|
||||||
|
size_t cap = m_firstChunk->m_capacity;
|
||||||
|
|
||||||
|
// Annihilate everything
|
||||||
|
VectorChunk* currentChunk = m_firstChunk->m_next;
|
||||||
while (currentChunk)
|
while (currentChunk)
|
||||||
{
|
{
|
||||||
VectorChunk* nextChunk = currentChunk->m_next;
|
VectorChunk* temp = currentChunk;
|
||||||
delete currentChunk;
|
currentChunk = currentChunk->m_next;
|
||||||
currentChunk = nextChunk;
|
temp->~VectorChunk();
|
||||||
|
::operator delete(temp);
|
||||||
}
|
}
|
||||||
|
|
||||||
m_firstChunk = Grow(DEFAULT_CHUNK_SIZE);
|
// Reset the first chunk
|
||||||
|
m_firstChunk->m_next = nullptr;
|
||||||
m_lastChunk = m_firstChunk;
|
m_lastChunk = m_firstChunk;
|
||||||
m_capacity = DEFAULT_CHUNK_SIZE;
|
m_firstChunk->m_size = 0;
|
||||||
|
m_firstChunk->m_nextIndex = 0;
|
||||||
|
m_firstChunk->m_gapCount = 0;
|
||||||
|
m_firstChunk->~VectorChunk();
|
||||||
m_size = 0;
|
m_size = 0;
|
||||||
|
m_capacity = cap;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t Size() const noexcept { return m_size; }
|
size_t Size() const noexcept { return m_size; }
|
||||||
@@ -423,7 +397,7 @@ namespace OpenVulkano
|
|||||||
size_t capacity() const noexcept { return Capacity(); }
|
size_t capacity() const noexcept { return Capacity(); }
|
||||||
//endregion
|
//endregion
|
||||||
|
|
||||||
protected:
|
private:
|
||||||
VectorChunk* Grow(size_t requestSize)
|
VectorChunk* Grow(size_t requestSize)
|
||||||
{
|
{
|
||||||
VectorChunk* newChunk = static_cast<VectorChunk*>(
|
VectorChunk* newChunk = static_cast<VectorChunk*>(
|
||||||
@@ -497,6 +471,15 @@ namespace OpenVulkano
|
|||||||
return InsertBack();
|
return InsertBack();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Delete(size_t index, VectorChunk* chunk)
|
||||||
|
{
|
||||||
|
chunk->m_data[index].~T();
|
||||||
|
chunk->m_occupiedIndices[index] = false;
|
||||||
|
chunk->m_size--;
|
||||||
|
chunk->m_gapCount++;
|
||||||
|
m_size--;
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
VectorChunk* m_firstChunk;
|
VectorChunk* m_firstChunk;
|
||||||
VectorChunk* m_lastChunk;
|
VectorChunk* m_lastChunk;
|
||||||
|
|||||||
Reference in New Issue
Block a user