Aleph-w 3.0
A C++ Library for Data Structures and Algorithms
Loading...
Searching...
No Matches
ah_stl_functional_example.cc
Go to the documentation of this file.
1/*
2 Aleph_w
3
4 Data structures & Algorithms
5 version 2.0.0b
6 https://github.com/lrleon/Aleph-w
7
8 This file is part of Aleph-w library
9
10 Copyright (c) 2002-2026 Leandro Rabindranath Leon
11
12 Permission is hereby granted, free of charge, to any person obtaining a copy
13 of this software and associated documentation files (the "Software"), to deal
14 in the Software without restriction, including without limitation the rights
15 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
16 copies of the Software, and to permit persons to whom the Software is
17 furnished to do so, subject to the following conditions:
18
19 The above copyright notice and this permission notice shall be included in all
20 copies or substantial portions of the Software.
21
22 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
23 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
24 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
25 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
26 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
27 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
28 SOFTWARE.
29*/
30
45#include <iostream>
46#include <iomanip>
47#include <vector>
48#include <list>
49#include <set>
50#include <string>
51#include <ah-stl-functional.H>
52#include <ah-uni-functional.H>
53#include <htlist.H>
54#include <tpl_dynSetTree.H>
55
56using namespace std;
57using namespace Aleph;
58
59// Helper to print vectors
60template <typename T>
61void print_vec(const string & label, const vector<T> & v)
62{
63 cout << label << ": {";
64 for (size_t i = 0; i < v.size(); ++i)
65 {
66 cout << v[i];
67 if (i < v.size() - 1) cout << ", ";
68 }
69 cout << "}" << endl;
70}
71
72// Helper to print pairs
73template <typename T1, typename T2>
74void print_pairs(const string & label, const vector<pair<T1, T2>> & v)
75{
76 cout << label << ": {";
77 for (size_t i = 0; i < v.size(); ++i)
78 {
79 cout << "(" << v[i].first << ", " << v[i].second << ")";
80 if (i < v.size() - 1) cout << ", ";
81 }
82 cout << "}" << endl;
83}
84
85// Helper for nested vectors
86template <typename T>
87void print_nested(const string & label, const vector<vector<T>> & v)
88{
89 cout << label << ":" << endl;
90 for (const auto & inner : v)
91 {
92 cout << " {";
93 for (size_t i = 0; i < inner.size(); ++i)
94 {
95 cout << inner[i];
96 if (i < inner.size() - 1) cout << ", ";
97 }
98 cout << "}" << endl;
99 }
100}
101
102int main()
103{
104 cout << "========================================" << endl;
105 cout << " ah-stl-functional.H Usage Examples" << endl;
106 cout << "========================================" << endl << endl;
107
108 // ============================================================================
109 // 1. Range Generation
110 // ============================================================================
111 cout << "--- 1. Range Generation ---" << endl;
112
113 auto r1 = stl_range(1, 5);
114 print_vec("stl_range(1, 5)", r1);
115
116 auto r2 = stl_range(0, 10, 2);
117 print_vec("stl_range(0, 10, 2)", r2);
118
119 auto r3 = stl_range(5);
120 print_vec("stl_range(5)", r3);
121
122 auto lin = stl_linspace(0.0, 1.0, 5);
123 cout << "stl_linspace(0.0, 1.0, 5): {";
124 for (size_t i = 0; i < lin.size(); ++i)
125 {
126 cout << fixed << setprecision(2) << lin[i];
127 if (i < lin.size() - 1) cout << ", ";
128 }
129 cout << "}" << endl;
130
131 auto rep = stl_rep(4, 42);
132 print_vec("stl_rep(4, 42)", rep);
133
134 auto gen = stl_generate(5, [](size_t i) { return i * i; });
135 print_vec("stl_generate(5, i -> i²)", gen);
136
137 cout << endl;
138
139 // ============================================================================
140 // 2. Map and Transform
141 // ============================================================================
142 cout << "--- 2. Map and Transform ---" << endl;
143
144 vector<int> nums = {1, 2, 3, 4, 5};
145 print_vec("Original", nums);
146
147 auto squares = stl_map([](int x) { return x * x; }, nums);
148 print_vec("stl_map(x -> x²)", squares);
149
150 auto strings = stl_map([](int x) { return "num_" + to_string(x); }, nums);
151 print_vec("stl_map(x -> \"num_\" + x)", strings);
152
153 auto indexed = stl_mapi([](size_t i, int x) {
154 return "[" + to_string(i) + "]=" + to_string(x);
155 }, nums);
156 print_vec("stl_mapi((i, x) -> \"[i]=x\")", indexed);
157
158 cout << endl;
159
160 // ============================================================================
161 // 3. Filter and Reject
162 // ============================================================================
163 cout << "--- 3. Filter and Reject ---" << endl;
164
165 vector<int> data = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
166 print_vec("Original", data);
167
168 auto evens = stl_filter([](int x) { return x % 2 == 0; }, data);
169 print_vec("stl_filter(x -> x % 2 == 0)", evens);
170
171 auto odds = stl_reject([](int x) { return x % 2 == 0; }, data);
172 print_vec("stl_reject(x -> x % 2 == 0)", odds);
173
174 auto even_indices = stl_filteri([](size_t i, int) { return i % 2 == 0; }, data);
175 print_vec("stl_filteri((i, x) -> i % 2 == 0)", even_indices);
176
177 cout << endl;
178
179 // ============================================================================
180 // 4. Fold (Reduce) Operations
181 // ============================================================================
182 cout << "--- 4. Fold (Reduce) Operations ---" << endl;
183
184 vector<int> v = {1, 2, 3, 4, 5};
185 print_vec("Original", v);
186
187 int sum = stl_foldl(0, [](int acc, int x) { return acc + x; }, v);
188 cout << "stl_foldl(0, +): " << sum << endl;
189
190 int product = stl_foldl(1, [](int acc, int x) { return acc * x; }, v);
191 cout << "stl_foldl(1, *): " << product << endl;
192
193 // Right fold: 1 - (2 - (3 - (4 - (5 - 0)))) = 3
194 int foldr_result = stl_foldr(0, [](int x, int acc) { return x - acc; }, v);
195 cout << "stl_foldr(0, -): " << foldr_result << " (1-(2-(3-(4-(5-0)))))" << endl;
196
197 // Scan left: running sum
198 auto scan = stl_scan_left(0, [](int acc, int x) { return acc + x; }, v);
199 print_vec("stl_scan_left(0, +)", scan);
200
201 cout << endl;
202
203 // ============================================================================
204 // 5. Predicates (all, exists, none)
205 // ============================================================================
206 cout << "--- 5. Predicates ---" << endl;
207
208 vector<int> all_even = {2, 4, 6, 8};
209 vector<int> some_even = {1, 2, 3, 4};
210 vector<int> no_even = {1, 3, 5, 7};
211
212 auto is_even = [](int x) { return x % 2 == 0; };
213
214 cout << "all_even = {2, 4, 6, 8}" << endl;
215 cout << " stl_all(is_even): " << boolalpha << stl_all(is_even, all_even) << endl;
216 cout << " stl_exists(is_even): " << stl_exists(is_even, all_even) << endl;
217 cout << " stl_none(is_even): " << stl_none(is_even, all_even) << endl;
218
219 cout << "no_even = {1, 3, 5, 7}" << endl;
220 cout << " stl_all(is_even): " << stl_all(is_even, no_even) << endl;
221 cout << " stl_exists(is_even): " << stl_exists(is_even, no_even) << endl;
222 cout << " stl_none(is_even): " << stl_none(is_even, no_even) << endl;
223
224 cout << endl;
225
226 // ============================================================================
227 // 6. Finding Elements
228 // ============================================================================
229 cout << "--- 6. Finding Elements ---" << endl;
230
231 vector<int> find_data = {10, 20, 30, 40, 50};
232 print_vec("Original", find_data);
233
234 auto found = stl_find([](int x) { return x > 25; }, find_data);
235 cout << "stl_find(x > 25): " << (found ? to_string(*found) : "not found") << endl;
236
237 auto last_found = stl_find_last([](int x) { return x < 45; }, find_data);
238 cout << "stl_find_last(x < 45): " << (last_found ? to_string(*last_found) : "not found") << endl;
239
240 auto idx = stl_find_index([](int x) { return x == 30; }, find_data);
241 cout << "stl_find_index(x == 30): " << (idx ? to_string(*idx) : "not found") << endl;
242
243 cout << "stl_mem(30, data): " << stl_mem(30, find_data) << endl;
244 cout << "stl_mem(99, data): " << stl_mem(99, find_data) << endl;
245
246 cout << endl;
247
248 // ============================================================================
249 // 7. Counting
250 // ============================================================================
251 cout << "--- 7. Counting ---" << endl;
252
253 vector<int> count_data = {1, 2, 2, 3, 3, 3, 4, 4, 4, 4};
254 print_vec("Original", count_data);
255
256 cout << "stl_count(x -> x % 2 == 0): " << stl_count(is_even, count_data) << endl;
257 cout << "stl_count_value(3): " << stl_count_value(3, count_data) << endl;
258
259 cout << endl;
260
261 // ============================================================================
262 // 8. Take and Drop
263 // ============================================================================
264 cout << "--- 8. Take and Drop ---" << endl;
265
266 vector<int> td = {1, 2, 3, 4, 5, 6, 7, 8};
267 print_vec("Original", td);
268
269 print_vec("stl_take(3)", stl_take(3, td));
270 print_vec("stl_drop(3)", stl_drop(3, td));
271 print_vec("stl_take_last(3)", stl_take_last(3, td));
272 print_vec("stl_take_while(x < 5)", stl_take_while([](int x) { return x < 5; }, td));
273 print_vec("stl_drop_while(x < 5)", stl_drop_while([](int x) { return x < 5; }, td));
274
275 cout << endl;
276
277 // ============================================================================
278 // 9. Accessing Elements
279 // ============================================================================
280 cout << "--- 9. Accessing Elements ---" << endl;
281
282 vector<int> access = {10, 20, 30, 40, 50};
283 print_vec("Original", access);
284
285 auto first = stl_first(access);
286 cout << "stl_first: " << (first ? to_string(*first) : "empty") << endl;
287
288 auto last = stl_last(access);
289 cout << "stl_last: " << (last ? to_string(*last) : "empty") << endl;
290
291 auto nth = stl_nth(2, access);
292 cout << "stl_nth(2): " << (nth ? to_string(*nth) : "out of bounds") << endl;
293
294 cout << endl;
295
296 // ============================================================================
297 // 10. Min, Max, Sum, Product
298 // ============================================================================
299 cout << "--- 10. Min, Max, Sum, Product ---" << endl;
300
301 vector<int> mm = {3, 1, 4, 1, 5, 9, 2, 6};
302 print_vec("Original", mm);
303
304 cout << "stl_min: " << *stl_min(mm) << endl;
305 cout << "stl_max: " << *stl_max(mm) << endl;
306
307 auto [min_val, max_val] = *stl_min_max(mm);
308 cout << "stl_min_max: (" << min_val << ", " << max_val << ")" << endl;
309
310 cout << "stl_sum: " << stl_sum(mm) << endl;
311 cout << "stl_product: " << stl_product(mm) << endl;
312
313 vector<string> words = {"hello", "a", "wonderful", "world"};
314 auto shortest = stl_min_by([](const string & s) { return s.length(); }, words);
315 auto longest = stl_max_by([](const string & s) { return s.length(); }, words);
316 cout << "Shortest word: " << *shortest << endl;
317 cout << "Longest word: " << *longest << endl;
318
319 cout << endl;
320
321 // ============================================================================
322 // 11. Partition
323 // ============================================================================
324 cout << "--- 11. Partition ---" << endl;
325
326 vector<int> part = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
327 print_vec("Original", part);
328
330 print_vec("Evens (matching)", evens_part);
331 print_vec("Odds (non-matching)", odds_part);
332
333 cout << endl;
334
335 // ============================================================================
336 // 12. Zip and Enumerate
337 // ============================================================================
338 cout << "--- 12. Zip and Enumerate ---" << endl;
339
340 vector<int> keys = {1, 2, 3};
341 vector<string> values = {"one", "two", "three"};
342
343 print_vec("Keys", keys);
344 print_vec("Values", values);
345
346 auto zipped = stl_zip_to_pairs(keys, values);
347 print_pairs("stl_zip_to_pairs", zipped);
348
350 print_vec("Unzipped keys", unzipped_keys);
351 print_vec("Unzipped values", unzipped_values);
352
353 auto enumerated = stl_enumerate_to_pairs(values);
354 print_pairs("stl_enumerate_to_pairs", enumerated);
355
356 cout << endl;
357
358 // ============================================================================
359 // 13. Reverse and Sort
360 // ============================================================================
361 cout << "--- 13. Reverse and Sort ---" << endl;
362
363 vector<int> unsorted = {3, 1, 4, 1, 5, 9, 2, 6};
364 print_vec("Original", unsorted);
365
366 print_vec("stl_reverse", stl_reverse(unsorted));
367 print_vec("stl_sort", stl_sort(unsorted));
368 print_vec("stl_sort_by(descending)", stl_sort_by([](int a, int b) { return a > b; }, unsorted));
369
370 cout << endl;
371
372 // ============================================================================
373 // 14. Unique and Distinct
374 // ============================================================================
375 cout << "--- 14. Unique and Distinct ---" << endl;
376
377 vector<int> with_dups = {1, 1, 2, 2, 2, 3, 3, 1, 1};
378 print_vec("Original", with_dups);
379
380 print_vec("stl_unique (consecutive)", stl_unique(with_dups));
381 print_vec("stl_distinct (all)", stl_distinct(with_dups));
382
383 cout << endl;
384
385 // ============================================================================
386 // 15. Concat and Flatten
387 // ============================================================================
388 cout << "--- 15. Concat and Flatten ---" << endl;
389
390 vector<int> a = {1, 2, 3};
391 vector<int> b = {4, 5, 6};
392 print_vec("a", a);
393 print_vec("b", b);
394 print_vec("stl_concat(a, b)", stl_concat(a, b));
395
396 vector<vector<int>> nested = {{1, 2}, {3, 4}, {5}};
397 print_nested("Nested", nested);
398 print_vec("stl_flatten", stl_flatten(nested));
399
400 auto flat_mapped = stl_flat_map([](int x) {
401 return vector<int>{x, x * 10};
402 }, a);
403 print_vec("stl_flat_map(x -> {x, x*10})", flat_mapped);
404
405 cout << endl;
406
407 // ============================================================================
408 // 16. Grouping
409 // ============================================================================
410 cout << "--- 16. Grouping ---" << endl;
411
412 vector<int> to_group = {1, 1, 2, 2, 2, 3, 1};
413 print_vec("Original", to_group);
414
415 auto grouped = stl_group(to_group);
416 cout << "stl_group (consecutive):" << endl;
417 for (const auto & g : grouped)
418 {
419 cout << " ";
420 print_vec("", g);
421 }
422
423 vector<string> words_to_group = {"apple", "ant", "banana", "bear", "apricot"};
424 print_vec("Words", words_to_group);
425
426 auto by_first_char = stl_group_by([](const string & s) { return s[0]; }, words_to_group);
427 cout << "stl_group_by(first char):" << endl;
428 for (const auto & [key, vals] : by_first_char)
429 {
430 cout << " '" << key << "': ";
431 print_vec("", vals);
432 }
433
434 cout << endl;
435
436 // ============================================================================
437 // 17. Tally (Frequency Count)
438 // ============================================================================
439 cout << "--- 17. Tally (Frequency Count) ---" << endl;
440
441 vector<string> fruits = {"apple", "banana", "apple", "cherry", "banana", "apple"};
442 print_vec("Original", fruits);
443
444 auto tally = stl_tally(fruits);
445 cout << "stl_tally:" << endl;
446 for (const auto & [item, count] : tally)
447 cout << " \"" << item << "\": " << count << endl;
448
449 cout << endl;
450
451 // ============================================================================
452 // 18. Sliding Window and Chunks
453 // ============================================================================
454 cout << "--- 18. Sliding Window and Chunks ---" << endl;
455
456 vector<int> seq = {1, 2, 3, 4, 5};
457 print_vec("Original", seq);
458
459 auto windows = stl_sliding_window(3, seq);
460 print_nested("stl_sliding_window(3)", windows);
461
462 auto chunks = stl_chunks(2, seq);
463 print_nested("stl_chunks(2)", chunks);
464
465 cout << endl;
466
467 // ============================================================================
468 // 19. Intersperse, Split, Span
469 // ============================================================================
470 cout << "--- 19. Intersperse, Split, Span ---" << endl;
471
472 vector<int> to_inter = {1, 2, 3};
473 print_vec("Original", to_inter);
474
475 print_vec("stl_intersperse(0)", stl_intersperse(0, to_inter));
476
477 vector<int> to_split = {1, 2, 3, 4, 5};
479 print_vec("stl_split_at(2) first", first_part);
480 print_vec("stl_split_at(2) second", second_part);
481
482 auto [span_match, span_rest] = stl_span([](int x) { return x < 4; }, to_split);
483 print_vec("stl_span(x < 4) matching", span_match);
484 print_vec("stl_span(x < 4) rest", span_rest);
485
486 cout << endl;
487
488 // ============================================================================
489 // 20. Init and Tail
490 // ============================================================================
491 cout << "--- 20. Init and Tail ---" << endl;
492
493 vector<int> it = {1, 2, 3, 4, 5};
494 print_vec("Original", it);
495
496 print_vec("stl_init (all except last)", stl_init(it));
497 print_vec("stl_tail (all except first)", stl_tail(it));
498
499 cout << endl;
500
501 // ============================================================================
502 // 21. Combinatorics
503 // ============================================================================
504 cout << "--- 21. Combinatorics ---" << endl;
505
506 vector<int> comb_set = {1, 2, 3};
507 print_vec("Original", comb_set);
508
510 cout << "stl_permutations (" << perms.size() << " total):" << endl;
511 for (const auto & p : perms)
512 {
513 cout << " ";
514 print_vec("", p);
515 }
516
518 cout << "stl_combinations(2) (" << combos.size() << " total):" << endl;
519 for (const auto & c : combos)
520 {
521 cout << " ";
522 print_vec("", c);
523 }
524
525 auto arrs = stl_arrangements(2, comb_set);
526 cout << "stl_arrangements(2) (" << arrs.size() << " total):" << endl;
527 for (const auto & arr : arrs)
528 {
529 cout << " ";
530 print_vec("", arr);
531 }
532
533 cout << endl;
534
535 // ============================================================================
536 // 22. Cartesian Product and Power Set
537 // ============================================================================
538 cout << "--- 22. Cartesian Product and Power Set ---" << endl;
539
540 vector<vector<int>> sets = {{1, 2}, {3, 4}};
541 cout << "Sets: {{1, 2}, {3, 4}}" << endl;
542
544 print_nested("stl_cartesian_product", cart);
545
546 vector<int> ps_set = {1, 2, 3};
547 print_vec("Original", ps_set);
548
549 auto power = stl_power_set(ps_set);
550 cout << "stl_power_set (" << power.size() << " subsets):" << endl;
551 for (const auto & s : power)
552 {
553 cout << " {";
554 for (size_t i = 0; i < s.size(); ++i)
555 {
556 cout << s[i];
557 if (i < s.size() - 1) cout << ", ";
558 }
559 cout << "}" << endl;
560 }
561
562 cout << endl;
563
564 // ============================================================================
565 // 23. Works with Different STL Container Types
566 // ============================================================================
567 cout << "--- 23. Works with Different STL Container Types ---" << endl;
568
569 // std::list
570 list<int> my_list = {1, 2, 3, 4, 5};
571 cout << "std::list<int>: {1, 2, 3, 4, 5}" << endl;
572
573 auto list_squares = stl_map([](int x) { return x * x; }, my_list);
574 print_vec("stl_map(x -> x²) on list", list_squares);
575
576 int list_sum = stl_foldl(0, std::plus<int>{}, my_list);
577 cout << "stl_foldl(0, +) on list: " << list_sum << endl;
578
579 cout << endl;
580
581 // std::set (ordered, unique elements)
582 set<int> my_set = {5, 2, 8, 1, 9, 3};
583 cout << "std::set<int>: {5, 2, 8, 1, 9, 3} -> ordered: {";
584 bool first_set = true;
585 for (int x : my_set)
586 {
587 if (!first_set) cout << ", ";
588 cout << x;
589 first_set = false;
590 }
591 cout << "}" << endl;
592
593 auto set_doubled = stl_map([](int x) { return x * 2; }, my_set);
594 print_vec("stl_map(x -> x*2) on set", set_doubled);
595
596 auto set_filtered_gt3 = stl_filter([](int x) { return x > 3; }, my_set);
597 print_vec("stl_filter(x > 3) on set", set_filtered_gt3);
598
599 cout << "stl_sum on set: " << stl_sum(my_set) << endl;
600
601 cout << endl;
602
603 // ============================================================================
604 // 23b. Works with Aleph Containers (using uni_* functions)
605 // ============================================================================
606 cout << "--- 23b. Aleph Containers (DynList, DynSetTree) ---" << endl;
607
608 // DynList (Aleph singly-linked list)
609 DynList<int> dyn_list = {10, 20, 30, 40, 50};
610 cout << "DynList<int>: {10, 20, 30, 40, 50}" << endl;
611
612 // uni_map/uni_filter return std::vector, works with both STL and Aleph containers
613 auto dyn_list_squares = uni_map([](int x) { return x * x; }, dyn_list);
614 print_vec("uni_map(x -> x²) on DynList", dyn_list_squares);
615
616 auto dyn_list_filtered = uni_filter([](int x) { return x >= 30; }, dyn_list);
617 print_vec("uni_filter(x >= 30) on DynList", dyn_list_filtered);
618
619 int dyn_list_sum = uni_foldl(0, [](int a, int b) { return a + b; }, dyn_list);
620 cout << "uni_foldl(0, +) on DynList: " << dyn_list_sum << endl;
621
622 cout << endl;
623
624 // DynSetTree (Aleph balanced tree set)
626 dyn_tree.insert(15);
627 dyn_tree.insert(5);
628 dyn_tree.insert(25);
629 dyn_tree.insert(10);
630 dyn_tree.insert(20);
631 cout << "DynSetTree<int>: {15, 5, 25, 10, 20} -> in-order: {";
632 bool first_tree = true;
633 for (auto it = dyn_tree.get_it(); it.has_curr(); it.next_ne())
634 {
635 if (!first_tree) cout << ", ";
636 cout << it.get_curr();
637 first_tree = false;
638 }
639 cout << "}" << endl;
640
641 auto tree_mapped = uni_map([](int x) { return x + 100; }, dyn_tree);
642 print_vec("uni_map(x -> x+100) on DynSetTree", tree_mapped);
643
645 uni_filter([](int x) { return x % 2 == 0; }, dyn_tree);
646 print_vec("uni_filter(even) on DynSetTree", dyn_tree_even_filtered);
647
648 bool tree_all_positive = uni_all([](int x) { return x > 0; }, dyn_tree);
649 cout << "uni_all(x > 0) on DynSetTree: " << boolalpha << tree_all_positive << endl;
650
651 cout << endl;
652
653 // ============================================================================
654 // 23c. Mixing STL and Aleph Results
655 // ============================================================================
656 cout << "--- 23c. Mixing STL and Aleph Results ---" << endl;
657
658 // Create containers of different types
659 vector<int> vec_a = {1, 2, 3, 4, 5};
660 set<int> set_b = {10, 20, 30, 40, 50};
661 DynList<int> dlist_c = {100, 200, 300, 400, 500};
662
663 cout << "vector: {1, 2, 3, 4, 5}" << endl;
664 cout << "set: {10, 20, 30, 40, 50}" << endl;
665 cout << "DynList: {100, 200, 300, 400, 500}" << endl;
666 cout << endl;
667
668 // Apply same squaring operation to all
669 auto vec_sq = stl_map([](int x) { return x * x; }, vec_a);
670 auto set_sq = stl_map([](int x) { return x * x; }, set_b);
671
672 // For DynList, uni_map already returns a std::vector
673 auto dlist_sq = uni_map([](int x) { return x * x; }, dlist_c);
674
675 print_vec("squares from vector", vec_sq);
676 print_vec("squares from set", set_sq);
677 print_vec("squares from DynList", dlist_sq);
678
679 // Combine results using STL concat
681 print_vec("All squares combined", combined);
682
683 cout << "Sum of all squares: " << stl_sum(combined) << endl;
684
685 cout << endl;
686
687 // ============================================================================
688 // 23d. Unified API Example: DynList, set, vector, DynSetTree
689 // ============================================================================
690 cout << "--- 23d. Unified API with uni_*: DynList, set, vector, DynSetTree ---" << endl;
691
692 // Create four different container types with similar data
693 vector<int> uni_vec = {10, 5, 8, 3, 15, 7, 12};
694 set<int> uni_set = {10, 5, 8, 3, 15, 7, 12};
696 for (int x : {10, 5, 8, 3, 15, 7, 12})
697 uni_dlist.append(x);
698
700 for (int x : {10, 5, 8, 3, 15, 7, 12})
701 uni_tree.insert(x);
702
703 cout << "All containers initialized with: {10, 5, 8, 3, 15, 7, 12}" << endl;
704 cout << " vector preserves insertion order" << endl;
705 cout << " set sorts and removes duplicates" << endl;
706 cout << " DynList preserves insertion order" << endl;
707 cout << " DynSetTree sorts and stores unique values" << endl;
708 cout << endl;
709
710 // Same operation applied to all containers using uni_* functions
711 auto is_greater_than_7 = [](int x) { return x > 7; };
712 auto square = [](int x) { return x * x; };
713
714 // 1. Filter: Keep only elements > 7
719
720 cout << "After uni_filter(x > 7):" << endl;
721 print_vec(" vector", vec_filtered);
722 print_vec(" set", set_filtered);
723 print_vec(" DynList", dlist_filtered);
724 print_vec(" DynSetTree", tree_filtered);
725 cout << endl;
726
727 // 2. Map: Square all remaining elements
728 auto vec_squared = uni_map(square, vec_filtered);
729 auto set_squared = uni_map(square, set_filtered);
730 auto dlist_squared = uni_map(square, dlist_filtered);
731 auto tree_squared = uni_map(square, tree_filtered);
732
733 cout << "After uni_map(x -> x²) on filtered results:" << endl;
734 print_vec(" vector", vec_squared);
735 print_vec(" set", set_squared);
736 print_vec(" DynList", dlist_squared);
737 print_vec(" DynSetTree", tree_squared);
738 cout << endl;
739
740 // 3. Fold: Sum all squared values
741 auto sum_op = [](int acc, int x) { return acc + x; };
746
747 cout << "After uni_foldl(0, +) on squared results:" << endl;
748 cout << " vector sum: " << vec_sum << endl;
749 cout << " set sum: " << set_sum << endl;
750 cout << " DynList sum: " << dlist_sum << endl;
751 cout << " DynSetTree sum: " << tree_sum << endl;
752 cout << endl;
753
754 // 4. Predicates: Check properties
755 auto all_positive = [](int x) { return x > 0; };
756 auto has_large = [](int x) { return x > 100; };
757
758 cout << "Predicate tests using uni_all and uni_exists:" << endl;
759 cout << " vector - uni_all(x > 0): " << boolalpha << uni_all(all_positive, uni_vec) << endl;
760 cout << " set - uni_all(x > 0): " << uni_all(all_positive, uni_set) << endl;
761 cout << " DynList - uni_all(x > 0): " << uni_all(all_positive, uni_dlist) << endl;
762 cout << " DynSetTree - uni_all(x > 0): " << uni_all(all_positive, uni_tree) << endl;
763 cout << endl;
764 cout << " vector - uni_exists(x > 100): " << uni_exists(has_large, vec_squared) << endl;
765 cout << " set - uni_exists(x > 100): " << uni_exists(has_large, set_squared) << endl;
766 cout << " DynList - uni_exists(x > 100): " << uni_exists(has_large, dlist_squared) << endl;
767 cout << " DynSetTree - uni_exists(x > 100): " << uni_exists(has_large, tree_squared) << endl;
768 cout << endl;
769
770 // 5. Min/Max operations
771 cout << "Min/Max operations:" << endl;
772 auto vec_min = uni_min(uni_vec);
773 auto set_min = uni_min(uni_set);
775 auto tree_min = uni_min(uni_tree);
776
777 cout << " vector min: " << (vec_min ? to_string(*vec_min) : "empty") << endl;
778 cout << " set min: " << (set_min ? to_string(*set_min) : "empty") << endl;
779 cout << " DynList min: " << (dlist_min ? to_string(*dlist_min) : "empty") << endl;
780 cout << " DynSetTree min: " << (tree_min ? to_string(*tree_min) : "empty") << endl;
781 cout << endl;
782
783 // 6. Take/Drop operations
784 cout << "Take/Drop operations (first 3 elements):" << endl;
785 auto vec_take = uni_take(3, uni_vec);
786 auto set_take = uni_take(3, uni_set);
787 auto dlist_take = uni_take(3, uni_dlist);
788 auto tree_take = uni_take(3, uni_tree);
789
790 print_vec(" uni_take(3) from vector", vec_take);
791 print_vec(" uni_take(3) from set", set_take);
792 print_vec(" uni_take(3) from DynList", dlist_take);
793 print_vec(" uni_take(3) from DynSetTree", tree_take);
794 cout << endl;
795
796 // 7. Comparison across container types
797 cout << "Cross-container comparisons:" << endl;
798 cout << " vector == DynList: " << boolalpha << uni_equal(uni_vec, uni_dlist) << endl;
799 cout << " set == DynSetTree: " << uni_equal(uni_set, uni_tree) << endl;
800 cout << " vector == set: " << uni_equal(uni_vec, uni_set) << " (order differs)" << endl;
801 cout << endl;
802
803 // 8. Unified pipeline demonstration
804 cout << "Unified pipeline: filter -> map -> take -> sum" << endl;
805 cout << " Applied identically to all four container types" << endl;
806
807 auto pipeline = [](const auto & container) {
808 auto step1 = uni_filter([](int x) { return x % 2 != 0; }, container); // odd numbers
809 auto step2 = uni_map([](int x) { return x * 3; }, step1); // triple them
810 auto step3 = uni_take(2, step2); // first 2
811 return uni_sum(step3); // sum
812 };
813
814 cout << " vector result: " << pipeline(uni_vec) << endl;
815 cout << " set result: " << pipeline(uni_set) << endl;
816 cout << " DynList result: " << pipeline(uni_dlist) << endl;
817 cout << " DynSetTree result: " << pipeline(uni_tree) << endl;
818 cout << endl;
819
820 cout << "Key insight: uni_* functions provide a single API that works" << endl;
821 cout << "seamlessly with both STL containers (vector, set) and Aleph" << endl;
822 cout << "containers (DynList, DynSetTree) without any code changes!" << endl;
823
824 cout << endl;
825
826 // ============================================================================
827 // 24. Function Composition Example
828 // ============================================================================
829 cout << "--- 24. Function Composition Example ---" << endl;
830
831 vector<int> raw = {1, 2, 2, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 5};
832 print_vec("Raw data", raw);
833
834 // Pipeline: distinct -> filter evens -> square -> sum
837 auto squared_vals = stl_map([](int x) { return x * x; }, even_vals);
838 int final_sum = stl_foldl(0, std::plus<int>{}, squared_vals);
839
840 cout << "Pipeline: distinct -> filter(even) -> map(square) -> sum" << endl;
841 print_vec(" After distinct", distinct_vals);
842 print_vec(" After filter(even)", even_vals);
843 print_vec(" After map(square)", squared_vals);
844 cout << " Final sum: " << final_sum << endl;
845
846 cout << endl;
847 cout << "========================================" << endl;
848 cout << " All examples completed successfully!" << endl;
849 cout << "========================================" << endl;
850
851 return 0;
852}
Functional programming utilities for C++ Standard Library containers.
Unified functional programming utilities for both STL and Aleph containers.
void print_vec(const string &label, const vector< T > &v)
void print_nested(const string &label, const vector< vector< T > > &v)
void print_pairs(const string &label, const vector< pair< T1, T2 > > &v)
Dynamic singly linked list with functional programming support.
Definition htlist.H:1423
T & insert(const T &item)
Insert a new item by copy.
Definition htlist.H:1502
T & append(const T &item)
Append a new item by copy.
Definition htlist.H:1562
Dynamic set backed by balanced binary search trees with automatic memory management.
size_t size() const noexcept
Count the number of elements of the list.
Definition htlist.H:1319
auto get_it() const
Return a properly initialized iterator positioned at the first item on the container.
Definition ah-dry.H:190
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.
std::vector< T > stl_scan_left(T init, Op &&op, const Container &c)
Scan left - fold with all intermediate results.
auto uni_filter(Pred &&pred, const Container &c)
Filter elements satisfying predicate.
auto stl_span(Pred &&pred, const Container &c)
Split at predicate boundary (span in Haskell).
auto stl_take_last(size_t n, const Container &c)
Take last n elements.
auto stl_chunks(size_t n, const Container &c)
Split container into chunks of size n (each_slice in Ruby).
auto stl_min_max(const Container &c)
Get both min and max in a single pass.
auto stl_last(const Container &c)
Get last element.
auto stl_distinct(const Container &c)
Remove all duplicates (keeps first occurrence).
auto stl_max(const Container &c)
Get maximum element.
bool uni_equal(const Container1 &c1, const Container2 &c2)
Check equality of two containers.
auto stl_flatten(const Container &c)
Flatten a container of containers.
auto stl_reject(Pred &&pred, const Container &c)
Filter out elements (reject in Ruby, opposite of filter).
auto stl_filter(Pred &&pred, const Container &c)
Filter elements satisfying predicate.
auto stl_arrangements(size_t k, const Container &c)
Generate all k-arrangements (k-permutations) of a container.
auto stl_drop(size_t n, const Container &c)
Drop first n elements, return the rest.
auto stl_enumerate_to_pairs(const Container &c)
Enumerate container (return pairs of index and element).
auto stl_concat(const Container1 &c1, const Container2 &c2)
Concatenate two containers.
auto stl_combinations(size_t k, const Container &c)
Generate all k-combinations of a container.
auto stl_take_while(Pred &&pred, const Container &c)
Take elements while predicate is true.
auto stl_nth(const size_t n, const Container &c)
Get n-th element.
auto stl_map(Op &&op, const Container &c)
Map operation - transform each element.
bool stl_mem(const T &target, const Container &c)
Check if element exists in container (mem in ML).
std::optional< size_t > stl_find_index(Pred &&pred, const Container &c)
Find index of first element satisfying predicate.
T stl_foldl(T init, Op &&op, const Container &c)
Left fold (foldl) - reduce from left to right.
auto stl_min_by(Key &&key, const Container &c)
Get minimum element by key function.
std::vector< T > stl_linspace(T start, T end, size_t n)
Generate n evenly spaced values between start and end.
bool stl_exists(Pred &&pred, const Container &c)
Check if any element satisfies predicate.
auto stl_take(size_t n, const Container &c)
Take first n elements.
auto stl_generate(size_t n, Gen &&gen)
Generate a vector using a generator function.
std::vector< T > stl_range(T start, T end, T step=1)
Generate a range of values [start, end] with given step.
auto stl_init(const Container &c)
Get all elements except the last (init in Haskell).
size_t stl_count_value(const T &target, const Container &c)
Count occurrences of a value.
auto stl_sort(const Container &c)
Return sorted copy of container.
auto stl_permutations(const Container &c)
Generate all permutations of a container.
T product(const Container &container, const T &init=T{1})
Compute product of all elements.
auto stl_tally(const Container &c)
Count occurrences of each element (tally in Ruby, frequencies).
std::pair< First, Second > pair
Alias to std::pair kept for backwards compatibility.
Definition ahPair.H:89
bool stl_all(Pred &&pred, const Container &c)
Check if all elements satisfy predicate.
auto stl_partition(Pred &&pred, const Container &c)
Partition elements by predicate.
auto stl_unique(const Container &c)
Remove consecutive duplicates.
auto uni_map(Op &&op, const Container &c)
Map operation - transform each element.
auto stl_mapi(Op &&op, const Container &c)
Map with index (mapi in ML).
size_t stl_count(Pred &&pred, const Container &c)
Count elements satisfying predicate.
auto stl_sum(const Container &c)
Sum all elements.
bool is_even(const long n)
Return true if n is even.
Definition ahUtils.H:102
auto uni_min(const Container &c)
Get minimum element.
auto stl_sliding_window(size_t n, const Container &c)
Sliding window of size n over container (each_cons in Ruby).
auto stl_max_by(Key &&key, const Container &c)
Get maximum element by key function.
std::string to_string(const time_t t, const std::string &format)
Format a time_t value into a string using format.
Definition ah-date.H:140
auto stl_group_by(Key &&key, const Container &c)
Group elements by key function.
auto stl_min(const Container &c)
Get minimum element.
bool stl_none(Pred &&pred, const Container &c)
Check if no element satisfies predicate.
auto stl_reverse(const Container &c)
Return reversed copy of container.
auto stl_flat_map(Op &&op, const Container &c)
Flat map - map then flatten.
std::vector< T > stl_rep(size_t n, const T &value)
Generate a vector of n repeated values.
T uni_foldl(T init, Op &&op, const Container &c)
Left fold (foldl) - reduce from left to right.
T stl_foldr(T init, Op &&op, const Container &c)
Right fold (foldr) - reduce from right to left.
auto stl_unzip_pairs(const Container &c)
Unzip pairs into two vectors.
auto stl_drop_while(Pred &&pred, const Container &c)
Drop elements while predicate is true, return the rest.
auto stl_intersperse(const T &sep, const Container &c)
Insert element between each pair (intersperse in Haskell).
auto stl_cartesian_product(const std::vector< std::vector< T > > &containers)
Generate cartesian product of multiple containers.
auto stl_product(const Container &c)
Product of all elements.
bool uni_all(Pred &&pred, const Container &c)
Check if all elements satisfy predicate.
auto stl_tail(const Container &c)
Get all elements except the first (tail in Haskell).
auto stl_filteri(Pred &&pred, const Container &c)
Filter with index (filteri in ML).
auto stl_find(Pred &&pred, const Container &c)
Find first element satisfying predicate.
auto stl_split_at(size_t n, const Container &c)
Split at position n, returning (take n, drop n) in one pass.
auto stl_sort_by(Cmp &&cmp, const Container &c)
Return sorted copy using custom comparator.
auto stl_power_set(const Container &c)
Generate power set (all subsets) of a container.
auto uni_take(size_t n, const Container &c)
Take first n elements.
auto uni_sum(const Container &c)
Sum all elements.
auto stl_group(const Container &c)
Group consecutive equal 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.
Itor::difference_type count(const Itor &beg, const Itor &end, const T &value)
Count elements equal to a value.
Definition ahAlgo.H:127
auto stl_zip_to_pairs(const Container1 &c1, const Container2 &c2)
Zip two containers into pairs.
DynList< T > rep(size_t n, const T &item)
Create a sequence of repeated items.
T sum(const Container &container, const T &init=T{})
Compute sum of all elements.
auto stl_find_last(Pred &&pred, const Container &c)
Find last element satisfying predicate.
STL namespace.
Dynamic set implementations based on balanced binary search trees.