Aleph-w 3.0
A C++ Library for Data Structures and Algorithms
Loading...
Searching...
No Matches
ah-dry-mixin.H
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
69#ifndef AH_DRY_MIXIN_H
70#define AH_DRY_MIXIN_H
71
72#include <cstddef>
73#include <tuple>
74#include <functional>
75#include <utility>
76#include <type_traits>
77#include <vector>
78#include <string>
79
80#include <ah-concepts.H>
81#include <ah-errors.H>
82
83namespace Aleph
84{
85
86// Forward declarations
87template<typename T> class DynList;
88
89// Dft_Map_Op is defined in ahFunctional.H, we just forward declare here
90// to avoid circular dependency. When ahFunctional.H is included, it provides
91// the actual definition.
92template <typename T, typename R> struct Dft_Map_Op;
93
94
95// =============================================================================
96// TraverseMixin - Basic traversal operations
97// =============================================================================
98
115template <typename Derived, typename Type>
117{
118protected:
121 {
122 return static_cast<const Derived&>(*this);
123 }
124
127 {
128 return static_cast<Derived&>(*this);
129 }
130
131public:
166 template <class Operation>
169 {
170 for (typename Derived::Iterator it(self()); it.has_curr(); it.next_ne())
171 if (not operation(it.get_curr()))
172 return false;
173 return true;
174 }
175
177 template <class Operation>
180 {
181 for (typename Derived::Iterator it(self()); it.has_curr(); it.next_ne())
182 if (not operation(it.get_curr()))
183 return false;
184 return true;
185 }
186
189 template <class Operation>
192 {
194 }
195
197 template <class Operation>
203};
204
205
206// =============================================================================
207// LocateMixin - Element location operations
208// =============================================================================
209
226template <typename Derived, typename Type>
228{
229protected:
231 {
232 return static_cast<const Derived&>(*this);
233 }
234
236 {
237 return static_cast<Derived&>(*this);
238 }
239
240public:
261 Type & nth(const size_t n) const
262 {
263 Type * ptr = nullptr;
264 size_t i = 0;
265 self().traverse([&ptr, &i, &n] (Type & item)
266 {
267 if (i++ < n)
268 return true;
269 ptr = &item;
270 return false;
271 });
272
273 ah_out_of_range_error_if(i != n + 1) << "index " << n << " out of range";
274
275 return *ptr;
276 }
277
292 Type & nth_ne(const size_t n) const noexcept
293 {
294 Type * ptr = nullptr;
295 size_t i = 0;
296 self().traverse([&ptr, &i, &n] (Type & item)
297 {
298 if (i++ < n)
299 return true;
300 ptr = &item;
301 return false;
302 });
303 return *ptr;
304 }
305
331 template <class Operation>
334 {
335 Type * ptr = nullptr;
336 self().traverse([&ptr, &operation] (Type & item)
337 {
338 if (operation(item))
339 {
340 ptr = &item;
341 return false;
342 }
343 return true;
344 });
345 return ptr;
346 }
347
350 template <class Operation>
353 {
354 Type * ptr = nullptr;
355 self().traverse([&ptr, &operation] (Type & item)
356 {
357 if (operation(item))
358 {
359 ptr = &item;
360 return false;
361 }
362 return true;
363 });
364 return ptr;
365 }
366
369 template <class Operation>
375
377 template <class Operation>
383
408 template <class Operation>
410 std::tuple<bool, Type> find_item(Operation & operation)
411 {
412 auto ptr = find_ptr(operation);
413 return ptr ? std::make_tuple(true, *ptr) : std::make_tuple(false, Type());
414 }
415
417 template <class Operation>
419 std::tuple<bool, Type> find_item(Operation & operation) const
420 {
421 auto ptr = find_ptr(operation);
422 return ptr ? std::make_tuple(true, *ptr) : std::make_tuple(false, Type());
423 }
424
426 template <class Operation>
428 std::tuple<bool, Type> find_item(Operation && operation = Operation())
429 {
430 return find_item(operation);
431 }
432
434 template <class Operation>
436 std::tuple<bool, Type> find_item(Operation && operation = Operation()) const
437 {
438 return find_item(operation);
439 }
440};
441
442
443// =============================================================================
444// FunctionalMixin - Functional programming operations
445// =============================================================================
446
469template <typename Derived, typename Type>
471{
472protected:
474 {
475 return static_cast<const Derived&>(*this);
476 }
477
479 {
480 return static_cast<Derived&>(*this);
481 }
482
483public:
484
485 // ---------------------------------------------------------------------------
486 // Iteration
487 // ---------------------------------------------------------------------------
488
505 template <class Operation>
507 auto for_each(Operation & operation) const -> decltype(self())
508 {
509 self().traverse([&operation] (const Type & item)
510 {
511 operation(item);
512 return true;
513 });
514 return self();
515 }
516
518 template <class Operation>
520 auto for_each(Operation & operation) -> decltype(self())
521 {
522 self().traverse([&operation] (const Type & item)
523 {
524 operation(item);
525 return true;
526 });
527 return self();
528 }
529
531 template <class Operation>
537
539 template <class Operation>
541 auto for_each(Operation && operation = Operation()) -> decltype(self())
542 {
544 }
545
561 template <class Operation>
564 {
565 self().traverse([&operation] (Type & item)
566 {
567 operation(item);
568 return true;
569 });
570 return self();
571 }
572
574 template <class Operation>
577 {
579 }
580
581 // ---------------------------------------------------------------------------
582 // Predicates
583 // ---------------------------------------------------------------------------
584
603 template <class Operation>
604 requires requires(const typename concepts_detail::defer<Derived, Operation>::type &c, Operation &op) { { c.template traverse<Operation>(op) } -> std::convertible_to<bool>; }
606 {
607 return self().template traverse<Operation>(operation);
608 }
609
611 template <class Operation>
612 requires requires(const typename concepts_detail::defer<Derived, Operation>::type &c, Operation &op) { { c.template traverse<Operation>(op) } -> std::convertible_to<bool>; }
614 {
616 }
617
621 template <class Operation>
622 requires requires(const typename concepts_detail::defer<Derived, Operation>::type &c, Operation &op) { { c.template traverse<Operation>(op) } -> std::convertible_to<bool>; }
624 {
626 }
627
629 template <class Operation>
630 requires requires(const typename concepts_detail::defer<Derived, Operation>::type &c, Operation &op) { { c.template traverse<Operation>(op) } -> std::convertible_to<bool>; }
632 {
634 }
635
654 template <class Operation>
657 {
658 return not self().traverse([&operation] (const Type & item)
659 {
660 return not operation(item);
661 });
662 }
663
665 template <class Operation>
668 {
670 }
671
672 // ---------------------------------------------------------------------------
673 // Transformation
674 // ---------------------------------------------------------------------------
675
703 template <typename __Type = Type,
704 template <typename> class Container = Aleph::DynList,
706 requires requires(Container<__Type> &l, Operation &op, const Type &item) { l.append(op(item)); }
708 {
710 for_each([&ret_val, &operation] (const Type & item)
711 {
712 ret_val.append(operation(item));
713 });
714 return ret_val;
715 }
716
718 template <typename __Type = Type,
719 template <typename> class Container = Aleph::DynList,
721 requires requires(Container<__Type> &l, Operation &op, const Type &item) { l.append(op(item)); }
726
756 template <typename __Type = Type>
758 std::function<__Type(const __Type&, const Type&)> operation) const
759 {
760 auto ret_val = init;
761 for_each([&ret_val, &operation] (const Type & item)
762 {
763 ret_val = operation(ret_val, item);
764 });
765 return ret_val;
766 }
767
771 template <typename __Type = Type>
772 [[nodiscard]] __Type fold_left(std::function<__Type(const __Type&, const Type&)> operation,
773 const __Type & init) const
774 {
776 }
777
787 template <class Operation>
788 requires requires(Type &acc, Operation &op, const Type &item) { acc = op(acc, item); }
790 {
791 auto ret_val = init;
792 for_each([&ret_val, &operation] (const Type & item)
793 {
794 ret_val = operation(ret_val, item);
795 });
796 return ret_val;
797 }
798
800 template <class Operation>
801 requires requires(Type &acc, Operation &op, const Type &item) { acc = op(acc, item); }
803 {
805 }
806
826 template <class Operation>
829 {
831 for_each([&ret_val, &operation] (const Type & item)
832 {
833 if (operation(item))
834 ret_val.append(item);
835 });
836 return ret_val;
837 }
838
840 template <class Operation>
846
862 template <class Operation>
865 {
867 size_t i = 0;
868 for_each([&ret_val, &operation, &i] (const Type & item)
869 {
870 if (operation(item))
871 ret_val.append(std::make_tuple(item, i));
872 ++i;
873 });
874 return ret_val;
875 }
876
878 template <class Operation>
884
901 template <class Operation>
903 [[nodiscard]] std::pair<DynList<Type>, DynList<Type>> partition(Operation & op) const
904 {
905 std::pair<DynList<Type>, DynList<Type>> ret_val;
906 for_each([&ret_val, &op] (const Type & item)
907 {
908 if (op(item))
909 ret_val.first.append(item);
910 else
911 ret_val.second.append(item);
912 });
913 return ret_val;
914 }
915
917 template <class Operation>
919 [[nodiscard]] std::pair<DynList<Type>, DynList<Type>> partition(Operation && op = Operation()) const
920 {
921 return partition<Operation>(op);
922 }
923
927 template <class Operation>
929 [[nodiscard]] std::tuple<DynList<Type>, DynList<Type>> tpartition(Operation & op) const
930 {
931 DynList<Type> r1, r2;
932 for_each([&r1, &r2, &op] (const Type & item)
933 {
934 if (op(item))
935 r1.append(item);
936 else
937 r2.append(item);
938 });
939 return std::make_tuple(r1, r2);
940 }
941
943 template <class Operation>
945 [[nodiscard]] std::tuple<DynList<Type>, DynList<Type>> tpartition(Operation && op = Operation()) const
946 {
947 return tpartition<Operation>(op);
948 }
949
950 // ---------------------------------------------------------------------------
951 // Utility
952 // ---------------------------------------------------------------------------
953
964 {
965 size_t count = 0;
966 for_each([&count] (const Type &) { ++count; });
967 return count;
968 }
969
985 template <template <typename> class Container = Aleph::DynList>
987 {
989 for_each([&ret_val] (const Type & item)
990 {
991 ret_val.insert(item);
992 });
993 return ret_val;
994 }
995
996 // ---------------------------------------------------------------------------
997 // Slicing
998 // ---------------------------------------------------------------------------
999
1016 template <template <typename> class Container = Aleph::DynList>
1017 [[nodiscard]] Container<Type> take(const size_t n) const
1018 {
1019 size_t i = 0;
1021 self().traverse([&i, &ret, n] (const Type & item)
1022 {
1023 if (i++ >= n)
1024 return false;
1025 ret.append(item);
1026 return true;
1027 });
1028 return ret;
1029 }
1030
1047 template <template <typename> class Container = Aleph::DynList>
1048 [[nodiscard]] Container<Type> drop(const size_t n) const
1049 {
1050 size_t i = 0;
1052 self().traverse([&i, &ret, n] (const Type & item)
1053 {
1054 if (i++ >= n)
1055 ret.append(item);
1056 return true;
1057 });
1058 return ret;
1059 }
1060
1061 // ---------------------------------------------------------------------------
1062 // Aggregation (Numeric)
1063 // ---------------------------------------------------------------------------
1064
1083 [[nodiscard]] Type sum(const Type & init = Type{}) const
1084 requires requires(Type a, Type b) { { a + b } -> std::convertible_to<Type>; }
1085 {
1086 Type result = init;
1087 for_each([&result] (const Type & item)
1088 {
1089 result = result + item;
1090 });
1091 return result;
1092 }
1093
1111 [[nodiscard]] Type product(const Type & init) const
1112 requires requires(Type a, Type b) { { a * b } -> std::convertible_to<Type>; }
1113 {
1114 Type result = init;
1115 for_each([&result] (const Type & item)
1116 {
1117 result = result * item;
1118 });
1119 return result;
1120 }
1121
1138 [[nodiscard]] const Type * min() const
1139 requires requires(Type a, Type b) { { a < b } -> std::convertible_to<bool>; }
1140 {
1141 const Type * result = nullptr;
1142 for_each([&result] (const Type & item)
1143 {
1144 if (result == nullptr or item < *result)
1145 result = &item;
1146 });
1147 return result;
1148 }
1149
1166 [[nodiscard]] const Type * max() const
1167 requires requires(Type a, Type b) { { a < b } -> std::convertible_to<bool>; }
1168 {
1169 const Type * result = nullptr;
1170 for_each([&result] (const Type & item)
1171 {
1172 if (result == nullptr or *result < item)
1173 result = &item;
1174 });
1175 return result;
1176 }
1177
1195 template <class Compare>
1197 [[nodiscard]] const Type * min_by(Compare cmp) const
1198 {
1199 const Type * result = nullptr;
1200 for_each([&result, &cmp] (const Type & item)
1201 {
1202 if (result == nullptr or cmp(item, *result))
1203 result = &item;
1204 });
1205 return result;
1206 }
1207
1225 template <class Compare>
1227 [[nodiscard]] const Type * max_by(Compare cmp) const
1228 {
1229 const Type * result = nullptr;
1230 for_each([&result, &cmp] (const Type & item)
1231 {
1232 if (result == nullptr or cmp(*result, item))
1233 result = &item;
1234 });
1235 return result;
1236 }
1237
1238 // ---------------------------------------------------------------------------
1239 // Search and Counting
1240 // ---------------------------------------------------------------------------
1241
1263 [[nodiscard]] bool has_value(const Type & val) const
1264 requires requires(Type a, Type b) { { a == b } -> std::convertible_to<bool>; }
1265 {
1266 return exists([&val] (const Type & item) { return item == val; });
1267 }
1268
1286 template <class Predicate>
1288 [[nodiscard]] bool none(Predicate & pred) const
1289 {
1290 return not exists(pred);
1291 }
1292
1294 template <class Predicate>
1296 [[nodiscard]] bool none(Predicate && pred) const
1297 {
1298 return not exists(std::forward<Predicate>(pred));
1299 }
1300
1316 template <class Predicate>
1319 {
1320 size_t count = 0;
1321 for_each([&count, &pred] (const Type & item)
1322 {
1323 if (pred(item))
1324 ++count;
1325 });
1326 return count;
1327 }
1328
1329 // ---------------------------------------------------------------------------
1330 // First/Last Element Access
1331 // ---------------------------------------------------------------------------
1332
1346 [[nodiscard]] const Type * first() const
1347 {
1348 const Type * result = nullptr;
1349 self().traverse([&result] (const Type & item)
1350 {
1351 result = &item;
1352 return false; // stop after first
1353 });
1354 return result;
1355 }
1356
1372 {
1373 auto ptr = first();
1374 return ptr ? *ptr : default_val;
1375 }
1376
1390 [[nodiscard]] const Type * last() const
1391 {
1392 const Type * result = nullptr;
1393 for_each([&result] (const Type & item)
1394 {
1395 result = &item;
1396 });
1397 return result;
1398 }
1399
1415 {
1416 auto ptr = last();
1417 return ptr ? *ptr : default_val;
1418 }
1419
1420 // ---------------------------------------------------------------------------
1421 // Enumeration and Indexing
1422 // ---------------------------------------------------------------------------
1423
1440 template <template <typename> class Container = Aleph::DynList>
1442 {
1444 size_t idx = 0;
1445 for_each([&ret, &idx] (const Type & item)
1446 {
1447 ret.append(std::make_pair(idx++, item));
1448 });
1449 return ret;
1450 }
1451
1467 template <class Predicate>
1470 {
1471 size_t idx = 0;
1472 size_t result = static_cast<size_t>(-1);
1473 self().traverse([&idx, &result, &pred] (const Type & item)
1474 {
1475 if (pred(item))
1476 {
1477 result = idx;
1478 return false;
1479 }
1480 ++idx;
1481 return true;
1482 });
1483 return result;
1484 }
1485
1504 [[nodiscard]] size_t index_of(const Type & val) const
1505 requires requires(Type a, Type b) { { a == b } -> std::convertible_to<bool>; }
1506 {
1507 return find_index([&val] (const Type & item) { return item == val; });
1508 }
1509
1510 // ---------------------------------------------------------------------------
1511 // Transformation (Advanced)
1512 // ---------------------------------------------------------------------------
1513
1531 template <template <typename> class Container = Aleph::DynList>
1533 requires requires(Type a, Type b) { { a == b } -> std::convertible_to<bool>; }
1534 {
1536 const Type * prev = nullptr;
1537 for_each([&ret, &prev] (const Type & item)
1538 {
1539 if (prev == nullptr or not (*prev == item))
1540 {
1541 ret.append(item);
1542 prev = &item;
1543 }
1544 });
1545 return ret;
1546 }
1547
1566 template <template <typename> class Container = Aleph::DynList, class EqPred>
1569 {
1571 const Type * prev = nullptr;
1572 for_each([&ret, &prev, &eq] (const Type & item)
1573 {
1574 if (prev == nullptr or not eq(*prev, item))
1575 {
1576 ret.append(item);
1577 prev = &item;
1578 }
1579 });
1580 return ret;
1581 }
1582
1598 template <template <typename> class Container = Aleph::DynList>
1600 {
1602 bool first = true;
1603 for_each([&ret, &sep, &first] (const Type & item)
1604 {
1605 if (not first)
1606 ret.append(sep);
1607 ret.append(item);
1608 first = false;
1609 });
1610 return ret;
1611 }
1612
1613 // ---------------------------------------------------------------------------
1614 // Chunking and Windowing
1615 // ---------------------------------------------------------------------------
1616
1632 template <template <typename> class Container = Aleph::DynList>
1634 {
1636 if (n == 0) return ret;
1637
1638 Container<Type> current;
1639 size_t count = 0;
1640
1641 for_each([&ret, &current, &count, n] (const Type & item)
1642 {
1643 current.append(item);
1644 if (++count >= n)
1645 {
1646 ret.append(std::move(current));
1647 current = Container<Type>{};
1648 count = 0;
1649 }
1650 });
1651
1652 if (count > 0)
1653 ret.append(std::move(current));
1654
1655 return ret;
1656 }
1657
1675 template <template <typename> class Container = Aleph::DynList>
1676 [[nodiscard]] Container<Container<Type>> sliding(size_t size, size_t step = 1) const
1677 {
1679 if (size == 0 or step == 0) return ret;
1680
1681 // Collect all elements first
1683 for_each([&all] (const Type & item) { all.append(item); });
1684
1685 size_t total = all.size();
1686 if (total < size) return ret;
1687
1688 for (size_t start = 0; start + size <= total; start += step)
1689 {
1690 Container<Type> window;
1691 size_t idx = 0;
1692 all.traverse([&window, &idx, start, size] (const Type & item)
1693 {
1694 if (idx >= start and idx < start + size)
1695 window.append(item);
1696 ++idx;
1697 return idx < start + size;
1698 });
1699 ret.append(std::move(window));
1700 }
1701
1702 return ret;
1703 }
1704
1705 // ---------------------------------------------------------------------------
1706 // Conversion
1707 // ---------------------------------------------------------------------------
1708
1722 [[nodiscard]] std::vector<Type> to_vector() const
1723 {
1724 std::vector<Type> ret;
1725 if constexpr (requires { self().size(); })
1726 ret.reserve(self().size());
1727 for_each([&ret] (const Type & item) { ret.push_back(item); });
1728 return ret;
1729 }
1730
1749 template <typename DynListType = DynList<Type>>
1751 {
1753 for_each([&ret] (const Type & item) { ret.append(item); });
1754 return ret;
1755 }
1756
1774 template <typename StringType = std::string>
1776 requires requires(Type a) { std::to_string(a); }
1777 {
1779 bool first = true;
1780 for_each([&ret, &sep, &first] (const Type & item)
1781 {
1782 if (not first)
1783 ret += sep;
1784 ret += std::to_string(item);
1785 first = false;
1786 });
1787 return ret;
1788 }
1789
1804 [[nodiscard]] std::string join_str(const std::string & sep = ", ") const
1806 {
1807 std::string ret;
1808 bool first = true;
1809 for_each([&ret, &sep, &first] (const Type & item)
1810 {
1811 if (not first)
1812 ret += sep;
1813 ret += static_cast<std::string>(item);
1814 first = false;
1815 });
1816 return ret;
1817 }
1818
1819 // ---------------------------------------------------------------------------
1820 // Zip Operations
1821 // ---------------------------------------------------------------------------
1822
1842 template <class Other, template <typename> class Container = Aleph::DynList>
1844 zip_with(const Other & other) const
1845 {
1846 using OtherType = typename Other::Item_Type;
1848
1849 auto it1 = self().get_it();
1850 auto it2 = other.get_it();
1851
1852 while (it1.has_curr() and it2.has_curr())
1853 {
1854 ret.append(std::make_pair(it1.get_curr(), it2.get_curr()));
1855 it1.next();
1856 it2.next();
1857 }
1858
1859 return ret;
1860 }
1861};
1862
1863
1864// =============================================================================
1865// KeysMixin - Keys/Items extraction
1866// =============================================================================
1867
1873template <typename Derived, typename Type>
1875{
1876protected:
1878 {
1879 return static_cast<const Derived&>(*this);
1880 }
1881
1882public:
1888 template <template <typename> class Container = DynList>
1890 {
1891 return self().template maps<Type, Container>([] (const Type & key)
1892 {
1893 return key;
1894 });
1895 }
1896
1900 template <template <typename> class Container = DynList>
1902 {
1903 return keys<Container>();
1904 }
1905};
1906
1907
1908} // end namespace Aleph
1909
1910#endif // AH_DRY_MIXIN_H
1911
C++20 concepts hub: comparison, BST policy, and Aleph container concepts.
Exception handling system with formatted messages for Aleph-w.
#define ah_out_of_range_error_if(C)
Throws std::out_of_range if condition holds.
Definition ah-errors.H:584
Doubly-linked list (defined in tpl_dynList.H).
Definition htlist.H:1155
T & append(const T &item)
Definition htlist.H:1271
CRTP Mixin providing functional programming operations.
Container< __Type > maps(Operation &&operation=Operation()) const
This is an overloaded member function, provided for convenience. It differs from the above function o...
Derived & self() noexcept
bool all(Operation &&operation=Operation()) const
This is an overloaded member function, provided for convenience. It differs from the above function o...
size_t count_if(Predicate pred) const
Count elements satisfying a predicate.
__Type fold_left(std::function< __Type(const __Type &, const Type &)> operation, const __Type &init) const
Left fold with operation first (alternative signature).
Container< Type > drop(const size_t n) const
Skip the first n elements.
Container< std::pair< size_t, Type > > enumerate() const
Enumerate elements with their indices.
bool forall(Operation &&operation=Operation()) const
This is an overloaded member function, provided for convenience. It differs from the above function o...
Container< Container< Type > > chunk(size_t n) const
Split into chunks of fixed size.
DynListType to_dynlist() const
Convert container to DynList.
std::pair< DynList< Type >, DynList< Type > > partition(Operation &op) const
Partition elements by a predicate.
std::tuple< DynList< Type >, DynList< Type > > tpartition(Operation &op) const
Partition returning tuple instead of pair.
DynList< std::tuple< Type, size_t > > pfilter(Operation &&operation=Operation()) const
This is an overloaded member function, provided for convenience. It differs from the above function o...
auto mutable_for_each(Operation &operation) -> decltype(self())
Apply an operation to each element (mutable).
bool none(Predicate &&pred) const
This is an overloaded member function, provided for convenience. It differs from the above function o...
const Type * min_by(Compare cmp) const
Find the minimum element using a custom comparator.
auto for_each(Operation &&operation=Operation()) -> decltype(self())
This is an overloaded member function, provided for convenience. It differs from the above function o...
const Type * max() const
Find the maximum element.
Container< Type > unique_by(EqPred eq) const
Remove consecutive duplicates using a custom equality predicate.
Type fold(const Type &init, Operation &operation) const
Simple fold with same type for accumulator and elements.
bool none(Predicate &pred) const
Check if no element satisfies a predicate.
Container< Type > rev() const
Create a reversed copy.
bool exists(Operation &operation) const
Test if any element satisfies a predicate.
Container< Container< Type > > sliding(size_t size, size_t step=1) const
Create sliding windows of fixed size.
Container< Type > take(const size_t n) const
Take the first n elements.
std::string join_str(const std::string &sep=", ") const
Join string elements with separator.
Container< Type > unique() const
Remove consecutive duplicate elements.
std::pair< DynList< Type >, DynList< Type > > partition(Operation &&op=Operation()) const
This is an overloaded member function, provided for convenience. It differs from the above function o...
Type fold(const Type &init, Operation &&operation=Operation()) const
This is an overloaded member function, provided for convenience. It differs from the above function o...
const Type * first() const
Get the first element.
Container< std::pair< Type, typename Other::Item_Type > > zip_with(const Other &other) const
Zip with another container.
Type last_or(const Type &default_val) const
Get the last element or a default value.
auto for_each(Operation &operation) const -> decltype(self())
Apply an operation to each element (read-only).
bool has_value(const Type &val) const
Check if container has a value.
StringType join(const StringType &sep=StringType{", "}) const
Join elements into a string with separator.
size_t index_of(const Type &val) const
Find the index of a specific value.
DynList< std::tuple< Type, size_t > > pfilter(Operation &operation) const
Filter with position information.
__Type foldl(const __Type &init, std::function< __Type(const __Type &, const Type &)> operation) const
Left fold (reduce) with initial value.
bool exists(Operation &&operation=Operation()) const
This is an overloaded member function, provided for convenience. It differs from the above function o...
Container< __Type > maps(Operation &operation) const
Transform elements using a mapping function.
Type product(const Type &init) const
Compute the product of all elements.
bool all(Operation &operation) const
Test if all elements satisfy a predicate.
auto for_each(Operation &&operation=Operation()) const -> decltype(self())
This is an overloaded member function, provided for convenience. It differs from the above function o...
size_t length() const noexcept
Count the number of elements.
DynList< Type > filter(Operation &&operation=Operation()) const
This is an overloaded member function, provided for convenience. It differs from the above function o...
Type sum(const Type &init=Type{}) const
Compute the sum of all elements.
size_t find_index(Predicate pred) const
Find the index of the first element satisfying a predicate.
std::vector< Type > to_vector() const
Convert to std::vector.
std::tuple< DynList< Type >, DynList< Type > > tpartition(Operation &&op=Operation()) const
This is an overloaded member function, provided for convenience. It differs from the above function o...
const Type * max_by(Compare cmp) const
Find the maximum element using a custom comparator.
const Derived & self() const noexcept
Container< Type > intersperse(const Type &sep) const
Intersperse a separator between elements.
bool forall(Operation &operation) const
Alias for all().
Type first_or(const Type &default_val) const
Get the first element or a default value.
auto mutable_for_each(Operation &&operation=Operation()) -> decltype(self())
This is an overloaded member function, provided for convenience. It differs from the above function o...
auto for_each(Operation &operation) -> decltype(self())
This is an overloaded member function, provided for convenience. It differs from the above function o...
DynList< Type > filter(Operation &operation) const
Filter elements by a predicate.
const Type * last() const
Get the last element.
const Type * min() const
Find the minimum element.
CRTP Mixin for extracting keys from set-like containers.
Container< Type > items() const
Alias for keys().
const Derived & self() const noexcept
Container< Type > keys() const
Extract all keys as a list.
CRTP Mixin providing element location operations.
std::tuple< bool, Type > find_item(Operation &operation) const
This is an overloaded member function, provided for convenience. It differs from the above function o...
std::tuple< bool, Type > find_item(Operation &operation)
Find element with success flag.
std::tuple< bool, Type > find_item(Operation &&operation=Operation())
This is an overloaded member function, provided for convenience. It differs from the above function o...
Type * find_ptr(Operation and operation=Operation())
This is an overloaded member function, provided for convenience. It differs from the above function o...
std::tuple< bool, Type > find_item(Operation &&operation=Operation()) const
This is an overloaded member function, provided for convenience. It differs from the above function o...
Type * find_ptr(Operation &operation) const
This is an overloaded member function, provided for convenience. It differs from the above function o...
Type * find_ptr(Operation and operation=Operation()) const
This is an overloaded member function, provided for convenience. It differs from the above function o...
Type & nth_ne(const size_t n) const noexcept
Access the n-th element (unchecked).
const Derived & self() const noexcept
Type * find_ptr(Operation &operation)
Find the first element satisfying a predicate.
Type & nth(const size_t n) const
Access the n-th element (bounds-checked).
Derived & self() noexcept
CRTP Mixin providing traversal operations.
bool traverse(Operation &operation) const
Traverse all elements, applying an operation to each.
const Derived & self() const noexcept
Access the derived class (const version).
bool traverse(Operation and operation=Operation()) const
This is an overloaded member function, provided for convenience. It differs from the above function o...
bool traverse(Operation and operation=Operation())
This is an overloaded member function, provided for convenience. It differs from the above function o...
bool traverse(Operation &operation)
This is an overloaded member function, provided for convenience. It differs from the above function o...
Derived & self() noexcept
Access the derived class (mutable version).
f(args...) is a valid call expression, exactly as written.
f(args...) is a valid call whose result is usable as a condition.
int cmp(const __gmp_expr< T, U > &expr1, const __gmp_expr< V, W > &expr2)
Definition gmpfrxx.h:4129
size_t blossom_maximum_cardinality_matching(const GT &g, DynDlist< typename GT::Arc * > &matching, SA sa=SA())
Alias of compute_maximum_cardinality_general_matching().
Definition Blossom.H:466
Freq_Node * pred
Predecessor node in level-order traversal.
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.
size_t size(Node *root) noexcept
and
Check uniqueness with explicit hash + equality functors.
static std::atomic< bool > init
Definition hash-fct.C:54
Itor::difference_type count(const Itor &beg, const Itor &end, const T &value)
Count elements equal to a value.
Definition ahAlgo.H:127
STL namespace.
Default mapping operation (identity).
DynList< int > l