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