StableVector repetition fix.
This commit is contained in:
@@ -14,7 +14,7 @@
|
||||
namespace OpenVulkano
|
||||
{
|
||||
template<typename K, typename V, template<typename, typename> class Pair = std::pair,
|
||||
template<typename> class Vec = std::vector, typename = std::enable_if_t<std::is_integral<K>::value>>
|
||||
template<typename...> class Vec = std::vector, typename = std::enable_if_t<std::is_integral<K>::value>>
|
||||
class BinSearchArrayMap
|
||||
{
|
||||
public:
|
||||
@@ -59,7 +59,7 @@ namespace OpenVulkano
|
||||
std::streamsize index = FindIndexInVector(key);
|
||||
if (index < 0)
|
||||
{
|
||||
std::runtime_error("Key not found");
|
||||
throw std::runtime_error("Key not found");
|
||||
}
|
||||
return m_data[index];
|
||||
}
|
||||
|
||||
@@ -30,7 +30,7 @@ namespace OpenVulkano
|
||||
*
|
||||
* @throw Please know that this vector creates array gaps when you remove an element.
|
||||
*/
|
||||
template<typename T, size_t GROW_FACTOR = 2, size_t DEFAULT_CHUNK_SIZE = 32> class StableVector
|
||||
template<typename T> class StableVector
|
||||
{
|
||||
struct VectorChunk
|
||||
{
|
||||
@@ -174,10 +174,7 @@ namespace OpenVulkano
|
||||
return m_chunk == other.m_chunk && m_index == other.m_index;
|
||||
}
|
||||
|
||||
bool operator!=(const Iterator& other) const
|
||||
{
|
||||
return m_chunk != other.m_chunk || m_index != other.m_index;
|
||||
}
|
||||
bool operator!=(const Iterator& other) const { return !(*this == other); }
|
||||
|
||||
std::streamsize GetIndex() const { return m_chunk->GetRealIndex(m_index); }
|
||||
VectorChunk* GetChunk() const { return m_chunk; }
|
||||
@@ -285,143 +282,17 @@ namespace OpenVulkano
|
||||
}
|
||||
}
|
||||
|
||||
void PushBack(const T& value)
|
||||
{
|
||||
if (m_lastChunk->m_nextIndex == m_lastChunk->m_capacity)
|
||||
{
|
||||
VectorChunk* newChunk = Grow(m_lastChunk->m_capacity * GROW_FACTOR);
|
||||
m_capacity += m_lastChunk->m_capacity * GROW_FACTOR;
|
||||
m_lastChunk->m_next = newChunk;
|
||||
newChunk->m_prev = m_lastChunk;
|
||||
m_lastChunk = newChunk;
|
||||
}
|
||||
|
||||
new (&m_lastChunk->m_data[m_lastChunk->m_nextIndex]) T(value);
|
||||
m_lastChunk->m_occupiedIndices[m_lastChunk->m_nextIndex] = true;
|
||||
m_lastChunk->m_nextIndex++;
|
||||
m_lastChunk->m_size++;
|
||||
m_size++;
|
||||
}
|
||||
|
||||
void PushBack(T&& value) noexcept
|
||||
{
|
||||
if (m_lastChunk->m_nextIndex == m_lastChunk->m_capacity)
|
||||
{
|
||||
VectorChunk* newChunk = Grow(m_lastChunk->m_capacity * GROW_FACTOR);
|
||||
m_capacity += m_lastChunk->m_capacity * GROW_FACTOR;
|
||||
m_lastChunk->m_next = newChunk;
|
||||
newChunk->m_prev = m_lastChunk;
|
||||
m_lastChunk = newChunk;
|
||||
}
|
||||
|
||||
new (&m_lastChunk->m_data[m_lastChunk->m_nextIndex]) T(std::move(value));
|
||||
m_lastChunk->m_occupiedIndices[m_lastChunk->m_nextIndex] = true;
|
||||
m_lastChunk->m_nextIndex++;
|
||||
m_lastChunk->m_size++;
|
||||
m_size++;
|
||||
}
|
||||
|
||||
// Checks the first available gap and inserts. If no gap it works like push_back(const T& value)
|
||||
void Push(const T& value)
|
||||
{
|
||||
VectorChunk* currentChunk = m_firstChunk;
|
||||
while (currentChunk)
|
||||
{
|
||||
if (currentChunk->m_gapCount > 0) // If there is a gap check occupied indices to find the first gap
|
||||
{
|
||||
for (size_t i = 0; i < currentChunk->m_capacity; i++)
|
||||
{
|
||||
if (!currentChunk->m_occupiedIndices[i])
|
||||
{
|
||||
new (¤tChunk->m_data[i]) T(value);
|
||||
currentChunk->m_occupiedIndices[i] = true;
|
||||
currentChunk->m_size++;
|
||||
currentChunk->m_gapCount--;
|
||||
m_size++;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
currentChunk = currentChunk->m_next;
|
||||
}
|
||||
|
||||
PushBack(value);
|
||||
}
|
||||
|
||||
// Checks the first available gap and inserts. If no gap it works like push_back(T&& value)
|
||||
void Push(T&& value) noexcept
|
||||
{
|
||||
VectorChunk* currentChunk = m_firstChunk;
|
||||
while (currentChunk)
|
||||
{
|
||||
if (currentChunk->m_gapCount > 0) // If there is a gap check occupied indices to find the first gap
|
||||
{
|
||||
for (size_t i = 0; i < currentChunk->m_capacity; i++)
|
||||
{
|
||||
if (!currentChunk->m_occupiedIndices[i])
|
||||
{
|
||||
new (¤tChunk->m_data[i]) T(std::move(value));
|
||||
currentChunk->m_occupiedIndices[i] = true;
|
||||
currentChunk->m_size++;
|
||||
currentChunk->m_gapCount--;
|
||||
m_size++;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
currentChunk = currentChunk->m_next;
|
||||
}
|
||||
|
||||
PushBack(std::move(value));
|
||||
}
|
||||
void PushBack(const T& value) { new (InsertBack()) T(value); }
|
||||
void PushBack(T&& value) noexcept { new (InsertBack()) T(std::move(value)); }
|
||||
|
||||
template<typename... Args> void EmplaceBack(Args&&... args)
|
||||
{
|
||||
if (m_lastChunk->m_nextIndex == m_lastChunk->m_capacity)
|
||||
{
|
||||
VectorChunk* newChunk = Grow(m_lastChunk->m_capacity * GROW_FACTOR);
|
||||
m_capacity += m_lastChunk->m_capacity * GROW_FACTOR;
|
||||
m_lastChunk->m_next = newChunk;
|
||||
newChunk->m_prev = m_lastChunk;
|
||||
m_lastChunk = newChunk;
|
||||
}
|
||||
|
||||
new (&m_lastChunk->m_data[m_lastChunk->m_nextIndex]) T(std::forward<Args>(args)...);
|
||||
m_lastChunk->m_occupiedIndices[m_lastChunk->m_nextIndex] = true;
|
||||
m_lastChunk->m_nextIndex++;
|
||||
m_lastChunk->m_size++;
|
||||
m_size++;
|
||||
new (InsertBack()) T(std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
// Checks the first available gap and inserts. If no gap it works like emplace_back(Args&&... args)
|
||||
template<typename... Args> void Emplace(Args&&... args)
|
||||
{
|
||||
VectorChunk* currentChunk = m_firstChunk;
|
||||
while (currentChunk)
|
||||
{
|
||||
if (currentChunk->m_gapCount > 0) // If there is a gap check occupied indices to find the first gap
|
||||
{
|
||||
for (size_t i = 0; i < currentChunk->m_capacity; i++)
|
||||
{
|
||||
if (!currentChunk->m_occupiedIndices[i])
|
||||
{
|
||||
new (¤tChunk->m_data[i]) T(std::forward<Args>(args)...);
|
||||
currentChunk->m_occupiedIndices[i] = true;
|
||||
currentChunk->m_size++;
|
||||
currentChunk->m_gapCount--;
|
||||
m_size++;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
currentChunk = currentChunk->m_next;
|
||||
}
|
||||
|
||||
EmplaceBack(std::forward<Args>(args)...);
|
||||
}
|
||||
void Push(const T& value) { new (Insert()) T(value); }
|
||||
void Push(T&& value) noexcept { new (Insert()) T(std::move(value)); }
|
||||
template<typename... Args> void Emplace(Args&&... args) { new (Insert()) T(std::forward<Args>(args)...); }
|
||||
|
||||
void PopBack()
|
||||
{
|
||||
@@ -580,11 +451,60 @@ namespace OpenVulkano
|
||||
throw std::out_of_range("Index out of range");
|
||||
}
|
||||
|
||||
T* InsertBack()
|
||||
{
|
||||
if (m_lastChunk->m_nextIndex == m_lastChunk->m_capacity)
|
||||
{
|
||||
VectorChunk* newChunk = Grow(m_lastChunk->m_capacity * GROW_FACTOR);
|
||||
m_capacity += m_lastChunk->m_capacity * GROW_FACTOR;
|
||||
m_lastChunk->m_next = newChunk;
|
||||
newChunk->m_prev = m_lastChunk;
|
||||
m_lastChunk = newChunk;
|
||||
}
|
||||
|
||||
m_lastChunk->m_occupiedIndices[m_lastChunk->m_nextIndex] = true;
|
||||
m_lastChunk->m_size++;
|
||||
m_lastChunk->m_gapCount++;
|
||||
m_size++;
|
||||
return &m_lastChunk->m_data[m_lastChunk->m_nextIndex++];
|
||||
}
|
||||
|
||||
T* Insert()
|
||||
{
|
||||
T* target = nullptr;
|
||||
VectorChunk* currentChunk = m_firstChunk;
|
||||
while (currentChunk)
|
||||
{
|
||||
if (currentChunk->m_gapCount > 0) // If there is a gap check occupied indices to find the first gap
|
||||
{
|
||||
for (size_t i = 0; i < currentChunk->m_capacity; i++)
|
||||
{
|
||||
if (!currentChunk->m_occupiedIndices[i])
|
||||
{
|
||||
target = ¤tChunk->m_data[i];
|
||||
currentChunk->m_occupiedIndices[i] = true;
|
||||
currentChunk->m_size++;
|
||||
currentChunk->m_gapCount--;
|
||||
m_size++;
|
||||
return target;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
currentChunk = currentChunk->m_next;
|
||||
}
|
||||
|
||||
return InsertBack();
|
||||
}
|
||||
|
||||
private:
|
||||
VectorChunk* m_firstChunk;
|
||||
VectorChunk* m_lastChunk;
|
||||
size_t m_size;
|
||||
size_t m_capacity;
|
||||
|
||||
static inline constexpr size_t DEFAULT_CHUNK_SIZE = 32;
|
||||
static inline constexpr size_t GROW_FACTOR = 2;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user