namespace MosesTraining { | |
namespace Syntax { | |
// A basic k-ary tree with node values of type T. Each node has a vector of | |
// pointers to its children and a pointer to its parent (or 0 for the root). | |
// | |
// See the unit tests in tree_test.cc for examples of usage. | |
// | |
// Note: a Tree owns its children: it will delete them on destruction. | |
// | |
// Note: it's the user's responsibility to ensure that parent and child pointers | |
// are correctly set and maintained. A convenient(-ish) way of building a | |
// properly-connected tree is to add all the nodes as children of their | |
// respective parents (using the children() accessor) and then call | |
// SetParents() on the root at the end. | |
// | |
template<typename T> | |
class Tree { | |
public: | |
// Constructors | |
Tree() | |
: value_() | |
, children_() | |
, parent_(0) {} | |
Tree(const T &value) | |
: value_(value) | |
, children_() | |
, parent_(0) {} | |
// Destructor (deletes children) | |
~Tree(); | |
// Access tree's value. | |
const T &value() const { return value_; } | |
T &value() { return value_; } | |
// Access tree's parent. | |
const Tree *parent() const { return parent_; } | |
Tree *&parent() { return parent_; } | |
// Access tree's children. | |
const std::vector<Tree *> &children() const { return children_; } | |
std::vector<Tree *> &children() { return children_; } | |
// Set the parent values for this subtree (excluding this node). | |
void SetParents(); | |
// Leaf predicate. | |
bool IsLeaf() const { return children_.empty(); } | |
// Calculate the depth of this node within the tree (where the root has a | |
// depth of 0, root's children have a depth 1, etc). | |
std::size_t Depth() const; | |
// Iterators | |
// | |
// All iterators are forward iterators. Example use: | |
// | |
// const Tree<int> &root = GetMeATree(); | |
// for (Tree<int>::ConstPreOrderIterator p(root); | |
// p != Tree<int>::ConstPreOrderIterator(); ++p) { | |
// std::cout << p->value() << "\n"; | |
// } | |
private: | |
// Use templates to avoid code duplication between const and non-const | |
// iterators. V is the value type: either Tree<T> or const Tree<T>. | |
template<typename V> class PreOrderIter; | |
// template<typename V> class PostOrderIter; TODO | |
template<typename V> class LeafIter; | |
public: | |
// Pre-order iterators. | |
typedef PreOrderIter<Tree<T> > PreOrderIterator; | |
typedef PreOrderIter<const Tree<T> > ConstPreOrderIterator; | |
// Post-order iterators. | |
// typedef PostOrderIter<Tree<T> > PostOrderIterator; TODO | |
// typedef PostOrderIter<const Tree<T> > ConstPostOrderIterator; TODO | |
// Leaf iterators (left-to-right). | |
typedef LeafIter<Tree<T> > LeafIterator; | |
typedef LeafIter<const Tree<T> > ConstLeafIterator; | |
private: | |
T value_; | |
std::vector<Tree *> children_; | |
Tree *parent_; | |
}; | |
} // namespace Syntax | |
} // namespace MosesTraining | |