mCRL2
Loading...
Searching...
No Matches
embedded_list.h
Go to the documentation of this file.
1// Author(s): Jan Friso Groote
2// Copyright: see the accompanying file COPYING or copy at
3// https://github.com/mCRL2org/mCRL2/blob/master/COPYING
4//
5// Distributed under the Boost Software License, Version 1.0.
6// (See accompanying file LICENSE_1_0.txt or copy at
7// http://www.boost.org/LICENSE_1_0.txt)
8//
10
11#ifndef _EMBEDDED_LIST_H
12#define _EMBEDDED_LIST_H
13
14#include <cassert>
15#include <vector>
16
17namespace mcrl2
18{
19namespace lts
20{
21namespace detail
22{
23
24// The list type below embeds a list in existing data structures.
25// For instance if elements are stored in a vector, and should also
26// be linked in a particular order in a list this data structure can be
27// used.
28//
29// For this purpose to each data structure that must be put in an embedded
30// list the embedded_list_node must be added to the data structure.
31//
32// From that point on the embedded_list data type can be used to construct
33// an embedded list. The data structure, once created will not require
34// extra memory.
35
36// prototype.
37template < class TYPE > class embedded_list;
38
39template <class TYPE>
41{
42
43 template < class T > friend class embedded_list;
44
45 protected:
46 TYPE* m_next; // Points to the next element in the list. The nullptr if it does not exist.
47 TYPE* m_prev; // Points to the current element in the list. The nullptr if it does not exist.
48};
49
50
51template < class TYPE >
53{
54 protected:
55 TYPE* m_first; // Points to the last element of the list. nulllptr if not valid.
56 TYPE* m_last; // Points to the first element of the list
57 std::size_t m_size; // The number of elements in the list.
58
59 protected:
60
62 {
63 std::size_t count_up=0;
64 for(TYPE* walker=m_first; walker!=nullptr && count_up<=m_size ; walker=walker->m_next)
65 {
66 count_up++;
67 }
68
69 std::size_t count_down=0;
70 for(TYPE* walker=m_last; walker!=nullptr && count_down<=m_size ; walker=walker->m_prev)
71 {
72 count_down++;
73 }
74
75 return m_size==count_up && m_size==count_down;
76 }
77
78 bool check_presence(const TYPE& e) const
79 {
80 for(TYPE* walker=m_first; walker!=nullptr; walker=walker->m_next)
81 {
82 if (walker==&e)
83 {
84 return true;
85 }
86 }
87 return false;
88 }
89
90
91
92 public:
93
94 // Constructor.
96 : m_first(nullptr), m_last(nullptr), m_size(0)
97 {}
98
99 // Copy constructor.
100 embedded_list(const embedded_list& other) = default;
101
102 // Assignment.
103 embedded_list& operator=(const embedded_list& other) = default;
104
105 // get the size
106 std::size_t size() const
107 {
108 return m_size;
109 }
110
111 // Get the first element of the list.
112 TYPE& front()
113 {
114 assert(m_size>0);
115 return *m_first;
116 }
117
118 // Get the last element of the list.
119 TYPE& back()
120 {
121 assert(m_size>0);
122 return *m_last;
123 }
124
125 // Insert an element at the end of the list. Note that the element e is changed.
126 void push_back(TYPE& e)
127 {
128 if (m_first==nullptr)
129 {
130 assert(m_last==nullptr && m_size==0);
131 m_first= &e;
132 e.m_prev= nullptr;
133 }
134 else
135 {
136 assert(m_last!=nullptr && m_size>0);
137 e.m_prev=m_last;
138 m_last->m_next=&e;
139 }
140 e.m_next=nullptr;
141 m_last= &e;
142 m_size++;
143 assert(check_this_embedded_list());
144 }
145
146 // Insert an element at the begining of the list. Note that the element e is changed.
147 void push_front(TYPE& e)
148 {
149 if (m_last==nullptr)
150 {
151 assert(m_first==nullptr && m_size==0);
152 m_last= &e;
153 e.m_next= nullptr;
154 }
155 else
156 {
157 assert(m_first!=nullptr && m_size>0);
158 e.m_next=m_first;
159 m_first->m_prev=&e;
160 }
161 e.m_prev=nullptr;
162 m_first= &e;
163 m_size++;
164 assert(check_this_embedded_list());
165 }
166
167 // Erase this element from the list. The list is adapted such that it does not contain
168 // element e anymore. Postcondition: The previous and next pointer in e are invalid.
169 void erase(TYPE& e)
170 {
171 assert(check_presence(e));
172 if (e.m_next==nullptr)
173 {
174 assert(&e==m_last);
175 m_last=e.m_prev;
176 }
177 else
178 {
179 assert(e.m_next->m_prev!=nullptr);
180 e.m_next->m_prev = e.m_prev;
181 }
182
183 if (e.m_prev==nullptr)
184 {
185 assert(&e==m_first);
186 m_first=e.m_next;
187 }
188 else
189 {
190 assert(e.m_prev->m_next!=nullptr);
191 e.m_prev->m_next = e.m_next;
192 }
193
194 e.m_next= nullptr;
195 e.m_prev= nullptr;
196
197 m_size--;
198
199 assert(check_this_embedded_list());
200 }
201
202 void clear()
203 {
204 m_first=nullptr;
205 m_last=nullptr;
206 m_size=0;
207 }
208
209 /* Append the list l to the current list.
210 After this operation the list l is replaced by the empty list
211 to prevent unwanted sharing of lists. */
212
214 {
215 if (l.size()==0)
216 {
217 return;
218 }
219
220 if (m_size==0)
221 {
222 *this=l;
223 }
224 else
225 {
226 m_last->m_next=l.m_first;
227 l.m_first->m_prev=m_last;
228 m_last=l.m_last;
230 }
231 // Explicitly invalidate l.
232 l.m_first=nullptr;
233 l.m_last=nullptr;
234 l.m_size=0;
235
236 assert(check_this_embedded_list());
237 }
238
239 class iterator
240 {
241 protected:
242 TYPE* m_ptr;
243
244 public:
245
246 iterator(TYPE* p)
247 : m_ptr(p)
248 {}
249
250 // Prefix increment
252 {
253 iterator old=*this;
254 m_ptr=m_ptr->m_next;
255 return old;
256 }
257
258 // Postfix increment
260 {
261 m_ptr=m_ptr->m_next;
262 return *this;
263 }
264
265 // Dereference of the iterator.
266 TYPE& operator*()
267 {
268 return *m_ptr;
269 }
270
271 // Dereference of the iterator.
272 TYPE* operator->()
273 {
274 return m_ptr;
275 }
276
277 // Equality operator on iterators.
278 bool operator ==(const iterator& other) const
279 {
280 return m_ptr==other.m_ptr;
281 }
282 // Inequality operator on iterators.
283 bool operator !=(const iterator& other) const
284 {
285 return !(*this==other);
286 }
287
288 };
289
291 {
292 assert(check_this_embedded_list());
293 return m_first;
294 }
295
296 iterator end() const
297 {
298 return nullptr;
299 }
300
301};
302
303} // end namespace detail
304} // end namespace lts
305} // end namespace mcrl2
306#endif //_EMBEDDED_LIST_H
bool operator==(const iterator &other) const
bool operator!=(const iterator &other) const
embedded_list(const embedded_list &other)=default
embedded_list & operator=(const embedded_list &other)=default
void append(embedded_list &l)
bool check_presence(const TYPE &e) const
A class that takes a linear process specification and checks all tau-summands of that LPS for conflue...
Definition indexed_set.h:72