sead
Loading...
Searching...
No Matches
seadTreeMap.h
Go to the documentation of this file.
1#pragma once
2
3#include <basis/seadNew.h>
4#include <container/seadFreeList.h>
5#include <container/seadTreeMapImpl.h>
6#include <prim/seadDelegate.h>
7
8namespace sead {
9
10template <typename Key>
12{
14 : key()
15 {
16 }
17
18 TreeMapKeyImpl(const Key& akey)
19 : key(akey)
20 {
21 }
22
23 TreeMapKeyImpl& operator=(const Key& akey)
24 {
25 key = akey;
26 return *this;
27 }
28
29 s32 compare(const TreeMapKeyImpl& rhs) const
30 {
31 if (key < rhs.key)
32 {
33 return -1;
34 }
35
36 if (rhs.key < key)
37 {
38 return 1;
39 }
40
41 return 0;
42 }
43
44 Key key;
45};
46
47template <typename Key, typename Value>
49{
50public:
51 class Node : public TreeMapNode<TreeMapKeyImpl<Key>>
52 {
53 public:
54 Node(const Key& akey, TreeMap* map)
56 , mValue()
57 , mMap(map)
58 {
59 this->mKey_ = akey;
60 }
61
62 Node(const Key& akey, const Value& avalue, TreeMap* map)
64 , mValue(avalue)
65 , mMap(map)
66 {
67 this->mKey_ = akey;
68 }
69
70 protected:
71 void erase_() override
72 {
73 mValue.~Value();
74
76 }
77
78 public:
79 Key& key()
80 {
81 return this->mKey_.key;
82 }
83
84 Value& value()
85 {
86 return mValue;
87 }
88
89 protected:
90 Value mValue;
92 };
93
94 template <typename T>
96 {
97 ForEachConstContext(const T& afun)
98 : fun(afun)
99 {
100 }
101
103 {
104 Node* node = static_cast<Node*>(n);
105 fun(node->key(), node->value());
106 }
107
108 private:
109 const T& fun;
110 };
111
112public:
116 , mSize(0)
117 , mNodeMax(0)
118 {
119 }
120
121 void allocBuffer(s32 node_max, s32 alignment = cDefaultAlignment)
122 {
123 if (!tryAllocBuffer(node_max, alignment))
124 {
125 SEAD_ASSERT_MSG(false, "node_max[%d] must be larger than zero", node_max);
126 }
127 }
128
129 void allocBuffer(s32 node_max, Heap* heap, s32 alignment = cDefaultAlignment)
130 {
131 if (!tryAllocBuffer(node_max, heap, alignment))
132 {
133 SEAD_ASSERT_MSG(false, "node_max[%d] must be larger than zero", node_max);
134 }
135 }
136
137 bool tryAllocBuffer(s32 node_max, s32 alignment = cDefaultAlignment)
138 {
139 SEAD_ASSERT(mFreeList.work() == nullptr);
140
141 if (node_max <= 0)
142 {
143 SEAD_ASSERT_MSG(false, "node_max[%d] must be larger than zero", node_max);
144 return false;
145 }
146
147 void* buf = new (nullptr, alignment) u8[node_max * sizeof(Node)];
148 if (!buf)
149 {
150 return false;
151 }
152
153 setBuffer(node_max, buf);
154 return true;
155 }
156
157 bool tryAllocBuffer(s32 node_max, Heap* heap, s32 alignment = cDefaultAlignment)
158 {
159 SEAD_ASSERT(mFreeList.work() == nullptr);
160
161 if (node_max <= 0)
162 {
163 SEAD_ASSERT_MSG(false, "node_max[%d] must be larger than zero", node_max);
164 return false;
165 }
166
167 void* buf = new(heap, alignment) u8[node_max * sizeof(Node)];
168 if (!buf)
169 {
170 return false;
171 }
172
173 setBuffer(node_max, buf);
174 return true;
175 }
176
178 {
179 if (isBufferReady())
180 {
181 clear();
182
183 delete[] static_cast<u8*>(mFreeList.work()); // DeleteArray<u8>(mFreeList.work())
184
185 mNodeMax = 0;
187 }
188 }
189
190 void setBuffer(s32 node_max, void* buf)
191 {
192 if (node_max <= 0)
193 {
194 SEAD_ASSERT_MSG(false, "node_max[%d] must be larger than zero", node_max);
195 return;
196 }
197
198 if (!buf)
199 {
200 SEAD_ASSERT_MSG(false, "buf is null");
201 return;
202 }
203
204 mNodeMax = node_max;
205 mFreeList.init(buf, sizeof(Node), node_max);
206 }
207
208 bool isBufferReady() const { return mFreeList.work() != nullptr; }
209 bool isEmpty() const { return mSize == 0; }
210 bool isFull() const { return mSize >= mNodeMax; }
211
212 s32 size() const { return mSize; }
213 s32 getSize() const { return mSize; }
214 s32 maxSize() const { return mNodeMax; }
215
216 Value* find(const Key& key) const
217 {
218 Node* node = static_cast<Node*>(TreeMapImpl<TreeMapKeyImpl<Key>>::find(key));
219 if (!node)
220 {
221 return nullptr;
222 }
223
224 return &node->value();
225 }
226
227 bool contains(const Key& key) const
228 {
229 return find(key) != nullptr;
230 }
231
232 Value* insert(const Key& key)
233 {
234 if (isFull())
235 {
236 Value* insertedValue = find(key);
237 if (!insertedValue)
238 {
239 SEAD_ASSERT_MSG(false, "map is full.");
240 return nullptr;
241 }
242
243 insertedValue->~Value();
244 new(insertedValue) Value();
245
246 return insertedValue;
247 }
248
249 Node* node = new(mFreeList.get()) Node(key, this);
250 mSize++;
251 TreeMapImpl<TreeMapKeyImpl<Key>>::insert(node);
252
253 return &node->value();
254 }
255
256 Value* insert(const Key& key, const Value& value)
257 {
258 if (isFull())
259 {
260 Value* insertedValue = find(key);
261 if (!insertedValue)
262 {
263 SEAD_ASSERT_MSG(false, "map is full.");
264 return nullptr;
265 }
266
267 insertedValue->~Value();
268 new(insertedValue) Value(value);
269
270 return insertedValue;
271 }
272
273 Node* node = new(mFreeList.get()) Node(key, value, this);
274 mSize++;
275 TreeMapImpl<TreeMapKeyImpl<Key>>::insert(node);
276
277 return &node->value();
278 }
279
280 void clear()
281 {
282 TreeMapImpl<TreeMapKeyImpl<Key>>::forEach(
283 DelegateCreator<TreeMap, TreeMapNode<TreeMapKeyImpl<Key>>*>(
284 this,
286 )
287 );
288
289 mSize = 0;
290 this->mRoot = nullptr;
291 }
292
293 template <typename T>
294 void forEach(const T& fun) const
295 {
296 ForEachConstContext<T> context(fun);
297
298 TreeMapImpl<TreeMapKeyImpl<Key>>::forEach(
299 DelegateCreator<ForEachConstContext<T>, TreeMapNode<TreeMapKeyImpl<Key>>*>(
300 &context,
301 &ForEachConstContext<T>::call
302 )
303 );
304 }
305
306protected:
307 void eraseNode_(Node* node)
308 {
309 mFreeList.put(node);
310 mSize--;
311 }
312
314 {
315 Node* node = static_cast<Node*>(n);
316 node->value().~Value();
317
318 mFreeList.put(node);
319 }
320
321protected:
325};
326
327template <typename Key, typename Value, s32 N>
328class FixedTreeMap : public TreeMap<Key, Value>
329{
330public:
332 : TreeMap<Key, Value>()
333 {
334 TreeMap<Key, Value>::setBuffer(N, mWork);
335 }
336
337 void allocBuffer(s32 node_max, s32 alignment = cDefaultAlignment) = delete;
338 void allocBuffer(s32 node_max, Heap* heap, s32 alignment = cDefaultAlignment) = delete;
339 bool tryAllocBuffer(s32 node_max, s32 alignment = cDefaultAlignment) = delete;
340 bool tryAllocBuffer(s32 node_max, Heap* heap, s32 alignment = cDefaultAlignment) = delete;
341 void freeBuffer() = delete;
342 void setBuffer(s32 node_max, void* buf) = delete;
343
344protected:
345 u8 mWork[N * sizeof(typename TreeMap<Key, Value>::Node)];
346};
347
348} // namespace sead
Definition seadTreeMap.h:329
void setBuffer(s32 node_max, void *buf)=delete
void allocBuffer(s32 node_max, s32 alignment=cDefaultAlignment)=delete
bool tryAllocBuffer(s32 node_max, Heap *heap, s32 alignment=cDefaultAlignment)=delete
u8 mWork[N *sizeof(typename TreeMap< Key, Value >::Node)]
Definition seadTreeMap.h:345
bool tryAllocBuffer(s32 node_max, s32 alignment=cDefaultAlignment)=delete
FixedTreeMap()
Definition seadTreeMap.h:331
void freeBuffer()=delete
void allocBuffer(s32 node_max, Heap *heap, s32 alignment=cDefaultAlignment)=delete
Definition seadFreeList.h:10
void put(void *ptr)
Definition seadFreeList.h:54
FreeList()
Definition seadFreeList.h:12
void * work() const
Definition seadFreeList.h:52
void * get()
Definition seadFreeList.h:36
void cleanup()
Definition seadFreeList.h:46
Definition seadHeap.h:23
Definition seadTreeMapImpl.h:36
Definition seadTreeMapImpl.h:10
Definition seadTreeMap.h:52
Value & value()
Definition seadTreeMap.h:84
Node(const Key &akey, TreeMap *map)
Definition seadTreeMap.h:54
TreeMap * mMap
Definition seadTreeMap.h:91
void erase_() override
Definition seadTreeMap.h:71
Key & key()
Definition seadTreeMap.h:79
Node(const Key &akey, const Value &avalue, TreeMap *map)
Definition seadTreeMap.h:62
Value mValue
Definition seadTreeMap.h:90
Definition seadTreeMap.h:49
s32 mNodeMax
Definition seadTreeMap.h:324
void eraseNodeForClear_(TreeMapNode< TreeMapKeyImpl< Key > > *n)
Definition seadTreeMap.h:313
s32 maxSize() const
Definition seadTreeMap.h:214
bool tryAllocBuffer(s32 node_max, Heap *heap, s32 alignment=cDefaultAlignment)
Definition seadTreeMap.h:157
Value * insert(const Key &key, const Value &value)
Definition seadTreeMap.h:256
s32 mSize
Definition seadTreeMap.h:323
void forEach(const T &fun) const
Definition seadTreeMap.h:294
void allocBuffer(s32 node_max, s32 alignment=cDefaultAlignment)
Definition seadTreeMap.h:121
Value * insert(const Key &key)
Definition seadTreeMap.h:232
FreeList mFreeList
Definition seadTreeMap.h:322
void freeBuffer()
Definition seadTreeMap.h:177
bool isFull() const
Definition seadTreeMap.h:210
void allocBuffer(s32 node_max, Heap *heap, s32 alignment=cDefaultAlignment)
Definition seadTreeMap.h:129
void clear()
Definition seadTreeMap.h:280
bool contains(const Key &key) const
Definition seadTreeMap.h:227
bool tryAllocBuffer(s32 node_max, s32 alignment=cDefaultAlignment)
Definition seadTreeMap.h:137
bool isEmpty() const
Definition seadTreeMap.h:209
s32 size() const
Definition seadTreeMap.h:212
s32 getSize() const
Definition seadTreeMap.h:213
Value * find(const Key &key) const
Definition seadTreeMap.h:216
void eraseNode_(Node *node)
Definition seadTreeMap.h:307
void setBuffer(s32 node_max, void *buf)
Definition seadTreeMap.h:190
TreeMap()
Definition seadTreeMap.h:113
bool isBufferReady() const
Definition seadTreeMap.h:208
Definition seadAssert.h:44
#define SEAD_ASSERT(condition)
Definition seadAssert.h:24
#define SEAD_ASSERT_MSG(condition, format,...)
Definition seadAssert.h:33
Definition seadTreeMap.h:12
s32 compare(const TreeMapKeyImpl &rhs) const
Definition seadTreeMap.h:29
TreeMapKeyImpl()
Definition seadTreeMap.h:13
Key key
Definition seadTreeMap.h:44
TreeMapKeyImpl & operator=(const Key &akey)
Definition seadTreeMap.h:23
TreeMapKeyImpl(const Key &akey)
Definition seadTreeMap.h:18
Definition seadTreeMap.h:96
void call(TreeMapNode< TreeMapKeyImpl< Key > > *n)
Definition seadTreeMap.h:102
const T & fun
Definition seadTreeMap.h:109
ForEachConstContext(const T &afun)
Definition seadTreeMap.h:97