Elementa v8.0.0
Minimalistic library for any C++ application (C++11 and up)
Loading...
Searching...
No Matches
graphs.h
Go to the documentation of this file.
1
3#include "elementa/license.inc"
4#include "elementa/checks.inc"
5
6#ifndef ELEMENTA_ADTS_GRAPHS_GRAPHS_H
7#define ELEMENTA_ADTS_GRAPHS_GRAPHS_H
8
9#include <cstddef>
10#include <memory>
11#include <map>
12#include <stack>
13#include <queue>
14#include <vector>
15#include <unordered_map>
16#include <algorithm>
17#include <utility>
18#include <type_traits>
25
27
28
29namespace elementa
30{
31
32namespace adts
33{
34
35namespace graphs
36{
37
61/* ***************************************************************************
62
63 General definitions: size_vertex, size_edge
64
65*******************************************************************************/
66
68using size_vertex = size_t;
69
71using size_edge = size_t;
72
73
74/* ***************************************************************************
75
76 Base template class: Graph
77
78*******************************************************************************/
79
81
105template <class Vertex, class Edge>
107{
108 public:
109
114 using VertexType = Vertex;
115 using EdgeType = Edge;
116
119
122
123
125
130 class VectorOfVIts: public std::vector<viterator>
131 {
132 public:
133
135 VectorOfVIts(void) = default;
136
138
140 VectorOfVIts(const Graph & g);
141 };
142
144
149 class VectorOfEIts: public std::vector<eiterator>
150 {
151 public:
152
154 VectorOfEIts(void) = default;
155
157
159 VectorOfEIts(const Graph & g);
160 };
161
163
174 {
175 public:
176
178
180 MapOfVItPos(const Graph & g);
181
183
184 MapOfVItPos(const VectorOfVIts & m);
185
186 MapOfVItPos(const MapOfVItPos & oth) { copyFrom(oth); }
187 MapOfVItPos(MapOfVItPos && oth) { moveFrom(std::move(oth)); }
188 MapOfVItPos & operator=(const MapOfVItPos & oth)
189 { if (this != &oth) copyFrom(oth); return(*this); }
190 MapOfVItPos & operator=(MapOfVItPos && oth)
191 { if (this != &oth) moveFrom(std::move(oth)); return(*this); }
192
193 ~MapOfVItPos(void) = default;
194
195
197
198 size_t size(void) const noexcept { return(map_.size()); }
199
201 bool empty(void) const noexcept { return(map_.empty()); }
202
204
205 size_t at(const viterator & vit) const
206 { return(map_.at(vit.implementation()->pointedData())); }
207
208 private:
209
210 std::unordered_map< void * , size_t > map_;
211
212 void copyFrom(const MapOfVItPos & oth) { map_ = oth.map_; }
213 void moveFrom(MapOfVItPos && oth) { map_ = std::move(oth.map_); }
214 };
215
217
228 {
229 public:
230
232
234 MapOfEItPos(const Graph & g);
235
237
238 MapOfEItPos(const VectorOfEIts & m);
239
240 MapOfEItPos(const MapOfEItPos & oth) { copyFrom(oth); }
241 MapOfEItPos(MapOfEItPos && oth) { moveFrom(std::move(oth)); }
242 MapOfEItPos & operator=(const MapOfEItPos & oth)
243 { if (this != &oth) copyFrom(oth); return(*this); }
244 MapOfEItPos & operator=(MapOfEItPos && oth)
245 { if (this != &oth) moveFrom(std::move(oth)); return(*this); }
246
247 ~MapOfEItPos(void) = default;
248
249
251
252 size_t size(void) const noexcept { return(map_.size()); }
253
255 bool empty(void) const noexcept { return(map_.empty()); }
256
258
259 size_t at(const eiterator & eit) const
260 { return(map_.at(eit.implementation()->pointedData())); }
261
262 private:
263
264 std::unordered_map< void * , size_t > map_;
265
266 void copyFrom(const MapOfEItPos & oth) { map_ = oth.map_; }
267 void moveFrom(MapOfEItPos && oth) { map_ = std::move(oth.map_); }
268 };
269
277
279 using EPred = std::function< bool(const Edge &) >;
280
282 static constexpr bool trivial_epred(const Edge &) noexcept { return(true); }
283
285 static constexpr bool nil_epred(const Edge &) noexcept { return(false); }
286
287
289 class VRange_All: public elementa::base::Range<viterator>
290 {
291 public:
292
294
296 VRange_All(const Graph & gr):gr_{&gr} {}
297
298 viterator begin(void) const { return(gr_->vallbegin()); }
299 viterator end(void) const { return(gr_->vallend()); }
300
301 private:
302
303 const Graph * gr_;
304 };
305
307
315 class VRange_Pred: public elementa::base::Range<viterator>
316 {
317 public:
318
320
322 using Pred = std::function< bool(const Vertex &) >;
323
325
327 VRange_Pred(const Graph & gr, eiterator & eit,
328 Pred & pred): gr_{&gr}, eit_{&eit}, pred_{&pred} {}
329
331
333 viterator begin(void) const;
334 viterator end(void) const;
335
336 private:
337
338 const Graph * gr_;
339 eiterator * eit_;
340 Pred * pred_;
341 };
342
344 class ERange_All: public elementa::base::Range<eiterator>
345 {
346 public:
347
349
351 ERange_All(const Graph & gr):gr_{&gr} {}
352
353 eiterator begin(void) const { return(gr_->eallbegin()); }
354 eiterator end(void) const { return(gr_->eallend()); }
355
356 private:
357
358 const Graph * gr_;
359 };
360
362
364 class ERange_Pred: public elementa::base::Range<eiterator>
365 {
366 public:
367
369
371 ERange_Pred(const Graph & gr, eiterator & eit,
372 EPred & pred): gr_{&gr}, eit_{&eit}, pred_{&pred} {}
373
375
377 eiterator begin(void) const;
378 eiterator end(void) const;
379
380 private:
381
382 const Graph * gr_;
383 eiterator * eit_;
384 EPred * pred_;
385 };
386
388 class ERange_Leaving: public elementa::base::Range<eiterator>
389 {
390 public:
391
393
395 ERange_Leaving(const Graph & gr, const viterator & v):gr_{&gr},
396 v_{v} {}
397
398 eiterator begin(void) const { return(gr_->eleavingbegin(v_));}
399 eiterator end(void) const { return(gr_->eleavingend(v_)); }
400
401 private:
402
403 const Graph * gr_;
404 viterator v_;
405 };
406
408 class ERange_Entering: public elementa::base::Range<eiterator>
409 {
410 public:
411
413
415 ERange_Entering(const Graph & gr, const viterator & v):
416 gr_{&gr},
417 v_{v} {}
418
419 eiterator begin(void) const { return(gr_->eenteringbegin(v_));}
420 eiterator end(void) const { return(gr_->eenteringend(v_)); }
421
422 private:
423
424 const Graph * gr_;
425 viterator v_;
426 };
427
429
441 {
442 public:
443
445
457 static size_edge forceBacktrack(eiterator & eit);
458
460
462 ERange_DepthFirst(const Graph & gr, const viterator & v):
463 gr_{&gr},
464 v_{v}
466 ELE_CODE_TRACE({}, "created erangedepthfirst.");
467 ELE_CODE_TRACE({}, "\t(for node " << v.to_string() << ")");
468 ELE_CODE_TRACE({}, "\t(keeping copy " << v_.to_string() << ")");
469 }
470
471 eiterator begin(void) const { return(gr_->edepthfirstbegin(v_));}
472 eiterator end(void) const { return(gr_->edepthfirstend(v_)); }
473
474 private:
475
476 const Graph * gr_;
477 viterator v_;
478 };
479
481
491 {
492 public:
493
495
497 ERange_BreadthFirst(const Graph & gr, const viterator & v):
498 gr_{&gr},
499 v_{v}
500 {}
501
502 eiterator begin(void) const
503 { return(gr_->ebreadthfirstbegin(v_)); }
504 eiterator end(void) const
505 { return(gr_->ebreadthfirstend(v_)); }
506
507 private:
508
509 const Graph * gr_;
510 viterator v_;
511 };
512
520 Graph(void) = default;
521
523 Graph(const Graph & oth) = default;
524
526 Graph & operator=(const Graph & oth) = default;
527
529 Graph(Graph && oth) = default;
530
532 Graph & operator=(Graph && oth) = default;
533
535 virtual ~Graph(void) = default;
536
544 virtual bool empty(void) const = 0;
545
547 virtual size_vertex size_vertices(void) const = 0;
548
550 virtual size_edge size_edges(void) const = 0;
551
553 bool isLeaf(const viterator & it) const noexcept
554 { return((it.valid()) && (erangeLeaving(it).begin().isEnd())); }
555
557 bool toLeaf(const eiterator & it) const noexcept
558 { return((it.valid()) && (isLeaf(destination(it)))); }
559
561
562 bool toLastChild(const eiterator & it, const viterator & vit)const noexcept;
563
565
566 virtual viterator origin(const eiterator & it) const = 0;
567
569
570 virtual viterator destination(const eiterator & it) const = 0;
571
573
574 virtual void connection(const eiterator & it,
575 viterator & vorg, viterator & vdest) const
576 { vorg = origin(it); vdest = destination(it); }
577
579
582 virtual eiterator connected(const viterator & v0,
583 const viterator & v1,
584 const EPred & epred = trivial_epred) const;
585
587
589 virtual viterator find_vertex(const Vertex & v) const;
590
592
594 virtual eiterator find_edge(const Edge & e) const;
595
603
609 virtual size_t vertexToPos(const viterator & vit) const;
610
612
616 virtual viterator posToVertex(size_t vpos) const;
617
619
625 virtual size_t edgeToPos(const eiterator & eit) const;
626
628
632 virtual eiterator posToEdge(size_t epos) const;
633
641 virtual void clear(void) = 0;
642
644
649 virtual viterator insert(const Vertex & v) = 0;
650
652
657 virtual eiterator connect(const viterator & itv0, const viterator & itv1,
658 const Edge & e) = 0;
659
661
664 virtual void unconnect(const eiterator & ite) = 0;
665
667
678 virtual void unconnect(const VectorOfEIts & sinds) = 0;
679
681
683 virtual void erase(const viterator & itv) = 0;
684
686
697 virtual void erase(const VectorOfVIts & sinds) = 0;
698
700
709 virtual void splice(Graph & oth,
710 VectorOfVIts * svothits = nullptr,
711 VectorOfEIts * seothits = nullptr,
712 VectorOfVIts * svits = nullptr,
713 VectorOfEIts * seits = nullptr) = 0;
714
722 { return(VRange_All{*this}); }
723
726 typename VRange_Pred::Pred & pred) const
727 { return(VRange_Pred{*this,eit,pred}); }
728
731 { return(ERange_All{*this}); }
732
734 ERange_Pred erangePred(eiterator & eit, const EPred & pred) const
735 { return(ERange_Pred{*this,eit,pred}); }
736
739 { return(ERange_Leaving{*this,v}); }
740
743 { return(ERange_Entering{*this,v}); }
744
747 { return(ERange_DepthFirst{*this,v}); }
748
751 { return(ERange_BreadthFirst{*this,v}); }
752
756 protected:
757
759 virtual viterator vallbegin(void) const = 0;
760
762 virtual viterator vallend(void) const = 0;
763
765 virtual eiterator eallbegin(void) const = 0;
766
768 virtual eiterator eallend(void) const = 0;
769
771 virtual eiterator eleavingbegin(const viterator &v) const = 0;
772
774 virtual eiterator eleavingend(const viterator &v) const = 0;
775
777 virtual eiterator eenteringbegin(const viterator &v) const = 0;
778
780 virtual eiterator eenteringend(const viterator &v) const = 0;
781
782
783 private:
784
785 // Depth-first, bread-first and Pred iterator behaviours provided entirely.
786
787 class VItImpl_Pred final: public elementa::base::MultItImpl<Vertex>
788 // indirectly derives from Validatable
789 {
790 public:
791
792 VItImpl_Pred(const Graph & gr,
793 typename VRange_Pred::Pred & itpred,
794 eiterator & eit,
795 bool beginorend = true):
797 gr_{&gr},
798 itpred_{&itpred},
799 eit_{&eit}
800 { if (beginorend) { isend_ = false; iterateToNext(); }
801 else isend_ = true; }
802
803 VItImpl_Pred(const VItImpl_Pred & oth):
806 { copyFrom(oth); }
807
808 VItImpl_Pred & operator=(const VItImpl_Pred & oth)
809 { if (this != &oth)
810 {
813 copyFrom(oth);
814 }
815 return(*this); }
816
817 VItImpl_Pred(VItImpl_Pred && oth):
818 elementa::patterns::Validatable{std::move(oth)},
820 { moveFrom(std::move(oth)); }
821
822 VItImpl_Pred & operator=(VItImpl_Pred && oth)
823 { if (this != &oth)
824 {
827 moveFrom(std::move(oth));
828 }
829 return(*this); }
830
831 typename elementa::base::MultItImpl<Vertex>::Ptr clone(void) const
833 new VItImpl_Pred{*this}}); }
834
835 Vertex & operator*(void)
836 { checkDeref(); auto vit = gr_->destination(*eit_);
837 return(*vit); }
838
839 Vertex * pointedData(void) const
840 { if ((isend_)||(eit_->isEnd())) return(nullptr);
841 return(&(const_cast<VItImpl_Pred *>(this)->operator*())); }
842
843 VItImpl_Pred & operator++(void)
844 { if ((!isend_)&&(!eit_->isEnd())) { ++(*eit_); iterateToNext(); }
845 return(*this); }
846
847 std::string to_string(void) const override;
848
849 private:
850
851 bool isend_;
852 const Graph * gr_;
853 typename VRange_Pred::Pred * itpred_;
854 eiterator * eit_;
855
856 void checkDeref(void) const;
857 void iterateToNext(void);
858
859 void copyFrom(const VItImpl_Pred & oth)
860 { isend_ = oth.isend_; gr_ = oth.gr_; itpred_ = oth.itpred_;
861 eit_ = oth.eit_; }
862
863 void moveFrom(VItImpl_Pred && oth)
864 { copyFrom(oth); oth.isend_ = true; }
865
866 };
867
868 class EItImpl_Pred final: public elementa::base::MultItImpl<Edge>
869 // indirectly derives from Validatable
870 {
871 public:
872
873 EItImpl_Pred(const Graph & gr,
874 typename ERange_Pred::Pred & itpred,
875 eiterator & eit,
876 bool beginorend = true):
877 elementa::patterns::Validatable{true},
878 gr_{&gr},
879 itpred_{&itpred},
880 eit_{&eit}
881 { if (beginorend) { isend_ = false; iterateToNext(); }
882 else isend_ = true; }
883
884 EItImpl_Pred(const EItImpl_Pred & oth):
885 elementa::patterns::Validatable{oth},
886 elementa::base::MultItImpl<Edge>{oth}
887 { copyFrom(oth); }
888
889 EItImpl_Pred & operator=(const EItImpl_Pred & oth)
890 { if (this != &oth)
891 {
894 copyFrom(oth);
895 }
896 return(*this); }
897
898 EItImpl_Pred(EItImpl_Pred && oth):
899 elementa::patterns::Validatable{std::move(oth)},
900 elementa::base::MultItImpl<Edge>{std::move(oth)}
901 { moveFrom(std::move(oth)); }
902
903 EItImpl_Pred & operator=(EItImpl_Pred && oth)
904 { if (this != &oth)
905 {
908 moveFrom(std::move(oth));
909 }
910 return(*this); }
911
912 typename elementa::base::MultItImpl<Edge>::Ptr clone(void) const
914 new EItImpl_Pred{*this}}); }
915
916 Edge & operator*(void)
917 { checkDeref(); return(*(*eit_)); }
918
919 Edge * pointedData(void) const
920 { if ((isend_)||(eit_->isEnd())) return(nullptr);
921 return(&(const_cast<EItImpl_Pred *>(this)->operator*())); }
922
923 EItImpl_Pred & operator++(void)
924 { if ((!isend_)&&(!eit_->isEnd())) { ++(*eit_); iterateToNext(); }
925 return(*this); }
926
927 std::string to_string(void) const override;
928
929 private:
930
931 bool isend_;
932 const Graph * gr_;
933 typename ERange_Pred::Pred * itpred_;
934 eiterator * eit_;
935
936 void checkDeref(void) const;
937 void iterateToNext(void);
938
939 void copyFrom(const EItImpl_Pred & oth)
940 { isend_ = oth.isend_; gr_ = oth.gr_; itpred_ = oth.itpred_;
941 eit_ = oth.eit_; }
942
943 void moveFrom(EItImpl_Pred && oth)
944 { copyFrom(oth); oth.isend_ = true; }
945
946 };
947
948 // Edge iteration for depth-first search from a vertex.
949 class EItImpl_DepthFirst final: public elementa::base::MultItImpl<Edge>
950 // indirectly derives from Validatable
951 {
952 public:
953
954 EItImpl_DepthFirst(Graph & gr, const viterator & vi,
955 bool beginorend = true);
956
957 EItImpl_DepthFirst(const EItImpl_DepthFirst & oth):
958 elementa::patterns::Validatable{oth},
959 elementa::base::MultItImpl<Edge>{oth}
960 { copyFrom(oth); }
961
962 EItImpl_DepthFirst & operator=(const EItImpl_DepthFirst & oth)
963 { if (this != &oth)
964 {
967 copyFrom(oth);
968 }
969 return(*this); }
970
971 EItImpl_DepthFirst(EItImpl_DepthFirst && oth):
972 elementa::patterns::Validatable{std::move(oth)},
973 elementa::base::MultItImpl<Edge>{std::move(oth)}
974 { copyFrom(oth); }
975
976 EItImpl_DepthFirst & operator=(EItImpl_DepthFirst && oth)
977 { if (this != &oth)
978 {
981 copyFrom(oth);
982 }
983 return(*this); }
984
985 typename elementa::base::MultItImpl<Edge>::Ptr clone(void) const
986 {ELE_CODE_TRACE_OFF; ELE_CODE_TRACE({},"");
988 new EItImpl_DepthFirst{*this}}); }
989
990 Edge & operator*(void);
991 Edge * pointedData(void) const;
992 EItImpl_DepthFirst & operator++(void);
993 std::string to_string(void) const override;
994
996 size_edge forceBacktrack(void)
997 { return(backtrack()); }
998
999 private:
1000
1001 using EStack = std::stack<eiterator>;
1002
1003 Graph * gr_;
1004 viterator vparent_;
1005 eiterator ecurr_;
1006 EStack stack_;
1007
1008 void checkDeref(void) const;
1009 void copyFrom(const EItImpl_DepthFirst & oth)
1010 { gr_ = oth.gr_; vparent_ = oth.vparent_; ecurr_ = oth.ecurr_;
1011 stack_ = oth.stack_; }
1012 size_edge backtrack(void);
1013 };
1014
1015
1016 // Edge iteration for breadth-first search from a vertex.
1017 class EItImpl_BreadthFirst final: public elementa::base::MultItImpl<Edge>
1018 // indirectly derives from Validatable
1019 {
1020 public:
1021
1022 EItImpl_BreadthFirst(Graph & gr, const viterator & vi,
1023 bool beginorend = true);
1024
1025 EItImpl_BreadthFirst(const EItImpl_BreadthFirst & oth):
1026 elementa::patterns::Validatable{oth},
1027 elementa::base::MultItImpl<Edge>{oth}
1028 { copyFrom(oth); }
1029
1030 EItImpl_BreadthFirst & operator=(const EItImpl_BreadthFirst &oth)
1031 { if (this != &oth)
1032 {
1035 copyFrom(oth);
1036 }
1037 return(*this); }
1038
1039 EItImpl_BreadthFirst(EItImpl_BreadthFirst && oth):
1040 elementa::patterns::Validatable{std::move(oth)},
1041 elementa::base::MultItImpl<Edge>{std::move(oth)}
1042 { copyFrom(oth); }
1043
1044 EItImpl_BreadthFirst & operator=(EItImpl_BreadthFirst && oth)
1045 { if (this != &oth)
1046 {
1049 copyFrom(oth);
1050 }
1051 return(*this); }
1052
1053 typename elementa::base::MultItImpl<Edge>::Ptr clone(void) const
1054 { return(typename elementa::base::MultItImpl<Edge>::Ptr{
1055 new EItImpl_BreadthFirst{*this}}); }
1056
1057 Edge & operator*(void);
1058 Edge * pointedData(void) const;
1059 EItImpl_BreadthFirst & operator++(void);
1060 std::string to_string(void) const override;
1061
1062 private:
1063
1064 using EQueue = std::queue<eiterator>;
1065
1066 Graph * gr_;
1067 viterator vparent_;
1068 eiterator ecurr_;
1069 EQueue queue_;
1070
1071 void checkDeref(void) const;
1072 void copyFrom(const EItImpl_BreadthFirst & oth)
1073 { gr_ = oth.gr_; vparent_ = oth.vparent_; ecurr_ = oth.ecurr_;
1074 queue_ = oth.queue_; }
1075 };
1076
1077 eiterator edepthfirstbegin(const viterator &v) const;
1078 eiterator edepthfirstend(const viterator &v) const;
1079 eiterator ebreadthfirstbegin(const viterator &v) const;
1080 eiterator ebreadthfirstend(const viterator &v) const;
1081
1082
1083 static_assert( (!std::is_void<Vertex>::value) && (!std::is_void<Edge>::value),
1084 "Graph cannot work with void Vertex/Edge data" );
1085};
1086
1087
1088/* ***************************************************************************
1089
1090 Template class: Szer_GraphCompactText
1091
1092*******************************************************************************/
1093
1095
1110template <class Vertex, class Edge>
1112 public elementa::base::Serializer<Graph<Vertex,Edge>>
1113{
1114 public:
1115
1117
1119
1126 szerv_{&szerv},
1127 szere_{&szere}
1128 {}
1129
1131 void ser(elementa::base::OutSerCh & chout, const GraphType & graph);
1132
1133 // No deserialization implemented.
1134
1135 private:
1136
1137 elementa::base::Serializer<Vertex> * szerv_{nullptr};
1138 elementa::base::Serializer<Edge> * szere_{nullptr};
1139
1140static_assert((sizeof(size_vertex)<=8) &&
1141 (sizeof(size_edge)<=8),
1142 "Serialization requires 64 bits or less for size_vertex and "
1143 "size_edge");
1144};
1145
1146
1147
1148/* ===========================================================================
1149
1150 ========== IMPLEMENTATION OF TEMPLATES ==========
1151
1152============================================================================= */
1153
1154
1155/* **********************************************************************
1156
1157 Template subclass: Graph::VectorOfVIts
1158
1159*************************************************************************/
1160
1161template <class Vertex, class Edge>
1163{
1164 viterator v = g.vrangeAll().begin();
1165 while (v != g.vrangeAll().end())
1166 {
1167 this->push_back(v);
1168 ++v;
1169 }
1170}
1171
1172
1173/* **********************************************************************
1174
1175 Template subclass: Graph::VectorOfEIts
1176
1177*************************************************************************/
1178
1179template <class Vertex, class Edge>
1181{
1182 eiterator e = g.erangeAll().begin();
1183 while (e != g.erangeAll().end())
1184 {
1185 this->push_back(e);
1186 ++e;
1187 }
1188}
1189
1190
1191/* **********************************************************************
1192
1193 Template subclass: Graph::MapOfVItPos
1194
1195*************************************************************************/
1196
1197template <class Vertex, class Edge>
1199{
1200 size_t pos{0};
1201 viterator v = g.vrangeAll().begin();
1202 while (v != g.vrangeAll().end())
1203 {
1204 map_[v.implementation()->pointedData()] = pos;
1205 ++pos;
1206 ++v;
1207 }
1208}
1209
1210template <class Vertex, class Edge>
1212{
1213 for (size_t f = 0; f < m.size(); ++f)
1214 map_[m[f].implementation()->pointedData()] = f;
1215}
1216
1217
1218/* **********************************************************************
1219
1220 Template subclass: Graph::MapOfEItPos
1221
1222*************************************************************************/
1223
1224template <class Vertex, class Edge>
1226{
1227 size_t pos{0};
1228 eiterator e = g.erangeAll().begin();
1229 while (e != g.erangeAll().end())
1230 {
1231 map_[e.implementation()->pointedData()] = pos;
1232 ++pos;
1233 ++e;
1234 }
1235}
1236
1237template <class Vertex, class Edge>
1239{
1240 for (size_t f = 0; f < m.size(); ++f)
1241 map_[m[f].implementation()->pointedData()] = f;
1242}
1243
1244
1245/* **********************************************************************
1246
1247 Template subclass: Graph::VRange_Pred
1248
1249*************************************************************************/
1250
1251template <class Vertex, class Edge>
1254{
1255 return(viterator{
1257 new VItImpl_Pred{*gr_,*(const_cast<VRange_Pred *>(this)->pred_),
1258 *eit_}}});
1259}
1260
1261template <class Vertex, class Edge>
1264{static Pred nilpred = [](const Vertex & si)->bool {return(false);};
1265
1266 eiterator nileit{gr_->erangeAll().end()};
1267 return(viterator{
1269 new VItImpl_Pred{*gr_,nilpred,nileit,false}}});
1270}
1271
1272
1273/* **********************************************************************
1274
1275 Template subclass: Graph::ERange_Pred
1276
1277*************************************************************************/
1278
1279template <class Vertex, class Edge>
1282{
1283 return(eiterator{
1285 new EItImpl_Pred{*gr_,*(const_cast<ERange_Pred *>(this)->pred_),
1286 *eit_}}});
1287}
1288
1289template <class Vertex, class Edge>
1292{
1293 eiterator nileit{gr_->erangeAll().end()};
1294 return(eiterator{
1296 new EItImpl_Pred{*gr_,nil_epred,nileit,false}}});
1297}
1298
1299
1300/* ***************************************************************************
1301
1302 Template subclass: Graph::ERange_DepthFirst
1303
1304*******************************************************************************/
1305
1306template <class Vertex, class Edge>
1308{
1309 if (!eit.valid()) ELE_CODE_INVSTATE("Invalid edge iterator");
1310 if (eit.implementation() == nullptr)
1311 ELE_CODE_INVSTATE("Null edge iterator");
1312 return( dynamic_cast<EItImpl_DepthFirst &>(
1313 *(eit.implementation())).forceBacktrack() );
1314}
1315
1316
1317/* **********************************************************************
1318
1319 Template subclass: Graph::VItImpl_Pred
1320
1321*************************************************************************/
1322
1323template <class Vertex, class Edge>
1325{
1326 if ((isend_)||(eit_->isEnd()))
1327 ELE_CODE_INVSTATE("End iterator cannot be dereferenced");
1328}
1329
1330template <class Vertex, class Edge>
1332{
1333 if ((!isend_)&&(!eit_->isEnd()))
1334 {
1335 bool finish{false};
1336 while (!finish)
1337 {
1338 Vertex & si = operator*();
1339 if (itpred_->operator()(si)) finish = true;
1340 else
1341 {
1342 ++(*eit_);
1343 if (eit_->isEnd()) finish = true;
1344 }
1345 }
1346 }
1347}
1348
1349template <class Vertex, class Edge>
1350std::string Graph<Vertex,Edge>::VItImpl_Pred::to_string(void) const
1351{
1352 return(std::string{"vit_pred(gr:"} +
1353 std::to_string(elementa::base::to_number(gr_)) + " " +
1355 ", isend_ = " + elementa::base::kYesNoCString(isend_) +
1356 ", with eit: " + eit_->to_string() + ")");
1357}
1358
1359
1360/* **********************************************************************
1361
1362 Template subclass: Graph::EItImpl_Pred
1363
1364*************************************************************************/
1365
1366template <class Vertex, class Edge>
1367void Graph<Vertex,Edge>::EItImpl_Pred::checkDeref(void) const
1368{
1369 if ((isend_)||(eit_->isEnd()))
1370 ELE_CODE_INVSTATE("End iterator cannot be dereferenced");
1371}
1372
1373template <class Vertex, class Edge>
1374void Graph<Vertex,Edge>::EItImpl_Pred::iterateToNext(void)
1375{
1376 if ((!isend_)&&(!eit_->isEnd()))
1377 {
1378 bool finish{false};
1379 while (!finish)
1380 {
1381 if (itpred_->operator()(*(*eit_))) finish = true;
1382 else
1383 {
1384 ++(*eit_);
1385 if (eit_->isEnd()) finish = true;
1386 }
1387 }
1388 }
1389}
1390
1391template <class Vertex, class Edge>
1392std::string Graph<Vertex,Edge>::EItImpl_Pred::to_string(void) const
1393{
1394 return(std::string{"eit_pred(gr:"} +
1395 std::to_string(elementa::base::to_number(gr_)) + " " +
1397 ", isend_ = " + elementa::base::kYesNoCString(isend_) +
1398 ", with eit: " + eit_->to_string() + ")");
1399}
1400
1401
1402/* ***************************************************************************
1403
1404 Template subclass: Graph::EItImpl_DepthFirst
1405
1406*******************************************************************************/
1407
1408template <class Vertex, class Edge>
1409void Graph<Vertex,Edge>::EItImpl_DepthFirst::checkDeref(void) const
1410{
1411 if ((!elementa::patterns::Validatable::valid()) || (!ecurr_.valid()))
1412 ELE_CODE_INVSTATE("De-referencing invalid iterator");
1413 if (ecurr_.isEnd())
1414 ELE_CODE_INVSTATE("De-referencing end iterator");
1415}
1416
1417template <class Vertex, class Edge>
1418Graph<Vertex,Edge>::EItImpl_DepthFirst::EItImpl_DepthFirst(
1419 Graph & gr,
1420 const viterator & vi,
1421 bool beginorend):gr_{&gr},vparent_{vi},
1422 ecurr_{gr_->erangeAll().end()}
1423{
1424 if ((vparent_.valid()) && (!vparent_.isEnd()))
1425 {
1426 if (beginorend) ecurr_ = gr_->erangeLeaving(vparent_).begin();
1428 }
1429 // else, it remains invalid
1430}
1431
1432template <class Vertex, class Edge>
1433Edge & Graph<Vertex,Edge>::EItImpl_DepthFirst::operator*(void)
1434{
1435 checkDeref();
1436 return(*ecurr_);
1437}
1438
1439template <class Vertex, class Edge>
1440Edge * Graph<Vertex,Edge>::EItImpl_DepthFirst::pointedData(void) const
1441{
1443 ELE_CODE_INVSTATE("Invalid iterator does not point anywhere");
1444 if (ecurr_.isEnd()) return(nullptr);
1445 return(ecurr_.implementation()->pointedData());
1446}
1447
1449template <class Vertex, class Edge>
1450size_edge Graph<Vertex,Edge>::EItImpl_DepthFirst::backtrack(void)
1451{
1452 size_edge bes{0};
1453 if ((elementa::patterns::Validatable::valid()) && (!ecurr_.isEnd()))
1454 while (1)
1455 {
1456 ++ecurr_; // next sibling of current edge, skipping current's depths
1457 ++bes;
1458 if (ecurr_.isEnd()) // no more siblings
1459 {
1460 if (stack_.empty()) // nothing to backtrack to
1461 {
1462 ecurr_ = gr_->erangeAll().end();
1463 break;
1464 }
1465 else // something to backtrack to
1466 {
1467 auto & prevei = stack_.top(); // not invalid or end()
1468 vparent_ = gr_->origin(prevei);
1469 ecurr_ = prevei;
1470 stack_.pop();
1471 // increment ecurr_ in the next iteration of this loop
1472 }
1473 }
1474 else break; // go on with the sibling in next step
1475 }
1476 return(bes);
1477}
1478
1479
1480template <class Vertex, class Edge>
1481typename Graph<Vertex,Edge>::EItImpl_DepthFirst &
1482 Graph<Vertex,Edge>::EItImpl_DepthFirst::operator++(void)
1483{
1484 if ((elementa::patterns::Validatable::valid()) && (!ecurr_.isEnd()))
1485 {
1486 // look for depth first child of ecurr_
1487 auto vi = gr_->destination(ecurr_); // vi cannot be end() or invalid
1488 auto ei = gr_->erangeLeaving(vi).begin();
1489 if (ei.isEnd()) // no more depth
1490 backtrack();
1491 else
1492 {
1493 stack_.push(ecurr_);
1494 vparent_ = vi;
1495 ecurr_ = ei; // next child
1496 }
1497 }
1498 return(*this);
1499}
1500
1501template <class Vertex, class Edge>
1502std::string Graph<Vertex,Edge>::EItImpl_DepthFirst::to_string(void) const
1503{
1504 return(std::string{"eit_depthfirst(gr:"} +
1505 std::to_string(elementa::base::to_number(gr_)) + " " +
1507}
1508
1509
1510/* ***************************************************************************
1511
1512 Template subclass: Graph::EItImpl_BreadthFirst
1513
1514*******************************************************************************/
1515
1516template <class Vertex, class Edge>
1517void Graph<Vertex,Edge>::EItImpl_BreadthFirst::checkDeref(void) const
1518{
1519 if ((!elementa::patterns::Validatable::valid()) || (!ecurr_.valid()))
1520 ELE_CODE_INVSTATE("De-referencing invalid iterator");
1521 if (ecurr_.isEnd())
1522 ELE_CODE_INVSTATE("De-referencing end iterator");
1523}
1524
1525template <class Vertex, class Edge>
1526Graph<Vertex,Edge>::EItImpl_BreadthFirst::EItImpl_BreadthFirst(
1527 Graph & gr,
1528 const viterator & vi,
1529 bool beginorend):gr_{&gr},vparent_{vi},
1530 ecurr_{gr_->erangeAll().end()}
1531{
1532 if ((vparent_.valid()) && (!vparent_.isEnd()))
1533 {
1534 if (beginorend) ecurr_ = gr_->erangeLeaving(vparent_).begin();
1536 }
1537 // else, it remains invalid
1538}
1539
1540template <class Vertex, class Edge>
1541Edge & Graph<Vertex,Edge>::EItImpl_BreadthFirst::operator*(void)
1542{
1543 checkDeref();
1544 return(*ecurr_);
1545}
1546
1547template <class Vertex, class Edge>
1548Edge * Graph<Vertex,Edge>::EItImpl_BreadthFirst::pointedData(void) const
1549{
1551 ELE_CODE_INVSTATE("Invalid iterator does not point anywhere");
1552 if (ecurr_.isEnd()) return(nullptr);
1553 return(ecurr_.implementation()->pointedData());
1554}
1555
1556template <class Vertex, class Edge>
1557typename Graph<Vertex,Edge>::EItImpl_BreadthFirst &
1558 Graph<Vertex,Edge>::EItImpl_BreadthFirst::operator++(void)
1559{
1560 if ((elementa::patterns::Validatable::valid()) && (!ecurr_.isEnd()))
1561 {
1562 // add first child of current edge to the queue, if any
1563 auto vi = gr_->destination(ecurr_);
1564 auto efirst = gr_->erangeLeaving(vi).begin();
1565 if (!efirst.isEnd()) queue_.push(efirst);
1566
1567 // update current edge
1568 ++ecurr_;
1569 if (ecurr_.isEnd())
1570 {
1571 if (queue_.empty()) ecurr_ = gr_->erangeAll().end(); // finished
1572 else
1573 {
1574 ecurr_ = queue_.front(); // cannot be end() or invalid
1575 queue_.pop();
1576 }
1577 }
1578 }
1579 return(*this);
1580}
1581
1582template <class Vertex, class Edge>
1583std::string Graph<Vertex,Edge>::EItImpl_BreadthFirst::to_string(void) const
1584{
1585 return(std::string{"eit_breadthfirst(gr:"} +
1586 std::to_string(elementa::base::to_number(gr_)) + " " +
1588}
1589
1590
1591/* ***************************************************************************
1592
1593 Template class: Graph
1594
1595*******************************************************************************/
1596
1597// --------------- Private methods
1598
1599template <class Vertex, class Edge>
1601 Graph<Vertex,Edge>::edepthfirstbegin(const viterator &v) const
1603
1604 ELE_CODE_TRACE({},"v is " << v.to_string());
1605 if ((!v.valid()) || (v.isEnd()))
1606 ELE_CODE_INVARG("There is no begin depth-first edge of an invalid "
1607 "vertex iterator");
1609 impl{new EItImpl_DepthFirst{const_cast<Graph<Vertex,Edge> &>(*this),
1610 v,true}};
1611 eiterator res{impl};
1612 return(res);
1613}
1614
1615template <class Vertex, class Edge>
1617 Graph<Vertex,Edge>::edepthfirstend(const viterator &v) const
1618{
1619 if ((!v.valid()) || (v.isEnd()))
1620 ELE_CODE_INVARG("There is no begin leaving edge of an invalid "
1621 "vertex iterator");
1623 impl{new EItImpl_DepthFirst{const_cast<Graph<Vertex,Edge> &>(*this),
1624 v,false}};
1625 eiterator res{impl};
1626 return(res);
1627}
1628
1629template <class Vertex, class Edge>
1631 Graph<Vertex,Edge>::ebreadthfirstbegin(const viterator &v) const
1632{
1633 if ((!v.valid()) || (v.isEnd()))
1634 ELE_CODE_INVARG("There is no begin depth-first edge of an invalid "
1635 "vertex iterator");
1637 impl{new EItImpl_BreadthFirst{const_cast<Graph<Vertex,Edge> &>(*this),
1638 v,true}};
1639 eiterator res{impl};
1640 return(res);
1641}
1642
1643template <class Vertex, class Edge>
1645 Graph<Vertex,Edge>::ebreadthfirstend(const viterator &v) const
1646{
1647 if ((!v.valid()) || (v.isEnd()))
1648 ELE_CODE_INVARG("There is no begin leaving edge of an invalid "
1649 "vertex iterator");
1651 impl{new EItImpl_BreadthFirst{const_cast<Graph<Vertex,Edge> &>(*this),
1652 v,false}};
1653 eiterator res{impl};
1654 return(res);
1655}
1656
1657
1658// ------------- Public methods
1659
1660template <class Vertex, class Edge>
1663 const viterator & v1,
1664 const EPred & epred) const
1665{
1666 auto eit = erangeLeaving(v0).begin();
1667 while (eit != erangeLeaving(v0).end())
1668 {
1669 if ((epred(*eit))&&(destination(eit) == v1)) break;
1670 ++eit;
1671 }
1672 return(eit);
1673}
1674
1675template <class Vertex, class Edge>
1677 Graph<Vertex,Edge>::find_vertex(const Vertex & v) const
1678{
1679 auto vit = vrangeAll().begin();
1680 while (vit != vrangeAll().end()) { if (*vit == v) break; ++vit; }
1681 return(vit);
1682}
1683
1684template <class Vertex, class Edge>
1686 Graph<Vertex,Edge>::find_edge(const Edge & e) const
1687{
1688 auto eit = erangeAll().begin();
1689 while (eit != erangeAll().end()) { if (*eit == e) break; ++eit; }
1690 return(eit);
1691}
1692
1693template <class Vertex, class Edge>
1695 const viterator & vit) const noexcept
1696{
1697 if ((!it.valid())||(!vit.valid())||(it.isEnd())||(vit.isEnd()))
1698 return(false);
1699 auto eit = erangeLeaving(vit).begin();
1700 if (eit.isEnd()) return(false);
1701 auto eit2 = eit;
1702 do
1703 {
1704 ++eit2;
1705 if (!eit2.isEnd()) eit = eit2;
1706 } while (!eit2.isEnd());
1707 // here, eit points to the last (not end) leaving edge iterator from vit
1708 bool res = (it == eit);
1709 return(res);
1710}
1711
1712template <class Vertex, class Edge>
1714{
1715 size_t pos{0};
1716 viterator v = VRange_All{*this}.begin();
1717 while (v != VRange_All{*this}.end())
1718 if (v == vi) break;
1719 else
1720 {
1721 ++pos;
1722 ++v;
1723 }
1724 if (v != vi)
1726 std::string{"Could not find index for iterator "} + vi.to_string());
1727 return(pos);
1728}
1729
1730template <class Vertex, class Edge>
1733{
1734 if (pos >= size_vertices()) ELE_CODE_INVARG("Position out of range");
1735 viterator v = VRange_All{*this}.begin();
1736 while ((pos > 0) && (v != VRange_All{*this}.end()))
1737 {
1738 --pos;
1739 ++v;
1740 }
1741 return(v);
1742}
1743
1744template <class Vertex, class Edge>
1746{
1747 size_t pos{0};
1748 eiterator e = ERange_All{*this}.begin();
1749 while (e != ERange_All{*this}.end())
1750 if (e == ei) break;
1751 else
1752 {
1753 ++pos;
1754 ++e;
1755 }
1756 if (e != ei) ELE_CODE_INTERNALERR(
1757 std::string{"Could not find index for iterator "} +
1758 ei.to_string());
1759 return(pos);
1760}
1761
1762template <class Vertex, class Edge>
1765{
1766 if (pos >= size_edges()) ELE_CODE_INVARG("Position out of range");
1767 eiterator e = ERange_All{*this}.begin();
1768 while ((pos > 0) && (e != ERange_All{*this}.end()))
1769 {
1770 --pos;
1771 ++e;
1772 }
1773 return(e);
1774}
1775
1776
1777/* ***************************************************************************
1778
1779 Template class: Szer_GraphCompactText
1780
1781*******************************************************************************/
1782
1783template <class Vertex, class Edge>
1785 elementa::base::OutSerCh & chout, const GraphType & graph)
1787
1788 auto writenewline = [](elementa::base::OutSerCh & chout)
1789 {
1790 chout.put('\n');
1792 };
1793
1794 ELE_CODE_TRACE({},"Serializing number of vertices (" <<
1795 graph.size_vertices()
1796 << ")");
1798 szern.ser(chout,graph.size_vertices());
1799 writenewline(chout);
1800
1801 ELE_CODE_TRACE({},"Serializing number of edges (" <<
1802 graph.size_edges() << ")");
1803 szern.ser(chout,graph.size_edges());
1804 writenewline(chout);
1805
1806 ELE_CODE_TRACE({},"Serializing connections from edges (ebegin() == eend(): "
1807 << (typename GraphType::ERange_All{graph}.begin() ==
1808 typename GraphType::ERange_All{graph}.end())
1809 << "; ebegin().valid: " <<
1810 typename GraphType::ERange_All{graph}.begin().valid() <<
1811 ", eend().valid: "
1812 << typename GraphType::ERange_All{graph}.end().valid()
1813 << ")");
1814 auto eit = typename GraphType::ERange_All{graph}.begin();
1815 while (eit != typename GraphType::ERange_All{graph}.end())
1816 {
1817 ELE_CODE_TRACE({},"\tserializing eit: " << eit.to_string());
1818 typename GraphType::viterator v0,v1;
1819 graph.connection(eit,v0,v1);
1820 ELE_CODE_TRACE({},"\t\tedge from " << v0.to_string() << " to " <<
1821 v1.to_string());
1822
1823 szern.ser(chout,graph.vertexToPos(v0));
1824 writenewline(chout);
1825
1826 szern.ser(chout,graph.vertexToPos(v1));
1827 writenewline(chout);
1828
1829 ++eit;
1830 }
1831
1832 if (szerv_ != nullptr)
1833 {
1834 ELE_CODE_TRACE({},"Serializing vertex data...");
1835 for (auto vertex : graph.vrangeAll())
1836 {
1837 szerv_->ser(chout,vertex);
1838 writenewline(chout);
1839 }
1840 }
1841
1842 if (szere_ != nullptr)
1843 {
1844 ELE_CODE_TRACE({},"Serializing edge data...");
1845 for (auto edge : graph.erangeAll())
1846 {
1847 szere_->ser(chout,edge);
1848 writenewline(chout);
1849 }
1850 }
1851
1852/*
1853 First 20+1 chars: the number of vertices + '\n'
1854 Next 20+1 chars: the number of edges + '\n'
1855 For each edge:
1856 First 20+1 chars: index of origin vertex + '\n'
1857 Next 20+1 chars: index of destination vertex + '\n'
1858 For each vertex:
1859 Serialization of the vertex object + '\n'
1860 For each edge:
1861 Serialization of the edge object + '\n'
1862*/
1863}
1864
1865
1866
1867
1870} // end graphs namespace
1871
1872} // end adts namespace
1873
1874} // end elementa namespace
1875
1876
1877#endif
1878
1879
A range to explore all edges in the graph, no special order.
Definition: graphs.h:345
eiterator begin(void) const
Must return an iterator pointing to the first element.
Definition: graphs.h:353
ERange_All(const Graph &gr)
Constructor from a graph.
Definition: graphs.h:351
eiterator end(void) const
Must return an iterator pointing past the last element.
Definition: graphs.h:354
A range to explore from a vertex all descendant edges in breadth-first.
Definition: graphs.h:491
ERange_BreadthFirst(const Graph &gr, const viterator &v)
Constructor from a graph and a vertex iterator.
Definition: graphs.h:497
eiterator end(void) const
Must return an iterator pointing past the last element.
Definition: graphs.h:504
eiterator begin(void) const
Must return an iterator pointing to the first element.
Definition: graphs.h:502
A range to explore from a vertex all descendant edges in depth-first.
Definition: graphs.h:441
ERange_DepthFirst(const Graph &gr, const viterator &v)
Constructor from a graph and a vertex iterator.
Definition: graphs.h:462
eiterator begin(void) const
Must return an iterator pointing to the first element.
Definition: graphs.h:471
eiterator end(void) const
Must return an iterator pointing past the last element.
Definition: graphs.h:472
A range to explore all edges entering a vertex, from the first created.
Definition: graphs.h:409
ERange_Entering(const Graph &gr, const viterator &v)
Constructor from a graph and a vertex iterator.
Definition: graphs.h:415
eiterator end(void) const
Must return an iterator pointing past the last element.
Definition: graphs.h:420
eiterator begin(void) const
Must return an iterator pointing to the first element.
Definition: graphs.h:419
A range to explore all edges leaving a vertex, from the first created.
Definition: graphs.h:389
eiterator end(void) const
Must return an iterator pointing past the last element.
Definition: graphs.h:399
eiterator begin(void) const
Must return an iterator pointing to the first element.
Definition: graphs.h:398
ERange_Leaving(const Graph &gr, const viterator &v)
Constructor from a graph and a vertex iterator.
Definition: graphs.h:395
A range to explore all edges whose data satisfy some predicate.
Definition: graphs.h:365
ERange_Pred(const Graph &gr, eiterator &eit, EPred &pred)
Constructor from a graph and an edge iterator in it.
Definition: graphs.h:371
A map (hash) from edge iterators in a graph to their num. positions.
Definition: graphs.h:228
size_t size(void) const noexcept
Return the number of elements in the map.
Definition: graphs.h:252
size_t at(const eiterator &eit) const
Given an iterator, return its position in the graph in O(1).
Definition: graphs.h:259
bool empty(void) const noexcept
Return TRUE if empty.
Definition: graphs.h:255
A map (hash) from vertex iterators in a graph to their num. positions.
Definition: graphs.h:174
size_t size(void) const noexcept
Return the number of elements in the map.
Definition: graphs.h:198
bool empty(void) const noexcept
Return TRUE if empty.
Definition: graphs.h:201
size_t at(const viterator &vit) const
Given an iterator, return its position in the graph in O(1).
Definition: graphs.h:205
A range to explore all vertices in the graph, no special order.
Definition: graphs.h:290
viterator end(void) const
Must return an iterator pointing past the last element.
Definition: graphs.h:299
viterator begin(void) const
Must return an iterator pointing to the first element.
Definition: graphs.h:298
VRange_All(const Graph &gr)
Constructor from a graph.
Definition: graphs.h:296
A range to explore all vertices whose data satisfy some predicate.
Definition: graphs.h:316
VRange_Pred(const Graph &gr, eiterator &eit, Pred &pred)
Constructor from a graph and an edge iterator in it.
Definition: graphs.h:327
std::function< bool(const Vertex &) > Pred
Predicate that indicates which nodes to iterate on.
Definition: graphs.h:322
A vector of edge iterators (might be repeated).
Definition: graphs.h:150
VectorOfEIts(void)=default
Empty vector.
A vector of vertex iterators (might be repeated).
Definition: graphs.h:131
VectorOfVIts(void)=default
Empty vector.
Any class derived from this base class must be clonable.
Definition: clonable.h:83
#define ELE_CODE_TRACE_OFF
Place this inside local scope (e.g., routine) to deactivate traces there.
Definition: debugging.h:283
#define ELE_CODE_PLACE
Produces a std::string with the place of source where the macro is placed.
Definition: debugging.h:194
constexpr const char * kYesNoCString(bool b)
User-friendly yes/no output.
Definition: definitions.h:85
#define ELE_CODE_INVSTATE(expl)
To throw an invalid-state exception with an explanation.
Definition: exceptions.h:306
#define ELE_CODE_INTERNALERR(expl)
To throw an internal-error exception with an explanation.
Definition: exceptions.h:302
#define ELE_CODE_INVARG(expl)
To throw an invalid-argument exception with an explanation.
Definition: exceptions.h:310
LongestUnsigned to_number(const void *p)
Convert a pointer address to a number.
ERange_Entering erangeEntering(const viterator &v) const
Return a range to iterate on edges entering a vertex, no special order.
Definition: graphs.h:742
Vertex VertexType
For making Vertex and Edge available to the public.
Definition: graphs.h:114
ERange_Pred erangePred(eiterator &eit, const EPred &pred) const
Return a range for iterating on a predicate of the edges.
Definition: graphs.h:734
bool toLeaf(const eiterator &it) const noexcept
Return whether the given edge iterator points to an edge ending in leaf.
Definition: graphs.h:557
ERange_Leaving erangeLeaving(const viterator &v) const
Return a range to iterate on edges leaving a vertex, no special order.
Definition: graphs.h:738
virtual viterator insert(const Vertex &v)=0
Must insert one more vertex in the graph, unconnected to any other.
virtual eiterator eenteringbegin(const viterator &v) const =0
Must return the begin() iterator for ERange_Entering.
virtual void erase(const VectorOfVIts &sinds)=0
Must delete all verts indicated in SINDS (they must not be repeated)
virtual viterator vallbegin(void) const =0
Must return the begin() iterator for VRange_All.
virtual eiterator connect(const viterator &itv0, const viterator &itv1, const Edge &e)=0
Must add a new edge in the graph connecting two existing vertices.
virtual void connection(const eiterator &it, viterator &vorg, viterator &vdest) const
Fill VORG and VDEST with VRange_All iterators to the edge vertices.
Definition: graphs.h:574
virtual eiterator eallbegin(void) const =0
Must return the begin() iterator for ERange_All.
std::function< bool(const Edge &) > EPred
Predicate that indicates which edges to iterate on.
Definition: graphs.h:279
virtual void splice(Graph &oth, VectorOfVIts *svothits=nullptr, VectorOfEIts *seothits=nullptr, VectorOfVIts *svits=nullptr, VectorOfEIts *seits=nullptr)=0
Must add another graph to the one existing in this object.
virtual viterator vallend(void) const =0
Must return the end() iterator for VRange_All.
virtual size_edge size_edges(void) const =0
Must return the number of edges.
virtual eiterator eleavingend(const viterator &v) const =0
Must return the end() iterator for ERange_Leaving.
virtual eiterator eenteringend(const viterator &v) const =0
Must return the end() iterator for ERange_Entering.
virtual viterator destination(const eiterator &it) const =0
Must return a VRange_All iterator to the destination vertex of an edge.
ERange_DepthFirst erangeDepthFirst(const viterator &v) const
Return a range to iterate on edges in depth-first fashion.
Definition: graphs.h:746
Graph & operator=(Graph &&oth)=default
Move assignment.
virtual void clear(void)=0
Must clear the content of the graph.
Graph(const Graph &oth)=default
Copy constructor.
virtual size_vertex size_vertices(void) const =0
Must return the number of vertices.
static constexpr bool trivial_epred(const Edge &) noexcept
A trivial predicate that always return true.
Definition: graphs.h:282
bool isLeaf(const viterator &it) const noexcept
Return whether the given vertex iterator points to a leaf vertex.
Definition: graphs.h:553
elementa::base::MultIterator< Edge > eiterator
Edge iterator. ForwardLegacyIterator.
Definition: graphs.h:121
virtual bool empty(void) const =0
Must return true if the graph is empty.
virtual ~Graph(void)=default
Virtual destructor.
elementa::base::MultIterator< Vertex > viterator
Vertex iterator. ForwardLegacyIterator.
Definition: graphs.h:118
virtual void erase(const viterator &itv)=0
Must delete the given vertex and all edges connected to it.
VRange_All vrangeAll(void) const
Return a range to iterate on all Vertex data, no special order.
Definition: graphs.h:721
virtual eiterator eallend(void) const =0
Must return the end() iterator for VRange_All.
virtual viterator origin(const eiterator &it) const =0
Must return a VRange_All iterator to the origin vertex of an edge.
Graph(Graph &&oth)=default
Move constructor.
ERange_All erangeAll(void) const
Return a range to iterate on all Edge data, no special order.
Definition: graphs.h:730
virtual void unconnect(const eiterator &ite)=0
Must delete the given edge.
ERange_BreadthFirst erangeBreadthFirst(const viterator &v) const
Return a range to iterate on edges in breadth-first fashion.
Definition: graphs.h:750
VRange_Pred vrangePred(eiterator &eit, typename VRange_Pred::Pred &pred) const
Return a range for iterating on a predicate of the vertices.
Definition: graphs.h:725
virtual eiterator eleavingbegin(const viterator &v) const =0
Must return the begin() iterator for ERange_Leaving.
Graph & operator=(const Graph &oth)=default
Copy assignment.
virtual void unconnect(const VectorOfEIts &sinds)=0
Must delete all edges indicated in SINDS (they must not be repeated)
Szer_GraphCompactText(elementa::base::Serializer< Vertex > &szerv, elementa::base::Serializer< Edge > &szere)
Constructor.
Definition: graphs.h:1124
static constexpr bool nil_epred(const Edge &) noexcept
A trivial predicate that always return false.
Definition: graphs.h:285
Graph(void)=default
Default constructor.
All graph classes derive from this one.
Definition: graphs.h:107
Serializer for any graph in simple, compact text format.
Definition: graphs.h:1113
virtual viterator posToVertex(size_t vpos) const
Return the iterator correponding to the given position (from 0 to V-1).
Definition: graphs.h:1732
virtual size_t edgeToPos(const eiterator &eit) const
Calculate a position of a single edge from its iterator, from 0 to E-1.
Definition: graphs.h:1745
viterator end(void) const
Must return an iterator pointing past the last element.
Definition: graphs.h:1263
eiterator begin(void) const
Return the first edge that satisfies the predicate, or end.
Definition: graphs.h:1281
size_t size_vertex
For holding numbers of vertices of a graph.
Definition: graphs.h:68
bool toLastChild(const eiterator &it, const viterator &vit) const noexcept
Return whether the given edge iterator points to the last child of VIT.
Definition: graphs.h:1694
size_t size_edge
For holding numbers of edges of a graph.
Definition: graphs.h:71
MapOfVItPos(const Graph &g)
Fill the map with the info in G.
Definition: graphs.h:1198
virtual eiterator connected(const viterator &v0, const viterator &v1, const EPred &epred=trivial_epred) const
Return the first edge that connects V0 to V1 or erangeLeaving().end().
Definition: graphs.h:1662
virtual eiterator find_edge(const Edge &e) const
Look for the first edge that contains the given data.
Definition: graphs.h:1686
static size_edge forceBacktrack(eiterator &eit)
Forces the given depth-first iterator to do backtrack.
Definition: graphs.h:1307
virtual viterator find_vertex(const Vertex &v) const
Look for the first vertex that contains the given data.
Definition: graphs.h:1677
void ser(elementa::base::OutSerCh &chout, const GraphType &graph)
Serialization.
Definition: graphs.h:1784
viterator begin(void) const
Return the first vertex that satisfies the predicate, or end.
Definition: graphs.h:1253
virtual eiterator posToEdge(size_t epos) const
Return the iterator correponding to the given position (from 0 to E-1).
Definition: graphs.h:1764
eiterator end(void) const
Must return an iterator pointing past the last element.
Definition: graphs.h:1291
virtual size_t vertexToPos(const viterator &vit) const
Calculate a position of a single vertex from its iterator, from 0 to V-1.
Definition: graphs.h:1713
MapOfEItPos(const Graph &g)
Fill the map with the info in G.
Definition: graphs.h:1225
MultItImpl & operator=(const MultItImpl &oth)
Copy assignment.
Definition: iterators.h:172
std::string to_string(void) const
Return a string with info about the iterator.
Definition: iterators.h:398
std::shared_ptr< MultItImpl > Ptr
A smart pointer to the iterator implementation.
Definition: iterators.h:156
MultItImpl(void)
Default constructor: invalid state.
Definition: iterators.h:165
bool valid(void) const
Return true if the iterator is in valid state.
Definition: iterators.h:365
virtual std::string to_string(void) const
Return a string with info about the iterator implementation.
Definition: iterators.h:244
ImplementationPtr implementation(void) const
Consulting the implementation.
Definition: iterators.h:406
typename MultItImpl< Data >::Ptr ImplementationPtr
Pointer to an implementation.
Definition: iterators.h:321
Base class for implementing diverse iteration behaviors.
Definition: iterators.h:149
A mutable iterator that can have multiple iteration behaviors. Forward case.
Definition: iterators.h:299
A range is a provider of begin() and end() iterators.
Definition: iterators.h:608
std::ostream OutSerCh
"Base class" that represents any output serial channel in Elementa.
Definition: basics.h:247
void serch_isgood(RootSerCh &serchconst, const std::string &place="", const RTTextWithEnum::Combination &flags={RTTextWith::kAll_})
Throw an exception if the channel is not good; do nothing otherwise.
void ser(OutSerCh &chout, const LongestInt &obj)
Serialization of the object into CHOUT.
Base abstract class / interface for any serializer.
Definition: serializers.h:189
Serializer of integer numbers as text in fixed or non-fixed size.
Definition: serializers.h:541
Validatable & operator=(const Validatable &oth)
Derived classes must call this base optor if they have non-default ones.
Definition: validatable.h:135
bool valid(void) const noexcept
Public method to be used by users of the derived class.
Definition: validatable.h:106
void setValid(bool defval=true) noexcept
Derived classes can rewrite their own (hiding this, calling this).
Definition: validatable.h:144
Any class derived from this base class gets a "valid"/"invalid" state.
Definition: validatable.h:100