Aleph-w 3.0
A C++ Library for Data Structures and Algorithms
Loading...
Searching...
No Matches
dlink.cc
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
33
38# include <gtest/gtest.h>
39
40# include <dlink.H>
41
42using namespace std;
43using namespace testing;
44using namespace Aleph;
45
47{
48 Dlink l;
50 EXPECT_EQ(l.get_next(), &l);
51 EXPECT_EQ(l.get_prev(), &l);
52}
53
55{
56 Dlink l, laux;
57 l.swap(laux); // swap between empty list
59 EXPECT_EQ(l.get_next(), &l);
60 EXPECT_EQ(l.get_prev(), &l);
62 EXPECT_EQ(laux.get_next(), &laux);
63 EXPECT_EQ(laux.get_prev(), &laux);
64
65 l = move(laux); // assignment of rvalue empty list
67 EXPECT_EQ(l.get_next(), &l);
68 EXPECT_EQ(l.get_prev(), &l);
70 EXPECT_EQ(laux.get_next(), &laux);
71 EXPECT_EQ(laux.get_prev(), &laux);
72
73 l = laux; // assignment of empty list
75 EXPECT_EQ(l.get_next(), &l);
76 EXPECT_EQ(l.get_prev(), &l);
78 EXPECT_EQ(laux.get_next(), &laux);
79 EXPECT_EQ(laux.get_prev(), &laux);
80
81 l = laux; // assignment of rvalue empty list
83 EXPECT_EQ(l.get_next(), &l);
84 EXPECT_EQ(l.get_prev(), &l);
86 EXPECT_EQ(laux.get_next(), &laux);
87 EXPECT_EQ(laux.get_prev(), &laux);
88
89 {
90 Dlink llaux(move(laux)); // copy constructor of empty rvalue list
92 EXPECT_EQ(laux.get_next(), &laux);
93 EXPECT_EQ(laux.get_prev(), &laux);
95 EXPECT_EQ(llaux.get_next(), &llaux);
96 EXPECT_EQ(llaux.get_prev(), &llaux);
97 }
98
99 {
100 Dlink llaux(laux); // copy constructor of empty list
102 EXPECT_EQ(laux.get_next(), &laux);
103 EXPECT_EQ(laux.get_prev(), &laux);
105 EXPECT_EQ(llaux.get_next(), &llaux);
106 EXPECT_EQ(llaux.get_prev(), &llaux);
107 }
108
109 l.append_list(&laux);
112
113 l.insert_list(&laux);
116}
117
119{
120 Dlink l, l1, l2;
121
122 l.reverse_list(); // revese of empty list
124
125 l.append(&l2);
129 EXPECT_EQ(l.get_first(), &l2);
130 EXPECT_EQ(l.get_first(), l.get_next());
131 EXPECT_EQ(l.get_last(), &l2);
132 EXPECT_EQ(l.get_last(), l.get_prev());
133
134 l.reverse_list(); // reverse with one item
135 EXPECT_EQ(l.get_first(), &l2);
136 EXPECT_EQ(l.get_first(), l.get_next());
137 EXPECT_EQ(l.get_last(), &l2);
138 EXPECT_EQ(l.get_last(), l.get_prev());
139
140
141 l.insert(&l1);
144 EXPECT_EQ(l.get_first(), &l1);
145 EXPECT_EQ(l.get_last(), &l2);
146
147 l.reverse_list(); // reverse of list of two items
148 EXPECT_EQ(l.get_first(), &l2);
149 EXPECT_EQ(l.get_last(), &l1);
150
151 l.reverse_list();
152
153 EXPECT_EQ(l.remove_first(), &l1);
154 EXPECT_EQ(l.get_first(), &l2);
155 EXPECT_EQ(l.get_last(), &l2);
159
160 l.insert(&l1);
161 EXPECT_EQ(l.get_first(), &l1);
165 EXPECT_EQ(l.get_first(), &l1);
166 EXPECT_EQ(l.get_last(), &l2);
167
168 EXPECT_EQ(l.remove_last(), &l2);
169 EXPECT_EQ(l.get_first(), &l1);
170 EXPECT_EQ(l.get_last(), &l1);
174
175 l.append(&l2);
176 EXPECT_EQ(l.get_first(), &l1);
180 EXPECT_EQ(l.get_first(), &l1);
181 EXPECT_EQ(l.get_last(), &l2);
182
183 l1.del();
184 EXPECT_TRUE(l1.is_empty());
186 EXPECT_EQ(l.get_first(), &l2);
187
188 l.insert(&l1);
192 EXPECT_EQ(l.get_first(), &l1);
193 EXPECT_EQ(l.get_last(), &l2);
194
195 l2.del();
196 EXPECT_TRUE(l2.is_empty());
198 EXPECT_EQ(l.get_first(), &l1);
199
200 l.append(&l2);
204 EXPECT_EQ(l.get_first(), &l1);
205 EXPECT_EQ(l.get_last(), &l2);
206}
207
209{
210 Dlink l;
211 Dlink::Iterator it = l;
212
214 EXPECT_THROW(it.get_curr(), overflow_error);
215 EXPECT_FALSE(it.is_last());
217
218 it.reset_first();
220 EXPECT_THROW(it.get_curr(), overflow_error);
221 EXPECT_FALSE(it.is_last());
223
224 it.reset_last();
226 EXPECT_THROW(it.get_curr(), overflow_error);
227 EXPECT_FALSE(it.is_last());
229}
230
231struct List_of_5_nodes : public testing::Test
232{
235 {
236 list.append(&l1);
237 list.append(&l2);
238 list.append(&l3);
239 list.append(&l4);
240 list.append(&l5);
241 }
242};
243
245{
246 Dlink::Iterator it = list;
247
248 for (size_t i = 0; i < 2; ++i)
249 {
250 EXPECT_TRUE(it.has_curr());
252 EXPECT_EQ(it.get_curr(), &l1);
253 it.next();
254
255 EXPECT_TRUE(it.has_curr());
256 EXPECT_EQ(it.get_curr(), &l2);
257 it.next();
258
259 EXPECT_TRUE(it.has_curr());
260 EXPECT_EQ(it.get_curr(), &l3);
261 it.next();
262
263 EXPECT_TRUE(it.has_curr());
264 EXPECT_EQ(it.get_curr(), &l4);
265 EXPECT_FALSE(it.is_last());
266 it.next();
267
268 EXPECT_TRUE(it.has_curr());
270 EXPECT_EQ(it.get_curr(), &l5);
271 EXPECT_TRUE(it.is_last());
272 it.next();
273
275 EXPECT_THROW(it.get_curr(), overflow_error);
276
277 it.reset_first();
278 }
279
280 it.reset_last();
281 for (size_t i = 0; i < 2; ++i)
282 {
283 EXPECT_TRUE(it.has_curr());
285 EXPECT_EQ(it.get_curr(), &l5);
286 it.prev();
287
288 EXPECT_TRUE(it.has_curr());
289 EXPECT_EQ(it.get_curr(), &l4);
290 it.prev();
291
292 EXPECT_TRUE(it.has_curr());
293 EXPECT_EQ(it.get_curr(), &l3);
294 it.prev();
295
296 EXPECT_TRUE(it.has_curr());
297 EXPECT_EQ(it.get_curr(), &l2);
298 EXPECT_FALSE(it.is_last());
299 it.prev();
300
301 EXPECT_TRUE(it.has_curr());
302 EXPECT_EQ(it.get_curr(), &l1);
304 it.prev();
305
307 EXPECT_THROW(it.get_curr(), overflow_error);
308
309 it.reset_last();
310 }
311
312 it.reset_first();
313 EXPECT_EQ(it.del(), &l1);
314 EXPECT_TRUE(it.has_curr());
315
316 EXPECT_EQ(it.del(), &l2);
317 EXPECT_TRUE(it.has_curr());
318
319 EXPECT_EQ(it.del(), &l3);
320 EXPECT_TRUE(it.has_curr());
321
322 EXPECT_EQ(it.del(), &l4);
323 EXPECT_TRUE(it.has_curr());
324
325 EXPECT_EQ(it.del(), &l5);
327 EXPECT_TRUE(list.is_empty());
328}
329
331{
332 Dlink laux;
333 list.swap(&laux);
334
335 EXPECT_TRUE(list.is_empty());
337 EXPECT_EQ(laux.get_first(), &l1);
338 EXPECT_EQ(laux.get_last(), &l5);
339
340 laux.swap(&list);
341
343 EXPECT_FALSE(list.is_empty());
344 EXPECT_EQ(list.get_first(), &l1);
345 EXPECT_EQ(list.get_last(), &l5);
346}
347
349{
350 Dlink laux, n1, n2, n3;
351 laux.append(&n1);
352 laux.append(&n2);
353 laux.append(&n3); // laux = { n1, n2, n3 }
354
355 list.append_list(&laux); // l = { l1, l2, l3, l4, l5, n1, n2 ,n3 }
357 EXPECT_EQ(list.get_first(), &l1);
358 EXPECT_EQ(list.get_last(), &n3);
359
360 laux = list.cut_list(&n1); // l = { l1, l2, l3, l4, l5 }, laux = { n1, n2, n3 }
361 EXPECT_EQ(laux.get_first(), &n1);
362 EXPECT_EQ(laux.get_last(), &n3);
363 EXPECT_EQ(list.get_first(), &l1);
364 EXPECT_EQ(list.get_last(), &l5);
365
366 Dlink lr = list.cut_list(&l1); // l = {}, lr = { l1, l2, l3, l4, l5 }
367 EXPECT_TRUE(list.is_empty());
368 EXPECT_EQ(lr.get_first(), &l1);
369 EXPECT_EQ(lr.get_last(), &l5);
370
371 list.insert_list(&lr); // list = { l1, l2, l3, l4, l5 }
373 EXPECT_EQ(list.get_first(), &l1);
374 EXPECT_EQ(list.get_last(), &l5);
375 EXPECT_FALSE(list.is_empty());
376
377 list.insert_list(&laux); // list = { n1, n2, n3, l1, l2, l3, l4, l5 }
379 EXPECT_EQ(list.get_first(), &n1);
380 EXPECT_EQ(list.get_last(), &l5);
381
382 Dlink n0;
383 list.insert(&n0); // list = { n0, n1, n2, n3, l1, l2, l3, l4, l5 }
384 EXPECT_EQ(list.get_first(), &n0);
385 EXPECT_EQ(list.get_last(), &l5);
386
387 Dlink m1, m2, m3; // laux = { m1, m2, m3 }
388 laux.append(&m1);
389 laux.append(&m2);
390 laux.append(&m3);
392 EXPECT_EQ(laux.get_first()->get_next(), &m2);
393 EXPECT_EQ(laux.get_last()->get_prev(), &m2);
395
396 EXPECT_EQ(laux.remove_last(), &m3);
399 laux.append(&m2);
403 EXPECT_EQ(laux.remove_last(), &m2);
404
405 laux.append(&m1); // laux = { m1, m2, m3 }
406 laux.append(&m2);
407 laux.append(&m3);
408
409 n3.append_list(&laux); // list = { n0, n1, n2, n3, m1, m2, m3, l1, l2, l3, l4, l5 }
411 EXPECT_EQ(list.get_first(), &n0);
412 EXPECT_EQ(list.get_first()->get_next()->get_next()->get_next(), &m1);
413 EXPECT_EQ(list.get_last(), &l5);
414
415 laux.append(m1.del());
416 laux.append(m2.del());
417 laux.append(m3.del()); // laux = { m1, m2, m3 }
419 EXPECT_EQ(laux.get_first()->get_next(), &m2);
421 EXPECT_EQ(laux.get_last()->get_prev(), &m2);
422 EXPECT_EQ(m2.get_prev(), &m1);
423 EXPECT_EQ(m2.get_next(), &m3);
424
425 Dlink l, r;
426 list.split_list(l, r); // l = { n0, n1, n2, n3, l1 } r = { l2, l3, l4, l5 }
427 EXPECT_TRUE(list.is_empty());
428 EXPECT_EQ(l.get_first(), &n0);
429 EXPECT_EQ(l.get_last(), &l1);
430 EXPECT_EQ(r.get_first(), &l2);
431 EXPECT_EQ(r.get_last(), &l5);
432}
433
435{
436 Dlink stack;
437 EXPECT_TRUE(stack.is_empty());
438 EXPECT_THROW(stack.top(), underflow_error);
439 EXPECT_THROW(stack.pop(), underflow_error);
441 Dlink n1, n2, n3;
442 stack.push(&n3);
443
444 EXPECT_FALSE(stack.is_empty());
445 EXPECT_TRUE(stack.is_unitarian());
446
447 stack.push(&n2);
448 stack.push(&n1);
449 EXPECT_EQ(stack.top(), &n1);
450 EXPECT_EQ(stack.pop(), &n1);
451 EXPECT_EQ(stack.top(), &n2);
452 EXPECT_EQ(stack.pop(), &n2);
453
454 EXPECT_TRUE(stack.is_unitarian());
455
456 EXPECT_EQ(stack.top(), &n3);
457 EXPECT_EQ(stack.pop(), &n3);
458 EXPECT_FALSE(stack.is_unitarian());
459 EXPECT_TRUE(stack.is_empty());
460}
461
463{
464 list.reverse_list();
465 EXPECT_EQ(list.get_first(), &l5);
466 EXPECT_EQ(list.get_last(), &l1);
467}
T & insert(const T &item)
Insert a new item by copy.
Definition htlist.H:1502
T & append(const T &item)
Append a new item by copy.
Definition htlist.H:1562
T & get_last() const
Return the last item of the list.
Definition htlist.H:1663
T & get_first() const
Return the first item of the list.
Definition htlist.H:1675
DynList & swap(DynList &l) noexcept
Swap this with l.
Definition htlist.H:1448
size_t reverse_list() noexcept
Definition htlist.H:1002
void cut_list(Slinknc *link, HTList &list) noexcept
Definition htlist.H:1037
constexpr bool is_empty() const noexcept
Return true if list is empty.
Definition htlist.H:523
size_t split_list(HTList &l, HTList &r) noexcept
It divides 'this' into two equal lists without modifying elements order.
Definition htlist.H:930
bool is_unitarian() const noexcept
Return true if the list contains exactly just one element.
Definition htlist.H:528
bool is_unitarian_or_empty() const noexcept
Return true if list contains one element or is empty.
Definition htlist.H:535
#define TEST(name)
Main namespace for Aleph-w library functions.
Definition ah-arena.H:89
void reverse(Itor beg, Itor end)
Reverse elements in a range.
Definition ahAlgo.H:1094
T & swap(T &t1, T &t2)
Generic swap using object's swap method.
Definition ahTypes.H:121
DynList< T > maps(const C &c, Op op)
Classic map operation.
STL namespace.
DynList< int > l