Aleph-w 3.0
A C++ Library for Data Structures and Algorithms
Loading...
Searching...
No Matches
graph-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
32
44# ifndef GRAPH_DRY_H
45# define GRAPH_DRY_H
46
47#include <concepts>
48#include <type_traits>
49#include <utility>
50#include <ah-concepts.H>
51
53{
63 template <class GT, class D>
64 struct node_curr
65 {
66 using type = decltype(std::declval<typename concepts_detail::defer<GT, D>::type::Node_Iterator &>().get_curr());
67 };
68
73 template <class GT, class D>
74 struct arc_curr
75 {
76 using type = decltype(std::declval<typename concepts_detail::defer<GT, D>::type::Arc_Iterator &>().get_curr());
77 };
78
83 template <class GT, class D>
85 {
86 using type = decltype(std::declval<typename concepts_detail::defer<GT, D>::type::Node_Arc_Iterator &>().get_curr());
87 };
88
89} // namespace Aleph::graph_dry_detail
90
91// ============================================================================
92// C++20 Concepts for Graph Iterators
93// ============================================================================
94
193template <typename It>
194concept BasicGraphIterator = requires(It it, const It cit)
195{
196 { cit.has_curr() } -> std::convertible_to<bool>;
197 { it.next() } -> std::same_as<void>;
198 { it.get_curr() };
199};
200
213template <typename It>
215{
216 { it.reset_first() } -> std::same_as<void>;
217};
218
232template <typename It, typename Node>
233concept GraphNodeIterator = BasicGraphIterator<It> && requires(const It cit)
234{
235 { cit.get_curr() } -> std::convertible_to<Node*>;
236};
237
251template <typename It, typename Arc>
252concept GraphArcIterator = BasicGraphIterator<It> && requires(const It cit)
253{
254 { cit.get_curr() } -> std::convertible_to<Arc*>;
255};
256
275template <typename It, typename Node, typename Arc>
276concept NodeArcIterator = GraphArcIterator<It, Arc> && requires(const It cit)
277{
278 { cit.get_tgt_node() } -> std::convertible_to<Node*>;
279};
280
// end of GraphConcepts group
282
283// ============================================================================
284// End of C++20 Concepts
285// ============================================================================
286
296template <class GT>
297struct GTNodeIterator : public Dlink::Iterator
298{
299 using Node = typename GT::Node;
300
302 using Item_Type = Node *;
303
305 using Set_Type = GT;
306
307 GTNodeIterator() noexcept
308 { /* empty */
309 }
310
312 GTNodeIterator(Dlink & head) noexcept : Dlink::Iterator(head)
313 { /* empty */
314 }
315
317 Node * get_curr_ne() const noexcept
318 {
319 return static_cast<Node *>(Dlink::Iterator::get_curr_ne());
320 }
321
323 Node * get_curr() const { return static_cast<Node *>(Dlink::Iterator::get_curr()); }
324
326 Node * get_current_node() const { return get_curr(); }
327
328 Node * get_current_node_ne() const { return get_curr_ne(); }
329};
330
331
341template <class GT>
342struct GTArcIterator : public Dlink::Iterator
343{
344 using Node = typename GT::Node;
345 using Arc = typename GT::Arc;
346
348 using Item_Type = Arc *;
349
351 using Set_Type = GT;
352
353 GTArcIterator() noexcept
354 { /* empty */
355 }
356
358 GTArcIterator(Dlink & head) noexcept
359 : Dlink::Iterator(head)
360 { /* empty */
361 }
362
364 Arc * get_curr_ne() const noexcept
365 {
366 return static_cast<Arc *>(Dlink::Iterator::get_curr_ne());
367 }
368
370 Arc * get_curr() const { return static_cast<Arc *>(Dlink::Iterator::get_curr()); }
371
373 Arc * get_current_arc() const { return get_curr(); }
374
376 Arc * get_current_arc_ne() const noexcept { return get_curr_ne(); }
377
379 Node * get_src_node_ne() const noexcept
380 {
381 return static_cast<Node *>(get_curr_ne()->src_node);
382 }
383
385 Node * get_tgt_node_ne() const noexcept
386 {
387 return static_cast<Node *>(get_curr_ne()->tgt_node);
388 }
389
392 {
393 return static_cast<Node *>(get_curr()->src_node);
394 }
395
398 {
399 return static_cast<Node *>(get_curr()->tgt_node);
400 }
401};
402
403
408template <class GT, class Cmp>
410{
411 using Node = typename GT::Node;
412
414
415 Cmp_Dlink_Node(Cmp && __cmp = Cmp()) noexcept : cmp(__cmp)
416 { /* empty */
417 }
418
419 Cmp_Dlink_Node(Cmp & __cmp) noexcept : cmp(__cmp)
420 { /* empty */
421 }
422
423 bool operator ()(Dlink *d1, Dlink *d2) const noexcept
424 {
425 Node *p1 = static_cast<Node *>(d1);
426 Node *p2 = static_cast<Node *>(d2);
427 return cmp(p1, p2);
428 }
429};
430
435template <class GT, class Cmp>
437{
438 using Arc = typename GT::Arc;
439
441
442 Cmp_Dlink_Arc(Cmp && __cmp = Cmp()) noexcept : cmp(__cmp)
443 { /* empty */
444 }
445
446 Cmp_Dlink_Arc(Cmp & __cmp) noexcept : cmp(__cmp)
447 { /* empty */
450 bool operator ()(Dlink *d1, Dlink *d2) const noexcept
451 {
452 Arc *arc1 = static_cast<Arc *>(d1);
453 Arc *arc2 = static_cast<Arc *>(d2);
454 return cmp(arc1, arc2);
455 }
456};
457
475template <typename NodeInfo>
477{
478public:
483 Graph_Attr attrs;
484
486
487
496 size_t num_arcs = 0;
497
499
501
503
505 GTNodeCommon() noexcept = default;
506
508 GTNodeCommon(const NodeInfo & info) : node_info(info) {}
509
511 GTNodeCommon(NodeInfo && info) : node_info(std::move(info)) {}
512
514 GTNodeCommon(const GTNodeCommon & other) : node_info(other.node_info) {}
515
517 GTNodeCommon(GTNodeCommon && other) noexcept : node_info(std::move(other.node_info)) {}
518
521 {
522 if (this != &other)
523 node_info = other.node_info;
524 return *this;
525 }
526
529 {
530 if (this != &other)
531 node_info = std::move(other.node_info);
532 return *this;
533 }
534
536 NodeInfo &get_info() noexcept { return node_info; }
537
539 const NodeInfo &get_info() const noexcept { return node_info; }
540
542 unsigned int state() const noexcept { return NODE_BITS(this).state; }
543
545 void set_state(unsigned int s) noexcept
546 {
547 NODE_BITS(this).state = s;
548 }
549};
550
551
568template <typename ArcInfo>
570{
571public:
574
575 void *src_node = nullptr;
576 void *tgt_node = nullptr;
577
582 Graph_Attr attrs;
583
585
587 GTArcCommon() noexcept = default;
588
590 GTArcCommon(const ArcInfo & info) : arc_info(info) {}
591
593 GTArcCommon(ArcInfo && info) : arc_info(std::move(info)) {}
594
596 GTArcCommon(void *src, void *tgt, const ArcInfo & data)
597 : src_node(src), tgt_node(tgt), arc_info(data) {}
598
600 GTArcCommon(void *src, void *tgt, ArcInfo && data = ArcInfo())
601 : src_node(src), tgt_node(tgt), arc_info(std::move(data)) {}
602
605 : src_node(other.src_node), tgt_node(other.tgt_node), arc_info(other.arc_info) {}
606
608 GTArcCommon(GTArcCommon && other) noexcept
609 : src_node(other.src_node), tgt_node(other.tgt_node), arc_info(std::move(other.arc_info)) {}
610
613 {
614 if (this != &other)
615 arc_info = other.arc_info;
616 return *this;
617 }
618
620 GTArcCommon & operator=(GTArcCommon && other) noexcept
621 {
622 if (this != &other)
623 arc_info = std::move(other.arc_info);
624 return *this;
625 }
626
628 unsigned int state() const noexcept { return ARC_BITS(this).state; }
629
631 void set_state(unsigned int s) noexcept
632 {
633 ARC_BITS(this).state = s;
634 }
635
637 ArcInfo &get_info() noexcept { return arc_info; }
638
640 const ArcInfo &get_info() const noexcept { return arc_info; }
641
642 void * get_connected_node(void *node) noexcept
643 {
644 return src_node == node ? tgt_node : src_node;
645 }
646
647 void * get_img_node(void *node) noexcept
648 {
649 return src_node == node ? src_node : tgt_node;
650 }
651};
652
653
658template <class GT, class Node, class Arc>
660{
661 GT * me() { return static_cast<GT *>(this); }
662
663 const GT * const_me() const { return static_cast<const GT *>(this); }
664
665protected:
666 void *cookie = nullptr;
667 size_t num_nodes = 0;
668 size_t num_arcs = 0;
669 bool digraph = false;
670
671public:
672 using Node_Type = typename Node::Node_Type;
673 using Arc_Type = typename Arc::Arc_Type;
674
675protected:
676 void init() noexcept
677 {
678 num_nodes = num_arcs = 0;
679 cookie = nullptr;
680 digraph = false;
681 }
682
683 void common_swap(GT & g) noexcept
684 {
685 std::swap(num_nodes, g.num_nodes);
686 std::swap(num_arcs, g.num_arcs);
687 std::swap(digraph, g.digraph);
688 std::swap(cookie, g.cookie);
689 }
690
691public:
693 void *&get_cookie() noexcept { return cookie; }
694
696 void * get_cookie() const noexcept { return cookie; }
697
699 bool is_digraph() const noexcept { return digraph; }
700
734 void set_digraph(bool val) { digraph = val; } // TODO: delete after
735
737 [[nodiscard]] constexpr size_t get_num_nodes() const noexcept { return num_nodes; }
738
743 [[nodiscard]] constexpr bool is_empty() const noexcept { return num_nodes == 0; }
744
746 [[nodiscard]] constexpr size_t vsize() const noexcept { return get_num_nodes(); }
747
756 Node * get_node() const { return const_me()->get_first_node(); }
757
766 Node * get_arc() const { return const_me()->get_first_arc(); }
767
776 Node * get_arc(Node *p) { return const_me()->get_first_arc(p); }
777
779 Node * get_src_node(Arc *arc) const noexcept
780 {
781 return static_cast<Node *>(arc->src_node);
782 }
783
785 Node * get_tgt_node(Arc *arc) const noexcept
786 {
787 return static_cast<Node *>(arc->tgt_node);
788 }
789
820 Node * get_connected_node(Arc *arc, Node *node) const noexcept
821 {
822 return static_cast<Node *>(arc->get_connected_node(node));
823 }
824
826 [[nodiscard]] constexpr size_t get_num_arcs() const noexcept { return num_arcs; }
827
830 size_t get_num_arcs(Node *node) const noexcept
831 {
832 return node->num_arcs;
833 }
834
837 size_t degree(Node *p) const noexcept { return get_num_arcs(p); }
838
840 size_t esize() const noexcept { return get_num_arcs(); }
841
843 Bit_Fields &get_control_bits(Node *node) const noexcept
844 {
845 return NODE_BITS(node).reset();
846 }
847
849 void reset_bit(Node *node, int bit) const noexcept
850 {
851 NODE_BITS(node).reset(bit);
852 }
853
855 void reset_bits(Node *node) const noexcept
856 {
857 NODE_BITS(node).reset();
858 }
859
861 int get_bit(Node *node, int bit) const noexcept
862 {
863 return NODE_BITS(node).get_bit(bit);
864 }
865
867 void set_bit(Node *node, int bit, int value) const noexcept
868 {
869 NODE_BITS(node).set_bit(bit, value);
870 }
871
873 Bit_Fields &get_control_bits(Arc *arc) const noexcept
874 {
875 return ARC_BITS(arc);
876 }
877
879 void reset_bit(Arc *arc, int bit) const noexcept
880 {
881 ARC_BITS(arc).reset(bit);
882 }
883
885 void reset_bits(Arc *arc) const noexcept
886 {
887 ARC_BITS(arc).reset();
888 }
889
891 int get_bit(Arc *arc, int bit) const noexcept
892 {
893 return ARC_BITS(arc).get_bit(bit);
894 }
895
897 void set_bit(Arc *arc, int bit, int value) const noexcept
898 {
899 ARC_BITS(arc).set_bit(bit, value);
900 }
901
903 void *&get_cookie(Node *node) const noexcept
904 {
905 return NODE_COOKIE(node);
906 }
907
909 void *&get_cookie(Arc *arc) const noexcept
910 {
911 return ARC_COOKIE(arc);
912 }
913
915 long &get_counter(Node *node) const noexcept
916 {
917 return NODE_COUNTER(node);
918 }
919
921 void reset_counter(Node *node) const noexcept
922 {
923 NODE_COUNTER(node) = 0;
924 }
925
927 void reset_node_counters() const noexcept
928 {
929 for_each_node([this](auto p) { this->reset_counter(p); });
930 }
931
935 void reset_node(Node *p) const noexcept
936 {
937 p->attrs.reset();
938 }
939
941 long &get_counter(Arc *arc) const noexcept
942 {
943 return ARC_COUNTER(arc);
944 }
945
947 void reset_counter(Arc *arc) const noexcept
948 {
949 ARC_COUNTER(arc) = No_Visited;
950 }
951
953 void reset_arc_counters() const noexcept
954 {
955 for_each_arc([this](auto a) { this->reset_counter(a); });
956 }
957
961 void reset_arc(Arc *arc) const noexcept
962 {
963 arc->attrs.reset();
964 }
965
968 void reset_nodes() const
969 {
970 for_each_node([](auto p) { p->attrs.reset(); });
971 }
972
975 void reset_arcs() const
976 {
977 for_each_arc([](auto a) { a->attrs.reset(); });
978 }
979
1041 template <class N1, class N2 = N1>
1042 static
1043 void map_nodes(N1 *p, N2 *q) noexcept
1044 {
1045 assert(p != nullptr and q != nullptr);
1046 // Use reinterpret_cast to preserve exact pointer values without any
1047 // implicit base class pointer adjustment from multiple inheritance
1048 if (NODE_COOKIE(p) == nullptr)
1049 {
1050 NODE_COOKIE(p) = reinterpret_cast<void *>(q);
1051 NODE_COOKIE(q) = reinterpret_cast<void *>(p);
1052 return;
1053 }
1054 NODE_COOKIE(q) = NODE_COOKIE(p);
1055 NODE_COOKIE(p) = reinterpret_cast<void *>(q);
1056 }
1057
1072 template <class A1, class A2 = A1>
1073 static
1074 void map_arcs(A1 *p, A2 *q) noexcept
1075 {
1076 assert(p != nullptr and q != nullptr);
1077 if (ARC_COOKIE(p) == nullptr)
1078 {
1079 ARC_COOKIE(p) = q;
1080 ARC_COOKIE(q) = p;
1081 return;
1082 }
1083 ARC_COOKIE(q) = ARC_COOKIE(p);
1084 ARC_COOKIE(p) = q;
1085 }
1086
1088 void reset_bit_nodes(int bit) const noexcept
1089 {
1090 for_each_node([bit, this](auto p) { this->reset_bit(p, bit); });
1091 }
1092
1094 void reset_bit_arcs(int bit) const noexcept
1095 {
1096 for_each_arc([bit, this](auto a) { this->reset_bit(a, bit); });
1097 }
1098
1100 void reset_bit_nodes() const noexcept
1101 {
1102 for_each_node([this](auto p) { this->reset_bits(p); });
1103 }
1104
1106 void reset_bit_arcs() const noexcept
1107 {
1108 for_each_arc([this](auto a) { this->reset_bits(a); });
1109 }
1110
1112 void reset_counter_nodes() const noexcept
1113 {
1114 for_each_node([this](auto p) { this->reset_counter(p); });
1115 }
1116
1118 void reset_counter_arcs() const noexcept
1119 {
1120 for_each_arc([this](auto a) { this->reset_counter(a); });
1121 }
1122
1129 void reset_cookie_nodes() const noexcept
1130 {
1131 for_each_node([](auto p) { NODE_COOKIE(p) = nullptr; });
1132 }
1133
1140 void reset_cookie_arcs() const noexcept
1141 {
1142 for_each_arc([](auto a) { ARC_COOKIE(a) = nullptr; });
1143 }
1144
1164 Node * insert_node(const Node_Type & node_info)
1165 {
1166 return me()->insert_node(new Node(node_info));
1167 }
1168
1189 {
1190 return me()->insert_node(new Node(std::forward<Node_Type>(node_info)));
1191 }
1192
1213 template <typename... Args>
1214 Node * emplace_node(Args &&... args)
1215 {
1216 return me()->insert_node(Node_Type(args...));
1217 }
1218
1241 Arc * insert_arc(Node *src, Node *tgt, const Arc_Type & arc_info)
1242 {
1243 std::unique_ptr<Arc> arc(new Arc(arc_info));
1244 me()->insert_arc(src, tgt, arc.get());
1245 return arc.release();
1246 }
1247
1271 Arc * insert_arc(Node *src, Node *tgt, Arc_Type && arc_info = Arc_Type())
1272 {
1273 std::unique_ptr<Arc> arc(new Arc(std::forward<Arc_Type>(arc_info)));
1274 me()->insert_arc(src, tgt, arc.get());
1275 return arc.release();
1276 }
1277
1299 template <typename... Args>
1300 Arc * emplace_arc(Node *src, Node *tgt, Args &&... args)
1301 {
1302 return me()->insert_arc(src, tgt, Arc_Type(args...));
1303 }
1304
1351 template <class Operation>
1353 bool traverse_nodes(Operation & op) const
1354 {
1355 for (typename GT::Node_Iterator it(*const_me()); it.has_curr(); it.next_ne())
1356 if (not op(it.get_curr()))
1357 return false;
1358 return true;
1359 }
1360
1362 template <class Operation>
1364 bool traverse_nodes(Operation && op = Operation()) const
1365 {
1366 return traverse_nodes(op);
1367 }
1368
1418 template <class Operation>
1420 bool traverse_arcs(Operation & op) const
1421 {
1422 for (typename GT::Arc_Iterator it(*const_me()); it.has_curr(); it.next_ne())
1423 if (not op(it.get_curr()))
1424 return false;
1425 return true;
1426 }
1427
1429 template <class Operation>
1431 bool traverse_arcs(Operation && op = Operation()) const
1432 {
1433 return traverse_arcs(op);
1434 }
1435
1487 template <class Operation>
1489 bool traverse_arcs(Node *p, Operation & op) const
1490 {
1491 for (typename GT::Node_Arc_Iterator it(p); it.has_curr(); it.next_ne())
1492 if (not op(it.get_curr()))
1493 return false;
1494 return true;
1495 }
1496
1498 template <class Operation>
1500 bool traverse_arcs(Node *p, Operation && op = Operation()) const
1501 {
1502 return traverse_arcs(p, op);
1503 }
1504
1529 template <class Operation>
1531 void for_each_node(Operation & operation) const
1532 {
1533 for (typename GT::Node_Iterator it(*const_me()); it.has_curr(); it.next_ne())
1534 operation(it.get_curr());
1535 }
1536
1538 template <class Operation>
1540 void for_each_node(Operation && operation = Operation()) const
1541 {
1542 for_each_node(operation);
1543 }
1544
1569 template <class Operation>
1571 void for_each_arc(Operation & op) const
1572 {
1573 for (typename GT::Arc_Iterator it(*const_me()); it.has_curr(); it.next_ne())
1574 op(it.get_curr());
1575 }
1576
1578 template <class Operation>
1580 void for_each_arc(Operation && operation = Operation()) const
1581 {
1582 for_each_arc(operation);
1583 }
1584
1618 template <class Operation>
1620 void for_each_arc(Node *p, Operation & op) const
1621 {
1622 for (typename GT::Node_Arc_Iterator it(p); it.has_curr(); it.next_ne())
1623 op(it.get_curr());
1624 }
1625
1627 template <class Operation>
1629 void for_each_arc(Node *p, Operation && op = Operation()) const
1630 {
1631 for_each_arc(p, op);
1632 }
1633
1663 template <class Operation>
1665 bool all_nodes(Operation & op) const
1666 {
1667 return traverse_nodes(op);
1668 }
1669
1671 template <class Operation>
1673 bool all_nodes(Operation && op = Operation()) const
1674 {
1675 return all_nodes(op);
1676 }
1677
1707 template <class Operation>
1709 bool all_arcs(Operation & op) const
1710 {
1711 return traverse_arcs(op);
1712 }
1713
1715 template <class Operation>
1717 bool all_arcs(Operation && op = Operation()) const
1718 {
1719 return all_arcs(op);
1720 }
1721
1754 template <class Operation>
1756 bool all_arcs(Node *p, Operation & op) const
1757 {
1758 return traverse_arcs(p, op);
1759 }
1760
1762 template <class Operation>
1764 bool all_arcs(Node *p, Operation && op = Operation()) const
1765 {
1766 return all_arcs(p, op);
1767 }
1768
1808 template <typename T = Node_Type, class Op>
1809 requires std::is_invocable_r_v<T, Op &, Node *>
1810 auto nodes_map(Op op) const
1811 {
1812 DynList<T> ret_val;
1813 for_each_node([&ret_val, &op](Node *p) { ret_val.append(Aleph::concepts_detail::invoke_as<T(Node *)>::call(op, p)); });
1814 return ret_val;
1815 }
1816
1856 template <typename T = Arc_Type, class Op>
1857 requires std::is_invocable_r_v<T, Op &, Arc *>
1858 auto arcs_map(Op operation) const
1859 {
1860 DynList<T> ret_val;
1861 for_each_arc([&ret_val, &operation](Arc *p)
1862 {
1863 ret_val.append(Aleph::concepts_detail::invoke_as<T(Arc *)>::call(operation, p));
1864 });
1865 return ret_val;
1866 }
1867
1908 template <typename T = Arc_Type, class Op>
1909 requires std::is_invocable_r_v<T, Op &, Arc *>
1910 auto arcs_map(Node *p, Op operation) const
1911 {
1912 DynList<T> ret_val;
1913 for_each_arc(p, [&ret_val, &operation](Arc *a)
1914 {
1915 ret_val.append(Aleph::concepts_detail::invoke_as<T(Arc *)>::call(operation, a));
1916 });
1917 return ret_val;
1918 }
1919
1954 template <typename T = Node_Type, class Op>
1955 requires std::is_invocable_r_v<T, Op &, const T &, Node *>
1956 T foldl_nodes(const T & init,
1957 Op op) const
1958 {
1959 T ret = init;
1960 for_each_node([&ret, &op](Node *p) { ret = Aleph::concepts_detail::invoke_as<T(const T &, Node *)>::call(op, ret, p); });
1961 return ret;
1962 }
1963
1997 template <typename T = Arc_Type, class Op>
1998 requires std::is_invocable_r_v<T, Op &, const T &, Arc *>
1999 T foldl_arcs(const T & init,
2000 Op op) const
2001 {
2002 T ret = init;
2003 for_each_arc([&ret, &op](Arc *p) { ret = Aleph::concepts_detail::invoke_as<T(const T &, Arc *)>::call(op, ret, p); });
2004 return ret;
2005 }
2006
2041 template <typename T = Arc_Type, class Op>
2042 requires std::is_invocable_r_v<T, Op &, const T &, Arc *>
2043 T foldl_arcs(Node *p, const T & init,
2044 Op op) const
2045 {
2046 T ret = init;
2047 for_each_arc(p, [&ret, &op](Arc *a) { ret = Aleph::concepts_detail::invoke_as<T(const T &, Arc *)>::call(op, ret, a); });
2048 return ret;
2049 }
2050
2072 template <class Op>
2074 auto filter_nodes(Op & op) const
2075 {
2076 DynList<Node *> ret;
2077 for_each_node([&ret, &op](Node *p)
2078 {
2079 if (op(p))
2080 ret.append(p);
2081 });
2082 return ret;
2083 }
2084
2086 template <class Op>
2088 auto filter_nodes(Op && op) const
2089 {
2090 return filter_nodes(op);
2091 }
2092
2114 template <class Op>
2116 auto filter_arcs(Op & op) const
2117 {
2118 DynList<Arc *> ret;
2119 for_each_arc([&ret, &op](Arc *a)
2120 {
2121 if (op(a))
2122 ret.append(a);
2123 });
2124 return ret;
2125 }
2126
2128 template <class Op>
2130 auto filter_arcs(Op && op) const
2131 {
2132 return filter_arcs(op);
2133 }
2134
2165 template <class Op>
2167 auto filter_arcs(Node *p, Op & op) const
2168 {
2169 DynList<Arc *> ret;
2170 for_each_arc(p, [&ret, &op](Arc *a)
2171 {
2172 if (op(a))
2173 ret.append(a);
2174 });
2175 return ret;
2176 }
2177
2179 template <class Op>
2181 auto filter_arcs(Node *p, Op && op) const
2182 {
2183 return filter_arcs(p, op);
2184 }
2185
2204 template <class Operation>
2206 bool exists_node(Operation & op) const
2207 {
2208 return not traverse_nodes([&op](Node *p) { return not op(p); });
2209 }
2210
2212 template <class Operation>
2214 bool exists_node(Operation && op = Operation()) const
2215 {
2216 return exists_node(op);
2217 }
2218
2237 template <class Operation>
2239 bool exists_arc(Operation & op) const
2240 {
2241 return not traverse_arcs([&op](Arc *a) { return not op(a); });
2242 }
2243
2245 template <class Operation>
2247 bool exists_arc(Operation && op = Operation()) const
2248 {
2249 return exists_arc(op);
2250 }
2251
2274 template <class Operation>
2276 bool exists_arc(Node *p, Operation & op) const
2277 {
2278 return not traverse_arcs(p, [&op](Arc *a) { return not op(a); });
2279 }
2280
2282 template <class Operation>
2284 bool exists_arc(Node *p, Operation && op = Operation()) const
2285 {
2286 return exists_arc(p, op);
2287 }
2288
2303 template <class Operation>
2305 bool none_node(Operation & op) const
2306 {
2307 return not exists_node(op);
2308 }
2309
2311 template <class Operation>
2313 bool none_node(Operation && op) const
2314 {
2315 return none_node(op);
2316 }
2317
2332 template <class Operation>
2334 bool none_arc(Operation & op) const
2335 {
2336 return not exists_arc(op);
2337 }
2338
2340 template <class Operation>
2342 bool none_arc(Operation && op) const
2343 {
2344 return none_arc(op);
2345 }
2346
2354 template <class Operation>
2356 bool none_arc(Node *p, Operation & op) const
2357 {
2358 return not exists_arc(p, op);
2359 }
2360
2362 template <class Operation>
2364 bool none_arc(Node *p, Operation && op) const
2365 {
2366 return none_arc(p, op);
2367 }
2368
2385 template <class Operation = std::function<bool(Node*)>>
2387 size_t count_nodes(Operation op = [](Node*) { return true; }) const
2388 {
2389 size_t count = 0;
2390 for_each_node([&count, &op](Node *p) { if (op(p)) ++count; });
2391 return count;
2392 }
2393
2410 template <class Operation = std::function<bool(Arc*)>>
2412 size_t count_arcs(Operation op = [](Arc*) { return true; }) const
2413 {
2414 size_t count = 0;
2415 for_each_arc([&count, &op](Arc *a) { if (op(a)) ++count; });
2416 return count;
2417 }
2418
2425 template <class Operation = std::function<bool(Arc*)>>
2427 size_t count_arcs(Node *p, Operation op = [](Arc*) { return true; }) const
2428 {
2429 size_t count = 0;
2430 for_each_arc(p, [&count, &op](Arc *a) { if (op(a)) ++count; });
2431 return count;
2432 }
2433
2450 template <typename T = double, class Extract>
2451 requires requires(T &sum, Extract &extract, Arc *a) { sum += extract(a); }
2452 T sum_arcs(Node *p, Extract extract) const
2453 {
2454 T sum = T{0};
2455 for_each_arc(p, [&sum, &extract](Arc *a) { sum += extract(a); });
2456 return sum;
2457 }
2458
2460 template <typename T = double>
2461 T sum_arcs(Node *p) const
2462 {
2463 T sum = T{0};
2464 for_each_arc(p, [&sum](Arc *a) { sum += static_cast<T>(a->get_info()); });
2465 return sum;
2466 }
2467
2483 template <class Compare = std::function<bool(Arc*, Arc*)>>
2485 Arc* min_arc(Node *p, Compare cmp = [](Arc *a, Arc *b) {
2486 return a->get_info() < b->get_info();
2487 }) const
2488 {
2489 Arc* result = nullptr;
2490 for_each_arc(p, [&result, &cmp](Arc *a) {
2491 if (result == nullptr or cmp(a, result))
2492 result = a;
2493 });
2494 return result;
2495 }
2496
2512 template <class Compare = std::function<bool(Arc*, Arc*)>>
2514 Arc* max_arc(Node *p, Compare cmp = [](Arc *a, Arc *b) {
2515 return a->get_info() < b->get_info();
2516 }) const
2517 {
2518 Arc* result = nullptr;
2519 for_each_arc(p, [&result, &cmp](Arc *a) {
2520 if (result == nullptr or cmp(result, a))
2521 result = a;
2522 });
2523 return result;
2524 }
2525
2531 template <class Compare = std::function<bool(Arc*, Arc*)>>
2533 Arc* min_arc(Compare cmp = [](Arc *a, Arc *b) {
2534 return a->get_info() < b->get_info();
2535 }) const
2536 {
2537 Arc* result = nullptr;
2538 for_each_arc([&result, &cmp](Arc *a) {
2539 if (result == nullptr or cmp(a, result))
2540 result = a;
2541 });
2542 return result;
2543 }
2544
2550 template <class Compare = std::function<bool(Arc*, Arc*)>>
2552 Arc* max_arc(Compare cmp = [](Arc *a, Arc *b) {
2553 return a->get_info() < b->get_info();
2554 }) const
2555 {
2556 Arc* result = nullptr;
2557 for_each_arc([&result, &cmp](Arc *a) {
2558 if (result == nullptr or cmp(result, a))
2559 result = a;
2560 });
2561 return result;
2562 }
2563
2579 template <class Operation>
2581 std::pair<DynList<Node*>, DynList<Node*>> partition_nodes(Operation op) const
2582 {
2583 DynList<Node*> yes, no;
2584 for_each_node([&yes, &no, &op](Node *p) {
2585 if (op(p))
2586 yes.append(p);
2587 else
2588 no.append(p);
2589 });
2590 return {std::move(yes), std::move(no)};
2591 }
2592
2603 template <class Operation>
2605 std::pair<DynList<Arc*>, DynList<Arc*>> partition_arcs(Operation op) const
2606 {
2607 DynList<Arc*> yes, no;
2608 for_each_arc([&yes, &no, &op](Arc *a) {
2609 if (op(a))
2610 yes.append(a);
2611 else
2612 no.append(a);
2613 });
2614 return {std::move(yes), std::move(no)};
2615 }
2616
2630 DynList<Node*> adjacent_nodes(Node *p) const
2631 {
2632 DynList<Node*> result;
2633 for_each_arc(p, [this, p, &result](Arc *a) {
2634 result.append(get_connected_node(a, p));
2635 });
2636 return result;
2637 }
2638
2655 template <class Op>
2657 Node * search_node(Op & op) const
2658 {
2659 for (typename GT::Node_Iterator it(*const_me()); it.has_curr(); it.next_ne())
2660 {
2661 auto p = it.get_curr();
2662 if (op(p))
2663 return p;
2664 }
2665 return nullptr;
2666 }
2667
2669 template <class Op>
2671 Node * search_node(Op && op) const
2672 {
2673 return search_node(op);
2674 }
2675
2687 Node * find_node(const Node_Type & info) const noexcept
2688 {
2689 return search_node([&info](auto p) { return p->get_info() == info; });
2690 }
2691
2708 template <class Op>
2710 Arc * search_arc(Op & op) const
2711 {
2712 for (typename GT::Arc_Iterator it(*const_me()); it.has_curr(); it.next_ne())
2713 {
2714 auto a = it.get_curr();
2715 if (op(a))
2716 return a;
2717 }
2718 return nullptr;
2719 }
2720
2722 template <class Op>
2724 Arc * search_arc(Op && op) const
2725 {
2726 return search_arc(op);
2727 }
2728
2740 Arc * find_arc(const Arc_Type & info) const noexcept
2741 {
2742 return search_arc([&info](auto a) { return a->get_info() == info; });
2743 }
2744
2763 template <class Operation>
2765 Arc * search_arc(Node *p, Operation & op) const
2766 {
2767 for (typename GT::Node_Arc_Iterator it(p); it.has_curr(); it.next_ne())
2768 {
2769 Arc *arc = it.get_curr();
2770 if (op(arc))
2771 return arc;
2772 }
2773 return nullptr;
2774 }
2775
2777 template <class Operation>
2779 Arc * search_arc(Node *p, Operation && op = Operation()) const
2780 {
2781 return search_arc(p, op);
2782 }
2783
2807 Arc * search_arc(Node *src, Node *tgt) const noexcept
2808 {
2809 for (typename GT::Node_Arc_Iterator it(src); it.has_curr(); it.next_ne())
2810 if (it.get_tgt_node_ne() == tgt)
2811 return it.get_curr();
2812 return nullptr;
2813 }
2814
2825 template <template <typename> class Container = Aleph::DynList>
2827 {
2829 for_each_node([&ret](Node *p) { ret.append(p); });
2830 return ret;
2831 }
2832
2843 template <template <typename> class Container = Aleph::DynList>
2845 {
2846 Container<Arc *> ret;
2847 for_each_arc([&ret](Arc *a) { ret.append(a); });
2848 return ret;
2849 }
2850
2861 template <template <typename> class Container = Aleph::DynList>
2863 {
2864 Container<Arc *> ret;
2865 this->for_each_arc(p, [&ret](Arc *a) { ret.append(a); });
2866 return ret;
2867 }
2868
2886 auto get_node_it() const noexcept
2887 {
2888 return typename GT::Node_Iterator(*const_me());
2889 }
2890
2908 auto get_arc_it() const noexcept
2909 {
2910 return typename GT::Arc_Iterator(*const_me());
2911 }
2912
2931 auto get_arc_it(Node *p) const noexcept
2932 {
2933 return typename GT::Node_Arc_Iterator(p);
2934 }
2935
2968 struct In_Filt
2969 {
2970 Node *tgt = nullptr;
2971
2973 In_Filt(Node *__tgt = nullptr) noexcept : tgt(__tgt)
2974 { /* empty */
2975 }
2976
2979 bool operator ()(Arc *a) const noexcept
2980 {
2981 assert(tgt);
2982 return a->tgt_node == tgt;
2983 }
2984
2986 Node * get_node(Arc *a) const noexcept
2987 {
2988 assert(tgt);
2989 return (typename GT::Node *) a->src_node;
2990 }
2991 };
2992
3026 {
3027 Node *src = nullptr;
3028
3030 Out_Filt(Node *__src) noexcept : src(__src)
3031 { /* empty */
3032 }
3033
3036 bool operator ()(Arc *a) const noexcept
3037 {
3038 assert(src);
3039 return a->src_node == src;
3040 }
3041
3043 Node * get_node(Arc *a) const noexcept
3044 {
3045 assert(src);
3046 return (Node *) a->tgt_node;
3047 }
3048 };
3049
3075 template <class Filter>
3077 {
3078 using Itor = Filter_Iterator<Node *, typename GT::Node_Arc_Iterator, Filter>;
3079
3080 Filter filt;
3082
3083 public:
3084 using Item_Type = typename Itor::Item_Type;
3085
3087
3090 {
3091 // empty
3092 }
3093
3094 void next_ne() noexcept { it.next_ne(); }
3095
3098 void next() { it.next(); }
3099
3102 void prev() { it.prev(); }
3103
3104 void prev_ne() { it.prev_ne(); }
3105
3107 bool has_curr() const noexcept { return it.has_curr(); }
3108
3111 typename GT::Arc * get_curr() const { return it.get_curr(); }
3112
3113 typename GT::Arc * get_curr_ne() const noexcept { return it.get_curr_ne(); }
3114
3116 auto get_current_arc() const { return get_curr(); }
3117
3118 auto get_current_arc_ne() const noexcept { return get_curr_ne(); }
3119
3122 typename GT::Node * get_node(typename GT::Arc *a) const noexcept
3123 {
3124 return filt.get_node(a);
3125 }
3126
3129 typename GT::Node * get_node_ne() const noexcept
3130 {
3131 return this->get_node(this->get_curr_ne());
3132 }
3133
3135 auto get_tgt_node_ne() const noexcept { return get_node_ne(); }
3136
3137 typename GT::Node * get_node() const
3138 {
3139 return this->get_node(this->get_curr());
3140 }
3141
3143 auto get_tgt_node() const { return get_node(); }
3144
3146 void reset_first() noexcept { it.reset_first(); }
3147
3149 void reset_last() noexcept { it.reset_last(); }
3150 };
3151
3153 // template <class Filt> using Filter_Iterator = Digraph_Iterator<Filt>;
3154
3155 // /** Iterator on incoming arcs of node */
3157 {
3158 using Digraph_Iterator<In_Filt>::Digraph_Iterator;
3159 };
3160
3161 // /** Iterator on incoming arcs of node */
3163 {
3164 using Digraph_Iterator<Out_Filt>::Digraph_Iterator;
3165 };
3166
3185 In_Iterator get_in_it(Node *p) const noexcept { return In_Iterator(p); }
3186
3205 Out_Iterator get_out_it(Node *p) const noexcept { return Out_Iterator(p); }
3206
3217 Arc * search_directed_arc(Node *src, Node *tgt) const noexcept
3218 {
3219 for (typename GT::Out_Iterator it(src); it.has_curr(); it.next_ne())
3220 if (it.get_tgt_node() == tgt)
3221 return it.get_curr();
3222 return nullptr;
3223 }
3224
3235 DynList<Node *> in_nodes(Node *p) const
3236 {
3237 DynList<Node *> ret;
3238 for (In_Iterator it(p); it.has_curr(); it.next_ne())
3239 ret.append(it.get_node());
3240 return ret;
3241 }
3242
3253 DynList<Node *> out_nodes(Node *p) const
3254 {
3255 DynList<Node *> ret;
3256 for (Out_Iterator it(p); it.has_curr(); it.next_ne())
3257 ret.append(it.get_node_ne());
3258 return ret;
3259 }
3260
3270 DynList<Arc *> out_arcs(Node *p) const
3271 {
3272 DynList<Arc *> ret;
3273 for (Out_Iterator it(p); it.has_curr(); it.next_ne())
3274 ret.append(it.get_curr());
3275 return ret;
3276 }
3277
3286 DynList<Arc *> in_arcs(Node *p) const
3287 {
3288 DynList<Arc *> ret;
3289 for (In_Iterator it(p); it.has_curr(); it.next_ne())
3290 ret.append(it.get_curr());
3291 return ret;
3292 }
3293
3295 using ArcPair = std::tuple<Arc *, Node *>;
3296
3309 auto in_pairs(Node *p) const
3310 {
3311 DynList<ArcPair> ret;
3312 for (In_Iterator it(p); it.has_curr(); it.next_ne())
3313 {
3314 auto a = it.get_curr();
3315 ret.append(std::make_tuple(a, (Node *) a->get_connected_node(p)));
3316 }
3317 return ret;
3318 }
3319
3332 auto out_pairs(Node *p) const
3333 {
3334 DynList<ArcPair> ret;
3335 for (Out_Iterator it(p); it.has_curr(); it.next_ne())
3336 {
3337 auto a = it.get_curr();
3338 ret.append(std::make_tuple(a, (Node *) a->get_connected_node(p)));
3339 }
3340 return ret;
3341 }
3342
3356 size_t in_degree(Node *p) const noexcept
3357 {
3358 size_t count = 0;
3359 for (In_Iterator it(p); it.has_curr(); it.next_ne())
3360 ++count;
3361 return count;
3362 }
3363
3379 size_t out_degree(Node *p) const noexcept
3380 {
3381 size_t count = 0;
3382 for (Out_Iterator it(p); it.has_curr(); it.next_ne())
3383 ++count;
3384 return count;
3385 }
3386
3405 template <class Itor, class Operation>
3407 bool traverse_arcs(Node *p, Operation & op) const
3408 {
3409 for (Itor it(p); it.has_curr(); it.next_ne())
3410 if (not op(it.get_curr()))
3411 return false;
3412 return true;
3413 }
3414
3416 template <class Itor, class Operation>
3418 void for_each_arc(Node *p, Operation & op) const
3419 {
3420 for (Itor it(p); it.has_curr(); it.next_ne())
3421 op(it.get_curr());
3422 }
3423
3426 template <class Op>
3427 bool traverse_in_arcs(Node *p, Op & op) const
3428 {
3429 return traverse_arcs<In_Iterator, Op>(p, op);
3430 }
3431
3433 template <class Op>
3434 bool traverse_in_arcs(Node *p, Op && op = Op()) const
3435 {
3436 return traverse_in_arcs(p, op);
3437 }
3438
3440 template <class Op>
3441 void for_each_in_arc(Node *p, Op & op) const
3442 {
3443 for_each_arc<In_Iterator>(p, op);
3444 }
3445
3447 template <class Op>
3448 void for_each_in_arc(Node *p, Op && op = Op()) const
3449 {
3450 for_each_in_arc(p, op);
3451 }
3452
3454 template <class Op>
3455 bool all_in_arcs(Node *p, Op & op) const
3456 {
3457 return traverse_in_arcs(p, [&op](auto a) { return op(a); });
3458 }
3459
3461 template <class Op>
3462 bool all_in_arcs(Node *p, Op && op = Op()) const
3463 {
3464 return all_in_arcs(p, op);
3465 }
3466
3469 template <class Op>
3470 bool exists_in_arc(Node *p, Op & op) const
3471 {
3472 return not traverse_in_arcs(p, [&op](auto a) { return not op(a); });
3473 }
3474
3476 template <class Op>
3477 bool exists_in_arc(Node *p, Op && op = Op()) const
3478 {
3479 return exists_in_arc(p, op);
3480 }
3481
3495 template <class Op>
3496 auto search_in_arc(Node *p, Op & op) const
3497 {
3498 Arc *ret = nullptr;
3499 traverse_in_arcs(p, [&op, &ret](auto a)
3500 {
3501 if (op(a))
3502 {
3503 ret = a;
3504 return false;
3505 }
3506 return true;
3507 });
3508 return ret;
3509 }
3510
3512 template <class Op>
3513 auto search_in_arc(Node *p, Op && op = Op()) const
3514 {
3515 return search_in_arc(p, op);
3516 }
3517
3526 template <typename T, class Op>
3527 requires std::is_invocable_r_v<T, Op &, Arc *>
3528 auto in_arcs_map(Node *p, Op op) const
3529 {
3530 DynList<T> ret;
3531 for_each_in_arc(p, [&ret, &op](auto a) { ret.append(Aleph::concepts_detail::invoke_as<T(Arc *)>::call(op, a)); });
3532 return ret;
3533 }
3534
3542 template <typename T = Arc_Type, class Op>
3543 requires std::is_invocable_r_v<T, Op &, const T &, Arc *>
3544 T foldl_in_arcs(Node *p, const T & init,
3545 Op op) const
3546 {
3547 T ret = init;
3548 for_each_in_arc(p, [&ret, &op](auto a) { ret = Aleph::concepts_detail::invoke_as<T(const T &, Arc *)>::call(op, ret, a); });
3549 return ret;
3550 }
3551
3559 template <class Op>
3560 DynList<Arc *> filter_in_arcs(Node *p, Op & op) const
3561 {
3562 DynList<Arc *> ret;
3563 for_each_in_arc(p, [&ret, &op](auto a)
3564 {
3565 if (op(a))
3566 ret.append(a);
3567 });
3568 return ret;
3569 }
3570
3572 template <class Op>
3573 auto filter_in_arcs(Node *p, Op && op = Op()) const
3574 {
3575 return filter_in_arcs(p, op);
3576 }
3577
3580 template <class Op>
3581 bool traverse_out_arcs(Node *p, Op & op) const
3582 {
3583 return traverse_arcs<Out_Iterator>(p, op);
3584 }
3585
3587 template <class Op>
3588 bool traverse_out_arcs(Node *p, Op && op = Op()) const
3589 {
3590 return traverse_out_arcs(p, op);
3591 }
3592
3594 template <class Op>
3595 void for_each_out_arc(Node *p, Op & op) const
3596 {
3597 for_each_arc<Out_Iterator>(p, op);
3598 }
3599
3601 template <class Op>
3602 void for_each_out_arc(Node *p, Op && op = Op()) const
3603 {
3604 for_each_out_arc(p, op);
3605 }
3606
3608 template <class Op>
3609 bool all_out_arcs(Node *p, Op & op) const
3610 {
3611 return traverse_out_arcs(p, [&op](auto a) { return op(a); });
3612 }
3613
3615 template <class Op>
3616 bool all_out_arcs(Node *p, Op && op = Op()) const
3617 {
3618 return all_out_arcs(p, op);
3619 }
3620
3623 template <class Op>
3624 bool exists_out_arc(Node *p, Op & op) const
3625 {
3626 return not traverse_out_arcs(p, [&op](auto a) { return not op(a); });
3627 }
3628
3630 template <class Op>
3631 bool exists_out_arc(Node *p, Op && op = Op()) const
3632 {
3633 return exists_out_arc(p, op);
3634 }
3635
3649 template <class Op>
3650 auto search_out_arc(Node *p, Op & op) const
3651 {
3652 typename GT::Arc *ret = nullptr;
3653 traverse_out_arcs(p, [&op, &ret](auto a)
3654 {
3655 if (op(a))
3656 {
3657 ret = a;
3658 return false;
3659 }
3660 return true;
3661 });
3662 return ret;
3663 }
3664
3666 template <class Op>
3667 auto search_out_arc(Node *p, Op && op = Op()) const
3668 {
3669 return search_out_arc(p, op);
3670 }
3671
3680 template <typename T = Arc_Type, class Op>
3681 requires std::is_invocable_r_v<T, Op &, Arc *>
3682 auto out_arcs_map(Node *p, Op op) const
3683 {
3684 DynList<T> ret;
3685 for_each_out_arc(p, [&ret, &op](auto a) { ret.append(Aleph::concepts_detail::invoke_as<T(Arc *)>::call(op, a)); });
3686 return ret;
3687 }
3688
3690 template <typename T = Arc_Type, class Op>
3691 requires std::is_invocable_r_v<T, Op &, const T &, Arc *>
3692 T foldl_out_arcs(Node *p, const T & init,
3693 Op op) const
3694 {
3695 T ret = init;
3696 for_each_out_arc(p, [&ret, &op](auto a) { ret = Aleph::concepts_detail::invoke_as<T(const T &, Arc *)>::call(op, ret, a); });
3697 return ret;
3698 }
3699
3707 template <class Op>
3708 DynList<Arc *> filter_out_arcs(Node *p, Op & op) const
3709 {
3710 DynList<Arc *> ret;
3711 for_each_out_arc(p, [&ret, &op](auto a)
3712 {
3713 if (op(a))
3714 ret.append(a);
3715 });
3716 return ret;
3717 }
3718
3720 template <class Op>
3721 auto filter_out_arcs(Node *p, Op && op = Op()) const
3722 {
3723 return filter_out_arcs(p, op);
3724 }
3725
3726 // ===========================================================================
3727 // Arc Removal Helpers (protected, for use in remove_node implementations)
3728 // ===========================================================================
3729
3730protected:
3745 template <class Predicate>
3746 DynList<Arc*> collect_arcs_if(Predicate pred) const
3747 {
3748 DynList<Arc*> result;
3749 for (typename GT::Arc_Iterator it(*const_me()); it.has_curr(); it.next_ne())
3750 if (pred(it.get_curr_ne()))
3751 result.append(it.get_curr_ne());
3752 return result;
3753 }
3754
3776 template <class Predicate>
3777 void remove_arcs_if(Predicate pred)
3778 {
3779 collect_arcs_if(pred).for_each([this](auto a) { me()->remove_arc(a); });
3780 }
3781
3782public:
3783 // ===========================================================================
3784 // Sorting Methods (for Dlink-based graphs)
3785 // ===========================================================================
3786
3805 template <class U>
3806 static constexpr bool has_node_dlink_v =
3807 requires(U & u) { { u.get_node_dlink() } -> std::same_as<Dlink&>; };
3808
3809 template <class U>
3810 static constexpr bool has_arc_dlink_v =
3811 requires(U & u) { { u.get_arc_dlink() } -> std::same_as<Dlink&>; };
3812
3813 template <class Compare>
3814 void sort_nodes(Compare & cmp) noexcept
3815 requires(has_node_dlink_v<GT>)
3816 {
3818 mergesort(me()->get_node_dlink(), c);
3819 }
3820
3822 template <class Compare>
3823 void sort_nodes(Compare && cmp = Compare()) noexcept
3824 requires(has_node_dlink_v<GT>)
3825 {
3826 sort_nodes(cmp);
3827 }
3828
3847 template <class Compare>
3848 void sort_arcs(Compare & cmp) noexcept
3849 requires(has_arc_dlink_v<GT>)
3850 {
3852 mergesort(me()->get_arc_dlink(), c);
3853 }
3854
3856 template <class Compare>
3857 void sort_arcs(Compare && cmp = Compare()) noexcept
3858 requires(has_arc_dlink_v<GT>)
3859 {
3860 sort_arcs(cmp);
3861 }
3862};
3863
3864
3865// ============================================================================
3866// Macro for Copy/Move/Swap Pattern
3867// ============================================================================
3868
3898#define ALEPH_GRAPH_COPY_MOVE_CTORS(GraphClass) \
3899 \
3900 GraphClass(const GraphClass & g) \
3901 { \
3902 copy_graph(*this, g); \
3903 } \
3904 \
3905 \
3906 GraphClass(GraphClass && g) noexcept \
3907 { \
3908 swap(g); \
3909 } \
3910 \
3911 \
3912 GraphClass & operator=(const GraphClass & g) \
3913 { \
3914 if (this == &g) \
3915 return *this; \
3916 copy_graph(*this, g); \
3917 return *this; \
3918 } \
3919 \
3920 \
3921 GraphClass & operator=(GraphClass && g) noexcept \
3922 { \
3923 swap(g); \
3924 return *this; \
3925 }
3926
3927
3928namespace Aleph
3929{
3930
3958template <class BaseGraph>
3959class Digraph : public BaseGraph
3960{
3961public:
3962 using GT = BaseGraph;
3963 using Node = typename BaseGraph::Node;
3964 using Arc = typename BaseGraph::Arc;
3965
3971 {
3972 this->digraph = true;
3973 }
3974
3982 Digraph(const Digraph & dg) : GT()
3983 {
3984 this->digraph = true;
3985 copy_graph(*this, dg, false);
3986 }
3987
3996 {
3997 this->digraph = true;
3998 this->swap(dg);
3999 }
4000
4010 {
4011 if (this == &g)
4012 return *this;
4013
4014 this->digraph = true;
4015 copy_graph(*this, g, false);
4016
4017 return *this;
4018 }
4019
4028 Digraph & operator = (Digraph && g) noexcept
4029 {
4030 this->digraph = true;
4031 this->swap(g);
4032
4033 return *this;
4034 }
4035};
4036
4037} // namespace Aleph
4038
4039
4040# endif // GRAPH_DRY_H
C++20 concepts hub: comparison, BST policy, and Aleph container concepts.
WeightedDigraph::Node Node
WeightedDigraph::Arc Arc
List_Graph< Graph_Node< Node_Info >, Graph_Arc< Arc_Info > > GT
size_t size_t int32_t value
Definition ca-c-api.h:116
Generic directed graph (digraph) wrapper template.
Definition graph-dry.H:3960
Digraph(const Digraph &dg)
Copy constructor.
Definition graph-dry.H:3982
Digraph(Digraph &&dg) noexcept
Move constructor.
Definition graph-dry.H:3995
Digraph & operator=(const Digraph &g)
Copy assignment operator.
Definition graph-dry.H:4009
typename BaseGraph::Arc Arc
Definition graph-dry.H:3964
typename BaseGraph::Node Node
Definition graph-dry.H:3963
Digraph() noexcept
Default constructor.
Definition graph-dry.H:3970
BaseGraph GT
Definition graph-dry.H:3962
Doubly-linked list (defined in tpl_dynList.H).
Definition htlist.H:1155
T & append(const T &item)
Definition htlist.H:1271
Generic filter iterator wrapper.
void next()
Advances the iterator to the next filtered element.
void next_ne() noexcept
Advances the iterator to the next filtered element (noexcept version).
void reset_first()
Resets the iterator to the first filtered element.
Node * get_first_node() const
Return any node in the graph.
Definition tpl_graph.H:577
Arc * get_first_arc(Node *node) const
Return any arc adjacent to a node.
Definition tpl_graph.H:596
virtual Node * insert_node(Node *node) noexcept
Insertion of a node already allocated.
Definition tpl_graph.H:525
virtual void remove_arc(Arc *arc) noexcept
Remove an arc from the graph and free it.
Definition tpl_graph.H:650
Arc * insert_arc(Node *src_node, Node *tgt_node, void *a)
Definition tpl_graph.H:605
void for_each(Operation &operation)
Traverse all the container and performs an operation on each element.
Definition ah-dry.H:796
Common methods for the arc of a graph.
Definition graph-dry.H:570
GTArcCommon() noexcept=default
data contained in arc
ArcInfo & get_info() noexcept
Return a modifiable reference to the arc data.
Definition graph-dry.H:637
void * tgt_node
Please don't use.
Definition graph-dry.H:576
void * get_connected_node(void *node) noexcept
Definition graph-dry.H:642
GTArcCommon(const GTArcCommon &other)
Copy constructor.
Definition graph-dry.H:604
GTArcCommon(void *src, void *tgt, const ArcInfo &data)
Construct with endpoints and info (copy)
Definition graph-dry.H:596
const ArcInfo & get_info() const noexcept
Return a constant reference to the arc data.
Definition graph-dry.H:640
GTArcCommon(GTArcCommon &&other) noexcept
Move constructor.
Definition graph-dry.H:608
Graph_Attr attrs
Please don't use.
Definition graph-dry.H:582
ArcInfo arc_info
Definition graph-dry.H:584
GTArcCommon(ArcInfo &&info)
Construct from info value (move)
Definition graph-dry.H:593
GTArcCommon & operator=(const GTArcCommon &other)
Copy assignment operator.
Definition graph-dry.H:612
void set_state(unsigned int s) noexcept
Set the state of arc to value s
Definition graph-dry.H:631
void * get_img_node(void *node) noexcept
Definition graph-dry.H:647
GTArcCommon(void *src, void *tgt, ArcInfo &&data=ArcInfo())
Construct with endpoints and info (move)
Definition graph-dry.H:600
unsigned int state() const noexcept
Return the state of arc.
Definition graph-dry.H:628
void * src_node
Definition graph-dry.H:575
GTArcCommon & operator=(GTArcCommon &&other) noexcept
Move assignment operator.
Definition graph-dry.H:620
Common attributes and methods for nodes (vertexes) belonging to graphs.
Definition graph-dry.H:477
NodeInfo Item_Type
Definition graph-dry.H:498
const NodeInfo & get_info() const noexcept
Return a constant reference to the data contained in the node.
Definition graph-dry.H:539
GTNodeCommon() noexcept=default
another alias for set type
NodeInfo node_info
Definition graph-dry.H:485
GTNodeCommon & operator=(const GTNodeCommon &other)
Copy assignment operator.
Definition graph-dry.H:520
GTNodeCommon(NodeInfo &&info)
Move constructor from info value.
Definition graph-dry.H:511
Graph_Attr attrs
Attributes of node.
Definition graph-dry.H:483
unsigned int state() const noexcept
Return the state's value.
Definition graph-dry.H:542
NodeInfo & get_info() noexcept
Return a modifiable reference to the data contained in the node.
Definition graph-dry.H:536
NodeInfo Node_Type
The node.
Definition graph-dry.H:502
GTNodeCommon & operator=(GTNodeCommon &&other) noexcept
Move assignment operator.
Definition graph-dry.H:528
GTNodeCommon(GTNodeCommon &&other) noexcept
Move constructor.
Definition graph-dry.H:517
GTNodeCommon(const GTNodeCommon &other)
Copy constructor.
Definition graph-dry.H:514
void set_state(unsigned int s) noexcept
Set the state to value s
Definition graph-dry.H:545
size_t num_arcs
data associated to the node. Access it with get_info()
Definition graph-dry.H:496
Special iterator for distinguishing input arcs of output ones.
Definition graph-dry.H:3077
void prev()
back to previous item.
Definition graph-dry.H:3102
typename Itor::Item_Type Item_Type
Definition graph-dry.H:3084
void next()
Advance to next arc.
Definition graph-dry.H:3098
Digraph_Iterator(Node *p)
Instantiate an filtered iterator for arcs on the node p
Definition graph-dry.H:3089
void reset_last() noexcept
Reset the iterator to last arc.
Definition graph-dry.H:3149
Filter_Iterator< Node *, typename GT::Node_Arc_Iterator, Filter > Itor
Definition graph-dry.H:3078
GT::Arc * get_curr_ne() const noexcept
Definition graph-dry.H:3113
GT::Arc * get_curr() const
Return the current arc.
Definition graph-dry.H:3111
GT::Node * get_node(typename GT::Arc *a) const noexcept
Return the node connected to p (passed during construction) and linked through a
Definition graph-dry.H:3122
Itor Iterator_Type
the type of items (Arc*)
Definition graph-dry.H:3086
auto get_tgt_node_ne() const noexcept
Backward-compatible alias: return target node (same as get_node_ne()).
Definition graph-dry.H:3135
auto get_current_arc_ne() const noexcept
Definition graph-dry.H:3118
GT::Node * get_node_ne() const noexcept
Return the node connected to p (passed during construction) and linked through the current arc.
Definition graph-dry.H:3129
void reset_first() noexcept
Reset the iterator to first arc.
Definition graph-dry.H:3146
bool has_curr() const noexcept
Return true is the iterator has a current arc.
Definition graph-dry.H:3107
auto get_tgt_node() const
Backward-compatible alias: return target node (same as get_node()).
Definition graph-dry.H:3143
GT::Node * get_node() const
Definition graph-dry.H:3137
Common methods to the Aleph-w ( ) graph classes.
Definition graph-dry.H:660
void init() noexcept
Definition graph-dry.H:676
Arc * min_arc(Node *p, Compare cmp=[](Arc *a, Arc *b) { return a->get_info()< b->get_info();}) const
Find the minimum arc adjacent to a node.
Definition graph-dry.H:2485
void for_each_arc(Node *p, Operation &op) const
Unconditionally traverse all the arcs adjacnt to a node and on each one perform an operation.
Definition graph-dry.H:1620
void reset_bit_nodes(int bit) const noexcept
Reset bit to zero for all the nodes of graph.
Definition graph-dry.H:1088
auto out_arcs_map(Node *p, Op op) const
Return a list of outcoming arcs of a node mapped to items of type given by transformation op.
Definition graph-dry.H:3682
typename Arc::Arc_Type Arc_Type
Definition graph-dry.H:673
auto search_in_arc(Node *p, Op &op) const
Search an incoming arc to a node satisfaying a condition.
Definition graph-dry.H:3496
T sum_arcs(Node *p, Extract extract) const
Sum values derived from arcs adjacent to a node.
Definition graph-dry.H:2452
void for_each_out_arc(Node *p, Op &op) const
Perform op on each outcoming arc of node p
Definition graph-dry.H:3595
auto filter_arcs(Node *p, Op &&op) const
Overload of filter_arcs(Node*, Op&) that accepts rvalues.
Definition graph-dry.H:2181
T foldl_arcs(Node *p, const T &init, Op op) const
Folding of arcs of a node.
Definition graph-dry.H:2043
bool exists_in_arc(Node *p, Op &op) const
Return true if it exists a incoming arc to p returning true for op
Definition graph-dry.H:3470
void for_each_arc(Node *p, Operation &&op=Operation()) const
Overload of for_each_arc(Node*, Operation&) that accepts rvalues.
Definition graph-dry.H:1629
void * get_cookie() const noexcept
Return a constant reference to graph's cookie.
Definition graph-dry.H:696
Arc * emplace_arc(Node *src, Node *tgt, Args &&... args)
Insert a new arc in the graph by constructing its associated data in-place with the given args.
Definition graph-dry.H:1300
void reset_arcs() const
Reset all the arcs of graph (the control bits, the state, the counter and the cookie)
Definition graph-dry.H:975
bool all_arcs(Node *p, Operation &&op=Operation()) const
Overload of all_arcs(Node*, Operation&) that accepts rvalues.
Definition graph-dry.H:1764
auto filter_in_arcs(Node *p, Op &&op=Op()) const
Overload of filter_in_arcs(Node*, Op&) that accepts rvalues.
Definition graph-dry.H:3573
void reset_cookie_arcs() const noexcept
Reset all the cookies to `nullptr for all the arcs of graph.
Definition graph-dry.H:1140
Container< Arc * > arcs() const
Return a container with all the arcs of the graph.
Definition graph-dry.H:2844
int get_bit(Arc *arc, int bit) const noexcept
Get the control bit of arc
Definition graph-dry.H:891
Arc * find_arc(const Arc_Type &info) const noexcept
Find an arc mathing a content.
Definition graph-dry.H:2740
size_t get_num_arcs(Node *node) const noexcept
Return the total of arcs of a node.
Definition graph-dry.H:830
Node * find_node(const Node_Type &info) const noexcept
Find a node mathing a content.
Definition graph-dry.H:2687
size_t num_nodes
Definition graph-dry.H:667
void for_each_arc(Operation &op) const
Unconditionally traverse all the arcs of graph and on each one perform an operation.
Definition graph-dry.H:1571
bool all_nodes(Operation &&op=Operation()) const
Overload of all_nodes(Operation&) that accepts rvalues.
Definition graph-dry.H:1673
bool exists_out_arc(Node *p, Op &op) const
Return true if it exists a outcoming arc to p returning true for op
Definition graph-dry.H:3624
void for_each_in_arc(Node *p, Op &op) const
Perform op on each incoming arc of node p
Definition graph-dry.H:3441
auto get_arc_it() const noexcept
Obtains an iterator to the arc of graph.
Definition graph-dry.H:2908
void reset_counter(Node *node) const noexcept
Reset the node counter to zero.
Definition graph-dry.H:921
void for_each_out_arc(Node *p, Op &&op=Op()) const
Overload of for_each_out_arc(Node*, Op&) that accepts rvalues.
Definition graph-dry.H:3602
Node * insert_node(Node_Type &&node_info=Node_Type())
Allocate a new node, set by moving its data content and insert it into the graph.
Definition graph-dry.H:1188
In_Iterator get_in_it(Node *p) const noexcept
Return an input iterator on the incoming arcs to p
Definition graph-dry.H:3185
Node * insert_node(const Node_Type &node_info)
Allocate a new node, set by copy its data content and insert it into the graph.
Definition graph-dry.H:1164
Node * get_src_node(Arc *arc) const noexcept
Return the source node of arc (only for directed graphs)
Definition graph-dry.H:779
Node * get_node() const
Return any node in the graph.
Definition graph-dry.H:756
Out_Iterator get_out_it(Node *p) const noexcept
Return an output iterator on the incoming nodes to p
Definition graph-dry.H:3205
auto search_out_arc(Node *p, Op &op) const
Search an outcoming arc to a node satisfaying a condition.
Definition graph-dry.H:3650
std::tuple< Arc *, Node * > ArcPair
Pair of arc and node (topologically related)
Definition graph-dry.H:3295
DynList< Node * > in_nodes(Node *p) const
Return a list with the incoming nodes to p
Definition graph-dry.H:3235
void for_each_arc(Node *p, Operation &op) const
Perform op on each arc of node p
Definition graph-dry.H:3418
bool traverse_nodes(Operation &op) const
Conditioned traversal of all the nodes of a graph.
Definition graph-dry.H:1353
T foldl_in_arcs(Node *p, const T &init, Op op) const
Fold the incoming arcs of a node.
Definition graph-dry.H:3544
constexpr size_t get_num_nodes() const noexcept
Return the total of nodes of graph.
Definition graph-dry.H:737
Arc * search_arc(Op &&op) const
Overload of search_arc(Op&) that accepts rvalues.
Definition graph-dry.H:2724
bool traverse_arcs(Node *p, Operation &op) const
Conditioned traversal of all the adjacent arcs of a node.
Definition graph-dry.H:1489
bool traverse_in_arcs(Node *p, Op &&op=Op()) const
Overload of traverse_in_arcs(Node*, Op&) that accepts rvalues.
Definition graph-dry.H:3434
void reset_bit_nodes() const noexcept
Reset all the bits for all the nodes of graph.
Definition graph-dry.H:1100
bool exists_arc(Node *p, Operation &op) const
Determine if exists at least a arc adjacent to a node satisfying a condition.
Definition graph-dry.H:2276
auto search_in_arc(Node *p, Op &&op=Op()) const
Overload of search_in_arc(Node*, Op&) that accepts rvalues.
Definition graph-dry.H:3513
auto search_out_arc(Node *p, Op &&op=Op()) const
Overload of search_out_arc(Node*, Op&) that accepts rvalues.
Definition graph-dry.H:3667
void for_each_in_arc(Node *p, Op &&op=Op()) const
Overload of for_each_in_arc(Node*, Op&) that accepts rvalues.
Definition graph-dry.H:3448
T sum_arcs(Node *p) const
Overload of sum_arcs(Node*, Extract) using the arc info as extractor.
Definition graph-dry.H:2461
Arc * max_arc(Compare cmp=[](Arc *a, Arc *b) { return a->get_info()< b->get_info();}) const
Find the maximum arc in the entire graph.
Definition graph-dry.H:2552
Arc * insert_arc(Node *src, Node *tgt, Arc_Type &&arc_info=Arc_Type())
Create and insert a new arc linking two nodes and moving the received data.
Definition graph-dry.H:1271
bool none_arc(Node *p, Operation &&op) const
Overload of none_arc(Node*, Operation&) that accepts rvalues.
Definition graph-dry.H:2364
bool none_node(Operation &&op) const
Overload of none_node(Operation&) that accepts rvalues.
Definition graph-dry.H:2313
void set_bit(Node *node, int bit, int value) const noexcept
Set the control bit of node to value
Definition graph-dry.H:867
DynList< Arc * > out_arcs(Node *p) const
Return a list with the outcoming arcs to p`.
Definition graph-dry.H:3270
bool exists_in_arc(Node *p, Op &&op=Op()) const
Overload of exists_in_arc(Node*, Op&) that accepts rvalues.
Definition graph-dry.H:3477
void set_bit(Arc *arc, int bit, int value) const noexcept
Set the control bit of arc to value
Definition graph-dry.H:897
Arc * search_arc(Node *p, Operation &op) const
Linear search of an arc.
Definition graph-dry.H:2765
bool is_digraph() const noexcept
Return true if the graph this is directed.
Definition graph-dry.H:699
void reset_cookie_nodes() const noexcept
Reset all the cookies to `nullptr for all the nodes of graph.
Definition graph-dry.H:1129
void reset_counter(Arc *arc) const noexcept
Reset the acr counter to zero.
Definition graph-dry.H:947
size_t num_arcs
Definition graph-dry.H:668
T foldl_nodes(const T &init, Op op) const
Folding of nodes on a graph.
Definition graph-dry.H:1956
auto filter_arcs(Node *p, Op &op) const
Filter the arcs adjacent to a node satisfying a condition.
Definition graph-dry.H:2167
void set_digraph(bool val)
Temporal indication for preventing to other algorithms that an graph must be treated as a directed gr...
Definition graph-dry.H:734
bool traverse_out_arcs(Node *p, Op &&op=Op()) const
Overload of traverse_out_arcs(Node*, Op&) that accepts rvalues.
Definition graph-dry.H:3588
bool traverse_arcs(Node *p, Operation &&op=Operation()) const
Overload of traverse_arcs(Node*, Operation&) that accepts rvalues.
Definition graph-dry.H:1500
bool all_arcs(Operation &op) const
Check if all the arcs of graph satisfy a boolean condition.
Definition graph-dry.H:1709
auto nodes_map(Op op) const
Map the nodes of a graph to a specific range.
Definition graph-dry.H:1810
void *& get_cookie() noexcept
Return a modifiable reference to graph's cookie.
Definition graph-dry.H:693
size_t degree(Node *p) const noexcept
Return the total of arcs (or degree) of a node.
Definition graph-dry.H:837
T foldl_arcs(const T &init, Op op) const
Folding of arcs on a graph.
Definition graph-dry.H:1999
bool all_nodes(Operation &op) const
Check if all the nodes of graph satisfy an boolean condition.
Definition graph-dry.H:1665
DynList< Arc * > filter_in_arcs(Node *p, Op &op) const
Filter the incoming arcs of a node.
Definition graph-dry.H:3560
auto arcs_map(Op operation) const
Map the arcs of a graph to a specific range.
Definition graph-dry.H:1858
bool all_in_arcs(Node *p, Op &op) const
Return true if op is true for all the incoming arcs to node p
Definition graph-dry.H:3455
void reset_bit_arcs() const noexcept
Reset all the bits for all the arcs of graph.
Definition graph-dry.H:1106
static void map_arcs(A1 *p, A2 *q) noexcept
Map the arcs through their cookies.
Definition graph-dry.H:1074
auto in_pairs(Node *p) const
Return a list of pair incoming arcs and nodes.
Definition graph-dry.H:3309
void reset_counter_nodes() const noexcept
Reset all the counters to zero for all the nodes of graph.
Definition graph-dry.H:1112
Arc * search_arc(Node *src, Node *tgt) const noexcept
Search an arc linking two nodes.
Definition graph-dry.H:2807
bool traverse_in_arcs(Node *p, Op &op) const
Traverse the incoming arcs of node p executing the conditioned operation
Definition graph-dry.H:3427
typename Node::Node_Type Node_Type
Definition graph-dry.H:672
size_t count_arcs(Node *p, Operation op=[](Arc *) { return true;}) const
Count arcs adjacent to a node satisfying a condition.
Definition graph-dry.H:2427
auto arcs_map(Node *p, Op operation) const
Map the adjacent arcs of a node to a specific range.
Definition graph-dry.H:1910
void sort_arcs(Compare &cmp) noexcept
Sort all the arcs of the graph according to a specific criteria.
Definition graph-dry.H:3848
DynList< Arc * > in_arcs(Node *p) const
Return a list with the incoming arcs to p`.
Definition graph-dry.H:3286
Node * get_connected_node(Arc *arc, Node *node) const noexcept
Return the adjacent node to node through arc.
Definition graph-dry.H:820
bool traverse_out_arcs(Node *p, Op &op) const
Traverse the outcoming arcs of node p executing the conditioned operation
Definition graph-dry.H:3581
void common_swap(GT &g) noexcept
Definition graph-dry.H:683
std::pair< DynList< Node * >, DynList< Node * > > partition_nodes(Operation op) const
Partition nodes into two groups based on a predicate.
Definition graph-dry.H:2581
constexpr bool is_empty() const noexcept
Checks if the graph is empty (has no nodes).
Definition graph-dry.H:743
bool exists_arc(Operation &&op=Operation()) const
Overload of exists_arc(Operation&) that accepts rvalues.
Definition graph-dry.H:2247
long & get_counter(Node *node) const noexcept
Get a modifiable reference to the counter of node
Definition graph-dry.H:915
bool traverse_arcs(Node *p, Operation &op) const
Traverse of arcs of a node according to specific arcs iterator.
Definition graph-dry.H:3407
bool all_out_arcs(Node *p, Op &op) const
Return true if op is true for all the outcoming arcs to node p
Definition graph-dry.H:3609
void reset_bit(Node *node, int bit) const noexcept
Reset the bit of node (to zero)
Definition graph-dry.H:849
auto filter_nodes(Op &&op) const
Overload of filter_nodes(Op&) that accepts rvalues.
Definition graph-dry.H:2088
void reset_bit_arcs(int bit) const noexcept
Reset bit to zero for all the arcs of graph.
Definition graph-dry.H:1094
GT * me()
Definition graph-dry.H:661
size_t out_degree(Node *p) const noexcept
Compute the output degree of a node.
Definition graph-dry.H:3379
Node * emplace_node(Args &&... args)
Insert a new node in the graph by constructing it in-place with the given args.
Definition graph-dry.H:1214
Arc * insert_arc(Node *src, Node *tgt, const Arc_Type &arc_info)
Create and insert a new arc linking two nodes and copying data.
Definition graph-dry.H:1241
void for_each_node(Operation &operation) const
Unconditionally traverse all the nodes of graph and on each one perform an operation.
Definition graph-dry.H:1531
void reset_node_counters() const noexcept
Reset all the node counters of graph to zero.
Definition graph-dry.H:927
Arc * max_arc(Node *p, Compare cmp=[](Arc *a, Arc *b) { return a->get_info()< b->get_info();}) const
Find the maximum arc adjacent to a node.
Definition graph-dry.H:2514
bool none_node(Operation &op) const
Determine if no node satisfies a condition.
Definition graph-dry.H:2305
bool traverse_nodes(Operation &&op=Operation()) const
Overload of traverse_nodes(Operation&) that accepts rvalues.
Definition graph-dry.H:1364
Bit_Fields & get_control_bits(Node *node) const noexcept
Return a reference to control fields of node
Definition graph-dry.H:843
Node * get_arc(Node *p)
Return any arc adjacent to a node.
Definition graph-dry.H:776
constexpr size_t get_num_arcs() const noexcept
Definition graph-dry.H:826
Arc * search_arc(Op &op) const
Linear search of an arc.
Definition graph-dry.H:2710
void reset_counter_arcs() const noexcept
Reset all the counters to zero for all the arcs of graph.
Definition graph-dry.H:1118
void sort_arcs(Compare &&cmp=Compare()) noexcept
Definition graph-dry.H:3857
constexpr size_t vsize() const noexcept
Definition graph-dry.H:746
void reset_bits(Node *node) const noexcept
Reset all the control bits of node
Definition graph-dry.H:855
bool all_out_arcs(Node *p, Op &&op=Op()) const
Overload of all_out_arcs(Node*, Op&) that accepts rvalues.
Definition graph-dry.H:3616
Arc * search_directed_arc(Node *src, Node *tgt) const noexcept
Search a directed arc linking two nodes.
Definition graph-dry.H:3217
long & get_counter(Arc *arc) const noexcept
Get a modifiable reference to the counter of arc
Definition graph-dry.H:941
bool traverse_arcs(Operation &&op=Operation()) const
Overload of traverse_arcs(Operation&) that accepts rvalues.
Definition graph-dry.H:1431
bool all_arcs(Node *p, Operation &op) const
Check if all the arcs adjacent to a node satisfy an boolean condition.
Definition graph-dry.H:1756
const GT * const_me() const
Definition graph-dry.H:663
size_t esize() const noexcept
Return the total of arcs of graph.
Definition graph-dry.H:840
void reset_arc(Arc *arc) const noexcept
Reset all the control attributes of arc.
Definition graph-dry.H:961
void reset_nodes() const
Reset all the nodes of graph (the control bits, the state, the counter and the cookie)
Definition graph-dry.H:968
void reset_node(Node *p) const noexcept
Reset all the control attributes of node p.
Definition graph-dry.H:935
auto in_arcs_map(Node *p, Op op) const
Return a list of incoming arcs of a node mapped to items of type given by transformation op.
Definition graph-dry.H:3528
size_t in_degree(Node *p) const noexcept
Compute the input degree of a node.
Definition graph-dry.H:3356
auto filter_arcs(Op &op) const
Filter the arcs of graph satisfying a condition.
Definition graph-dry.H:2116
auto get_node_it() const noexcept
Obtains an iterator to the nodes of graph.
Definition graph-dry.H:2886
Arc * search_arc(Node *p, Operation &&op=Operation()) const
Overload of search_arc(Node*, Operation&) that accepts rvalues.
Definition graph-dry.H:2779
Node * get_tgt_node(Arc *arc) const noexcept
Return the target node of arc (only for directed graphs)
Definition graph-dry.H:785
Node * get_arc() const
Return any arc in the graph.
Definition graph-dry.H:766
auto filter_out_arcs(Node *p, Op &&op=Op()) const
Overload of filter_out_arcs(Node*, Op&) that accepts rvalues.
Definition graph-dry.H:3721
DynList< Arc * > collect_arcs_if(Predicate pred) const
Collect all arcs matching a predicate.
Definition graph-dry.H:3746
void for_each_arc(Operation &&operation=Operation()) const
Overload of for_each_arc(Operation&) that accepts rvalues.
Definition graph-dry.H:1580
bool all_in_arcs(Node *p, Op &&op=Op()) const
Overload of all_in_arcs(Node*, Op&) that accepts rvalues.
Definition graph-dry.H:3462
void reset_bits(Arc *arc) const noexcept
Reset all the control bits of arc
Definition graph-dry.H:885
bool exists_node(Operation &op) const
Determine if exists at least a node satisfying a condition.
Definition graph-dry.H:2206
auto get_arc_it(Node *p) const noexcept
Obtains an iterator to the adjacent arcs of a node.
Definition graph-dry.H:2931
DynList< Node * > out_nodes(Node *p) const
Return a list with the outcoming nodes to p
Definition graph-dry.H:3253
void *& get_cookie(Arc *arc) const noexcept
Get a modifiable reference to the cookie pointer of arc
Definition graph-dry.H:909
Container< Node * > nodes() const
Return a container with all the nodes of the graph.
Definition graph-dry.H:2826
static void map_nodes(N1 *p, N2 *q) noexcept
Map the nodes through their cookies.
Definition graph-dry.H:1043
std::pair< DynList< Arc * >, DynList< Arc * > > partition_arcs(Operation op) const
Partition arcs into two groups based on a predicate.
Definition graph-dry.H:2605
Container< Arc * > arcs(Node *p) const
Return a container with all the arcs adjacent to a node.
Definition graph-dry.H:2862
void reset_arc_counters() const noexcept
Reset all the arc counters of graph to zero.
Definition graph-dry.H:953
void reset_bit(Arc *arc, int bit) const noexcept
Reset the bit of arc to zero.
Definition graph-dry.H:879
void sort_nodes(Compare &cmp) noexcept
Definition graph-dry.H:3814
auto filter_nodes(Op &op) const
Filter the nodes satisfying a condition.
Definition graph-dry.H:2074
bool all_arcs(Operation &&op=Operation()) const
Overload of all_arcs(Operation&) that accepts rvalues.
Definition graph-dry.H:1717
Node * search_node(Op &op) const
Linear search of a node.
Definition graph-dry.H:2657
Node * search_node(Op &&op) const
Overload of search_node(Op&) that accepts rvalues.
Definition graph-dry.H:2671
Bit_Fields & get_control_bits(Arc *arc) const noexcept
Return a reference to the control bits of arc
Definition graph-dry.H:873
DynList< Arc * > filter_out_arcs(Node *p, Op &op) const
Filter the outcoming arcs of a node.
Definition graph-dry.H:3708
void sort_nodes(Compare &&cmp=Compare()) noexcept
Definition graph-dry.H:3823
bool traverse_arcs(Operation &op) const
Conditioned traversal of all the arcs of a graph.
Definition graph-dry.H:1420
DynList< Node * > adjacent_nodes(Node *p) const
Get all adjacent nodes (neighbors) of a node.
Definition graph-dry.H:2630
bool none_arc(Operation &&op) const
Overload of none_arc(Operation&) that accepts rvalues.
Definition graph-dry.H:2342
auto filter_arcs(Op &&op) const
Overload of filter_arcs(Op&) that accepts rvalues.
Definition graph-dry.H:2130
static constexpr bool has_arc_dlink_v
Definition graph-dry.H:3810
void remove_arcs_if(Predicate pred)
Remove all arcs matching a predicate.
Definition graph-dry.H:3777
bool none_arc(Node *p, Operation &op) const
Determine if no arc adjacent to a node satisfies a condition.
Definition graph-dry.H:2356
void *& get_cookie(Node *node) const noexcept
Get a modifiable reference to the cookie pointer of node
Definition graph-dry.H:903
bool exists_node(Operation &&op=Operation()) const
Overload of exists_node(Operation&) that accepts rvalues.
Definition graph-dry.H:2214
size_t count_arcs(Operation op=[](Arc *) { return true;}) const
Count the arcs satisfying a condition.
Definition graph-dry.H:2412
void for_each_node(Operation &&operation=Operation()) const
Overload of for_each_node(Operation&) that accepts rvalues.
Definition graph-dry.H:1540
T foldl_out_arcs(Node *p, const T &init, Op op) const
Fold-left over outcoming arcs of a node.
Definition graph-dry.H:3692
Arc * min_arc(Compare cmp=[](Arc *a, Arc *b) { return a->get_info()< b->get_info();}) const
Find the minimum arc in the entire graph.
Definition graph-dry.H:2533
bool exists_out_arc(Node *p, Op &&op=Op()) const
Overload of exists_out_arc(Node*, Op&) that accepts rvalues.
Definition graph-dry.H:3631
static constexpr bool has_node_dlink_v
Sort all the nodes of the graph according to a specific criteria.
Definition graph-dry.H:3806
auto out_pairs(Node *p) const
Return a list of pair outcoming arcs and nodes.
Definition graph-dry.H:3332
int get_bit(Node *node, int bit) const noexcept
Get the control bit of node
Definition graph-dry.H:861
void * cookie
Definition graph-dry.H:666
bool none_arc(Operation &op) const
Determine if no arc satisfies a condition.
Definition graph-dry.H:2334
bool exists_arc(Node *p, Operation &&op=Operation()) const
Overload of exists_arc(Node*, Operation&) that accepts rvalues.
Definition graph-dry.H:2284
bool exists_arc(Operation &op) const
Determine if exists at least a arc satisfying a condition.
Definition graph-dry.H:2239
size_t count_nodes(Operation op=[](Node *) { return true;}) const
Count the nodes satisfying a condition.
Definition graph-dry.H:2387
f(args...) is a valid call expression, exactly as written.
f(args...) is a valid call whose result is usable as a condition.
Concept for basic graph iterators.
Definition graph-dry.H:194
Concept for graph arc iterators.
Definition graph-dry.H:252
Concept for graph node iterators.
Definition graph-dry.H:233
Concept for node adjacency iterators.
Definition graph-dry.H:276
Concept for resettable graph iterators.
Definition graph-dry.H:214
int cmp(const __gmp_expr< T, U > &expr1, const __gmp_expr< V, W > &expr2)
Definition gmpfrxx.h:4129
#define ARC_COOKIE(p)
Return the arc cookie
#define NODE_COUNTER(p)
Get the counter of a node.
#define ARC_COUNTER(p)
Return the counter of arc p.
#define ARC_BITS(p)
Return the control bits of arc p.
#define NODE_COOKIE(p)
Return the node cookie
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
#define NODE_BITS(p)
Get the control bits of a node.
void copy_graph(GT &gtgt, const GT &gsrc, bool cookie_map=false)
Explicit copy of graph.
Definition tpl_graph.H:3677
Freq_Node * pred
Predecessor node in level-order traversal.
Main namespace for Aleph-w library functions.
Definition ah-arena.H:89
T & swap(T &t1, T &t2)
Generic swap using object's swap method.
Definition ahTypes.H:121
std::decay_t< typename HeadC::Item_Type > T
Definition ah-zip.H:105
auto get_curr() const
Return the current tuple (bounds-checked).
Definition ah-zip.H:145
Itor::difference_type count(const Itor &beg, const Itor &end, const T &value)
Count elements equal to a value.
Definition ahAlgo.H:127
T sum(const Container &container, const T &init=T{})
Compute sum of all elements.
STL namespace.
Empty_Class ArcInfo
string NodeInfo
Empty placeholder class with no data members.
Definition ahDefs.H:107
What GT::Arc_Iterator::get_curr() yields, deferred on D.
Definition graph-dry.H:75
decltype(std::declval< typename concepts_detail::defer< GT, D >::type::Arc_Iterator & >().get_curr()) type
Definition graph-dry.H:76
What GT::Node_Arc_Iterator::get_curr() yields, deferred on D.
Definition graph-dry.H:85
decltype(std::declval< typename concepts_detail::defer< GT, D >::type::Node_Arc_Iterator & >().get_curr()) type
Definition graph-dry.H:86
What GT::Node_Iterator::get_curr() yields, deferred on D.
Definition graph-dry.H:65
decltype(std::declval< typename concepts_detail::defer< GT, D >::type::Node_Iterator & >().get_curr()) type
Definition graph-dry.H:66
Common arc iterator for graph having its arcs derived from Dlink class.
Definition graph-dry.H:343
Arc * get_curr() const
Return current arc.
Definition graph-dry.H:370
typename GT::Node Node
Definition graph-dry.H:344
Arc * Item_Type
The type of item that returns the iterator.
Definition graph-dry.H:348
Arc * get_curr_ne() const noexcept
Return current arc without exception.
Definition graph-dry.H:364
GTArcIterator() noexcept
Definition graph-dry.H:353
Node * get_tgt_node() const
Return the target node of current arc (if it is a directed graph)
Definition graph-dry.H:397
Arc * get_current_arc() const
Return the current arc.
Definition graph-dry.H:373
typename GT::Arc Arc
Definition graph-dry.H:345
Node * get_src_node_ne() const noexcept
Return the source node of current arc (if it is a directed graph)
Definition graph-dry.H:379
Arc * get_current_arc_ne() const noexcept
Return the current arc without exception.
Definition graph-dry.H:376
Node * get_tgt_node_ne() const noexcept
Return the target node of current arc (if it is a directed graph)
Definition graph-dry.H:385
Node * get_src_node() const
Return the source node of current arc (if it is a directed graph)
Definition graph-dry.H:391
GTArcIterator(Dlink &head) noexcept
Build a iterator for all the arcs of g.
Definition graph-dry.H:358
Common node iterator for graph having its node derived from Dlink class.
Definition graph-dry.H:298
GTNodeIterator() noexcept
Definition graph-dry.H:307
Node * Item_Type
The type of item that returns the iterator.
Definition graph-dry.H:302
Node * get_current_node() const
Return the current node.
Definition graph-dry.H:326
GTNodeIterator(Dlink &head) noexcept
Build a iterator for all the nodes of g.
Definition graph-dry.H:312
Node * get_curr_ne() const noexcept
Return the current node without exception.
Definition graph-dry.H:317
typename GT::Node Node
Definition graph-dry.H:299
Node * get_current_node_ne() const
Definition graph-dry.H:328
Node * get_curr() const
Return the current node.
Definition graph-dry.H:323
Filter for input arcs of a node.
Definition graph-dry.H:2969
Node * get_node(Arc *a) const noexcept
Return the source node of arc a
Definition graph-dry.H:2986
In_Filt(Node *__tgt=nullptr) noexcept
target node of iteration
Definition graph-dry.H:2973
bool operator()(Arc *a) const noexcept
Return true if the arc a is incoming arc to tgt; false otherwise.
Definition graph-dry.H:2979
Alias for Digraph_Iterator
Definition graph-dry.H:3157
Filter for output arcs of a node.
Definition graph-dry.H:3026
Out_Filt(Node *__src) noexcept
source node of iteration
Definition graph-dry.H:3030
Node * get_node(Arc *a) const noexcept
Return the source node of arc a (whose target is tgt)
Definition graph-dry.H:3043
bool operator()(Arc *a) const noexcept
Return true if a is a outcoming arc from src; false otherwise.
Definition graph-dry.H:3036