Extract slotkey from slotmap
This commit is contained in:
@@ -40,7 +40,7 @@ static_assert(std::is_trivially_copyable_v<MyComplexStruct>,
|
|||||||
class SlotMapAdaptor
|
class SlotMapAdaptor
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
using Key = SlotMap<MyComplexStruct>::SlotKey;
|
using Key = SlotMap<MyComplexStruct>::InternalSlotKey;
|
||||||
|
|
||||||
Key Add(MyComplexStruct&& p_value)
|
Key Add(MyComplexStruct&& p_value)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -15,77 +15,77 @@
|
|||||||
|
|
||||||
namespace Bigfoot
|
namespace Bigfoot
|
||||||
{
|
{
|
||||||
|
template<class VERSION_TYPE = std::uint32_t,
|
||||||
template<class TYPE,
|
|
||||||
class VERSION_TYPE = std::uint32_t,
|
|
||||||
class INDEX_TYPE = std::uint32_t,
|
class INDEX_TYPE = std::uint32_t,
|
||||||
std::enable_if_t<std::is_unsigned_v<VERSION_TYPE> && std::is_unsigned_v<INDEX_TYPE>, bool> = true>
|
std::enable_if_t<std::is_unsigned_v<VERSION_TYPE> && std::is_unsigned_v<INDEX_TYPE>, bool> = true>
|
||||||
|
class SlotMapKey
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
using IndexType = INDEX_TYPE;
|
||||||
|
using VersionType = VERSION_TYPE;
|
||||||
|
|
||||||
|
private:
|
||||||
|
static constexpr std::uint32_t VERSION_BIT_COUNT = sizeof(VersionType) * std::numeric_limits<unsigned char>::digits;
|
||||||
|
static constexpr std::uint32_t INDEX_BIT_COUNT = sizeof(IndexType) * std::numeric_limits<unsigned char>::digits;
|
||||||
|
static_assert(VERSION_BIT_COUNT + INDEX_BIT_COUNT <= 64,
|
||||||
|
"We cant construct a 64 bit key from the given Version and Index types!");
|
||||||
|
|
||||||
|
static constexpr std::uint64_t INDEX_MASK = (static_cast<std::uint64_t>(1) << INDEX_BIT_COUNT) - 1;
|
||||||
|
|
||||||
|
public:
|
||||||
|
static constexpr VersionType INVALID_VERSION = 0;
|
||||||
|
|
||||||
|
static constexpr IndexType MAX_INDEX = std::numeric_limits<IndexType>::max();
|
||||||
|
|
||||||
|
constexpr SlotMapKey(const VersionType p_version, const IndexType p_index):
|
||||||
|
m_key((static_cast<std::uint64_t>(p_version) << INDEX_BIT_COUNT) |
|
||||||
|
(static_cast<std::uint64_t>(p_index) & INDEX_MASK))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr SlotMapKey():
|
||||||
|
SlotMapKey(INVALID_VERSION, 0)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr SlotMapKey(const SlotMapKey& p_slotKey) = default;
|
||||||
|
constexpr SlotMapKey(SlotMapKey&& p_slotKey) = default;
|
||||||
|
|
||||||
|
constexpr ~SlotMapKey() = default;
|
||||||
|
|
||||||
|
constexpr bool Valid() const
|
||||||
|
{
|
||||||
|
return GetVersion() != INVALID_VERSION;
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr VersionType GetVersion() const
|
||||||
|
{
|
||||||
|
return static_cast<VersionType>(m_key >> INDEX_BIT_COUNT);
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr IndexType GetIndex() const
|
||||||
|
{
|
||||||
|
return static_cast<IndexType>(m_key & INDEX_MASK);
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr SlotMapKey& operator=(const SlotMapKey& p_slotKey) = default;
|
||||||
|
constexpr SlotMapKey& operator=(SlotMapKey&& p_slotKey) = default;
|
||||||
|
|
||||||
|
[[nodiscard]]
|
||||||
|
constexpr bool operator==(const SlotMapKey& p_other) const = default;
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::uint64_t m_key;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<class TYPE, class VERSION_TYPE = std::uint32_t, class INDEX_TYPE = std::uint32_t>
|
||||||
class SlotMap
|
class SlotMap
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
class SlotKey
|
using InternalSlotKey = SlotMapKey<VERSION_TYPE, INDEX_TYPE>;
|
||||||
{
|
|
||||||
public:
|
|
||||||
using IndexType = INDEX_TYPE;
|
|
||||||
using VersionType = VERSION_TYPE;
|
|
||||||
|
|
||||||
private:
|
|
||||||
static constexpr std::uint32_t VERSION_BIT_COUNT = sizeof(VersionType) *
|
|
||||||
std::numeric_limits<unsigned char>::digits;
|
|
||||||
static constexpr std::uint32_t INDEX_BIT_COUNT = sizeof(IndexType) * std::numeric_limits<unsigned char>::digits;
|
|
||||||
static_assert(VERSION_BIT_COUNT + INDEX_BIT_COUNT <= 64,
|
|
||||||
"We cant construct a 64 bit key from the given Version and Index types!");
|
|
||||||
|
|
||||||
static constexpr std::uint64_t INDEX_MASK = (static_cast<std::uint64_t>(1) << INDEX_BIT_COUNT) - 1;
|
|
||||||
|
|
||||||
public:
|
|
||||||
static constexpr VersionType INVALID_VERSION = 0;
|
|
||||||
|
|
||||||
static constexpr IndexType MAX_INDEX = std::numeric_limits<IndexType>::max();
|
|
||||||
|
|
||||||
constexpr SlotKey(const VersionType p_version, const IndexType p_index):
|
|
||||||
m_key((static_cast<std::uint64_t>(p_version) << INDEX_BIT_COUNT) |
|
|
||||||
(static_cast<std::uint64_t>(p_index) & INDEX_MASK))
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
constexpr SlotKey():
|
|
||||||
SlotKey(INVALID_VERSION, 0)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
constexpr SlotKey(const SlotKey& p_slotKey) = default;
|
|
||||||
constexpr SlotKey(SlotKey&& p_slotKey) = default;
|
|
||||||
|
|
||||||
constexpr ~SlotKey() = default;
|
|
||||||
|
|
||||||
constexpr bool Valid() const
|
|
||||||
{
|
|
||||||
return GetVersion() != INVALID_VERSION;
|
|
||||||
}
|
|
||||||
|
|
||||||
constexpr VersionType GetVersion() const
|
|
||||||
{
|
|
||||||
return static_cast<VersionType>(m_key >> INDEX_BIT_COUNT);
|
|
||||||
}
|
|
||||||
|
|
||||||
constexpr IndexType GetIndex() const
|
|
||||||
{
|
|
||||||
return static_cast<IndexType>(m_key & INDEX_MASK);
|
|
||||||
}
|
|
||||||
|
|
||||||
constexpr SlotKey& operator=(const SlotKey& p_slotKey) = default;
|
|
||||||
constexpr SlotKey& operator=(SlotKey&& p_slotKey) = default;
|
|
||||||
|
|
||||||
[[nodiscard]]
|
|
||||||
constexpr bool operator==(const SlotKey& p_other) const = default;
|
|
||||||
|
|
||||||
private:
|
|
||||||
std::uint64_t m_key;
|
|
||||||
};
|
|
||||||
|
|
||||||
SlotMap():
|
SlotMap():
|
||||||
m_freeSlotHead(std::numeric_limits<typename SlotKey::IndexType>::max())
|
m_freeSlotHead(std::numeric_limits<typename InternalSlotKey::IndexType>::max())
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -96,67 +96,68 @@ class SlotMap
|
|||||||
|
|
||||||
template<class... ARGS>
|
template<class... ARGS>
|
||||||
[[nodiscard]]
|
[[nodiscard]]
|
||||||
SlotKey Insert(ARGS&&... p_args)
|
InternalSlotKey Insert(ARGS&&... p_args)
|
||||||
{
|
{
|
||||||
ASSERT(UtilsAssertHandler, m_slots.size() < SlotKey::MAX_INDEX, "All slots have been exhausted!");
|
ASSERT(UtilsAssertHandler, m_slots.size() < InternalSlotKey::MAX_INDEX, "All slots have been exhausted!");
|
||||||
|
|
||||||
const typename SlotKey::IndexType dataIndex = static_cast<SlotKey::IndexType>(m_data.size());
|
const typename InternalSlotKey::IndexType dataIndex = static_cast<InternalSlotKey::IndexType>(m_data.size());
|
||||||
m_data.emplace_back(std::forward<ARGS>(p_args)...);
|
m_data.emplace_back(std::forward<ARGS>(p_args)...);
|
||||||
|
|
||||||
if (HasFreeSlots())
|
if (HasFreeSlots())
|
||||||
{
|
{
|
||||||
const typename SlotKey::IndexType slotIndex = m_freeSlotHead;
|
const typename InternalSlotKey::IndexType slotIndex = m_freeSlotHead;
|
||||||
|
|
||||||
m_freeSlotHead = m_slots[slotIndex].GetIndex();
|
m_freeSlotHead = m_slots[slotIndex].GetIndex();
|
||||||
|
|
||||||
m_slots[slotIndex] = SlotKey {m_slots[slotIndex].GetVersion(), dataIndex};
|
m_slots[slotIndex] = InternalSlotKey {m_slots[slotIndex].GetVersion(), dataIndex};
|
||||||
m_dataToSlots.push_back(slotIndex);
|
m_dataToSlots.push_back(slotIndex);
|
||||||
|
|
||||||
return SlotKey {m_slots[slotIndex].GetVersion(), slotIndex};
|
return InternalSlotKey {m_slots[slotIndex].GetVersion(), slotIndex};
|
||||||
}
|
}
|
||||||
|
|
||||||
const typename SlotKey::IndexType slotIndex = static_cast<SlotKey::IndexType>(m_slots.size());
|
const typename InternalSlotKey::IndexType slotIndex = static_cast<InternalSlotKey::IndexType>(m_slots.size());
|
||||||
m_slots.emplace_back(1, dataIndex);
|
m_slots.emplace_back(1, dataIndex);
|
||||||
m_dataToSlots.push_back(slotIndex);
|
m_dataToSlots.push_back(slotIndex);
|
||||||
|
|
||||||
return SlotKey {1, slotIndex};
|
return InternalSlotKey {1, slotIndex};
|
||||||
}
|
}
|
||||||
|
|
||||||
void Remove(const SlotKey p_slotKey)
|
void Remove(const InternalSlotKey p_slotKey)
|
||||||
{
|
{
|
||||||
if (!Has(p_slotKey))
|
if (!Has(p_slotKey))
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const typename SlotKey::IndexType dataIndex = m_slots[p_slotKey.GetIndex()].GetIndex();
|
const typename InternalSlotKey::IndexType dataIndex = m_slots[p_slotKey.GetIndex()].GetIndex();
|
||||||
|
|
||||||
m_data.erase_unsorted(m_data.begin() + dataIndex);
|
m_data.erase_unsorted(m_data.begin() + dataIndex);
|
||||||
m_dataToSlots.erase_unsorted(m_dataToSlots.begin() + dataIndex);
|
m_dataToSlots.erase_unsorted(m_dataToSlots.begin() + dataIndex);
|
||||||
|
|
||||||
if (dataIndex < m_data.size())
|
if (dataIndex < m_data.size())
|
||||||
{
|
{
|
||||||
m_slots[m_dataToSlots[dataIndex]] = SlotKey {m_slots[m_dataToSlots[dataIndex]].GetVersion(), dataIndex};
|
m_slots[m_dataToSlots[dataIndex]] = InternalSlotKey {m_slots[m_dataToSlots[dataIndex]].GetVersion(),
|
||||||
|
dataIndex};
|
||||||
}
|
}
|
||||||
|
|
||||||
RecycleSlot(p_slotKey.GetVersion() + 1, p_slotKey.GetIndex());
|
RecycleSlot(p_slotKey.GetVersion() + 1, p_slotKey.GetIndex());
|
||||||
}
|
}
|
||||||
|
|
||||||
[[nodiscard]]
|
[[nodiscard]]
|
||||||
bool Has(const SlotKey p_slotKey) const
|
bool Has(const InternalSlotKey p_slotKey) const
|
||||||
{
|
{
|
||||||
return p_slotKey.Valid() && (p_slotKey.GetIndex() < m_slots.size() &&
|
return p_slotKey.Valid() && (p_slotKey.GetIndex() < m_slots.size() &&
|
||||||
p_slotKey.GetVersion() == m_slots[p_slotKey.GetIndex()].GetVersion());
|
p_slotKey.GetVersion() == m_slots[p_slotKey.GetIndex()].GetVersion());
|
||||||
}
|
}
|
||||||
|
|
||||||
[[nodiscard]]
|
[[nodiscard]]
|
||||||
TYPE* Get(const SlotKey p_slotKey)
|
TYPE* Get(const InternalSlotKey p_slotKey)
|
||||||
{
|
{
|
||||||
return Has(p_slotKey) ? &m_data[m_slots[p_slotKey.GetIndex()].GetIndex()] : nullptr;
|
return Has(p_slotKey) ? &m_data[m_slots[p_slotKey.GetIndex()].GetIndex()] : nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
[[nodiscard]]
|
[[nodiscard]]
|
||||||
const TYPE* Get(const SlotKey p_slotKey) const
|
const TYPE* Get(const InternalSlotKey p_slotKey) const
|
||||||
{
|
{
|
||||||
return Has(p_slotKey) ? &m_data[m_slots[p_slotKey.GetIndex()].GetIndex()] : nullptr;
|
return Has(p_slotKey) ? &m_data[m_slots[p_slotKey.GetIndex()].GetIndex()] : nullptr;
|
||||||
}
|
}
|
||||||
@@ -166,14 +167,14 @@ class SlotMap
|
|||||||
m_data.clear();
|
m_data.clear();
|
||||||
m_slots.clear();
|
m_slots.clear();
|
||||||
m_dataToSlots.clear();
|
m_dataToSlots.clear();
|
||||||
m_freeSlotHead = std::numeric_limits<typename SlotKey::IndexType>::max();
|
m_freeSlotHead = std::numeric_limits<typename InternalSlotKey::IndexType>::max();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Clear()
|
void Clear()
|
||||||
{
|
{
|
||||||
for (const typename eastl::vector<TYPE>::size_type slotIndex: m_dataToSlots)
|
for (const typename eastl::vector<TYPE>::size_type slotIndex: m_dataToSlots)
|
||||||
{
|
{
|
||||||
RecycleSlot(m_slots[slotIndex].GetVersion() + 1, static_cast<SlotKey::IndexType>(slotIndex));
|
RecycleSlot(m_slots[slotIndex].GetVersion() + 1, static_cast<InternalSlotKey::IndexType>(slotIndex));
|
||||||
}
|
}
|
||||||
|
|
||||||
m_data.clear();
|
m_data.clear();
|
||||||
@@ -284,27 +285,27 @@ class SlotMap
|
|||||||
[[nodiscard]]
|
[[nodiscard]]
|
||||||
bool HasFreeSlots() const
|
bool HasFreeSlots() const
|
||||||
{
|
{
|
||||||
return m_freeSlotHead != std::numeric_limits<typename SlotKey::IndexType>::max();
|
return m_freeSlotHead != std::numeric_limits<typename InternalSlotKey::IndexType>::max();
|
||||||
}
|
}
|
||||||
|
|
||||||
void RecycleSlot(const SlotKey::VersionType p_version, const SlotKey::IndexType p_slotIndex)
|
void RecycleSlot(const InternalSlotKey::VersionType p_version, const InternalSlotKey::IndexType p_slotIndex)
|
||||||
{
|
{
|
||||||
if (p_version == SlotKey::INVALID_VERSION)
|
if (p_version == InternalSlotKey::INVALID_VERSION)
|
||||||
{
|
{
|
||||||
m_slots[p_slotIndex] = SlotKey {SlotKey::INVALID_VERSION, 0};
|
m_slots[p_slotIndex] = InternalSlotKey {InternalSlotKey::INVALID_VERSION, 0};
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_slots[p_slotIndex] = SlotKey {p_version, m_freeSlotHead};
|
m_slots[p_slotIndex] = InternalSlotKey {p_version, m_freeSlotHead};
|
||||||
m_freeSlotHead = p_slotIndex;
|
m_freeSlotHead = p_slotIndex;
|
||||||
}
|
}
|
||||||
|
|
||||||
eastl::vector<TYPE> m_data;
|
eastl::vector<TYPE> m_data;
|
||||||
eastl::vector<SlotKey> m_slots;
|
eastl::vector<InternalSlotKey> m_slots;
|
||||||
|
|
||||||
eastl::vector<typename eastl::vector<TYPE>::size_type> m_dataToSlots;
|
eastl::vector<typename eastl::vector<TYPE>::size_type> m_dataToSlots;
|
||||||
|
|
||||||
SlotKey::IndexType m_freeSlotHead;
|
InternalSlotKey::IndexType m_freeSlotHead;
|
||||||
};
|
};
|
||||||
} // namespace Bigfoot
|
} // namespace Bigfoot
|
||||||
|
|
||||||
|
|||||||
@@ -43,10 +43,11 @@ template<class CONFIG>
|
|||||||
class SlotKeyFixture: public ::testing::Test
|
class SlotKeyFixture: public ::testing::Test
|
||||||
{
|
{
|
||||||
protected:
|
protected:
|
||||||
using SlotMapVersion = typename CONFIG::Version;
|
using SlotMapVersionType = typename CONFIG::Version;
|
||||||
using SlotMapIndex = typename CONFIG::Index;
|
using SlotMapIndexType = typename CONFIG::Index;
|
||||||
using SlotMapType = SlotMap<std::uint32_t, SlotMapVersion, SlotMapIndex>;
|
|
||||||
using SlotKey = typename SlotMapType::SlotKey;
|
using SlotMapType = SlotMap<std::uint32_t, SlotMapVersionType, SlotMapIndexType>;
|
||||||
|
using SlotKeyType = typename SlotMapType::InternalSlotKey;
|
||||||
};
|
};
|
||||||
|
|
||||||
TYPED_TEST_SUITE(SlotKeyFixture, SlotMapConfigs, SlotMapConfigNames);
|
TYPED_TEST_SUITE(SlotKeyFixture, SlotMapConfigs, SlotMapConfigNames);
|
||||||
@@ -55,10 +56,10 @@ TYPED_TEST_SUITE(SlotKeyFixture, SlotMapConfigs, SlotMapConfigNames);
|
|||||||
|
|
||||||
TYPED_TEST(SlotKeyFixture, DefaultSlotKeyIsInvalid)
|
TYPED_TEST(SlotKeyFixture, DefaultSlotKeyIsInvalid)
|
||||||
{
|
{
|
||||||
constexpr typename TestFixture::SlotMapIndex index = 0;
|
constexpr typename TestFixture::SlotMapIndexType index = 0;
|
||||||
constexpr typename TestFixture::SlotMapVersion version = 0;
|
constexpr typename TestFixture::SlotMapVersionType version = 0;
|
||||||
|
|
||||||
constexpr typename TestFixture::SlotKey slotKey {};
|
constexpr typename TestFixture::SlotKeyType slotKey {};
|
||||||
EXPECT_FALSE(slotKey.Valid());
|
EXPECT_FALSE(slotKey.Valid());
|
||||||
EXPECT_EQ(slotKey.GetVersion(), version);
|
EXPECT_EQ(slotKey.GetVersion(), version);
|
||||||
EXPECT_EQ(slotKey.GetIndex(), index);
|
EXPECT_EQ(slotKey.GetIndex(), index);
|
||||||
@@ -68,10 +69,10 @@ TYPED_TEST(SlotKeyFixture, DefaultSlotKeyIsInvalid)
|
|||||||
|
|
||||||
TYPED_TEST(SlotKeyFixture, Valid_ShouldReturnTrueIfTheSlotKeyIsValid)
|
TYPED_TEST(SlotKeyFixture, Valid_ShouldReturnTrueIfTheSlotKeyIsValid)
|
||||||
{
|
{
|
||||||
constexpr typename TestFixture::SlotMapIndex index = 0;
|
constexpr typename TestFixture::SlotMapIndexType index = 0;
|
||||||
constexpr typename TestFixture::SlotMapVersion version = 1;
|
constexpr typename TestFixture::SlotMapVersionType version = 1;
|
||||||
|
|
||||||
constexpr typename TestFixture::SlotKey slotKey {version, index};
|
constexpr typename TestFixture::SlotKeyType slotKey {version, index};
|
||||||
EXPECT_TRUE(slotKey.Valid());
|
EXPECT_TRUE(slotKey.Valid());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -79,10 +80,10 @@ TYPED_TEST(SlotKeyFixture, Valid_ShouldReturnTrueIfTheSlotKeyIsValid)
|
|||||||
|
|
||||||
TYPED_TEST(SlotKeyFixture, Valid_ShouldReturnFalseIfTheSlotKeyIsValid)
|
TYPED_TEST(SlotKeyFixture, Valid_ShouldReturnFalseIfTheSlotKeyIsValid)
|
||||||
{
|
{
|
||||||
constexpr typename TestFixture::SlotMapIndex index = 0;
|
constexpr typename TestFixture::SlotMapIndexType index = 0;
|
||||||
constexpr typename TestFixture::SlotMapVersion version = 0;
|
constexpr typename TestFixture::SlotMapVersionType version = 0;
|
||||||
|
|
||||||
constexpr typename TestFixture::SlotKey slotKey {version, index};
|
constexpr typename TestFixture::SlotKeyType slotKey {version, index};
|
||||||
EXPECT_FALSE(slotKey.Valid());
|
EXPECT_FALSE(slotKey.Valid());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -90,10 +91,10 @@ TYPED_TEST(SlotKeyFixture, Valid_ShouldReturnFalseIfTheSlotKeyIsValid)
|
|||||||
|
|
||||||
TYPED_TEST(SlotKeyFixture, GetVersion_ShouldReturnTheVersion)
|
TYPED_TEST(SlotKeyFixture, GetVersion_ShouldReturnTheVersion)
|
||||||
{
|
{
|
||||||
constexpr typename TestFixture::SlotMapIndex index = 0;
|
constexpr typename TestFixture::SlotMapIndexType index = 0;
|
||||||
constexpr typename TestFixture::SlotMapVersion version = 42;
|
constexpr typename TestFixture::SlotMapVersionType version = 42;
|
||||||
|
|
||||||
constexpr typename TestFixture::SlotKey slotKey {version, index};
|
constexpr typename TestFixture::SlotKeyType slotKey {version, index};
|
||||||
EXPECT_EQ(slotKey.GetVersion(), version);
|
EXPECT_EQ(slotKey.GetVersion(), version);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -101,10 +102,10 @@ TYPED_TEST(SlotKeyFixture, GetVersion_ShouldReturnTheVersion)
|
|||||||
|
|
||||||
TYPED_TEST(SlotKeyFixture, GetIndex_ShouldReturnTheIndex)
|
TYPED_TEST(SlotKeyFixture, GetIndex_ShouldReturnTheIndex)
|
||||||
{
|
{
|
||||||
constexpr typename TestFixture::SlotMapIndex index = 42;
|
constexpr typename TestFixture::SlotMapIndexType index = 42;
|
||||||
constexpr typename TestFixture::SlotMapVersion version = 0;
|
constexpr typename TestFixture::SlotMapVersionType version = 0;
|
||||||
|
|
||||||
constexpr typename TestFixture::SlotKey slotKey {version, index};
|
constexpr typename TestFixture::SlotKeyType slotKey {version, index};
|
||||||
EXPECT_EQ(slotKey.GetIndex(), index);
|
EXPECT_EQ(slotKey.GetIndex(), index);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -114,10 +115,11 @@ template<class CONFIG>
|
|||||||
class SlotMapFixture: public ::testing::Test
|
class SlotMapFixture: public ::testing::Test
|
||||||
{
|
{
|
||||||
protected:
|
protected:
|
||||||
using SlotMapVersion = typename CONFIG::Version;
|
using SlotMapVersionType = typename CONFIG::Version;
|
||||||
using SlotMapIndex = typename CONFIG::Index;
|
using SlotMapIndexType = typename CONFIG::Index;
|
||||||
using SlotMapType = SlotMap<std::uint32_t, SlotMapVersion, SlotMapIndex>;
|
|
||||||
using SlotKey = typename SlotMapType::SlotKey;
|
using SlotMapType = SlotMap<std::uint32_t, SlotMapVersionType, SlotMapIndexType>;
|
||||||
|
using SlotKeyType = typename SlotMapType::InternalSlotKey;
|
||||||
|
|
||||||
SlotMapType m_slotMap;
|
SlotMapType m_slotMap;
|
||||||
};
|
};
|
||||||
@@ -159,8 +161,8 @@ TYPED_TEST(SlotMapFixture, Has_ShouldReturnFalseIfTheSlotMapDoesNotHaveTheKey)
|
|||||||
const auto slotKey = this->m_slotMap.Insert(42);
|
const auto slotKey = this->m_slotMap.Insert(42);
|
||||||
this->m_slotMap.Remove(slotKey);
|
this->m_slotMap.Remove(slotKey);
|
||||||
EXPECT_FALSE(this->m_slotMap.Has(slotKey));
|
EXPECT_FALSE(this->m_slotMap.Has(slotKey));
|
||||||
EXPECT_FALSE(this->m_slotMap.Has(typename TestFixture::SlotKey {1, 22}));
|
EXPECT_FALSE(this->m_slotMap.Has(typename TestFixture::SlotKeyType {1, 22}));
|
||||||
EXPECT_FALSE(this->m_slotMap.Has(typename TestFixture::SlotKey {}));
|
EXPECT_FALSE(this->m_slotMap.Has(typename TestFixture::SlotKeyType {}));
|
||||||
}
|
}
|
||||||
|
|
||||||
/****************************************************************************************/
|
/****************************************************************************************/
|
||||||
@@ -176,7 +178,7 @@ TYPED_TEST(SlotMapFixture, Remove_ShouldRemoveTheSlotKey)
|
|||||||
|
|
||||||
TYPED_TEST(SlotMapFixture, Remove_ShouldNotRecycleASlotWhenVersionWasExhausted)
|
TYPED_TEST(SlotMapFixture, Remove_ShouldNotRecycleASlotWhenVersionWasExhausted)
|
||||||
{
|
{
|
||||||
if constexpr (std::is_same_v<typename TestFixture::SlotMapVersion, std::uint32_t>)
|
if constexpr (std::is_same_v<typename TestFixture::SlotMapVersionType, std::uint32_t>)
|
||||||
{
|
{
|
||||||
GTEST_SKIP() << "Skipped for 32-bit version: exhausting all versions is too slow.";
|
GTEST_SKIP() << "Skipped for 32-bit version: exhausting all versions is too slow.";
|
||||||
}
|
}
|
||||||
@@ -184,8 +186,8 @@ TYPED_TEST(SlotMapFixture, Remove_ShouldNotRecycleASlotWhenVersionWasExhausted)
|
|||||||
{
|
{
|
||||||
auto key = this->m_slotMap.Insert(1);
|
auto key = this->m_slotMap.Insert(1);
|
||||||
|
|
||||||
for (typename TestFixture::SlotMapVersion i = 1;
|
for (typename TestFixture::SlotMapVersionType i = 1;
|
||||||
i < std::numeric_limits<typename TestFixture::SlotMapVersion>::max();
|
i < std::numeric_limits<typename TestFixture::SlotMapVersionType>::max();
|
||||||
++i)
|
++i)
|
||||||
{
|
{
|
||||||
this->m_slotMap.Remove(key);
|
this->m_slotMap.Remove(key);
|
||||||
@@ -195,7 +197,7 @@ TYPED_TEST(SlotMapFixture, Remove_ShouldNotRecycleASlotWhenVersionWasExhausted)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Slot is at MAX_VERSION — one more remove should overflow and permanently deactivate it
|
// Slot is at MAX_VERSION — one more remove should overflow and permanently deactivate it
|
||||||
EXPECT_EQ(key.GetVersion(), std::numeric_limits<typename TestFixture::SlotMapVersion>::max());
|
EXPECT_EQ(key.GetVersion(), std::numeric_limits<typename TestFixture::SlotMapVersionType>::max());
|
||||||
this->m_slotMap.Remove(key);
|
this->m_slotMap.Remove(key);
|
||||||
|
|
||||||
EXPECT_FALSE(this->m_slotMap.Has(key));
|
EXPECT_FALSE(this->m_slotMap.Has(key));
|
||||||
@@ -205,7 +207,7 @@ TYPED_TEST(SlotMapFixture, Remove_ShouldNotRecycleASlotWhenVersionWasExhausted)
|
|||||||
EXPECT_NE(newKey.GetIndex(), key.GetIndex());
|
EXPECT_NE(newKey.GetIndex(), key.GetIndex());
|
||||||
|
|
||||||
// Ensure an invalid key does not return an exhausted slot
|
// Ensure an invalid key does not return an exhausted slot
|
||||||
EXPECT_EQ(this->m_slotMap.Get(typename TestFixture::SlotKey {}), nullptr);
|
EXPECT_EQ(this->m_slotMap.Get(typename TestFixture::SlotKeyType {}), nullptr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -228,7 +230,7 @@ TYPED_TEST(SlotMapFixture, Remove_ShouldNotDoAnythingInCaseStaleKey)
|
|||||||
{
|
{
|
||||||
const auto slotKey1 = this->m_slotMap.Insert(42);
|
const auto slotKey1 = this->m_slotMap.Insert(42);
|
||||||
|
|
||||||
this->m_slotMap.Remove(typename TestFixture::SlotKey {2, 0});
|
this->m_slotMap.Remove(typename TestFixture::SlotKeyType {2, 0});
|
||||||
|
|
||||||
EXPECT_EQ(*this->m_slotMap.Get(slotKey1), 42);
|
EXPECT_EQ(*this->m_slotMap.Get(slotKey1), 42);
|
||||||
}
|
}
|
||||||
@@ -243,8 +245,8 @@ TYPED_TEST(SlotMapFixture, Get_ShouldReturnNullptrForInvalidSlotKeys)
|
|||||||
const auto validate = [&](auto& p_slotMap)
|
const auto validate = [&](auto& p_slotMap)
|
||||||
{
|
{
|
||||||
EXPECT_EQ(p_slotMap.Get(slotKey), nullptr);
|
EXPECT_EQ(p_slotMap.Get(slotKey), nullptr);
|
||||||
EXPECT_EQ(p_slotMap.Get(typename TestFixture::SlotKey {1, 3}), nullptr);
|
EXPECT_EQ(p_slotMap.Get(typename TestFixture::SlotKeyType {1, 3}), nullptr);
|
||||||
EXPECT_EQ(p_slotMap.Get(typename TestFixture::SlotKey {}), nullptr);
|
EXPECT_EQ(p_slotMap.Get(typename TestFixture::SlotKeyType {}), nullptr);
|
||||||
};
|
};
|
||||||
|
|
||||||
validate(this->m_slotMap);
|
validate(this->m_slotMap);
|
||||||
|
|||||||
Reference in New Issue
Block a user