Aleph-w 3.0
A C++ Library for Data Structures and Algorithms
Loading...
Searching...
No Matches
ah-dry.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
43#ifndef AH_DRY_H
44#define AH_DRY_H
45
46#include "ahFunctional.H"
47#include <ah-concepts.H>
48#include <type_traits>
49#include <utility>
50#include <vector>
51#include <ah-errors.H>
52
53namespace Aleph {
54template <class>
55class Array;
56}
57
69template <class Container>
71{
72private:
73 template <class Operation>
74 static constexpr bool traverse_is_noexcept() noexcept
75 {
76 return noexcept(std::declval<Operation &>()(std::declval<typename Container::Item_Type &>()));
77 }
78
79public:
99 template <class Operation>
101 bool traverse(Operation &operation) noexcept(traverse_is_noexcept<Operation>())
102 {
103 for (typename Container::Iterator it(*static_cast<Container *>(this)); it.has_curr(); it.next())
104 if (not operation(it.get_curr()))
105 return false;
106 return true;
107 }
108
110 template <class Operation>
112 bool traverse(Operation &operation) const noexcept(traverse_is_noexcept<Operation>())
113 {
114 return const_cast<GenericTraverse *>(this)->traverse<Operation>(operation);
115 }
116
120 template <class Operation>
122 bool traverse(Operation &&operation) const noexcept(traverse_is_noexcept<Operation>())
123 {
124 return traverse<Operation>(operation);
125 }
126
130 template <class Operation>
132 bool traverse(Operation &&operation) noexcept(traverse_is_noexcept<Operation>())
133 {
134 return traverse<Operation>(operation);
135 }
136};
137
150template <class Container, class Operation>
151bool traverse(const Container &c, Operation &op) noexcept(noexcept(c.traverse(op)))
152{
153 return c.traverse(op);
154}
155
170template <class Container, class Operation>
171bool traverse(const Container &c, Operation &&op) noexcept(noexcept(c.traverse(op)))
172{
173 return c.traverse(op);
174}
175
198template <class Container, typename Type>
200{
201 Container *me() noexcept
202 {
203 return static_cast<Container *>(this);
204 }
205
206 const Container *const_me() const noexcept
207 {
208 return static_cast<const Container *>(this);
209 }
210
212 {
213 return const_cast<LocateFunctions *>(this);
214 }
215
216 template <class Operation>
217 static constexpr bool operation_is_noexcept() noexcept
218 {
219 return noexcept(std::declval<Operation &>()(std::declval<Type &>()));
220 }
221
222public:
228 auto get_it() const
229 {
230 return typename Container::Iterator(*const_me());
231 }
232
233 // auto get_it()
234 // {
235 // return typename Container::Iterator(*me());
236 // }
237
244 auto get_it(const size_t pos) const
245 {
246 auto ret = typename Container::Iterator(*const_me());
247 for (size_t i = 0; i < pos; ++i)
248 ret.next();
249 return ret;
250 }
251
256 auto get_itor() const
257 {
258 return get_it();
259 }
260
267 Type &nth_ne(const size_t n) noexcept
268 {
269 Type *ptr = nullptr;
270 size_t i = 0;
271 me()->traverse([&ptr, &i, &n](Type &item)
272 {
273 if (i++ < n)
274 return true;
275 ptr = &item;
276 return false;
277 });
278 return *ptr;
279 }
280
287 const Type &nth_ne(const size_t n) const noexcept
288 {
289 return base()->nth_ne(n);
290 }
291
308 Type &nth(const size_t n)
309 {
310 Type *ptr = nullptr;
311 size_t i = 0;
312 me()->traverse([&ptr, &i, &n](Type &item)
313 {
314 if (i++ < n)
315 return true;
316 ptr = &item;
317 return false;
318 });
319
320 ah_out_of_range_error_if(i != n + 1) << "index out of range";
321
322 return *ptr;
323 }
324
331 const Type &nth(const size_t n) const
332 {
333 return base()->nth(n);
334 }
335
357 template <class Operation>
359 Type *find_ptr(Operation &operation) noexcept(operation_is_noexcept<Operation>())
360 {
361 Type *ptr = nullptr;
362 me()->traverse([&ptr, &operation](Type &item)
363 {
364 if (operation(item))
365 {
366 ptr = &item;
367 return false;
368 }
369 return true;
370 });
371 return ptr;
372 }
373
379 template <class Operation>
381 const Type *find_ptr(Operation &operation) const noexcept(operation_is_noexcept<Operation>())
382 {
383 return base()->find_ptr(operation);
384 }
385
397 template <class Operation>
399 const Type *find_ptr(Operation &&operation) const noexcept(operation_is_noexcept<Operation>())
400 {
401 return find_ptr<Operation>(operation);
402 }
403
415 template <class Operation>
417 Type *find_ptr(Operation &&operation) noexcept(operation_is_noexcept<Operation>())
418 {
419 return find_ptr<Operation>(operation);
420 }
421
444 template <class Operation>
446 size_t find_index(Operation &operation) const noexcept(operation_is_noexcept<Operation>())
447 {
448 size_t i = 0;
449 const_me()->traverse([&i, &operation](const Type &item)
450 {
451 if (operation(item))
452 return false;
453 ++i;
454 return true;
455 });
456 return i;
457 }
458
470 template <class Operation>
472 size_t find_index(Operation &&operation) const noexcept(operation_is_noexcept<Operation>())
473 {
474 return find_index<Operation>(operation);
475 }
476
497 template <class Operation>
499 std::tuple<bool, Type> find_item(Operation &operation) noexcept(operation_is_noexcept<Operation>())
500 {
501 using TT = std::tuple<bool, Type>;
502 auto ptr = find_ptr(operation);
503 return ptr ? TT(true, *ptr) : TT(false, Type());
504 }
505
507 template <class Operation>
509 std::tuple<bool, Type> find_item(Operation &operation) const
510 noexcept(operation_is_noexcept<Operation>())
511 {
512 using TT = std::tuple<bool, Type>;
513 auto ptr = find_ptr(operation);
514 return ptr ? TT(true, *ptr) : TT(false, Type());
515 }
516
528 template <class Operation>
530 std::tuple<bool, Type> find_item(Operation &&operation) noexcept(operation_is_noexcept<Operation>())
531 {
532 return find_item<Operation>(operation);
533 }
534
546 template <class Operation>
548 std::tuple<bool, Type> find_item(Operation &&operation) const
549 noexcept(operation_is_noexcept<Operation>())
550 {
551 return find_item<Operation>(operation);
552 }
553
561 template <class Operation>
563 bool contains_if(Operation &&operation) const noexcept(operation_is_noexcept<Operation>())
564 {
565 return find_ptr(operation) != nullptr;
566 }
567
574 bool contains(const Type &item) const
575 {
576 return contains_if([&item](const Type &x)
577 {
578 return x == item;
579 });
580 }
581};
582
598template <class Container, typename T>
600{
601 SpecialCtors() = default;
602
603 SpecialCtors(const SpecialCtors &) = default;
604
606
608
610 {
611 return *this;
612 }
613
619 {
620 l.for_each([this](const T &item)
621 {
622 static_cast<Container *>(this)->append(item);
623 });
624 }
625
631 template <class It>
633 {
634 for (It it = b; it != e; ++it)
635 static_cast<Container *>(this)->append(*it);
636 }
637
642 SpecialCtors(std::initializer_list<T> l)
643 {
644 for (const auto &item : l)
645 static_cast<Container *>(this)->append(item);
646 }
647};
648
656template <class Container, typename T>
658{
660 {
661 return static_cast<Container *>(this);
662 }
663
665 {
666 return const_cast<FunctionalMethods<Container, T> *>(this);
667 }
668
669 const Container *const_me() const noexcept
670 {
671 return static_cast<const Container *>(this);
672 }
673
674public:
693 template <typename... Args>
694 void emplace(Args &&...args)
695 {
696 (void) me()->append(T(std::forward<Args>(args)...));
697 }
698
700 template <typename... Args>
701 void emplace_end(Args &&...args)
702 {
703 (void) me()->append(T(std::forward<Args>(args)...));
704 }
705
724 template <typename... Args>
725 void emplace_ins(Args &&...args)
726 {
727 (void) me()->insert(T(std::forward<Args>(args)...));
728 }
729
730private:
731 static void nninsert(size_t &) {}
732 static void nnappend(size_t &) {}
733
734 template <typename... Args>
735 void nninsert(size_t &n, const T &item, Args &...args)
736 {
737 (void) me()->insert(item);
738 ++n;
739 nninsert(n, args...);
740 }
741
742 template <typename... Args>
743 void nnappend(size_t &n, const T &item, Args &...args)
744 {
745 (void) me()->append(item);
746 ++n;
747 nnappend(n, args...);
748 }
749
750public:
756 template <typename... Args>
757 size_t ninsert(Args... args)
758 {
759 size_t n = 0;
760 nninsert(n, args...);
761 return n;
762 }
763
769 template <typename... Args>
770 size_t nappend(Args... args)
771 {
772 size_t n = 0;
773 nnappend(n, args...);
774 return n;
775 }
776
794 template <class Operation>
796 void for_each(Operation &operation)
797 {
798 me()->traverse([&operation](const T &item)
799 {
800 operation(item);
801 return true;
802 });
803 }
804
806 template <class Operation>
808 void for_each(Operation &operation) const
809 {
810 base()->for_each(operation);
811 }
812
823 template <class Operation>
825 void for_each(Operation &&operation) const
826 {
827 for_each<Operation>(operation);
828 }
829
840 template <class Operation>
842 void for_each(Operation &&operation)
843 {
844 for_each<Operation>(operation);
845 }
846
848 template <class Operation>
850 void each(Operation &operation)
851 {
852 for_each(operation);
853 }
854
856 template <class Operation>
858 void each(Operation &operation) const
859 {
860 for_each(operation);
861 }
862
873 template <class Operation>
875 void each(Operation &&operation) const
876 {
877 for_each<Operation>(operation);
878 }
879
890 template <class Operation>
892 void each(Operation &&operation)
893 {
894 for_each<Operation>(operation);
895 }
896
917 template <class Operation>
918 void each(size_t pos, const size_t slice, Operation &operation) const
919 {
920 if (slice == 0)
921 return;
922 auto it = const_me()->get_it(pos);
923 while (true)
924 {
925 operation(it.get_curr());
926 for (size_t k = 0; k < slice; ++k)
927 {
928 it.next();
929 if (not it.has_curr())
930 return;
931 }
932 }
933 }
934
936 template <class Operation>
937 void each(const size_t pos, const size_t slice, Operation &&operation) const
938 {
939 each<Operation>(pos, slice, operation);
940 }
941
951 template <class Operation>
953 void mutable_for_each(Operation &operation)
954 {
955 me()->traverse([&operation](T &item)
956 {
957 operation(item);
958 return true;
959 });
960 }
961
963 template <class Operation>
965 void mutable_for_each(Operation &&operation)
966 {
967 mutable_for_each<Operation>(operation);
968 }
969
982 template <class Operation>
983 requires requires(const typename Aleph::concepts_detail::defer<Container, Operation>::type &c, Operation &op) { { c.traverse(op) } -> std::convertible_to<bool>; }
984 bool all(Operation &operation) const
985 {
986 return const_me()->traverse(operation);
987 }
988
1000 template <class Operation>
1001 requires requires(const typename Aleph::concepts_detail::defer<Container, Operation>::type &c, Operation &op) { { c.traverse(op) } -> std::convertible_to<bool>; }
1002 bool all(Operation &&operation) const
1003 {
1004 return all<Operation>(operation);
1005 }
1006
1020 template <class Operation>
1022 bool exists(Operation &op) const
1023 {
1024 return not const_me()->traverse([&op](const T &i)
1025 {
1026 return not op(i);
1027 });
1028 }
1029
1041 template <class Operation>
1043 bool exists(Operation &&op) const
1044 {
1045 return exists<Operation>(op);
1046 }
1047
1088 template <typename __T = T, class Operation = Aleph::Dft_Map_Op<T, __T>>
1089 requires requires(Aleph::DynList<__T> &l, Operation &op, const T &item) { l.append(op(item)); }
1090 Aleph::DynList<__T> maps(Operation &op) const
1091 {
1092 Aleph::DynList<__T> ret_val;
1093 const_me()->for_each([&ret_val, &op](const T &item)
1094 {
1095 ret_val.append(op(item));
1096 });
1097 return ret_val;
1098 }
1099
1112 template <typename __T = T, class Operation = Aleph::Dft_Map_Op<__T, __T>>
1113 requires requires(Aleph::DynList<__T> &l, Operation &op, const T &item) { l.append(op(item)); }
1114 Aleph::DynList<__T> maps(Operation &&op) const
1115 {
1116 return maps<__T, Operation>(op);
1117 }
1118
1135 template <typename __T = T, class Prop, class Operation>
1137 requires(Aleph::DynList<__T> &l, Operation &op, const T &item) { l.append(op(item)); }
1138 Aleph::DynList<__T> maps_if(Prop prop, Operation &op) const
1139 {
1140 Aleph::DynList<__T> ret_val;
1141 const_me()->for_each([&ret_val, &prop, &op](const T &item)
1142 {
1143 if (prop(item))
1144 ret_val.append(op(item));
1145 });
1146 return ret_val;
1147 }
1148
1163 template <typename __T = T, class Prop, class Operation>
1165 requires(Aleph::DynList<__T> &l, Operation &op, const T &item) { l.append(op(item)); }
1166 Aleph::DynList<__T> maps_if(Prop prop, Operation &&op) const
1167 {
1168 return maps_if<__T, Prop, Operation>(prop, op);
1169 }
1170
1180 template <typename __T = T, class Operation = Aleph::Dft_Map_Op<T, __T>>
1181 requires requires(Aleph::DynList<__T> &l, Operation &op, const T &item) { l.append(op(item)); }
1182 Aleph::DynList<__T> map(Operation &op) const
1183 {
1184 return maps<__T, Operation>(op);
1185 }
1186
1195 template <typename __T = T, class Operation = Aleph::Dft_Map_Op<__T, __T>>
1196 requires requires(Aleph::DynList<__T> &l, Operation &op, const T &item) { l.append(op(item)); }
1197 Aleph::DynList<__T> map(Operation &&op) const
1198 {
1199 return maps<__T, Operation>(op);
1200 }
1201
1209 template <typename __T = T, class Prop, class Operation>
1211 requires(Aleph::DynList<__T> &l, Operation &op, const T &item) { l.append(op(item)); }
1212 Aleph::DynList<__T> map_if(Prop prop, Operation &op) const
1213 {
1214 return maps_if<__T, Prop, Operation>(prop, op);
1215 }
1216
1227 template <typename __T = T, class Prop, class Operation>
1229 requires(Aleph::DynList<__T> &l, Operation &op, const T &item) { l.append(op(item)); }
1230 Aleph::DynList<__T> map_if(Prop prop, Operation &&op) const
1231 {
1232 return maps_if<__T, Prop, Operation>(prop, op);
1233 }
1234
1240 {
1241 return maps([](auto &item)
1242 {
1243 return item;
1244 });
1245 }
1246
1251 std::vector<T> to_vector() const
1252 {
1253 std::vector<T> ret;
1254 if constexpr (requires { const_me()->size(); })
1255 ret.reserve(const_me()->size());
1256 const_me()->for_each([&ret](const T &item)
1257 {
1258 ret.push_back(item);
1259 });
1260 return ret;
1261 }
1262
1310 template <typename __T = T, class Op = Aleph::Dft_Fold_Op<__T, T>>
1311 requires requires(__T &acc, Op &op, const T &item) { acc = op(acc, item); }
1312 __T foldl(const __T &init, Op &op) const
1313 {
1314 __T ret_val = init;
1315 const_me()->for_each([&ret_val, &op](const T &item)
1316 {
1317 ret_val = op(ret_val, item);
1318 });
1319 return ret_val;
1320 }
1321
1335 template <typename __T = T, class Op = Aleph::Dft_Fold_Op<__T, T>>
1336 requires requires(__T &acc, Op &op, const T &item) { acc = op(acc, item); }
1337 __T foldl(const __T &init, Op &&op = Op()) const
1338 {
1339 return foldl<__T, Op>(init, op);
1340 }
1341
1349 template <typename __T = T, class Op = Aleph::Dft_Fold_Op<__T, T>>
1350 requires requires(__T &acc, Op &op, const T &item) { acc = op(acc, item); }
1351 __T fold_left(const __T &init, Op &op) const
1352 {
1353 return const_me()->template foldl<__T>(init, op);
1354 }
1355
1369 template <typename __T = T, class Op = Aleph::Dft_Fold_Op<__T, T>>
1370 requires requires(__T &acc, Op &op, const T &item) { acc = op(acc, item); }
1371 __T fold_left(const __T &init, Op &&op = Op()) const
1372 {
1373 return const_me()->template foldl<__T>(init, op);
1374 }
1375
1381 template <class Operation>
1382 requires requires(T &acc, Operation &op, const T &item) { acc = op(acc, item); }
1383 T fold(const T &init, Operation &operation) const
1384 {
1385 auto ret_val = init;
1386 const_me()->for_each([&ret_val, &operation](const T &item)
1387 {
1388 ret_val = operation(ret_val, item);
1389 });
1390 return ret_val;
1391 }
1392
1405 template <class Operation>
1406 requires requires(T &acc, Operation &op, const T &item) { acc = op(acc, item); }
1407 T fold(const T &init, Operation &&operation) const
1408 {
1409 return fold<Operation>(init, operation);
1410 }
1411
1435 template <class Operation>
1437 Aleph::DynList<T> filter(Operation &operation) const
1438 {
1439 Aleph::DynList<T> ret_val;
1440 const_me()->for_each([&ret_val, &operation](const T &item)
1441 {
1442 if (operation(item))
1443 ret_val.append(item);
1444 });
1445 return ret_val;
1446 }
1447
1459 template <class Operation>
1461 Aleph::DynList<T> filter(Operation &&operation) const
1462 {
1463 return filter<Operation>(operation);
1464 }
1465
1489 template <class Operation>
1491 Aleph::DynList<const T *> ptr_filter(Operation &operation) const
1492 {
1494 const_me()->for_each([&ret_val, &operation](const T &item)
1495 {
1496 if (operation(item))
1497 ret_val.append(&item);
1498 });
1499 return ret_val;
1500 }
1501
1513 template <class Operation>
1515 Aleph::DynList<const T *> ptr_filter(Operation &&operation) const
1516 {
1517 return ptr_filter<Operation>(operation);
1518 }
1519
1539 template <class Operation>
1542 {
1543 using TT = std::tuple<T, size_t>;
1544 Aleph::DynList<TT> ret_val;
1545 size_t i = 0;
1546 const_me()->for_each([&ret_val, &operation, &i](const T &item)
1547 {
1548 if (operation(item))
1549 ret_val.append(TT(item, i));
1550 ++i;
1551 });
1552 return ret_val;
1553 }
1554
1566 template <class Operation>
1568 Aleph::DynList<std::tuple<T, size_t>> pfilter(Operation &&operation) const
1569 {
1570 return pfilter<Operation>(operation);
1571 }
1572
1590 template <class Operation>
1592 std::pair<Aleph::DynList<T>, Aleph::DynList<T>> partition(Operation &op) const
1593 {
1594 std::pair<Aleph::DynList<T>, Aleph::DynList<T>> ret_val;
1595 const_me()->for_each([&ret_val, &op](const T &item)
1596 {
1597 if (op(item))
1598 ret_val.first.append(item);
1599 else
1600 ret_val.second.append(item);
1601 });
1602 return ret_val;
1603 }
1604
1616 template <class Operation>
1618 std::pair<Aleph::DynList<T>, Aleph::DynList<T>> partition(Operation &&op) const
1619 {
1620 return partition<Operation>(op);
1621 }
1622
1633 std::pair<Aleph::DynList<T>, Aleph::DynList<T>> partition(size_t n) const
1634 {
1635 size_t i = 0;
1636 std::pair<Aleph::DynList<T>, Aleph::DynList<T>> ret_val;
1637 const_me()->for_each([&ret_val, &i, n](const T &item)
1638 {
1639 if (i++ < n)
1640 ret_val.first.append(item);
1641 else
1642 ret_val.second.append(item);
1643 });
1644 return ret_val;
1645 }
1646
1653 std::pair<Aleph::DynList<T>, Aleph::DynList<T>> split_half() const
1654 {
1655 size_t i = 0;
1656 std::pair<Aleph::DynList<T>, Aleph::DynList<T>> ret_val;
1657 const_me()->for_each([&ret_val, &i](const T &item)
1658 {
1659 if (i % 2 == 0)
1660 ret_val.first.append(item);
1661 else
1662 ret_val.second.append(item);
1663 i++;
1664 });
1665 return ret_val;
1666 }
1667
1681 template <class Operation>
1683 std::tuple<Aleph::DynList<T>, Aleph::DynList<T>> tpartition(Operation &op) const
1684 {
1685 Aleph::DynList<T> r1, r2;
1686 const_me()->for_each([&r1, &r2, &op](const T &item)
1687 {
1688 if (op(item))
1689 r1.append(item);
1690 else
1691 r2.append(item);
1692 });
1693 return std::tuple<Aleph::DynList<T>, Aleph::DynList<T>>(r1, r2);
1694 }
1695
1707 template <class Operation>
1709 std::tuple<Aleph::DynList<T>, Aleph::DynList<T>> tpartition(Operation &&op) const
1710 {
1711 return tpartition<Operation>(op);
1712 }
1713
1725 [[nodiscard]] size_t length() const noexcept
1726 {
1727 size_t count = 0;
1728 const_me()->for_each([&count](const T &)
1729 {
1730 ++count;
1731 });
1732 return count;
1733 }
1734
1743 {
1745 const_me()->for_each([&ret](const T &i)
1746 {
1747 ret.insert(i);
1748 });
1749 return ret;
1750 }
1751
1764 Aleph::DynList<T> take(const size_t n) const
1765 {
1766 size_t i = 0;
1768 const_me()->traverse([&i, &ret, n](const T &item)
1769 {
1770 if (i++ >= n)
1771 return false;
1772 ret.append(item);
1773 return true;
1774 });
1775 return ret;
1776 }
1777
1790 Aleph::DynList<T> take(size_t i, const size_t j, const size_t step = 1) const
1791 {
1793 if (step == 0)
1794 return ret;
1795 for (auto it = const_me()->get_it(i); i <= j and it.has_curr(); it.next_ne(), i += step)
1796 ret.append(it.get_curr());
1797 return ret;
1798 }
1799
1812 Aleph::DynList<T> drop(const size_t n) const
1813 {
1814 size_t i = 0;
1816 const_me()->traverse([&i, &ret, n](const T &item)
1817 {
1818 if (i++ >= n)
1819 ret.append(item);
1820 return true;
1821 });
1822 return ret;
1823 }
1824
1833 void mutable_drop(const size_t n)
1834 {
1835 for (size_t i = 0; i < n; ++i)
1836 me()->remove();
1837 }
1838};
1839
1844template <class Container, typename T>
1846{
1855 {
1856 return static_cast<const Container *>(this)->Container::template maps<T>([](const T &key)
1857 {
1858 return key;
1859 });
1860 }
1861
1864 {
1865 return items();
1866 }
1867};
1868
1873template <class Container, typename T>
1875
1889template <class Container>
1891{
1892 const Container *const_me() const noexcept
1893 {
1894 return static_cast<const Container *>(this);
1895 }
1896
1897public:
1909 bool equal_to(const Container &r) const
1910 {
1911 if (const_me() == &r)
1912 return true;
1913
1914 if (const_me()->size() != r.size())
1915 return false;
1916
1917 auto it1 = const_me()->get_it();
1918 auto it2 = r.get_it();
1919
1920 while (it1.has_curr())
1921 {
1922 if (not(it1.get_curr() == it2.get_curr()))
1923 return false;
1924
1925 it1.next();
1926 it2.next();
1927 }
1928
1929 return true;
1930 }
1931
1937 bool operator == (const Container &r) const
1938 {
1939 return equal_to(r);
1940 }
1941
1947 bool operator != (const Container &r) const
1948 {
1949 return not equal_to(r);
1950 }
1951};
1952
1957template <class Container>
1959{
1960 const Container *const_me() const
1961 {
1962 return static_cast<const Container *>(this);
1963 }
1964
1965public:
1984 bool equal_to(const Container &r) const noexcept
1985 {
1986 if (const_me() == &r) // Use const_me() to get correct pointer in case of multiple inheritance
1987 return true;
1988
1989 if (const_me()->size() != r.size())
1990 return false;
1991
1992 return const_me()->all([&r](const typename Container::Key_Type &k)
1993 {
1994 return r.search(k) != nullptr;
1995 });
1996 }
1997
1999 bool operator == (const Container &r) const noexcept
2000 {
2001 return equal_to(r);
2002 }
2003
2005 bool operator != (const Container &r) const noexcept
2006 {
2007 return not equal_to(r);
2008 }
2009};
2010
2015template <class Container, typename Key, typename Data>
2017{
2018 const Container *const_me() const
2019 {
2020 return static_cast<const Container *>(this);
2021 }
2022
2024 {
2025 return static_cast<Container *>(this);
2026 }
2027
2028public:
2042 template <template <typename> class C = Aleph::DynList>
2043 C<Key> keys() const
2044 {
2045 C<Key> ret_val;
2046 const_me()->for_each([&ret_val](const Key &p)
2047 {
2048 ret_val.append(p.first);
2049 });
2050 return ret_val;
2051 }
2052
2066 template <template <typename> class C = Aleph::DynList>
2067 C<Data> values() const
2068 {
2069 C<Data> ret_val;
2070 const_me()->for_each([&ret_val](const std::pair<Key, Data> &p)
2071 {
2072 ret_val.append(p.second);
2073 });
2074 return ret_val;
2075 }
2076
2092 template <template <typename> class C = Aleph::DynList>
2093 C<Data *> values_ptr() const
2094 {
2095 C<Data *> ret_val;
2096 const_me()->for_each([&ret_val](std::pair<Key, Data> &p)
2097 {
2098 ret_val.append(&p.second);
2099 });
2100 return ret_val;
2101 }
2102
2112 template <template <typename> class C = Aleph::DynList>
2113 C<std::pair<Key, Data>> items() const
2114 {
2115 C<std::pair<Key, Data>> ret;
2116 const_me()->for_each([&ret](std::pair<Key, Data> &p)
2117 {
2118 ret.append(p);
2119 });
2120 return ret;
2121 }
2122
2134 template <template <typename> class C = Aleph::DynList>
2135 C<std::pair<Key, Data *>> items_ptr() const
2136 {
2137 C<std::pair<Key, Data *>> ret_val;
2138 const_me()->for_each([&ret_val](std::pair<Key, Data> &p)
2139 {
2140 ret_val.append(std::pair<Key, Data *>(p.first, &p.second));
2141 });
2142 return ret_val;
2143 }
2144
2150 Data &operator () (const Key &key)
2151 {
2152 // CRTP: `find` lives on the derived `Container`, not on this base.
2153 // Casting via `me()` is required for AppleClang (which performs the
2154 // member lookup eagerly at template definition time) and is the
2155 // correct pattern regardless of compiler leniency.
2156 return me()->find(key);
2157 }
2158
2164 const Data &operator () (const Key &key) const
2165 {
2166 return const_me()->find(key);
2167 }
2168};
2169#endif // AH_DRY_H
C++20 concepts hub: comparison, BST policy, and Aleph container concepts.
bool traverse(const Container &c, Operation &op) noexcept(noexcept(c.traverse(op)))
Invoke c.traverse(op) as a free function (lvalue operation).
Definition ah-dry.H:151
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
Functional programming utilities for Aleph-w containers.
Doubly-linked list (defined in tpl_dynList.H).
Definition htlist.H:1155
T & insert(const T &item)
Definition htlist.H:1220
T & append(const T &item)
Definition htlist.H:1271
Mixin providing equality comparison for sequence containers.
Definition ah-dry.H:1891
bool operator==(const Container &r) const
Equality operator.
Definition ah-dry.H:1937
bool operator!=(const Container &r) const
Inequality operator.
Definition ah-dry.H:1947
bool equal_to(const Container &r) const
Equality test between this and r.
Definition ah-dry.H:1909
const Container * const_me() const noexcept
Definition ah-dry.H:1892
Equality test for containers.
Definition ah-dry.H:1959
const Container * const_me() const
Definition ah-dry.H:1960
bool operator!=(const Container &r) const noexcept
Negation of equal_to()
Definition ah-dry.H:2005
bool operator==(const Container &r) const noexcept
Definition ah-dry.H:1999
bool equal_to(const Container &r) const noexcept
Test if elements of this are exactly contained in another container.
Definition ah-dry.H:1984
Common methods to the Aleph-w ( ) containers.
Definition ah-dry.H:658
Aleph::DynList< const T * > ptr_filter(Operation &&operation) const
Overload of ptr_filter() that accepts rvalues.
Definition ah-dry.H:1515
Aleph::DynList< std::tuple< T, size_t > > pfilter(Operation &&operation) const
Overload of pfilter() that accepts rvalues.
Definition ah-dry.H:1568
void emplace_end(Args &&...args)
Definition ah-dry.H:701
Aleph::DynList< T > filter(Operation &operation) const
Filter the elements of a container according to a matching criterion.
Definition ah-dry.H:1437
std::vector< T > to_vector() const
Convert container to std::vector.
Definition ah-dry.H:1251
Aleph::DynList< __T > maps_if(Prop prop, Operation &op) const
Definition ah-dry.H:1138
void each(Operation &&operation)
Alias of each() that accepts rvalues.
Definition ah-dry.H:892
std::pair< Aleph::DynList< T >, Aleph::DynList< T > > partition(size_t n) const
Exclusive partition of container in the nth item.
Definition ah-dry.H:1633
Aleph::DynList< __T > map_if(Prop prop, Operation &&op) const
Definition ah-dry.H:1230
bool exists(Operation &op) const
Test for existence in the container of an element satisfying a criterion.
Definition ah-dry.H:1022
Aleph::DynList< T > to_dynlist() const
Convert container to DynList.
Definition ah-dry.H:1239
void each(Operation &operation)
Alias of for_each(Operation&).
Definition ah-dry.H:850
T fold(const T &init, Operation &operation) const
Simplified version of foldl() where the folded type is the same type of elements stored in the contai...
Definition ah-dry.H:1383
Aleph::DynList< std::tuple< T, size_t > > pfilter(Operation &operation) const
Filter the elements of a container according to a matching criterion and determine its positions resp...
Definition ah-dry.H:1541
std::tuple< Aleph::DynList< T >, Aleph::DynList< T > > tpartition(Operation &op) const
Exclusive partition of container according to a filter criterion.
Definition ah-dry.H:1683
Aleph::DynList< __T > maps(Operation &&op) const
Overload of maps() that accepts rvalues.
Definition ah-dry.H:1114
FunctionalMethods< Container, T > * base() const noexcept
Definition ah-dry.H:664
size_t ninsert(Args... args)
Insert n variadic items.
Definition ah-dry.H:757
void each(const size_t pos, const size_t slice, Operation &&operation) const
Definition ah-dry.H:937
__T foldl(const __T &init, Op &op) const
Fold the elements of the container to a specific result.
Definition ah-dry.H:1312
void emplace_ins(Args &&...args)
Insert a new element into the container by constructing it in-place with the given args.
Definition ah-dry.H:725
bool all(Operation &&operation) const
Overload of all() that accepts rvalues.
Definition ah-dry.H:1002
void each(Operation &operation) const
Const alias of for_each(Operation&).
Definition ah-dry.H:858
Aleph::DynList< __T > map(Operation &&op) const
Overload of map() that accepts rvalues.
Definition ah-dry.H:1197
Aleph::DynList< T > take(const size_t n) const
Return a list with the first n elements seen in the container during its traversal.
Definition ah-dry.H:1764
static void nnappend(size_t &)
Definition ah-dry.H:732
Aleph::DynList< __T > maps_if(Prop prop, Operation &&op) const
Definition ah-dry.H:1166
Aleph::DynList< const T * > ptr_filter(Operation &operation) const
Filter the elements of a container according to a matching criterion and return a pointer to the matc...
Definition ah-dry.H:1491
const Container * const_me() const noexcept
Definition ah-dry.H:669
void each(size_t pos, const size_t slice, Operation &operation) const
Traverse the container starting at pos taking one item every slice, performing a mutable operation on...
Definition ah-dry.H:918
Aleph::DynList< T > rev() const
Return a list with the elements of container in reverse order respect to its traversal order.
Definition ah-dry.H:1742
void mutable_for_each(Operation &operation)
Apply a mutable operation to each element of the container.
Definition ah-dry.H:953
std::tuple< Aleph::DynList< T >, Aleph::DynList< T > > tpartition(Operation &&op) const
Overload of tpartition() that accepts rvalues.
Definition ah-dry.H:1709
static void nninsert(size_t &)
Definition ah-dry.H:731
__T fold_left(const __T &init, Op &&op=Op()) const
Overload of fold_left() that accepts rvalues.
Definition ah-dry.H:1371
Aleph::DynList< T > filter(Operation &&operation) const
Overload of filter() that accepts rvalues.
Definition ah-dry.H:1461
std::pair< Aleph::DynList< T >, Aleph::DynList< T > > partition(Operation &&op) const
Overload of partition() that accepts rvalues.
Definition ah-dry.H:1618
Aleph::DynList< __T > map(Operation &op) const
Synonym of maps().
Definition ah-dry.H:1182
size_t length() const noexcept
Count the number of elements of a container.
Definition ah-dry.H:1725
__T foldl(const __T &init, Op &&op=Op()) const
Overload of foldl() that accepts rvalues.
Definition ah-dry.H:1337
size_t nappend(Args... args)
Append n variadic items.
Definition ah-dry.H:770
void nninsert(size_t &n, const T &item, Args &...args)
Definition ah-dry.H:735
Aleph::DynList< __T > maps(Operation &op) const
Map the elements of the container.
Definition ah-dry.H:1090
void for_each(Operation &&operation) const
Overload of for_each() const that accepts rvalues.
Definition ah-dry.H:825
void for_each(Operation &operation)
Traverse all the container and performs an operation on each element.
Definition ah-dry.H:796
void each(Operation &&operation) const
Const alias of each() that accepts rvalues.
Definition ah-dry.H:875
Aleph::DynList< __T > map_if(Prop prop, Operation &op) const
Definition ah-dry.H:1212
void mutable_drop(const size_t n)
Drop the first n elements seen from container.
Definition ah-dry.H:1833
bool all(Operation &operation) const
Check if all the elements of the container satisfy a condition.
Definition ah-dry.H:984
T fold(const T &init, Operation &&operation) const
Overload of fold() that accepts rvalues.
Definition ah-dry.H:1407
Container * me()
Definition ah-dry.H:659
Aleph::DynList< T > take(size_t i, const size_t j, const size_t step=1) const
Return a list with elements seen in the container between i and j position respect to its traversal.
Definition ah-dry.H:1790
std::pair< Aleph::DynList< T >, Aleph::DynList< T > > split_half() const
Split the container into two halves by alternating elements.
Definition ah-dry.H:1653
void for_each(Operation &operation) const
Const overload of for_each(Operation&).
Definition ah-dry.H:808
void emplace(Args &&...args)
Appends a new element into the container by constructing it in-place with the given args.
Definition ah-dry.H:694
void nnappend(size_t &n, const T &item, Args &...args)
Definition ah-dry.H:743
and
Conditional mapping of the elements of the container.
Definition ah-dry.H:1137
Aleph::DynList< T > drop(const size_t n) const
Drop the first n elements seen in the container during its traversal.
Definition ah-dry.H:1812
std::pair< Aleph::DynList< T >, Aleph::DynList< T > > partition(Operation &op) const
Exclusive partition of container according to a filter criterion.
Definition ah-dry.H:1592
bool exists(Operation &&op) const
Overload of exists() that accepts rvalues.
Definition ah-dry.H:1043
__T fold_left(const __T &init, Op &op) const
Alias for foldl with the same accumulator type.
Definition ah-dry.H:1351
void for_each(Operation &&operation)
Overload of for_each() that accepts rvalues.
Definition ah-dry.H:842
void mutable_for_each(Operation &&operation)
Definition ah-dry.H:965
Common sequential searching methods on containers.
Definition ah-dry.H:200
static constexpr bool operation_is_noexcept() noexcept
Definition ah-dry.H:217
auto get_itor() const
Alias of get_it().
Definition ah-dry.H:256
std::tuple< bool, Type > find_item(Operation &&operation) const noexcept(operation_is_noexcept< Operation >())
Overload of find_item() const that accepts rvalues.
Definition ah-dry.H:548
const Type * find_ptr(Operation &&operation) const noexcept(operation_is_noexcept< Operation >())
Overload of find_ptr() const that accepts rvalues.
Definition ah-dry.H:399
Container * me() noexcept
Definition ah-dry.H:201
Type & nth_ne(const size_t n) noexcept
Return the n‑th element without bounds checking.
Definition ah-dry.H:267
std::tuple< bool, Type > find_item(Operation &operation) noexcept(operation_is_noexcept< Operation >())
Safe sequential searching of an item matching a criterion.
Definition ah-dry.H:499
std::tuple< bool, Type > find_item(Operation &operation) const noexcept(operation_is_noexcept< Operation >())
Definition ah-dry.H:509
bool contains(const Type &item) const
Test if an item is present in the container using equality.
Definition ah-dry.H:574
LocateFunctions< Container, Type > * base() const
Definition ah-dry.H:211
Type * find_ptr(Operation &operation) noexcept(operation_is_noexcept< Operation >())
Find a pointer to an item in the container according to a searching criterion.
Definition ah-dry.H:359
const Type & nth(const size_t n) const
Const overload of nth(size_t).
Definition ah-dry.H:331
Type & nth(const size_t n)
Return the n-th item of the container.
Definition ah-dry.H:308
const Container * const_me() const noexcept
Definition ah-dry.H:206
Type * find_ptr(Operation &&operation) noexcept(operation_is_noexcept< Operation >())
Overload of find_ptr() that accepts rvalues.
Definition ah-dry.H:417
std::tuple< bool, Type > find_item(Operation &&operation) noexcept(operation_is_noexcept< Operation >())
Overload of find_item() that accepts rvalues.
Definition ah-dry.H:530
size_t find_index(Operation &&operation) const noexcept(operation_is_noexcept< Operation >())
Overload of find_index() that accepts rvalues.
Definition ah-dry.H:472
size_t find_index(Operation &operation) const noexcept(operation_is_noexcept< Operation >())
Find the position of an item in the container according to a searching criterion.
Definition ah-dry.H:446
auto get_it() const
Return a properly initialized iterator positioned at the first item on the container.
Definition ah-dry.H:228
auto get_it(const size_t pos) const
Return a properly initialized iterator positioned at the pos item on the container.
Definition ah-dry.H:244
const Type * find_ptr(Operation &operation) const noexcept(operation_is_noexcept< Operation >())
Const overload of find_ptr(Operation&).
Definition ah-dry.H:381
bool contains_if(Operation &&operation) const noexcept(operation_is_noexcept< Operation >())
Test if an item satisfying a criterion is present in the container.
Definition ah-dry.H:563
const Type & nth_ne(const size_t n) const noexcept
Const overload of nth_ne(size_t).
Definition ah-dry.H:287
Common methods to mapping containers.
Definition ah-dry.H:2017
C< Key > keys() const
Return the domain set of container.
Definition ah-dry.H:2043
Container * me()
Definition ah-dry.H:2023
C< std::pair< Key, Data * > > items_ptr() const
Return a container with the entire mapping where the range could be modified.
Definition ah-dry.H:2135
C< Data > values() const
Return the range set of container.
Definition ah-dry.H:2067
C< std::pair< Key, Data > > items() const
Return a container with the entire mapping.
Definition ah-dry.H:2113
Data & operator()(const Key &key)
Return the image or element mapped to key.
Definition ah-dry.H:2150
const Container * const_me() const
Definition ah-dry.H:2018
C< Data * > values_ptr() const
Return a container of pointers to the elements of range set of container.
Definition ah-dry.H:2093
f(args...) is a valid call expression, exactly as written.
f(args...) is a valid call whose result is usable as a condition.
Main namespace for Aleph-w library functions.
Definition ah-arena.H:89
#define TT
Definition ran_array.c:29
Generic list of items stored in a container.
Definition ah-dry.H:1846
Aleph::DynList< T > keys() const
Definition ah-dry.H:1863
Aleph::DynList< T > items() const
Return a list of all the elements of a container sorted by traversal order.
Definition ah-dry.H:1854
Generic traversal of the container through its iterator.
Definition ah-dry.H:71
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:101
bool traverse(Operation &&operation) noexcept(traverse_is_noexcept< Operation >())
Overload of traverse(Operation&) that accepts rvalues.
Definition ah-dry.H:132
bool traverse(Operation &operation) const noexcept(traverse_is_noexcept< Operation >())
Const overload of traverse(Operation&).
Definition ah-dry.H:112
bool traverse(Operation &&operation) const noexcept(traverse_is_noexcept< Operation >())
Overload of traverse(Operation&) const that accepts rvalues.
Definition ah-dry.H:122
static constexpr bool traverse_is_noexcept() noexcept
Definition ah-dry.H:74
Special constructors common to Aleph-w ( ) containers.
Definition ah-dry.H:600
SpecialCtors(const SpecialCtors &)=default
SpecialCtors(SpecialCtors &&) noexcept
Definition ah-dry.H:605
SpecialCtors(std::initializer_list< T > l)
Construct the container from an initializer list.
Definition ah-dry.H:642
SpecialCtors(It b, It e)
Construct the container from a range of iterators.
Definition ah-dry.H:632
SpecialCtors(const Aleph::DynList< T > &l)
Build the container by inserting all items of the list l.
Definition ah-dry.H:618
SpecialCtors()=default
SpecialCtors & operator=(const SpecialCtors &)=default
static int * k
Filter_Iterator< DynList< int >, DynList< int >::Iterator, Par > It
Definition test_htlist.C:61
gsl_rng * r
DynList< int > l