Aleph-w 3.0
A C++ Library for Data Structures and Algorithms
Loading...
Searching...
No Matches
tpl_dynSlist.H
Go to the documentation of this file.
1
2/*
3 Aleph_w
4
5 Data structures & Algorithms
6 version 2.0.0b
7 https://github.com/lrleon/Aleph-w
8
9 This file is part of Aleph-w library
10
11 Copyright (c) 2002-2026 Leandro Rabindranath Leon
12
13 Permission is hereby granted, free of charge, to any person obtaining a copy
14 of this software and associated documentation files (the "Software"), to deal
15 in the Software without restriction, including without limitation the rights
16 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
17 copies of the Software, and to permit persons to whom the Software is
18 furnished to do so, subject to the following conditions:
19
20 The above copyright notice and this permission notice shall be included in all
21 copies or substantial portions of the Software.
22
23 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
24 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
25 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
26 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
27 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
28 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
29 SOFTWARE.
30*/
31
32
39# ifndef TPL_DYNSLIST_H
40# define TPL_DYNSLIST_H
41
42# include <tpl_slist.H>
43# include <cstddef>
44# include <stdexcept>
45# include <utility>
46# include <ah-errors.H>
47
48using namespace Aleph;
49
50namespace Aleph {
51
60 template <typename T>
61 class DynSlist : public Slist<T>
62 {
63 size_t num_items;
66
68 {
69 while (not this->is_empty())
70 delete this->remove_first_ne();
71 num_items = 0;
72 current_pos = 0;
73 current_node = this;
74 }
75 typename Slist<T>::Node *
76 get_previous_to_pos(const size_t pos, const bool allow_equal)
77 {
79 << "position out of range";
80
81 if (pos < current_pos)
82 {
83 current_pos = 0;
84 current_node = this;
85 }
86 while (current_pos < pos)
87 {
90 }
91 return current_node;
92 }
93
94 public:
95
98 {
99 // Empty
100 }
101
103 {
104 using Node = typename Slist<T>::Node;
105
106 Node * head = nullptr;
107 Node * tail = nullptr;
108 size_t n = 0;
109
110 try
111 {
112 const Node * end = static_cast<const Node*>(&other);
113 for (const Node * cur = other.get_first_ne(); cur != end;
114 cur = cur->get_next())
115 {
116 auto * node = new Node(cur->get_data());
117 node->get_next() = nullptr;
118
119 if (tail == nullptr)
120 head = tail = node;
121 else
122 {
123 tail->get_next() = node;
124 tail = node;
125 }
126 ++n;
127 }
128 }
129 catch (...)
130 {
131 while (head != nullptr)
132 {
133 Node * next = head->get_next();
134 delete head;
135 head = next;
136 }
137 throw;
138 }
139
140 if (head != nullptr)
141 {
142 this->get_next() = head;
143 tail->get_next() = this;
144 }
145
146 num_items = n;
147 current_pos = 0;
148 current_node = this;
149 }
150
152 {
153 if (this == &other)
154 return *this;
155
156 using Node = typename Slist<T>::Node;
157
158 Node * head = nullptr;
159 Node * tail = nullptr;
160 size_t n = 0;
161
162 try
163 {
164 const Node * end = static_cast<const Node*>(&other);
165 for (const Node * cur = other.get_first_ne(); cur != end;
166 cur = cur->get_next())
167 {
168 auto * node = new Node(cur->get_data());
169 node->get_next() = nullptr;
170
171 if (tail == nullptr)
172 head = tail = node;
173 else
174 {
175 tail->get_next() = node;
176 tail = node;
177 }
178 ++n;
179 }
180 }
181 catch (...)
182 {
183 while (head != nullptr)
184 {
185 Node * next = head->get_next();
186 delete head;
187 head = next;
188 }
189 throw;
190 }
191
192 clear();
193
194 if (head != nullptr)
195 {
196 this->get_next() = head;
197 tail->get_next() = this;
198 }
199
200 num_items = n;
201 current_pos = 0;
202 current_node = this;
203 return *this;
204 }
205
207 {
208 using Node = typename Slist<T>::Node;
209
210 if (other.is_empty())
211 return;
212
213 Node * other_sentinel = static_cast<Node*>(&other);
214 Node * head = other_sentinel->get_next();
215 Node * tail = head;
216 while (tail->get_next() != other_sentinel)
217 tail = tail->get_next();
218
219 this->get_next() = head;
220 tail->get_next() = this;
221
222 num_items = other.num_items;
223
225 other.num_items = 0;
226 other.current_pos = 0;
227 other.current_node = &other;
228
229 current_pos = 0;
230 current_node = this;
231 }
232
234 {
235 if (this == &other)
236 return *this;
237
238 using Node = typename Slist<T>::Node;
239
240 clear();
241
242 if (other.is_empty())
243 return *this;
244
245 Node * other_sentinel = static_cast<Node*>(&other);
246 Node * head = other_sentinel->get_next();
247 Node * tail = head;
248 while (tail->get_next() != other_sentinel)
249 tail = tail->get_next();
250
251 this->get_next() = head;
252 tail->get_next() = this;
253
254 num_items = other.num_items;
255
257 other.num_items = 0;
258 other.current_pos = 0;
259 other.current_node = &other;
260
261 current_pos = 0;
262 current_node = this;
263
264 return *this;
265 }
266
275 T & operator [] (const size_t i)
276 {
277 return get_previous_to_pos(i, false)->get_next()->get_data();
278 }
279
281 const T & operator[](const size_t i) const
282 {
283 ah_out_of_range_error_if(i >= num_items) << "position out of range";
284
285 using Node = typename Slist<T>::Node;
286 const Node * cur = this->get_first_ne();
287
288 for (size_t idx = 0; idx < i; ++idx)
289 cur = cur->get_next();
290
291 return cur->get_data();
292 }
293
295 size_t size() const noexcept { return num_items; }
296
304 void insert(const int pos, const T & data)
305 {
306 auto * prev = get_previous_to_pos(static_cast<size_t>(pos), true);
307 auto * node = new typename Slist<T>::Node (data);
308 prev->insert_next(node);
309 ++num_items;
310 current_pos = 0;
311 current_node = this;
312 }
313
315 void insert(const int pos, T && data)
316 {
317 auto * prev = get_previous_to_pos(static_cast<size_t>(pos), true);
318 auto * node = new typename Slist<T>::Node (std::move(data));
319 prev->insert_next(node);
320 ++num_items;
321 current_pos = 0;
322 current_node = this;
323 }
324
330 void remove(const int pos)
331 {
332 auto * prev = get_previous_to_pos(static_cast<size_t>(pos), false);
333 auto * node_to_delete = prev->remove_next();
334 delete node_to_delete;
335 --num_items;
336 current_pos = 0;
337 current_node = this;
338 }
339
340 virtual ~DynSlist() { clear(); }
341
346 class Iterator : public Slist<T>::Iterator
347 {
348 public:
352 typedef T Item_Type;
353
355 explicit Iterator(DynSlist & list) : Slist<T>::Iterator(list) { }
356
359
361 const T & get_curr() const
362 {
364 }
365 };
366 };
367} // end namespace Aleph
368
369# endif // TPL_DYNSLIST_H
370
Exception handling system with formatted messages for Aleph-w.
#define ah_out_of_range_error_if(C)
Throws std::out_of_range if condition holds.
Definition ah-errors.H:579
T & get_first_ne() const noexcept
Return the first item of the list without exception.
Definition htlist.H:1653
Iterator specialized for DynSlist returning payload references.
T & get_curr()
Return a reference to the current payload.
const T & get_curr() const
Return a const reference to the current payload.
Iterator(DynSlist &list)
Constructor.
T Item_Type
Type returned by get_curr().
Slist< T > Set_Type
Type of the data structure being iterated.
Dynamic list of elements of type T implemented with a singly linked list of nodes.
DynSlist & operator=(const DynSlist &other)
virtual ~DynSlist()
DynSlist(DynSlist &&other) noexcept
void clear() noexcept
Slist< T >::Node * get_previous_to_pos(const size_t pos, const bool allow_equal)
T & operator[](const size_t i)
Access the element at position i.
const T & operator[](const size_t i) const
Const overload of operator[].
DynSlist(const DynSlist &other)
size_t size() const noexcept
Return the number of stored elements.
void remove(const int pos)
Remove the node at position pos.
void insert(const int pos, T &&data)
Insert an element by moving the provided value.
DynSlist & operator=(DynSlist &&other) noexcept
void insert(const int pos, const T &data)
Insert an element at position pos.
Snode< T > * current_node
DynSlist()
Constructor.
constexpr bool is_empty() const noexcept
Return true if list is empty.
Definition htlist.H:523
void reset() noexcept
Definition htlist.H:516
Node * get_curr()
Return the current node.
Definition tpl_slist.H:205
Singly linked list of nodes that store values of type T.
Definition tpl_slist.H:102
Node * remove_first_ne() noexcept
Remove and return the first node without checking emptiness.
Definition tpl_slist.H:124
Snode< T > Node
Definition tpl_slist.H:106
Node * get_first_ne() noexcept
Return the first node without checking emptiness.
Definition tpl_slist.H:158
Singly linked node that stores data of type T.
Definition tpl_snode.H:66
T & get_data()
Return a modifiable reference to the stored data.
Definition tpl_snode.H:73
Snode *& get_next()
Return the next node after this.
Definition tpl_snode.H:91
Main namespace for Aleph-w library functions.
Definition ah-arena.H:89
std::decay_t< typename HeadC::Item_Type > T
Definition ah-zip.H:107
void next()
Advance all underlying iterators (bounds-checked).
Definition ah-zip.H:175
DynList< T > maps(const C &c, Op op)
Classic map operation.
Singly linked list with typed nodes.