3#include "elementa/license.inc"
4#include "elementa/checks.inc"
6#ifndef ELEMENTA_ADTS_GRAPHS_GRAPHS_H
7#define ELEMENTA_ADTS_GRAPHS_GRAPHS_H
15#include <unordered_map>
105template <
class Vertex,
class Edge>
115 using EdgeType = Edge;
189 {
if (
this != &oth) copyFrom(oth);
return(*
this); }
191 {
if (
this != &oth) moveFrom(std::move(oth));
return(*
this); }
198 size_t size(
void)
const noexcept {
return(map_.size()); }
201 bool empty(
void)
const noexcept {
return(map_.empty()); }
210 std::unordered_map< void * , size_t > map_;
212 void copyFrom(
const MapOfVItPos & oth) { map_ = oth.map_; }
213 void moveFrom(MapOfVItPos && oth) { map_ = std::move(oth.map_); }
243 {
if (
this != &oth) copyFrom(oth);
return(*
this); }
245 {
if (
this != &oth) moveFrom(std::move(oth));
return(*
this); }
252 size_t size(
void)
const noexcept {
return(map_.size()); }
255 bool empty(
void)
const noexcept {
return(map_.empty()); }
264 std::unordered_map< void * , size_t > map_;
266 void copyFrom(
const MapOfEItPos & oth) { map_ = oth.map_; }
267 void moveFrom(MapOfEItPos && oth) { map_ = std::move(oth.map_); }
279 using EPred = std::function< bool(
const Edge &) >;
282 static constexpr bool trivial_epred(
const Edge &)
noexcept {
return(
true); }
285 static constexpr bool nil_epred(
const Edge &)
noexcept {
return(
false); }
322 using Pred = std::function< bool(
const Vertex &) >;
328 Pred & pred): gr_{&gr}, eit_{&eit}, pred_{&pred} {}
372 EPred & pred): gr_{&gr}, eit_{&eit}, pred_{&pred} {}
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() <<
")");
503 {
return(gr_->ebreadthfirstbegin(v_)); }
505 {
return(gr_->ebreadthfirstend(v_)); }
554 {
return((it.valid()) && (
erangeLeaving(it).begin().isEnd())); }
792 VItImpl_Pred(
const Graph & gr,
795 bool beginorend =
true):
800 {
if (beginorend) { isend_ =
false; iterateToNext(); }
801 else isend_ =
true; }
803 VItImpl_Pred(
const VItImpl_Pred & oth):
808 VItImpl_Pred & operator=(
const VItImpl_Pred & oth)
817 VItImpl_Pred(VItImpl_Pred && oth):
820 { moveFrom(std::move(oth)); }
822 VItImpl_Pred & operator=(VItImpl_Pred && oth)
827 moveFrom(std::move(oth));
833 new VItImpl_Pred{*
this}}); }
835 Vertex & operator*(
void)
836 { checkDeref();
auto vit = gr_->destination(*eit_);
839 Vertex * pointedData(
void)
const
840 {
if ((isend_)||(eit_->isEnd()))
return(
nullptr);
841 return(&(
const_cast<VItImpl_Pred *
>(
this)->
operator*())); }
843 VItImpl_Pred & operator++(
void)
844 {
if ((!isend_)&&(!eit_->isEnd())) { ++(*eit_); iterateToNext(); }
847 std::string to_string(
void)
const override;
856 void checkDeref(
void)
const;
857 void iterateToNext(
void);
859 void copyFrom(
const VItImpl_Pred & oth)
860 { isend_ = oth.isend_; gr_ = oth.gr_; itpred_ = oth.itpred_;
863 void moveFrom(VItImpl_Pred && oth)
864 { copyFrom(oth); oth.isend_ =
true; }
873 EItImpl_Pred(
const Graph & gr,
874 typename ERange_Pred::Pred & itpred,
876 bool beginorend =
true):
877 elementa::patterns::Validatable{true},
881 {
if (beginorend) { isend_ =
false; iterateToNext(); }
882 else isend_ =
true; }
884 EItImpl_Pred(
const EItImpl_Pred & oth):
885 elementa::patterns::Validatable{oth},
889 EItImpl_Pred &
operator=(
const EItImpl_Pred & oth)
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)); }
903 EItImpl_Pred &
operator=(EItImpl_Pred && oth)
908 moveFrom(std::move(oth));
914 new EItImpl_Pred{*
this}}); }
916 Edge & operator*(
void)
917 { checkDeref();
return(*(*eit_)); }
919 Edge * pointedData(
void)
const
920 {
if ((isend_)||(eit_->isEnd()))
return(
nullptr);
921 return(&(
const_cast<EItImpl_Pred *
>(
this)->
operator*())); }
923 EItImpl_Pred & operator++(
void)
924 {
if ((!isend_)&&(!eit_->isEnd())) { ++(*eit_); iterateToNext(); }
927 std::string to_string(
void)
const override;
933 typename ERange_Pred::Pred * itpred_;
936 void checkDeref(
void)
const;
937 void iterateToNext(
void);
939 void copyFrom(
const EItImpl_Pred & oth)
940 { isend_ = oth.isend_; gr_ = oth.gr_; itpred_ = oth.itpred_;
943 void moveFrom(EItImpl_Pred && oth)
944 { copyFrom(oth); oth.isend_ =
true; }
955 bool beginorend =
true);
957 EItImpl_DepthFirst(
const EItImpl_DepthFirst & oth):
958 elementa::patterns::Validatable{oth},
962 EItImpl_DepthFirst &
operator=(
const EItImpl_DepthFirst & oth)
971 EItImpl_DepthFirst(EItImpl_DepthFirst && oth):
972 elementa::patterns::Validatable{std::move(oth)},
973 elementa::base::
MultItImpl<Edge>{std::move(oth)}
976 EItImpl_DepthFirst &
operator=(EItImpl_DepthFirst && oth)
988 new EItImpl_DepthFirst{*
this}}); }
990 Edge & operator*(
void);
991 Edge * pointedData(
void)
const;
992 EItImpl_DepthFirst & operator++(
void);
993 std::string to_string(
void)
const override;
997 {
return(backtrack()); }
1001 using EStack = std::stack<eiterator>;
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_; }
1023 bool beginorend =
true);
1025 EItImpl_BreadthFirst(
const EItImpl_BreadthFirst & oth):
1026 elementa::patterns::Validatable{oth},
1030 EItImpl_BreadthFirst &
operator=(
const EItImpl_BreadthFirst &oth)
1039 EItImpl_BreadthFirst(EItImpl_BreadthFirst && oth):
1040 elementa::patterns::Validatable{std::move(oth)},
1041 elementa::base::
MultItImpl<Edge>{std::move(oth)}
1044 EItImpl_BreadthFirst &
operator=(EItImpl_BreadthFirst && oth)
1055 new EItImpl_BreadthFirst{*
this}}); }
1057 Edge & operator*(
void);
1058 Edge * pointedData(
void)
const;
1059 EItImpl_BreadthFirst & operator++(
void);
1060 std::string to_string(
void)
const override;
1064 using EQueue = std::queue<eiterator>;
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_; }
1083 static_assert( (!std::is_void<Vertex>::value) && (!std::is_void<Edge>::value),
1084 "Graph cannot work with void Vertex/Edge data" );
1110template <
class Vertex,
class Edge>
1142 "Serialization requires 64 bits or less for size_vertex and "
1161template <
class Vertex,
class Edge>
1179template <
class Vertex,
class Edge>
1197template <
class Vertex,
class Edge>
1210template <
class Vertex,
class Edge>
1213 for (
size_t f = 0; f < m.size(); ++f)
1214 map_[m[f].implementation()->pointedData()] = f;
1224template <
class Vertex,
class Edge>
1237template <
class Vertex,
class Edge>
1240 for (
size_t f = 0; f < m.size(); ++f)
1241 map_[m[f].implementation()->pointedData()] = f;
1251template <
class Vertex,
class Edge>
1257 new VItImpl_Pred{*gr_,*(
const_cast<VRange_Pred *
>(
this)->pred_),
1261template <
class Vertex,
class Edge>
1264{
static Pred nilpred = [](
const Vertex & si)->
bool {
return(
false);};
1266 eiterator nileit{gr_->erangeAll().end()};
1269 new VItImpl_Pred{*gr_,nilpred,nileit,
false}}});
1279template <
class Vertex,
class Edge>
1285 new EItImpl_Pred{*gr_,*(
const_cast<ERange_Pred *
>(
this)->pred_),
1289template <
class Vertex,
class Edge>
1293 eiterator nileit{gr_->erangeAll().end()};
1296 new EItImpl_Pred{*gr_,
nil_epred,nileit,
false}}});
1306template <
class Vertex,
class Edge>
1312 return(
dynamic_cast<EItImpl_DepthFirst &
>(
1323template <
class Vertex,
class Edge>
1326 if ((isend_)||(eit_->isEnd()))
1330template <
class Vertex,
class Edge>
1333 if ((!isend_)&&(!eit_->isEnd()))
1338 Vertex & si = operator*();
1339 if (itpred_->operator()(si)) finish =
true;
1343 if (eit_->isEnd()) finish =
true;
1349template <
class Vertex,
class Edge>
1350std::string Graph<Vertex,Edge>::VItImpl_Pred::to_string(
void)
const
1352 return(std::string{
"vit_pred(gr:"} +
1356 ", with eit: " + eit_->to_string() +
")");
1366template <
class Vertex,
class Edge>
1367void Graph<Vertex,Edge>::EItImpl_Pred::checkDeref(
void)
const
1369 if ((isend_)||(eit_->isEnd()))
1373template <
class Vertex,
class Edge>
1374void Graph<Vertex,Edge>::EItImpl_Pred::iterateToNext(
void)
1376 if ((!isend_)&&(!eit_->isEnd()))
1381 if (itpred_->operator()(*(*eit_))) finish =
true;
1385 if (eit_->isEnd()) finish =
true;
1391template <
class Vertex,
class Edge>
1392std::string Graph<Vertex,Edge>::EItImpl_Pred::to_string(
void)
const
1394 return(std::string{
"eit_pred(gr:"} +
1398 ", with eit: " + eit_->to_string() +
")");
1408template <
class Vertex,
class Edge>
1409void Graph<Vertex,Edge>::EItImpl_DepthFirst::checkDeref(
void)
const
1417template <
class Vertex,
class Edge>
1418Graph<Vertex,Edge>::EItImpl_DepthFirst::EItImpl_DepthFirst(
1421 bool beginorend):gr_{&gr},vparent_{vi},
1424 if ((vparent_.valid()) && (!vparent_.isEnd()))
1426 if (beginorend) ecurr_ = gr_->erangeLeaving(vparent_).
begin();
1432template <
class Vertex,
class Edge>
1433Edge & Graph<Vertex,Edge>::EItImpl_DepthFirst::operator*(
void)
1439template <
class Vertex,
class Edge>
1440Edge * Graph<Vertex,Edge>::EItImpl_DepthFirst::pointedData(
void)
const
1444 if (ecurr_.isEnd())
return(
nullptr);
1445 return(ecurr_.implementation()->pointedData());
1449template <
class Vertex,
class Edge>
1450size_edge Graph<Vertex,Edge>::EItImpl_DepthFirst::backtrack(
void)
1462 ecurr_ = gr_->erangeAll().end();
1467 auto & prevei = stack_.top();
1468 vparent_ = gr_->origin(prevei);
1480template <
class Vertex,
class Edge>
1481typename Graph<Vertex,Edge>::EItImpl_DepthFirst &
1482 Graph<Vertex,Edge>::EItImpl_DepthFirst::operator++(
void)
1487 auto vi = gr_->destination(ecurr_);
1488 auto ei = gr_->erangeLeaving(vi).begin();
1493 stack_.push(ecurr_);
1501template <
class Vertex,
class Edge>
1502std::string Graph<Vertex,Edge>::EItImpl_DepthFirst::to_string(
void)
const
1504 return(std::string{
"eit_depthfirst(gr:"} +
1516template <
class Vertex,
class Edge>
1517void Graph<Vertex,Edge>::EItImpl_BreadthFirst::checkDeref(
void)
const
1525template <
class Vertex,
class Edge>
1526Graph<Vertex,Edge>::EItImpl_BreadthFirst::EItImpl_BreadthFirst(
1529 bool beginorend):gr_{&gr},vparent_{vi},
1532 if ((vparent_.valid()) && (!vparent_.isEnd()))
1534 if (beginorend) ecurr_ = gr_->erangeLeaving(vparent_).
begin();
1540template <
class Vertex,
class Edge>
1541Edge & Graph<Vertex,Edge>::EItImpl_BreadthFirst::operator*(
void)
1547template <
class Vertex,
class Edge>
1548Edge * Graph<Vertex,Edge>::EItImpl_BreadthFirst::pointedData(
void)
const
1552 if (ecurr_.isEnd())
return(
nullptr);
1553 return(ecurr_.implementation()->pointedData());
1556template <
class Vertex,
class Edge>
1557typename Graph<Vertex,Edge>::EItImpl_BreadthFirst &
1558 Graph<Vertex,Edge>::EItImpl_BreadthFirst::operator++(
void)
1563 auto vi = gr_->destination(ecurr_);
1564 auto efirst = gr_->erangeLeaving(vi).begin();
1565 if (!efirst.isEnd()) queue_.push(efirst);
1571 if (queue_.empty()) ecurr_ = gr_->erangeAll().end();
1574 ecurr_ = queue_.front();
1582template <
class Vertex,
class Edge>
1583std::string Graph<Vertex,Edge>::EItImpl_BreadthFirst::to_string(
void)
const
1585 return(std::string{
"eit_breadthfirst(gr:"} +
1599template <
class Vertex,
class Edge>
1601 Graph<Vertex,Edge>::edepthfirstbegin(
const viterator &v)
const
1604 ELE_CODE_TRACE({},
"v is " << v.to_string());
1605 if ((!v.valid()) || (v.isEnd()))
1609 impl{
new EItImpl_DepthFirst{
const_cast<Graph<Vertex,Edge> &
>(*this),
1615template <
class Vertex,
class Edge>
1617 Graph<Vertex,Edge>::edepthfirstend(
const viterator &v)
const
1619 if ((!v.valid()) || (v.isEnd()))
1623 impl{
new EItImpl_DepthFirst{
const_cast<Graph<Vertex,Edge> &
>(*this),
1629template <
class Vertex,
class Edge>
1631 Graph<Vertex,Edge>::ebreadthfirstbegin(
const viterator &v)
const
1633 if ((!v.valid()) || (v.isEnd()))
1637 impl{
new EItImpl_BreadthFirst{
const_cast<Graph<Vertex,Edge> &
>(*this),
1643template <
class Vertex,
class Edge>
1645 Graph<Vertex,Edge>::ebreadthfirstend(
const viterator &v)
const
1647 if ((!v.valid()) || (v.isEnd()))
1651 impl{
new EItImpl_BreadthFirst{
const_cast<Graph<Vertex,Edge> &
>(*this),
1660template <
class Vertex,
class Edge>
1664 const EPred & epred)
const
1669 if ((epred(*eit))&&(
destination(eit) == v1))
break;
1675template <
class Vertex,
class Edge>
1680 while (vit !=
vrangeAll().end()) {
if (*vit == v)
break; ++vit; }
1684template <
class Vertex,
class Edge>
1689 while (eit !=
erangeAll().end()) {
if (*eit == e)
break; ++eit; }
1693template <
class Vertex,
class Edge>
1697 if ((!it.valid())||(!vit.valid())||(it.isEnd())||(vit.isEnd()))
1700 if (eit.isEnd())
return(
false);
1705 if (!eit2.isEnd()) eit = eit2;
1706 }
while (!eit2.isEnd());
1708 bool res = (it == eit);
1712template <
class Vertex,
class Edge>
1726 std::string{
"Could not find index for iterator "} + vi.
to_string());
1730template <
class Vertex,
class Edge>
1744template <
class Vertex,
class Edge>
1757 std::string{
"Could not find index for iterator "} +
1762template <
class Vertex,
class Edge>
1783template <
class Vertex,
class Edge>
1794 ELE_CODE_TRACE({},
"Serializing number of vertices (" <<
1799 writenewline(chout);
1801 ELE_CODE_TRACE({},
"Serializing number of edges (" <<
1804 writenewline(chout);
1806 ELE_CODE_TRACE({},
"Serializing connections from edges (ebegin() == eend(): "
1809 <<
"; ebegin().valid: " <<
1817 ELE_CODE_TRACE({},
"\tserializing eit: " << eit.to_string());
1820 ELE_CODE_TRACE({},
"\t\tedge from " << v0.
to_string() <<
" to " <<
1824 writenewline(chout);
1827 writenewline(chout);
1832 if (szerv_ !=
nullptr)
1834 ELE_CODE_TRACE({},
"Serializing vertex data...");
1837 szerv_->ser(chout,vertex);
1838 writenewline(chout);
1842 if (szere_ !=
nullptr)
1844 ELE_CODE_TRACE({},
"Serializing edge data...");
1847 szere_->ser(chout,edge);
1848 writenewline(chout);
A range to explore all edges in the graph, no special order.
eiterator begin(void) const
Must return an iterator pointing to the first element.
ERange_All(const Graph &gr)
Constructor from a graph.
eiterator end(void) const
Must return an iterator pointing past the last element.
A range to explore from a vertex all descendant edges in breadth-first.
ERange_BreadthFirst(const Graph &gr, const viterator &v)
Constructor from a graph and a vertex iterator.
eiterator end(void) const
Must return an iterator pointing past the last element.
eiterator begin(void) const
Must return an iterator pointing to the first element.
A range to explore from a vertex all descendant edges in depth-first.
ERange_DepthFirst(const Graph &gr, const viterator &v)
Constructor from a graph and a vertex iterator.
eiterator begin(void) const
Must return an iterator pointing to the first element.
eiterator end(void) const
Must return an iterator pointing past the last element.
A range to explore all edges entering a vertex, from the first created.
ERange_Entering(const Graph &gr, const viterator &v)
Constructor from a graph and a vertex iterator.
eiterator end(void) const
Must return an iterator pointing past the last element.
eiterator begin(void) const
Must return an iterator pointing to the first element.
A range to explore all edges leaving a vertex, from the first created.
eiterator end(void) const
Must return an iterator pointing past the last element.
eiterator begin(void) const
Must return an iterator pointing to the first element.
ERange_Leaving(const Graph &gr, const viterator &v)
Constructor from a graph and a vertex iterator.
A range to explore all edges whose data satisfy some predicate.
ERange_Pred(const Graph &gr, eiterator &eit, EPred &pred)
Constructor from a graph and an edge iterator in it.
A map (hash) from edge iterators in a graph to their num. positions.
size_t size(void) const noexcept
Return the number of elements in the map.
size_t at(const eiterator &eit) const
Given an iterator, return its position in the graph in O(1).
bool empty(void) const noexcept
Return TRUE if empty.
A map (hash) from vertex iterators in a graph to their num. positions.
size_t size(void) const noexcept
Return the number of elements in the map.
bool empty(void) const noexcept
Return TRUE if empty.
size_t at(const viterator &vit) const
Given an iterator, return its position in the graph in O(1).
A range to explore all vertices in the graph, no special order.
viterator end(void) const
Must return an iterator pointing past the last element.
viterator begin(void) const
Must return an iterator pointing to the first element.
VRange_All(const Graph &gr)
Constructor from a graph.
A range to explore all vertices whose data satisfy some predicate.
VRange_Pred(const Graph &gr, eiterator &eit, Pred &pred)
Constructor from a graph and an edge iterator in it.
std::function< bool(const Vertex &) > Pred
Predicate that indicates which nodes to iterate on.
A vector of edge iterators (might be repeated).
VectorOfEIts(void)=default
Empty vector.
A vector of vertex iterators (might be repeated).
VectorOfVIts(void)=default
Empty vector.
Any class derived from this base class must be clonable.
#define ELE_CODE_TRACE_OFF
Place this inside local scope (e.g., routine) to deactivate traces there.
#define ELE_CODE_PLACE
Produces a std::string with the place of source where the macro is placed.
constexpr const char * kYesNoCString(bool b)
User-friendly yes/no output.
#define ELE_CODE_INVSTATE(expl)
To throw an invalid-state exception with an explanation.
#define ELE_CODE_INTERNALERR(expl)
To throw an internal-error exception with an explanation.
#define ELE_CODE_INVARG(expl)
To throw an invalid-argument exception with an explanation.
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.
Vertex VertexType
For making Vertex and Edge available to the public.
ERange_Pred erangePred(eiterator &eit, const EPred &pred) const
Return a range for iterating on a predicate of the edges.
bool toLeaf(const eiterator &it) const noexcept
Return whether the given edge iterator points to an edge ending in leaf.
ERange_Leaving erangeLeaving(const viterator &v) const
Return a range to iterate on edges leaving a vertex, no special order.
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.
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.
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.
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.
bool isLeaf(const viterator &it) const noexcept
Return whether the given vertex iterator points to a leaf vertex.
elementa::base::MultIterator< Edge > eiterator
Edge iterator. ForwardLegacyIterator.
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.
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.
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.
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.
VRange_Pred vrangePred(eiterator &eit, typename VRange_Pred::Pred &pred) const
Return a range for iterating on a predicate of the vertices.
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.
static constexpr bool nil_epred(const Edge &) noexcept
A trivial predicate that always return false.
Graph(void)=default
Default constructor.
All graph classes derive from this one.
Serializer for any graph in simple, compact text format.
virtual viterator posToVertex(size_t vpos) const
Return the iterator correponding to the given position (from 0 to V-1).
virtual size_t edgeToPos(const eiterator &eit) const
Calculate a position of a single edge from its iterator, from 0 to E-1.
viterator end(void) const
Must return an iterator pointing past the last element.
eiterator begin(void) const
Return the first edge that satisfies the predicate, or end.
size_t size_vertex
For holding numbers of vertices of a graph.
bool toLastChild(const eiterator &it, const viterator &vit) const noexcept
Return whether the given edge iterator points to the last child of VIT.
size_t size_edge
For holding numbers of edges of a graph.
MapOfVItPos(const Graph &g)
Fill the map with the info in G.
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().
virtual eiterator find_edge(const Edge &e) const
Look for the first edge that contains the given data.
static size_edge forceBacktrack(eiterator &eit)
Forces the given depth-first iterator to do backtrack.
virtual viterator find_vertex(const Vertex &v) const
Look for the first vertex that contains the given data.
void ser(elementa::base::OutSerCh &chout, const GraphType &graph)
Serialization.
viterator begin(void) const
Return the first vertex that satisfies the predicate, or end.
virtual eiterator posToEdge(size_t epos) const
Return the iterator correponding to the given position (from 0 to E-1).
eiterator end(void) const
Must return an iterator pointing past the last element.
virtual size_t vertexToPos(const viterator &vit) const
Calculate a position of a single vertex from its iterator, from 0 to V-1.
MapOfEItPos(const Graph &g)
Fill the map with the info in G.
MultItImpl & operator=(const MultItImpl &oth)
Copy assignment.
std::string to_string(void) const
Return a string with info about the iterator.
std::shared_ptr< MultItImpl > Ptr
A smart pointer to the iterator implementation.
MultItImpl(void)
Default constructor: invalid state.
bool valid(void) const
Return true if the iterator is in valid state.
virtual std::string to_string(void) const
Return a string with info about the iterator implementation.
ImplementationPtr implementation(void) const
Consulting the implementation.
typename MultItImpl< Data >::Ptr ImplementationPtr
Pointer to an implementation.
Base class for implementing diverse iteration behaviors.
A mutable iterator that can have multiple iteration behaviors. Forward case.
A range is a provider of begin() and end() iterators.
std::ostream OutSerCh
"Base class" that represents any output serial channel in Elementa.
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.
Serializer of integer numbers as text in fixed or non-fixed size.
Validatable & operator=(const Validatable &oth)
Derived classes must call this base optor if they have non-default ones.
bool valid(void) const noexcept
Public method to be used by users of the derived class.
void setValid(bool defval=true) noexcept
Derived classes can rewrite their own (hiding this, calling this).
Any class derived from this base class gets a "valid"/"invalid" state.