| #pragma once |
|
|
| #include <stack> |
| #include <vector> |
|
|
| namespace MosesTraining { |
| namespace Syntax { |
|
|
| template<typename T> |
| Tree<T>::~Tree() { |
| for (typename std::vector<Tree *>::iterator p = children_.begin(); |
| p != children_.end(); ++p) { |
| delete *p; |
| } |
| } |
|
|
| template<typename T> |
| void Tree<T>::SetParents() { |
| for (typename std::vector<Tree *>::iterator p = children_.begin(); |
| p != children_.end(); ++p) { |
| (*p)->parent() = this; |
| (*p)->SetParents(); |
| } |
| } |
|
|
| template<typename T> |
| std::size_t Tree<T>::Depth() const { |
| std::size_t depth = 0; |
| Tree *ancestor = parent_; |
| while (ancestor != 0) { |
| ++depth; |
| ancestor = ancestor->parent_; |
| } |
| return depth; |
| } |
|
|
| template<typename T> |
| template<typename V> |
| class Tree<T>::PreOrderIter { |
| public: |
| PreOrderIter(); |
| PreOrderIter(V &); |
|
|
| V &operator*() { return *node_; } |
| V *operator->() { return node_; } |
|
|
| PreOrderIter &operator++(); |
| PreOrderIter operator++(int); |
|
|
| bool operator==(const PreOrderIter &); |
| bool operator!=(const PreOrderIter &); |
|
|
| private: |
| |
| V *node_; |
|
|
| |
| |
| std::stack<std::size_t> index_stack_; |
| }; |
|
|
| template<typename T> |
| template<typename V> |
| Tree<T>::PreOrderIter<V>::PreOrderIter() |
| : node_(0) { |
| } |
|
|
| template<typename T> |
| template<typename V> |
| Tree<T>::PreOrderIter<V>::PreOrderIter(V &t) |
| : node_(&t) { |
| } |
|
|
| template<typename T> |
| template<typename V> |
| typename Tree<T>::template PreOrderIter<V> &Tree<T>::PreOrderIter<V>::operator++() { |
| |
| if (!node_->children().empty()) { |
| index_stack_.push(0); |
| node_ = node_->children()[0]; |
| return *this; |
| } |
| |
| |
| |
| V *ancestor = node_->parent_; |
| while (ancestor) { |
| std::size_t index = index_stack_.top(); |
| index_stack_.pop(); |
| if (index+1 < ancestor->children_.size()) { |
| index_stack_.push(index+1); |
| node_ = ancestor->children()[index+1]; |
| return *this; |
| } |
| ancestor = ancestor->parent_; |
| } |
| node_ = 0; |
| return *this; |
| } |
|
|
| template<typename T> |
| template<typename V> |
| typename Tree<T>::template PreOrderIter<V> Tree<T>::PreOrderIter<V>::operator++(int) { |
| PreOrderIter tmp(*this); |
| ++*this; |
| return tmp; |
| } |
|
|
| template<typename T> |
| template<typename V> |
| bool Tree<T>::PreOrderIter<V>::operator==(const PreOrderIter &rhs) { |
| return node_ == rhs.node_; |
| } |
|
|
| template<typename T> |
| template<typename V> |
| bool Tree<T>::PreOrderIter<V>::operator!=(const PreOrderIter &rhs) { |
| return node_ != rhs.node_; |
| } |
|
|
| template<typename T> |
| template<typename V> |
| class Tree<T>::LeafIter { |
| public: |
| LeafIter(); |
| LeafIter(V &); |
|
|
| V &operator*() { return *node_; } |
| V *operator->() { return node_; } |
|
|
| LeafIter &operator++(); |
| LeafIter operator++(int); |
|
|
| bool operator==(const LeafIter &); |
| bool operator!=(const LeafIter &); |
|
|
| private: |
| |
| V *node_; |
|
|
| |
| |
| std::stack<std::size_t> index_stack_; |
| }; |
|
|
| template<typename T> |
| template<typename V> |
| Tree<T>::LeafIter<V>::LeafIter() |
| : node_(0) { |
| } |
|
|
| template<typename T> |
| template<typename V> |
| Tree<T>::LeafIter<V>::LeafIter(V &t) |
| : node_(&t) { |
| |
| while (!node_->IsLeaf()) { |
| index_stack_.push(0); |
| node_ = node_->children()[0]; |
| } |
| } |
|
|
| template<typename T> |
| template<typename V> |
| typename Tree<T>::template LeafIter<V> &Tree<T>::LeafIter<V>::operator++() { |
| |
| |
| V *ancestor = node_->parent_; |
| while (ancestor) { |
| std::size_t index = index_stack_.top(); |
| index_stack_.pop(); |
| if (index+1 < ancestor->children_.size()) { |
| index_stack_.push(index+1); |
| node_ = ancestor->children()[index+1]; |
| |
| while (!node_->IsLeaf()) { |
| index_stack_.push(0); |
| node_ = node_->children()[0]; |
| } |
| return *this; |
| } |
| ancestor = ancestor->parent_; |
| } |
| node_ = 0; |
| return *this; |
| } |
|
|
| template<typename T> |
| template<typename V> |
| typename Tree<T>::template LeafIter<V> Tree<T>::LeafIter<V>::operator++(int) { |
| LeafIter tmp(*this); |
| ++*this; |
| return tmp; |
| } |
|
|
| template<typename T> |
| template<typename V> |
| bool Tree<T>::LeafIter<V>::operator==(const LeafIter &rhs) { |
| return node_ == rhs.node_; |
| } |
|
|
| template<typename T> |
| template<typename V> |
| bool Tree<T>::LeafIter<V>::operator!=(const LeafIter &rhs) { |
| return node_ != rhs.node_; |
| } |
|
|
| } |
| } |
|
|