CommonLibSSE (Parapets fork)
Loading...
Searching...
No Matches
NiTMapBase.h
Go to the documentation of this file.
1#pragma once
2
4
5namespace RE
6{
7 template <class Key, class T>
9 {
10 public:
11 using key_type = Key;
12 using mapped_type = T;
13
14 // members
18 };
19 static_assert(sizeof(NiTMapItem<std::uint32_t, std::uint64_t>) == 0x18);
20
21 // hash table with separate chaining
22 template <class Allocator, class Key, class T>
24 {
25 private:
26 template <class U>
27 friend class iterator_base;
28
29 public:
30 using key_type = Key;
31 using mapped_type = T;
33 using size_type = std::uint32_t;
34
35 template <class U>
37 {
38 public:
39 using difference_type = std::ptrdiff_t;
40 using value_type = U;
41 using pointer = U*;
42 using reference = U&;
43 using iterator_category = std::forward_iterator_tag;
44
46 _proxy(0),
47 _iter(0),
48 _idx(0)
49 {}
50
52 _proxy(a_rhs._proxy),
53 _iter(a_rhs._iter),
54 _idx(a_rhs._idx)
55 {}
56
58 _proxy(a_rhs._proxy),
59 _iter(std::move(a_rhs._iter)),
60 _idx(std::move(a_rhs._idx))
61 {
62 assert(_proxy);
63 a_rhs._iter = nullptr;
64 a_rhs._idx = a_rhs._proxy->_capacity;
65 }
66
67 iterator_base(NiTMapBase* a_proxy, std::uint32_t a_idx) :
68 _proxy(a_proxy),
69 _iter(nullptr),
70 _idx(a_idx)
71 {
72 assert(_proxy);
73 _iter = _proxy->_data[_idx];
74 while (!_iter && _idx < _proxy->_capacity) {
75 ++_idx;
76 _iter = _proxy->_data[_idx];
77 }
78 }
79
80 iterator_base(NiTMapBase* a_proxy, value_type* a_iter, std::uint32_t a_idx) :
81 _proxy(a_proxy),
82 _iter(a_iter),
83 _idx(a_idx)
84 {
85 assert(_proxy);
86 assert(_iter);
87 }
88
90 {}
91
93 {
94 assert(_proxy == a_rhs._proxy);
95 _iter = a_rhs._iter;
96 _idx = a_rhs._idx;
97 }
98
100 {
101 assert(_proxy == a_rhs._proxy);
102
103 _iter = std::move(a_rhs._iter);
104 a_rhs._iter = 0;
105
106 _idx = std::move(a_rhs._idx);
107 a_rhs._idx = a_rhs._proxy->_capacity;
108 }
109
110 void swap(iterator_base& a_rhs)
111 {
112 assert(_proxy == a_rhs._proxy);
113 std::swap(_iter, a_rhs._iter);
114 std::swap(_idx, a_rhs._idx);
115 }
116
117 [[nodiscard]] reference operator*() const
118 {
119 assert(_iter);
120 assert(_idx < _proxy->_capacity);
121 return *_iter;
122 }
123
124 [[nodiscard]] pointer operator->() const
125 {
126 assert(_iter);
127 assert(_idx < _proxy->_capacity);
128 return _iter;
129 }
130
131 [[nodiscard]] bool operator==(const iterator_base& a_rhs) const
132 {
133 assert(_proxy == a_rhs._proxy);
134
135 if (_idx != a_rhs._idx) {
136 return false;
137 }
138
139 if (_idx < _proxy->_capacity) {
140 return _iter == a_rhs._iter;
141 }
142
143 return true;
144 }
145
146 [[nodiscard]] bool operator!=(const iterator_base& a_rhs) const
147 {
148 return !operator==(a_rhs);
149 }
150
151 // prefix
153 {
154 assert(_proxy);
155 assert(_iter);
156 assert(_idx < _proxy->_capacity);
157
158 if (_iter->next) {
159 _iter = _iter->next;
160 } else {
161 do {
162 ++_idx;
163 _iter = _proxy->_data[_idx];
164 } while (!_iter && _idx < _proxy->_capacity);
165 }
166
167 return *this;
168 }
169
170 // postfix
172 {
173 iterator_base tmp(*this);
174 operator++();
175 return tmp;
176 }
177
178 private:
179 NiTMapBase* _proxy;
180 value_type* _iter;
181 std::uint32_t _idx;
182 };
183
186
187 struct AntiBloatAllocator : public Allocator
188 {
190 Allocator(),
191 size(0)
192 {}
193
194 // members
196 };
197
198 NiTMapBase(size_type a_capacity = 37) :
199 _capacity(a_capacity),
200 _pad0C(0),
201 _data(0),
202 _allocator()
203 {
204 std::size_t memSize = sizeof(value_type*) * _capacity;
205 _data = malloc<value_type*>(memSize);
206 std::memset(_data, 0, memSize);
207 }
208
209 virtual ~NiTMapBase() // 00
210 {
211 clear();
212 if (_data) {
213 free(_data);
214 _data = nullptr;
215 }
216 _capacity = 0;
217 }
218
219 protected:
220 virtual std::uint32_t hash_function(key_type a_key) const; // 01 - { return a_key % _capacity; }
221 virtual bool key_eq(key_type a_lhs, key_type a_rhs) const; // 02 - { return stricmp(a_lhs == a_rhs); }
222 virtual void assign_value(value_type* a_value, key_type a_key, mapped_type a_mapped); // 03 - { a_value->key = a_key; a_value->mapped = a_mapped; }
223 virtual void clear_value(value_type* a_value); // 04 - { return; }
224 virtual value_type* malloc_value() = 0; // 05
225 virtual void free_value(value_type* a_value) = 0; // 06
226
227 public:
229 {
230 return iterator(this, 0);
231 }
232
234 {
235 return const_iterator(this, 0);
236 }
237
239 {
240 return const_iterator(this, 0);
241 }
242
244 {
245 return iterator(this, _capacity);
246 }
247
249 {
250 return const_iterator(this, _capacity);
251 }
252
254 {
255 return const_iterator(this, _capacity);
256 }
257
258 [[nodiscard]] bool empty() const noexcept
259 {
260 return _allocator.size == 0;
261 }
262
263 [[nodiscard]] size_type size() const noexcept
264 {
265 return _allocator.size;
266 }
267
268 void clear()
269 {
270 for (std::uint32_t i = 0; i < _capacity; i++) {
271 while (_data[i]) {
272 auto elem = _data[i];
273 _data[i] = _data[i]->next;
274 clear_value(elem);
275 free_value(elem);
276 }
277 }
278
279 _allocator.size = 0;
280 }
281
282 template <class M>
283 bool insert_or_assign(key_type&& a_key, M&& a_obj)
284 {
285 // look up hash table location for key
286 auto index = hash_function(a_key);
287 auto item = _data[index];
288
289 // search list at hash table location for key
290 while (item) {
291 if (key_eq(a_key, item->key)) {
292 // item already in hash table, set its new value
293 item->val = std::forward<M>(a_obj);
294 return false;
295 }
296 item = item->next;
297 }
298
299 // add object to beginning of list for this hash table index
300 item = malloc_value();
301
302 assert(item != 0);
303 assign_value(item, std::move(a_key), std::forward<M>(a_obj));
304 item->next = _data[index];
305 _data[index] = item;
307 return true;
308 }
309
311 {
312 // look up hash table location for key
313 auto index = hash_function(a_key);
314 auto item = _data[index];
315
316 value_type* prev = 0;
317 while (item) {
318 if (key_eq(a_key, item->key)) {
319 if (prev) {
320 prev->next = item->next;
321 } else {
322 _data[index] = item->next;
323 }
324 remove_value(item);
325 return 1;
326 }
327 prev = item;
328 item = item->next;
329 }
330 return 0;
331 }
332
333 iterator find(const Key& a_key)
334 {
335 auto result = do_find(a_key);
336 return result ? iterator(this, result->first, result->second) : end();
337 }
338
339 const_iterator find(const Key& a_key) const
340 {
341 auto result = do_find(a_key);
342 return result ? const_iterator(this, result->first, result->second) : end();
343 }
344
345 private:
346 inline void remove_value(value_type* a_value)
347 {
348 clear_value(a_value);
349 free_value(a_value);
351 }
352
353 std::optional<std::pair<value_type*, std::uint32_t>> do_find(const Key& a_key) const
354 {
355 size_type idx = hash_function(a_key);
356 for (auto iter = _data[idx]; iter; iter = iter->next) {
357 if (key_eq(a_key, iter->first)) {
358 return std::make_optional(std::make_pair(iter, idx));
359 }
360 }
361
362 return std::nullopt;
363 }
364
365 protected:
366 // members
367 std::uint32_t _capacity; // 08
368 std::uint32_t _pad0C; // 0C
371 };
372}
Definition: NiTMapBase.h:24
iterator_base< value_type > iterator
Definition: NiTMapBase.h:184
std::uint32_t size_type
Definition: NiTMapBase.h:33
std::uint32_t _capacity
Definition: NiTMapBase.h:367
bool insert_or_assign(key_type &&a_key, M &&a_obj)
Definition: NiTMapBase.h:283
const_iterator cend() const
Definition: NiTMapBase.h:253
virtual value_type * malloc_value()=0
virtual std::uint32_t hash_function(key_type a_key) const
T mapped_type
Definition: NiTMapBase.h:31
iterator_base< const value_type > const_iterator
Definition: NiTMapBase.h:185
const_iterator find(const Key &a_key) const
Definition: NiTMapBase.h:339
virtual ~NiTMapBase()
Definition: NiTMapBase.h:209
Key key_type
Definition: NiTMapBase.h:30
virtual void assign_value(value_type *a_value, key_type a_key, mapped_type a_mapped)
virtual void clear_value(value_type *a_value)
const_iterator cbegin() const
Definition: NiTMapBase.h:238
std::uint32_t _pad0C
Definition: NiTMapBase.h:368
size_type size() const noexcept
Definition: NiTMapBase.h:263
NiTMapBase(size_type a_capacity=37)
Definition: NiTMapBase.h:198
value_type ** _data
Definition: NiTMapBase.h:369
size_type erase(const key_type &a_key)
Definition: NiTMapBase.h:310
AntiBloatAllocator _allocator
Definition: NiTMapBase.h:370
iterator begin()
Definition: NiTMapBase.h:228
NiTMapItem< Key, T > value_type
Definition: NiTMapBase.h:32
const_iterator begin() const
Definition: NiTMapBase.h:233
virtual bool key_eq(key_type a_lhs, key_type a_rhs) const
bool empty() const noexcept
Definition: NiTMapBase.h:258
iterator end()
Definition: NiTMapBase.h:243
const_iterator end() const
Definition: NiTMapBase.h:248
void clear()
Definition: NiTMapBase.h:268
iterator find(const Key &a_key)
Definition: NiTMapBase.h:333
virtual void free_value(value_type *a_value)=0
Definition: NiTMapBase.h:9
Key key_type
Definition: NiTMapBase.h:11
key_type first
Definition: NiTMapBase.h:16
mapped_type second
Definition: NiTMapBase.h:17
NiTMapItem * next
Definition: NiTMapBase.h:15
T mapped_type
Definition: NiTMapBase.h:12
Definition: AbsorbEffect.h:6
void free(void *a_ptr)
Definition: MemoryManager.h:183
Definition: NiBinaryStream.h:94
Definition: NiTMapBase.h:188
AntiBloatAllocator()
Definition: NiTMapBase.h:189
size_type size
Definition: NiTMapBase.h:195
Definition: NiTMapBase.h:37
reference operator*() const
Definition: NiTMapBase.h:117
iterator_base()
Definition: NiTMapBase.h:45
iterator_base(iterator_base &&a_rhs)
Definition: NiTMapBase.h:57
iterator_base & operator++()
Definition: NiTMapBase.h:152
iterator_base(NiTMapBase *a_proxy, value_type *a_iter, std::uint32_t a_idx)
Definition: NiTMapBase.h:80
iterator_base & operator=(iterator_base &&a_rhs)
Definition: NiTMapBase.h:99
iterator_base(NiTMapBase *a_proxy, std::uint32_t a_idx)
Definition: NiTMapBase.h:67
pointer operator->() const
Definition: NiTMapBase.h:124
iterator_base(const iterator_base &a_rhs)
Definition: NiTMapBase.h:51
bool operator!=(const iterator_base &a_rhs) const
Definition: NiTMapBase.h:146
U value_type
Definition: NiTMapBase.h:40
iterator_base & operator=(const iterator_base &a_rhs)
Definition: NiTMapBase.h:92
std::ptrdiff_t difference_type
Definition: NiTMapBase.h:39
~iterator_base()
Definition: NiTMapBase.h:89
iterator_base operator++(int)
Definition: NiTMapBase.h:171
void swap(iterator_base &a_rhs)
Definition: NiTMapBase.h:110
U * pointer
Definition: NiTMapBase.h:41
U & reference
Definition: NiTMapBase.h:42
std::forward_iterator_tag iterator_category
Definition: NiTMapBase.h:43
bool operator==(const iterator_base &a_rhs) const
Definition: NiTMapBase.h:131