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
49// ============================================================================
50// C++20 Concepts for Graph Iterators
51// ============================================================================
52
151template <typename It>
152concept BasicGraphIterator = requires(It it, const It cit)
153{
154 { cit.has_curr() } -> std::convertible_to<bool>;
155 { it.next() } -> std::same_as<void>;
156 { it.get_curr() };
157};
158
171template <typename It>
173{
174 { it.reset_first() } -> std::same_as<void>;
175};
176
190template <typename It, typename Node>
191concept GraphNodeIterator = BasicGraphIterator<It> && requires(const It cit)
192{
193 { cit.get_curr() } -> std::convertible_to<Node*>;
194};
195
209template <typename It, typename Arc>
210concept GraphArcIterator = BasicGraphIterator<It> && requires(const It cit)
211{
212 { cit.get_curr() } -> std::convertible_to<Arc*>;
213};
214
233template <typename It, typename Node, typename Arc>
234concept NodeArcIterator = GraphArcIterator<It, Arc> && requires(const It cit)
235{
236 { cit.get_tgt_node() } -> std::convertible_to<Node*>;
237};
238
// end of GraphConcepts group
240
241// ============================================================================
242// End of C++20 Concepts
243// ============================================================================
244
254template <class GT>
255struct GTNodeIterator : public Dlink::Iterator
256{
257 using Node = typename GT::Node;
258
260 using Item_Type = Node *;
261
263 using Set_Type = GT;
264
265 GTNodeIterator() noexcept
266 { /* empty */
268
270 GTNodeIterator(Dlink & head) noexcept : Dlink::Iterator(head)
271 { /* empty */
272 }
273
275 Node * get_curr_ne() const noexcept
276 {
277 return static_cast<Node *>(Dlink::Iterator::get_curr_ne());
278 }
279
281 Node * get_curr() const { return static_cast<Node *>(Dlink::Iterator::get_curr()); }
282
284 Node * get_current_node() const { return get_curr(); }
285
286 Node * get_current_node_ne() const { return get_curr_ne(); }
287};
299template <class GT>
300struct GTArcIterator : public Dlink::Iterator
301{
302 using Node = typename GT::Node;
303 using Arc = typename GT::Arc;
304
306 using Item_Type = Arc *;
307
309 using Set_Type = GT;
310
311 GTArcIterator() noexcept
312 { /* empty */
313 }
314
316 GTArcIterator(Dlink & head) noexcept
317 : Dlink::Iterator(head)
318 { /* empty */
319 }
320
322 Arc * get_curr_ne() const noexcept
323 {
324 return static_cast<Arc *>(Dlink::Iterator::get_curr_ne());
325 }
326
328 Arc * get_curr() const { return static_cast<Arc *>(Dlink::Iterator::get_curr()); }
329
331 Arc * get_current_arc() const { return get_curr(); }
332
334 Arc * get_current_arc_ne() const noexcept { return get_curr_ne(); }
335
337 Node * get_src_node_ne() const noexcept
338 {
339 return static_cast<Node *>(get_curr_ne()->src_node);
340 }
341
343 Node * get_tgt_node_ne() const noexcept
344 {
345 return static_cast<Node *>(get_curr_ne()->tgt_node);
346 }
347
350 {
351 return static_cast<Node *>(get_curr()->src_node);
352 }
353
356 {
357 return static_cast<Node *>(get_curr()->tgt_node);
358 }
359};
360
361
366template <class GT, class Cmp>
368{
369 using Node = typename GT::Node;
370
371 Cmp & cmp;
372
373 Cmp_Dlink_Node(Cmp && __cmp = Cmp()) noexcept : cmp(__cmp)
374 { /* empty */
375 }
376
377 Cmp_Dlink_Node(Cmp & __cmp) noexcept : cmp(__cmp)
378 { /* empty */
379 }
380
381 bool operator ()(Dlink *d1, Dlink *d2) const noexcept
382 {
383 Node *p1 = static_cast<Node *>(d1);
384 Node *p2 = static_cast<Node *>(d2);
385 return cmp(p1, p2);
386 }
387};
388
393template <class GT, class Cmp>
395{
396 using Arc = typename GT::Arc;
397
398 Cmp & cmp;
399
400 Cmp_Dlink_Arc(Cmp && __cmp = Cmp()) noexcept : cmp(__cmp)
401 { /* empty */
402 }
403
404 Cmp_Dlink_Arc(Cmp & __cmp) noexcept : cmp(__cmp)
405 { /* empty */
406 }
407
408 bool operator ()(Dlink *d1, Dlink *d2) const noexcept
409 {
410 Arc *arc1 = static_cast<Arc *>(d1);
411 Arc *arc2 = static_cast<Arc *>(d2);
412 return cmp(arc1, arc2);
413 }
414};
415
433template <typename NodeInfo>
435{
436public:
441 Graph_Attr attrs;
442
444
445
454 size_t num_arcs = 0;
455
457
459
461
463 GTNodeCommon() noexcept = default;
464
466 GTNodeCommon(const NodeInfo & info) : node_info(info) {}
467
469 GTNodeCommon(NodeInfo && info) : node_info(std::move(info)) {}
470
472 GTNodeCommon(const GTNodeCommon & other) : node_info(other.node_info) {}
473
475 GTNodeCommon(GTNodeCommon && other) noexcept : node_info(std::move(other.node_info)) {}
476
479 {
480 if (this != &other)
481 node_info = other.node_info;
482 return *this;
483 }
484
487 {
488 if (this != &other)
489 node_info = std::move(other.node_info);
490 return *this;
491 }
492
494 NodeInfo &get_info() noexcept { return node_info; }
495
497 const NodeInfo &get_info() const noexcept { return node_info; }
498
500 unsigned int state() const noexcept { return NODE_BITS(this).state; }
501
503 void set_state(unsigned int s) noexcept
504 {
505 NODE_BITS(this).state = s;
506 }
507};
508
509
526template <typename ArcInfo>
528{
529public:
532
533 void *src_node = nullptr;
534 void *tgt_node = nullptr;
535
540 Graph_Attr attrs;
541
543
545 GTArcCommon() noexcept = default;
546
548 GTArcCommon(const ArcInfo & info) : arc_info(info) {}
549
551 GTArcCommon(ArcInfo && info) : arc_info(std::move(info)) {}
552
554 GTArcCommon(void *src, void *tgt, const ArcInfo & data)
555 : src_node(src), tgt_node(tgt), arc_info(data) {}
556
558 GTArcCommon(void *src, void *tgt, ArcInfo && data = ArcInfo())
559 : src_node(src), tgt_node(tgt), arc_info(std::move(data)) {}
560
563 : src_node(other.src_node), tgt_node(other.tgt_node), arc_info(other.arc_info) {}
564
566 GTArcCommon(GTArcCommon && other) noexcept
567 : src_node(other.src_node), tgt_node(other.tgt_node), arc_info(std::move(other.arc_info)) {}
568
571 {
572 if (this != &other)
573 arc_info = other.arc_info;
574 return *this;
575 }
576
578 GTArcCommon & operator=(GTArcCommon && other) noexcept
579 {
580 if (this != &other)
581 arc_info = std::move(other.arc_info);
582 return *this;
583 }
584
586 unsigned int state() const noexcept { return ARC_BITS(this).state; }
587
589 void set_state(unsigned int s) noexcept
590 {
591 ARC_BITS(this).state = s;
592 }
593
595 ArcInfo &get_info() noexcept { return arc_info; }
596
598 const ArcInfo &get_info() const noexcept { return arc_info; }
599
600 void * get_connected_node(void *node) noexcept
601 {
602 return src_node == node ? tgt_node : src_node;
603 }
604
605 void * get_img_node(void *node) noexcept
606 {
607 return src_node == node ? src_node : tgt_node;
608 }
609};
610
611
616template <class GT, class Node, class Arc>
618{
619 GT * me() { return static_cast<GT *>(this); }
620
621 const GT * const_me() const { return static_cast<const GT *>(this); }
622
623protected:
624 void *cookie = nullptr;
625 size_t num_nodes = 0;
626 size_t num_arcs = 0;
627 bool digraph = false;
628
629public:
630 using Node_Type = typename Node::Node_Type;
631 using Arc_Type = typename Arc::Arc_Type;
632
633protected:
634 void init() noexcept
635 {
636 num_nodes = num_arcs = 0;
637 cookie = nullptr;
638 digraph = false;
639 }
640
641 void common_swap(GT & g) noexcept
642 {
643 std::swap(num_nodes, g.num_nodes);
644 std::swap(num_arcs, g.num_arcs);
645 std::swap(digraph, g.digraph);
646 std::swap(cookie, g.cookie);
647 }
648
649public:
651 void *&get_cookie() noexcept { return cookie; }
652
654 void * get_cookie() const noexcept { return cookie; }
655
657 bool is_digraph() const noexcept { return digraph; }
658
692 void set_digraph(bool val) { digraph = val; } // TODO: delete after
693
695 [[nodiscard]] constexpr size_t get_num_nodes() const noexcept { return num_nodes; }
696
698 [[nodiscard]] constexpr size_t vsize() const noexcept { return get_num_nodes(); }
699
708 Node * get_node() const { return const_me()->get_first_node(); }
709
718 Node * get_arc() const { return const_me()->get_first_arc(); }
719
728 Node * get_arc(Node *p) { return const_me()->get_first_arc(p); }
729
731 Node * get_src_node(Arc *arc) const noexcept
732 {
733 return static_cast<Node *>(arc->src_node);
734 }
735
737 Node * get_tgt_node(Arc *arc) const noexcept
738 {
739 return static_cast<Node *>(arc->tgt_node);
740 }
741
772 Node * get_connected_node(Arc *arc, Node *node) const noexcept
773 {
774 return static_cast<Node *>(arc->get_connected_node(node));
775 }
776
778 [[nodiscard]] constexpr size_t get_num_arcs() const noexcept { return num_arcs; }
779
782 size_t get_num_arcs(Node *node) const noexcept
783 {
784 return node->num_arcs;
785 }
786
789 size_t degree(Node *p) const noexcept { return get_num_arcs(p); }
790
792 size_t esize() const noexcept { return get_num_arcs(); }
793
795 Bit_Fields &get_control_bits(Node *node) const noexcept
796 {
797 return NODE_BITS(node).reset();
798 }
799
801 void reset_bit(Node *node, int bit) const noexcept
802 {
803 NODE_BITS(node).reset(bit);
804 }
805
807 void reset_bits(Node *node) const noexcept
808 {
809 NODE_BITS(node).reset();
810 }
811
813 int get_bit(Node *node, int bit) const noexcept
814 {
815 return NODE_BITS(node).get_bit(bit);
816 }
817
819 void set_bit(Node *node, int bit, int value) const noexcept
820 {
821 NODE_BITS(node).set_bit(bit, value);
822 }
823
825 Bit_Fields &get_control_bits(Arc *arc) const noexcept
826 {
827 return ARC_BITS(arc);
828 }
829
831 void reset_bit(Arc *arc, int bit) const noexcept
832 {
833 ARC_BITS(arc).reset(bit);
834 }
835
837 void reset_bits(Arc *arc) const noexcept
838 {
839 ARC_BITS(arc).reset();
840 }
841
843 int get_bit(Arc *arc, int bit) const noexcept
844 {
845 return ARC_BITS(arc).get_bit(bit);
846 }
847
849 void set_bit(Arc *arc, int bit, int value) const noexcept
850 {
851 ARC_BITS(arc).set_bit(bit, value);
852 }
853
855 void *&get_cookie(Node *node) const noexcept
856 {
857 return NODE_COOKIE(node);
858 }
859
861 void *&get_cookie(Arc *arc) const noexcept
862 {
863 return ARC_COOKIE(arc);
864 }
865
867 long &get_counter(Node *node) const noexcept
868 {
869 return NODE_COUNTER(node);
870 }
871
873 void reset_counter(Node *node) const noexcept
874 {
875 NODE_COUNTER(node) = 0;
876 }
877
879 void reset_node_counters() const noexcept
880 {
881 for_each_node([this](auto p) { this->reset_counter(p); });
882 }
883
887 void reset_node(Node *p) const noexcept
888 {
889 p->attrs.reset();
890 }
891
893 long &get_counter(Arc *arc) const noexcept
894 {
895 return ARC_COUNTER(arc);
896 }
897
899 void reset_counter(Arc *arc) const noexcept
900 {
901 ARC_COUNTER(arc) = No_Visited;
902 }
903
905 void reset_arc_counters() const noexcept
906 {
907 for_each_arc([this](auto a) { this->reset_counter(a); });
908 }
909
913 void reset_arc(Arc *arc) const noexcept
914 {
915 arc->attrs.reset();
916 }
917
920 void reset_nodes() const
921 {
922 for_each_node([](auto p) { p->attrs.reset(); });
923 }
924
927 void reset_arcs() const
928 {
929 for_each_arc([](auto a) { a->attrs.reset(); });
930 }
931
993 template <class N1, class N2 = N1>
994 static
995 void map_nodes(N1 *p, N2 *q) noexcept
996 {
997 assert(p != nullptr and q != nullptr);
998 // Use reinterpret_cast to preserve exact pointer values without any
999 // implicit base class pointer adjustment from multiple inheritance
1000 if (NODE_COOKIE(p) == nullptr)
1001 {
1002 NODE_COOKIE(p) = reinterpret_cast<void *>(q);
1003 NODE_COOKIE(q) = reinterpret_cast<void *>(p);
1004 return;
1005 }
1006 NODE_COOKIE(q) = NODE_COOKIE(p);
1007 NODE_COOKIE(p) = reinterpret_cast<void *>(q);
1008 }
1009
1024 template <class A1, class A2 = A1>
1025 static
1026 void map_arcs(A1 *p, A2 *q) noexcept
1027 {
1028 assert(p != nullptr and q != nullptr);
1029 if (ARC_COOKIE(p) == nullptr)
1030 {
1031 ARC_COOKIE(p) = q;
1032 ARC_COOKIE(q) = p;
1033 return;
1034 }
1035 ARC_COOKIE(q) = ARC_COOKIE(p);
1036 ARC_COOKIE(p) = q;
1037 }
1038
1040 void reset_bit_nodes(int bit) const noexcept
1041 {
1042 for_each_node([bit, this](auto p) { this->reset_bit(p, bit); });
1043 }
1044
1046 void reset_bit_arcs(int bit) const noexcept
1047 {
1048 for_each_arc([bit, this](auto a) { this->reset_bit(a, bit); });
1049 }
1050
1052 void reset_bit_nodes() const noexcept
1053 {
1054 for_each_node([this](auto p) { this->reset_bits(p); });
1055 }
1056
1058 void reset_bit_arcs() const noexcept
1059 {
1060 for_each_arc([this](auto a) { this->reset_bits(a); });
1061 }
1062
1064 void reset_counter_nodes() const noexcept
1065 {
1066 for_each_node([this](auto p) { this->reset_counter(p); });
1067 }
1068
1070 void reset_counter_arcs() const noexcept
1071 {
1072 for_each_arc([this](auto a) { this->reset_counter(a); });
1073 }
1074
1081 void reset_cookie_nodes() const noexcept
1082 {
1083 for_each_node([](auto p) { NODE_COOKIE(p) = nullptr; });
1084 }
1085
1092 void reset_cookie_arcs() const noexcept
1093 {
1094 for_each_arc([](auto a) { ARC_COOKIE(a) = nullptr; });
1095 }
1096
1116 Node * insert_node(const Node_Type & node_info)
1117 {
1118 return me()->insert_node(new Node(node_info));
1119 }
1120
1141 {
1142 return me()->insert_node(new Node(std::forward<Node_Type>(node_info)));
1143 }
1144
1165 template <typename... Args>
1166 Node * emplace_node(Args &&... args)
1167 {
1168 return me()->insert_node(Node_Type(args...));
1169 }
1170
1193 Arc * insert_arc(Node *src, Node *tgt, const Arc_Type & arc_info)
1194 {
1195 std::unique_ptr<Arc> arc(new Arc(arc_info));
1196 me()->insert_arc(src, tgt, arc.get());
1197 return arc.release();
1198 }
1199
1223 Arc * insert_arc(Node *src, Node *tgt, Arc_Type && arc_info = Arc_Type())
1224 {
1225 std::unique_ptr<Arc> arc(new Arc(std::forward<Arc_Type>(arc_info)));
1226 me()->insert_arc(src, tgt, arc.get());
1227 return arc.release();
1228 }
1229
1251 template <typename... Args>
1252 Arc * emplace_arc(Node *src, Node *tgt, Args &&... args)
1253 {
1254 return me()->insert_arc(src, tgt, Arc_Type(args...));
1255 }
1256
1303 template <class Operation>
1304 bool traverse_nodes(Operation & op) const
1305 {
1306 for (typename GT::Node_Iterator it(*const_me()); it.has_curr(); it.next_ne())
1307 if (not op(it.get_curr()))
1308 return false;
1309 return true;
1310 }
1311
1313 template <class Operation>
1314 bool traverse_nodes(Operation && op = Operation()) const
1315 {
1316 return traverse_nodes(op);
1317 }
1318
1368 template <class Operation>
1369 bool traverse_arcs(Operation & op) const
1370 {
1371 for (typename GT::Arc_Iterator it(*const_me()); it.has_curr(); it.next_ne())
1372 if (not op(it.get_curr()))
1373 return false;
1374 return true;
1375 }
1376
1378 template <class Operation>
1379 bool traverse_arcs(Operation && op = Operation()) const
1380 {
1381 return traverse_arcs(op);
1382 }
1383
1435 template <class Operation>
1436 bool traverse_arcs(Node *p, Operation & op) const
1437 {
1438 for (typename GT::Node_Arc_Iterator it(p); it.has_curr(); it.next_ne())
1439 if (not op(it.get_curr()))
1440 return false;
1441 return true;
1442 }
1443
1445 template <class Operation>
1446 bool traverse_arcs(Node *p, Operation && op = Operation()) const
1447 {
1448 return traverse_arcs(p, op);
1449 }
1450
1475 template <class Operation>
1476 void for_each_node(Operation & operation) const
1477 {
1478 for (typename GT::Node_Iterator it(*const_me()); it.has_curr(); it.next_ne())
1479 operation(it.get_curr());
1480 }
1481
1483 template <class Operation>
1484 void for_each_node(Operation && operation = Operation()) const
1485 {
1486 for_each_node(operation);
1487 }
1488
1513 template <class Operation>
1514 void for_each_arc(Operation & op) const
1515 {
1516 for (typename GT::Arc_Iterator it(*const_me()); it.has_curr(); it.next_ne())
1517 op(it.get_curr());
1518 }
1519
1521 template <class Operation>
1522 void for_each_arc(Operation && operation = Operation()) const
1523 {
1524 for_each_arc(operation);
1525 }
1526
1560 template <class Operation>
1561 void for_each_arc(Node *p, Operation & op) const
1562 {
1563 for (typename GT::Node_Arc_Iterator it(p); it.has_curr(); it.next_ne())
1564 op(it.get_curr());
1565 }
1566
1568 template <class Operation>
1569 void for_each_arc(Node *p, Operation && op = Operation()) const
1570 {
1571 for_each_arc(p, op);
1572 }
1573
1603 template <class Operation>
1604 bool all_nodes(Operation & op) const
1605 {
1606 return traverse_nodes(op);
1607 }
1608
1610 template <class Operation>
1611 bool all_nodes(Operation && op = Operation()) const
1612 {
1613 return all_nodes(op);
1614 }
1615
1645 template <class Operation>
1646 bool all_arcs(Operation & op) const
1647 {
1648 return traverse_arcs(op);
1649 }
1650
1652 template <class Operation>
1653 bool all_arcs(Operation && op = Operation()) const
1654 {
1655 return all_arcs(op);
1656 }
1657
1690 template <class Operation>
1691 bool all_arcs(Node *p, Operation & op) const
1692 {
1693 return traverse_arcs(p, op);
1694 }
1695
1697 template <class Operation>
1698 bool all_arcs(Node *p, Operation && op = Operation()) const
1699 {
1700 return all_arcs(p, op);
1701 }
1702
1742 template <typename T = Node_Type>
1743 auto nodes_map(std::function<T(Node *)> op) const
1744 {
1745 DynList<T> ret_val;
1746 for_each_node([&ret_val, &op](Node *p) { ret_val.append(op(p)); });
1747 return ret_val;
1748 }
1749
1789 template <typename T = Arc_Type>
1790 auto arcs_map(std::function<T(Arc *)> operation) const
1791 {
1792 DynList<T> ret_val;
1793 for_each_arc([&ret_val, &operation](Arc *p)
1794 {
1795 ret_val.append(operation(p));
1796 });
1797 return ret_val;
1798 }
1799
1840 template <typename T = Arc_Type>
1841 auto arcs_map(Node *p, std::function<T(Arc *)> operation) const
1842 {
1843 DynList<T> ret_val;
1844 for_each_arc(p, [&ret_val, &operation](Arc *a)
1845 {
1846 ret_val.append(operation(a));
1847 });
1848 return ret_val;
1849 }
1850
1885 template <typename T = Node_Type>
1886 T foldl_nodes(const T & init,
1887 std::function<T(const T &, Node *)> op) const
1888 {
1889 T ret = init;
1890 for_each_node([&ret, &op](Node *p) { ret = op(ret, p); });
1891 return ret;
1892 }
1893
1927 template <typename T = Arc_Type>
1928 T foldl_arcs(const T & init,
1929 std::function<T(const T &, Arc *)> op) const
1930 {
1931 T ret = init;
1932 for_each_arc([&ret, &op](Arc *p) { ret = op(ret, p); });
1933 return ret;
1934 }
1935
1970 template <typename T = Arc_Type>
1971 T foldl_arcs(Node *p, const T & init,
1972 std::function<T(const T &, Arc *)> op) const
1973 {
1974 T ret = init;
1975 for_each_arc(p, [&ret, &op](Arc *a) { ret = op(ret, a); });
1976 return ret;
1977 }
1978
2000 template <class Op>
2001 auto filter_nodes(Op & op) const
2002 {
2003 DynList<Node *> ret;
2004 for_each_node([&ret, &op](Node *p)
2005 {
2006 if (op(p))
2007 ret.append(p);
2008 });
2009 return ret;
2010 }
2011
2013 template <class Op>
2014 auto filter_nodes(Op && op) const
2015 {
2016 return filter_nodes(op);
2017 }
2018
2040 template <class Op>
2041 auto filter_arcs(Op & op) const
2042 {
2043 DynList<Arc *> ret;
2044 for_each_arc([&ret, &op](Arc *a)
2045 {
2046 if (op(a))
2047 ret.append(a);
2048 });
2049 return ret;
2050 }
2051
2053 template <class Op>
2054 auto filter_arcs(Op && op) const
2055 {
2056 return filter_arcs(op);
2057 }
2058
2089 template <class Op>
2090 auto filter_arcs(Node *p, Op & op) const
2091 {
2092 DynList<Arc *> ret;
2093 for_each_arc(p, [&ret, &op](Arc *a)
2094 {
2095 if (op(a))
2096 ret.append(a);
2097 });
2098 return ret;
2099 }
2100
2102 template <class Op>
2103 auto filter_arcs(Node *p, Op && op) const
2104 {
2105 return filter_arcs(p, op);
2106 }
2107
2126 template <class Operation>
2127 bool exists_node(Operation & op) const
2128 {
2129 return not traverse_nodes([&op](Node *p) { return not op(p); });
2130 }
2131
2133 template <class Operation>
2134 bool exists_node(Operation && op = Operation()) const
2135 {
2136 return exists_node(op);
2137 }
2138
2157 template <class Operation>
2158 bool exists_arc(Operation & op) const
2159 {
2160 return not traverse_arcs([&op](Arc *a) { return not op(a); });
2161 }
2162
2164 template <class Operation>
2165 bool exists_arc(Operation && op = Operation()) const
2166 {
2167 return exists_arc(op);
2168 }
2169
2192 template <class Operation>
2193 bool exists_arc(Node *p, Operation & op) const
2194 {
2195 return not traverse_arcs(p, [&op](Arc *a) { return not op(a); });
2196 }
2197
2199 template <class Operation>
2200 bool exists_arc(Node *p, Operation && op = Operation()) const
2201 {
2202 return exists_arc(p, op);
2203 }
2204
2219 template <class Operation>
2220 bool none_node(Operation & op) const
2221 {
2222 return not exists_node(op);
2223 }
2224
2226 template <class Operation>
2227 bool none_node(Operation && op) const
2228 {
2229 return none_node(op);
2230 }
2231
2246 template <class Operation>
2247 bool none_arc(Operation & op) const
2248 {
2249 return not exists_arc(op);
2250 }
2251
2253 template <class Operation>
2254 bool none_arc(Operation && op) const
2255 {
2256 return none_arc(op);
2257 }
2258
2266 template <class Operation>
2267 bool none_arc(Node *p, Operation & op) const
2268 {
2269 return not exists_arc(p, op);
2270 }
2271
2273 template <class Operation>
2274 bool none_arc(Node *p, Operation && op) const
2275 {
2276 return none_arc(p, op);
2277 }
2278
2295 template <class Operation = std::function<bool(Node*)>>
2296 size_t count_nodes(Operation op = [](Node*) { return true; }) const
2297 {
2298 size_t count = 0;
2299 for_each_node([&count, &op](Node *p) { if (op(p)) ++count; });
2300 return count;
2301 }
2302
2319 template <class Operation = std::function<bool(Arc*)>>
2320 size_t count_arcs(Operation op = [](Arc*) { return true; }) const
2321 {
2322 size_t count = 0;
2323 for_each_arc([&count, &op](Arc *a) { if (op(a)) ++count; });
2324 return count;
2325 }
2326
2333 template <class Operation = std::function<bool(Arc*)>>
2334 size_t count_arcs(Node *p, Operation op = [](Arc*) { return true; }) const
2335 {
2336 size_t count = 0;
2337 for_each_arc(p, [&count, &op](Arc *a) { if (op(a)) ++count; });
2338 return count;
2339 }
2340
2357 template <typename T = double, class Extract>
2358 T sum_arcs(Node *p, Extract extract) const
2359 {
2360 T sum = T{0};
2361 for_each_arc(p, [&sum, &extract](Arc *a) { sum += extract(a); });
2362 return sum;
2363 }
2364
2366 template <typename T = double>
2367 T sum_arcs(Node *p) const
2368 {
2369 T sum = T{0};
2370 for_each_arc(p, [&sum](Arc *a) { sum += static_cast<T>(a->get_info()); });
2371 return sum;
2372 }
2373
2389 template <class Compare = std::function<bool(Arc*, Arc*)>>
2390 Arc* min_arc(Node *p, Compare cmp = [](Arc *a, Arc *b) {
2391 return a->get_info() < b->get_info();
2392 }) const
2393 {
2394 Arc* result = nullptr;
2395 for_each_arc(p, [&result, &cmp](Arc *a) {
2396 if (result == nullptr or cmp(a, result))
2397 result = a;
2398 });
2399 return result;
2400 }
2401
2417 template <class Compare = std::function<bool(Arc*, Arc*)>>
2418 Arc* max_arc(Node *p, Compare cmp = [](Arc *a, Arc *b) {
2419 return a->get_info() < b->get_info();
2420 }) const
2421 {
2422 Arc* result = nullptr;
2423 for_each_arc(p, [&result, &cmp](Arc *a) {
2424 if (result == nullptr or cmp(result, a))
2425 result = a;
2426 });
2427 return result;
2428 }
2429
2435 template <class Compare = std::function<bool(Arc*, Arc*)>>
2436 Arc* min_arc(Compare cmp = [](Arc *a, Arc *b) {
2437 return a->get_info() < b->get_info();
2438 }) const
2439 {
2440 Arc* result = nullptr;
2441 for_each_arc([&result, &cmp](Arc *a) {
2442 if (result == nullptr or cmp(a, result))
2443 result = a;
2444 });
2445 return result;
2446 }
2447
2453 template <class Compare = std::function<bool(Arc*, Arc*)>>
2454 Arc* max_arc(Compare cmp = [](Arc *a, Arc *b) {
2455 return a->get_info() < b->get_info();
2456 }) const
2457 {
2458 Arc* result = nullptr;
2459 for_each_arc([&result, &cmp](Arc *a) {
2460 if (result == nullptr or cmp(result, a))
2461 result = a;
2462 });
2463 return result;
2464 }
2465
2481 template <class Operation>
2482 std::pair<DynList<Node*>, DynList<Node*>> partition_nodes(Operation op) const
2483 {
2484 DynList<Node*> yes, no;
2485 for_each_node([&yes, &no, &op](Node *p) {
2486 if (op(p))
2487 yes.append(p);
2488 else
2489 no.append(p);
2490 });
2491 return {std::move(yes), std::move(no)};
2492 }
2493
2504 template <class Operation>
2505 std::pair<DynList<Arc*>, DynList<Arc*>> partition_arcs(Operation op) const
2506 {
2507 DynList<Arc*> yes, no;
2508 for_each_arc([&yes, &no, &op](Arc *a) {
2509 if (op(a))
2510 yes.append(a);
2511 else
2512 no.append(a);
2513 });
2514 return {std::move(yes), std::move(no)};
2515 }
2516
2530 DynList<Node*> adjacent_nodes(Node *p) const
2531 {
2532 DynList<Node*> result;
2533 for_each_arc(p, [this, p, &result](Arc *a) {
2534 result.append(get_connected_node(a, p));
2535 });
2536 return result;
2537 }
2538
2555 template <class Op>
2556 Node * search_node(Op & op) const
2557 {
2558 for (typename GT::Node_Iterator it(*const_me()); it.has_curr(); it.next_ne())
2559 {
2560 auto p = it.get_curr();
2561 if (op(p))
2562 return p;
2563 }
2564 return nullptr;
2565 }
2566
2568 template <class Op>
2569 Node * search_node(Op && op) const
2570 {
2571 return search_node(op);
2572 }
2573
2585 Node * find_node(const Node_Type & info) const noexcept
2586 {
2587 return search_node([&info](auto p) { return p->get_info() == info; });
2588 }
2589
2606 template <class Op>
2607 Arc * search_arc(Op & op) const
2608 {
2609 for (typename GT::Arc_Iterator it(*const_me()); it.has_curr(); it.next_ne())
2610 {
2611 auto a = it.get_curr();
2612 if (op(a))
2613 return a;
2614 }
2615 return nullptr;
2616 }
2617
2619 template <class Op>
2620 Arc * search_arc(Op && op) const
2621 {
2622 return search_arc(op);
2623 }
2624
2636 Arc * find_arc(const Arc_Type & info) const noexcept
2637 {
2638 return search_arc([&info](auto a) { return a->get_info() == info; });
2639 }
2640
2659 template <class Operation>
2660 Arc * search_arc(Node *p, Operation & op) const
2661 {
2662 for (typename GT::Node_Arc_Iterator it(p); it.has_curr(); it.next_ne())
2663 {
2664 Arc *arc = it.get_curr();
2665 if (op(arc))
2666 return arc;
2667 }
2668 return nullptr;
2669 }
2670
2672 template <class Operation>
2673 Arc * search_arc(Node *p, Operation && op = Operation()) const
2674 {
2675 return search_arc(p, op);
2676 }
2677
2701 Arc * search_arc(Node *src, Node *tgt) const noexcept
2702 {
2703 for (typename GT::Node_Arc_Iterator it(src); it.has_curr(); it.next_ne())
2704 if (it.get_tgt_node_ne() == tgt)
2705 return it.get_curr();
2706 return nullptr;
2707 }
2708
2719 template <template <typename> class Container = Aleph::DynList>
2721 {
2723 for_each_node([&ret](Node *p) { ret.append(p); });
2724 return ret;
2725 }
2726
2737 template <template <typename> class Container = Aleph::DynList>
2739 {
2740 Container<Arc *> ret;
2741 for_each_arc([&ret](Arc *a) { ret.append(a); });
2742 return ret;
2743 }
2744
2755 template <template <typename> class Container = Aleph::DynList>
2757 {
2758 Container<Arc *> ret;
2759 this->for_each_arc(p, [&ret](Arc *a) { ret.append(a); });
2760 return ret;
2761 }
2762
2780 auto get_node_it() const noexcept
2781 {
2782 return typename GT::Node_Iterator(*const_me());
2783 }
2784
2802 auto get_arc_it() const noexcept
2803 {
2804 return typename GT::Arc_Iterator(*const_me());
2805 }
2806
2825 auto get_arc_it(Node *p) const noexcept
2826 {
2827 return typename GT::Node_Arc_Iterator(p);
2828 }
2829
2862 struct In_Filt
2863 {
2864 Node *tgt = nullptr;
2865
2867 In_Filt(Node *__tgt = nullptr) noexcept : tgt(__tgt)
2868 { /* empty */
2869 }
2870
2873 bool operator ()(Arc *a) const noexcept
2874 {
2875 assert(tgt);
2876 return a->tgt_node == tgt;
2877 }
2878
2880 Node * get_node(Arc *a) const noexcept
2881 {
2882 assert(tgt);
2883 return (typename GT::Node *) a->src_node;
2884 }
2885 };
2886
2920 {
2921 Node *src = nullptr;
2922
2924 Out_Filt(Node *__src) noexcept : src(__src)
2925 { /* empty */
2926 }
2927
2930 bool operator ()(Arc *a) const noexcept
2931 {
2932 assert(src);
2933 return a->src_node == src;
2934 }
2935
2937 Node * get_node(Arc *a) const noexcept
2938 {
2939 assert(src);
2940 return (Node *) a->tgt_node;
2941 }
2942 };
2943
2969 template <class Filter>
2971 {
2972 using Itor = Filter_Iterator<Node *, typename GT::Node_Arc_Iterator, Filter>;
2973
2974 Filter filt;
2976
2977 public:
2978 using Item_Type = typename Itor::Item_Type;
2979
2981
2984 {
2985 // empty
2986 }
2987
2988 void next_ne() noexcept { it.next_ne(); }
2989
2992 void next() { it.next(); }
2993
2996 void prev() { it.prev(); }
2997
2998 void prev_ne() { it.prev_ne(); }
2999
3001 bool has_curr() const noexcept { return it.has_curr(); }
3002
3005 typename GT::Arc * get_curr() const { return it.get_curr(); }
3006
3007 typename GT::Arc * get_curr_ne() const noexcept { return it.get_curr_ne(); }
3008
3010 auto get_current_arc() const { return get_curr(); }
3011
3012 auto get_current_arc_ne() const noexcept { return get_curr_ne(); }
3013
3016 typename GT::Node * get_node(typename GT::Arc *a) const noexcept
3017 {
3018 return filt.get_node(a);
3019 }
3020
3023 typename GT::Node * get_node_ne() const noexcept
3024 {
3025 return this->get_node(this->get_curr_ne());
3026 }
3027
3029 auto get_tgt_node_ne() const noexcept { return get_node_ne(); }
3030
3031 typename GT::Node * get_node() const
3032 {
3033 return this->get_node(this->get_curr());
3034 }
3035
3037 auto get_tgt_node() const { return get_node(); }
3038
3040 void reset_first() noexcept { it.reset_first(); }
3041
3043 void reset_last() noexcept { it.reset_last(); }
3044 };
3045
3047 // template <class Filt> using Filter_Iterator = Digraph_Iterator<Filt>;
3048
3049 // /** Iterator on incoming arcs of node */
3051 {
3052 using Digraph_Iterator<In_Filt>::Digraph_Iterator;
3053 };
3054
3055 // /** Iterator on incoming arcs of node */
3057 {
3058 using Digraph_Iterator<Out_Filt>::Digraph_Iterator;
3059 };
3060
3079 In_Iterator get_in_it(Node *p) const noexcept { return In_Iterator(p); }
3080
3099 Out_Iterator get_out_it(Node *p) const noexcept { return Out_Iterator(p); }
3100
3111 Arc * search_directed_arc(Node *src, Node *tgt) const noexcept
3112 {
3113 for (typename GT::Out_Iterator it(src); it.has_curr(); it.next_ne())
3114 if (it.get_tgt_node() == tgt)
3115 return it.get_curr();
3116 return nullptr;
3117 }
3118
3129 DynList<Node *> in_nodes(Node *p) const
3130 {
3131 DynList<Node *> ret;
3132 for (In_Iterator it(p); it.has_curr(); it.next_ne())
3133 ret.append(it.get_node());
3134 return ret;
3135 }
3136
3147 DynList<Node *> out_nodes(Node *p) const
3148 {
3149 DynList<Node *> ret;
3150 for (Out_Iterator it(p); it.has_curr(); it.next_ne())
3151 ret.append(it.get_node_ne());
3152 return ret;
3153 }
3154
3164 DynList<Arc *> out_arcs(Node *p) const
3165 {
3166 DynList<Arc *> ret;
3167 for (Out_Iterator it(p); it.has_curr(); it.next_ne())
3168 ret.append(it.get_curr());
3169 return ret;
3170 }
3171
3180 DynList<Arc *> in_arcs(Node *p) const
3181 {
3182 DynList<Arc *> ret;
3183 for (In_Iterator it(p); it.has_curr(); it.next_ne())
3184 ret.append(it.get_curr());
3185 return ret;
3186 }
3187
3189 using ArcPair = std::tuple<Arc *, Node *>;
3190
3203 auto in_pairs(Node *p) const
3204 {
3205 DynList<ArcPair> ret;
3206 for (In_Iterator it(p); it.has_curr(); it.next_ne())
3207 {
3208 auto a = it.get_curr();
3209 ret.append(std::make_tuple(a, (Node *) a->get_connected_node(p)));
3210 }
3211 return ret;
3212 }
3213
3226 auto out_pairs(Node *p) const
3227 {
3228 DynList<ArcPair> ret;
3229 for (Out_Iterator it(p); it.has_curr(); it.next_ne())
3230 {
3231 auto a = it.get_curr();
3232 ret.append(std::make_tuple(a, (Node *) a->get_connected_node(p)));
3233 }
3234 return ret;
3235 }
3236
3250 size_t in_degree(Node *p) const noexcept
3251 {
3252 size_t count = 0;
3253 for (In_Iterator it(p); it.has_curr(); it.next_ne())
3254 ++count;
3255 return count;
3256 }
3257
3273 size_t out_degree(Node *p) const noexcept
3274 {
3275 size_t count = 0;
3276 for (Out_Iterator it(p); it.has_curr(); it.next_ne())
3277 ++count;
3278 return count;
3279 }
3280
3299 template <class Itor, class Operation>
3300 bool traverse_arcs(Node *p, Operation & op) const
3301 {
3302 for (Itor it(p); it.has_curr(); it.next_ne())
3303 if (not op(it.get_curr()))
3304 return false;
3305 return true;
3306 }
3307
3309 template <class Itor, class Operation>
3310 void for_each_arc(Node *p, Operation & op) const
3311 {
3312 for (Itor it(p); it.has_curr(); it.next_ne())
3313 op(it.get_curr());
3314 }
3315
3318 template <class Op>
3319 bool traverse_in_arcs(Node *p, Op & op) const
3320 {
3321 return traverse_arcs<In_Iterator, Op>(p, op);
3322 }
3323
3325 template <class Op>
3326 bool traverse_in_arcs(Node *p, Op && op = Op()) const
3327 {
3328 return traverse_in_arcs(p, op);
3329 }
3330
3332 template <class Op>
3333 void for_each_in_arc(Node *p, Op & op) const
3334 {
3335 for_each_arc<In_Iterator>(p, op);
3336 }
3337
3339 template <class Op>
3340 void for_each_in_arc(Node *p, Op && op = Op()) const
3341 {
3342 for_each_in_arc(p, op);
3343 }
3344
3346 template <class Op>
3347 bool all_in_arcs(Node *p, Op & op) const
3348 {
3349 return traverse_in_arcs(p, [&op](auto a) { return op(a); });
3350 }
3351
3353 template <class Op>
3354 bool all_in_arcs(Node *p, Op && op = Op()) const
3355 {
3356 return all_in_arcs(p, op);
3357 }
3358
3361 template <class Op>
3362 bool exists_in_arc(Node *p, Op & op) const
3363 {
3364 return not traverse_in_arcs(p, [&op](auto a) { return not op(a); });
3365 }
3366
3368 template <class Op>
3369 bool exists_in_arc(Node *p, Op && op = Op()) const
3370 {
3371 return exists_in_arc(p, op);
3372 }
3373
3387 template <class Op>
3388 auto search_in_arc(Node *p, Op & op) const
3389 {
3390 Arc *ret = nullptr;
3391 traverse_in_arcs(p, [&op, &ret](auto a)
3392 {
3393 if (op(a))
3394 {
3395 ret = a;
3396 return false;
3397 }
3398 return true;
3399 });
3400 return ret;
3401 }
3402
3404 template <class Op>
3405 auto search_in_arc(Node *p, Op && op = Op()) const
3406 {
3407 return search_in_arc(p, op);
3408 }
3409
3418 template <typename T>
3419 auto in_arcs_map(Node *p, std::function<T(Arc *)> op) const
3420 {
3421 DynList<T> ret;
3422 for_each_in_arc(p, [&ret, &op](auto a) { ret.append(op(a)); });
3423 return ret;
3424 }
3425
3433 template <typename T = Arc_Type>
3434 T foldl_in_arcs(Node *p, const T & init,
3435 std::function<T(const T &, Arc *)> op) const
3436 {
3437 T ret = init;
3438 for_each_in_arc(p, [&ret, &op](auto a) { ret = op(ret, a); });
3439 return ret;
3440 }
3441
3449 template <class Op>
3450 DynList<Arc *> filter_in_arcs(Node *p, Op & op) const
3451 {
3452 DynList<Arc *> ret;
3453 for_each_in_arc(p, [&ret, &op](auto a)
3454 {
3455 if (op(a))
3456 ret.append(a);
3457 });
3458 return ret;
3459 }
3460
3462 template <class Op>
3463 auto filter_in_arcs(Node *p, Op && op = Op()) const
3464 {
3465 return filter_in_arcs(p, op);
3466 }
3467
3470 template <class Op>
3471 bool traverse_out_arcs(Node *p, Op & op) const
3472 {
3473 return traverse_arcs<Out_Iterator>(p, op);
3474 }
3475
3477 template <class Op>
3478 bool traverse_out_arcs(Node *p, Op && op = Op()) const
3479 {
3480 return traverse_out_arcs(p, op);
3481 }
3482
3484 template <class Op>
3485 void for_each_out_arc(Node *p, Op & op) const
3486 {
3487 for_each_arc<Out_Iterator>(p, op);
3488 }
3489
3491 template <class Op>
3492 void for_each_out_arc(Node *p, Op && op = Op()) const
3493 {
3494 for_each_out_arc(p, op);
3495 }
3496
3498 template <class Op>
3499 bool all_out_arcs(Node *p, Op & op) const
3500 {
3501 return traverse_out_arcs(p, [&op](auto a) { return op(a); });
3502 }
3503
3505 template <class Op>
3506 bool all_out_arcs(Node *p, Op && op = Op()) const
3507 {
3508 return all_out_arcs(p, op);
3509 }
3510
3513 template <class Op>
3514 bool exists_out_arc(Node *p, Op & op) const
3515 {
3516 return not traverse_out_arcs(p, [&op](auto a) { return not op(a); });
3517 }
3518
3520 template <class Op>
3521 bool exists_out_arc(Node *p, Op && op = Op()) const
3522 {
3523 return exists_out_arc(p, op);
3524 }
3525
3539 template <class Op>
3540 auto search_out_arc(Node *p, Op & op) const
3541 {
3542 typename GT::Arc *ret = nullptr;
3543 traverse_out_arcs(p, [&op, &ret](auto a)
3544 {
3545 if (op(a))
3546 {
3547 ret = a;
3548 return false;
3549 }
3550 return true;
3551 });
3552 return ret;
3553 }
3554
3556 template <class Op>
3557 auto search_out_arc(Node *p, Op && op = Op()) const
3558 {
3559 return search_out_arc(p, op);
3560 }
3561
3570 template <typename T = Arc_Type>
3571 auto out_arcs_map(Node *p, std::function<T(Arc *)> op) const
3572 {
3573 DynList<T> ret;
3574 for_each_out_arc(p, [&ret, &op](auto a) { ret.append(op(a)); });
3575 return ret;
3576 }
3577
3579 template <typename T = Arc_Type>
3580 T foldl_out_arcs(Node *p, const T & init,
3581 std::function<T(const T &, Arc *)> op) const
3582 {
3583 T ret = init;
3584 for_each_out_arc(p, [&ret, &op](auto a) { ret = op(ret, a); });
3585 return ret;
3586 }
3587
3595 template <class Op>
3596 DynList<Arc *> filter_out_arcs(Node *p, Op & op) const
3597 {
3598 DynList<Arc *> ret;
3599 for_each_out_arc(p, [&ret, &op](auto a)
3600 {
3601 if (op(a))
3602 ret.append(a);
3603 });
3604 return ret;
3605 }
3606
3608 template <class Op>
3609 auto filter_out_arcs(Node *p, Op && op = Op()) const
3610 {
3611 return filter_out_arcs(p, op);
3612 }
3613
3614 // ===========================================================================
3615 // Arc Removal Helpers (protected, for use in remove_node implementations)
3616 // ===========================================================================
3617
3618protected:
3633 template <class Predicate>
3634 DynList<Arc*> collect_arcs_if(Predicate pred) const
3635 {
3636 DynList<Arc*> result;
3637 for (typename GT::Arc_Iterator it(*const_me()); it.has_curr(); it.next_ne())
3638 if (pred(it.get_curr_ne()))
3639 result.append(it.get_curr_ne());
3640 return result;
3641 }
3642
3664 template <class Predicate>
3665 void remove_arcs_if(Predicate pred)
3666 {
3667 collect_arcs_if(pred).for_each([this](auto a) { me()->remove_arc(a); });
3668 }
3669
3670public:
3671 // ===========================================================================
3672 // Sorting Methods (for Dlink-based graphs)
3673 // ===========================================================================
3674
3693 template <class U>
3694 static constexpr bool has_node_dlink_v =
3695 requires(U & u) { { u.get_node_dlink() } -> std::same_as<Dlink&>; };
3696
3697 template <class U>
3698 static constexpr bool has_arc_dlink_v =
3699 requires(U & u) { { u.get_arc_dlink() } -> std::same_as<Dlink&>; };
3700
3701 template <class Compare>
3702 void sort_nodes(Compare & cmp) noexcept
3703 requires(has_node_dlink_v<GT>)
3704 {
3706 mergesort(me()->get_node_dlink(), c);
3707 }
3708
3710 template <class Compare>
3711 void sort_nodes(Compare && cmp = Compare()) noexcept
3712 requires(has_node_dlink_v<GT>)
3713 {
3714 sort_nodes(cmp);
3715 }
3716
3735 template <class Compare>
3736 void sort_arcs(Compare & cmp) noexcept
3737 requires(has_arc_dlink_v<GT>)
3738 {
3740 mergesort(me()->get_arc_dlink(), c);
3741 }
3742
3744 template <class Compare>
3745 void sort_arcs(Compare && cmp = Compare()) noexcept
3746 requires(has_arc_dlink_v<GT>)
3747 {
3748 sort_arcs(cmp);
3749 }
3750};
3751
3752
3753// ============================================================================
3754// Macro for Copy/Move/Swap Pattern
3755// ============================================================================
3756
3786#define ALEPH_GRAPH_COPY_MOVE_CTORS(GraphClass) \
3787 \
3788 GraphClass(const GraphClass & g) \
3789 { \
3790 copy_graph(*this, g); \
3791 } \
3792 \
3793 \
3794 GraphClass(GraphClass && g) noexcept \
3795 { \
3796 swap(g); \
3797 } \
3798 \
3799 \
3800 GraphClass & operator=(const GraphClass & g) \
3801 { \
3802 if (this == &g) \
3803 return *this; \
3804 copy_graph(*this, g); \
3805 return *this; \
3806 } \
3807 \
3808 \
3809 GraphClass & operator=(GraphClass && g) noexcept \
3810 { \
3811 swap(g); \
3812 return *this; \
3813 }
3814
3815
3816namespace Aleph
3817{
3818
3846template <class BaseGraph>
3847class Digraph : public BaseGraph
3848{
3849public:
3850 using GT = BaseGraph;
3851 using Node = typename BaseGraph::Node;
3852 using Arc = typename BaseGraph::Arc;
3853
3859 {
3860 this->digraph = true;
3861 }
3862
3870 Digraph(const Digraph & dg) : GT()
3871 {
3872 this->digraph = true;
3873 copy_graph(*this, dg, false);
3874 }
3875
3884 {
3885 this->digraph = true;
3886 this->swap(dg);
3887 }
3888
3898 {
3899 if (this == &g)
3900 return *this;
3901
3902 this->digraph = true;
3903 copy_graph(*this, g, false);
3904
3905 return *this;
3906 }
3907
3916 Digraph & operator = (Digraph && g) noexcept
3917 {
3918 this->digraph = true;
3919 this->swap(g);
3920
3921 return *this;
3922 }
3923};
3924
3925} // namespace Aleph
3926
3927
3928# endif // GRAPH_DRY_H
WeightedDigraph::Node Node
WeightedDigraph::Arc Arc
Generic directed graph (digraph) wrapper template.
Definition graph-dry.H:3848
Digraph(const Digraph &dg)
Copy constructor.
Definition graph-dry.H:3870
Digraph(Digraph &&dg) noexcept
Move constructor.
Definition graph-dry.H:3883
Digraph & operator=(const Digraph &g)
Copy assignment operator.
Definition graph-dry.H:3897
typename BaseGraph::Arc Arc
Definition graph-dry.H:3852
typename BaseGraph::Node Node
Definition graph-dry.H:3851
Digraph() noexcept
Default constructor.
Definition graph-dry.H:3858
BaseGraph GT
Definition graph-dry.H:3850
Dynamic singly linked list with functional programming support.
Definition htlist.H:1423
T & append(const T &item)
Append a new item by copy.
Definition htlist.H:1562
Node * get_first_node() const
Return any node in the graph.
Definition tpl_graph.H:576
Arc * get_first_arc(Node *node) const
Return any arc adjacent to a node.
Definition tpl_graph.H:595
virtual Node * insert_node(Node *node) noexcept
Insertion of a node already allocated.
Definition tpl_graph.H:524
virtual void remove_arc(Arc *arc) noexcept
Remove an arc from the graph and free it.
Definition tpl_graph.H:649
Graph_Arc< int > Arc
The node class type.
Definition tpl_graph.H:433
Arc * insert_arc(Node *src_node, Node *tgt_node, void *a)
Definition tpl_graph.H:604
void for_each(Operation &operation)
Traverse all the container and performs an operation on each element.
Definition ah-dry.H:685
Common methods for the arc of a graph.
Definition graph-dry.H:528
GTArcCommon() noexcept=default
data contained in arc
ArcInfo & get_info() noexcept
Return a modifiable reference to the arc data.
Definition graph-dry.H:595
void * tgt_node
Please don't use.
Definition graph-dry.H:534
void * get_connected_node(void *node) noexcept
Definition graph-dry.H:600
GTArcCommon(const GTArcCommon &other)
Copy constructor.
Definition graph-dry.H:562
GTArcCommon(void *src, void *tgt, const ArcInfo &data)
Construct with endpoints and info (copy)
Definition graph-dry.H:554
const ArcInfo & get_info() const noexcept
Return a constant reference to the arc data.
Definition graph-dry.H:598
GTArcCommon(GTArcCommon &&other) noexcept
Move constructor.
Definition graph-dry.H:566
Graph_Attr attrs
Please don't use.
Definition graph-dry.H:540
ArcInfo arc_info
Definition graph-dry.H:542
GTArcCommon(ArcInfo &&info)
Construct from info value (move)
Definition graph-dry.H:551
GTArcCommon & operator=(const GTArcCommon &other)
Copy assignment operator.
Definition graph-dry.H:570
void set_state(unsigned int s) noexcept
Set the state of arc to value s
Definition graph-dry.H:589
void * get_img_node(void *node) noexcept
Definition graph-dry.H:605
GTArcCommon(void *src, void *tgt, ArcInfo &&data=ArcInfo())
Construct with endpoints and info (move)
Definition graph-dry.H:558
unsigned int state() const noexcept
Return the state of arc.
Definition graph-dry.H:586
void * src_node
Definition graph-dry.H:533
GTArcCommon & operator=(GTArcCommon &&other) noexcept
Move assignment operator.
Definition graph-dry.H:578
Common attributes and methods for nodes (vertexes) belonging to graphs.
Definition graph-dry.H:435
NodeInfo Item_Type
Definition graph-dry.H:456
const NodeInfo & get_info() const noexcept
Return a constant reference to the data contained in the node.
Definition graph-dry.H:497
GTNodeCommon() noexcept=default
another alias for set type
NodeInfo node_info
Definition graph-dry.H:443
GTNodeCommon & operator=(const GTNodeCommon &other)
Copy assignment operator.
Definition graph-dry.H:478
GTNodeCommon(NodeInfo &&info)
Move constructor from info value.
Definition graph-dry.H:469
Graph_Attr attrs
Attributes of node.
Definition graph-dry.H:441
unsigned int state() const noexcept
Return the state's value.
Definition graph-dry.H:500
NodeInfo & get_info() noexcept
Return a modifiable reference to the data contained in the node.
Definition graph-dry.H:494
NodeInfo Node_Type
The node.
Definition graph-dry.H:460
GTNodeCommon & operator=(GTNodeCommon &&other) noexcept
Move assignment operator.
Definition graph-dry.H:486
GTNodeCommon(GTNodeCommon &&other) noexcept
Move constructor.
Definition graph-dry.H:475
GTNodeCommon(const GTNodeCommon &other)
Copy constructor.
Definition graph-dry.H:472
void set_state(unsigned int s) noexcept
Set the state to value s
Definition graph-dry.H:503
size_t num_arcs
data associated to the node. Access it with get_info()
Definition graph-dry.H:454
Special iterator for distinguishing input arcs of output ones.
Definition graph-dry.H:2971
void prev()
back to previous item.
Definition graph-dry.H:2996
typename Itor::Item_Type Item_Type
Definition graph-dry.H:2978
void next()
Advance to next arc.
Definition graph-dry.H:2992
Digraph_Iterator(Node *p)
Instantiate an filtered iterator for arcs on the node p
Definition graph-dry.H:2983
void reset_last() noexcept
Reset the iterator to last arc.
Definition graph-dry.H:3043
Filter_Iterator< Node *, typename GT::Node_Arc_Iterator, Filter > Itor
Definition graph-dry.H:2972
GT::Arc * get_curr_ne() const noexcept
Definition graph-dry.H:3007
GT::Arc * get_curr() const
Return the current arc.
Definition graph-dry.H:3005
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:3016
Itor Iterator_Type
the type of items (Arc*)
Definition graph-dry.H:2980
auto get_tgt_node_ne() const noexcept
Backward-compatible alias: return target node (same as get_node_ne()).
Definition graph-dry.H:3029
auto get_current_arc_ne() const noexcept
Definition graph-dry.H:3012
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:3023
void reset_first() noexcept
Reset the iterator to first arc.
Definition graph-dry.H:3040
bool has_curr() const noexcept
Return true is the iterator has a current arc.
Definition graph-dry.H:3001
auto get_tgt_node() const
Backward-compatible alias: return target node (same as get_node()).
Definition graph-dry.H:3037
GT::Node * get_node() const
Definition graph-dry.H:3031
Common methods to the Aleph-w ( ) graph classes.
Definition graph-dry.H:618
void init() noexcept
Definition graph-dry.H:634
T foldl_nodes(const T &init, std::function< T(const T &, Node *)> op) const
Folding of nodes on a graph.
Definition graph-dry.H:1886
void reset_bit_nodes(int bit) const noexcept
Reset bit to zero for all the nodes of graph.
Definition graph-dry.H:1040
Node * search_node(Op &&op) const
Overload of search_node(Op&) that accepts rvalues.
Definition graph-dry.H:2569
typename Arc::Arc_Type Arc_Type
Definition graph-dry.H:631
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:1561
auto search_in_arc(Node *p, Op &op) const
Search an incoming arc to a node satisfaying a condition.
Definition graph-dry.H:3388
size_t count_nodes(Operation op=[](Node *) { return true;}) const
Count the nodes satisfying a condition.
Definition graph-dry.H:2296
T foldl_arcs(Node *p, const T &init, std::function< T(const T &, Arc *)> op) const
Folding of arcs of a node.
Definition graph-dry.H:1971
void for_each_out_arc(Node *p, Op &op) const
Perform op on each outcoming arc of node p
Definition graph-dry.H:3485
bool exists_arc(Operation &&op=Operation()) const
Overload of exists_arc(Operation&) that accepts rvalues.
Definition graph-dry.H:2165
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:3362
void * get_cookie() const noexcept
Return a constant reference to graph's cookie.
Definition graph-dry.H:654
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:1252
bool traverse_arcs(Node *p, Operation &op) const
Conditioned traversal of all the adjacent arcs of a node.
Definition graph-dry.H:1436
void reset_arcs() const
Reset all the arcs of graph (the control bits, the state, the counter and the cookie)
Definition graph-dry.H:927
T foldl_arcs(const T &init, std::function< T(const T &, Arc *)> op) const
Folding of arcs on a graph.
Definition graph-dry.H:1928
auto filter_in_arcs(Node *p, Op &&op=Op()) const
Overload of filter_in_arcs(Node*, Op&) that accepts rvalues.
Definition graph-dry.H:3463
void reset_cookie_arcs() const noexcept
Reset all the cookies to `nullptr for all the arcs of graph.
Definition graph-dry.H:1092
Container< Arc * > arcs() const
Return a container with all the arcs of the graph.
Definition graph-dry.H:2738
int get_bit(Arc *arc, int bit) const noexcept
Get the control bit of arc
Definition graph-dry.H:843
Arc * find_arc(const Arc_Type &info) const noexcept
Find an arc mathing a content.
Definition graph-dry.H:2636
size_t get_num_arcs(Node *node) const noexcept
Return the total of arcs of a node.
Definition graph-dry.H:782
Node * find_node(const Node_Type &info) const noexcept
Find a node mathing a content.
Definition graph-dry.H:2585
Arc * search_arc(Node *p, Operation &&op=Operation()) const
Overload of search_arc(Node*, Operation&) that accepts rvalues.
Definition graph-dry.H:2673
size_t num_nodes
Definition graph-dry.H:625
bool none_node(Operation &op) const
Determine if no node satisfies a condition.
Definition graph-dry.H:2220
bool all_arcs(Operation &&op=Operation()) const
Overload of all_arcs(Operation&) that accepts rvalues.
Definition graph-dry.H:1653
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:3514
Arc * search_arc(Op &&op) const
Overload of search_arc(Op&) that accepts rvalues.
Definition graph-dry.H:2620
void for_each_in_arc(Node *p, Op &op) const
Perform op on each incoming arc of node p
Definition graph-dry.H:3333
auto arcs_map(Node *p, std::function< T(Arc *)> operation) const
Map the adjacent arcs of a node to a specific range.
Definition graph-dry.H:1841
auto get_arc_it() const noexcept
Obtains an iterator to the arc of graph.
Definition graph-dry.H:2802
auto filter_arcs(Op &op) const
Filter the arcs of graph satisfying a condition.
Definition graph-dry.H:2041
void reset_counter(Node *node) const noexcept
Reset the node counter to zero.
Definition graph-dry.H:873
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:3492
bool none_arc(Node *p, Operation &op) const
Determine if no arc adjacent to a node satisfies a condition.
Definition graph-dry.H:2267
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:1140
In_Iterator get_in_it(Node *p) const noexcept
Return an input iterator on the incoming arcs to p
Definition graph-dry.H:3079
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:1116
Node * get_src_node(Arc *arc) const noexcept
Return the source node of arc (only for directed graphs)
Definition graph-dry.H:731
Node * get_node() const
Return any node in the graph.
Definition graph-dry.H:708
Out_Iterator get_out_it(Node *p) const noexcept
Return an output iterator on the incoming nodes to p
Definition graph-dry.H:3099
auto search_out_arc(Node *p, Op &op) const
Search an outcoming arc to a node satisfaying a condition.
Definition graph-dry.H:3540
std::tuple< Arc *, Node * > ArcPair
Pair of arc and node (topologically related)
Definition graph-dry.H:3189
bool traverse_arcs(Operation &op) const
Conditioned traversal of all the arcs of a graph.
Definition graph-dry.H:1369
DynList< Node * > in_nodes(Node *p) const
Return a list with the incoming nodes to p
Definition graph-dry.H:3129
T foldl_out_arcs(Node *p, const T &init, std::function< T(const T &, Arc *)> op) const
Fold-left over outcoming arcs of a node.
Definition graph-dry.H:3580
constexpr size_t get_num_nodes() const noexcept
Return the total of nodes of graph.
Definition graph-dry.H:695
auto filter_arcs(Node *p, Op &op) const
Filter the arcs adjacent to a node satisfying a condition.
Definition graph-dry.H:2090
Arc * search_arc(Node *p, Operation &op) const
Linear search of an arc.
Definition graph-dry.H:2660
auto out_arcs_map(Node *p, std::function< T(Arc *)> op) const
Return a list of outcoming arcs of a node mapped to items of type given by transformation op.
Definition graph-dry.H:3571
auto filter_nodes(Op &&op) const
Overload of filter_nodes(Op&) that accepts rvalues.
Definition graph-dry.H:2014
bool traverse_in_arcs(Node *p, Op &&op=Op()) const
Overload of traverse_in_arcs(Node*, Op&) that accepts rvalues.
Definition graph-dry.H:3326
bool all_nodes(Operation &op) const
Check if all the nodes of graph satisfy an boolean condition.
Definition graph-dry.H:1604
void reset_bit_nodes() const noexcept
Reset all the bits for all the nodes of graph.
Definition graph-dry.H:1052
auto search_in_arc(Node *p, Op &&op=Op()) const
Overload of search_in_arc(Node*, Op&) that accepts rvalues.
Definition graph-dry.H:3405
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:2454
bool traverse_arcs(Node *p, Operation &&op=Operation()) const
Overload of traverse_arcs(Node*, Operation&) that accepts rvalues.
Definition graph-dry.H:1446
auto search_out_arc(Node *p, Op &&op=Op()) const
Overload of search_out_arc(Node*, Op&) that accepts rvalues.
Definition graph-dry.H:3557
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:3340
T sum_arcs(Node *p) const
Overload of sum_arcs(Node*, Extract) using the arc info as extractor.
Definition graph-dry.H:2367
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:1223
void set_bit(Node *node, int bit, int value) const noexcept
Set the control bit of node to value
Definition graph-dry.H:819
DynList< Arc * > out_arcs(Node *p) const
Return a list with the outcoming arcs to p`.
Definition graph-dry.H:3164
bool exists_in_arc(Node *p, Op &&op=Op()) const
Overload of exists_in_arc(Node*, Op&) that accepts rvalues.
Definition graph-dry.H:3369
void set_bit(Arc *arc, int bit, int value) const noexcept
Set the control bit of arc to value
Definition graph-dry.H:849
bool is_digraph() const noexcept
Return true if the graph this is directed.
Definition graph-dry.H:657
void reset_cookie_nodes() const noexcept
Reset all the cookies to `nullptr for all the nodes of graph.
Definition graph-dry.H:1081
void reset_counter(Arc *arc) const noexcept
Reset the acr counter to zero.
Definition graph-dry.H:899
size_t num_arcs
Definition graph-dry.H:626
bool none_arc(Operation &&op) const
Overload of none_arc(Operation&) that accepts rvalues.
Definition graph-dry.H:2254
auto arcs_map(std::function< T(Arc *)> operation) const
Map the arcs of a graph to a specific range.
Definition graph-dry.H:1790
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:692
bool all_nodes(Operation &&op=Operation()) const
Overload of all_nodes(Operation&) that accepts rvalues.
Definition graph-dry.H:1611
bool traverse_out_arcs(Node *p, Op &&op=Op()) const
Overload of traverse_out_arcs(Node*, Op&) that accepts rvalues.
Definition graph-dry.H:3478
void *& get_cookie() noexcept
Return a modifiable reference to graph's cookie.
Definition graph-dry.H:651
void for_each_arc(Node *p, Operation &op) const
Perform op on each arc of node p
Definition graph-dry.H:3310
size_t degree(Node *p) const noexcept
Return the total of arcs (or degree) of a node.
Definition graph-dry.H:789
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:2193
void for_each_node(Operation &&operation=Operation()) const
Overload of for_each_node(Operation&) that accepts rvalues.
Definition graph-dry.H:1484
bool exists_node(Operation &op) const
Determine if exists at least a node satisfying a condition.
Definition graph-dry.H:2127
DynList< Arc * > filter_in_arcs(Node *p, Op &op) const
Filter the incoming arcs of a node.
Definition graph-dry.H:3450
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:3347
void reset_bit_arcs() const noexcept
Reset all the bits for all the arcs of graph.
Definition graph-dry.H:1058
void for_each_arc(Operation &&operation=Operation()) const
Overload of for_each_arc(Operation&) that accepts rvalues.
Definition graph-dry.H:1522
static void map_arcs(A1 *p, A2 *q) noexcept
Map the arcs through their cookies.
Definition graph-dry.H:1026
auto in_pairs(Node *p) const
Return a list of pair incoming arcs and nodes.
Definition graph-dry.H:3203
void reset_counter_nodes() const noexcept
Reset all the counters to zero for all the nodes of graph.
Definition graph-dry.H:1064
Arc * search_arc(Node *src, Node *tgt) const noexcept
Search an arc linking two nodes.
Definition graph-dry.H:2701
bool traverse_in_arcs(Node *p, Op &op) const
Traverse the incoming arcs of node p executing the conditioned operation
Definition graph-dry.H:3319
bool none_node(Operation &&op) const
Overload of none_node(Operation&) that accepts rvalues.
Definition graph-dry.H:2227
typename Node::Node_Type Node_Type
Definition graph-dry.H:630
void for_each_arc(Node *p, Operation &&op=Operation()) const
Overload of for_each_arc(Node*, Operation&) that accepts rvalues.
Definition graph-dry.H:1569
void sort_arcs(Compare &cmp) noexcept
Sort all the arcs of the graph according to a specific criteria.
Definition graph-dry.H:3736
DynList< Arc * > in_arcs(Node *p) const
Return a list with the incoming arcs to p`.
Definition graph-dry.H:3180
auto filter_arcs(Op &&op) const
Overload of filter_arcs(Op&) that accepts rvalues.
Definition graph-dry.H:2054
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:2418
Node * get_connected_node(Arc *arc, Node *node) const noexcept
Return the adjacent node to node through arc.
Definition graph-dry.H:772
bool traverse_out_arcs(Node *p, Op &op) const
Traverse the outcoming arcs of node p executing the conditioned operation
Definition graph-dry.H:3471
size_t count_arcs(Operation op=[](Arc *) { return true;}) const
Count the arcs satisfying a condition.
Definition graph-dry.H:2320
void common_swap(GT &g) noexcept
Definition graph-dry.H:641
auto in_arcs_map(Node *p, std::function< T(Arc *)> op) const
Return a list of incoming arcs of a node mapped to items of type given by transformation op.
Definition graph-dry.H:3419
bool all_arcs(Node *p, Operation &&op=Operation()) const
Overload of all_arcs(Node*, Operation&) that accepts rvalues.
Definition graph-dry.H:1698
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:1691
long & get_counter(Node *node) const noexcept
Get a modifiable reference to the counter of node
Definition graph-dry.H:867
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:3499
void reset_bit(Node *node, int bit) const noexcept
Reset the bit of node (to zero)
Definition graph-dry.H:801
void reset_bit_arcs(int bit) const noexcept
Reset bit to zero for all the arcs of graph.
Definition graph-dry.H:1046
GT * me()
Definition graph-dry.H:619
size_t out_degree(Node *p) const noexcept
Compute the output degree of a node.
Definition graph-dry.H:3273
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:1514
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:1166
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:1193
void reset_node_counters() const noexcept
Reset all the node counters of graph to zero.
Definition graph-dry.H:879
Bit_Fields & get_control_bits(Node *node) const noexcept
Return a reference to control fields of node
Definition graph-dry.H:795
Node * get_arc(Node *p)
Return any arc adjacent to a node.
Definition graph-dry.H:728
constexpr size_t get_num_arcs() const noexcept
Definition graph-dry.H:778
Arc * search_arc(Op &op) const
Linear search of an arc.
Definition graph-dry.H:2607
void reset_counter_arcs() const noexcept
Reset all the counters to zero for all the arcs of graph.
Definition graph-dry.H:1070
void sort_arcs(Compare &&cmp=Compare()) noexcept
Definition graph-dry.H:3745
constexpr size_t vsize() const noexcept
Definition graph-dry.H:698
bool none_arc(Operation &op) const
Determine if no arc satisfies a condition.
Definition graph-dry.H:2247
bool none_arc(Node *p, Operation &&op) const
Overload of none_arc(Node*, Operation&) that accepts rvalues.
Definition graph-dry.H:2274
void reset_bits(Node *node) const noexcept
Reset all the control bits of node
Definition graph-dry.H:807
bool all_out_arcs(Node *p, Op &&op=Op()) const
Overload of all_out_arcs(Node*, Op&) that accepts rvalues.
Definition graph-dry.H:3506
Arc * search_directed_arc(Node *src, Node *tgt) const noexcept
Search a directed arc linking two nodes.
Definition graph-dry.H:3111
long & get_counter(Arc *arc) const noexcept
Get a modifiable reference to the counter of arc
Definition graph-dry.H:893
const GT * const_me() const
Definition graph-dry.H:621
size_t esize() const noexcept
Return the total of arcs of graph.
Definition graph-dry.H:792
void reset_arc(Arc *arc) const noexcept
Reset all the control attributes of arc.
Definition graph-dry.H:913
void reset_nodes() const
Reset all the nodes of graph (the control bits, the state, the counter and the cookie)
Definition graph-dry.H:920
bool exists_arc(Node *p, Operation &&op=Operation()) const
Overload of exists_arc(Node*, Operation&) that accepts rvalues.
Definition graph-dry.H:2200
bool all_arcs(Operation &op) const
Check if all the arcs of graph satisfy a boolean condition.
Definition graph-dry.H:1646
void reset_node(Node *p) const noexcept
Reset all the control attributes of node p.
Definition graph-dry.H:887
size_t in_degree(Node *p) const noexcept
Compute the input degree of a node.
Definition graph-dry.H:3250
auto get_node_it() const noexcept
Obtains an iterator to the nodes of graph.
Definition graph-dry.H:2780
Node * get_tgt_node(Arc *arc) const noexcept
Return the target node of arc (only for directed graphs)
Definition graph-dry.H:737
Node * get_arc() const
Return any arc in the graph.
Definition graph-dry.H:718
auto filter_out_arcs(Node *p, Op &&op=Op()) const
Overload of filter_out_arcs(Node*, Op&) that accepts rvalues.
Definition graph-dry.H:3609
DynList< Arc * > collect_arcs_if(Predicate pred) const
Collect all arcs matching a predicate.
Definition graph-dry.H:3634
bool all_in_arcs(Node *p, Op &&op=Op()) const
Overload of all_in_arcs(Node*, Op&) that accepts rvalues.
Definition graph-dry.H:3354
void reset_bits(Arc *arc) const noexcept
Reset all the control bits of arc
Definition graph-dry.H:837
auto get_arc_it(Node *p) const noexcept
Obtains an iterator to the adjacent arcs of a node.
Definition graph-dry.H:2825
auto nodes_map(std::function< T(Node *)> op) const
Map the nodes of a graph to a specific range.
Definition graph-dry.H:1743
bool traverse_nodes(Operation &&op=Operation()) const
Overload of traverse_nodes(Operation&) that accepts rvalues.
Definition graph-dry.H:1314
DynList< Node * > out_nodes(Node *p) const
Return a list with the outcoming nodes to p
Definition graph-dry.H:3147
void *& get_cookie(Arc *arc) const noexcept
Get a modifiable reference to the cookie pointer of arc
Definition graph-dry.H:861
Container< Node * > nodes() const
Return a container with all the nodes of the graph.
Definition graph-dry.H:2720
static void map_nodes(N1 *p, N2 *q) noexcept
Map the nodes through their cookies.
Definition graph-dry.H:995
Container< Arc * > arcs(Node *p) const
Return a container with all the arcs adjacent to a node.
Definition graph-dry.H:2756
bool exists_arc(Operation &op) const
Determine if exists at least a arc satisfying a condition.
Definition graph-dry.H:2158
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:2390
bool exists_node(Operation &&op=Operation()) const
Overload of exists_node(Operation&) that accepts rvalues.
Definition graph-dry.H:2134
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:2436
Node * search_node(Op &op) const
Linear search of a node.
Definition graph-dry.H:2556
auto filter_nodes(Op &op) const
Filter the nodes satisfying a condition.
Definition graph-dry.H:2001
void reset_arc_counters() const noexcept
Reset all the arc counters of graph to zero.
Definition graph-dry.H:905
auto filter_arcs(Node *p, Op &&op) const
Overload of filter_arcs(Node*, Op&) that accepts rvalues.
Definition graph-dry.H:2103
void reset_bit(Arc *arc, int bit) const noexcept
Reset the bit of arc to zero.
Definition graph-dry.H:831
void sort_nodes(Compare &cmp) noexcept
Definition graph-dry.H:3702
T sum_arcs(Node *p, Extract extract) const
Sum values derived from arcs adjacent to a node.
Definition graph-dry.H:2358
T foldl_in_arcs(Node *p, const T &init, std::function< T(const T &, Arc *)> op) const
Fold the incoming arcs of a node.
Definition graph-dry.H:3434
std::pair< DynList< Node * >, DynList< Node * > > partition_nodes(Operation op) const
Partition nodes into two groups based on a predicate.
Definition graph-dry.H:2482
Bit_Fields & get_control_bits(Arc *arc) const noexcept
Return a reference to the control bits of arc
Definition graph-dry.H:825
bool traverse_arcs(Node *p, Operation &op) const
Traverse of arcs of a node according to specific arcs iterator.
Definition graph-dry.H:3300
DynList< Arc * > filter_out_arcs(Node *p, Op &op) const
Filter the outcoming arcs of a node.
Definition graph-dry.H:3596
void sort_nodes(Compare &&cmp=Compare()) noexcept
Definition graph-dry.H:3711
DynList< Node * > adjacent_nodes(Node *p) const
Get all adjacent nodes (neighbors) of a node.
Definition graph-dry.H:2530
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:1476
static constexpr bool has_arc_dlink_v
Definition graph-dry.H:3698
void remove_arcs_if(Predicate pred)
Remove all arcs matching a predicate.
Definition graph-dry.H:3665
bool traverse_nodes(Operation &op) const
Conditioned traversal of all the nodes of a graph.
Definition graph-dry.H:1304
void *& get_cookie(Node *node) const noexcept
Get a modifiable reference to the cookie pointer of node
Definition graph-dry.H:855
bool exists_out_arc(Node *p, Op &&op=Op()) const
Overload of exists_out_arc(Node*, Op&) that accepts rvalues.
Definition graph-dry.H:3521
static constexpr bool has_node_dlink_v
Sort all the nodes of the graph according to a specific criteria.
Definition graph-dry.H:3694
auto out_pairs(Node *p) const
Return a list of pair outcoming arcs and nodes.
Definition graph-dry.H:3226
int get_bit(Node *node, int bit) const noexcept
Get the control bit of node
Definition graph-dry.H:813
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:2334
void * cookie
Definition graph-dry.H:624
bool traverse_arcs(Operation &&op=Operation()) const
Overload of traverse_arcs(Operation&) that accepts rvalues.
Definition graph-dry.H:1379
std::pair< DynList< Arc * >, DynList< Arc * > > partition_arcs(Operation op) const
Partition arcs into two groups based on a predicate.
Definition graph-dry.H:2505
Concept for basic graph iterators.
Definition graph-dry.H:152
Concept for graph arc iterators.
Definition graph-dry.H:210
Concept for graph node iterators.
Definition graph-dry.H:191
Concept for node adjacency iterators.
Definition graph-dry.H:234
Concept for resettable graph iterators.
Definition graph-dry.H:172
List_Graph< Graph_Node< int >, Graph_Arc< int > > GT
int cmp(const __gmp_expr< T, U > &expr1, const __gmp_expr< V, W > &expr2)
Definition gmpfrxx.h:4118
#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
#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:3567
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
DynList< T > maps(const C &c, Op op)
Classic map operation.
Itor::difference_type count(const Itor &beg, const Itor &end, const T &value)
Count elements equal to a value.
Definition ahAlgo.H:127
STL namespace.
Empty_Class ArcInfo
string NodeInfo
Empty placeholder class with no data members.
Definition ahDefs.H:105
Arc of graph implemented with double-linked adjacency lists.
Definition tpl_graph.H:222
Common arc iterator for graph having its arcs derived from Dlink class.
Definition graph-dry.H:301
Arc * get_curr() const
Return current arc.
Definition graph-dry.H:328
typename GT::Node Node
Definition graph-dry.H:302
Arc * Item_Type
The type of item that returns the iterator.
Definition graph-dry.H:306
Arc * get_curr_ne() const noexcept
Return current arc without exception.
Definition graph-dry.H:322
GTArcIterator() noexcept
Definition graph-dry.H:311
Node * get_tgt_node() const
Return the target node of current arc (if it is a directed graph)
Definition graph-dry.H:355
Arc * get_current_arc() const
Return the current arc.
Definition graph-dry.H:331
typename GT::Arc Arc
Definition graph-dry.H:303
Node * get_src_node_ne() const noexcept
Return the source node of current arc (if it is a directed graph)
Definition graph-dry.H:337
Arc * get_current_arc_ne() const noexcept
Return the current arc without exception.
Definition graph-dry.H:334
Node * get_tgt_node_ne() const noexcept
Return the target node of current arc (if it is a directed graph)
Definition graph-dry.H:343
Node * get_src_node() const
Return the source node of current arc (if it is a directed graph)
Definition graph-dry.H:349
GTArcIterator(Dlink &head) noexcept
Build a iterator for all the arcs of g.
Definition graph-dry.H:316
Common node iterator for graph having its node derived from Dlink class.
Definition graph-dry.H:256
GTNodeIterator() noexcept
Definition graph-dry.H:265
Node * Item_Type
The type of item that returns the iterator.
Definition graph-dry.H:260
Node * get_current_node() const
Return the current node.
Definition graph-dry.H:284
GTNodeIterator(Dlink &head) noexcept
Build a iterator for all the nodes of g.
Definition graph-dry.H:270
Node * get_curr_ne() const noexcept
Return the current node without exception.
Definition graph-dry.H:275
typename GT::Node Node
Definition graph-dry.H:257
Node * get_current_node_ne() const
Definition graph-dry.H:286
Node * get_curr() const
Return the current node.
Definition graph-dry.H:281
Filter for input arcs of a node.
Definition graph-dry.H:2863
Node * get_node(Arc *a) const noexcept
Return the source node of arc a
Definition graph-dry.H:2880
In_Filt(Node *__tgt=nullptr) noexcept
target node of iteration
Definition graph-dry.H:2867
bool operator()(Arc *a) const noexcept
Return true if the arc a is incoming arc to tgt; false otherwise.
Definition graph-dry.H:2873
Alias for Digraph_Iterator
Definition graph-dry.H:3051
Filter for output arcs of a node.
Definition graph-dry.H:2920
Out_Filt(Node *__src) noexcept
source node of iteration
Definition graph-dry.H:2924
Node * get_node(Arc *a) const noexcept
Return the source node of arc a (whose target is tgt)
Definition graph-dry.H:2937
bool operator()(Arc *a) const noexcept
Return true if a is a outcoming arc from src; false otherwise.
Definition graph-dry.H:2930