Aleph-w 3.0
A C++ Library for Data Structures and Algorithms
Loading...
Searching...
No Matches
dynlist.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# include <ah-unique.H>
42# include <ah-convert.H>
43
44using namespace testing;
45using namespace Aleph;
46
47struct List_of_25_items : public Test
48{
49 size_t n = 0;
53 {
54 for (size_t i = 0; i < 25; ++i, ++n)
55 list.append(i + 1);
56
57 const DynList<int> l = list;
58 rlist = l.rev();
59 }
60};
61
63{
64 DynList<int> list;
65 EXPECT_TRUE(list.is_empty());
68
69 list.append(2);
70 EXPECT_FALSE(list.is_empty());
73 EXPECT_EQ(list.get_first(), list.get_last());
74
75 list.insert(1);
76 EXPECT_FALSE(list.is_empty());
79
80 EXPECT_EQ(list.get_first(), 1);
81 EXPECT_EQ(list.get_last(), 2);
82
83 list.insert(0);
84 list.append(3);
85 EXPECT_EQ(list.get_first(), 0);
86 EXPECT_EQ(list.get_last(), 3);
87
88 EXPECT_EQ(list.remove_first(), 0);
89 EXPECT_EQ(list.size(), 3);
90 EXPECT_EQ(list.get_last(), 3);
91
92 EXPECT_EQ(list.remove_first(), 1);
93 EXPECT_EQ(list.size(), 2);
94 EXPECT_EQ(list.get_last(), 3);
95
96 EXPECT_EQ(list.remove_first(), 2);
97 EXPECT_EQ(list.size(), 1);
98 EXPECT_EQ(list.get_last(), 3);
99
102
103 EXPECT_EQ(list.remove_first(), 3);
104 EXPECT_TRUE(list.is_empty());
105 EXPECT_EQ(list.size(), 0);
106
107 EXPECT_THROW(list.rotate_left(1), std::domain_error);
109}
110
112{
113 DynList<int> list;
114 list.append(1);
115 list.append(2);
116 list.append(3);
117 EXPECT_FALSE(list.is_empty());
118 EXPECT_EQ(list.size(), 3);
119
120 list.clear();
121 EXPECT_TRUE(list.is_empty());
122 EXPECT_EQ(list.size(), 0);
123
124 list.append(4);
125 EXPECT_FALSE(list.is_empty());
126 EXPECT_EQ(list.size(), 1);
127 EXPECT_EQ(list.get_first(), 4);
128
129 EXPECT_TRUE(list.contains(4));
130 EXPECT_FALSE(list.contains(1));
131}
132
134{
135 DynList<int> l1 = {1, 2, 3};
136 DynList<int> l2 = {1, 2, 3};
137 DynList<int> l3 = {1, 2, 4};
138 DynList<int> l4 = {1, 2};
139
140 EXPECT_TRUE(l1 == l2);
141 EXPECT_FALSE(l1 != l2);
142
143 EXPECT_FALSE(l1 == l3);
144 EXPECT_TRUE(l1 != l3);
145
146 EXPECT_FALSE(l1 == l4);
147 EXPECT_TRUE(l1 != l4);
148
151}
152
154{
155 DynList<int> laux, list;
156 laux.insert(2);
157 list.append(std::move(laux));
158
159 EXPECT_TRUE(laux.is_empty());
161
162 laux.insert(1);
163 list.insert(std::move(laux));
164 EXPECT_TRUE(laux.is_empty());
165 EXPECT_EQ(list.size(), 2);
166 EXPECT_EQ(list.get_first(), 1);
167 EXPECT_EQ(list.get_last(), 2);
168}
169
171{
172 {
173 DynList<int> list;
174 list.append(3);
175 list.append(1);
176 list.append(2);
177 list.append(3);
178
179 in_place_unique(list);
180
181 ASSERT_EQ(list.size(), 3u);
182 auto it = list.get_it();
183 ASSERT_TRUE(it.has_curr()); EXPECT_EQ(it.get_curr(), 3); it.next();
184 ASSERT_TRUE(it.has_curr()); EXPECT_EQ(it.get_curr(), 1); it.next();
185 ASSERT_TRUE(it.has_curr()); EXPECT_EQ(it.get_curr(), 2); it.next();
186 EXPECT_FALSE(it.has_curr());
187 }
188
189 {
192 EXPECT_EQ(empty_list.size(), 0u);
193 EXPECT_FALSE(empty_list.get_it().has_curr());
194 }
195
196 {
200 EXPECT_EQ(single_list.size(), 1u);
201 EXPECT_EQ(single_list.get_first(), 42);
202 }
203
204 {
206 all_equal.append(5);
207 all_equal.append(5);
208 all_equal.append(5);
210 EXPECT_EQ(all_equal.size(), 1u);
211 EXPECT_EQ(all_equal.get_first(), 5);
212 }
213}
214
216{
217 EXPECT_EQ(list.get_first(), 1);
218 EXPECT_EQ(list.get_last(), 25);
219 EXPECT_EQ(list.size(), 25);
220 EXPECT_FALSE(list.is_empty());
221 EXPECT_FALSE(list.is_unitarian());
222 EXPECT_FALSE(list.is_unitarian_or_empty());
223}
224
226{
227 int i = 1;
228 for (auto it = list.get_it(); it.has_curr(); it.next(), ++i)
229 {
230 EXPECT_EQ(it.get_curr(), i);
231 EXPECT_EQ(it.get_pos(), i - 1);
232 }
233}
234
236{
238 list.split(l, r);
239
240 EXPECT_TRUE(list.is_empty());
241 EXPECT_EQ(l.size(), 13);
242 EXPECT_EQ(r.size(), 12);
243 EXPECT_EQ(l.get_first(), 1);
244 EXPECT_EQ(l.get_last(), 13);
245 EXPECT_EQ(r.get_first(), 14);
246 EXPECT_EQ(r.get_last(), 25);
247
248 int i = 1;
249 for (auto it = l.get_it(); it.has_curr(); it.next(), ++i)
250 EXPECT_EQ(it.get_curr(), i);
251
252 for (auto it = r.get_it(); it.has_curr(); it.next(), ++i)
253 EXPECT_EQ(it.get_curr(), i);
254
255 list.append(r);
256 list.insert(l);
257 i = 1;
258 for (auto it = l.get_it(); it.has_curr(); it.next(), ++i)
259 EXPECT_EQ(it.get_curr(), i);
260}
261
263{
265 laux.swap(list);
266
267 EXPECT_TRUE(list.is_empty());
268 EXPECT_EQ(list.size(), 0);
269 EXPECT_FALSE(laux.is_empty());
270
271 int i = 1;
272 for (auto it = laux.get_it(); it.has_curr(); it.next(), ++i)
273 EXPECT_EQ(it.get_curr(), i);
274}
275
277{
278 list.reverse();
279 int i = 25;
280 for (auto it = list.get_it(); it.has_curr(); it.next(), --i)
281 EXPECT_EQ(it.get_curr(), i);
282
283 list.reverse();
284
285 i = 1;
286 for (auto it = list.get_it(); it.has_curr(); it.next(), ++i)
287 EXPECT_EQ(it.get_curr(), i);
288
289 const DynList<int> list_cpy = list;
290 const DynList<int> rlist_cpy = rlist;
291
292 EXPECT_TRUE(eq(list_cpy.rev(), rlist));
293 EXPECT_TRUE(eq(rlist_cpy.rev(), list));
294
296 list.split(l, r);
297
298 EXPECT_TRUE(list.is_empty());
299
300 l.reverse();
301 r.reverse();
302 list.insert(l);
303 list.insert(r);
304
305 list.reverse();
306 i = 1;
307 for (HTList::Iterator it = list; it.has_curr(); it.next(), ++i)
308 EXPECT_EQ(it.get_curr()->to_data<int>(), i);
309
310}
311
313{
314 list.rotate_left(3);
315
316 {
317 auto it = list.get_it();
318 for (int i = 0, n = 4; i < 3; ++i, ++n, it.next())
319 EXPECT_EQ(it.get_curr(), n);
320 }
321
322 list.rotate_left(22);
323 int i = 1;
324 for (auto it = list.get_it(); it.has_curr(); it.next(), ++i)
325 EXPECT_EQ(it.get_curr(), i);
326}
327
329{
330 DynList<int> ll = { 0, -1, -2, -3, -4, -5, -6, -7, -8, -9 };
331 DynList<int> lg = { 26, 27, 28, 29, 30, 31, 32, 33, 34, 35 };
332
333 ll.reverse();
334
335 list.insert(std::move(ll));
336 list.append(std::move(lg));
337
338 EXPECT_TRUE(ll.is_empty());
339 EXPECT_TRUE(lg.is_empty());
340
341 int i = -9;
342 for (auto it = list.get_it(); it.has_curr(); it.next(), ++i)
343 EXPECT_EQ(it.get_curr(), i);
344}
345
347{
349 size_t n = 0;
350 auto ret = m.traverse([&n] (int) { ++n; return true; });
352 EXPECT_EQ(n, 0);
353}
354
356{
357 EXPECT_TRUE(list.size() > 0);
358 EXPECT_EQ(list.size(), n);
359 int N = 0;
360 auto ret = list.traverse([&N, this] (int i) { ++N; return i < n/2; });
362 EXPECT_EQ(N, n/2);
363}
364
366{
367 // empty list
368 {
369 DynList<int> empty;
370 auto arr = to_array(empty);
371 EXPECT_EQ(arr.size(), 0u);
372 }
373
374 // single element
375 {
376 DynList<int> one;
377 one.append(42);
378 auto arr = to_array(one);
379 ASSERT_EQ(arr.size(), 1u);
380 EXPECT_EQ(arr(0), 42);
381 }
382
383 // multiple elements — order preserved
384 DynList<int> list;
385 for (int v : {5, 8, 13})
386 list.append(v);
387
388 auto arr = to_array(list);
389
390 ASSERT_EQ(arr.size(), list.size());
391 size_t i = 0;
392 for (auto it = list.get_it(); it.has_curr(); it.next(), ++i)
393 EXPECT_EQ(arr(i), it.get_curr());
394}
395
Conversion utilities between Aleph-w and STL container types.
Deduplicate sequential Aleph containers in-place.
Dynamic singly linked list with functional programming support.
Definition htlist.H:1155
T & insert(const T &item)
Definition htlist.H:1220
T & append(const T &item)
Definition htlist.H:1271
T & get_last() const
Return the last item of the list.
Definition htlist.H:1363
T & get_first() const
Return the first item of the list.
Definition htlist.H:1375
DynList & rev() noexcept
Definition htlist.H:1475
void clear() noexcept
Empties the container.
Definition htlist.H:1411
DynList & reverse() noexcept
Definition htlist.H:1469
DynList & swap(DynList &l) noexcept
Definition htlist.H:1176
bool has_curr() const noexcept
Definition htlist.H:930
constexpr bool is_empty() const noexcept
Definition htlist.H:419
void rotate_left(size_t n)
Rotate to left the list n positions.
Definition htlist.H:1090
size_t split(HTList &l, HTList &r) noexcept
Definition htlist.H:778
size_t size() const noexcept
Count the number of elements of the list.
Definition htlist.H:1065
bool is_unitarian() const noexcept
Return true if the list contains exactly just one.
Definition htlist.H:424
bool is_unitarian_or_empty() const noexcept
Return true if list contains one element or is empty.
Definition htlist.H:431
bool contains(const Type &item) const
Test if an item is present in the container using equality.
Definition ah-dry.H:563
auto get_it() const
Return a properly initialized iterator positioned at the first item on the container.
Definition ah-dry.H:222
#define TEST(name)
TEST_F(List_of_25_items, Basic_operations)
Definition dynlist.cc:215
#define N
Definition fib.C:294
Singly linked list implementations with head-tail access.
Main namespace for Aleph-w library functions.
Definition ah-arena.H:89
Array< typename C::Item_Type > to_array(const C &c)
Convenience wrapper identical to to_Array (copy contents).
Definition ah-convert.H:180
void in_place_unique(Container &c, Compare cmp={})
Remove duplicates in-place preserving first occurrence order.
Definition ah-unique.H:74
void reverse(Itor beg, Itor end)
Reverse elements in a range.
Definition ahAlgo.H:1094
bool eq(const C1 &c1, const C2 &c2, Eq e=Eq())
Check equality of two containers using a predicate.
T & swap(T &t1, T &t2)
Generic swap using object's swap method.
Definition ahTypes.H:121
bool traverse(Node *root, Op op)
Divide_Conquer_DP_Result< Cost > divide_and_conquer_partition_dp(const size_t groups, const size_t n, Transition_Cost_Fn transition_cost, const Cost inf=dp_optimization_detail::default_inf< Cost >())
Optimize partition DP using divide-and-conquer optimization.
void rotate_left(T *ptr, const size_t n, size_t m) noexcept
Rotate array elements left by m positions.
bool traverse(Operation &operation) noexcept(traverse_is_noexcept< Operation >())
Traverse the container via its iterator and performs a conditioned operation on each item.
Definition ah-dry.H:97
DynList< int > rlist
Definition dynlist.cc:51
DynList< int > list
Definition dynlist.cc:50
FooMap m(5, fst_unit_pair_hash, snd_unit_pair_hash)
DynList< char > l3
DynList< int > l1
DynList< int > l2
gsl_rng * r
DynList< int > l