CommonLibSSE NG
Loading...
Searching...
No Matches
BSTList.h
Go to the documentation of this file.
1#pragma once
2
4
5namespace RE
6{
7 // forward list
8 template <class T>
10 {
11 public:
12 using value_type = T;
13 using size_type = std::uint32_t;
16
17 struct Node
18 {
19 public:
20 inline Node() :
21 item{},
22 next(nullptr)
23 {}
24
25 inline Node(value_type a_value, Node* a_next) :
26 item(a_value),
27 next(a_next)
28 {}
29
30 inline Node(const Node& a_rhs) :
31 item(a_rhs.item),
32 next(a_rhs.next)
33 {}
34
35 inline Node(Node&& a_rhs) :
36 item(std::move(a_rhs.item)),
37 next(std::move(a_rhs.next))
38 {
39 a_rhs.next = nullptr;
40 }
41
42 inline Node(const value_type& a_value) :
43 item(a_value),
44 next(nullptr)
45 {}
46
47 inline Node(value_type&& a_value) :
48 item(std::move(a_value)),
49 next(nullptr)
50 {}
51
52 ~Node() = default;
53
54 inline Node& operator=(const Node& a_rhs)
55 {
56 if (this != std::addressof(a_rhs)) {
57 item = a_rhs.item;
58 next = a_rhs.next;
59 }
60 return *this;
61 }
62
63 inline Node& operator=(Node&& a_rhs)
64 {
65 if (this != std::addressof(a_rhs)) {
66 item = std::move(a_rhs.item);
67
68 next = std::move(a_rhs.next);
69 a_rhs.next = nullptr;
70 }
71 return *this;
72 }
73
75
76 // members
79 };
80
81 template <class U>
83 {
84 public:
85 using difference_type = std::ptrdiff_t;
86 using value_type = U;
87 using pointer = U*;
88 using reference = U&;
89 using iterator_category = std::forward_iterator_tag;
90
91 constexpr iterator_base() noexcept :
92 _cur(nullptr)
93 {}
94
95 constexpr iterator_base(const iterator_base& a_rhs) noexcept :
96 _cur(a_rhs._cur)
97 {}
98
99 constexpr iterator_base(iterator_base&& a_rhs) noexcept :
100 _cur(std::move(a_rhs._cur))
101 {
102 a_rhs._cur = nullptr;
103 }
104
105 constexpr iterator_base(Node* a_node) noexcept :
106 _cur(a_node)
107 {}
108
109 inline ~iterator_base() noexcept { _cur = nullptr; }
110
111 constexpr iterator_base& operator=(const iterator_base& a_rhs) noexcept
112 {
113 if (this != std::addressof(a_rhs)) {
114 _cur = a_rhs._cur;
115 }
116 return *this;
117 }
118
119 constexpr iterator_base& operator=(iterator_base&& a_rhs) noexcept
120 {
121 if (this != std::addressof(a_rhs)) {
122 _cur = std::move(a_rhs._cur);
123 a_rhs._cur = nullptr;
124 }
125 return *this;
126 }
127
128 [[nodiscard]] constexpr reference operator*() const noexcept { return _cur->item; }
129 [[nodiscard]] constexpr pointer operator->() const noexcept { return std::addressof(_cur->item); }
130
131 [[nodiscard]] constexpr bool operator==(const iterator_base& a_rhs) const noexcept { return _cur == a_rhs._cur; }
132 [[nodiscard]] constexpr bool operator!=(const iterator_base& a_rhs) const noexcept { return !(*this == a_rhs); }
133
134 // prefix
135 constexpr iterator_base& operator++() noexcept
136 {
137 assert(_cur);
138 _cur = _cur->next;
139 return *this;
140 }
141
142 // postfix
143 [[nodiscard]] constexpr iterator_base operator++(int) noexcept
144 {
145 iterator_base tmp(*this);
146 ++(*this);
147 return tmp;
148 }
149
150 protected:
151 friend class BSSimpleList<T>;
152
153 [[nodiscard]] constexpr Node* get_current() noexcept { return _cur; }
154 [[nodiscard]] constexpr const Node* get_current() const noexcept { return _cur; }
155
156 [[nodiscard]] constexpr bool comes_before(const iterator_base& a_rhs) const noexcept
157 {
158 for (auto iter = _cur; iter; iter = iter->next) {
159 if (iter == a_rhs._cur) {
160 return true;
161 }
162 }
163 return false;
164 }
165
166 private:
168 };
169
172
173 inline BSSimpleList() :
174 _listHead()
175 {}
176
177 inline BSSimpleList(const BSSimpleList& a_rhs) :
178 _listHead()
179 {
180 copy_from(a_rhs);
181 }
182
183 inline BSSimpleList(BSSimpleList&& a_rhs) :
184 _listHead(std::move(a_rhs._listHead))
185 {}
186
188 {
189 clear();
190 }
191
192 inline BSSimpleList& operator=(const BSSimpleList& a_rhs)
193 {
194 if (this != std::addressof(a_rhs)) {
195 clear();
196 copy_from(a_rhs);
197 }
198 return *this;
199 }
200
202 {
203 if (this != std::addressof(a_rhs)) {
204 clear();
205 _listHead = std::move(a_rhs._listHead);
206 }
207 return *this;
208 }
209
211
212 [[nodiscard]] inline reference front()
213 {
214 assert(!empty());
215 return *begin();
216 }
217
218 [[nodiscard]] inline const_reference front() const
219 {
220 assert(!empty());
221 return *begin();
222 }
223
224 [[nodiscard]] inline iterator begin() { return empty() ? end() : iterator(get_head()); }
225 [[nodiscard]] inline const_iterator begin() const { return empty() ? end() : const_iterator(get_head()); }
226 [[nodiscard]] inline const_iterator cbegin() const { return begin(); }
227
228 [[nodiscard]] constexpr iterator end() noexcept { return iterator(nullptr); }
229 [[nodiscard]] constexpr const_iterator end() const noexcept { return const_iterator(nullptr); }
230 [[nodiscard]] constexpr const_iterator cend() const noexcept { return end(); }
231
232 [[nodiscard]] inline bool empty() const { return !_listHead.next && !_listHead.item; }
233
234 inline void clear()
235 {
236 erase_after_impl(get_head(), nullptr);
237 if (static_cast<bool>(_listHead.item)) {
238 std::destroy_at(std::addressof(_listHead.item));
239 }
240 }
241
243 {
244 auto node = new Node(a_value);
245 return insert_after_impl(
246 a_pos.get_current(),
247 std::make_pair(node, node));
248 }
249
250 inline iterator insert_after(iterator a_pos, value_type&& a_value)
251 {
252 auto node = new Node(std::move(a_value));
253 return insert_after_impl(
254 a_pos.get_current(),
255 std::make_pair(node, node));
256 }
257
259 {
260 auto node = new Node(a_value);
261 return insert_after_impl(
262 a_pos.get_current(),
263 std::make_pair(node, node));
264 }
265
267 {
268 auto node = new Node(std::move(a_value));
269 return insert_after_impl(
270 a_pos.get_current(),
271 std::make_pair(node, node));
272 }
273
275 {
276 if (a_count <= 0) {
277 return a_pos;
278 }
279
280 return insert_after_impl(
281 a_pos.get_current(),
282 alloc_copies(a_count, a_value));
283 }
284
286 {
287 if (a_pos == cend()) {
288 return end();
289 }
290
291 auto node = a_pos.get_current();
292 erase_after_impl(node, node->next);
293 return node->next;
294 }
295
297 {
298 assert(a_first.comes_before(a_last));
299
300 auto head = a_first.get_current();
301 auto tail = a_last.get_current();
302
303 erase_after_impl(head, tail);
304 return tail;
305 }
306
307 inline void push_front(const_reference a_value) { emplace_front_impl(a_value); }
308 inline void push_front(value_type&& a_value) { emplace_front_impl(std::move(a_value)); }
309
310 template <class... Args>
311 inline reference emplace_front(Args&&... a_args)
312 {
313 emplace_front_impl(std::forward<Args>(a_args)...);
314 return front();
315 }
316
317 inline void pop_front()
318 {
319 assert(!empty());
320
321 std::destroy_at(std::addressof(_listHead.item));
322 auto node = _listHead.next;
323 if (node) {
324 _listHead.next = node->next;
325 std::construct_at(std::addressof(_listHead.item), std::move(node->item));
326 delete node;
327 }
328 }
329
330 inline void resize(size_type a_count) { resize(a_count, value_type{}); }
331 inline void resize(size_type a_count, const value_type& a_value) { resize_impl(a_count, a_value); }
332
333 protected:
334 [[nodiscard]] constexpr Node* get_head() noexcept { return std::addressof(_listHead); }
335 [[nodiscard]] constexpr const Node* get_head() const noexcept { return std::addressof(_listHead); }
336
337 [[nodiscard]] inline std::pair<Node*, Node*> alloc_copies(size_type a_count, const_reference a_value)
338 {
339 assert(a_count > 0);
340
341 auto head = new Node(a_value);
342 auto tail = head;
343 for (size_type i = 1; i < a_count; ++i) {
344 tail->next = new Node(a_value);
345 tail = tail->next;
346 }
347
348 return std::make_pair(head, tail);
349 }
350
351 inline void copy_from(const BSSimpleList& a_rhs)
352 {
353 auto lhs = get_head();
354 auto rhs = a_rhs.get_head();
355
356 lhs->item = rhs->item;
357 while (rhs->next) {
358 rhs = rhs->next;
359 lhs->next = new Node(rhs->item);
360 lhs = lhs->next;
361 }
362 }
363
364 [[nodiscard]] inline Node* insert_after_impl(Node* a_pos, std::pair<Node*, Node*> a_values)
365 {
366 auto [head, tail] = a_values;
367
368 assert(a_pos);
369 assert(head && tail);
370
371 tail->next = a_pos->next;
372 a_pos->next = head;
373 return tail;
374 }
375
376 inline void erase_after_impl(Node* a_head, Node* a_tail)
377 {
378 if (a_head && a_head != a_tail) {
379 auto iter = a_head->next;
380 auto tmp = iter;
381 while (iter != a_tail) {
382 tmp = iter;
383 iter = iter->next;
384 delete tmp;
385 }
386 a_head->next = a_tail;
387 }
388 }
389
390 template <class... Args>
391 inline void emplace_front_impl(Args&&... a_args)
392 {
393 if (static_cast<bool>(_listHead.item)) {
394 auto node = new Node(std::move(_listHead));
395 _listHead.next = node;
396 }
397
398 std::destroy_at(std::addressof(_listHead.item));
399 std::construct_at(std::addressof(_listHead.item), std::forward<Args>(a_args)...);
400 }
401
402 inline void resize_impl(size_type a_count, const_reference a_value)
403 {
404 if (a_count <= 0) {
405 clear();
406 }
407
408 auto iter = begin();
409 auto last = end();
410 size_type elems = 1;
411 while (iter != last && elems != a_count) {
412 ++iter;
413 ++elems;
414 }
415
416 if (elems < a_count) {
417 // need to grow
418 insert_after(iter, a_count - elems, a_value);
419 } else if (iter != last) {
420 // need to shrink
421 erase_after(iter, last);
422 } else {
423 // already required size
424 }
425 }
426
427 // members
429
430 // T _item; // 00
431 // BSSimpleList<T>* _next; // ??
432 };
433}
Definition BSTList.h:83
constexpr bool operator==(const iterator_base &a_rhs) const noexcept
Definition BSTList.h:131
constexpr reference operator*() const noexcept
Definition BSTList.h:128
constexpr iterator_base(const iterator_base &a_rhs) noexcept
Definition BSTList.h:95
constexpr Node * get_current() noexcept
Definition BSTList.h:153
constexpr bool operator!=(const iterator_base &a_rhs) const noexcept
Definition BSTList.h:132
constexpr iterator_base & operator=(iterator_base &&a_rhs) noexcept
Definition BSTList.h:119
constexpr const Node * get_current() const noexcept
Definition BSTList.h:154
constexpr iterator_base & operator=(const iterator_base &a_rhs) noexcept
Definition BSTList.h:111
constexpr iterator_base(Node *a_node) noexcept
Definition BSTList.h:105
constexpr iterator_base() noexcept
Definition BSTList.h:91
std::forward_iterator_tag iterator_category
Definition BSTList.h:89
~iterator_base() noexcept
Definition BSTList.h:109
constexpr iterator_base(iterator_base &&a_rhs) noexcept
Definition BSTList.h:99
U value_type
Definition BSTList.h:86
U & reference
Definition BSTList.h:88
constexpr iterator_base & operator++() noexcept
Definition BSTList.h:135
std::ptrdiff_t difference_type
Definition BSTList.h:85
constexpr bool comes_before(const iterator_base &a_rhs) const noexcept
Definition BSTList.h:156
U * pointer
Definition BSTList.h:87
constexpr pointer operator->() const noexcept
Definition BSTList.h:129
Definition BSTList.h:10
constexpr const_iterator cend() const noexcept
Definition BSTList.h:230
const value_type & const_reference
Definition BSTList.h:15
constexpr const Node * get_head() const noexcept
Definition BSTList.h:335
constexpr const_iterator end() const noexcept
Definition BSTList.h:229
iterator insert_after(iterator a_pos, const_reference a_value)
Definition BSTList.h:242
reference front()
Definition BSTList.h:212
void resize(size_type a_count, const value_type &a_value)
Definition BSTList.h:331
const_iterator cbegin() const
Definition BSTList.h:226
BSSimpleList & operator=(const BSSimpleList &a_rhs)
Definition BSTList.h:192
T value_type
Definition BSTList.h:12
void push_front(value_type &&a_value)
Definition BSTList.h:308
void resize(size_type a_count)
Definition BSTList.h:330
BSSimpleList(BSSimpleList &&a_rhs)
Definition BSTList.h:183
iterator insert_after(const_iterator a_pos, const_reference a_value)
Definition BSTList.h:258
BSSimpleList & operator=(BSSimpleList &&a_rhs)
Definition BSTList.h:201
iterator insert_after(const_iterator a_pos, size_type a_count, const_reference a_value)
Definition BSTList.h:274
iterator erase_after(const_iterator a_pos)
Definition BSTList.h:285
reference emplace_front(Args &&... a_args)
Definition BSTList.h:311
~BSSimpleList()
Definition BSTList.h:187
iterator begin()
Definition BSTList.h:224
iterator_base< const value_type > const_iterator
Definition BSTList.h:171
void emplace_front_impl(Args &&... a_args)
Definition BSTList.h:391
iterator erase_after(const_iterator a_first, const_iterator a_last)
Definition BSTList.h:296
const_iterator begin() const
Definition BSTList.h:225
constexpr Node * get_head() noexcept
Definition BSTList.h:334
iterator insert_after(iterator a_pos, value_type &&a_value)
Definition BSTList.h:250
void copy_from(const BSSimpleList &a_rhs)
Definition BSTList.h:351
std::uint32_t size_type
Definition BSTList.h:13
BSSimpleList(const BSSimpleList &a_rhs)
Definition BSTList.h:177
constexpr iterator end() noexcept
Definition BSTList.h:228
void erase_after_impl(Node *a_head, Node *a_tail)
Definition BSTList.h:376
const_reference front() const
Definition BSTList.h:218
iterator_base< value_type > iterator
Definition BSTList.h:170
iterator insert_after(const_iterator a_pos, value_type &&a_value)
Definition BSTList.h:266
value_type & reference
Definition BSTList.h:14
void push_front(const_reference a_value)
Definition BSTList.h:307
Node _listHead
Definition BSTList.h:428
void clear()
Definition BSTList.h:234
std::pair< Node *, Node * > alloc_copies(size_type a_count, const_reference a_value)
Definition BSTList.h:337
BSSimpleList()
Definition BSTList.h:173
bool empty() const
Definition BSTList.h:232
void pop_front()
Definition BSTList.h:317
Node * insert_after_impl(Node *a_pos, std::pair< Node *, Node * > a_values)
Definition BSTList.h:364
void resize_impl(size_type a_count, const_reference a_value)
Definition BSTList.h:402
Definition AbsorbEffect.h:6
T observer
Definition PCH.h:93
Definition ActorValueList.h:28
Definition BSTList.h:18
Node()
Definition BSTList.h:20
stl::observer< Node * > next
Definition BSTList.h:78
Node(const Node &a_rhs)
Definition BSTList.h:30
Node(value_type &&a_value)
Definition BSTList.h:47
Node(value_type a_value, Node *a_next)
Definition BSTList.h:25
value_type item
Definition BSTList.h:77
Node(const value_type &a_value)
Definition BSTList.h:42
Node & operator=(Node &&a_rhs)
Definition BSTList.h:63
Node(Node &&a_rhs)
Definition BSTList.h:35
Node & operator=(const Node &a_rhs)
Definition BSTList.h:54