3#include "elementa/license.inc"
4#include "elementa/checks.inc"
6#ifndef ELEMENTA_ADTS_TREES_H
7#define ELEMENTA_ADTS_TREES_H
63template <
class Vertex,
class Edge>
75 using Ptr = std::shared_ptr<Tree>;
97 pgraph_{reinterpret_cast<
BGraph *>(exemplar.emptyClone())} {}
105 { moveFrom(std::move(oth)); }
109 {
if (
this != & oth) copyFrom(oth);
return(*
this); }
113 {
if (
this != & oth) moveFrom(std::move(oth));
return(*
this); }
129 return(pgraph_->empty()); }
148 void clear(
void) { pgraph_->clear(); }
158 const Vertex & v,
const Edge & e);
175 void copyFrom(
const Tree & oth)
176 {
if (pgraph_ !=
nullptr)
delete pgraph_;
177 pgraph_ =
reinterpret_cast<BGraph *
>(oth.pgraph_->clone()); }
179 void moveFrom(
Tree && oth)
180 {
if (pgraph_ !=
nullptr)
delete pgraph_;
181 pgraph_ = oth.pgraph_;
194template <
class Vertex,
class Edge>
207 { szerv_ = &szerv; szere_ = &szere; }
222 "Serialization requires 64 bits or less for size_vertex and size_edge");
240template <
class Vertex,
class Edge>
248template <
class Vertex,
class Edge>
258 if (!eparent.
isEnd())
261 node = pgraph_->
origin(eparent);
263 }
while (!eparent.
isEnd());
267template <
class Vertex,
class Edge>
274 ELE_CODE_TRACE({},
"Creating root node in empty tree.");
275 return(pgraph_->
insert(v));
277 ELE_CODE_TRACE({},
"Changing existing root node content.");
283template <
class Vertex,
class Edge>
287 const Vertex & v,
const Edge & e)
290 ELE_CODE_TRACE({},
"Adding new child to parent " << parent.
to_string());
293 ELE_CODE_TRACE({},
"Inserting new vertex in the tree (to parent " <<
295 auto it = pgraph_->
insert(v);
296 ELE_CODE_TRACE({},std::endl <<
"New vertex inserted in the tree. Parent: "<<
297 parent.
to_string() <<
". Child: " << it.to_string());
298 ELE_CODE_TRACE({},
"Inserting new edge to connect vertex in the tree");
300 ELE_CODE_TRACE({},
"Child added.");
304template <
class Vertex,
class Edge>
314 ELE_CODE_TRACE({},
"eraseNode adding a connection");
316 if (std::find(vinds.begin(),vinds.end(),v0) == vinds.end())
318 if (std::find(vinds.begin(),vinds.end(),v1) == vinds.end())
322 ELE_CODE_TRACE({},
"erasing all collected connections");
323 pgraph_->
erase(vinds);
326template <
class Vertex,
class Edge>
330 if (oth.
empty())
return;
332 ELE_CODE_TRACE({},
"Copying root iterators for merging");
334 svothits.push_back(oth.
root());
335 svits.push_back(root());
336 ELE_CODE_TRACE({},
"My root: " << root().to_string() <<
", inside svits: " <<
337 svits[0].to_string());
338 ELE_CODE_TRACE({},
"Oth root: " << root().to_string() <<
339 ", inside svothits: "<< svothits[0].to_string());
340 ELE_CODE_TRACE({},
"Doing the graph splice");
341 pgraph_->
splice(*oth.pgraph_,&svothits,
nullptr,&svits,
nullptr);
342 ELE_CODE_TRACE({},
"Doing the graph connect");
343 pgraph_->
connect(svits[0],svothits[0],edge);
344 ELE_CODE_TRACE({},
"Graph merge done, other tree clearing");
355template <
class Vertex,
class Edge>
360 ELE_CODE_TRACE({},
"");
362 if (tree.
empty())
return;
364 ELE_CODE_TRACE({},
"Tree to serialize is not empty: " <<
365 tree.
graph().size_vertices() <<
" vertices, " <<
381 for (
unsigned char g = 0; g<2; ++g)
383 for (
unsigned f = 0; f < start; ++f)
399 for (
unsigned f = 0; f < length; ++f)
407 auto vit = tree.
root();
408 ELE_CODE_TRACE({},
"Serializing root: " << vit.to_string());
409 szerv_->ser(chout,*vit);
410 ELE_CODE_TRACE({},
"Root serialized ok");
413 ELE_CODE_TRACE({},
"Serializing others from root: " << vit.to_string());
414 const auto & gr =
const_cast<TreeType &
>(tree).graph();
418 auto eit = gr.erangeDepthFirst(vit).begin();
419 bool changelevel{
true};
424 auto vchildit = gr.destination(eit);
425 if (changelevel) level = tree.
depth(vchildit);
426 writebranch(chout,level,2);
429 szere_->ser(chout,*eit);
434 szerv_->ser(chout,*vchildit);
437 changelevel = ( (!gr.toLeaf(eit)) ||
438 (gr.toLastChild(eit,gr.origin(eit))) );
eiterator begin(void) const
Must return an iterator pointing to the first element.
eiterator begin(void) const
Must return an iterator pointing to the first element.
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.
A vector of vertex iterators (might be repeated).
virtual Clonable * emptyClone(void) const
Derived classes can override this to provide a clone that is "empty".
#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.
#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.
virtual viterator insert(const Vertex &v)=0
Must insert one more vertex in the graph, unconnected to any other.
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 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 size_edge size_edges(void) const =0
Must return the number of edges.
ERange_DepthFirst erangeDepthFirst(const viterator &v) const
Return a range to iterate on edges in depth-first fashion.
virtual size_vertex size_vertices(void) const =0
Must return the number of vertices.
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 viterator origin(const eiterator &it) const =0
Must return a VRange_All iterator to the origin vertex of an edge.
All graph classes derive from this one.
size_t size_vertex
For holding numbers of vertices of a graph.
size_t size_edge
For holding numbers of edges of a graph.
bool isEnd(void) const
Check for end. If it is invalid or points not to end, return false.
std::string to_string(void) const
Return a string with info about the iterator.
bool valid(void) const
Return true if the iterator is in valid state.
A mutable iterator that can have multiple iteration behaviors. Forward case.
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.
Base abstract class / interface for any serializer.
bool empty(void) const
Return TRUE if the tree is empty.
graphs::Graph< Vertex, Edge > BGraph
Base Graph class of any particular graph implementation used in the tree.
virtual ~Tree(void)
Virtual destructor.
Tree(const BGraph &exemplar)
Constructor.
Tree(const Tree &oth)
Copy constructor.
Tree(Tree &&oth)
Move constructor.
BGraph & graph(void) const
return a reference to the internal graph.
std::shared_ptr< Tree > Ptr
Pointer to a tree.
Tree & operator=(const Tree &oth)
Copy assignment.
void clear(void)
Clear the tree.
Tree & operator=(Tree &&oth)
Move assignment.
std::vector< Ptr > Forest
A forest is a set of pointers to trees.
Szer_TreeText(elementa::base::Serializer< Vertex > &szerv, elementa::base::Serializer< Edge > &szere)
Constructor: configure the serializer.
Serializer of any tree as a text with a tree-like structure.
This class is the base for any tree implementation.
BGraph::viterator addChild(const typename BGraph::viterator &parent, const Vertex &v, const Edge &e)
Add a new child to a given node, as the last child of the node.
BGraph::viterator setRoot(const Vertex &v)
If the tree has a root, changes its value by V; otherwise, add V as root.
graphs::size_edge depth(const typename BGraph::viterator &n) const
Return the depth of the given node in the tree (0 for root).
void eraseNode(const typename BGraph::viterator &node)
Erase a node and all its descendants.
BGraph::viterator root(void) const
Return an iterator to the root of the tree or to end() if empty.
void splice(Tree &oth, const Edge &edgeval)
Move OTH to this tree, connecting its root to this root, and clearing it.
void ser(elementa::base::OutSerCh &chout, const TreeType &tree)
Serialize.