PixelBullet  0.0.1
A C++ game engine
Loading...
Searching...
No Matches
SparseSet.hpp
1#pragma once
2
3#include <cassert>
4#include <cstdint>
5#include <limits>
6#include <vector>
7
8namespace PixelBullet
9{
10 template <typename T, typename Index = uint32_t>
12 {
13 public:
14 static constexpr Index INVALID_INDEX = std::numeric_limits<Index>::max();
15
16 bool Has(Index id) const
17 {
18 return id < m_Sparse.size() && m_Sparse[id] != INVALID_INDEX && m_Sparse[id] < m_Dense.size() &&
19 m_Dense[m_Sparse[id]].id == id;
20 }
21
22 void Insert(Index id, const T& value)
23 {
24 if (id >= m_Sparse.size())
25 {
26 m_Sparse.resize(id + 1, INVALID_INDEX);
27 }
28
29 if (Has(id))
30 {
31 m_Dense[m_Sparse[id]].data = value;
32 }
33 else
34 {
35 m_Sparse[id] = static_cast<Index>(m_Dense.size());
36 m_Dense.push_back({ id, value });
37 }
38 }
39
40 void Erase(Index id)
41 {
42 if (!Has(id))
43 {
44 return;
45 }
46
47 Index denseIdx = m_Sparse[id];
48 auto lastIdx = static_cast<Index>(m_Dense.size() - 1);
49
50 if (denseIdx != lastIdx)
51 {
52 std::swap(m_Dense[denseIdx], m_Dense[lastIdx]);
53 m_Sparse[m_Dense[denseIdx].id] = denseIdx;
54 }
55
56 m_Dense.pop_back();
57 m_Sparse[id] = INVALID_INDEX;
58 }
59
60 T& Get(Index id)
61 {
62 assert(Has(id));
63 return m_Dense[m_Sparse[id]].data;
64 }
65
66 const T& Get(Index id) const
67 {
68 assert(Has(id));
69 return m_Dense[m_Sparse[id]].data;
70 }
71
72 std::vector<T> Values() const
73 {
74 std::vector<T> out;
75 for (const auto& pair : m_Dense)
76 {
77 out.push_back(pair.data);
78 }
79 return out;
80 }
81
82 std::vector<Index> Keys() const
83 {
84 std::vector<Index> out;
85 for (const auto& pair : m_Dense)
86 {
87 out.push_back(pair.id);
88 }
89 return out;
90 }
91
92 void Clear()
93 {
94 m_Sparse.clear();
95 m_Dense.clear();
96 }
97
98 [[nodiscard]] size_t Size() const
99 {
100 return m_Dense.size();
101 }
102 [[nodiscard]] bool Empty() const
103 {
104 return m_Dense.empty();
105 }
106
107 struct Entry
108 {
109 Index id;
110 T data;
111 };
112
113 auto begin()
114 {
115 return m_Dense.begin();
116 }
117 auto end()
118 {
119 return m_Dense.end();
120 }
121 auto begin() const
122 {
123 return m_Dense.begin();
124 }
125 auto end() const
126 {
127 return m_Dense.end();
128 }
129
130 private:
131 std::vector<Index> m_Sparse;
132 std::vector<Entry> m_Dense;
133 };
134} // namespace PixelBullet
Definition SparseSet.hpp:12
Definition SparseSet.hpp:108