CommonLibSSE (Parapets fork)
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
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 if (a_count <= 0) {
261 return a_pos;
262 }
263
264 return insert_after_impl(
265 a_pos.get_current(),
266 alloc_copies(a_count, a_value));
267 }
268
270 {
271 if (a_pos == cend()) {
272 return end();
273 }
274
275 auto node = a_pos.get_current();
276 erase_after_impl(node, node->next);
277 return node->next;
278 }
279
281 {
282 assert(a_first.comes_before(a_last));
283
284 auto head = a_first.get_current();
285 auto tail = a_last.get_current();
286
287 erase_after_impl(head, tail);
288 return tail;
289 }
290
291 inline void push_front(const_reference a_value) { emplace_front_impl(a_value); }
292 inline void push_front(value_type&& a_value) { emplace_front_impl(std::move(a_value)); }
293
294 template <class... Args>
295 inline reference emplace_front(Args&&... a_args)
296 {
297 emplace_front_impl(std::forward<Args>(a_args)...);
298 return front();
299 }
300
301 inline void pop_front()
302 {
303 assert(!empty());
304
305 std::destroy_at(std::addressof(_listHead.item));
306 auto node = _listHead.next;
307 if (node) {
308 _listHead.next = node->next;
309 std::construct_at(std::addressof(_listHead.item), std::move(node->item));
310 delete node;
311 }
312 }
313
314 inline void resize(size_type a_count) { resize(a_count, value_type{}); }
315 inline void resize(size_type a_count, const value_type& a_value) { resize_impl(a_count, a_value); }
316
317 protected:
318 [[nodiscard]] constexpr Node* get_head() noexcept { return std::addressof(_listHead); }
319 [[nodiscard]] constexpr const Node* get_head() const noexcept { return std::addressof(_listHead); }
320
321 [[nodiscard]] inline std::pair<Node*, Node*> alloc_copies(size_type a_count, const_reference a_value)
322 {
323 assert(a_count > 0);
324
325 auto head = new Node(a_value);
326 auto tail = head;
327 for (size_type i = 1; i < a_count; ++i) {
328 tail->next = new Node(a_value);
329 tail = tail->next;
330 }
331
332 return std::make_pair(head, tail);
333 }
334
335 inline void copy_from(const BSSimpleList& a_rhs)
336 {
337 auto lhs = get_head();
338 auto rhs = a_rhs.get_head();
339
340 lhs->item = rhs->item;
341 while (rhs->next) {
342 rhs = rhs->next;
343 lhs->next = new Node(rhs->item);
344 lhs = lhs->next;
345 }
346 }
347
348 [[nodiscard]] inline Node* insert_after_impl(Node* a_pos, std::pair<Node*, Node*> a_values)
349 {
350 auto [head, tail] = a_values;
351
352 assert(a_pos);
353 assert(head && tail);
354
355 tail->next = a_pos->next;
356 a_pos->next = head;
357 return tail;
358 }
359
360 inline void erase_after_impl(Node* a_head, Node* a_tail)
361 {
362 if (a_head && a_head != a_tail) {
363 auto iter = a_head->next;
364 auto tmp = iter;
365 while (iter != a_tail) {
366 tmp = iter;
367 iter = iter->next;
368 delete tmp;
369 }
370 a_head->next = a_tail;
371 }
372 }
373
374 template <class... Args>
375 inline void emplace_front_impl(Args&&... a_args)
376 {
377 if (static_cast<bool>(_listHead.item)) {
378 auto node = new Node(std::move(_listHead));
379 _listHead.next = node;
380 }
381
382 std::destroy_at(std::addressof(_listHead.item));
383 std::construct_at(std::addressof(_listHead.item), std::forward<Args>(a_args)...);
384 }
385
386 inline void resize_impl(size_type a_count, const_reference a_value)
387 {
388 if (a_count <= 0) {
389 clear();
390 }
391
392 auto iter = begin();
393 auto last = end();
394 size_type elems = 1;
395 while (iter != last && elems != a_count) {
396 ++iter;
397 ++elems;
398 }
399
400 if (elems < a_count) {
401 // need to grow
402 insert_after(iter, a_count - elems, a_value);
403 } else if (iter != last) {
404 // need to shrink
405 erase_after(iter, last);
406 } else {
407 // already required size
408 }
409 }
410
411 // members
413
414 // T _item; // 00
415 // BSSimpleList<T>* _next; // ??
416 };
417}
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:319
constexpr const_iterator end() const noexcept
Definition: BSTList.h:229
reference front()
Definition: BSTList.h:212
void resize(size_type a_count, const value_type &a_value)
Definition: BSTList.h:315
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:292
void resize(size_type a_count)
Definition: BSTList.h:314
BSSimpleList(BSSimpleList &&a_rhs)
Definition: BSTList.h:183
iterator insert_after(const_iterator a_pos, const_reference a_value)
Definition: BSTList.h:242
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:258
iterator erase_after(const_iterator a_pos)
Definition: BSTList.h:269
reference emplace_front(Args &&... a_args)
Definition: BSTList.h:295
~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:375
iterator erase_after(const_iterator a_first, const_iterator a_last)
Definition: BSTList.h:280
const_iterator begin() const
Definition: BSTList.h:225
constexpr Node * get_head() noexcept
Definition: BSTList.h:318
void copy_from(const BSSimpleList &a_rhs)
Definition: BSTList.h:335
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:360
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:250
value_type & reference
Definition: BSTList.h:14
void push_front(const_reference a_value)
Definition: BSTList.h:291
Node _listHead
Definition: BSTList.h:412
void clear()
Definition: BSTList.h:234
std::pair< Node *, Node * > alloc_copies(size_type a_count, const_reference a_value)
Definition: BSTList.h:321
BSSimpleList()
Definition: BSTList.h:173
bool empty() const
Definition: BSTList.h:232
void pop_front()
Definition: BSTList.h:301
Node * insert_after_impl(Node *a_pos, std::pair< Node *, Node * > a_values)
Definition: BSTList.h:348
void resize_impl(size_type a_count, const_reference a_value)
Definition: BSTList.h:386
Definition: AbsorbEffect.h:6
T observer
Definition: PCH.h:92
Definition: NiBinaryStream.h:94
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