237 lines
5.2 KiB
C++
237 lines
5.2 KiB
C++
#pragma once
|
|
|
|
#include "Globals.h"
|
|
#include <Entities/Entity.h>
|
|
#include <SwapBackVectorIterator.hpp>
|
|
#include <bitset>
|
|
#include <cassert>
|
|
#include <cstddef>
|
|
#include <cstdint>
|
|
#include <iterator>
|
|
#include <ostream>
|
|
|
|
|
|
template<typename T, EntityIndex capacity_in = Global::MAX_ENTITIES>
|
|
class SwapBackVector
|
|
{
|
|
public:
|
|
//iterator typedefs
|
|
using iterator_category = std::forward_iterator_tag;
|
|
using difference_type = std::ptrdiff_t;
|
|
using data_type = T;
|
|
using iterator = SwapBackVectorIterator<SwapBackVector<T, capacity_in>>;
|
|
using const_iterator = SwapBackVectorConstIterator<SwapBackVector<T, capacity_in>>;
|
|
|
|
public:
|
|
SwapBackVector()
|
|
{
|
|
m_data = new T[capacity_in];
|
|
}
|
|
|
|
~SwapBackVector()
|
|
{
|
|
delete[] m_data;
|
|
}
|
|
|
|
SwapBackVector(const SwapBackVector<T>& other)
|
|
{
|
|
m_nextValidIndex = other.m_nextValidIndex;
|
|
for (int i = 0; i < m_nextValidIndex; i++)
|
|
{
|
|
m_data[i] = other.m_data[i];
|
|
}
|
|
}
|
|
|
|
SwapBackVector(SwapBackVector<T>&& other)
|
|
{
|
|
m_data = other.m_data;
|
|
other.m_data = nullptr;
|
|
m_nextValidIndex = other.m_nextValidIndex;
|
|
}
|
|
|
|
SwapBackVector<T>& operator=(const SwapBackVector<T>& rhs)
|
|
{
|
|
if (this == &rhs) return this;
|
|
|
|
m_nextValidIndex = rhs.m_nextValidIndex;
|
|
for (int i = 0; i < m_nextValidIndex; i++)
|
|
{
|
|
m_data[i] = rhs.m_data[i];
|
|
}
|
|
return *this;
|
|
}
|
|
|
|
SwapBackVector<T>& operator=(SwapBackVector<T>&& rhs)
|
|
{
|
|
if (this == &rhs) return this;
|
|
|
|
delete[] m_data;
|
|
m_data = rhs.m_data;
|
|
rhs.m_data = nullptr;
|
|
|
|
return *this;
|
|
}
|
|
|
|
public:
|
|
T& operator[](EntityIndex index)
|
|
{
|
|
assert(index < m_nextValidIndex && "ASSERT ERROR -> SwapBackVector.hpp: attempting to index beyond next valid index");
|
|
return m_data[index];
|
|
}
|
|
|
|
const T& operator[](EntityIndex index) const
|
|
{
|
|
assert(index < m_nextValidIndex && "ASSERT ERROR -> SwapBackVector.hpp: attempting to index beyond next valid index");
|
|
return m_data[index];
|
|
}
|
|
|
|
public:
|
|
T* data() { return m_data; }
|
|
|
|
const T* data() const { return m_data; }
|
|
|
|
void remove(EntityIndex index)
|
|
{
|
|
if (index >= m_nextValidIndex) return;
|
|
|
|
m_data[index] = m_data[m_nextValidIndex - 1];
|
|
m_nextValidIndex--;
|
|
}
|
|
|
|
void push()
|
|
{
|
|
assert(capacity_in > m_nextValidIndex);
|
|
|
|
m_data[m_nextValidIndex] = T();
|
|
m_nextValidIndex++;
|
|
}
|
|
|
|
void push(const T& data)
|
|
{
|
|
assert(capacity_in > m_nextValidIndex);
|
|
|
|
m_data[m_nextValidIndex] = data;
|
|
m_nextValidIndex++;
|
|
}
|
|
inline EntityIndex size() const { return m_nextValidIndex; }
|
|
|
|
inline constexpr EntityIndex capacity() const { return capacity_in; }
|
|
|
|
iterator begin() { return iterator(m_data); }
|
|
|
|
iterator end() { return iterator(m_data + m_nextValidIndex); }
|
|
|
|
const_iterator cbegin() const { return const_iterator(m_data); }
|
|
|
|
const_iterator cend() const { return const_iterator(m_data + m_nextValidIndex); }
|
|
|
|
private:
|
|
T* m_data;
|
|
EntityIndex m_nextValidIndex{};
|
|
};
|
|
|
|
|
|
//bool specialization
|
|
template<EntityIndex capacity_in>
|
|
class SwapBackVector<bool, capacity_in>
|
|
{
|
|
public:
|
|
SwapBackVector()
|
|
{
|
|
m_data = new uint8_t[(capacity_in / 8) + 1];
|
|
}
|
|
|
|
~SwapBackVector()
|
|
{
|
|
delete[] m_data;
|
|
}
|
|
|
|
SwapBackVector(const SwapBackVector& other) = delete;
|
|
SwapBackVector(SwapBackVector&& other) = delete;
|
|
|
|
SwapBackVector& operator=(const SwapBackVector& rhs) = delete;
|
|
SwapBackVector& operator=(SwapBackVector&& rhs) = delete;
|
|
|
|
public:
|
|
bool operator[](EntityIndex index)
|
|
{
|
|
//assert(index < m_nextValidIndex && "ASSERT ERROR -> SwapBackVector.hpp: attempting to index beyond next valid index");
|
|
EntityIndex clusterIndex = index / 8u;
|
|
EntityIndex stateIndex = index % 8u;
|
|
return m_data[clusterIndex] & (1 << stateIndex);
|
|
}
|
|
|
|
friend std::ostream& operator<<(std::ostream&, const SwapBackVector<bool>&);
|
|
public:
|
|
void remove(EntityIndex index)
|
|
{
|
|
if (index >= m_nextValidIndex) return;
|
|
|
|
readAt(m_nextValidIndex - 1) ? setTrueAt(index) : setFalseAt(index);
|
|
m_nextValidIndex--;
|
|
}
|
|
|
|
void push()
|
|
{
|
|
assert(capacity_in > m_nextValidIndex);
|
|
|
|
setFalseAt(m_nextValidIndex);
|
|
m_nextValidIndex++;
|
|
}
|
|
|
|
void push(bool state)
|
|
{
|
|
assert(capacity_in > m_nextValidIndex);
|
|
|
|
state ? setTrueAt(m_nextValidIndex) : setFalseAt(m_nextValidIndex);
|
|
m_nextValidIndex++;
|
|
}
|
|
|
|
bool readAt(EntityIndex index) const
|
|
{
|
|
EntityIndex clusterIndex = index / 8u;
|
|
EntityIndex stateIndex = index % 8u;
|
|
return m_data[clusterIndex] & 1 << stateIndex;
|
|
}
|
|
|
|
void setTrueAt(EntityIndex index)
|
|
{
|
|
EntityIndex clusterIndex = index / 8u;
|
|
EntityIndex stateIndex = index % 8u;
|
|
m_data[clusterIndex] |= 1 << stateIndex;
|
|
}
|
|
|
|
void setFalseAt(EntityIndex index)
|
|
{
|
|
EntityIndex clusterIndex = index / 8u;
|
|
EntityIndex stateIndex = index % 8u;
|
|
m_data[clusterIndex] &= ~(1 << stateIndex);
|
|
}
|
|
|
|
inline EntityIndex size() const { return m_nextValidIndex; }
|
|
|
|
inline constexpr EntityIndex capacity() const { return capacity_in; }
|
|
|
|
private:
|
|
uint8_t* m_data;
|
|
EntityIndex m_nextValidIndex{};
|
|
};
|
|
|
|
inline std::ostream& operator<<(std::ostream& out, const SwapBackVector<bool>& vec)
|
|
{
|
|
for(size_t i = 0; i < (vec.size() / 8) + 1; i++)
|
|
{
|
|
out << std::bitset<8>(vec.m_data[i]) << " ";
|
|
}
|
|
out << "\n";
|
|
return out;
|
|
}
|
|
|
|
//Entity specialization
|
|
template<EntityIndex capacity_in>
|
|
class SwapBackVector<Entity, capacity_in>
|
|
{
|
|
|
|
};
|
|
|