Skip to content
Snippets Groups Projects
tree.hpp 35.3 KiB
Newer Older
 * tree.hpp
 *
 * This file is part of Algorithms library toolkit.
 * Copyright (C) 2017 Jan Travnicek (jan.travnicek@fit.cvut.cz)

 * Algorithms library toolkit 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.

 * Algorithms library toolkit 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 Algorithms library toolkit.  If not, see <http://www.gnu.org/licenses/>.
 *
 * Created on: Jul 2, 2016
 * Author: Jan Travnicek
 */

#ifndef __TREE_HPP_
#define __TREE_HPP_

#include <memory>
#include <sstream>
#include <string>
#include "vector.hpp"
#include "compare.hpp"
#include "iterator.hpp"
#include "tree_base.hpp"

namespace ext {
/**
 * \brief
 * Class introducing a tree with interface trying to be close to the interface of standard library containers.
 *
 * The tree is a hierarchical structure of nodes with parent child relationship, where the children are ordered and indexed by integers.
 *
 * \tparam T the type of values inside nodes of the tree
 */
Jan Trávníček's avatar
Jan Trávníček committed
template < class T >
class tree {
	/**
	 * \brief
	 * The value in the root node of the tree
	 */
	/**
	 * \brief
	 * Pointer to the parent of the node. Null pointer for root of a tree.
	 */

