Aleph-w 3.0
A C++ Library for Data Structures and Algorithms
Loading...
Searching...
No Matches
arrayqueue.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(ArrayQueue, empty_queue)
77{
80 EXPECT_EQ(q.size(), 0);
81 EXPECT_THROW(q.rear(), range_error);
82 EXPECT_THROW(q.front(), range_error);
83 EXPECT_THROW(q.rear(2), range_error);
84 EXPECT_THROW(q.front(2), range_error);
85 EXPECT_THROW(q.rear(q.capacity()), range_error);
86 EXPECT_THROW(q.front(q.capacity()), range_error);
87 EXPECT_THROW(q.get(), underflow_error);
88 EXPECT_THROW(q.getn(0), underflow_error);
89 EXPECT_THROW(q.getn(1), underflow_error);
90 EXPECT_THROW(q.getn(q.capacity()), underflow_error);
91}
92
94{
96 const size_t N = q.capacity();
97 for (int i = 0; i < N; ++i)
98 {
99 ASSERT_EQ(q.put(i), i);
100 ASSERT_EQ(q.rear(), i);
101 ASSERT_EQ(q.front(), 0);
102 }
103 EXPECT_EQ(q.size(), N);
105
106 for (int i = 0; i < N; ++i)
107 {
108 ASSERT_EQ(q.front(i), i);
109 ASSERT_EQ(q.rear(i), N - i - 1);
110 }
111
112 for (int i = 0; i < N; ++i)
113 {
114 ASSERT_EQ(q.front(), i);
115 ASSERT_EQ(q.rear(), N - 1);
116 ASSERT_EQ(q.get(), i);
117 }
119 EXPECT_EQ(q.size(), 0);
120 EXPECT_EQ(q.capacity(), N);
121}
122
124{
125 EXPECT_LT(q.size(), q.capacity());
126
127 // fill until complete initial_cap
128 for (int i = q.size(); i < q.capacity(); ++i)
129 ASSERT_EQ(q.put(i), i);
130
131 EXPECT_EQ(q.size(), q.capacity());
132
133 for (size_t i = 0; i < q.size(); ++i)
134 {
135 ASSERT_EQ(q.front(i), i);
136 ASSERT_EQ(q.rear(i), q.size() - i - 1);
137 }
138
139 // now put more entries
140 for (size_t i = q.size(), n = 2*q.size(); i < n; ++i)
141 ASSERT_EQ(q.put(i), i);
142
143 EXPECT_EQ(q.size(), q.capacity());
144
145 const size_t nn = q.size();
146
147 // get out the half
148 for (size_t i = 0; i < nn/2; ++i)
149 ASSERT_EQ(q.get(), i);
150
151 EXPECT_EQ(q.size(), nn/2);
152
153 // test consistency of remaining items
154 for (size_t i = 0; i < nn/2; ++i)
155 ASSERT_EQ(q.front(i), i + nn/2);
156
157 // now extract them all
158 for (size_t i = 0; i < nn/2; ++i)
159 ASSERT_EQ(q.get(), i + nn/2);
160
161 EXPECT_EQ(q.size(), 0);
162 EXPECT_TRUE(q.is_empty());
163
164 // now we put the queue thus
165 //
166 // xxx------xxxxxxx
167 //
168 // where x is an item
169 const size_t cap = 16;
170 for (size_t i = 0; i < cap; ++i)
171 ASSERT_EQ(q.put(i), i);
172
173 for (size_t i = 0; i < cap/4; ++i) // extract a fourth
174 ASSERT_EQ(q.get(), i);
175
176 ASSERT_FALSE(q.is_empty());
177 ASSERT_EQ(q.size(), 3*cap/4);
178
179 for (size_t i = 0; i < cap/4; ++i) // put them again
180 ASSERT_EQ(q.put(i), i);
181
182 for (size_t i = 0; i < 3*cap/4; ++i) // extract and verify the 3/4 oldest
183 ASSERT_EQ(q.get(), cap/4 + i);
184
185 // now extract and verify the 1/4 remaining
186 for (size_t i = 0; i < cap/4; ++i)
187 ASSERT_EQ(q.get(), i);
188}
189
191{
192 EXPECT_LT(q.size(), q.capacity());
193
194 // fill until complete initial_cap
195 for (int i = q.size(); i < q.capacity(); ++i)
196 {
197 auto & l = q.put({int(i), 1, 2, int(i)});
198 ASSERT_EQ(l.get_first(), i);
199 ASSERT_EQ(l.get_last(), i);
200 ASSERT_EQ(l.nth(1), 1);
201 ASSERT_EQ(l.nth(2), 2);
202 }
203
204 EXPECT_EQ(q.size(), q.capacity());
205
206 for (size_t i = 0; i < q.size(); ++i)
207 {
208 auto & lf = q.front(i);
209 ASSERT_EQ(lf.get_first(), i);
210 ASSERT_EQ(lf.get_last(), i);
211 ASSERT_EQ(lf.nth(1), 1);
212 ASSERT_EQ(lf.nth(2), 2);
213
214 auto & lr = q.rear(i);
215 ASSERT_EQ(lr.get_first(), q.size() - i - 1);
216 ASSERT_EQ(lr.get_last(), q.size() - i - 1);
217 ASSERT_EQ(lr.nth(1), 1);
218 ASSERT_EQ(lr.nth(2), 2);
219 }
220
221 // now put more entries
222 for (size_t i = q.size(), n = 2*q.size(); i < n; ++i)
223 {
224 auto & l = q.put({int(i), 1, 2, int(i)});
225 ASSERT_EQ(l.get_first(), i);
226 ASSERT_EQ(l.get_last(), i);
227 ASSERT_EQ(l.nth(1), 1);
228 ASSERT_EQ(l.nth(2), 2);
229 }
230
231 EXPECT_EQ(q.size(), q.capacity());
232
233 const size_t nn = q.size();
234
235 // get out the half
236 for (size_t i = 0; i < nn/2; ++i)
237 {
238 auto l = q.get();
239 ASSERT_EQ(l.get_first(), i);
240 ASSERT_EQ(l.get_last(), i);
241 ASSERT_EQ(l.nth(1), 1);
242 ASSERT_EQ(l.nth(2), 2);
243 }
244
245 EXPECT_EQ(q.size(), nn/2);
246
247 // test consistency of remaining items
248 for (size_t i = 0; i < nn/2; ++i)
249 {
250 auto & l = q.front(i);
251 ASSERT_EQ(l.get_first(), i + nn/2);
252 ASSERT_EQ(l.get_last(), i + nn/2);
253 ASSERT_EQ(l.nth(1), 1);
254 ASSERT_EQ(l.nth(2), 2);
255 }
256
257 // now extract them all
258 for (size_t i = 0; i < nn/2; ++i)
259 {
260 auto l = q.get();
261 ASSERT_EQ(l.get_first(), i + nn/2);
262 ASSERT_EQ(l.get_last(), i + nn/2);
263 ASSERT_EQ(l.nth(1), 1);
264 ASSERT_EQ(l.nth(2), 2);
265 }
266
267 EXPECT_EQ(q.size(), 0);
268 EXPECT_TRUE(q.is_empty());
269
270 // now we put the queue thus
271 //
272 // xxx------xxxxxxx
273 //
274 // where x is an item
275 const size_t cap = 16;
276 for (size_t i = 0; i < cap; ++i)
277 {
278 auto & l = q.put({int(i), 1, 2, int(i)});
279 ASSERT_EQ(l.get_first(), i);
280 ASSERT_EQ(l.get_last(), i);
281 ASSERT_EQ(l.nth(1), 1);
282 ASSERT_EQ(l.nth(2), 2);
283 }
284
285 for (size_t i = 0; i < cap/4; ++i) // extract a fourth
286 {
287 auto l = q.get();
288 ASSERT_EQ(l.get_first(), i);
289 ASSERT_EQ(l.get_last(), i);
290 ASSERT_EQ(l.nth(1), 1);
291 ASSERT_EQ(l.nth(2), 2);
292 }
293
294 ASSERT_FALSE(q.is_empty());
295 ASSERT_EQ(q.size(), 3*cap/4);
296
297 for (size_t i = 0; i < cap/4; ++i) // put them again
298 {
299 auto l = q.put({int(i), 1, 2, int(i)});
300 ASSERT_EQ(l.get_first(), i);
301 ASSERT_EQ(l.get_last(), i);
302 ASSERT_EQ(l.nth(1), 1);
303 ASSERT_EQ(l.nth(2), 2);
304 }
305
306 for (size_t i = 0; i < 3*cap/4; ++i) // extract and verify the 3/4 oldest
307 {
308 auto l = q.get();
309 ASSERT_EQ(l.get_first(), cap/4 + i);
310 ASSERT_EQ(l.get_last(), cap/4 + i);
311 ASSERT_EQ(l.nth(1), 1);
312 ASSERT_EQ(l.nth(2), 2);
313 }
314
315 // now extract and verify the 1/4 remaining
316 for (size_t i = 0; i < cap/4; ++i)
317 {
318 auto l = q.get();
319 ASSERT_EQ(l.get_first(), i);
320 ASSERT_EQ(l.get_last(), i);
321 ASSERT_EQ(l.nth(1), 1);
322 ASSERT_EQ(l.nth(2), 2);
323 }
324}
325
327{
329 auto it = q.get_it();
330 ASSERT_FALSE(it.has_curr());
331 ASSERT_THROW(it.get_curr(), overflow_error);
332 ASSERT_THROW(it.next(), overflow_error);
333 ASSERT_THROW(it.prev(), underflow_error);
334}
335
336static size_t primes[] = {13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59,
337 61, 67, 71, 73, 79, 83, 89, 97, 197 };
338TEST(ArrayQueue, Iterator)
339{
340 for (size_t i = 0, N = primes[i]; N < 100; ++i, N = primes[i])
341 {
343
344 for (size_t i = 0; i < N; ++i)
345 ASSERT_EQ(q.put(i), i);
346
347 int k = 0;
348 for (auto it = q.get_it(); it.has_curr(); it.next(), ++k)
349 ASSERT_EQ(it.get_curr(), k);
350 ASSERT_EQ(k, N); // test that queue has been traversed
351
352 // extract 1/4 of items
353 for (size_t i = 0; i < N/4; ++i)
354 ASSERT_EQ(q.get(), i);
355
357
358 // Test iterator again
359 k = N/4;
360 for (auto it = q.get_it(); it.has_curr(); it.next(), ++k)
361 ASSERT_EQ(it.get_curr(), k);
362 ASSERT_EQ(k, N); // test that queue has been traversed
363
364 // now put again N/4 for testing iterator on queue of form xxx----xxxxxxx
365 for (size_t i = 0; i < N/4; ++i)
366 ASSERT_EQ(q.put(i), i);
367 ASSERT_EQ(q.size(), N);
368
369 // now test if iterator still works
370 k = 0;
371 for (auto it = q.get_it(); it.has_curr(); it.next(), ++k)
372 ASSERT_EQ(it.get_curr(), (k + N/4) % N);
373 ASSERT_EQ(k, N); // test that queue has been traversed
374
375 k = N - 1;
376 auto it = q.get_it();
377 it.reset_last();
378 for (; it.has_curr(); it.prev(), --k)
379 ASSERT_EQ(it.get_curr(), (k + N/4) % N);
380 ASSERT_EQ(k, -1); // test that queue has been traversed
381 }
382}
383
385{
386 for (size_t i = 0, N = primes[i]; N < 100; ++i, N = primes[i])
387 {
389
390 for (size_t i = 0; i < N; ++i)
391 ASSERT_EQ(q.put(i), i);
392
393 int k = 0;
394 auto ret = q.traverse([&k] (int i) { return i == k++; });
396 ASSERT_EQ(k, N);
397
398 // extract 1/4 of items
399 for (size_t i = 0; i < N/4; ++i)
400 ASSERT_EQ(q.get(), i);
401
403
404 // Test traverse
405 k = N/4;
406 ret = q.traverse([&k] (int i) { return i == k++; });
408 ASSERT_EQ(k, N);
409
410 // now put again N/4 for testing iterator on queue of form xxx----xxxxxxx
411 for (size_t i = 0; i < N/4; ++i)
412 ASSERT_EQ(q.put(i), i);
413 ASSERT_EQ(q.size(), N);
414
415 // now test if iterator still works
416 k = 0;
417 ret = q.traverse([&k, N] (int i) { return i == (k++ + N/4) % N; });
419 ASSERT_EQ(k, N);
420
421 // finally test partial traverse
422 k = 0;
423 ret = q.traverse([&k, n = N/4] (int) { return ++k < n; });
425 ASSERT_EQ(k, N/4);
426 }
427}
428
430{
431 size_t N = 31;
432 {
434 for (size_t i = 0; i < N; ++i)
435 ASSERT_EQ(q.put(i), i);
436
437 {
439 ASSERT_TRUE(eq(q, qc));
440 }
441
442 {
445 ASSERT_EQ(q.size(), 0);
446 int k = 0;
447 auto ret = qc.traverse([&k] (int i) { return i == k++; });
449 ASSERT_EQ(k, qc.size());
450
451 q.swap(qc);
452 ASSERT_EQ(qc.size(), 0);
454 ASSERT_EQ(q.size(), N);
456 }
457
459 qc = q;
460 ASSERT_TRUE(eq(q, qc));
461
462 qc.empty();
463 ASSERT_EQ(qc.size(), 0);
465
466 qc = move(q);
468 ASSERT_EQ(q.size(), 0);
469 int k = 0;
470 auto ret = qc.traverse([&k] (int i) { return i == k++; });
472 ASSERT_EQ(k, qc.size());
473 }
474}
475
Functional programming utilities for Aleph-w containers.
TEST_F(SimpleQueue, put_and_get_stress)
static size_t primes[]
constexpr size_t N
Definition arrayqueue.cc:48
Queue implemented with a single dynamic array.
T & front(const size_t i=0) const
Return the i-th oldest item of the queue.
bool traverse(Operation &operation)
Traverse all the elements from the youngest to the oldest and execute operation on each on them.
T & getn(const size_t i)
Remove the i oldest items of the queue.
T & put(const T &item)
Copy and put an item in the queue.
T & rear(const size_t i=0) const
Return the i-th youngest item of the queue.
T get()
Remove the oldest item of the queue and return a copy.
void swap(ArrayQueue &q) noexcept
Swap this with q
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
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
size_t size() const noexcept
Return the number of elements.
constexpr size_t capacity() const noexcept
The type of element of array.
bool is_empty() const noexcept
Return true is the array is empty.
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)
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.
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 arrayqueue.cc:59
Circular queue implementations backed by arrays.
DynList< int > l