Open
Graph Drawing
Framework

 v. 2023.09 (Elderberry)
 

Loading...
Searching...
No Matches
IntrusiveList.h
Go to the documentation of this file.
1
32#pragma once
33
34#include <ogdf/basic/basic.h>
35#include <ogdf/basic/internal/config_autogen.h>
36
37#include <cstddef>
38#include <iterator>
39
40namespace ogdf::pc_tree {
41template<class T>
43 T* m_first = nullptr;
44 T* m_last = nullptr;
45 size_t m_count = 0;
46
47public:
48 class iterator {
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:
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
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
209private:
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}
Basic declarations, included by all source files.
bool operator==(iterator other) const
std::input_iterator_tag iterator_category
bool operator!=(iterator other) const
void splice(iterator at, IntrusiveList< T > &other)
#define OGDF_ASSERT(expr)
Assert condition expr. See doc/build.md for more information.
Definition basic.h:52