	/**
	 * \brief
	 * Container of children of the root node of the tree.
	 *
	 * The children are trees themselves, hence the subtree of a tree is itself a tree.
	 */
	ext::vector < tree > m_children;
	/**
	 * \brief
	 * Getter of the parent node. Null if the node is root.
	 *
	 * \return pointer to the parent node
	 */
Jan Trávníček's avatar
Jan Trávníček committed
	tree * getParent ( ) {
	/**
	 * \brief
	 * Getter of the parent node. Null if the node is root.
	 *
	 * \return pointer to the parent node
	 */
Jan Trávníček's avatar
Jan Trávníček committed
	const tree * getParent ( ) const {
	/**
	 * \brief
	 * Getter of the value in the root node.
	 *
	 * \return the value in the root node
	 */
Jan Trávníček's avatar
Jan Trávníček committed
	T & getData ( ) {
	/**
	 * \brief
	 * Getter of the value in the root node.
	 *
	 * \return the value in the root node
	 */
Jan Trávníček's avatar
Jan Trávníček committed
	const T & getData ( ) const {
	/**
	 * \brief
	 * Getter of children of the root node.
	 *
	 * \return children of the root node
	 */
	ext::vector < tree > & getChildren ( ) {
		return m_children;
	/**
	 * \brief
	 * Getter of children of the root node.
	 *
	 * \return children of the root node
	 */
	const ext::vector < tree > & getChildren ( ) const {
		return m_children;
	/**
	 * \brief
	 * The iterator type over children of the node
	 */
	typedef typename ext::vector < tree >::const_iterator const_children_iterator;
	/**
	 * \brief
	 * The iterator type over children of the node
	 */
	typedef typename ext::vector < tree >::iterator children_iterator;

	/**
	 * \brief
	 * The iterator type over structure of the tree representing nodes and node_ends
	 *
	 * The iterator performs a top to bottom, left to right or depth first travrsal stopping at each node twice. Once as it enters it the first time and second time when it leaves it (on the way to its parent).
	 */
	class const_structure_iterator : public std::iterator < std::bidirectional_iterator_tag, T > {
		/**
		 * \brief
		 * The underlying iterator within some list of children.
		 */
		typename ext::vector < tree >::const_iterator node;

		/**
		 * \brief
		 * The depth of the current pointed to node.
		 */
		unsigned level;

		/**
		 * \brief
		 * True if the iterator is pointing to a tree node in the first visit, false in the second (leaving case).
		 */
		bool virtual_node;

		/**
		 * \brief
		 * True if the iterator is one position after the last valid iterator value.
		 */
		bool isEnd;

	public:
		/**
		 * \brief
		 * Constructor of the iterator based on the iterator to child list
		 *
		 * \param n the iterator to child list
		 */
		const_structure_iterator ( typename ext::vector < tree >::const_iterator n ) : node ( n ), level ( 0 ), virtual_node ( false ), isEnd ( false ) {
		/**
		 * \brief
		 * Advance the iterator.
		 *
		 * \return the updated iterator
		 */
		const_structure_iterator & operator ++( ) {
			if ( virtual_node ) {
				const tree * parent = node->getParent ( );
Jan Trávníček's avatar
Jan Trávníček committed
				++node;
				if ( parent != nullptr ) {
					if ( node == parent->getChildren ( ).end ( ) ) {
						node = typename ext::vector < tree >::const_iterator ( parent );
					} else {
						virtual_node = false;
					}
				} else {
					virtual_node = false;
					isEnd = true;
				}
			} else {
				typename ext::vector < tree >::const_iterator newIter = node->getChildren ( ).begin ( );

				if ( newIter != node->getChildren ( ).end ( ) ) {
					++level;
					node = newIter;
				} else {
					virtual_node = true;
				}
			}

			return * this;
		}

		/**
		 * \brief
		 * Advance the iterator.
		 *
		 * \return the original iterator
		 */
		const_structure_iterator operator ++( int ) {
			const_structure_iterator tmp ( * this );

			operator ++( );
			return tmp;
		}

		/**
		 * \brief
		 * Retract the iterator.
		 *
		 * \return the updated iterator
		 */
		const_structure_iterator & operator --( ) {
			if ( isEnd ) {
				--node;
				virtual_node = true;
				isEnd = false;
			} else if ( virtual_node ) {
				typename ext::vector < tree >::const_iterator newIter = node->getChildren ( ).end ( );

				if ( newIter != node->getChildren ( ).begin ( ) ) {
					++level;
					node = newIter;
					--node;
				} else {
					virtual_node = false;
				}
			} else {
				const tree * parent = node->getParent ( );
				if ( parent != nullptr ) {
					if ( node == parent->getChildren ( ).begin ( ) ) {
						node = typename ext::vector < tree >::const_iterator ( parent );
					} else {
						--node;
						virtual_node = true;
					}
				}
			}

			return * this;
		}

		/**
		 * \brief
		 * Retract the iterator.
		 *
		 * \return the original iterator
		 */
		const_structure_iterator operator --( int ) {
			const_structure_iterator tmp ( * this );

			operator --( );
			return tmp;
		}

		/**
		 * \brief
		 * Compare the iterators for equality.
		 *
		 * \param other the other instance
		 *
		 * \return true if the two iterators are the same, false othervise
		 */
		bool operator ==( const const_structure_iterator & other ) {
			return node == other.node && virtual_node == other.virtual_node;
		}

		/**
		 * \brief
		 * Compare the iterators for nonequality.
		 *
		 * \param other the other instance
		 *
		 * \return true if the two iterators are not the same, false othervise
		 */
		bool operator !=( const const_structure_iterator & other ) {
			return !( * this == other );
		}

		/**
		 * \brief
		 * Dereference the iterator by accessing the pointed node value.
		 *
		 * \return the value of node pointed to
		 */
		const T & operator *( ) const {
			return node->getData ( );
		}

		/**
		 * \brief
		 * Dereference the iterator by accessing the pointed node value.
		 *
		 * \return the value of node pointed to
		 */
		const T * operator ->( ) const {
			return & node->getData ( );
		}

		/**
		 * \brief
		 * Retrieves what is the depth of node the iterator is pointing to.
		 *
		 * \return the depth of node pointed to
		 */
		unsigned getLevel ( ) const {
			return level;
		}

		/**
		 * \brief
		 * Allows to distinguish entry or leave visit of a pointed to node.
		 *
		 * \return true if the iterator is pointing to a tree node in the first visit, false in the second (leaving case).
		 */
		bool getVirtual ( ) const {
			return virtual_node;
		}

Jan Trávníček's avatar
Jan Trávníček committed
		template < class F >
		friend class tree;
	};

	/**
	 * \brief
	 * The iterator type over structure of the tree following preorder traversal.
	 *
	 * The prefix iterator is constructed as a wrapper over structure iterator, it selects only non-virtual nodes.
	 */
	class const_prefix_iterator : public std::iterator < std::bidirectional_iterator_tag, T > {
		/**
		 * \brief
		 * The underlying structure iterator.
		 */
		const_structure_iterator node;

	public:
		/**
		 * \brief
		 * Constructor of the iterator based on the iterator to child list
		 *
		 * \param n the iterator to child list
		 */
		const_prefix_iterator ( typename ext::vector < tree >::const_iterator n ) : node ( n ) {
		/**
		 * \brief
		 * Advance the iterator.
		 *
		 * \return the updated iterator
		 */
		const_prefix_iterator & operator ++( ) {
			while ( ( ++node ).getVirtual ( ) );

			return * this;
		}

		/**
		 * \brief
		 * Advance the iterator.
		 *
		 * \return the original iterator
		 */
		const_prefix_iterator operator ++( int ) {
			const_prefix_iterator tmp ( * this );

			operator ++( );
			return tmp;
		}

		/**
		 * \brief
		 * Retract the iterator.
		 *
		 * \return the updated iterator
		 */
		const_prefix_iterator & operator --( ) {
			while ( ( --node ).getVirtual ( ) );

			return * this;
		}

		/**
		 * \brief
		 * Retract the iterator.
		 *
		 * \return the original iterator
		 */
		const_prefix_iterator operator --( int ) {
			const_prefix_iterator tmp ( * this );

			operator --( );
			return tmp;
		}

		/**
		 * \brief
		 * Compare the iterators for equality.
		 *
		 * \param other the other instance
		 *
		 * \return true if the two iterators are the same, false othervise
		 */
		bool operator ==( const const_prefix_iterator & other ) {
			return node == other.node;
		}

		/**
		 * \brief
		 * Compare the iterators for nonequality.
		 *
		 * \param other the other instance
		 *
		 * \return true if the two iterators are not the same, false othervise
		 */
		bool operator !=( const const_prefix_iterator & other ) {
			return !( * this == other );
		}

		/**
		 * \brief
		 * Dereference the iterator by accessing the pointed node value.
		 *
		 * \return the value of node pointed to
		 */
		const T & operator *( ) const {
			return * node;
		}

		/**
		 * \brief
		 * Dereference the iterator by accessing the pointed node value.
		 *
		 * \return the value of node pointed to
		 */
		const T * operator ->( ) const {
			return & node->getData ( );
		}

		/**
		 * \brief
		 * Retrieves what is the depth of node the iterator is pointing to.
		 *
		 * \return the depth of node pointed to
		 */
		unsigned getLevel ( ) const {
			return node.getLevel ( );
		}

Jan Trávníček's avatar
Jan Trávníček committed
		template < class F >
		friend class tree;
	};

	/**
	 * \brief
	 * The iterator type over structure of the tree following postorder traversal
	 *
	 * The prefix iterator is constructed as a wrapper over structure iterator, it selects only virtual nodes.
	 */
	class const_postfix_iterator : public std::iterator < std::bidirectional_iterator_tag, T > {
		/**
		 * \brief
		 * The underlying structure iterator.
		 */
		const_structure_iterator node;

	public:
		/**
		 * \brief
		 * Constructor of the iterator based on the iterator to child list
		 *
		 * \param n the iterator to child list
		 */
		const_postfix_iterator ( typename ext::vector < tree >::const_iterator n ) : node ( n ) {
		/**
		 * \brief
		 * Advances the iterator.
		 *
		 * \return the updated iterator
		 */
		const_postfix_iterator & operator ++( ) {
			while ( !( ++node ).getVirtual ( ) && !node.isEnd );

			return * this;
		}

		/**
		 * \brief
		 * Advances the iterator.
		 *
		 * \return the original iterator
		 */
		const_postfix_iterator operator ++( int ) {
			const_postfix_iterator tmp ( * this );

			operator ++( );
			return tmp;
		}

		/**
		 * \brief
		 * Retract the iterator.
		 *
		 * \return the updated iterator
		 */
		const_postfix_iterator & operator --( ) {
			while ( !( --node ).getVirtual ( ) );

			return * this;
		}

		/**
		 * \brief
		 * Retract the iterator.
		 *
		 * \return the original iterator
		 */
		const_postfix_iterator operator --( int ) {
			const_postfix_iterator tmp ( * this );

			operator --( );
			return tmp;
		}

		/**
		 * \brief
		 * Compare the iterators for equality.
		 *
		 * \brief other the other instance
		 *
		 * \return true if the two iterators are the same, false othervise
		 */
		bool operator ==( const const_postfix_iterator & other ) {
			return node == other.node;
		}

		/**
		 * \brief
		 * Compare the iterators for nonequality.
		 *
		 * \brief other the other instance
		 *
		 * \return true if the two iterators are not the same, false othervise
		 */
		bool operator !=( const const_postfix_iterator & other ) {
			return !( * this == other );
		}

		/**
		 * \brief
		 * Dereference the iterator by accessing the pointed node value.
		 *
		 * \return the value of node pointed to
		 */
		const T & operator *( ) const {
			return * node;
		}

		/**
		 * \brief
		 * Dereference the iterator by accessing the pointed node value.
		 *
		 * \return the value of node pointed to
		 */
		const T * operator ->( ) const {
			return & node->getData ( );
		}

		/**
		 * \brief
		 * Retrieves what is the depth of node the iterator is pointing to.
		 *
		 * \return the depth of node pointed to
		 */
		unsigned getLevel ( ) const {
			return node.getLevel ( );
		}

Jan Trávníček's avatar
Jan Trávníček committed
		template < class F >
		friend class tree;
	};

// ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

private:
	/**
	 * \brief
	 * vector of trees construction helper. Trees are nullary nodes having value given by values in the range begin to end.
	 *
	 * \tparam Iterator the type of iterators forming the range
	 *
	 * \param begin the start of the range of values
	 * \param end the end of the range of values
	 *
	 * \return vector of unary nodes constructed from the begin and end range
	 */
Jan Trávníček's avatar
Jan Trávníček committed
	template < typename Iterator >
	ext::vector < tree > fromIterator ( Iterator begin, Iterator end ) {
		ext::vector < tree > res;
Jan Trávníček's avatar
Jan Trávníček committed
		for ( ; begin != end; ++begin )
			res.push_back ( tree ( * begin, { } ) );
Jan Trávníček's avatar
Jan Trávníček committed
		return res;
	/**
	 * \brief
	 * Inserts a subtree into a tree.
	 *
	 * \param position the specification of position in children of the node where to add subtrees
	 * \param value a subtree to insert
	 *
	 * \return updated position iterator pointing to the first node inserted
	 */
	const_children_iterator insert ( const_children_iterator position, tree < T > && value ) {
		ext::vector < tree > & children = const_cast < ext::vector < tree > & > ( getChildren ( ) );
		typename ext::vector < tree >::iterator iter = children.insert ( position, std::move ( value ) );
		iter->m_parent = this;
Jan Trávníček's avatar
Jan Trávníček committed
		return iter;
	/**
	 * \brief
	 * Inserts a subtree into a tree.
	 *
	 * \param position the specification of position in children of the node where to add subtrees
	 * \param value a subtree to insert
	 *
	 * \return updated position iterator pointing to the first node inserted
	 */
	const_children_iterator insert ( const_children_iterator position, const tree < T > & value ) {
		return insert ( position, tree < T > ( value ) );
	/**
	 * \brief
	 * Insert helper for insertion specified by position in children and inserted subtrees given by range of iterators.
	 *
	 * \param position the specification of position in children of the node where to add subtrees
	 * \param begin the start of the range of subtrees
	 * \param end the end of the range of subtrees
	 *
	 * \return updated position iterator pointing to the first node inserted
	 */
	const_children_iterator insert ( const_children_iterator position, const_children_iterator begin, const_children_iterator end ) {
		ext::vector < tree > & children = const_cast < ext::vector < tree > & > ( getChildren ( ) );
Jan Trávníček's avatar
Jan Trávníček committed

		typename ext::vector < tree >::iterator iter = children.insert ( position, begin, end );

		for ( typename ext::vector < tree >::iterator iterCopy = iter; begin != end; ++begin, ++iterCopy )
			iterCopy->m_parent = this;
	/**
	 * \brief
	 * Inserts a subtrees into a tree. The subtrees are nullary nodes having value given by values in the range begin to end.
	 *
	 * \tparam Iterator the type of iterators forming the range
	 *
	 * \param position the specification of position in children of the node where to add subtrees
	 * \param begin the start of the range of values
	 * \param end the end of the range of values
	 *
	 * \return updated position iterator pointing to the first node inserted
	 */
	template < class Iterator >
	const_children_iterator insert ( const_children_iterator position, Iterator begin, Iterator end ) {
		ext::vector < tree > children = fromIterator ( begin, end );
		return insert ( position, children.cbegin ( ), children.cend ( ) );
	}

// ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

public:
	/**
	 * \brief
	 * Constructor of the tree from value to be stored in the root node and children trees.
	 *
	 * \param data the value to be stored in the root
	 * \param children list of subtrees
	 */
	tree ( T && data, ext::vector < tree > && children ) : m_data ( std::move ( data ) ), m_parent ( nullptr ), m_children ( std::move ( children ) ) {
		for ( tree & child : m_children )
	/**
	 * \brief
	 * Constructor of the tree from value to be stored in the root node and children trees.
	 *
	 * \param data the value to be stored in the root
	 * \param children list of subtrees
	 */
	tree ( const T & data, const ext::vector < tree > & subtrees ) : tree ( T ( data ), ext::vector < tree > ( subtrees ) ) {
	/**
	 * \brief
	 * Constructor of the tree from value to be stored in the root node and pack of children trees.
	 *
	 * \tparam Types ... pack of types convertible to tree
	 *
	 * \param data the value to be stored in the root
	 * \param subtrees ... pack of subtrees
	 */
	template < typename ... Types >
	tree ( const T & data, Types ... subtrees ) : tree ( data, ext::vector < tree > { subtrees ... } ) {
	/**
	 * \brief
	 * Constructor of the tree from value to be stored in the root node and pack of children trees.
	 *
	 * \tparam Types ... pack of types convertible to tree
	 *
	 * \param data the value to be stored in the root
	 * \param subtrees ... pack of subtrees
	 */
	template < typename ... Types >
	tree ( T && data, Types ... subtrees ) : tree ( std::move ( data ), ext::vector < tree > { subtrees ... } ) {
	/**
	 * \brief
	 * Constructor of the tree from value to be stored in the root node and range of values to construct nullary nodes from range of values.
	 *
	 * \param data the value to be stored in the root
	 * \param begin the iterator to the begining of values range
	 * \param end the iterator to the end of values range
	 */
	template < typename Iterator, typename std::enable_if < ext::is_iterator < Iterator >::value >::type >
	tree ( const T & data, Iterator begin, Iterator end ) : tree ( data, fromIterator ( begin, end ) ) {
	/**
	 * \brief
	 * Constructor of the tree from value to be stored in the root node and range of subtrees.
	 *
	 * \param data the value to be stored in the root
	 * \param begin the iterator to the begining of subtree range
	 * \param end the iterator to the end of subtree range
	 */
	tree ( const T & data, const_children_iterator begin, const_children_iterator end ) : tree ( data, ext::vector < tree > ( begin, end ) ) {
	/**
	 * \brief
	 * Dectructor of the tree
	 */
Jan Trávníček's avatar
Jan Trávníček committed
	~tree ( ) noexcept {
	/**
	 * \brief
	 * Copy constructor of the tree.
	 *
	 * \param other the other instace of the tree
	 */
	tree ( const tree & other ) : m_data ( other.m_data ), m_parent ( other.m_parent ), m_children ( other.m_children ) {
		for ( tree & child : m_children )
			child.m_parent = this;
	/**
	 * \brief
	 * Move constructor of the tree.
	 *
	 * \param other the other instace of the tree
	 */
	tree ( tree && other ) noexcept : m_data ( std::move ( other.m_data ) ), m_parent ( other.m_parent ), m_children ( std::move ( other.m_children ) ) {
		for ( tree & child : m_children )
			child.m_parent = this;
	/**
	 * \brief
	 * Copy operator of assignment of the tree.
	 *
	 * \param other the other instace of the tree
	 *
	 * \return the assigned to instance
	 */
Jan Trávníček's avatar
Jan Trávníček committed
	tree & operator =( const tree & node ) {
		return this->operator =( tree ( node ) );
	}

	/**
	 * \brief
	 * Move operator of assignment of the tree.
	 *
	 * \param other the other instace of the tree
	 *
	 * \return the assigned to instance
	 */
Jan Trávníček's avatar
Jan Trávníček committed
	tree & operator =( tree && node ) noexcept {
		m_data = std::move ( node.m_data );
		m_children = std::move ( node.m_children );
		for ( tree & child : m_children )
			child.m_parent = this;
Jan Trávníček's avatar
Jan Trávníček committed

		return * this;
// ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

	 * Getter of a children iterator to the begining of children
	 * \return iterator to the first child
	const_children_iterator begin ( ) const {
		return m_children.begin ( );
	 * Getter of a children iterator to the begining of children
	 *
	 * \return iterator to the first child
	children_iterator begin ( ) {
		return m_children.begin ( );
	 * Getter of a children iterator one after the last child
	 * \return iterator one after the last child
	const_children_iterator end ( ) const {
		return m_children.end ( );
	/**
	 * \brief
	 * Getter of a children iterator one after the last child
	 *
	 * \return iterator one after the last child
	 */
	children_iterator end ( ) {
		return m_children.end ( );
	}

// ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

	/**
	 * \brief
	 * Getter of the prefix iterator to the root node
	 *
	 * \return prefix iterator to the root
	 */
	const_prefix_iterator prefix_begin ( ) const {
		return typename ext::vector < tree >::const_iterator ( this );
	/**
	 * \brief
	 * Getter of the prefix iterator one after the last node in the prefix traversal
	 *
	 * \return prefix iterator one after the last node in the prefix traversal
	 */
	const_prefix_iterator prefix_end ( ) const {
		const_prefix_iterator res ( typename ext::vector < tree >::const_iterator ( this + 1 ) );

		res.node.isEnd = true;
		return res;
	}

// ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

	/**
	 * \brief
	 * Getter of the postfix iterator to the first node in the postfix traversal
	 *
	 * \return prefix iterator to the first node in the postfix traversal
	 */
	const_postfix_iterator postfix_begin ( ) const {
		const_postfix_iterator res { typename ext::vector < tree >::const_iterator ( this ) };
Jan Trávníček's avatar
Jan Trávníček committed
		while ( ! res.node.getVirtual ( ) ) ++res.node;
	/**
	 * \brief
	 * Getter of the postfix iterator one after the last node in the postfix traversal
	 *
	 * \return prefix iterator one after the last node in the postfix traversal
	 */
	const_postfix_iterator postfix_end ( ) const {
		const_postfix_iterator res ( typename ext::vector < tree >::const_iterator ( this + 1 ) );

		res.node.isEnd = true;
		return res;
	}

// ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

	/**
	 * \brief
	 * Getter of the structure iterator to the first node in the traversal
	 *
	 * \return prefix iterator to the first node in the traversal
	 */
	const_structure_iterator structure_begin ( ) const {
		return typename ext::vector < tree >::const_iterator ( this );
	/**
	 * \brief
	 * Getter of the structure iterator to one after the last node in the traversal
	 *
	 * \return prefix iterator to one after the last node in the traversal
	 */
	const_structure_iterator structure_end ( ) const {
		const_structure_iterator res ( typename ext::vector < tree >::const_iterator ( this + 1 ) );

		res.isEnd = true;
		return res;
	}

// ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

	 * Pushbacks a subtree after last child of a tree.
	 *
	 * \param value a subtree to pushback to child list
	 */
	void push_back ( ext::tree < T > && value ) {
		ext::vector < tree > & children = const_cast < ext::vector < tree > & > ( getChildren ( ) );
		children.push_back ( std::move ( value ) );
		children.back ( ).m_parent = this;
	 * Pushbacks a subtree after last child of a tree.
	 *
	 * \param value a subtree to pushback to child list
	 */
	void push_back ( const ext::tree < T > & value ) {
		push_back ( tree ( value ) );
	 * Pushbacks a nullary node after last child of a tree.
	 *
	 * \param value a value to store in nullary node push-backed to the child list
	 */
	void push_back ( T && value ) {
		push_back ( tree ( std::move ( value ) ) );
	 * Pushbacks a nullary node after last child of a tree.
	 *
	 * \param value a value to store in nullary node push-backed to the child list