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