Aleph-w 3.0
A C++ Library for Data Structures and Algorithms
Loading...
Searching...
No Matches
tpl_dynListQueue.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
42# include <gtest/gtest.h>
43
44# include <string>
45# include <memory>
46# include <vector>
47# include <stdexcept>
48
49# include <tpl_dynListQueue.H>
50# include <ahFunctional.H>
51# include <ah-zip.H>
52
53using namespace std;
54using namespace testing;
55using namespace Aleph;
56
57// =============================================================================
58// Test Fixture for Basic Operations
59// =============================================================================
60
61class DynListQueueTest : public ::testing::Test
62{
63protected:
66
67 static constexpr size_t N = 100;
68
69 void SetUp() override
70 {
71 for (size_t i = 0; i < N; ++i)
72 queue_with_items.put(static_cast<int>(i));
73 }
74};
75
76// =============================================================================
77// Construction Tests
78// =============================================================================
79
86
88{
89 DynListQueue<int> copy(queue_with_items);
90
91 EXPECT_EQ(copy.size(), queue_with_items.size());
92 EXPECT_EQ(copy.size(), N);
93
94 // Verify independent copies
95 while (!queue_with_items.is_empty())
96 {
97 EXPECT_EQ(queue_with_items.get(), copy.get());
98 }
99 EXPECT_TRUE(queue_with_items.is_empty());
100 EXPECT_TRUE(copy.is_empty());
101}
102
104{
105 DynListQueue<int> source;
106 for (int i = 0; i < 10; ++i)
107 source.put(i);
108
109 size_t original_size = source.size();
110 DynListQueue<int> moved(std::move(source));
111
113 EXPECT_TRUE(source.is_empty()); // Source should be empty after move
114
115 // Verify content
116 for (int i = 0; i < 10; ++i)
117 EXPECT_EQ(moved.get(), i);
118}
119
121{
122 DynListQueue<int> q = {1, 2, 3, 4, 5};
123
124 EXPECT_EQ(q.size(), 5u);
125 EXPECT_EQ(q.front(), 1);
126 EXPECT_EQ(q.rear(), 5);
127}
128
130{
131 std::vector<int> vec = {10, 20, 30, 40, 50};
133
134 EXPECT_EQ(q.size(), vec.size());
135 for (int val : vec)
136 EXPECT_EQ(q.get(), val);
137}
138
140{
141 DynList<int> list = {100, 200, 300};
142 DynListQueue<int> q(list);
143
144 EXPECT_EQ(q.size(), list.size());
145 // Elements should be in the same order
146 auto it = list.get_it();
147 while (!q.is_empty() && it.has_curr())
148 {
149 EXPECT_EQ(q.get(), it.get_curr());
150 it.next();
151 }
152}
153
154// =============================================================================
155// Assignment Tests
156// =============================================================================
157
159{
161 q.put(999); // Pre-existing content
162
163 q = queue_with_items;
164
165 EXPECT_EQ(q.size(), N);
166 EXPECT_EQ(q.front(), 0);
167 EXPECT_EQ(q.rear(), static_cast<int>(N - 1));
168}
169
171{
172 DynListQueue<int> q = {1, 2, 3};
173 q = q; // Self-assignment
174
175 EXPECT_EQ(q.size(), 3u);
176 EXPECT_EQ(q.front(), 1);
177}
178
180{
181 DynListQueue<int> source = {1, 2, 3};
183 target.put(999);
184
185 target = std::move(source);
186
187 EXPECT_EQ(target.size(), 3u);
188 EXPECT_EQ(target.front(), 1);
189 // Source should have the old target content or be empty
190}
191
192// =============================================================================
193// Core Queue Operations Tests
194// =============================================================================
195
197{
199 int value = 42;
200
201 int& ref = q.put(value);
202
203 EXPECT_EQ(q.size(), 1u);
204 EXPECT_EQ(ref, 42);
205 EXPECT_EQ(q.front(), 42);
206 EXPECT_EQ(q.rear(), 42);
207}
208
210{
212 std::string value = "hello";
213
214 std::string& ref = q.put(std::move(value));
215
216 EXPECT_EQ(q.size(), 1u);
217 EXPECT_EQ(ref, "hello");
218 // Original might be empty or in valid but unspecified state
219}
220
222{
224
225 q.append(1);
226 q.insert(2);
227 q.put(3);
228
229 EXPECT_EQ(q.size(), 3u);
230 // All should be at rear (FIFO order)
231 EXPECT_EQ(q.get(), 1);
232 EXPECT_EQ(q.get(), 2);
233 EXPECT_EQ(q.get(), 3);
234}
235
237{
239 for (int i = 0; i < 10; ++i)
240 q.put(i);
241
242 for (int i = 0; i < 10; ++i)
243 {
244 EXPECT_EQ(q.front(), i);
245 EXPECT_EQ(q.get(), i);
246 }
247
249}
250
252{
254 EXPECT_THROW(q.get(), std::underflow_error);
255}
256
258{
259 EXPECT_EQ(queue_with_items.front(), 0);
260
261 // Multiple peeks should return same value
262 EXPECT_EQ(queue_with_items.front(), 0);
263 EXPECT_EQ(queue_with_items.front(), 0);
264
265 // Size should not change
266 EXPECT_EQ(queue_with_items.size(), N);
267}
268
270{
272 EXPECT_THROW(q.front(), std::underflow_error);
273}
274
276{
277 EXPECT_EQ(queue_with_items.rear(), static_cast<int>(N - 1));
278
279 // Multiple peeks should return same value
280 EXPECT_EQ(queue_with_items.rear(), static_cast<int>(N - 1));
281
282 // Size should not change
283 EXPECT_EQ(queue_with_items.size(), N);
284}
285
287{
289 EXPECT_THROW(q.rear(), std::underflow_error);
290}
291
293{
294 DynListQueue<int> q = {1, 2, 3};
295 q.front() = 100;
296
297 EXPECT_EQ(q.get(), 100);
298 EXPECT_EQ(q.get(), 2);
299}
300
302{
303 DynListQueue<int> q = {1, 2, 3};
304 q.rear() = 300;
305
306 q.get(); // 1
307 q.get(); // 2
308 EXPECT_EQ(q.get(), 300);
309}
310
311// =============================================================================
312// Size and Empty Operations Tests
313// =============================================================================
314
316{
318
319 EXPECT_EQ(q.size(), 0u);
320
321 q.put(1);
322 EXPECT_EQ(q.size(), 1u);
323
324 q.put(2);
325 EXPECT_EQ(q.size(), 2u);
326
327 q.get();
328 EXPECT_EQ(q.size(), 1u);
329
330 q.get();
331 EXPECT_EQ(q.size(), 0u);
332}
333
335{
337
339
340 q.put(1);
342
343 q.get();
345}
346
348{
349 EXPECT_EQ(queue_with_items.size(), N);
350
351 queue_with_items.empty();
352
353 EXPECT_TRUE(queue_with_items.is_empty());
354 EXPECT_EQ(queue_with_items.size(), 0u);
355}
356
358{
359 empty_queue.empty();
360
361 EXPECT_TRUE(empty_queue.is_empty());
362 EXPECT_EQ(empty_queue.size(), 0u);
363}
364
365// =============================================================================
366// Swap Operation Tests
367// =============================================================================
368
370{
371 DynListQueue<int> q1 = {1, 2, 3};
372 DynListQueue<int> q2 = {10, 20};
373
374 q1.swap(q2);
375
376 EXPECT_EQ(q1.size(), 2u);
377 EXPECT_EQ(q2.size(), 3u);
378
379 EXPECT_EQ(q1.front(), 10);
380 EXPECT_EQ(q2.front(), 1);
381}
382
384{
385 DynListQueue<int> q1 = {1, 2, 3};
387
388 q1.swap(q2);
389
390 EXPECT_TRUE(q1.is_empty());
391 EXPECT_EQ(q2.size(), 3u);
392 EXPECT_EQ(q2.front(), 1);
393}
394
396{
397 DynListQueue<int> q = {1, 2, 3};
398
399 q.swap(q);
400
401 EXPECT_EQ(q.size(), 3u);
402 EXPECT_EQ(q.front(), 1);
403}
404
405// =============================================================================
406// Iterator Tests
407// =============================================================================
408
410{
411 DynListQueue<int> q = {1, 2, 3, 4, 5};
413
414 int expected = 1;
415 while (it.has_curr())
416 {
418 it.next();
419 ++expected;
420 }
422}
423
425{
426 // Iterator should visit from oldest (front) to youngest (rear)
428 q.put(1); // oldest
429 q.put(2);
430 q.put(3); // youngest
431
432 std::vector<int> visited;
433 for (auto it = q.get_it(); it.has_curr(); it.next())
434 visited.push_back(it.get_curr());
435
436 ASSERT_EQ(visited.size(), 3u);
437 EXPECT_EQ(visited[0], 1); // oldest first
438 EXPECT_EQ(visited[1], 2);
439 EXPECT_EQ(visited[2], 3); // youngest last
440}
441
443{
444 DynListQueue<int> q = {1, 2, 3, 4, 5};
445
446 int sum = 0;
447 for (const auto& item : q)
448 sum += item;
449
450 EXPECT_EQ(sum, 15);
451}
452
454{
455 DynListQueue<int> q = {1, 2, 3};
456
457 auto it = q.begin();
458 EXPECT_EQ(*it, 1);
459 ++it;
460 EXPECT_EQ(*it, 2);
461 ++it;
462 EXPECT_EQ(*it, 3);
463 ++it;
464 EXPECT_EQ(it, q.end());
465}
466
468{
469 const DynListQueue<int> q = {1, 2, 3};
470
471 int sum = 0;
472 for (const auto& item : q)
473 sum += item;
474
475 EXPECT_EQ(sum, 6);
476}
477
485
486// =============================================================================
487// Traverse Operation Tests
488// =============================================================================
489
491{
492 int sum = 0;
493 bool result = queue_with_items.traverse([&sum](int& item) {
494 sum += item;
495 return true;
496 });
497
498 EXPECT_TRUE(result);
499 EXPECT_EQ(sum, static_cast<int>(N * (N - 1) / 2));
500}
501
503{
504 int count = 0;
505 bool result = queue_with_items.traverse([&count](int&) {
506 return ++count < 5; // Stop after 5 elements
507 });
508
509 EXPECT_FALSE(result);
510 EXPECT_EQ(count, 5);
511}
512
514{
515 bool called = false;
516 bool result = empty_queue.traverse([&called](int&) {
517 called = true;
518 return true;
519 });
520
521 EXPECT_TRUE(result);
522 EXPECT_FALSE(called);
523}
524
526{
527 const DynListQueue<int>& const_ref = queue_with_items;
528
529 int sum = 0;
530 const_ref.traverse([&sum](const int& item) {
531 sum += item;
532 return true;
533 });
534
535 EXPECT_EQ(sum, static_cast<int>(N * (N - 1) / 2));
536}
537
538// =============================================================================
539// Functional Methods Tests (inherited from FunctionalMethods)
540// =============================================================================
541
543{
544 int sum = 0;
545 queue_with_items.for_each([&sum](const int& item) {
546 sum += item;
547 });
548
549 EXPECT_EQ(sum, static_cast<int>(N * (N - 1) / 2));
550}
551
553{
554 DynListQueue<int> q = {1, 2, 3, 4, 5};
555 auto doubled = q.maps([](int i) { return i * 2; });
556
557 EXPECT_EQ(doubled.size(), 5u);
558
559 DynList<int> expected = {2, 4, 6, 8, 10};
561}
562
564{
565 DynListQueue<int> q = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
566 auto evens = q.filter([](int i) { return i % 2 == 0; });
567
568 DynList<int> expected = {2, 4, 6, 8, 10};
570}
571
573{
574 DynListQueue<int> q = {1, 2, 3, 4, 5};
575 int product = q.foldl(1, [](int acc, int item) { return acc * item; });
576
577 EXPECT_EQ(product, 120);
578}
579
581{
582 DynListQueue<int> q = {2, 4, 6, 8, 10};
583
584 EXPECT_TRUE(q.all([](int i) { return i % 2 == 0; }));
585 EXPECT_FALSE(q.all([](int i) { return i > 5; }));
586}
587
589{
590 DynListQueue<int> q = {1, 2, 3, 4, 5};
591
592 EXPECT_TRUE(q.exists([](int i) { return i == 3; }));
593 EXPECT_FALSE(q.exists([](int i) { return i == 10; }));
594}
595
597{
598 DynListQueue<int> q = {1, 2, 3, 4, 5, 6};
599 auto [evens, odds] = q.partition([](int i) { return i % 2 == 0; });
600
601 EXPECT_EQ(evens.size(), 3u);
602 EXPECT_EQ(odds.size(), 3u);
603}
604
606{
607 auto first_five = queue_with_items.take(5);
608
612}
613
615{
616 size_t drop_count = N - 5;
617 auto last_five = queue_with_items.drop(drop_count);
618
619 EXPECT_EQ(last_five.size(), 5u);
620 EXPECT_EQ(last_five.get_first(), static_cast<int>(N - 5));
621 EXPECT_EQ(last_five.get_last(), static_cast<int>(N - 1));
622}
623
625{
626 DynListQueue<int> q = {1, 2, 3, 4, 5};
627 auto reversed = q.rev();
628
629 DynList<int> expected = {5, 4, 3, 2, 1};
631}
632
634{
635 EXPECT_EQ(queue_with_items.length(), N);
636 EXPECT_EQ(empty_queue.length(), 0u);
637}
638
639// =============================================================================
640// Locate Functions Tests (inherited from LocateFunctions)
641// =============================================================================
642
644{
645 auto ptr = queue_with_items.find_ptr([](int i) { return i == 50; });
646
647 ASSERT_NE(ptr, nullptr);
648 EXPECT_EQ(*ptr, 50);
649}
650
652{
653 auto ptr = queue_with_items.find_ptr([](int i) { return i == 9999; });
654
655 EXPECT_EQ(ptr, nullptr);
656}
657
659{
660 auto idx = queue_with_items.find_index([](int i) { return i == 50; });
661
662 EXPECT_EQ(idx, 50u);
663}
664
666{
667 auto [found, value] = queue_with_items.find_item([](int i) { return i == 50; });
668
670 EXPECT_EQ(value, 50);
671}
672
674{
675 EXPECT_EQ(queue_with_items.nth(0), 0);
676 EXPECT_EQ(queue_with_items.nth(50), 50);
677 EXPECT_EQ(queue_with_items.nth(N - 1), static_cast<int>(N - 1));
678}
679
681{
682 EXPECT_THROW(queue_with_items.nth(N), std::out_of_range);
683 EXPECT_THROW(queue_with_items.nth(N + 100), std::out_of_range);
684}
685
687{
688 auto it = queue_with_items.get_it();
689 EXPECT_TRUE(it.has_curr());
690 EXPECT_EQ(it.get_curr(), 0);
691}
692
694{
695 auto it = queue_with_items.get_it(50);
696 EXPECT_TRUE(it.has_curr());
697 EXPECT_EQ(it.get_curr(), 50);
698}
699
700// =============================================================================
701// GenericKeys Tests (inherited from GenericKeys)
702// =============================================================================
703
705{
706 DynListQueue<int> q = {1, 2, 3};
707 auto keys = q.keys();
708
709 EXPECT_EQ(keys.size(), 3u);
710 EXPECT_EQ(keys.get_first(), 1);
711 EXPECT_EQ(keys.get_last(), 3);
712}
713
715{
716 DynListQueue<int> q = {1, 2, 3};
717 auto items = q.items();
718
719 EXPECT_EQ(items.size(), 3u);
720}
721
722// =============================================================================
723// Type Alias Tests
724// =============================================================================
725
727{
728 using SetType = typename DynListQueue<int>::Set_Type;
729 using ItemType = typename DynListQueue<int>::Item_Type;
730
731 static_assert(std::is_same_v<SetType, DynListQueue<int>>,
732 "Set_Type should be DynListQueue<int>");
733 static_assert(std::is_same_v<ItemType, int>,
734 "Item_Type should be int");
735}
736
737// =============================================================================
738// Complex Type Tests
739// =============================================================================
740
742{
744
745 q.put("hello");
746 q.put("world");
747 q.put("!");
748
749 EXPECT_EQ(q.size(), 3u);
750 EXPECT_EQ(q.get(), "hello");
751 EXPECT_EQ(q.get(), "world");
752 EXPECT_EQ(q.get(), "!");
753}
754
756{
758
759 q.put(std::make_unique<int>(1));
760 q.put(std::make_unique<int>(2));
761 q.put(std::make_unique<int>(3));
762
763 EXPECT_EQ(q.size(), 3u);
764
765 auto p1 = q.get();
766 EXPECT_EQ(*p1, 1);
767
768 auto p2 = q.get();
769 EXPECT_EQ(*p2, 2);
770
771 auto p3 = q.get();
772 EXPECT_EQ(*p3, 3);
773}
774
776{
777 int value;
778 NonCopyable(int v) : value(v) {}
779 NonCopyable(const NonCopyable&) = delete;
783 {
784 value = other.value;
785 return *this;
786 }
787};
788
790{
792
793 q.put(NonCopyable(1));
794 q.put(NonCopyable(2));
795
796 EXPECT_EQ(q.size(), 2u);
797
798 auto item = q.get();
799 EXPECT_EQ(item.value, 1);
800}
801
803{
805 int value;
806
807 ThrowingType(int v) : value(v)
808 {
809 if (++construction_count > 100)
810 throw std::runtime_error("Too many constructions");
811 }
812
814 {
815 if (++construction_count > 100)
816 throw std::runtime_error("Too many constructions");
817 }
818
820
821 static void reset() { construction_count = 0; }
822};
823
825
827{
830
831 // Should be able to add some elements
832 for (int i = 0; i < 50; ++i)
833 q.put(ThrowingType(i));
834
835 EXPECT_EQ(q.size(), 50u);
836}
837
838// =============================================================================
839// Stress Tests
840// =============================================================================
841
843{
844 constexpr size_t LARGE_N = 100000;
846
847 for (size_t i = 0; i < LARGE_N; ++i)
848 q.put(static_cast<int>(i));
849
850 EXPECT_EQ(q.size(), LARGE_N);
851 EXPECT_EQ(q.front(), 0);
852 EXPECT_EQ(q.rear(), static_cast<int>(LARGE_N - 1));
853
854 for (size_t i = 0; i < LARGE_N; ++i)
855 EXPECT_EQ(q.get(), static_cast<int>(i));
856
858}
859
861{
863
864 // Interleave puts and gets
865 int put_count = 0;
866 int get_count = 0;
867
868 for (int round = 0; round < 1000; ++round)
869 {
870 // Put 3 elements
871 for (int i = 0; i < 3; ++i)
872 q.put(put_count++);
873
874 // Get 2 elements
875 for (int i = 0; i < 2; ++i)
876 {
877 EXPECT_EQ(q.get(), get_count);
878 get_count++;
879 }
880 }
881
882 // Queue should have 1000 elements remaining
883 EXPECT_EQ(q.size(), 1000u);
884
885 // Drain remaining
886 while (!q.is_empty())
887 {
888 EXPECT_EQ(q.get(), get_count);
889 get_count++;
890 }
891}
892
894{
896
897 for (int round = 0; round < 100; ++round)
898 {
899 // Fill
900 for (int i = 0; i < 100; ++i)
901 q.put(i);
902
903 EXPECT_EQ(q.size(), 100u);
904
905 // Empty
906 q.empty();
907
909 EXPECT_EQ(q.size(), 0u);
910 }
911}
912
913// =============================================================================
914// Edge Cases Tests
915// =============================================================================
916
918{
920
921 q.put(42);
922
923 EXPECT_EQ(q.size(), 1u);
924 EXPECT_EQ(q.front(), 42);
925 EXPECT_EQ(q.rear(), 42);
926 EXPECT_EQ(q.get(), 42);
928}
929
931{
933
934 for (int i = 0; i < 100; ++i)
935 {
937
938 q.put(i);
940 EXPECT_EQ(q.front(), i);
941 EXPECT_EQ(q.rear(), i);
942
943 int val = q.get();
944 EXPECT_EQ(val, i);
946 }
947}
948
950{
952
953 q.put(0);
954 EXPECT_EQ(q.front(), 0);
955 EXPECT_EQ(q.get(), 0);
956}
957
959{
961
962 for (int i = -100; i <= 100; ++i)
963 q.put(i);
964
965 for (int i = -100; i <= 100; ++i)
966 EXPECT_EQ(q.get(), i);
967}
968
970{
972
973 q.put("");
974 q.put("non-empty");
975 q.put("");
976
977 EXPECT_EQ(q.get(), "");
978 EXPECT_EQ(q.get(), "non-empty");
979 EXPECT_EQ(q.get(), "");
980}
981
982// =============================================================================
983// Noexcept Tests
984// =============================================================================
985
987{
989 static_assert(noexcept(q1.swap(q2)), "swap should be noexcept");
990}
991
993{
995 static_assert(noexcept(q.size()), "size should be noexcept");
996}
997
999{
1001 static_assert(noexcept(q.is_empty()), "is_empty should be noexcept");
1002}
1003
1005{
1007 static_assert(noexcept(q.empty()), "empty should be noexcept");
1008}
1009
1011{
1012 static_assert(std::is_nothrow_move_constructible_v<DynListQueue<int>>,
1013 "Move constructor should be noexcept");
1014}
1015
1017{
1018 static_assert(std::is_nothrow_move_assignable_v<DynListQueue<int>>,
1019 "Move assignment should be noexcept");
1020}
1021
1022// =============================================================================
1023// Emplace Tests
1024// =============================================================================
1025
1027{
1029
1030 q.emplace(1, "one");
1031 q.emplace(2, "two");
1032 q.emplace(3, "three");
1033
1034 EXPECT_EQ(q.size(), 3u);
1035
1036 auto p1 = q.get();
1037 EXPECT_EQ(p1.first, 1);
1038 EXPECT_EQ(p1.second, "one");
1039}
1040
1042{
1044
1045 auto& ref = q.emplace(10, 20);
1046 EXPECT_EQ(ref.first, 10);
1047 EXPECT_EQ(ref.second, 20);
1048
1049 // Modifying through reference
1050 ref.first = 100;
1051 EXPECT_EQ(q.front().first, 100);
1052}
1053
1055{
1057
1058 // Emplace constructs string from const char*
1059 q.emplace("hello");
1060 q.emplace(5, 'x'); // std::string(5, 'x') = "xxxxx"
1061
1062 EXPECT_EQ(q.get(), "hello");
1063 EXPECT_EQ(q.get(), "xxxxx");
1064}
1065
1066// =============================================================================
1067// Pop and Clear Alias Tests
1068// =============================================================================
1069
1071{
1072 DynListQueue<int> q = {1, 2, 3};
1073
1074 EXPECT_EQ(q.pop(), 1);
1075 EXPECT_EQ(q.pop(), 2);
1076 EXPECT_EQ(q.pop(), 3);
1077 EXPECT_TRUE(q.is_empty());
1078}
1079
1081{
1083 EXPECT_THROW(q.pop(), std::underflow_error);
1084}
1085
1087{
1088 DynListQueue<int> q = {1, 2, 3, 4, 5};
1089
1090 EXPECT_EQ(q.size(), 5u);
1091 q.clear();
1092 EXPECT_TRUE(q.is_empty());
1093 EXPECT_EQ(q.size(), 0u);
1094}
1095
1097{
1099
1100 q.clear(); // Should not throw
1101 EXPECT_TRUE(q.is_empty());
1102}
1103
1105{
1107 static_assert(noexcept(q.clear()), "clear should be noexcept");
1108}
1109
1110// =============================================================================
1111// Memory Safety Tests
1112// =============================================================================
1113
1115{
1116 // This test verifies that queue destructor properly cleans up
1117 // Run with valgrind or AddressSanitizer for proper verification
1118
1119 {
1121 for (int i = 0; i < 1000; ++i)
1122 q.put(i);
1123 // q destroyed here
1124 }
1125
1126 // If we get here without memory errors, destructor works
1127 SUCCEED();
1128}
1129
1131{
1133
1134 for (int i = 0; i < 1000; ++i)
1135 q.put(i);
1136
1137 q.empty();
1138
1139 EXPECT_TRUE(q.is_empty());
1140
1141 // Verify queue is reusable after empty
1142 for (int i = 0; i < 100; ++i)
1143 q.put(i);
1144
1145 EXPECT_EQ(q.size(), 100u);
1146}
1147
1148// =============================================================================
1149// Const Correctness Tests
1150// =============================================================================
1151
1153{
1154 const DynListQueue<int> q = {1, 2, 3};
1155
1156 const int& ref = q.front();
1157 EXPECT_EQ(ref, 1);
1158
1159 // Verify it's a const reference (should not compile if uncommented):
1160 // ref = 100; // This should fail to compile
1161}
1162
1164{
1165 DynListQueue<int> q = {1, 2, 3};
1166
1167 int& ref = q.front();
1168 ref = 100;
1169
1170 EXPECT_EQ(q.front(), 100);
1171}
1172
1174{
1175 const DynListQueue<int> q = {1, 2, 3};
1176
1177 const int& ref = q.rear();
1178 EXPECT_EQ(ref, 3);
1179}
1180
1182{
1183 DynListQueue<int> q = {1, 2, 3};
1184
1185 int& ref = q.rear();
1186 ref = 300;
1187
1188 q.get(); // 1
1189 q.get(); // 2
1190 EXPECT_EQ(q.get(), 300);
1191}
1192
1193// =============================================================================
1194// Equality Operator Tests (using EqualToMethod mixin)
1195// =============================================================================
1196
1198{
1199 DynListQueue<int> q1 = {1, 2, 3, 4, 5};
1200 DynListQueue<int> q2 = {1, 2, 3, 4, 5};
1201
1202 // Use intermediate variables to avoid -Ofast optimization issues
1203 bool eq = (q1 == q2);
1204 bool neq = (q1 != q2);
1205 EXPECT_TRUE(eq);
1207}
1208
1210{
1211 DynListQueue<int> q1 = {1, 2, 3};
1212 DynListQueue<int> q2 = {1, 2, 3, 4};
1213
1214 bool eq = (q1 == q2);
1215 bool neq = (q1 != q2);
1218}
1219
1221{
1222 DynListQueue<int> q1 = {1, 2, 3};
1223 DynListQueue<int> q2 = {1, 2, 4};
1224
1225 bool eq = (q1 == q2);
1226 bool neq = (q1 != q2);
1229}
1230
1232{
1235
1236 bool eq = (q1 == q2);
1237 bool neq = (q1 != q2);
1238 EXPECT_TRUE(eq);
1240}
1241
1243{
1244 DynListQueue<int> q = {1, 2, 3};
1245
1246 // Use intermediate variables to avoid compiler optimization issues with -Ofast
1247 bool eq = (q == q);
1248 bool neq = (q != q);
1249 EXPECT_TRUE(eq);
1251}
1252
1254{
1255 DynListQueue<int> empty;
1257
1258 bool eq = (empty == non_empty);
1259 bool neq = (empty != non_empty);
1262}
1263
1264// =============================================================================
1265// Search Method Tests
1266// =============================================================================
1267
1269{
1270 DynListQueue<int> q = {1, 2, 3, 4, 5};
1271
1272 auto ptr = q.search(3);
1273 ASSERT_NE(ptr, nullptr);
1274 EXPECT_EQ(*ptr, 3);
1275}
1276
1278{
1279 DynListQueue<int> q = {1, 2, 3, 4, 5};
1280
1281 auto ptr = q.search(10);
1282 EXPECT_EQ(ptr, nullptr);
1283}
1284
1286{
1288
1289 auto ptr = q.search(1);
1290 EXPECT_EQ(ptr, nullptr);
1291}
1292
1294{
1295 DynListQueue<int> q = {1, 2, 3};
1296
1297 auto ptr = q.search(1);
1298 ASSERT_NE(ptr, nullptr);
1299 EXPECT_EQ(*ptr, 1);
1300}
1301
1303{
1304 DynListQueue<int> q = {1, 2, 3};
1305
1306 auto ptr = q.search(3);
1307 ASSERT_NE(ptr, nullptr);
1308 EXPECT_EQ(*ptr, 3);
1309}
1310
1312{
1313 const DynListQueue<int> q = {1, 2, 3, 4, 5};
1314
1315 const int* ptr = q.search(3);
1316 ASSERT_NE(ptr, nullptr);
1317 EXPECT_EQ(*ptr, 3);
1318}
1319
1321{
1322 DynListQueue<int> q = {1, 2, 2, 2, 3};
1323
1324 auto ptr = q.search(2);
1325 ASSERT_NE(ptr, nullptr);
1326 EXPECT_EQ(*ptr, 2);
1327 // search returns first match (from front)
1328}
1329
1330// =============================================================================
1331// Main function
1332// =============================================================================
1333
1334int main(int argc, char** argv)
1335{
1336 ::testing::InitGoogleTest(&argc, argv);
1337 return RUN_ALL_TESTS();
1338}
Zip iterators and functional operations for multiple containers.
Functional programming utilities for Aleph-w containers.
int main()
Dynamic queue of elements of generic type T based on single linked list.
T & put(const T &data)
The type of element.
constexpr size_t size() const noexcept
Return the number of elements.
T get()
Remove the oldest item of the queue.
void swap(DynListQueue &__q) noexcept
Swap this with __q in constant time.
void empty() noexcept
Empty the queue.
T & front()
Return a modifiable reference to the oldest item in the queue.
void clear() noexcept
Alias for empty() - clears all items from the queue.
T pop()
Alias for get() - removes and returns the front item.
T & insert(const T &data)
T & append(const T &data)
T & emplace(Args &&... args)
Construct an item in place at the rear of the queue.
T Item_Type
The type of set.
T & rear()
Return a modifiable reference to the youngest item in the queue.
T * search(const T &key) noexcept
Search for an item in the queue using equality comparison.
bool is_empty() const noexcept
Return true if this is empty.
T & get_curr() const
Return the current item.
Definition htlist.H:1740
Dynamic singly linked list with functional programming support.
Definition htlist.H:1423
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 next()
Move the iterator one item forward.
Definition htlist.H:1222
bool has_curr() const noexcept
Return true if iterator has current item.
Definition htlist.H:1150
size_t size() const noexcept
Count the number of elements of the list.
Definition htlist.H:1319
DynListQueue< int > queue_with_items
void SetUp() override
DynListQueue< int > empty_queue
static constexpr size_t N
__T foldl(const __T &init, Op &op) const
Fold the elements of the container to a specific result.
Definition ah-dry.H:1034
Aleph::DynList< T > filter(Operation &operation) const
Filter the elements of a container according to a matching criteria.
Definition ah-dry.H:1135
std::pair< Aleph::DynList< T >, Aleph::DynList< T > > partition(Operation &op) const
Exclusive partition of container according to a filter criteria.
Definition ah-dry.H:1266
Aleph::DynList< T > take(const size_t n) const
Return a list with the first n elements seen in the container during its traversal.
Definition ah-dry.H:1418
bool exists(Operation &op) const
Test for existence in the container of an element satisfying a criteria.
Definition ah-dry.H:846
bool all(Operation &operation) const
Check if all the elements of container satisfy a condition.
Definition ah-dry.H:816
Aleph::DynList< T > rev() const
Return a list with the elements of container in reverse order respect to its traversal order.
Definition ah-dry.H:1399
Aleph::DynList< __T > maps(Operation &op) const
Map the elements of the container.
Definition ah-dry.H:904
Aleph::DynList< T > drop(const size_t n) const
Drop the first n elements seen in the container during its traversal.
Definition ah-dry.H:1467
auto get_it() const
Return a properly initialized iterator positioned at the first item on the container.
Definition ah-dry.H:190
iterator end() noexcept
Return an STL-compatible end iterator.
iterator begin() noexcept
Return an STL-compatible iterator to the first element.
#define TEST(name)
constexpr size_t LARGE_N
#define N
Definition fib.C:294
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.
Itor2 copy(Itor1 sourceBeg, const Itor1 &sourceEnd, Itor2 destBeg)
Copy elements from one range to another.
Definition ahAlgo.H:584
T product(const Container &container, const T &init=T{1})
Compute product of all elements.
DynList< T > maps(const C &c, Op op)
Classic map operation.
Itor::difference_type count(const Itor &beg, const Itor &end, const T &value)
Count elements equal to a value.
Definition ahAlgo.H:127
T sum(const Container &container, const T &init=T{})
Compute sum of all elements.
STL namespace.
Iterator on elements of a queue.
Aleph::DynList< T > keys() const
Definition ah-dry.H:1516
Aleph::DynList< T > items() const
Return a list of all the elements of a container sorted by traversal order.
Definition ah-dry.H:1509
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
NonCopyable & operator=(const NonCopyable &)=delete
NonCopyable(const NonCopyable &)=delete
NonCopyable(NonCopyable &&other) noexcept
NonCopyable & operator=(NonCopyable &&other) noexcept
ThrowingType(const ThrowingType &other)
static void reset()
static int construction_count
ThrowingType(ThrowingType &&other) noexcept
Dynamic queue implementation based on linked lists.
TEST_F(DynListQueueTest, DefaultConstruction)