Aleph-w 3.0
A C++ Library for Data Structures and Algorithms
Loading...
Searching...
No Matches
fixedqueue.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 <tpl_arrayQueue.H>
41
42# include <ahFunctional.H>
43
44using namespace std;
45using namespace testing;
46using namespace Aleph;
47
48constexpr size_t N = 17;
49
50struct SimpleQueue : public Test
51{
52 size_t n = 0;
55 {
56 for (size_t i = 0; i < N; ++i, ++n)
57 q.put(i);
58 }
59 void print() const
60 {
61 cout << "q ="; q.for_each([] (auto i) { cout << " " << i; }); cout << endl;
62 }
63};
64
65struct ComplexQueue : public Test
66{
67 size_t n = 0;
70 {
71 for (size_t i = 0; i < N; ++i, ++n)
72 q.put({ int(i), 1, 2, int(i) });
73 }
74};
75
76TEST(FixedQueue, empty_queue)
77{
80 EXPECT_EQ(q.size(), 0);
81}
82
84{
86 const size_t N = q.capacity();
87 for (int i = 0; i < N; ++i)
88 {
89 ASSERT_EQ(q.put(i), i);
90 ASSERT_EQ(q.rear(), i);
91 ASSERT_EQ(q.front(), 0);
92 }
93 EXPECT_EQ(q.size(), N);
95
96 for (int i = 0; i < N; ++i)
97 {
98 ASSERT_EQ(q.front(i), i);
99 ASSERT_EQ(q.rear(i), N - i - 1);
100 }
101
102 for (int i = 0; i < N; ++i)
103 {
104 ASSERT_EQ(q.front(), i);
105 ASSERT_EQ(q.rear(), N - 1);
106 ASSERT_EQ(q.get(), i);
107 }
109 EXPECT_EQ(q.size(), 0);
110 EXPECT_EQ(q.capacity(), N);
111}
112
114{
115 EXPECT_LT(q.size(), q.capacity());
116
117 // fill until complete initial_cap
118 for (int i = q.size(); i < q.capacity(); ++i)
119 ASSERT_EQ(q.put(i), i);
120
121 EXPECT_EQ(q.size(), q.capacity());
122
123 for (size_t i = 0; i < q.size(); ++i)
124 {
125 ASSERT_EQ(q.front(i), i);
126 ASSERT_EQ(q.rear(i), q.size() - i - 1);
127 }
128
129 const size_t nn = q.size();
130
131 // get out the half
132 for (size_t i = 0; i < nn/2; ++i)
133 ASSERT_EQ(q.get(), i);
134
135 EXPECT_EQ(q.size(), nn/2);
136
137 // test consistency of remaining items
138 for (size_t i = 0; i < nn/2; ++i)
139 ASSERT_EQ(q.front(i), i + nn/2);
140
141 // now extract them all
142 for (size_t i = 0; i < nn/2; ++i)
143 ASSERT_EQ(q.get(), i + nn/2);
144
145 EXPECT_EQ(q.size(), 0);
146 EXPECT_TRUE(q.is_empty());
147
148 // now we put the queue thus
149 //
150 // xxx------xxxxxxx
151 //
152 // where x is an item
153 const size_t cap = q.capacity();
154 for (size_t i = 0; i < cap; ++i)
155 ASSERT_EQ(q.put(i), i);
156
157 for (size_t i = 0; i < cap/4; ++i) // extract a fourth
158 ASSERT_EQ(q.get(), i);
159
160 ASSERT_FALSE(q.is_empty());
161 ASSERT_EQ(q.size(), 3*cap/4);
162
163 for (size_t i = 0; i < cap/4; ++i) // put them again
164 ASSERT_EQ(q.put(i), i);
165
166 for (size_t i = 0; i < 3*cap/4; ++i) // extract and verify the 3/4 oldest
167 ASSERT_EQ(q.get(), cap/4 + i);
168
169 // now extract and verify the 1/4 remaining
170 for (size_t i = 0; i < cap/4; ++i)
171 ASSERT_EQ(q.get(), i);
172}
173
175{
176 EXPECT_LT(q.size(), q.capacity());
177
178 // fill until complete initial_cap
179 for (int i = q.size(); i < q.capacity(); ++i)
180 {
181 auto & l = q.put({int(i), 1, 2, int(i)});
182 ASSERT_EQ(l.get_first(), i);
183 ASSERT_EQ(l.get_last(), i);
184 ASSERT_EQ(l.nth(1), 1);
185 ASSERT_EQ(l.nth(2), 2);
186 }
187
188 EXPECT_EQ(q.size(), q.capacity());
189
190 for (size_t i = 0; i < q.size(); ++i)
191 {
192 auto & lf = q.front(i);
193 ASSERT_EQ(lf.get_first(), i);
194 ASSERT_EQ(lf.get_last(), i);
195 ASSERT_EQ(lf.nth(1), 1);
196 ASSERT_EQ(lf.nth(2), 2);
197
198 auto & lr = q.rear(i);
199 ASSERT_EQ(lr.get_first(), q.size() - i - 1);
200 ASSERT_EQ(lr.get_last(), q.size() - i - 1);
201 ASSERT_EQ(lr.nth(1), 1);
202 ASSERT_EQ(lr.nth(2), 2);
203 }
204
205 const size_t nn = q.size();
206
207 // get out the half
208 for (size_t i = 0; i < nn/2; ++i)
209 {
210 auto l = q.get();
211 ASSERT_EQ(l.get_first(), i);
212 ASSERT_EQ(l.get_last(), i);
213 ASSERT_EQ(l.nth(1), 1);
214 ASSERT_EQ(l.nth(2), 2);
215 }
216
217 EXPECT_EQ(q.size(), nn/2);
218
219 // test consistency of remaining items
220 for (size_t i = 0; i < nn/2; ++i)
221 {
222 auto & l = q.front(i);
223 ASSERT_EQ(l.get_first(), i + nn/2);
224 ASSERT_EQ(l.get_last(), i + nn/2);
225 ASSERT_EQ(l.nth(1), 1);
226 ASSERT_EQ(l.nth(2), 2);
227 }
228
229 // now extract them all
230 for (size_t i = 0; i < nn/2; ++i)
231 {
232 auto l = q.get();
233 ASSERT_EQ(l.get_first(), i + nn/2);
234 ASSERT_EQ(l.get_last(), i + nn/2);
235 ASSERT_EQ(l.nth(1), 1);
236 ASSERT_EQ(l.nth(2), 2);
237 }
238
239 EXPECT_EQ(q.size(), 0);
240 EXPECT_TRUE(q.is_empty());
241
242 // now we put the queue thus
243 //
244 // xxx------xxxxxxx
245 //
246 // where x is an item
247 const size_t cap = q.capacity();
248 for (size_t i = 0; i < cap; ++i)
249 {
250 auto & l = q.put({int(i), 1, 2, int(i)});
251 ASSERT_EQ(l.get_first(), i);
252 ASSERT_EQ(l.get_last(), i);
253 ASSERT_EQ(l.nth(1), 1);
254 ASSERT_EQ(l.nth(2), 2);
255 }
256
257 for (size_t i = 0; i < cap/4; ++i) // extract a fourth
258 {
259 auto l = q.get();
260 ASSERT_EQ(l.get_first(), i);
261 ASSERT_EQ(l.get_last(), i);
262 ASSERT_EQ(l.nth(1), 1);
263 ASSERT_EQ(l.nth(2), 2);
264 }
265
266 ASSERT_FALSE(q.is_empty());
267 ASSERT_EQ(q.size(), 3*cap/4);
268
269 for (size_t i = 0; i < cap/4; ++i) // put them again
270 {
271 auto l = q.put({int(i), 1, 2, int(i)});
272 ASSERT_EQ(l.get_first(), i);
273 ASSERT_EQ(l.get_last(), i);
274 ASSERT_EQ(l.nth(1), 1);
275 ASSERT_EQ(l.nth(2), 2);
276 }
277
278 for (size_t i = 0; i < 3*cap/4; ++i) // extract and verify the 3/4 oldest
279 {
280 auto l = q.get();
281 ASSERT_EQ(l.get_first(), cap/4 + i);
282 ASSERT_EQ(l.get_last(), cap/4 + i);
283 ASSERT_EQ(l.nth(1), 1);
284 ASSERT_EQ(l.nth(2), 2);
285 }
286
287 // now extract and verify the 1/4 remaining
288 for (size_t i = 0; i < cap/4; ++i)
289 {
290 auto l = q.get();
291 ASSERT_EQ(l.get_first(), i);
292 ASSERT_EQ(l.get_last(), i);
293 ASSERT_EQ(l.nth(1), 1);
294 ASSERT_EQ(l.nth(2), 2);
295 }
296}
297
299{
301 auto it = q.get_it();
302 ASSERT_FALSE(it.has_curr());
303 ASSERT_THROW(it.get_curr(), overflow_error);
304 ASSERT_THROW(it.next(), overflow_error);
305 ASSERT_THROW(it.prev(), underflow_error);
306}
307
308static size_t primes[] = {13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59,
309 61, 67, 71, 73, 79, 83, 89, 97, 197 };
310TEST(FixedQueue, Iterator)
311{
312 for (size_t i = 0, N = primes[i]; N < 100; ++i, N = primes[i])
313 //size_t N = 13;
314 {
316
317 for (size_t i = 0; i < N; ++i)
318 ASSERT_EQ(q.put(i), i);
319
320 int k = 0;
321 for (auto it = q.get_it(); it.has_curr(); it.next(), ++k)
322 ASSERT_EQ(it.get_curr(), k);
323 ASSERT_EQ(k, N); // test that queue has been traversed
324
325 // extract 1/4 of items
326 for (size_t i = 0; i < N/4; ++i)
327 ASSERT_EQ(q.get(), i);
328
330
331 // Test iterator again
332 k = N/4;
333 for (auto it = q.get_it(); it.has_curr(); it.next(), ++k)
334 ASSERT_EQ(it.get_curr(), k);
335 ASSERT_EQ(k, N); // test that queue has been traversed
336
337 // now put again N/4 for testing iterator on queue of form xxx----xxxxxxx
338 for (size_t i = 0; i < N/4; ++i)
339 ASSERT_EQ(q.put(i), i);
340 ASSERT_EQ(q.size(), N);
341
342 // now test if iterator still works
343 k = 0;
344 for (auto it = q.get_it(); it.has_curr(); it.next(), ++k)
345 ASSERT_EQ(it.get_curr(), (k + N/4) % N);
346 ASSERT_EQ(k, N); // test that queue has been traversed
347
348 k = N - 1;
349 auto it = q.get_it();
350 it.reset_last();
351 for (; it.has_curr(); it.prev(), --k)
352 ASSERT_EQ(it.get_curr(), (k + N/4) % N);
353 ASSERT_EQ(k, -1); // test that queue has been traversed
354 }
355}
356
358{
359 for (size_t i = 0, N = primes[i]; N < 100; ++i, N = primes[i])
360 {
362
363 for (size_t i = 0; i < N; ++i)
364 ASSERT_EQ(q.put(i), i);
365
366 int k = 0;
367 auto ret = q.traverse([&k] (int i) { return i == k++; });
369 ASSERT_EQ(k, N);
370
371 // extract 1/4 of items
372 for (size_t i = 0; i < N/4; ++i)
373 ASSERT_EQ(q.get(), i);
374
376 assert(not q.is_empty());
377
378 // Test traverse
379 k = N/4;
380 ret = q.traverse([&k] (int i) { return i == k++; });
382 ASSERT_EQ(k, N);
383
384 // now put again N/4 for testing iterator on queue of form xxx----xxxxxxx
385 for (size_t i = 0; i < N/4; ++i)
386 ASSERT_EQ(q.put(i), i);
387 ASSERT_EQ(q.size(), N);
388
389 // now test if iterator still works
390 k = 0;
391 ret = q.traverse([&k, N] (int i) { return i == (k++ + N/4) % N; });
393 ASSERT_EQ(k, N);
394
395 // finally test partial traverse
396 k = 0;
397 ret = q.traverse([&k, n = N/4] (int) { return ++k < n; });
399 ASSERT_EQ(k, N/4);
400 }
401}
402
404{
405 size_t N = 31;
406 {
408 for (size_t i = 0; i < N; ++i)
409 ASSERT_EQ(q.put(i), i);
410
411 {
413 ASSERT_TRUE(eq(q, qc));
414 }
415
416 {
419 ASSERT_EQ(q.size(), 0);
420 int k = 0;
421 auto ret = qc.traverse([&k] (int i) { return i == k++; });
423 ASSERT_EQ(k, qc.size());
424
425 q.swap(qc);
426 ASSERT_EQ(qc.size(), 0);
428 ASSERT_EQ(q.size(), N);
430 }
431
433 qc = q;
434 ASSERT_TRUE(eq(q, qc));
435
436 qc.empty();
437 ASSERT_EQ(qc.size(), 0);
439
440 qc = move(q);
442 ASSERT_EQ(q.size(), 0);
443 int k = 0;
444 auto ret = qc.traverse([&k] (int i) { return i == k++; });
446 ASSERT_EQ(k, qc.size());
447 }
448}
449
450
Functional programming utilities for Aleph-w containers.
T & put(const T &item)
Copy and put an item in the queue.
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
T & put(const T &item)
Definition htlist.H:1532
void empty() noexcept
empty the list
Definition htlist.H:1689
Very simple queue implemented with a contiguous array.
T & put(const T &item) noexcept
Put an item into the queue by copy.
bool traverse(Operation &operation)
Traverse all the elements from the youngest to the oldest and execute operation on each on them.
constexpr bool is_empty() const noexcept
Return true if the queue is empty.
T get() noexcept
Remove the oldest item of the queue.
void swap(FixedQueue &q) noexcept
constexpr size_t size() const noexcept
Return the number of items.
T & rear(const size_t i=0) const noexcept
Return the i-th youngest item.
constexpr size_t capacity() const noexcept
Return the queue capacity (maximum number of element to be stored)
T & front(const size_t i=0) const noexcept
Return the i-th oldest item.
constexpr bool is_empty() const noexcept
Return true if list is empty.
Definition htlist.H:523
size_t size() const noexcept
Count the number of elements of the list.
Definition htlist.H:1319
void for_each(Operation &operation)
Traverse all the container and performs an operation on each element.
Definition ah-dry.H:685
Type & nth(const size_t n)
Return the n-th item of container.
Definition ah-dry.H:267
auto get_it() const
Return a properly initialized iterator positioned at the first item on the container.
Definition ah-dry.H:190
#define TEST(name)
TEST_F(SimpleQueue, put_and_get_stress)
static size_t primes[]
constexpr size_t N
Definition fixedqueue.cc:48
Main namespace for Aleph-w library functions.
Definition ah-arena.H:89
bool eq(const C1 &c1, const C2 &c2, Eq e=Eq())
Check equality of two containers using a predicate.
bool traverse(Node *root, Op op)
DynList< T > maps(const C &c, Op op)
Classic map operation.
STL namespace.
FixedQueue< DynList< int > > q
Definition fixedqueue.cc:68
ArrayQueue< DynList< int > > q
Definition arrayqueue.cc:68
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:95
ArrayQueue< int > q
Definition arrayqueue.cc:53
void print() const
Definition fixedqueue.cc:59
FixedQueue< int > q
Definition fixedqueue.cc:53
Circular queue implementations backed by arrays.
DynList< int > l