Open
Graph Drawing
Framework

 v. 2023.09 (Elderberry)
 

IntrusiveList.h
Go to the documentation of this file.
1 
32 #pragma once
33 
34 #include <ogdf/basic/basic.h>
35 
36 #include <cassert>
37 #include <iterator>
38 
39 namespace ogdf::pc_tree {
40 template<class T>
42  T* m_first = nullptr;
43  T* m_last = nullptr;
44  size_t m_count = 0;
45 
46 public:
47  class iterator {
48  T* m_node;
49 
50  public:
51  // iterator traits
52  using iterator_category = std::input_iterator_tag;
53  using value_type = T*;
54  using difference_type = std::ptrdiff_t;
55  using pointer = const T*;
56  using reference = T*;
57 
58  explicit iterator(T* node) : m_node(node) { }
59 
61  m_node = m_node->m_next;
62  return *this;
63  }
64 
66  iterator other = *this;
67  ++(*this);
68  return other;
69  }
70 
71  bool operator==(iterator other) const { return m_node == other.m_node; }
72 
73  bool operator!=(iterator other) const { return m_node != other.m_node; }
74 
75  T* operator*() const { return m_node; }
76  };
77 
78  class node {
79  friend class IntrusiveList;
80 
81  private:
82  T* m_next;
83  T* m_prev;
84  };
85 
86  iterator begin() const { return iterator(m_first); }
87 
88  iterator end() const { return iterator(nullptr); }
89 
90  void clear() {
91  m_first = nullptr;
92  m_last = nullptr;
93  m_count = 0;
94  }
95 
96  [[nodiscard]] bool empty() const { return m_count == 0; }
97 
98  [[nodiscard]] size_t size() const { return m_count; }
99 
100  T* front() const {
101  OGDF_ASSERT(m_first != nullptr);
102  return m_first;
103  }
104 
105  T* back() const {
106  OGDF_ASSERT(m_last != nullptr);
107  return m_last;
108  }
109 
110  void push_front(T* obj) {
111  OGDF_ASSERT(obj != nullptr);
112  check();
113 
114  if (m_first == nullptr) {
115  obj->m_next = nullptr;
116  m_last = obj;
117  } else {
118  obj->m_next = m_first;
119  m_first->m_prev = obj;
120  }
121 
122  obj->m_prev = nullptr;
123  m_first = obj;
124  m_count++;
125  check();
126  }
127 
128  void push_back(T* obj) {
129  OGDF_ASSERT(obj != nullptr);
130  check();
131 
132  if (m_last == nullptr) {
133  obj->m_prev = nullptr;
134  m_first = obj;
135  } else {
136  obj->m_prev = m_last;
137  m_last->m_next = obj;
138  }
139 
140  obj->m_next = nullptr;
141  m_last = obj;
142  m_count++;
143  check();
144  }
145 
146  void pop_front() { erase(front()); }
147 
148  void pop_back() { erase(back()); }
149 
150  void erase(T* obj) {
151  OGDF_ASSERT(obj != nullptr);
152  OGDF_ASSERT(m_count > 0);
153  check();
154 
155  if (obj == m_first) {
156  m_first = obj->m_next;
157  }
158 
159  if (obj == m_last) {
160  m_last = obj->m_prev;
161  }
162 
163  if (obj->m_prev) {
164  obj->m_prev->m_next = obj->m_next;
165  }
166 
167  if (obj->m_next) {
168  obj->m_next->m_prev = obj->m_prev;
169  }
170 
171  m_count--;
172  check();
173  }
174 
175  void splice(iterator at, IntrusiveList<T>& other) {
176  OGDF_ASSERT(at == begin() || at == end());
177  check();
178  other.check();
179 
180  if (at == end()) {
181  if (m_last != nullptr) {
182  m_last->m_next = other.m_first;
183  other.m_first->m_prev = m_last;
184  m_last = other.m_last;
185  } else {
186  m_first = other.m_first;
187  m_last = other.m_last;
188  }
189  } else if (at == begin()) {
190  if (m_first != nullptr) {
191  m_first->m_prev = other.m_last;
192  other.m_last->m_next = m_first;
193  m_first = other.m_first;
194  } else {
195  m_first = other.m_first;
196  m_last = other.m_last;
197  }
198  }
199 
200  m_count += other.m_count;
201  other.m_count = 0;
202  other.m_first = nullptr;
203  other.m_last = nullptr;
204  check();
205  other.check();
206  }
207 
208 private:
209  void check() {
210 #ifdef OGDF_DEBUG
211  size_t counter = 0;
212  for ([[maybe_unused]] T* _ : *this) {
213  counter++;
214  }
215  OGDF_ASSERT(counter == m_count);
216 #endif
217  }
218 };
219 }
ogdf::pc_tree::IntrusiveList::pop_front
void pop_front()
Definition: IntrusiveList.h:146
ogdf::pc_tree::IntrusiveList::m_count
size_t m_count
Definition: IntrusiveList.h:44
ogdf::pc_tree::IntrusiveList::iterator::operator++
iterator & operator++()
Definition: IntrusiveList.h:60
ogdf::pc_tree::IntrusiveList::iterator::value_type
T * value_type
Definition: IntrusiveList.h:53
OGDF_ASSERT
#define OGDF_ASSERT(expr)
Assert condition expr. See doc/build.md for more information.
Definition: basic.h:54
ogdf::pc_tree::IntrusiveList::iterator::difference_type
std::ptrdiff_t difference_type
Definition: IntrusiveList.h:54
ogdf::pc_tree::IntrusiveList::iterator::operator++
iterator operator++(int)
Definition: IntrusiveList.h:65
ogdf::pc_tree
Definition: NodePCRotation.h:37
ogdf::pc_tree::IntrusiveList::m_first
T * m_first
Definition: IntrusiveList.h:42
ogdf::pc_tree::IntrusiveList::node::m_next
T * m_next
Definition: IntrusiveList.h:82
ogdf::pc_tree::IntrusiveList::erase
void erase(T *obj)
Definition: IntrusiveList.h:150
ogdf::pc_tree::IntrusiveList::begin
iterator begin() const
Definition: IntrusiveList.h:86
ogdf::pc_tree::IntrusiveList::size
size_t size() const
Definition: IntrusiveList.h:98
ogdf::pc_tree::IntrusiveList::iterator
Definition: IntrusiveList.h:47
ogdf::pc_tree::IntrusiveList::push_back
void push_back(T *obj)
Definition: IntrusiveList.h:128
ogdf::pc_tree::IntrusiveList::clear
void clear()
Definition: IntrusiveList.h:90
ogdf::pc_tree::IntrusiveList::back
T * back() const
Definition: IntrusiveList.h:105
ogdf::pc_tree::IntrusiveList
Definition: IntrusiveList.h:41
ogdf::pc_tree::IntrusiveList::iterator::pointer
const T * pointer
Definition: IntrusiveList.h:55
ogdf::pc_tree::IntrusiveList::check
void check()
Definition: IntrusiveList.h:209
ogdf::pc_tree::IntrusiveList::iterator::reference
T * reference
Definition: IntrusiveList.h:56
ogdf::pc_tree::IntrusiveList::empty
bool empty() const
Definition: IntrusiveList.h:96
ogdf::pc_tree::IntrusiveList::iterator::operator==
bool operator==(iterator other) const
Definition: IntrusiveList.h:71
ogdf::pc_tree::IntrusiveList::iterator::operator!=
bool operator!=(iterator other) const
Definition: IntrusiveList.h:73
ogdf::pc_tree::IntrusiveList::iterator::operator*
T * operator*() const
Definition: IntrusiveList.h:75
basic.h
Basic declarations, included by all source files.
ogdf::pc_tree::IntrusiveList::iterator::m_node
T * m_node
Definition: IntrusiveList.h:48
ogdf::pc_tree::IntrusiveList::front
T * front() const
Definition: IntrusiveList.h:100
ogdf::pc_tree::IntrusiveList::node
Definition: IntrusiveList.h:78
ogdf::pc_tree::IntrusiveList::push_front
void push_front(T *obj)
Definition: IntrusiveList.h:110
ogdf::pc_tree::IntrusiveList::node::m_prev
T * m_prev
Definition: IntrusiveList.h:83
ogdf::pc_tree::IntrusiveList::splice
void splice(iterator at, IntrusiveList< T > &other)
Definition: IntrusiveList.h:175
ogdf::pc_tree::IntrusiveList::m_last
T * m_last
Definition: IntrusiveList.h:43
ogdf::pc_tree::IntrusiveList::end
iterator end() const
Definition: IntrusiveList.h:88
ogdf::pc_tree::IntrusiveList::iterator::iterator
iterator(T *node)
Definition: IntrusiveList.h:58
ogdf::pc_tree::IntrusiveList::iterator::iterator_category
std::input_iterator_tag iterator_category
Definition: IntrusiveList.h:52
ogdf::pc_tree::IntrusiveList::pop_back
void pop_back()
Definition: IntrusiveList.h:148