Atoms Crowd  7.0.0
List.h
1 #pragma once
2 #include <ToolchefsSTL/Allocators/Allocator.h>
3 
4 namespace ToolchefsSTL
5 {
6  template<typename T>
7  class List
8  {
9  public:
10 
11  class Node
12  {
13  public:
14  Node(): data(), _prev(nullptr), _next(nullptr) {}
15 
16  Node(const T& value) : data(value), _prev(nullptr), _next(nullptr) {}
17 
18  template <typename... Args>
19  Node(Args&&... args): data(std::forward<Args>(args)...), _prev(nullptr), _next(nullptr) {}
20 
21  ~Node() = default;
22 
23  public:
24  T data;
25  Node* _prev;
26  Node* _next;
27  };
28 
29  template <class Item, class ItemType, bool Reverse>
30  struct ListIterator
31  {
32  ListIterator(Item* ptr) : m_ptr(ptr) {}
33  ~ListIterator() = default;
34  ListIterator operator +(size_t value) const
35  {
36  Item* node = m_ptr;
37  for (size_t i=0; i < value; ++i)
38  {
39  if (Reverse)
40  {
41  if (node && node->_prev)
42  node = node->_prev;
43  }
44  else
45  {
46  if (node && node->_next)
47  node = node->_next;
48  }
49  }
50  return ListIterator(node);
51  }
52 
53  ListIterator operator -(size_t value) const
54  {
55  Item* node = m_ptr;
56  for (size_t i = 0; i < value; ++i)
57  {
58  if (Reverse)
59  {
60  if (node && node->_next)
61  node = node->_next;
62  }
63  else
64  {
65  if (node && node->_prev)
66  node = node->_prev;
67  }
68  }
69  return ListIterator(node);
70  }
71 
72  ListIterator& operator ++()
73  {
74  if (Reverse)
75  m_ptr = m_ptr ? m_ptr->_prev : nullptr;
76  else
77  m_ptr = m_ptr ? m_ptr->_next : nullptr;
78  return *this;
79  }
80 
81  ListIterator& operator --()
82  {
83  if (Reverse)
84  m_ptr = m_ptr ? m_ptr->_next : nullptr;
85  else
86  m_ptr = m_ptr ? m_ptr->_prev : nullptr;
87  return *this;
88  }
89 
90  bool operator ==(const ListIterator& rhs) const { return m_ptr == rhs.m_ptr; }
91  bool operator !=(const ListIterator& rhs) const { return m_ptr != rhs.m_ptr; }
92  ItemType& operator *() const { return m_ptr->data; }
93  ItemType* operator->() const { return &m_ptr->data; }
94  Item* m_ptr;
95  };
96 
97  typedef T value_type;
98  typedef T& reference_type;
99  typedef T* ptr_type;
100 
105 
106  explicit List(Allocator* allocator = defaultAllocator()) noexcept;
107 
108  ~List() noexcept;
109 
110  List(const List& rhs) noexcept;
111 
112  List& operator=(const List& rhs) noexcept;
113 
114  List(List&& rhs) noexcept;
115 
116  List& operator=(List&& rhs) noexcept;
117 
118  void clear() noexcept;
119 
120  size_t size() const noexcept;
121 
122  size_t length() const noexcept;
123 
125  iterator begin() noexcept;
126  iterator end() noexcept;
127  const_iterator cbegin() const noexcept;
128  const_iterator cend() const noexcept;
129 
130  reverse_iterator rbegin() noexcept;
131  reverse_iterator rend() noexcept;
132  const_reverse_iterator crbegin() const noexcept;
133  const_reverse_iterator crend() const noexcept;
134 
136  T& back() noexcept;
137  const T& back() const noexcept;
138 
139  T& front() noexcept;
140  const T& front() const noexcept;
141 
143  void push_back(const T& element) noexcept;
144 
145  void pop_back() noexcept;
146 
147  template <typename... Args>
148  T& emplace_back(Args&&... args)
149  {
150  Node* value = static_cast<Node*>(m_allocator->malloc(sizeof(Node)));
151  new (value) Node(std::forward<Args>(args)...);
152  if (!m_head)
153  {
154  m_head = value;
155  m_tail = m_head;
156  return value->data;
157  }
158  m_tail->_next = value;
159  value->_prev = m_tail;
160  m_tail = value;
161  return value->data;
162  }
163 
164  template <typename... Args>
165  T& emplace_front(Args&&... args)
166  {
167  Node* value = static_cast<Node*>(m_allocator->malloc(sizeof(Node)));
168  new (value) Node(std::forward<Args>(args)...);
169  if (!m_head)
170  {
171  m_head = value;
172  m_tail = m_head;
173  return value->data;
174  }
175 
176  value->_next = m_head;
177  m_head = value;
178  return value->data;
179  }
180 
182  void push_front(const T& element) noexcept;
183 
184  void pop_front() noexcept;
185 
186  inline bool empty() noexcept { return m_head == nullptr; }
187 
188  iterator insert(const_iterator pos, const T& value) noexcept;
189 
190  iterator insert(iterator pos, const T& value) noexcept;
191 
192  template <typename... Args>
193  iterator emplace(const_iterator pos, Args&&... args) noexcept
194  {
195 
196  if (pos == cend() || !pos.m_ptr) return end();
197  Node* node = const_cast<Node*>(pos.m_ptr);
198 
199  Node* new_node = static_cast<Node*>(m_allocator->malloc(sizeof(Node)));
200  new (new_node) Node(std::forward<Args>(args)...);
201  Node* prevNode = node->_prev;
202  node->_prev = new_node;
203  new_node->_next = node;
204  if (prevNode)
205  {
206  prevNode->_next = new_node;
207  new_node->_prev = prevNode;
208  }
209  return iterator(new_node);
210  }
211 
212  template <typename... Args>
213  iterator emplace(iterator pos, Args&&... args) noexcept
214  {
215 
216  if (pos == end() || !pos.m_ptr) return end();
217  Node* node = pos.m_ptr;
218 
219  Node* new_node = static_cast<Node*>(m_allocator->malloc(sizeof(Node)));
220  new (new_node) Node(std::forward<Args>(args)...);
221  Node* prevNode = node->_prev;
222  node->_prev = new_node;
223  new_node->_next = node;
224  if (prevNode)
225  {
226  prevNode->_next = new_node;
227  new_node->_prev = prevNode;
228  }
229  return iterator(new_node);
230  }
231 
232  iterator erase(const_iterator pos) noexcept;
233 
234  iterator erase(iterator pos) noexcept;
235 
236  iterator find(const T& element) noexcept;
237 
238  const_iterator find(const T& element) const noexcept;
239 
240  private:
241  Node* m_head;
242  Node* m_tail;
243  Allocator* m_allocator;
244  };
245 }
246 
247 #include "List.impl.h"
Definition: Allocator.h:10
Definition: List.h:12
Definition: List.h:8
void push_back(const T &element) noexcept
Insert element.
Definition: List.impl.h:171
T & back() noexcept
Direct access.
Definition: List.impl.h:147
iterator begin() noexcept
Iterators.
Definition: List.impl.h:99
void push_front(const T &element) noexcept
Insert element.
Definition: List.impl.h:208