Aleph-w 3.0
A C++ Library for Data Structures and Algorithms
Loading...
Searching...
No Matches
htlist.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 <htlist.H>
41
42using namespace std;
43using namespace testing;
44using namespace Aleph;
45
46struct List_of_25_nodes : public Test
47{
50 {
51 for (size_t i = 0; i < 25; ++i)
52 list.append(new Snodenc<int>(i + 1));
53 }
58};
59
61{
62 HTList list;
63 EXPECT_TRUE(list.is_empty());
66 EXPECT_EQ(list.get_head(), list.get_first());
67 EXPECT_EQ(list.get_tail(), list.get_last());
68
69 list.append(new Snodenc<int>(2));
70 EXPECT_FALSE(list.is_empty());
73 EXPECT_EQ(list.get_head(), list.get_first());
74 EXPECT_EQ(list.get_tail(), list.get_last());
75 EXPECT_EQ(list.get_first(), list.get_last());
76
77 list.insert(new Snodenc<int>(1));
78 EXPECT_FALSE(list.is_empty());
81 EXPECT_EQ(list.get_head(), list.get_first());
82 EXPECT_EQ(list.get_tail(), list.get_last());
83
84 // list = { 1, 2}
85
86 EXPECT_EQ(static_cast<Snodenc<int>*>(list.get_first())->get_data(), 1);
87 EXPECT_EQ(static_cast<Snodenc<int>*>(list.get_last())->get_data(), 2);
88
89 auto p1 = new Snodenc<int>(0);
90 auto p2 = new Snodenc<int>(3);
91 list.insert(p1);
92 list.append(p2);
93 EXPECT_EQ(list.get_first()->to_snodenc<int>()->get_data(), 0);
94 EXPECT_EQ(list.get_last()->to_snodenc<int>()->get_data(), 3);
95
96 // list = { 0, 1, 2, 3}
97
98 auto fst = list.remove_first(); // remove 0
99 EXPECT_EQ(fst, p1);
100 EXPECT_EQ(fst->to_snodenc<int>()->get_data(), 0);
101 delete fst;
102 EXPECT_EQ(list.size(), 3);
103 EXPECT_EQ(list.get_last()->to_data<int>(), 3);
104
105 fst = list.remove_first(); // remove 1
106 EXPECT_EQ(fst->to_data<int>(), 1);
107 delete fst;
108 EXPECT_EQ(list.size(), 2);
109 EXPECT_EQ(list.get_last()->to_data<int>(), 3);
110
111 fst = list.remove_first(); // remove 2
112 EXPECT_EQ(fst->to_data<int>(), 2);
113 delete fst;
114 EXPECT_EQ(list.size(), 1);
115 EXPECT_EQ(list.get_last()->to_data<int>(), 3);
116
117 //list = { 3 }
118
119 EXPECT_EQ(list.get_first()->to_data<int>(), 3);
120 EXPECT_EQ(list.get_last()->to_data<int>(), 3);
123
124 fst = list.remove_first(); // remove 3
125 EXPECT_EQ(fst->to_data<int>(), 3);
126 delete fst;
127 EXPECT_TRUE(list.is_empty());
128 EXPECT_EQ(list.size(), 0);
129
130 EXPECT_THROW(list.rotate_left(1), std::domain_error);
132}
133
135{
136 HTList laux, list;
137 laux.insert(new Snodenc<int>(2));
138 list.append(laux);
139
142
143 laux.insert(new Snodenc<int>(1));
144 list.insert(laux);
146 EXPECT_EQ(list.size(), 2);
147 EXPECT_EQ(list.get_first()->to_data<int>(), 1);
148 EXPECT_EQ(list.get_last()->to_data<int>(), 2);
149
151}
152
154{
155 EXPECT_EQ(static_cast<Snodenc<int>*>(list.get_first())->get_data(), 1);
156 EXPECT_EQ(static_cast<Snodenc<int>*>(list.get_last())->get_data(), 25);
157 EXPECT_EQ(list.get_first(), list.get_head());
158 EXPECT_EQ(list.get_last(), list.get_tail());
159 EXPECT_EQ(list.size(), 25);
160 EXPECT_FALSE(list.is_empty());
161 EXPECT_FALSE(list.is_unitarian());
162 EXPECT_FALSE(list.is_unitarian_or_empty());
163}
164
166{
167 HTList l;
169 ASSERT_EQ(it.has_curr(), false);
170 EXPECT_THROW(it.get_curr(), std::overflow_error);
173
174 it.reset_first();
176 EXPECT_THROW(it.get_curr(), std::overflow_error);
177 EXPECT_FALSE(it.is_last());
179}
180
182{
183 int i = 1;
184 for (HTList::Iterator it = list; it.has_curr(); it.next(), ++i)
185 {
186 EXPECT_EQ(it.get_curr()->to_snodenc<int>()->get_data(), i);
187 EXPECT_EQ(it.get_pos(), i - 1);
188 }
189}
190
192{
193 HTList l, r;
194 list.split(l, r);
195
196 EXPECT_TRUE(list.is_empty());
197 EXPECT_EQ(l.size(), 13);
198 EXPECT_EQ(r.size(), 12);
199 EXPECT_EQ(l.get_first()->to_data<int>(), 1);
200 EXPECT_EQ(l.get_last()->to_data<int>(), 13);
201 EXPECT_EQ(r.get_first()->to_data<int>(), 14);
202 EXPECT_EQ(r.get_last()->to_data<int>(), 25);
203
204 int i = 1;
205 for (HTList::Iterator it = l; it.has_curr(); it.next(), ++i)
206 EXPECT_EQ(it.get_curr()->to_data<int>(), i);
207
208 for (HTList::Iterator it = r; it.has_curr(); it.next(), ++i)
209 EXPECT_EQ(it.get_curr()->to_data<int>(), i);
210
211 list.append(r);
212 list.insert(l);
213 i = 1;
214 for (HTList::Iterator it = l; it.has_curr(); it.next(), ++i)
215 EXPECT_EQ(it.get_curr()->to_data<int>(), i);
216}
217
219{
220 HTList laux;
221 laux.swap(list);
222
223 EXPECT_TRUE(list.is_empty());
224 EXPECT_EQ(list.size(), 0);
226
227 int i = 1;
228 for (HTList::Iterator it = laux; it.has_curr(); it.next(), ++i)
229 EXPECT_EQ(it.get_curr()->to_data<int>(), i);
230
232}
233
235{
236 HTList::Iterator it = list;
237 for (size_t i = 1; i < 13; ++i, it.next())
238 ;
239
240 HTList laux;
241 list.cut(it.get_curr(), laux);
242
244
245 int i = 1;
246 for (HTList::Iterator it = list; it.has_curr(); it.next(), ++i)
247 EXPECT_EQ(it.get_curr()->to_data<int>(), i);
248
249 for (HTList::Iterator it = laux; it.has_curr(); it.next(), ++i)
250 EXPECT_EQ(it.get_curr()->to_data<int>(), i);
251
252 list.concat(laux);
253 i = 1;
254 for (HTList::Iterator it = list; it.has_curr(); it.next(), ++i)
255 EXPECT_EQ(it.get_curr()->to_data<int>(), i);
256}
257
259{
260 EXPECT_EQ(list.reverse(), 25);
261 int i = 25;
262 for (HTList::Iterator it = list; it.has_curr(); it.next(), --i)
263 EXPECT_EQ(it.get_curr()->to_data<int>(), i);
264
265 EXPECT_EQ(list.reverse(), 25);
266
267 i = 1;
268 for (HTList::Iterator it = list; it.has_curr(); it.next(), ++i)
269 EXPECT_EQ(it.get_curr()->to_data<int>(), i);
270
271 HTList l, r;
272 list.split(l, r);
273
274 EXPECT_TRUE(list.is_empty());
275
276 l.reverse();
277 r.reverse();
278 list.insert(l);
279 list.insert(r);
282
283 list.reverse();
284 i = 1;
285 for (HTList::Iterator it = list; it.has_curr(); it.next(), ++i)
286 EXPECT_EQ(it.get_curr()->to_data<int>(), i);
287}
288
290{
291 list.rotate_left(3);
292
293 {
294 HTList::Iterator it = list;
295 for (int i = 0, n = 4; i < 3; ++i, ++n, it.next())
296 EXPECT_EQ(it.get_curr()->to_data<int>(), n);
297 }
298
299 list.rotate_left(22);
300 int i = 1;
301 for (HTList::Iterator it = list; it.has_curr(); it.next(), ++i)
302 EXPECT_EQ(it.get_curr()->to_data<int>(), i);
303}
304
306{
307 HTList stack;
308 ASSERT_TRUE(stack.is_empty());
309 ASSERT_THROW(stack.top(), underflow_error);
310 ASSERT_THROW(stack.pop(), underflow_error);
312 Slinknc n1, n2, n3;
313 stack.push(&n3);
314
315 ASSERT_FALSE(stack.is_empty());
316 ASSERT_TRUE(stack.is_unitarian());
317
318 stack.push(&n2);
319 stack.push(&n1);
320 ASSERT_EQ(stack.top(), &n1);
321 ASSERT_EQ(stack.pop(), &n1);
322 ASSERT_EQ(stack.top(), &n2);
323 ASSERT_EQ(stack.pop(), &n2);
324
325 ASSERT_TRUE(stack.is_unitarian());
326
327 ASSERT_EQ(stack.top(), &n3);
328 ASSERT_EQ(stack.pop(), &n3);
329 ASSERT_FALSE(stack.is_unitarian());
330 ASSERT_TRUE(stack.is_empty());
331}
332
T & insert(const T &item)
Insert a new item by copy.
Definition htlist.H:1502
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 & reverse() noexcept
Definition htlist.H:1763
DynList & swap(DynList &l) noexcept
Swap this with l.
Definition htlist.H:1448
Iterator on HTList.
Definition htlist.H:1083
void reset_first() noexcept
Definition htlist.H:1114
bool is_in_last() const noexcept
Return true if the iterator is positioned on the last item.
Definition htlist.H:1164
bool is_last() const noexcept
Definition htlist.H:1152
void next()
Move the iterator one item forward.
Definition htlist.H:1222
Slinknc * get_curr() const
Return the current node on which the iterator is positioned.
Definition htlist.H:1177
bool has_curr() const noexcept
Return true if iterator has current item.
Definition htlist.H:1150
bool is_in_first() const noexcept
Return true if the iterator is positioned on the first item.
Definition htlist.H:1158
Single linked list of nodes.
Definition htlist.H:507
Slinknc * get_first() const noexcept
Return list first element.
Definition htlist.H:547
void push(Slinknc *link) noexcept
Insert link as first element.
Definition htlist.H:862
void remove_all_and_delete() noexcept
Remove and free memory for all the items of list.
Definition htlist.H:1065
Slinknc * top() const
Definition htlist.H:893
Slinknc * get_tail() const noexcept
Return list tail (last element)
Definition htlist.H:543
size_t reverse() noexcept
It inverts all list elements.
Definition htlist.H:985
constexpr bool is_empty() const noexcept
Return true if list is empty.
Definition htlist.H:523
Slinknc * get_head() const noexcept
Return list head (first element)
Definition htlist.H:539
void rotate_left(size_t n)
Rotate to left the list n positions.
Definition htlist.H:1359
void cut(Slinknc *link, HTList &list) noexcept
It cuts 'this' over 'link' element and it puts all remaining elements.
Definition htlist.H:1025
Slinknc * pop()
Definition htlist.H:886
void append(Slinknc *link) noexcept
Insert link as last element.
Definition htlist.H:613
Slinknc * remove_first()
Definition htlist.H:803
size_t split(HTList &l, HTList &r) noexcept
Definition htlist.H:977
size_t size() const noexcept
Count the number of elements of the list.
Definition htlist.H:1319
void insert(Slinknc *link) noexcept
Insert link as first element.
Definition htlist.H:588
bool is_unitarian() const noexcept
Return true if the list contains exactly just one element.
Definition htlist.H:528
Slinknc * get_last() const noexcept
Return the last item of the list (nullptr if the list is empty)
Definition htlist.H:550
bool is_unitarian_or_empty() const noexcept
Return true if list contains one element or is empty.
Definition htlist.H:535
Link of a single linked list non-circular and without header node.
Definition htlist.H:100
T & to_data() noexcept
Definition htlist.H:445
Snodenc< T > * to_snodenc() noexcept
Convert this to a Snodenc<T>.
Definition htlist.H:434
Node belonging to a single non-circular linked list without header node.
Definition htlist.H:328
T & get_data() noexcept
Return a modifiable reference to the data.
Definition htlist.H:336
#define TEST(name)
Singly linked list implementations with head-tail access.
TEST_F(List_of_25_nodes, Basic_operations)
Definition htlist.cc:153
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
void rotate_left(T *ptr, const size_t n, size_t m) noexcept
Rotate array elements left by m positions.
DynList< T > maps(const C &c, Op op)
Classic map operation.
STL namespace.
DynList< int > l