Aleph-w 3.0
A C++ Library for Data Structures and Algorithms
Loading...
Searching...
No Matches
functional_example.C
Go to the documentation of this file.
1
165#include <iostream>
166#include <iomanip>
167#include <string>
168#include <cmath>
169
170#include <tclap/CmdLine.h>
171
172#include <tpl_dynArray.H>
173#include <tpl_dynDlist.H>
174#include <htlist.H>
175#include <ahFunctional.H>
176#include <ahSort.H>
177
178using namespace std;
179using namespace Aleph;
180
181// =============================================================================
182// Helper functions for printing
183// =============================================================================
184
185template <typename Container>
186void print_container(const string& label, const Container& c)
187{
188 cout << label << ": [";
189 bool first = true;
190 c.for_each([&first](const auto& x) {
191 if (not first) cout << ", ";
192 cout << x;
193 first = false;
194 });
195 cout << "]" << endl;
196}
197
198template <typename T1, typename T2>
199void print_pairs(const string& label, const DynList<pair<T1, T2>>& c)
200{
201 cout << label << ": [";
202 bool first = true;
203 c.for_each([&first](const auto& p) {
204 if (not first) cout << ", ";
205 cout << "(" << p.first << ", " << p.second << ")";
206 first = false;
207 });
208 cout << "]" << endl;
209}
210
211void print_section(const string& title)
212{
213 cout << "\n" << string(60, '=') << "\n";
214 cout << " " << title << "\n";
215 cout << string(60, '=') << "\n\n";
216}
217
218void print_subsection(const string& title)
219{
220 cout << "\n--- " << title << " ---\n";
221}
222
223// =============================================================================
224// 1. Range Generation
225// =============================================================================
226
228{
229 print_section("RANGE GENERATION");
230
231 // Basic range: range(start, end, step)
232 print_subsection("range(start, end, step)");
233 auto r1 = range(1, 10); // 1 to 10, step 1
234 auto r2 = range(0, 20, 5); // 0 to 20, step 5
235 auto r3 = range(10, 1, -2); // 10 to 1, step -2 (empty, doesn't work backwards)
236
237 print_container("range(1, 10)", r1);
238 print_container("range(0, 20, 5)", r2);
239 print_container("range(10, 1, -2)", r3);
240 cout << " Note: range() only works with positive steps\n";
241
242 // Single argument range: range(n) = 0, 1, ..., n-1
243 print_subsection("range(n) - generates 0 to n-1");
244 auto r4 = range(5);
245 print_container("range(5)", r4);
246
247 // nrange: exactly n values evenly spaced
248 print_subsection("nrange(start, end, n) - n evenly spaced values");
249 auto nr1 = nrange(0.0, 1.0, 5); // 5 values from 0 to 1
250 auto nr2 = nrange(0.0, 10.0, 11); // 11 values from 0 to 10
251
252 cout << "nrange(0.0, 1.0, 5): [";
253 bool first = true;
254 nr1.for_each([&first](double x) {
255 if (not first) cout << ", ";
256 cout << fixed << setprecision(2) << x;
257 first = false;
258 });
259 cout << "]" << endl;
260
261 cout << "nrange(0.0, 10.0, 11): [";
262 first = true;
263 nr2.for_each([&first](double x) {
264 if (not first) cout << ", ";
265 cout << fixed << setprecision(1) << x;
266 first = false;
267 });
268 cout << "]" << endl;
269
270 // contiguous_range: n consecutive values
271 print_subsection("contiguous_range(start, n) - n consecutive values");
272 auto cr1 = contiguous_range(100, 5);
273 auto cr2 = contiguous_range(-3, 7);
274 print_container("contiguous_range(100, 5)", cr1);
275 print_container("contiguous_range(-3, 7)", cr2);
276
277 // rep: repeat a value
278 print_subsection("rep(n, value) - repeat value n times");
279 auto rep1 = rep(5, 42);
280 auto rep2 = rep<string>(3, "hello");
281 print_container("rep(5, 42)", rep1);
282 print_container("rep(3, \"hello\")", rep2);
283}
284
285// =============================================================================
286// 2. Iteration
287// =============================================================================
288
290{
291 print_section("ITERATION");
292
293 DynList<int> nums = {1, 2, 3, 4, 5};
294
295 // for_each: apply operation to each element
296 print_subsection("for_each(container, op)");
297 cout << "Elements: ";
298 nums.for_each([](int x) { cout << x << " "; });
299 cout << endl;
300
301 // Method chaining
302 cout << "Squared: ";
303 nums.for_each([](int x) { cout << (x * x) << " "; });
304 cout << endl;
305
306 // enum_for_each: with index
307 print_subsection("enum_for_each(container, op) - with index");
308 DynList<string> names = {"Alice", "Bob", "Carol", "Dave"};
309 cout << "Indexed list:\n";
310 enum_for_each(names, [](const string& name, size_t i) {
311 cout << " [" << i << "] " << name << endl;
312 });
313
314 // traverse: conditional traversal (stops on false)
315 print_subsection("traverse(container, op) - stops on false");
316 cout << "Print until finding 3: ";
317 nums.traverse([](int x) {
318 cout << x << " ";
319 return x != 3; // stop when x == 3
320 });
321 cout << "(stopped)" << endl;
322}
323
324// =============================================================================
325// 3. Predicates
326// =============================================================================
327
329{
330 print_section("PREDICATES");
331
332 DynList<int> nums = {2, 4, 6, 8, 10};
333 DynList<int> mixed = {1, 2, 3, 4, 5};
335
336 print_container("nums", nums);
337 print_container("mixed", mixed);
338
339 // all: check if all elements satisfy predicate
340 print_subsection("all(container, pred)");
341 auto is_even = [](int x) { return x % 2 == 0; };
342 auto is_positive = [](int x) { return x > 0; };
343 auto is_less_than_20 = [](int x) { return x < 20; };
344
345 cout << "All even in nums? " << (nums.all(is_even) ? "yes" : "no") << endl;
346 cout << "All even in mixed? " << (mixed.all(is_even) ? "yes" : "no") << endl;
347 cout << "All positive in nums? " << (nums.all(is_positive) ? "yes" : "no") << endl;
348 cout << "All < 20 in nums? " << (nums.all(is_less_than_20) ? "yes" : "no") << endl;
349 cout << "All in empty list? " << (empty_list.all(is_even) ? "yes (vacuous truth)" : "no") << endl;
350
351 // exists: check if at least one satisfies
352 print_subsection("exists(container, pred)");
353 auto is_five = [](int x) { return x == 5; };
354 auto is_greater_than_7 = [](int x) { return x > 7; };
355
356 cout << "Exists 5 in nums? " << (nums.exists(is_five) ? "yes" : "no") << endl;
357 cout << "Exists 5 in mixed? " << (mixed.exists(is_five) ? "yes" : "no") << endl;
358 cout << "Exists > 7 in nums? " << (nums.exists(is_greater_than_7) ? "yes" : "no") << endl;
359
360 // none: check if no element satisfies
361 print_subsection("none(container, pred)");
362 auto is_negative = [](int x) { return x < 0; };
363 auto is_odd = [](int x) { return x % 2 != 0; };
364
365 cout << "None negative in nums? " << (none(nums, is_negative) ? "yes" : "no") << endl;
366 cout << "None odd in nums? " << (none(nums, is_odd) ? "yes" : "no") << endl;
367 cout << "None odd in mixed? " << (none(mixed, is_odd) ? "yes" : "no") << endl;
368
369 // contains: check if value exists
370 print_subsection("contains(container, value)");
371 cout << "nums contains 6? " << (contains(nums, 6) ? "yes" : "no") << endl;
372 cout << "nums contains 7? " << (contains(nums, 7) ? "yes" : "no") << endl;
373}
374
375// =============================================================================
376// 4. Transformation (map, filter)
377// =============================================================================
378
380{
381 print_section("TRANSFORMATION");
382
383 DynList<int> nums = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
384 print_container("Original", nums);
385
386 // filter: keep elements satisfying predicate
387 print_subsection("filter(container, pred)");
388 auto evens = nums.filter([](int x) { return x % 2 == 0; });
389 auto greater_than_5 = nums.filter([](int x) { return x > 5; });
390 auto primes = nums.filter([](int x) {
391 if (x < 2) return false;
392 for (int i = 2; i * i <= x; ++i)
393 if (x % i == 0) return false;
394 return true;
395 });
396
397 print_container("Even numbers", evens);
398 print_container("Greater than 5", greater_than_5);
399 print_container("Primes", primes);
400
401 // maps: transform elements
402 print_subsection("maps<T>(container, op)");
403 auto squares = nums.template maps<int>([](int x) { return x * x; });
404 auto doubled = nums.template maps<int>([](int x) { return x * 2; });
405 auto as_strings = nums.template maps<string>([](int x) {
406 return "n" + to_string(x);
407 });
408
409 print_container("Squares", squares);
410 print_container("Doubled", doubled);
411 print_container("As strings", as_strings);
412
413 // Chaining filter and map
414 print_subsection("Chaining: filter then map");
415 auto even_squares = nums
416 .filter([](int x) { return x % 2 == 0; })
417 .template maps<int>([](int x) { return x * x; });
418 print_container("Even numbers squared", even_squares);
419
420 // reverse
421 print_subsection("reverse(container)");
422 auto reversed = reverse(nums);
423 print_container("Reversed", reversed);
424
425 // flat_map: map and flatten
426 print_subsection("flat_map(container, op) - map then flatten");
427 DynList<int> small = {1, 2, 3};
428 auto expanded = flat_map(small, [](int x) {
429 return DynList<int>({x, x * 10, x * 100});
430 });
431 print_container("flat_map({1,2,3}, x -> {x, x*10, x*100})", expanded);
432
433 // flatten: flatten nested containers
434 print_subsection("flatten(container) - flatten nested lists");
436 nested.append(DynList<int>({1, 2}));
437 nested.append(DynList<int>({3, 4, 5}));
439
440 cout << "Nested: [[1,2], [3,4,5], [6]]\n";
441 auto flattened = flatten(nested);
442 print_container("Flattened", flattened);
443}
444
445// =============================================================================
446// 5. Folding/Reduction
447// =============================================================================
448
450{
451 print_section("FOLDING / REDUCTION");
452
453 DynList<int> nums = {1, 2, 3, 4, 5};
454 print_container("nums", nums);
455
456 // foldl: left fold (reduce from left)
457 print_subsection("foldl(container, init, op) - left fold");
458
459 // Sum using foldl
460 int sum_result = nums.template foldl<int>(0, [](int acc, int x) {
461 return acc + x;
462 });
463 cout << "Sum (foldl): " << sum_result << endl;
464
465 // Product using foldl
466 int prod_result = nums.template foldl<int>(1, [](int acc, int x) {
467 return acc * x;
468 });
469 cout << "Product (foldl): " << prod_result << endl;
470
471 // Max using foldl
472 int max_result = nums.template foldl<int>(nums.get_first(), [](int acc, int x) {
473 return x > acc ? x : acc;
474 });
475 cout << "Max (foldl): " << max_result << endl;
476
477 // String concatenation
478 DynList<string> words = {"Hello", " ", "World", "!"};
479 string concat = words.template foldl<string>("", [](const string& acc, const string& s) {
480 return acc + s;
481 });
482 cout << "Concatenation: \"" << concat << "\"" << endl;
483
484 // Demonstrate fold order
485 print_subsection("Fold direction matters!");
486 DynList<int> seq = {1, 2, 3};
487
488 // foldl: ((init op 1) op 2) op 3
489 string left = seq.template foldl<string>("", [](const string& acc, int x) {
490 return "(" + acc + "+" + to_string(x) + ")";
491 });
492 cout << "foldl with +: " << left << endl;
493 cout << " Evaluation: ((\"\" + 1) + 2) + 3" << endl;
494
495 // For foldr, show the concept with a reversed list
496 auto rev_seq = reverse(seq);
497 string right = rev_seq.template foldl<string>("", [](const string& acc, int x) {
498 return "(" + to_string(x) + "+" + acc + ")";
499 });
500 cout << "Right-to-left fold: " << right << endl;
501 cout << " Evaluation: 1 + (2 + (3 + \"\"))" << endl;
502
503 // Convenience functions: sum and product
504 print_subsection("sum(container) and product(container)");
505 cout << "sum({1,2,3,4,5}) = " << sum(nums) << endl;
506 cout << "product({1,2,3,4,5}) = " << product(nums) << endl;
507
508 DynList<double> doubles = {1.5, 2.0, 3.5};
509 cout << "sum({1.5, 2.0, 3.5}) = " << sum(doubles) << endl;
510}
511
512// =============================================================================
513// 6. Zipping
514// =============================================================================
515
517{
518 print_section("ZIPPING");
519
520 DynList<int> nums = {1, 2, 3, 4};
521 DynList<string> letters = {"a", "b", "c", "d"};
522 DynList<double> values = {1.1, 2.2, 3.3};
523
524 print_container("nums", nums);
525 print_container("letters", letters);
526 print_container("values (shorter)", values);
527
528 // zip: combine two containers
529 print_subsection("zip(c1, c2) - stops at shorter");
530 auto zipped = zip(nums, letters);
531 print_pairs("zip(nums, letters)", zipped);
532
533 auto zipped_short = zip(nums, values);
534 cout << "zip(nums, values): [";
535 bool first = true;
536 zipped_short.for_each([&first](const auto& p) {
537 if (not first) cout << ", ";
538 cout << "(" << p.first << ", " << p.second << ")";
539 first = false;
540 });
541 cout << "] (stops at shorter)\n";
542
543 // Using ZipIterator for lazy evaluation
544 print_subsection("ZipIterator - lazy zipping");
545 cout << "Iterating with ZipIterator:\n";
546 for (ZipIterator it(nums, letters); it.has_curr(); it.next())
547 {
548 auto [n, l] = it.get_curr();
549 cout << " " << n << " -> " << l << endl;
550 }
551
552 // unzip: separate pairs
553 print_subsection("unzip(pairs) - separate into two lists");
555 pairs.append({1, "one"});
556 pairs.append({2, "two"});
557 pairs.append({3, "three"});
558
560 print_container("First elements", first_list);
561 print_container("Second elements", second_list);
562
563 // zip with operation
564 print_subsection("Combining zipped elements");
565 DynList<int> a = {1, 2, 3};
566 DynList<int> b = {10, 20, 30};
567
568 auto sums = zip(a, b).template maps<int>([](const auto& p) {
569 return p.first + p.second;
570 });
571 auto products = zip(a, b).template maps<int>([](const auto& p) {
572 return p.first * p.second;
573 });
574
575 print_container("Pairwise sums", sums);
576 print_container("Pairwise products", products);
577}
578
579// =============================================================================
580// 7. Grouping and Partitioning
581// =============================================================================
582
584{
585 print_section("GROUPING AND PARTITIONING");
586
587 DynList<int> nums = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
588 print_container("nums", nums);
589
590 // partition: split by predicate
591 print_subsection("partition(container, pred) - split by predicate");
592 auto [evens, odds] = partition(nums, [](int x) { return x % 2 == 0; });
593 print_container("Even (satisfies)", evens);
594 print_container("Odd (doesn't satisfy)", odds);
595
596 // take_while: take prefix while predicate holds
597 print_subsection("take_while(container, pred) - take prefix");
598 auto prefix = take_while(nums, [](int x) { return x < 5; });
599 print_container("take_while(< 5)", prefix);
600
601 // drop_while: drop prefix while predicate holds
602 print_subsection("drop_while(container, pred) - drop prefix");
603 auto suffix = drop_while(nums, [](int x) { return x < 5; });
604 print_container("drop_while(< 5)", suffix);
605
606 // group_by: group elements by key
607 print_subsection("group_by(container, key_func)");
608
609 // Group by remainder mod 3
610 auto by_mod3 = group_by(nums, [](int x) { return x % 3; });
611 cout << "Grouped by x % 3:\n";
612 by_mod3.for_each([](const auto& group) {
613 cout << " Key " << group.first << ": [";
614 bool first = true;
615 group.second.for_each([&first](int x) {
616 if (not first) cout << ", ";
617 cout << x;
618 first = false;
619 });
620 cout << "]\n";
621 });
622
623 // Group strings by length
624 DynList<string> words = {"hi", "hello", "bye", "ok", "world", "no", "yes"};
625 print_container("words", words);
626
627 auto by_length = group_by(words, [](const string& s) { return s.length(); });
628 cout << "Grouped by length:\n";
629 by_length.for_each([](const auto& group) {
630 cout << " Length " << group.first << ": [";
631 bool first = true;
632 group.second.for_each([&first](const string& s) {
633 if (not first) cout << ", ";
634 cout << "\"" << s << "\"";
635 first = false;
636 });
637 cout << "]\n";
638 });
639}
640
641// =============================================================================
642// 8. Practical Examples
643// =============================================================================
644
646{
647 print_section("PRACTICAL EXAMPLES");
648
649 // Example 1: Statistics
650 print_subsection("Example 1: Computing statistics");
651 DynList<double> data = {23.5, 45.2, 12.8, 67.3, 34.1, 89.0, 56.4};
652 print_container("Data", data);
653
654 double total = sum(data);
655 size_t count = data.size();
656 double mean = total / count;
657
658 // Variance using map and fold
659 double variance = data
660 .template maps<double>([mean](double x) { return (x - mean) * (x - mean); })
661 .template foldl<double>(0.0, [](double acc, double x) { return acc + x; }) / count;
662
663 double stddev = sqrt(variance);
664
665 cout << "Count: " << count << endl;
666 cout << "Sum: " << fixed << setprecision(2) << total << endl;
667 cout << "Mean: " << mean << endl;
668 cout << "Variance: " << variance << endl;
669 cout << "Std Dev: " << stddev << endl;
670
671 // Example 2: Word processing
672 print_subsection("Example 2: Word processing pipeline");
673 DynList<string> text = {"Hello", "WORLD", "this", "IS", "a", "TEST"};
674 print_container("Original text", text);
675
676 // Convert to lowercase and filter long words
677 auto processed = text
678 .template maps<string>([](const string& s) {
679 string lower;
680 for (char c : s) lower += tolower(c);
681 return lower;
682 })
683 .filter([](const string& s) { return s.length() > 2; });
684
685 print_container("Lowercase, length > 2", processed);
686
687 // Example 3: Matrix operations with nested lists
688 print_subsection("Example 3: Matrix transpose using zip");
690 matrix.append(DynList<int>({1, 2, 3}));
691 matrix.append(DynList<int>({4, 5, 6}));
692
693 cout << "Matrix:\n";
694 matrix.for_each([](const DynList<int>& row) {
695 cout << " ";
696 row.for_each([](int x) { cout << x << " "; });
697 cout << endl;
698 });
699
700 // Example 4: Fibonacci using unfold pattern
701 print_subsection("Example 4: Generate sequence with fold");
702 auto fibonacci = range(10).template foldl<DynList<int>>(
703 DynList<int>({0, 1}),
704 [](DynList<int> acc, int) {
705 size_t n = acc.size();
706 int next = 0;
707 size_t idx = 0;
708 acc.for_each([&](int x) {
709 if (idx == n - 2 or idx == n - 1)
710 next += x;
711 idx++;
712 });
713 acc.append(next);
714 return acc;
715 }
716 );
717 print_container("First 12 Fibonacci numbers", fibonacci);
718}
719
720// =============================================================================
721// 9. Comparison and Equality
722// =============================================================================
723
725{
726 print_section("COMPARISON AND EQUALITY");
727
728 DynList<int> a = {1, 2, 3, 4, 5};
729 DynList<int> b = {1, 2, 3, 4, 5};
730 DynList<int> c = {1, 2, 3};
731 DynList<int> d = {1, 2, 3, 4, 6};
732
733 print_container("a", a);
734 print_container("b", b);
735 print_container("c", c);
736 print_container("d", d);
737
738 // eq: check equality
739 print_subsection("eq(c1, c2) - element-wise equality");
740 cout << "eq(a, b)? " << (eq(a, b) ? "yes" : "no") << endl;
741 cout << "eq(a, c)? " << (eq(a, c) ? "yes" : "no") << " (different lengths)" << endl;
742 cout << "eq(a, d)? " << (eq(a, d) ? "yes" : "no") << " (different element)" << endl;
743
744 // diff: find first difference
745 print_subsection("diff(c1, c2) - check if different");
746 cout << "diff(a, b)? " << (diff(a, b) ? "yes" : "no") << endl;
747 cout << "diff(a, d)? " << (diff(a, d) ? "yes" : "no") << endl;
748
749 // lesser: lexicographic comparison
750 print_subsection("lesser(c1, c2) - lexicographic less-than");
751 DynList<int> x = {1, 2, 3};
752 DynList<int> y = {1, 2, 4};
753 DynList<int> z = {1, 2};
754
755 print_container("x", x);
756 print_container("y", y);
757 print_container("z", z);
758
759 cout << "lesser(x, y)? " << (lesser(x, y) ? "yes" : "no") << " (3 < 4)" << endl;
760 cout << "lesser(y, x)? " << (lesser(y, x) ? "yes" : "no") << endl;
761 cout << "lesser(z, x)? " << (lesser(z, x) ? "yes" : "no") << " (prefix)" << endl;
762}
763
764// =============================================================================
765// Main
766// =============================================================================
767
768int main(int argc, char* argv[])
769{
770 try
771 {
772 TCLAP::CmdLine cmd(
773 "Comprehensive functional programming example for Aleph-w.\n"
774 "Demonstrates range generation, iteration, predicates, transformation,\n"
775 "folding, zipping, grouping, and more.",
776 ' ', "1.0"
777 );
778
779 TCLAP::ValueArg<string> sectionArg(
780 "s", "section",
781 "Run only specific section: ranges, iteration, predicates, transform, "
782 "fold, zip, group, practical, compare, or 'all'",
783 false, "all", "section", cmd
784 );
785
786 cmd.parse(argc, argv);
787
788 string section = sectionArg.getValue();
789
790 cout << "\n";
791 cout << "============================================================\n";
792 cout << " ALEPH-W FUNCTIONAL PROGRAMMING EXAMPLE\n";
793 cout << "============================================================\n";
794
795 if (section == "all" or section == "ranges")
796 demo_ranges();
797
798 if (section == "all" or section == "iteration")
800
801 if (section == "all" or section == "predicates")
803
804 if (section == "all" or section == "transform")
806
807 if (section == "all" or section == "fold")
808 demo_folding();
809
810 if (section == "all" or section == "zip")
811 demo_zipping();
812
813 if (section == "all" or section == "group")
815
816 if (section == "all" or section == "practical")
818
819 if (section == "all" or section == "compare")
821
822 cout << "\n" << string(60, '=') << "\n";
823 cout << "Functional programming demo completed!\n";
824 cout << string(60, '=') << "\n\n";
825
826 return 0;
827 }
828 catch (TCLAP::ArgException& e)
829 {
830 cerr << "Error: " << e.error() << " for argument " << e.argId() << endl;
831 return 1;
832 }
833 catch (exception& e)
834 {
835 cerr << "Error: " << e.what() << endl;
836 return 1;
837 }
838}
839
Functional programming utilities for Aleph-w containers.
High-level sorting functions for Aleph containers.
int main()
static size_t primes[]
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
T & get_first() const
Return the first item of the list.
Definition htlist.H:1675
size_t size() const noexcept
Count the number of elements of the list.
Definition htlist.H:1319
Aleph::DynList< T > filter(Operation &operation) const
Filter the elements of a container according to a matching criteria.
Definition ah-dry.H:1135
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
size_t length() const noexcept
Count the number of elements of a container.
Definition ah-dry.H:1385
void for_each(Operation &operation)
Traverse all the container and performs an operation on each element.
Definition ah-dry.H:685
Iterator that traverses multiple Aleph containers in lockstep.
void demo_zipping()
void print_subsection(const string &title)
void demo_ranges()
void print_section(const string &title)
void print_pairs(const string &label, const DynList< pair< T1, T2 > > &c)
void demo_predicates()
void print_container(const string &label, const Container &c)
void demo_practical()
void demo_folding()
void demo_comparison()
void demo_iteration()
void demo_grouping()
void demo_transformation()
__gmp_expr< T, __gmp_unary_expr< __gmp_expr< T, U >, __gmp_sqrt_function > > sqrt(const __gmp_expr< T, U > &expr)
Definition gmpfrxx.h:4058
Singly linked list implementations with head-tail access.
static mpfr_t y
Definition mpfr_mul_d.c:3
Main namespace for Aleph-w library functions.
Definition ah-arena.H:89
std::string tolower(const char *str)
Convert a C std::string to lower-case.
DynList< T > flatten(const C2< C1< T > > &c)
Flatten a nested container of one level.
Container< T > nrange(const T start, const T end, const size_t n)
Generate exactly n values evenly spaced between [start, end].
auto unzip(const Container &l)
Separate a list of pairs into two lists.
void reverse(Itor beg, Itor end)
Reverse elements in a range.
Definition ahAlgo.H:1094
bool eq(const C1 &c1, const C2 &c2, Eq e=Eq())
Check equality of two containers using a predicate.
DynList< typename Container::Item_Type > drop_while(const Container &c, Pred pred)
Skip elements while predicate is true (drop_while).
auto variance(const Container &data, bool population=false) -> std::decay_t< decltype(*std::begin(data))>
Compute variance using Welford's numerically stable algorithm.
Definition stat_utils.H:215
std::pair< TgtContainer< typename SrcContainer::Item_Type >, TgtContainer< typename SrcContainer::Item_Type > > partition(const SrcContainer &c, std::function< bool(const typename SrcContainer::Item_Type &)> operation)
Partition a container into two based on a predicate.
Container2< typename Container1::Item_Type > filter(Container1 &container, Operation &operation)
Filter elements that satisfy operation.
static void suffix(Node *root, DynList< Node * > &acc)
DynList< typename Container::Item_Type > take_while(const Container &c, Pred pred)
Return elements while predicate is true (take_while).
DynList< std::pair< typename Container1::Item_Type, typename Container2::Item_Type > > zip(const Container1 &a, const Container2 &b)
Zip two containers into a list of pairs.
bool contains(const std::string_view &str, const std::string_view &substr)
Check if substr appears inside str.
auto flat_map(const Container &container, Op op) -> DynList< typename std::decay_t< decltype(op(std::declval< typename Container::Item_Type >()))>::Item_Type >
Apply operation and flatten results (flatMap/concatMap).
static void prefix(Node *root, DynList< Node * > &acc)
auto stddev(const Container &data, bool population=false) -> std::decay_t< decltype(*std::begin(data))>
Compute standard deviation.
Definition stat_utils.H:257
auto mean(const Container &data) -> std::decay_t< decltype(*std::begin(data))>
Compute the arithmetic mean.
Definition stat_utils.H:183
T product(const Container &container, const T &init=T{1})
Compute product of all elements.
bool diff(const C1 &c1, const C2 &c2, Eq e=Eq())
Check if two containers differ.
std::pair< First, Second > pair
Alias to std::pair kept for backwards compatibility.
Definition ahPair.H:89
bool is_even(const long n)
Return true if n is even.
Definition ahUtils.H:102
bool lesser(const C1 &c1, const C2 &c2, Cmp cmp=Cmp())
Lexicographical comparison between two containers.
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
std::string concat(const Args &... args)
Concatenate multiple streamable arguments into a single std::string.
void next()
Advance all underlying iterators (bounds-checked).
Definition ah-zip.H:175
Container< T > range(const T start, const T end, const T step=1)
Generate a range of values [start, end] with a given step.
void enum_for_each(const Container &container, Operation &operation)
Apply an operation to each element and its index.
DynList< std::pair< std::invoke_result_t< KeyFunc, const T & >, DynList< T > > > group_by(const Container< T > &c, KeyFunc key_func)
Group consecutive elements by a key function.
Container< T > contiguous_range(T start, const size_t n)
Generate n contiguous values starting from start.
bool none(const Container &container, Operation &operation)
Return true if no element satisfies operation.
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
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.
STL namespace.
#define is_odd(x)
Definition ran_array.c:30
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
Lazy and scalable dynamic array implementation.
Dynamic doubly linked list implementation.
DynList< int > l