libtree/include/Tree/tree.hpp

353 lines
9.7 KiB
C++

#ifndef __TREE_BASENODE_HPP__
#define __TREE_BASENODE_HPP__
/**
* @file
* @brief header file for the libtree++ library
* @author Dominik Meyer <dmeyer@hsu-hh.de>
* @date 2019-03-03
* @copyright 2019 GPLv2 by Dominik Meyer
*/
/*
Copyright (C) 2019 Dominik Meyer
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
#include <memory>
#include <string>
#include <list>
#include <algorithm>
/**
* @brief main namespace for the libtree++ library
*/
namespace Tree
{
/**
* @brief base node for all nodes within the tree, implementing base tree methods
*/
class BaseNode : public std::enable_shared_from_this<Tree::BaseNode>
{
private:
/// the parent node of a node ;)
std::shared_ptr<Tree::BaseNode> parent;
/// all child nodes of a node
std::list<std::shared_ptr<Tree::BaseNode>> children;
public:
/**
* @brief print the tree starting with the current node to stdout
*
* @param depth - used for indenting the tree
*/
void printTree(const uint32_t depth);
/**
* @brief print the tree starting with the current node to stdout
*
* just calls printTree(0)
*/
void printTree() { printTree(0); }
/**
* @brief returns a string representing this node
*
* this method has to be implemented by all nodes extending this class
*
* @return std::string representing this node
*/
virtual const std::string toString() const = 0;
/**
* @brief returns the type of this node as a string
*
* this method has to be implemented by all nodes extending this class
*
* @return std::string representing the type of this node
*/
virtual const std::string type() const = 0;
/**
* @brief returns the base of this node as a string
*
* this method has to be implemented by all nodes extending this class
*
* a base is some kind of way to group nodes belonging to a certain topic
*
* @return std::string representing the type of this node
*/
virtual const std::string base() const = 0;
/**
* @brief return the parent node of the node
*
* @return nullptr - no parent is set, therefore, it should be a root node
* @return a std::shared_ptr to the the parent node
*/
const std::shared_ptr<Tree::BaseNode> getParent() const { return parent;}
/**
* @brief set the parent node of this node
*
* @param p - the parent node as a shared_ptr
*/
void setParent(const std::shared_ptr<Tree::BaseNode> &p) {parent=p;}
/**
* @brief returns an iterator to the beginning of the list of children
*
* @return iterator to the beginning of the list of children
*/
std::list<std::shared_ptr<Tree::BaseNode>>::iterator getChildrenBegin() {return children.begin();}
/**
* @brief returns an iterator to the end of the list of children
*
* @return iterator to the end of the list of children
*/
std::list<std::shared_ptr<Tree::BaseNode>>::iterator getChildrenEnd() {return children.end();}
/**
* @brief returns the nr of direct children
*
* @return the nr of direct children
*/
const unsigned int getNrDirectChildren() const { return children.size(); }
/**
* @brief returns the nr of all children
*
* @return the nr of all children
*/
const unsigned int getNrChildren() const;
/**
* @brief deletes all the children and their children and ... from the tree
*/
void deleteChildren();
/**
* @brief deletes the given node and all its children
*
* @param c - the node to delete
*
*/
void deleteChild(const std::shared_ptr<Tree::BaseNode> &c);
/**
* @brief remove the given node from the children of the node
*
* remove is not delete. The node gets just disconnected from the tree
*
* @param c - the node to remove from the nodes list of children
*
*/
void removeChild(const std::shared_ptr<Tree::BaseNode> &c);
/**
* @brief adds a child to the node which is already a shared_ptr
*
* @param c - a shared_ptr to a BaseNode
*/
void addChild(const std::shared_ptr<Tree::BaseNode> &c) {c->setParent(shared_from_this()); children.push_back(c); }
/**
* @brief adds a container of nodes to the list of children
*
* @param begin - iterator to the beginning of the container of objects of type std::shared_ptr<Tree::BaseNode>
* @param end - iterator to the end of the container of objects of type std::shared_ptr<Tree::BaseNode>
*/
template <typename Iter>
void addChildren(Iter begin, Iter end) { std::copy( begin, end, std::back_inserter( children ) );}
/**
* @brief finds the next node in the tree of a given type
*
* @param t - the type of the node as a string
*
* @return nullptr - a node of that type could not be found
* @return the found node as a shared_ptr
*/
std::shared_ptr<Tree::BaseNode> findNext(const std::string &t);
/**
* @brief finds all nodes of a given type
*
* @param type - the type of the node as a string
* @param c - a container for holding all found nodes, has to be holding objects of type std::shared_ptr<Tree::BaseNode>
*/
template <typename Container>
void findAll(const std::string &type, Container &c);
/**
* @brief finds all nodes of a given base
*
* @param base - the base type of the node as a string
* @param c - a container for holding all found nodes, has to be holding objects of type std::shared_ptr<Tree::BaseNode>
*/
template <typename Container>
void findAllBase(const std::string &base, Container &c);
/**
* @brief checks if the given node is a direct child of this node
*
* @param n - shared_ptr of the node to check
*
* @return true - the node is a direct child
* @return false - the node is not a direct child
*/
const bool isDirectChild(std::shared_ptr<Tree::BaseNode> &n) const;
/**
* @brief checks if the given node is a child of this node
*
* @param n - shared_ptr of the node to check
*
* @return true - the node is a child
* @return false - the node is not a child
*/
const bool isChild(std::shared_ptr<Tree::BaseNode> &n) const;
/**
* @brief replaces this node within the tree with the given one
*
* this means moving all children to the given node and setting all of their parents
* to the new node
*
* @param n - the new node to replace the current one with
*/
void replace(std::shared_ptr<Tree::BaseNode> n);
/**
* @brief overriding the to string operator
*
* used to convert the object on the fly to a string
*
* @return a string representing this object
*/
operator std::string() const { return toString(); }
};
/**
* @brief stream operator override
*
* make it possible to use nodes within output streams
*
* @param Str - the output stream to stream to ;)
* @param v - the node which should be streamed to Str
*
* @return the outstream returned
*/
inline std::ostream & operator<<(std::ostream & Str, const Tree::BaseNode &v) {
Str << v.toString();
return Str;
}
/*
* Some basic Node Types
*/
/**
* @brief class representing the Root of a Tree
*/
class TreeRoot : public Tree::BaseNode
{
public:
/**
* @brief returns the type of this node as a string
*
* this method has to be implemented by all nodes extending this class
*
* @return std::string representing the type of this node
*/
const std::string type() const { return "Tree::TreeRoot";}
/**
* @brief returns the base of this node as a string
*
* this method has to be implemented by all nodes extending this class
*
* a base is some kind of way to group nodes belonging to a certain topic
*
* @return std::string representing the type of this node
*/
const std::string base() const { return "Tree::Base";}
/**
* @brief returns a string representing this node
*
* this method has to be implemented by all nodes extending this class
*
* @return std::string representing this node
*/
virtual const std::string toString() const { return type();};
};
/**
* @brief class representing a temporary node within the tree
*/
class TempNode : public Tree::BaseNode
{
public:
/**
* @brief returns the type of this node as a string
*
* this method has to be implemented by all nodes extending this class
*
* @return std::string representing the type of this node
*/
const std::string type() const { return "Tree::TempNode";}
/**
* @brief returns the base of this node as a string
*
* this method has to be implemented by all nodes extending this class
*
* a base is some kind of way to group nodes belonging to a certain topic
*
* @return std::string representing the type of this node
*/
const std::string base() const { return "Tree::Base";}
/**
* @brief returns a string representing this node
*
* this method has to be implemented by all nodes extending this class
*
* @return std::string representing this node
*/
virtual const std::string toString() const { return type();};
};
}; // namespace Tree
#endif