Control Surface  1.2.0
MIDI Control Surface library for Arduino
LinkedList.hpp
Go to the documentation of this file.
1 /* ✔ */
2 
3 #pragma once
4 
6 
7 AH_DIAGNOSTIC_WERROR() // Enable errors on warnings
8 
9 #include <AH/Debug/Debug.hpp>
10 #include <AH/Math/MinMaxFix.hpp>
11 #include <stdlib.h>
12 
13 #include <AH/STL/iterator>
14 
17 
24 template <class Node>
26  public:
28  template <class INode>
30  public:
32 
33  bool operator!=(const node_iterator_base &rhs) const {
34  return node != rhs.node;
35  }
36 
37  bool operator==(const node_iterator_base &rhs) const {
38  return !(*this != rhs);
39  }
40 
41  INode &operator*() const {
42  // TODO: check node != nullptr
43  return *node;
44  }
45 
46  protected:
47  INode *node;
48  };
49 
51  template <class INode>
52  class node_iterator : public node_iterator_base<INode> {
53  public:
55 
56  using difference_type = long;
57  using value_type = INode;
58  using pointer = INode *;
59  using reference = INode &;
60  using iterator_category = std::bidirectional_iterator_tag;
61 
64  // TODO: check node != nullptr
65  this->node = this->node->next;
66  return *this;
67  }
68 
71  // TODO: check node != nullptr
72  this->node = this->node->previous;
73  return *this;
74  }
75  };
76 
78  template <class INode>
79  class reverse_node_iterator : public node_iterator_base<INode> {
80  public:
82 
83  using difference_type = long;
84  using value_type = INode;
85  using pointer = INode *;
86  using reference = INode &;
87  using iterator_category = std::bidirectional_iterator_tag;
88 
91  // TODO: check node != nullptr
92  this->node = this->node->previous;
93  return *this;
94  }
95 
98  // TODO: check node != nullptr
99  this->node = this->node->next;
100  return *this;
101  }
102  };
103 
104  using iterator = node_iterator<Node>;
105  using const_iterator = node_iterator<const Node>;
106  using reverse_iterator = reverse_node_iterator<Node>;
107  using const_reverse_iterator = reverse_node_iterator<const Node>;
108 
115  void append(Node *node) {
116  if (first == nullptr)
117  first = node;
118  node->previous = last;
119  if (node->previous != nullptr)
120  node->previous->next = node;
121  last = node;
122  node->next = nullptr;
123  }
124 
131  void append(Node &node) { append(&node); }
132 
142  void insertBefore(Node *toBeInserted, Node *before) {
143  if (before == first)
144  first = toBeInserted;
145  else
146  before->previous->next = toBeInserted;
147  toBeInserted->previous = before->previous;
148  toBeInserted->next = before;
149  before->previous = toBeInserted;
150  }
151 
153  void insertBefore(Node &toBeInserted, Node &before) {
154  insertBefore(&toBeInserted, &before);
155  }
156 
167  template <class Compare>
168  void insertSorted(Node *node, Compare cmp) {
169  iterator it = this->begin();
170  iterator end = this->end();
171  while (it != end) {
172  if (cmp(*node, *it)) {
173  insertBefore(*node, *it);
174  return;
175  }
176  ++it;
177  }
178  append(node);
179  }
180 
188  void insertSorted(Node *node) {
189  insertSorted(node, [](Node &lhs, Node &rhs) { return lhs < rhs; });
190  }
191 
198  void remove(Node *node) {
199  if (node->previous != nullptr)
200  node->previous->next = node->next;
201  if (node == last)
202  last = node->previous;
203  if (node->next != nullptr)
204  node->next->previous = node->previous;
205  if (node == first)
206  first = node->next;
207  node->previous = nullptr;
208  node->next = nullptr;
209  }
210 
217  void remove(Node &node) { remove(&node); }
218 
230  void moveDown(Node *node) {
231  Node *nodeB = node->previous;
232  if (nodeB == nullptr) // Can't move first node further down
233  return;
234  Node *nodeA = nodeB->previous;
235  Node *nodeD = node->next;
236 
237  if (nodeA != nullptr)
238  nodeA->next = node;
239  else
240  first = node;
241  nodeB->next = nodeD;
242  nodeB->previous = node;
243  node->next = nodeB;
244  node->previous = nodeA;
245  if (nodeD != nullptr)
246  nodeD->previous = nodeB;
247  else
248  last = nodeB;
249  }
250 
262  void moveDown(Node &node) {
263  moveDown(&node);
264  }
265 
281  bool couldContain(const Node *node) const {
282  return node && (node == first || node->next != nullptr ||
283  node->previous != nullptr);
284  }
285 
287  bool couldContain(const Node &node) const {
288  return couldContain(&node);
289  }
290 
291  iterator begin() { return {first}; }
292  iterator end() { return {nullptr}; }
293 
294  const_iterator begin() const { return {first}; }
295  const_iterator end() const { return {nullptr}; }
296 
297  reverse_iterator rbegin() { return {last}; }
298  reverse_iterator rend() { return {nullptr}; }
299 
300  const_reverse_iterator rbegin() const { return {last}; }
301  const_reverse_iterator rend() const { return {nullptr}; }
302 
304  Node *getFirst() const { return first; }
306  Node *getLast() const { return last; }
307 
308  private:
309  Node *first = nullptr;
310  Node *last = nullptr;
311 };
312 
319 template <class Node>
321  protected:
322  friend class DoublyLinkedList<Node>;
323  Node *next = nullptr;
324  Node *previous = nullptr;
325  virtual ~DoublyLinkable() = default;
326 };
327 
329 
DoublyLinkedList::reverse_node_iterator::difference_type
long difference_type
Definition: LinkedList.hpp:83
DoublyLinkedList< DisplayInterface >::const_reverse_iterator
reverse_node_iterator< const DisplayInterface > const_reverse_iterator
Definition: LinkedList.hpp:107
DoublyLinkedList::getFirst
Node * getFirst() const
Get a pointer to the first node.
Definition: LinkedList.hpp:304
DoublyLinkedList::first
Node * first
Definition: LinkedList.hpp:309
DoublyLinkedList::rbegin
const_reverse_iterator rbegin() const
Definition: LinkedList.hpp:300
DoublyLinkedList::reverse_node_iterator
Reverse bidirectional doubly linked list iterator.
Definition: LinkedList.hpp:79
DoublyLinkedList::reverse_node_iterator::operator++
reverse_node_iterator & operator++()
Prefix increment operator.
Definition: LinkedList.hpp:90
DoublyLinkedList::node_iterator::operator++
node_iterator & operator++()
Prefix increment operator.
Definition: LinkedList.hpp:63
Warnings.hpp
DoublyLinkedList::insertBefore
void insertBefore(Node *toBeInserted, Node *before)
Insert a node before another node.
Definition: LinkedList.hpp:142
DoublyLinkedList::remove
void remove(Node &node)
Remove a node from the linked list.
Definition: LinkedList.hpp:217
DoublyLinkedList::rbegin
reverse_iterator rbegin()
Definition: LinkedList.hpp:297
DoublyLinkedList::node_iterator_base::node_iterator_base
node_iterator_base(INode *node)
Definition: LinkedList.hpp:31
DoublyLinkable::previous
Node * previous
Definition: LinkedList.hpp:324
DoublyLinkedList::node_iterator::node_iterator
node_iterator(INode *node)
Definition: LinkedList.hpp:54
DoublyLinkedList::end
iterator end()
Definition: LinkedList.hpp:292
DoublyLinkedList::reverse_node_iterator::reference
INode & reference
Definition: LinkedList.hpp:86
DoublyLinkedList::node_iterator_base::operator!=
bool operator!=(const node_iterator_base &rhs) const
Definition: LinkedList.hpp:33
AH_DIAGNOSTIC_POP
#define AH_DIAGNOSTIC_POP()
Definition: Warnings.hpp:36
DoublyLinkedList::node_iterator::value_type
INode value_type
Definition: LinkedList.hpp:57
DoublyLinkedList::node_iterator_base::node
INode * node
Definition: LinkedList.hpp:47
DoublyLinkedList::node_iterator::operator--
node_iterator & operator--()
Prefix decrement operator.
Definition: LinkedList.hpp:70
DoublyLinkedList::couldContain
bool couldContain(const Node *node) const
Check if the linked list could contain the given node.
Definition: LinkedList.hpp:281
DoublyLinkedList< DisplayInterface >::iterator
node_iterator< DisplayInterface > iterator
Definition: LinkedList.hpp:104
DoublyLinkedList::insertSorted
void insertSorted(Node *node)
Insert a new node at the correct location into a sorted list, using operator<.
Definition: LinkedList.hpp:188
DoublyLinkedList::last
Node * last
Definition: LinkedList.hpp:310
DoublyLinkedList::append
void append(Node *node)
Append a node to a linked list.
Definition: LinkedList.hpp:115
DoublyLinkedList::getLast
Node * getLast() const
Get a pointer to the last node.
Definition: LinkedList.hpp:306
DoublyLinkedList::node_iterator_base::operator*
INode & operator*() const
Definition: LinkedList.hpp:41
DoublyLinkedList::end
const_iterator end() const
Definition: LinkedList.hpp:295
DoublyLinkedList< DisplayInterface >::const_iterator
node_iterator< const DisplayInterface > const_iterator
Definition: LinkedList.hpp:105
DoublyLinkedList::begin
iterator begin()
Definition: LinkedList.hpp:291
DoublyLinkedList::node_iterator_base
Base class for doubly linked list iterators.
Definition: LinkedList.hpp:29
DoublyLinkedList::moveDown
void moveDown(Node *node)
Move down the given node in the linked list.
Definition: LinkedList.hpp:230
DoublyLinkedList::reverse_node_iterator::pointer
INode * pointer
Definition: LinkedList.hpp:85
DoublyLinkedList::remove
void remove(Node *node)
Remove a node from the linked list.
Definition: LinkedList.hpp:198
DoublyLinkedList::node_iterator
Forward bidirectional doubly linked list iterator.
Definition: LinkedList.hpp:52
DoublyLinkedList::rend
reverse_iterator rend()
Definition: LinkedList.hpp:298
DoublyLinkedList::moveDown
void moveDown(Node &node)
Move down the given node in the linked list.
Definition: LinkedList.hpp:262
DoublyLinkedList::reverse_node_iterator::operator--
reverse_node_iterator & operator--()
Prefix decrement operator.
Definition: LinkedList.hpp:97
DoublyLinkedList::append
void append(Node &node)
Append a node to a linked list.
Definition: LinkedList.hpp:131
DoublyLinkedList< DisplayInterface >::reverse_iterator
reverse_node_iterator< DisplayInterface > reverse_iterator
Definition: LinkedList.hpp:106
DoublyLinkedList
A class for doubly linked lists.
Definition: LinkedList.hpp:25
DoublyLinkedList::node_iterator::pointer
INode * pointer
Definition: LinkedList.hpp:58
DoublyLinkable::~DoublyLinkable
virtual ~DoublyLinkable()=default
DoublyLinkedList::node_iterator::difference_type
long difference_type
Definition: LinkedList.hpp:56
DoublyLinkable
A class that can be inherited from to allow inserting into a DoublyLinkedList.
Definition: LinkedList.hpp:320
AH_DIAGNOSTIC_WERROR
#define AH_DIAGNOSTIC_WERROR()
Definition: Warnings.hpp:35
DoublyLinkedList::node_iterator::iterator_category
std::bidirectional_iterator_tag iterator_category
Definition: LinkedList.hpp:60
DoublyLinkedList::reverse_node_iterator::iterator_category
std::bidirectional_iterator_tag iterator_category
Definition: LinkedList.hpp:87
DoublyLinkedList::couldContain
bool couldContain(const Node &node) const
Check if the linked list could contain the given node.
Definition: LinkedList.hpp:287
DoublyLinkable::next
Node * next
Definition: LinkedList.hpp:323
DoublyLinkedList::reverse_node_iterator::reverse_node_iterator
reverse_node_iterator(INode *node)
Definition: LinkedList.hpp:81
DoublyLinkedList::begin
const_iterator begin() const
Definition: LinkedList.hpp:294
DoublyLinkedList::insertSorted
void insertSorted(Node *node, Compare cmp)
Insert a new node at the correct location into a sorted list.
Definition: LinkedList.hpp:168
DoublyLinkedList::reverse_node_iterator::value_type
INode value_type
Definition: LinkedList.hpp:84
DoublyLinkedList::rend
const_reverse_iterator rend() const
Definition: LinkedList.hpp:301
MinMaxFix.hpp
DoublyLinkedList::node_iterator::reference
INode & reference
Definition: LinkedList.hpp:59
DoublyLinkedList::node_iterator_base::operator==
bool operator==(const node_iterator_base &rhs) const
Definition: LinkedList.hpp:37
DoublyLinkedList::insertBefore
void insertBefore(Node &toBeInserted, Node &before)
Definition: LinkedList.hpp:153