Aleph-w 3.0
A C++ Library for Data Structures and Algorithms
Loading...
Searching...
No Matches
tpl_dynListStack.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_dynListStack.H>
50# include <ahFunctional.H>
51
52using namespace std;
53using namespace testing;
54using namespace Aleph;
55
56// =============================================================================
57// Test Fixture for Basic Operations
58// =============================================================================
59
60class DynListStackTest : public ::testing::Test
61{
62protected:
65
66 static constexpr size_t N = 100;
67
68 void SetUp() override
69 {
70 for (size_t i = 0; i < N; ++i)
71 stack_with_items.push(static_cast<int>(i));
72 }
73};
74
75// =============================================================================
76// Construction Tests
77// =============================================================================
78
85
87{
88 DynListStack<int> copy(stack_with_items);
89
90 EXPECT_EQ(copy.size(), stack_with_items.size());
91 EXPECT_EQ(copy.size(), N);
92
93 // Verify independent copies - both should have same LIFO order
94 while (!stack_with_items.is_empty())
95 {
96 EXPECT_EQ(stack_with_items.pop(), copy.pop());
97 }
98 EXPECT_TRUE(stack_with_items.is_empty());
99 EXPECT_TRUE(copy.is_empty());
100}
101
103{
104 DynListStack<int> source;
105 for (int i = 0; i < 10; ++i)
106 source.push(i);
107
108 size_t original_size = source.size();
109 int top_value = source.top();
110 DynListStack<int> moved(std::move(source));
111
113 EXPECT_TRUE(source.is_empty()); // Source should be empty after move
115}
116
118{
119 DynListStack<int> s = {1, 2, 3, 4, 5};
120
121 EXPECT_EQ(s.size(), 5u);
122 // Initializer list inserts in order, so last element is on top
123 EXPECT_EQ(s.top(), 5);
124}
125
127{
128 std::vector<int> vec = {10, 20, 30, 40, 50};
130
131 EXPECT_EQ(s.size(), vec.size());
132 // Elements should be in reverse order (last pushed is on top)
133 EXPECT_EQ(s.top(), 50);
134}
135
137{
138 DynList<int> list = {100, 200, 300};
139 DynListStack<int> s(list);
140
141 EXPECT_EQ(s.size(), list.size());
142}
143
144// =============================================================================
145// Assignment Tests
146// =============================================================================
147
149{
151 s.push(999); // Pre-existing content
152
153 s = stack_with_items;
154
155 EXPECT_EQ(s.size(), N);
156 EXPECT_EQ(s.top(), static_cast<int>(N - 1)); // Last pushed is on top
157}
158
160{
161 DynListStack<int> s = {1, 2, 3};
162 s = s; // Self-assignment
163
164 EXPECT_EQ(s.size(), 3u);
165 EXPECT_EQ(s.top(), 3);
166}
167
169{
170 DynListStack<int> source = {1, 2, 3};
172 target.push(999);
173
174 target = std::move(source);
175
176 EXPECT_EQ(target.size(), 3u);
177 EXPECT_EQ(target.top(), 3);
178}
179
180// =============================================================================
181// Core Stack Operations Tests
182// =============================================================================
183
185{
187 int value = 42;
188
189 int& ref = s.push(value);
190
191 EXPECT_EQ(s.size(), 1u);
192 EXPECT_EQ(ref, 42);
193 EXPECT_EQ(s.top(), 42);
194}
195
197{
199 std::string value = "hello";
200
201 std::string& ref = s.push(std::move(value));
202
203 EXPECT_EQ(s.size(), 1u);
204 EXPECT_EQ(ref, "hello");
205}
206
208{
210
211 s.push(1);
212 EXPECT_EQ(s.top(), 1);
213
214 s.push(2);
215 EXPECT_EQ(s.top(), 2);
216
217 s.push(3);
218 EXPECT_EQ(s.top(), 3);
219
220 EXPECT_EQ(s.size(), 3u);
221}
222
224{
226 s.push(1);
227 s.push(2);
228 s.push(3);
229
230 EXPECT_EQ(s.pop(), 3); // Last in, first out
231 EXPECT_EQ(s.pop(), 2);
232 EXPECT_EQ(s.pop(), 1);
234}
235
237{
239 EXPECT_THROW(s.pop(), std::underflow_error);
240}
241
243{
244 DynListStack<int> s = {1, 2, 3};
245
246 EXPECT_EQ(s.get(), 3);
247 EXPECT_EQ(s.get(), 2);
248 EXPECT_EQ(s.get(), 1);
249}
250
252{
253 // Top is last pushed (N-1)
254 EXPECT_EQ(stack_with_items.top(), static_cast<int>(N - 1));
255
256 // Multiple peeks should return same value
257 EXPECT_EQ(stack_with_items.top(), static_cast<int>(N - 1));
258 EXPECT_EQ(stack_with_items.top(), static_cast<int>(N - 1));
259
260 // Size should not change
261 EXPECT_EQ(stack_with_items.size(), N);
262}
263
265{
267 EXPECT_THROW(s.top(), std::underflow_error);
268}
269
271{
272 DynListStack<int> s = {1, 2, 3};
273
274 EXPECT_EQ(s.peek(), 3);
275 EXPECT_EQ(s.size(), 3u); // Size unchanged
276}
277
279{
280 DynListStack<int> s = {1, 2, 3};
281 s.top() = 100;
282
283 EXPECT_EQ(s.pop(), 100);
284 EXPECT_EQ(s.pop(), 2);
285}
286
287// =============================================================================
288// Size and Empty Operations Tests
289// =============================================================================
290
292{
294
295 EXPECT_EQ(s.size(), 0u);
296
297 s.push(1);
298 EXPECT_EQ(s.size(), 1u);
299
300 s.push(2);
301 EXPECT_EQ(s.size(), 2u);
302
303 s.pop();
304 EXPECT_EQ(s.size(), 1u);
305
306 s.pop();
307 EXPECT_EQ(s.size(), 0u);
308}
309
311{
313
315
316 s.push(1);
318
319 s.pop();
321}
322
324{
325 EXPECT_EQ(stack_with_items.size(), N);
326
327 stack_with_items.empty();
328
329 EXPECT_TRUE(stack_with_items.is_empty());
330 EXPECT_EQ(stack_with_items.size(), 0u);
331}
332
334{
335 empty_stack.empty();
336
337 EXPECT_TRUE(empty_stack.is_empty());
338 EXPECT_EQ(empty_stack.size(), 0u);
339}
340
342{
343 DynListStack<int> s = {1, 2, 3, 4, 5};
344
345 s.clear();
346
348 EXPECT_EQ(s.size(), 0u);
349}
350
351// =============================================================================
352// Swap Operation Tests
353// =============================================================================
354
356{
357 DynListStack<int> s1 = {1, 2, 3};
358 DynListStack<int> s2 = {10, 20};
359
360 s1.swap(s2);
361
362 EXPECT_EQ(s1.size(), 2u);
363 EXPECT_EQ(s2.size(), 3u);
364
365 EXPECT_EQ(s1.top(), 20);
366 EXPECT_EQ(s2.top(), 3);
367}
368
370{
371 DynListStack<int> s1 = {1, 2, 3};
373
374 s1.swap(s2);
375
377 EXPECT_EQ(s2.size(), 3u);
378 EXPECT_EQ(s2.top(), 3);
379}
380
382{
383 DynListStack<int> s = {1, 2, 3};
384
385 s.swap(s);
386
387 EXPECT_EQ(s.size(), 3u);
388 EXPECT_EQ(s.top(), 3);
389}
390
391// =============================================================================
392// Iterator Tests
393// =============================================================================
394
396{
397 DynListStack<int> s = {1, 2, 3, 4, 5};
399
400 // Iterator visits from top to bottom
401 int expected = 5;
402 while (it.has_curr())
403 {
405 it.next();
406 --expected;
407 }
409}
410
412{
413 // Iterator should visit from top to bottom (LIFO order)
415 s.push(1); // bottom
416 s.push(2);
417 s.push(3); // top
418
419 std::vector<int> visited;
420 for (auto it = s.get_it(); it.has_curr(); it.next())
421 visited.push_back(it.get_curr());
422
423 ASSERT_EQ(visited.size(), 3u);
424 EXPECT_EQ(visited[0], 3); // top first
425 EXPECT_EQ(visited[1], 2);
426 EXPECT_EQ(visited[2], 1); // bottom last
427}
428
430{
431 DynListStack<int> s = {1, 2, 3, 4, 5};
432
433 int sum = 0;
434 for (const auto& item : s)
435 sum += item;
436
437 EXPECT_EQ(sum, 15);
438}
439
441{
442 DynListStack<int> s = {1, 2, 3};
443
444 auto it = s.begin();
445 EXPECT_EQ(*it, 3); // top
446 ++it;
447 EXPECT_EQ(*it, 2);
448 ++it;
449 EXPECT_EQ(*it, 1); // bottom
450 ++it;
451 EXPECT_EQ(it, s.end());
452}
453
455{
456 const DynListStack<int> s = {1, 2, 3};
457
458 int sum = 0;
459 for (const auto& item : s)
460 sum += item;
461
462 EXPECT_EQ(sum, 6);
463}
464
472
473// =============================================================================
474// Traverse Operation Tests
475// =============================================================================
476
478{
479 int sum = 0;
480 bool result = stack_with_items.traverse([&sum](int& item) {
481 sum += item;
482 return true;
483 });
484
485 EXPECT_TRUE(result);
486 EXPECT_EQ(sum, static_cast<int>(N * (N - 1) / 2));
487}
488
490{
491 int count = 0;
492 bool result = stack_with_items.traverse([&count](int&) {
493 return ++count < 5; // Stop after 5 elements
494 });
495
496 EXPECT_FALSE(result);
497 EXPECT_EQ(count, 5);
498}
499
501{
502 bool called = false;
503 bool result = empty_stack.traverse([&called](int&) {
504 called = true;
505 return true;
506 });
507
508 EXPECT_TRUE(result);
509 EXPECT_FALSE(called);
510}
511
513{
514 const DynListStack<int>& const_ref = stack_with_items;
515
516 int sum = 0;
517 const_ref.traverse([&sum](const int& item) {
518 sum += item;
519 return true;
520 });
521
522 EXPECT_EQ(sum, static_cast<int>(N * (N - 1) / 2));
523}
524
525// =============================================================================
526// Functional Methods Tests (inherited from FunctionalMethods)
527// =============================================================================
528
530{
531 int sum = 0;
532 stack_with_items.for_each([&sum](const int& item) {
533 sum += item;
534 });
535
536 EXPECT_EQ(sum, static_cast<int>(N * (N - 1) / 2));
537}
538
540{
541 DynListStack<int> s = {1, 2, 3, 4, 5};
542 auto doubled = s.maps([](int i) { return i * 2; });
543
544 EXPECT_EQ(doubled.size(), 5u);
545
546 // Check the doubled values
547 DynList<int> expected = {10, 8, 6, 4, 2}; // top to bottom order
549}
550
552{
553 DynListStack<int> s = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
554 auto evens = s.filter([](int i) { return i % 2 == 0; });
555
556 EXPECT_EQ(evens.size(), 5u);
557}
558
560{
561 DynListStack<int> s = {1, 2, 3, 4, 5};
562 int product = s.foldl(1, [](int acc, int item) { return acc * item; });
563
564 EXPECT_EQ(product, 120);
565}
566
568{
569 DynListStack<int> s = {2, 4, 6, 8, 10};
570
571 EXPECT_TRUE(s.all([](int i) { return i % 2 == 0; }));
572 EXPECT_FALSE(s.all([](int i) { return i > 5; }));
573}
574
576{
577 DynListStack<int> s = {1, 2, 3, 4, 5};
578
579 EXPECT_TRUE(s.exists([](int i) { return i == 3; }));
580 EXPECT_FALSE(s.exists([](int i) { return i == 10; }));
581}
582
584{
585 DynListStack<int> s = {1, 2, 3, 4, 5, 6};
586 auto [evens, odds] = s.partition([](int i) { return i % 2 == 0; });
587
588 EXPECT_EQ(evens.size(), 3u);
589 EXPECT_EQ(odds.size(), 3u);
590}
591
593{
594 auto first_five = stack_with_items.take(5);
595
597}
598
600{
601 size_t drop_count = N - 5;
602 auto last_five = stack_with_items.drop(drop_count);
603
604 EXPECT_EQ(last_five.size(), 5u);
605}
606
608{
609 DynListStack<int> s = {1, 2, 3, 4, 5};
610 auto reversed = s.rev();
611
612 EXPECT_EQ(reversed.size(), 5u);
613}
614
616{
617 EXPECT_EQ(stack_with_items.length(), N);
618 EXPECT_EQ(empty_stack.length(), 0u);
619}
620
621// =============================================================================
622// Locate Functions Tests (inherited from LocateFunctions)
623// =============================================================================
624
626{
627 auto ptr = stack_with_items.find_ptr([](int i) { return i == 50; });
628
629 ASSERT_NE(ptr, nullptr);
630 EXPECT_EQ(*ptr, 50);
631}
632
634{
635 auto ptr = stack_with_items.find_ptr([](int i) { return i == 9999; });
636
637 EXPECT_EQ(ptr, nullptr);
638}
639
641{
642 // Stack has items in reverse order (N-1 at top, 0 at bottom)
643 // So index 0 corresponds to top element (N-1)
644 auto idx = stack_with_items.find_index([](int i) { return i == static_cast<int>(N - 1); });
645
646 EXPECT_EQ(idx, 0u); // Top of stack is index 0
647}
648
650{
651 auto [found, value] = stack_with_items.find_item([](int i) { return i == 50; });
652
654 EXPECT_EQ(value, 50);
655}
656
658{
659 // nth(0) is top of stack
660 EXPECT_EQ(stack_with_items.nth(0), static_cast<int>(N - 1));
661}
662
664{
665 EXPECT_THROW(stack_with_items.nth(N), std::out_of_range);
666 EXPECT_THROW(stack_with_items.nth(N + 100), std::out_of_range);
667}
668
670{
671 auto it = stack_with_items.get_it();
672 EXPECT_TRUE(it.has_curr());
673 EXPECT_EQ(it.get_curr(), static_cast<int>(N - 1)); // Top of stack
674}
675
676// =============================================================================
677// GenericKeys Tests (inherited from GenericKeys)
678// =============================================================================
679
681{
682 DynListStack<int> s = {1, 2, 3};
683 auto keys = s.keys();
684
685 EXPECT_EQ(keys.size(), 3u);
686}
687
689{
690 DynListStack<int> s = {1, 2, 3};
691 auto items = s.items();
692
693 EXPECT_EQ(items.size(), 3u);
694}
695
696// =============================================================================
697// Type Alias Tests
698// =============================================================================
699
701{
702 using SetType = typename DynListStack<int>::Set_Type;
703 using ItemType = typename DynListStack<int>::Item_Type;
704
705 static_assert(std::is_same_v<SetType, DynListStack<int>>,
706 "Set_Type should be DynListStack<int>");
707 static_assert(std::is_same_v<ItemType, int>,
708 "Item_Type should be int");
709}
710
711// =============================================================================
712// Complex Type Tests
713// =============================================================================
714
716{
718
719 s.push("hello");
720 s.push("world");
721 s.push("!");
722
723 EXPECT_EQ(s.size(), 3u);
724 EXPECT_EQ(s.pop(), "!");
725 EXPECT_EQ(s.pop(), "world");
726 EXPECT_EQ(s.pop(), "hello");
727}
728
730{
732
733 s.push(std::make_unique<int>(1));
734 s.push(std::make_unique<int>(2));
735 s.push(std::make_unique<int>(3));
736
737 EXPECT_EQ(s.size(), 3u);
738
739 auto p3 = s.pop();
740 EXPECT_EQ(*p3, 3);
741
742 auto p2 = s.pop();
743 EXPECT_EQ(*p2, 2);
744
745 auto p1 = s.pop();
746 EXPECT_EQ(*p1, 1);
747}
748
749struct NonCopyable
750{
751 int value;
752 NonCopyable(int v) : value(v) {}
753 NonCopyable(const NonCopyable&) = delete;
757 {
758 value = other.value;
759 return *this;
760 }
761};
762
764{
766
767 s.push(NonCopyable(1));
768 s.push(NonCopyable(2));
769
770 EXPECT_EQ(s.size(), 2u);
771
772 auto item = s.pop();
773 EXPECT_EQ(item.value, 2); // LIFO - last pushed first
774}
775
776struct ThrowingType
777{
778 static int construction_count;
779 int value;
780
781 ThrowingType(int v) : value(v)
782 {
783 if (++construction_count > 100)
784 throw std::runtime_error("Too many constructions");
785 }
786
788 {
789 if (++construction_count > 100)
790 throw std::runtime_error("Too many constructions");
791 }
792
794
795 static void reset() { construction_count = 0; }
796};
797
799
801{
804
805 for (int i = 0; i < 50; ++i)
806 s.push(ThrowingType(i));
807
808 EXPECT_EQ(s.size(), 50u);
809}
810
811// =============================================================================
812// Stress Tests
813// =============================================================================
814
816{
817 constexpr size_t LARGE_N = 100000;
819
820 for (size_t i = 0; i < LARGE_N; ++i)
821 s.push(static_cast<int>(i));
822
823 EXPECT_EQ(s.size(), LARGE_N);
824 EXPECT_EQ(s.top(), static_cast<int>(LARGE_N - 1));
825
826 // Pop in LIFO order
827 for (size_t i = LARGE_N; i > 0; --i)
828 EXPECT_EQ(s.pop(), static_cast<int>(i - 1));
829
831}
832
834{
836
837 int push_count = 0;
838
839 for (int round = 0; round < 1000; ++round)
840 {
841 // Push 3 elements
842 for (int i = 0; i < 3; ++i)
843 s.push(push_count++);
844
845 // Pop 2 elements
846 s.pop();
847 s.pop();
848 }
849
850 // Stack should have 1000 elements remaining
851 EXPECT_EQ(s.size(), 1000u);
852}
853
855{
857
858 for (int round = 0; round < 100; ++round)
859 {
860 // Fill
861 for (int i = 0; i < 100; ++i)
862 s.push(i);
863
864 EXPECT_EQ(s.size(), 100u);
865
866 // Empty
867 s.clear();
868
870 EXPECT_EQ(s.size(), 0u);
871 }
872}
873
874// =============================================================================
875// Edge Cases Tests
876// =============================================================================
877
879{
881
882 s.push(42);
883
884 EXPECT_EQ(s.size(), 1u);
885 EXPECT_EQ(s.top(), 42);
886 EXPECT_EQ(s.pop(), 42);
888}
889
891{
893
894 for (int i = 0; i < 100; ++i)
895 {
897
898 s.push(i);
900 EXPECT_EQ(s.top(), i);
901
902 int val = s.pop();
903 EXPECT_EQ(val, i);
905 }
906}
907
909{
911
912 s.push(0);
913 EXPECT_EQ(s.top(), 0);
914 EXPECT_EQ(s.pop(), 0);
915}
916
918{
920
921 for (int i = -100; i <= 100; ++i)
922 s.push(i);
923
924 // Pop in reverse order (LIFO)
925 for (int i = 100; i >= -100; --i)
926 EXPECT_EQ(s.pop(), i);
927}
928
930{
932
933 s.push("");
934 s.push("non-empty");
935 s.push("");
936
937 EXPECT_EQ(s.pop(), "");
938 EXPECT_EQ(s.pop(), "non-empty");
939 EXPECT_EQ(s.pop(), "");
940}
941
942// =============================================================================
943// Noexcept Tests
944// =============================================================================
945
947{
949 static_assert(noexcept(s1.swap(s2)), "swap should be noexcept");
950}
951
953{
955 static_assert(noexcept(s.size()), "size should be noexcept");
956}
957
959{
961 static_assert(noexcept(s.is_empty()), "is_empty should be noexcept");
962}
963
965{
967 static_assert(noexcept(s.empty()), "empty should be noexcept");
968}
969
971{
973 static_assert(noexcept(s.clear()), "clear should be noexcept");
974}
975
977{
978 static_assert(std::is_nothrow_move_constructible_v<DynListStack<int>>,
979 "Move constructor should be noexcept");
980}
981
983{
984 static_assert(std::is_nothrow_move_assignable_v<DynListStack<int>>,
985 "Move assignment should be noexcept");
986}
987
988// =============================================================================
989// Emplace Tests
990// =============================================================================
991
993{
995
996 s.emplace(1, "one");
997 s.emplace(2, "two");
998 s.emplace(3, "three");
999
1000 EXPECT_EQ(s.size(), 3u);
1001
1002 auto p3 = s.pop();
1003 EXPECT_EQ(p3.first, 3);
1004 EXPECT_EQ(p3.second, "three");
1005}
1006
1008{
1010
1011 auto& ref = s.emplace(10, 20);
1012 EXPECT_EQ(ref.first, 10);
1013 EXPECT_EQ(ref.second, 20);
1014
1015 // Modifying through reference
1016 ref.first = 100;
1017 EXPECT_EQ(s.top().first, 100);
1018}
1019
1021{
1023
1024 s.emplace("hello");
1025 s.emplace(5, 'x'); // std::string(5, 'x') = "xxxxx"
1026
1027 EXPECT_EQ(s.pop(), "xxxxx");
1028 EXPECT_EQ(s.pop(), "hello");
1029}
1030
1031// =============================================================================
1032// Memory Safety Tests
1033// =============================================================================
1034
1036{
1037 {
1039 for (int i = 0; i < 1000; ++i)
1040 s.push(i);
1041 }
1042
1043 SUCCEED();
1044}
1045
1047{
1049
1050 for (int i = 0; i < 1000; ++i)
1051 s.push(i);
1052
1053 s.empty();
1054
1055 EXPECT_TRUE(s.is_empty());
1056
1057 // Verify stack is reusable after empty
1058 for (int i = 0; i < 100; ++i)
1059 s.push(i);
1060
1061 EXPECT_EQ(s.size(), 100u);
1062}
1063
1064// =============================================================================
1065// Const Correctness Tests
1066// =============================================================================
1067
1069{
1070 const DynListStack<int> s = {1, 2, 3};
1071
1072 const int& ref = s.top();
1073 EXPECT_EQ(ref, 3);
1074}
1075
1077{
1078 DynListStack<int> s = {1, 2, 3};
1079
1080 int& ref = s.top();
1081 ref = 100;
1082
1083 EXPECT_EQ(s.top(), 100);
1084}
1085
1087{
1088 const DynListStack<int> s = {1, 2, 3};
1089
1090 const int& ref = s.peek();
1091 EXPECT_EQ(ref, 3);
1092}
1093
1095{
1096 DynListStack<int> s = {1, 2, 3};
1097
1098 int& ref = s.peek();
1099 ref = 300;
1100
1101 EXPECT_EQ(s.pop(), 300);
1102}
1103
1104// =============================================================================
1105// Equality Operator Tests (using EqualToMethod mixin)
1106// =============================================================================
1107
1109{
1110 DynListStack<int> s1 = {1, 2, 3, 4, 5};
1111 DynListStack<int> s2 = {1, 2, 3, 4, 5};
1112
1113 // Use intermediate variables to avoid -Ofast optimization issues
1114 bool eq = (s1 == s2);
1115 bool neq = (s1 != s2);
1116 EXPECT_TRUE(eq);
1118}
1119
1121{
1122 DynListStack<int> s1 = {1, 2, 3};
1123 DynListStack<int> s2 = {1, 2, 3, 4};
1124
1125 bool eq = (s1 == s2);
1126 bool neq = (s1 != s2);
1129}
1130
1132{
1133 DynListStack<int> s1 = {1, 2, 3};
1134 DynListStack<int> s2 = {1, 2, 4};
1135
1136 bool eq = (s1 == s2);
1137 bool neq = (s1 != s2);
1140}
1141
1143{
1146
1147 bool eq = (s1 == s2);
1148 bool neq = (s1 != s2);
1149 EXPECT_TRUE(eq);
1151}
1152
1154{
1155 DynListStack<int> s = {1, 2, 3};
1156
1157 // Use intermediate variables to avoid compiler optimization issues with -Ofast
1158 bool eq = (s == s);
1159 bool neq = (s != s);
1160 EXPECT_TRUE(eq);
1162}
1163
1165{
1166 DynListStack<int> empty;
1168
1169 bool eq = (empty == non_empty);
1170 bool neq = (empty != non_empty);
1173}
1174
1175// =============================================================================
1176// Search Method Tests
1177// =============================================================================
1178
1180{
1181 DynListStack<int> s = {1, 2, 3, 4, 5};
1182
1183 auto ptr = s.search(3);
1184 ASSERT_NE(ptr, nullptr);
1185 EXPECT_EQ(*ptr, 3);
1186}
1187
1189{
1190 DynListStack<int> s = {1, 2, 3, 4, 5};
1191
1192 auto ptr = s.search(10);
1193 EXPECT_EQ(ptr, nullptr);
1194}
1195
1197{
1199
1200 auto ptr = s.search(1);
1201 EXPECT_EQ(ptr, nullptr);
1202}
1203
1205{
1206 DynListStack<int> s = {1, 2, 3};
1207
1208 auto ptr = s.search(3); // 3 is on top
1209 ASSERT_NE(ptr, nullptr);
1210 EXPECT_EQ(*ptr, 3);
1211}
1212
1214{
1215 DynListStack<int> s = {1, 2, 3};
1216
1217 auto ptr = s.search(1); // 1 is at bottom
1218 ASSERT_NE(ptr, nullptr);
1219 EXPECT_EQ(*ptr, 1);
1220}
1221
1223{
1224 const DynListStack<int> s = {1, 2, 3, 4, 5};
1225
1226 const int* ptr = s.search(3);
1227 ASSERT_NE(ptr, nullptr);
1228 EXPECT_EQ(*ptr, 3);
1229}
1230
1232{
1233 DynListStack<int> s = {1, 2, 2, 2, 3};
1234
1235 auto ptr = s.search(2);
1236 ASSERT_NE(ptr, nullptr);
1237 EXPECT_EQ(*ptr, 2);
1238}
1239
1240// =============================================================================
1241// LIFO Behavior Verification
1242// =============================================================================
1243
1245{
1247
1248 // Push elements 1, 2, 3, 4, 5
1249 for (int i = 1; i <= 5; ++i)
1250 s.push(i);
1251
1252 // Pop should return in reverse order: 5, 4, 3, 2, 1
1253 EXPECT_EQ(s.pop(), 5);
1254 EXPECT_EQ(s.pop(), 4);
1255 EXPECT_EQ(s.pop(), 3);
1256 EXPECT_EQ(s.pop(), 2);
1257 EXPECT_EQ(s.pop(), 1);
1258}
1259
1261{
1263
1264 for (int i = 1; i <= 10; ++i)
1265 {
1266 s.push(i);
1267 EXPECT_EQ(s.top(), i);
1268 }
1269}
1270
1271// =============================================================================
1272// Compatibility Alias Tests (put, get, insert for queue/list-like interfaces)
1273// =============================================================================
1274
1276{
1278
1279 s.put(1);
1280 s.put(2);
1281 s.put(3);
1282
1283 EXPECT_EQ(s.size(), 3u);
1284 EXPECT_EQ(s.top(), 3); // LIFO - last put is on top
1285}
1286
1288{
1290 s.put(1);
1291 s.put(2);
1292 s.put(3);
1293
1294 // get() is alias for pop()
1295 EXPECT_EQ(s.get(), 3);
1296 EXPECT_EQ(s.get(), 2);
1297 EXPECT_EQ(s.get(), 1);
1298}
1299
1301{
1303
1304 s.insert(10);
1305 s.insert(20);
1306 s.insert(30);
1307
1308 EXPECT_EQ(s.size(), 3u);
1309 EXPECT_EQ(s.top(), 30);
1310}
1311
1313{
1314 // This tests the queue-like interface that graph-traverse.H uses
1316
1317 s.put(1);
1318 s.put(2);
1319 s.put(3);
1320
1321 // For a stack, get returns in LIFO order
1322 EXPECT_EQ(s.get(), 3);
1323 EXPECT_EQ(s.get(), 2);
1324 EXPECT_EQ(s.get(), 1);
1325 EXPECT_TRUE(s.is_empty());
1326}
1327
1329{
1331
1332 // Mix push/put/insert - all should work the same
1333 s.push(1);
1334 s.put(2);
1335 s.insert(3);
1336
1337 EXPECT_EQ(s.size(), 3u);
1338
1339 // Mix pop/get - all should work the same
1340 EXPECT_EQ(s.pop(), 3);
1341 EXPECT_EQ(s.get(), 2);
1342 EXPECT_EQ(s.pop(), 1);
1343}
1344
1345// =============================================================================
1346// Main function
1347// =============================================================================
1348
1349int main(int argc, char** argv)
1350{
1351 ::testing::InitGoogleTest(&argc, argv);
1352 return RUN_ALL_TESTS();
1353}
Functional programming utilities for Aleph-w containers.
int main()
Dynamic stack of elements of generic type T based on a singly linked list.
void clear() noexcept
Alias for empty() - removes all elements.
T & top()
Return a modifiable reference to the top item of the stack.
bool is_empty() const noexcept
Check if the stack is empty.
constexpr size_t size() const noexcept
Return the number of elements in the stack.
T & emplace(Args &&... args)
Construct an item in place at the top of the stack.
T & peek()
Alias for top() - returns reference to top item.
void swap(DynListStack &other) noexcept
Swap the contents of this stack with another.
T * search(const T &key) noexcept
Search for an item in the stack using equality comparison.
T get()
Alias for pop() - removes and returns the top item.
T Item_Type
The type of elements stored in the stack.
T & put(const T &data)
Alias for push() - for compatibility with queue-like interfaces.
T & insert(const T &data)
Alias for push() - for STL-like insert semantics.
T pop()
Remove and return the top item of the stack.
T & push(const T &data)
Push an item by copy onto the top of the stack.
void empty() noexcept
Remove all elements from the stack.
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 & top() const
Definition htlist.H:1683
T & push(const T &item)
Definition htlist.H:1523
DynList & swap(DynList &l) noexcept
Swap this with l.
Definition htlist.H:1448
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
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
DynListStack< int > stack_with_items
void SetUp() override
DynListStack< int > empty_stack
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 for traversing elements of the stack.
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
Fixture with a stack of strings.
ThrowingType(const ThrowingType &other)
static void reset()
static int construction_count
ThrowingType(ThrowingType &&other) noexcept
Dynamic stack implementation based on linked lists.
TEST_F(DynListStackTest, DefaultConstruction)