Aleph-w 3.0
A C++ Library for Data Structures and Algorithms
Loading...
Searching...
No Matches
ah-uni-functional_test.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
45#include <gtest/gtest.h>
46#include <ah-uni-functional.H>
47
48// Aleph containers
49#include <htlist.H>
50#include <tpl_dynArray.H>
51#include <tpl_dynDlist.H>
52
53// STL containers
54#include <vector>
55#include <list>
56#include <deque>
57#include <string>
58
59using namespace Aleph;
60
61//==============================================================================
62// STL Container Tests
63//==============================================================================
64
66{
67 std::vector<int> v = {1, 2, 3, 4, 5};
68 auto squares = uni_map([](int x) { return x * x; }, v);
69
71 EXPECT_EQ(squares[0], 1);
72 EXPECT_EQ(squares[4], 25);
73}
74
76{
77 std::vector<int> v = {1, 2, 3, 4, 5, 6};
78 auto evens = uni_filter([](int x) { return x % 2 == 0; }, v);
79
80 EXPECT_EQ(evens.size(), 3);
81 EXPECT_EQ(evens[0], 2);
82 EXPECT_EQ(evens[2], 6);
83}
84
86{
87 std::vector<int> v = {1, 2, 3, 4, 5};
88 int sum = uni_foldl(0, [](int acc, int x) { return acc + x; }, v);
89 EXPECT_EQ(sum, 15);
90}
91
93{
94 std::vector<int> v = {2, 4, 6, 8};
95 EXPECT_TRUE(uni_all([](int x) { return x % 2 == 0; }, v));
96}
97
99{
100 std::vector<int> v = {1, 2, 3, 4, 5};
101 EXPECT_TRUE(uni_exists([](int x) { return x == 3; }, v));
102}
103
104//==============================================================================
105// Aleph Container Tests
106//==============================================================================
107
109{
110 DynList<int> l = {1, 2, 3, 4, 5};
111 auto squares = uni_map([](int x) { return x * x; }, l);
112
113 EXPECT_EQ(squares.size(), 5);
114 EXPECT_EQ(squares[0], 1);
115 EXPECT_EQ(squares[4], 25);
116}
117
119{
120 DynList<int> l = {1, 2, 3, 4, 5, 6};
121 auto evens = uni_filter([](int x) { return x % 2 == 0; }, l);
122
123 EXPECT_EQ(evens.size(), 3);
124 EXPECT_EQ(evens[0], 2);
125 EXPECT_EQ(evens[2], 6);
126}
127
129{
130 DynList<int> l = {1, 2, 3, 4, 5};
131 int sum = uni_foldl(0, [](int acc, int x) { return acc + x; }, l);
132 EXPECT_EQ(sum, 15);
133}
134
136{
137 DynList<int> l = {2, 4, 6, 8};
138 EXPECT_TRUE(uni_all([](int x) { return x % 2 == 0; }, l));
139}
140
142{
143 DynList<int> l = {1, 2, 3, 4, 5};
144 EXPECT_TRUE(uni_exists([](int x) { return x == 3; }, l));
145}
146
148{
149 DynArray<int> arr;
150 arr.append(1);
151 arr.append(2);
152 arr.append(3);
153
154 auto squares = uni_map([](int x) { return x * x; }, arr);
155
156 EXPECT_EQ(squares.size(), 3);
157 EXPECT_EQ(squares[0], 1);
158 EXPECT_EQ(squares[2], 9);
159}
160
162{
164 l.append(1);
165 l.append(2);
166 l.append(3);
167 l.append(4);
168 l.append(5);
169 l.append(6);
170
171 auto evens = uni_filter([](int x) { return x % 2 == 0; }, l);
172
173 EXPECT_EQ(evens.size(), 3);
174}
175
176//==============================================================================
177// Same Function Works on Both - Comparison Tests
178//==============================================================================
179
181{
182 std::vector<int> stl = {1, 2, 3, 4, 5};
183 DynList<int> aleph = {1, 2, 3, 4, 5};
184
185 auto stl_result = uni_map([](int x) { return x * 2; }, stl);
186 auto aleph_result = uni_map([](int x) { return x * 2; }, aleph);
187
189}
190
192{
193 std::vector<int> stl = {1, 2, 3, 4, 5, 6};
194 DynList<int> aleph = {1, 2, 3, 4, 5, 6};
195
196 auto stl_result = uni_filter([](int x) { return x > 3; }, stl);
197 auto aleph_result = uni_filter([](int x) { return x > 3; }, aleph);
198
200}
201
203{
204 std::vector<int> stl = {1, 2, 3, 4, 5};
205 DynList<int> aleph = {1, 2, 3, 4, 5};
206
207 int stl_sum = uni_foldl(0, [](int acc, int x) { return acc + x; }, stl);
208 int aleph_sum = uni_foldl(0, [](int acc, int x) { return acc + x; }, aleph);
209
211 EXPECT_EQ(stl_sum, 15);
212}
213
214//==============================================================================
215// ML-style Operations Tests
216//==============================================================================
217
219{
220 std::vector<std::string> stl = {"a", "b", "c"};
221 DynList<std::string> aleph = {"a", "b", "c"};
222
223 auto stl_result = uni_mapi([](size_t i, const std::string& s) {
224 return std::to_string(i) + s;
225 }, stl);
226
227 auto aleph_result = uni_mapi([](size_t i, const std::string& s) {
228 return std::to_string(i) + s;
229 }, aleph);
230
232 EXPECT_EQ(stl_result[0], "0a");
233 EXPECT_EQ(stl_result[2], "2c");
234}
235
237{
238 std::vector<int> stl = {10, 20, 30, 40, 50};
239 DynList<int> aleph = {10, 20, 30, 40, 50};
240
241 auto stl_evens = uni_filteri([](size_t i, int) { return i % 2 == 0; }, stl);
242 auto aleph_evens = uni_filteri([](size_t i, int) { return i % 2 == 0; }, aleph);
243
246}
247
249{
250 std::vector<int> stl = {1, 2, 3, 4};
251 DynList<int> aleph = {1, 2, 3, 4};
252
253 auto stl_sums = uni_scan_left(0, [](int acc, int x) { return acc + x; }, stl);
254 auto aleph_sums = uni_scan_left(0, [](int acc, int x) { return acc + x; }, aleph);
255
257 EXPECT_EQ(stl_sums.size(), 5);
258 EXPECT_EQ(stl_sums[0], 0);
259 EXPECT_EQ(stl_sums[4], 10);
260}
261
262//==============================================================================
263// Find Operations Tests
264//==============================================================================
265
267{
268 std::vector<int> stl = {1, 2, 3, 4, 5};
269 DynList<int> aleph = {1, 2, 3, 4, 5};
270
271 auto stl_result = uni_find([](int x) { return x > 3; }, stl);
272 auto aleph_result = uni_find([](int x) { return x > 3; }, aleph);
273
274 ASSERT_TRUE(stl_result.has_value());
275 ASSERT_TRUE(aleph_result.has_value());
278}
279
281{
282 std::vector<std::string> stl = {"a", "b", "c", "d"};
283 DynList<std::string> aleph = {"a", "b", "c", "d"};
284
285 auto stl_idx = uni_find_index([](const std::string& s) { return s == "c"; }, stl);
286 auto aleph_idx = uni_find_index([](const std::string& s) { return s == "c"; }, aleph);
287
288 ASSERT_TRUE(stl_idx.has_value());
289 ASSERT_TRUE(aleph_idx.has_value());
291 EXPECT_EQ(*stl_idx, 2);
292}
293
295{
296 std::vector<int> stl = {1, 2, 3, 4, 5};
297 DynList<int> aleph = {1, 2, 3, 4, 5};
298
303}
304
305//==============================================================================
306// Count and Length Tests
307//==============================================================================
308
310{
311 std::vector<int> stl = {1, 2, 3, 4, 5, 6};
312 DynList<int> aleph = {1, 2, 3, 4, 5, 6};
313
314 size_t stl_count = uni_count([](int x) { return x % 2 == 0; }, stl);
315 size_t aleph_count = uni_count([](int x) { return x % 2 == 0; }, aleph);
316
319}
320
322{
323 std::vector<int> stl = {1, 2, 3, 4, 5};
324 DynList<int> aleph = {1, 2, 3, 4, 5};
325
328}
329
330//==============================================================================
331// Take and Drop Tests
332//==============================================================================
333
335{
336 std::vector<int> stl = {1, 2, 3, 4, 5};
337 DynList<int> aleph = {1, 2, 3, 4, 5};
338
339 auto stl_result = uni_take(3, stl);
340 auto aleph_result = uni_take(3, aleph);
341
344 EXPECT_EQ(stl_result[2], 3);
345}
346
348{
349 std::vector<int> stl = {1, 2, 3, 4, 5};
350 DynList<int> aleph = {1, 2, 3, 4, 5};
351
352 auto stl_result = uni_drop(2, stl);
353 auto aleph_result = uni_drop(2, aleph);
354
357 EXPECT_EQ(stl_result[0], 3);
358}
359
361{
362 std::vector<int> stl = {1, 2, 3, 10, 4, 5};
363 DynList<int> aleph = {1, 2, 3, 10, 4, 5};
364
365 auto stl_result = uni_take_while([](int x) { return x < 10; }, stl);
366 auto aleph_result = uni_take_while([](int x) { return x < 10; }, aleph);
367
370}
371
373{
374 std::vector<int> stl = {1, 2, 3, 10, 4, 5};
375 DynList<int> aleph = {1, 2, 3, 10, 4, 5};
376
377 auto stl_result = uni_drop_while([](int x) { return x < 10; }, stl);
378 auto aleph_result = uni_drop_while([](int x) { return x < 10; }, aleph);
379
382 EXPECT_EQ(stl_result[0], 10);
383}
384
385//==============================================================================
386// Access Tests
387//==============================================================================
388
390{
391 std::vector<int> stl = {10, 20, 30};
392 DynList<int> aleph = {10, 20, 30};
393
394 auto stl_first = uni_first(stl);
396
397 ASSERT_TRUE(stl_first.has_value());
398 ASSERT_TRUE(aleph_first.has_value());
400 EXPECT_EQ(*stl_first, 10);
401}
402
404{
405 std::vector<int> stl = {10, 20, 30};
406 DynList<int> aleph = {10, 20, 30};
407
408 auto stl_last = uni_last(stl);
409 auto aleph_last = uni_last(aleph);
410
411 ASSERT_TRUE(stl_last.has_value());
412 ASSERT_TRUE(aleph_last.has_value());
414 EXPECT_EQ(*stl_last, 30);
415}
416
418{
419 std::vector<int> stl = {10, 20, 30, 40, 50};
420 DynList<int> aleph = {10, 20, 30, 40, 50};
421
422 auto stl_nth = uni_nth(2, stl);
423 auto aleph_nth = uni_nth(2, aleph);
424
425 ASSERT_TRUE(stl_nth.has_value());
426 ASSERT_TRUE(aleph_nth.has_value());
428 EXPECT_EQ(*stl_nth, 30);
429}
430
431//==============================================================================
432// Min/Max Tests
433//==============================================================================
434
436{
437 std::vector<int> stl = {3, 1, 4, 1, 5, 9};
438 DynList<int> aleph = {3, 1, 4, 1, 5, 9};
439
440 auto stl_min = uni_min(stl);
441 auto aleph_min = uni_min(aleph);
442
443 ASSERT_TRUE(stl_min.has_value());
444 ASSERT_TRUE(aleph_min.has_value());
446 EXPECT_EQ(*stl_min, 1);
447}
448
450{
451 std::vector<int> stl = {3, 1, 4, 1, 5, 9};
452 DynList<int> aleph = {3, 1, 4, 1, 5, 9};
453
454 auto stl_max = uni_max(stl);
455 auto aleph_max = uni_max(aleph);
456
457 ASSERT_TRUE(stl_max.has_value());
458 ASSERT_TRUE(aleph_max.has_value());
460 EXPECT_EQ(*stl_max, 9);
461}
462
464{
465 std::vector<int> stl = {3, 1, 4, 1, 5, 9};
466 DynList<int> aleph = {3, 1, 4, 1, 5, 9};
467
468 auto stl_mm = uni_min_max(stl);
469 auto aleph_mm = uni_min_max(aleph);
470
471 ASSERT_TRUE(stl_mm.has_value());
472 ASSERT_TRUE(aleph_mm.has_value());
473 EXPECT_EQ(stl_mm->first, aleph_mm->first);
474 EXPECT_EQ(stl_mm->second, aleph_mm->second);
475 EXPECT_EQ(stl_mm->first, 1);
476 EXPECT_EQ(stl_mm->second, 9);
477}
478
479//==============================================================================
480// Sum and Product Tests
481//==============================================================================
482
484{
485 std::vector<int> stl = {1, 2, 3, 4, 5};
486 DynList<int> aleph = {1, 2, 3, 4, 5};
487
489 EXPECT_EQ(uni_sum(stl), 15);
490}
491
493{
494 std::vector<int> stl = {1, 2, 3, 4};
495 DynList<int> aleph = {1, 2, 3, 4};
496
499}
500
501//==============================================================================
502// Partition Tests
503//==============================================================================
504
506{
507 std::vector<int> stl = {1, 2, 3, 4, 5, 6};
508 DynList<int> aleph = {1, 2, 3, 4, 5, 6};
509
510 auto [stl_evens, stl_odds] = uni_partition([](int x) { return x % 2 == 0; }, stl);
511 auto [aleph_evens, aleph_odds] = uni_partition([](int x) { return x % 2 == 0; }, aleph);
512
516 EXPECT_EQ(stl_odds.size(), 3);
517}
518
519//==============================================================================
520// Conversion Tests
521//==============================================================================
522
524{
525 DynList<int> aleph = {1, 2, 3, 4, 5};
526
527 auto vec = uni_to_vector(aleph);
528
529 EXPECT_EQ(vec.size(), 5);
530 EXPECT_EQ(vec[0], 1);
531 EXPECT_EQ(vec[4], 5);
532}
533
534//==============================================================================
535// Comparison Tests
536//==============================================================================
537
539{
540 std::vector<int> stl = {1, 2, 3};
541 DynList<int> aleph = {1, 2, 3};
542 DynList<int> aleph_diff = {1, 2, 4};
543
546}
547
549{
550 std::vector<int> stl = {1, 2, 3};
551 DynList<int> aleph_equal = {1, 2, 3};
552 DynList<int> aleph_less = {1, 2, 2};
553 DynList<int> aleph_greater = {1, 2, 4};
554
558}
559
560//==============================================================================
561// Works with Different STL Container Types
562//==============================================================================
563
565{
566 std::list<int> l = {1, 2, 3, 4, 5};
567
568 auto squares = uni_map([](int x) { return x * x; }, l);
569 EXPECT_EQ(squares.size(), 5);
570 EXPECT_EQ(squares[4], 25);
571}
572
574{
575 std::deque<int> d = {1, 2, 3, 4, 5, 6};
576
577 auto evens = uni_filter([](int x) { return x % 2 == 0; }, d);
578 EXPECT_EQ(evens.size(), 3);
579}
580
581//==============================================================================
582// Edge Cases
583//==============================================================================
584
586{
587 std::vector<int> empty;
588
589 auto mapped = uni_map([](int x) { return x * 2; }, empty);
591
592 auto first = uni_first(empty);
593 EXPECT_FALSE(first.has_value());
594
595 int sum = uni_foldl(0, std::plus<int>{}, empty);
596 EXPECT_EQ(sum, 0);
597}
598
600{
601 DynList<int> empty;
602
603 auto mapped = uni_map([](int x) { return x * 2; }, empty);
605
606 auto first = uni_first(empty);
607 EXPECT_FALSE(first.has_value());
608
609 int sum = uni_foldl(0, std::plus<int>{}, empty);
610 EXPECT_EQ(sum, 0);
611}
612
614{
615 std::vector<int> stl = {42};
616 DynList<int> aleph = {42};
617
622}
623
624// Main
625int main(int argc, char **argv)
626{
627 ::testing::InitGoogleTest(&argc, argv);
628 return RUN_ALL_TESTS();
629}
Unified functional programming utilities for both STL and Aleph containers.
int main()
T & append()
Allocate a new entry to the end of array.
Dynamic doubly linked list with O(1) size and bidirectional access.
Dynamic singly linked list with functional programming support.
Definition htlist.H:1423
T & append(const T &item)
Append a new item by copy.
Definition htlist.H:1562
void empty() noexcept
empty the list
Definition htlist.H:1689
size_t size() const noexcept
Count the number of elements of the list.
Definition htlist.H:1319
#define TEST(name)
Singly linked list implementations with head-tail access.
Main namespace for Aleph-w library functions.
Definition ah-arena.H:89
auto stl_first(const Container &c)
Get first element.
auto uni_filter(Pred &&pred, const Container &c)
Filter elements satisfying predicate.
auto uni_nth(size_t n, const Container &c)
Get n-th element.
auto stl_last(const Container &c)
Get last element.
auto stl_max(const Container &c)
Get maximum element.
int uni_compare(const Container1 &c1, const Container2 &c2)
Compare two containers lexicographically.
bool uni_equal(const Container1 &c1, const Container2 &c2)
Check equality of two containers.
std::vector< T > uni_scan_left(T init, Op &&op, const Container &c)
Scan left - fold with all intermediate results.
size_t uni_length(const Container &c)
Get container length.
auto stl_nth(const size_t n, const Container &c)
Get n-th element.
auto uni_drop_while(Pred &&pred, const Container &c)
Drop elements while predicate is true, return the rest.
auto uni_product(const Container &c)
Product of all elements.
auto uni_find(Pred &&pred, const Container &c)
Find first element satisfying predicate.
bool uni_mem(const T &target, const Container &c)
Check if element exists in container (mem in ML).
auto uni_filteri(Pred &&pred, const Container &c)
Filter with index (filteri in ML).
auto uni_map(Op &&op, const Container &c)
Map operation - transform each element.
size_t stl_count(Pred &&pred, const Container &c)
Count elements satisfying predicate.
auto stl_sum(const Container &c)
Sum all elements.
auto uni_last(const Container &c)
Get last element.
auto uni_min_max(const Container &c)
Get both min and max in a single pass.
auto uni_min(const Container &c)
Get minimum element.
size_t uni_count(Pred &&pred, const Container &c)
Count elements satisfying predicate.
auto stl_min(const Container &c)
Get minimum element.
T uni_foldl(T init, Op &&op, const Container &c)
Left fold (foldl) - reduce from left to right.
auto uni_drop(size_t n, const Container &c)
Drop first n elements, return the rest.
auto uni_max(const Container &c)
Get maximum element.
auto uni_take_while(Pred &&pred, const Container &c)
Take elements while predicate is true.
bool uni_all(Pred &&pred, const Container &c)
Check if all elements satisfy predicate.
auto uni_first(const Container &c)
Get first element.
auto uni_partition(Pred &&pred, const Container &c)
Partition elements by predicate.
auto uni_to_vector(const Container &c)
Convert container to std::vector.
auto uni_mapi(Op &&op, const Container &c)
Map with index (mapi in ML).
auto uni_take(size_t n, const Container &c)
Take first n elements.
auto uni_sum(const Container &c)
Sum all elements.
bool uni_exists(Pred &&pred, const Container &c)
Check if any element satisfies predicate.
DynList< T > maps(const C &c, Op op)
Classic map operation.
T sum(const Container &container, const T &init=T{})
Compute sum of all elements.
std::optional< size_t > uni_find_index(Pred &&pred, const Container &c)
Find index of first element satisfying predicate.
Lazy and scalable dynamic array implementation.
Dynamic doubly linked list implementation.
DynList< int > l