CommonLibSSE (Parapets fork)
GList.h
Go to the documentation of this file.
1 #pragma once
2 
3 namespace RE
4 {
5  template <class T>
6  struct GListNode
7  {
8  public:
10  prev{ 0 },
11  next{ 0 }
12  {}
13 
14  void Remove()
15  {
16  prev->next = next;
17  next->prev = prev;
18  }
19 
22  };
23  static_assert(sizeof(GListNode<void*>) == 0x10);
24 
25  // circular doubly-linked list
26  // classes must derive from GListNode
27  template <class T>
28  class GList
29  {
30  private:
31  using Node = GListNode<T>;
32 
33  public:
34  using value_type = T;
35  using size_type = std::size_t;
36  using difference_type = std::ptrdiff_t;
38  using const_reference = const value_type&;
39  using pointer = value_type*;
40  using const_pointer = typename std::pointer_traits<pointer>::template rebind<const value_type>;
41 
42  template <class U>
44  {
45  using difference_type = std::ptrdiff_t;
46  using value_type = U;
47  using pointer = U*;
48  using reference = U&;
49  using iterator_category = std::bidirectional_iterator_tag;
50  };
51 
52  template <class U>
53  class iterator_base : public iterator_traits<U>
54  {
55  private:
56  friend class GList<T>;
57 
58  using Traits = iterator_traits<U>;
59 
60  public:
62  using value_type = typename Traits::value_type;
63  using pointer = typename Traits::pointer;
64  using reference = typename Traits::reference;
66 
68  _cur{ 0 }
69  {}
70 
72  {
73  _cur = a_node;
74  }
75 
76  iterator_base(const iterator_base& a_rhs) :
77  _cur(a_rhs._cur)
78  {}
79 
81  _cur(std::move(a_rhs._cur))
82  {
83  a_rhs._cur = 0;
84  }
85 
86  static void swap(iterator_base& a_lhs, iterator_base& a_rhs)
87  {
88  std::swap(a_lhs._cur, a_rhs._cur);
89  }
90 
92  {
93  iterator_base tmp(a_rhs);
94  swap(*this, tmp);
95  }
96 
98  {
99  _cur = std::move(a_rhs._cur);
100  a_rhs._cur = 0;
101  }
102 
103  [[nodiscard]] reference operator*() const
104  {
105  return (reference)*_cur;
106  }
107 
108  [[nodiscard]] pointer operator->() const
109  {
110  return std::pointer_traits<pointer>::pointer_to(operator*());
111  }
112 
113  [[nodiscard]] bool operator==(const iterator_base& a_rhs) const
114  {
115  return _cur == a_rhs._cur;
116  }
117 
118  [[nodiscard]] bool operator!=(const iterator_base& a_rhs) const
119  {
120  return !operator==(a_rhs);
121  }
122 
123  // prefix
125  {
126  _cur = _cur->next;
127  return *this;
128  }
129 
130  // postfix
132  {
133  iterator_base tmp{ *this };
134  operator++();
135  return tmp;
136  }
137 
138  // prefix
140  {
141  _cur = _cur->prev;
142  return *this;
143  }
144 
145  // postifx
147  {
148  iterator_base tmp{ *this };
149  operator--();
150  return tmp;
151  }
152 
153  protected:
155  };
156 
159  using reverse_iterator = std::reverse_iterator<iterator>;
160  using const_reverse_iterator = std::reverse_iterator<const_iterator>;
161 
162  GList() :
163  _root{}
164  {
165  _root.next = _root.prev = &_root;
166  }
167 
169  {
170  return (reference)_root.next;
171  }
172 
173  [[nodiscard]] const_reference front() const
174  {
175  return (const_reference)_root.next;
176  }
177 
179  {
180  return (reference)_root.prev;
181  }
182 
183  [[nodiscard]] const_reference back() const
184  {
185  return (const_reference)_root.prev;
186  }
187 
188  iterator begin() noexcept
189  {
190  return iterator(_root.next);
191  }
192 
193  [[nodiscard]] const_iterator begin() const noexcept
194  {
195  return const_iterator(_root.next);
196  }
197 
198  [[nodiscard]] const_iterator cbegin() const noexcept
199  {
200  return const_iterator(_root.next);
201  }
202 
203  iterator end() noexcept
204  {
205  return iterator(&_root);
206  }
207 
208  [[nodiscard]] const_iterator end() const noexcept
209  {
210  return const_iterator(const_cast<GListNode<value_type>*>(&_root));
211  }
212 
213  [[nodiscard]] const_iterator cend() const noexcept
214  {
215  return const_iterator(const_cast<GListNode<value_type>*>(&_root));
216  }
217 
219  {
220  return reverse_iterator(_root.prev);
221  }
222 
223  [[nodiscard]] const_reverse_iterator rbegin() const noexcept
224  {
226  }
227 
228  [[nodiscard]] const_reverse_iterator crbegin() const noexcept
229  {
231  }
232 
234  {
235  return reverse_iterator(&_root);
236  }
237 
238  [[nodiscard]] const_reverse_iterator rend() const noexcept
239  {
240  return const_reverse_iterator(const_cast<GListNode<value_type>*>(&_root));
241  }
242 
243  [[nodiscard]] const_reverse_iterator crend() const noexcept
244  {
245  return const_reverse_iterator(const_cast<GListNode<value_type>*>(&_root));
246  }
247 
248  [[nodiscard]] bool empty() const noexcept
249  {
250  return _root.next == &_root;
251  }
252 
253  [[nodiscard]] size_type size() const noexcept
254  {
255  size_type size = 0;
256  for (auto it = begin(); it != end(); ++it) {
257  ++size;
258  }
259  return size;
260  }
261 
262  void clear() noexcept
263  {
264  _root.next = _root.prev = &_root;
265  }
266 
267  iterator insert(const_iterator a_pos, const T& a_value)
268  {
269  Node* node = (Node*)&a_value;
270  node->prev = a_pos._cur->prev;
271  a_pos._cur->prev->next = node;
272  node->next = a_pos._cur;
273  a_pos._cur->prev = node;
274  return { node };
275  }
276 
278  {
279  a_pos._cur->prev->next = a_pos._cur->next;
280  a_pos._cur->next->prev = a_pos._cur->prev;
281  }
282 
284  {
285  a_first._cur->prev->next = a_last._cur->next;
286  a_last._cur->next->prev = a_first._cur->prev;
287  }
288 
289  void push_back(const T& a_value)
290  {
291  Node* node = (Node*)&a_value;
292  node->next = &_root;
293  node->prev = _root.prev;
294  _root.prev->next = node;
295  _root.prev = node;
296  }
297 
298  void pop_back()
299  {
300  _root.prev = _root.prev->prev;
301  _root.prev->next = &_root;
302  }
303 
304  void push_front(const T& a_value)
305  {
306  Node* node = (Node*)&a_value;
307  node->next = _root.next;
308  node->prev = &_root;
309  _root.next->prev = node;
310  _root.next = node;
311  }
312 
313  void pop_front()
314  {
315  _root.next = _root.next->next;
316  _root.next->prev = &_root;
317  }
318 
319  void merge(GList& a_other)
320  {
321  while (!a_other.empty()) {
322  push_front(a_other.front());
323  }
324  }
325 
326  protected:
327  // members
329  };
330  static_assert(sizeof(GList<void*>) == 0x10);
331 }
Definition: GList.h:54
iterator_base & operator=(const iterator_base &a_rhs)
Definition: GList.h:91
bool operator!=(const iterator_base &a_rhs) const
Definition: GList.h:118
iterator_base operator--(int)
Definition: GList.h:146
static void swap(iterator_base &a_lhs, iterator_base &a_rhs)
Definition: GList.h:86
iterator_base & operator=(iterator_base &&a_rhs)
Definition: GList.h:97
iterator_base()
Definition: GList.h:67
iterator_base(iterator_base &&a_rhs)
Definition: GList.h:80
bool operator==(const iterator_base &a_rhs) const
Definition: GList.h:113
iterator_base(const iterator_base &a_rhs)
Definition: GList.h:76
Node * _cur
Definition: GList.h:154
pointer operator->() const
Definition: GList.h:108
iterator_base & operator--()
Definition: GList.h:139
iterator_base(Node *a_node)
Definition: GList.h:71
reference operator*() const
Definition: GList.h:103
iterator_base & operator++()
Definition: GList.h:124
iterator_base operator++(int)
Definition: GList.h:131
Definition: GList.h:29
std::ptrdiff_t difference_type
Definition: GList.h:36
value_type & reference
Definition: GList.h:37
iterator end() noexcept
Definition: GList.h:203
iterator_base< T > iterator
Definition: GList.h:157
const_iterator begin() const noexcept
Definition: GList.h:193
T value_type
Definition: GList.h:34
std::size_t size_type
Definition: GList.h:35
iterator erase(const_iterator a_first, const_iterator a_last)
Definition: GList.h:283
const_reference front() const
Definition: GList.h:173
const_iterator cend() const noexcept
Definition: GList.h:213
const_reverse_iterator crbegin() const noexcept
Definition: GList.h:228
const value_type & const_reference
Definition: GList.h:38
value_type * pointer
Definition: GList.h:39
const_reverse_iterator rbegin() const noexcept
Definition: GList.h:223
reference back()
Definition: GList.h:178
GListNode< value_type > _root
Definition: GList.h:328
iterator begin() noexcept
Definition: GList.h:188
iterator erase(const_iterator a_pos)
Definition: GList.h:277
const_reverse_iterator crend() const noexcept
Definition: GList.h:243
const_iterator cbegin() const noexcept
Definition: GList.h:198
typename std::pointer_traits< pointer >::template rebind< const value_type > const_pointer
Definition: GList.h:40
reverse_iterator rbegin() noexcept
Definition: GList.h:218
void push_back(const T &a_value)
Definition: GList.h:289
std::reverse_iterator< iterator > reverse_iterator
Definition: GList.h:159
bool empty() const noexcept
Definition: GList.h:248
size_type size() const noexcept
Definition: GList.h:253
iterator_base< const T > const_iterator
Definition: GList.h:158
std::reverse_iterator< const_iterator > const_reverse_iterator
Definition: GList.h:160
reverse_iterator rend() noexcept
Definition: GList.h:233
const_reverse_iterator rend() const noexcept
Definition: GList.h:238
const_iterator end() const noexcept
Definition: GList.h:208
void pop_front()
Definition: GList.h:313
const_reference back() const
Definition: GList.h:183
reference front()
Definition: GList.h:168
void merge(GList &a_other)
Definition: GList.h:319
void pop_back()
Definition: GList.h:298
void clear() noexcept
Definition: GList.h:262
GList()
Definition: GList.h:162
void push_front(const T &a_value)
Definition: GList.h:304
iterator insert(const_iterator a_pos, const T &a_value)
Definition: GList.h:267
Definition: AbsorbEffect.h:6
void swap(BSTTuple< T1, T2 > &a_lhs, BSTTuple< T1, T2 > &a_rhs) noexcept(noexcept(a_lhs.swap(a_rhs))) requires(std
Definition: BSTTuple.h:212
Definition: NiBinaryStream.h:94
Definition: GList.h:7
GListNode()
Definition: GList.h:9
GListNode< T > * prev
Definition: GList.h:20
void Remove()
Definition: GList.h:14
GListNode< T > * next
Definition: GList.h:21
Definition: GList.h:44
std::ptrdiff_t difference_type
Definition: GList.h:45
std::bidirectional_iterator_tag iterator_category
Definition: GList.h:49
U value_type
Definition: GList.h:46
U * pointer
Definition: GList.h:47
U & reference
Definition: GList.h:48