Aleph-w 3.0
A C++ Library for Data Structures and Algorithms
Loading...
Searching...
No Matches
dynslist.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
38#include <gtest/gtest.h>
39
40#include <tpl_dynSlist.H>
41
42#include <random>
43#include <vector>
44
45using namespace Aleph;
46using namespace testing;
47
48namespace {
49
50struct Movable
51{
52 static inline int move_count = 0;
53 int value;
54
55 Movable() : value(0) {}
56 Movable(int v) : value(v) {}
57 Movable(const Movable &) = default;
58 Movable & operator=(const Movable &) = default;
59
60 Movable(Movable && other) noexcept : value(other.value)
61 {
62 other.value = -1;
63 ++move_count;
64 }
65
66 Movable & operator=(Movable && other) noexcept
67 {
68 if (this != &other)
69 {
70 value = other.value;
71 other.value = -1;
72 ++move_count;
73 }
74 return *this;
75 }
76};
77
78} // namespace
79
81{
82 DynSlist<int> list;
83 list.insert(0, 1);
84 list.insert(1, 3);
85 list.insert(1, 2); // middle insert
86
87 ASSERT_EQ(list.size(), 3u);
88 EXPECT_EQ(list[0], 1);
89 EXPECT_EQ(list[1], 2);
90 EXPECT_EQ(list[2], 3);
91
92 list.remove(1);
93 EXPECT_EQ(list.size(), 2u);
94 EXPECT_EQ(list[0], 1);
95 EXPECT_EQ(list[1], 3);
96}
97
99{
100 Movable::move_count = 0;
102 Movable m1(10);
103 list.insert(0, std::move(m1));
104 EXPECT_EQ(list.size(), 1u);
105 EXPECT_EQ(list[0].value, 10);
106 EXPECT_EQ(Movable::move_count, 1);
107}
108
110{
111 DynSlist<int> list;
112 EXPECT_THROW(list.remove(0), std::out_of_range);
113 EXPECT_THROW(list.insert(2, 5), std::out_of_range);
114 list.insert(0, 7);
115 EXPECT_THROW((void)list[1], std::out_of_range);
116}
117
119{
120 DynSlist<int> list;
121 for (int i = 0; i < 5; ++i)
122 list.insert(i, i + 1);
123
124 std::vector<int> got;
126 for (; it.has_curr(); it.next())
127 got.push_back(it.get_curr());
128
129 EXPECT_EQ(got, (std::vector<int>{1, 2, 3, 4, 5}));
130}
131
133{
134 DynSlist<int> list;
135 for (int i = 0; i < 4; ++i)
136 list.insert(i, 10 + i);
137
138 const DynSlist<int> & c = list;
139 EXPECT_EQ(c[0], 10);
140 EXPECT_EQ(c[1], 11);
141 EXPECT_EQ(c[2], 12);
142 EXPECT_EQ(c[3], 13);
143 EXPECT_THROW((void)c[4], std::out_of_range);
144}
145
147{
149 for (int i = 0; i < 5; ++i)
150 a.insert(i, i);
151
152 DynSlist<int> b(a);
153 ASSERT_EQ(b.size(), 5u);
154 for (size_t i = 0; i < b.size(); ++i)
155 EXPECT_EQ(b[i], static_cast<int>(i));
156
157 a.remove(0);
158 a.insert(0, 42);
159
160 EXPECT_EQ(b[0], 0);
161 EXPECT_EQ(a[0], 42);
162}
163
165{
167 for (int i = 0; i < 3; ++i)
168 a.insert(i, i + 1);
169
171 b.insert(0, 99);
172 b = a;
173
174 ASSERT_EQ(b.size(), 3u);
175 EXPECT_EQ(b[0], 1);
176 EXPECT_EQ(b[1], 2);
177 EXPECT_EQ(b[2], 3);
178
179 a = a;
180 ASSERT_EQ(a.size(), 3u);
181 EXPECT_EQ(a[0], 1);
182 EXPECT_EQ(a[1], 2);
183 EXPECT_EQ(a[2], 3);
184}
185
187{
189 for (int i = 0; i < 4; ++i)
190 a.insert(i, 10 + i);
191
192 DynSlist<int> b(std::move(a));
193
194 ASSERT_EQ(b.size(), 4u);
195 EXPECT_EQ(b[0], 10);
196 EXPECT_EQ(b[1], 11);
197 EXPECT_EQ(b[2], 12);
198 EXPECT_EQ(b[3], 13);
199
200 EXPECT_EQ(a.size(), 0u);
201 EXPECT_THROW((void)a[0], std::out_of_range);
202
203 a.insert(0, 7);
204 EXPECT_EQ(a.size(), 1u);
205 EXPECT_EQ(a[0], 7);
206}
207
209{
211 for (int i = 0; i < 3; ++i)
212 a.insert(i, i);
213
215 b.insert(0, 77);
216
217 b = std::move(a);
218
219 ASSERT_EQ(b.size(), 3u);
220 EXPECT_EQ(b[0], 0);
221 EXPECT_EQ(b[1], 1);
222 EXPECT_EQ(b[2], 2);
223 EXPECT_EQ(a.size(), 0u);
224}
225
227{
228 Movable::move_count = 0;
230 Movable m(10);
231
232 EXPECT_THROW(list.insert(-1, std::move(m)), std::out_of_range);
233 EXPECT_EQ(Movable::move_count, 0);
234 EXPECT_EQ(m.value, 10);
235
236 EXPECT_THROW(list.remove(-1), std::out_of_range);
237}
238
240{
241 DynSlist<int> list;
242 std::vector<int> oracle;
243
244 std::mt19937 rng(123456);
245 std::uniform_int_distribution<int> op_dist(0, 1);
246 std::uniform_int_distribution<int> val_dist(-100, 100);
247
248 for (int step = 0; step < 300; ++step)
249 {
250 const int op = op_dist(rng);
251 if (op == 0)
252 {
253 const int v = val_dist(rng);
254 std::uniform_int_distribution<int> pos_dist(0, static_cast<int>(oracle.size()));
255 const int pos = pos_dist(rng);
256 list.insert(pos, v);
257 oracle.insert(oracle.begin() + pos, v);
258 }
259 else
260 {
261 if (oracle.empty())
262 {
263 EXPECT_THROW(list.remove(0), std::out_of_range);
264 }
265 else
266 {
267 std::uniform_int_distribution<int> pos_dist(0, static_cast<int>(oracle.size() - 1));
268 const int pos = pos_dist(rng);
269 list.remove(pos);
270 oracle.erase(oracle.begin() + pos);
271 }
272 }
273
274 ASSERT_EQ(list.size(), oracle.size());
275 for (size_t i = 0; i < oracle.size(); ++i)
276 EXPECT_EQ(list[i], oracle[i]);
277 }
278}
T & insert(const T &item)
Insert a new item by copy.
Definition htlist.H:1502
void empty() noexcept
empty the list
Definition htlist.H:1689
Iterator specialized for DynSlist returning payload references.
T & get_curr()
Return a reference to the current payload.
Dynamic list of elements of type T implemented with a singly linked list of nodes.
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, const T &data)
Insert an element at position pos.
size_t size() const noexcept
Count the number of elements of the list.
Definition htlist.H:1319
void next()
Advance the iterator to the next node.
Definition tpl_slist.H:215
bool has_curr() const noexcept
Return true if the iterator currently points to a node.
Definition tpl_slist.H:198
iterator begin() noexcept
Return an STL-compatible iterator to the first element.
#define TEST(name)
static mt19937 rng
Main namespace for Aleph-w library functions.
Definition ah-arena.H:89
DynList< T > maps(const C &c, Op op)
Classic map operation.
Dynamic singly linked list.