From 47c5279e3145cf47d2d61da7b98c1d7b112fde81 Mon Sep 17 00:00:00 2001 From: Ilyong Cho Date: Mon, 9 Sep 2013 15:32:07 +0900 Subject: [PATCH] Add AncestorIterator by jgraham --- src/components/util/tree.rs | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/src/components/util/tree.rs b/src/components/util/tree.rs index d38d4a7f5da5..2b3b467ac45d 100644 --- a/src/components/util/tree.rs +++ b/src/components/util/tree.rs @@ -42,6 +42,23 @@ impl> Iterator for ChildIterator { } } +pub struct AncestorIterator { + priv current: Option, +} + +impl> Iterator for AncestorIterator { + fn next(&mut self) -> Option { + if self.current.is_none() { + return None; + } + + // FIXME: Do we need two clones here? + let x = self.current.get_ref().clone(); + self.current = x.with_base(|n| TreeNodeRef::::parent_node(n)); + Some(x.clone()) + } +} + // FIXME: Do this without precomputing a vector of refs. // Easy for preorder; harder for postorder. pub struct TreeIterator { @@ -196,6 +213,13 @@ pub trait TreeNodeRef: Clone { } } + /// Iterates over all ancestors of this node. + fn ancestors(&self) -> AncestorIterator { + AncestorIterator { + current: self.with_base(|n| get!(n, parent_node)), + } + } + /// Iterates over this node and all its descendants, in preorder. fn traverse_preorder(&self) -> TreeIterator { self.traverse_preorder_prune(|_| false)