use bitstring::BitString;
use std::option::Option;
use super::*;
#[derive(Clone,Copy,PartialEq,Eq)]
enum Direction {
Down,
Left,
Right,
Up,
}
use self::Direction::*;
pub struct IterFull<'a, S: BitString+'a, V: 'a> {
stack: Vec<(Direction, &'a Node<S, V>)>,
depth: usize,
}
impl<'a, S: BitString+Clone, V> IterFull<'a, S, V> {
pub fn new(tree: &'a RadixMap<S, V>) -> Self {
match tree.root() {
None => IterFull{
stack: Vec::new(),
depth: 0,
},
Some(node) => IterFull{
stack: vec![(Down, node)],
depth: 0,
},
}
}
}
impl<'a, S: BitString+Clone, V> Iterator for IterFull<'a, S, V> {
type Item = (S, Option<&'a V>);
fn next(&mut self) -> Option<Self::Item> {
if self.stack.is_empty() {
if self.depth == 0 {
self.depth = !0;
return Some((S::null(), None));
} else {
return None;
}
}
while Up == self.stack[self.stack.len()-1].0 {
if 0 == self.depth {
debug_assert_eq!(1, self.stack.len());
self.stack.clear();
self.depth = !0;
return None;
}
if self.stack.len() > 1 {
let up_len = self.stack[self.stack.len()-2].1.key().len();
if self.depth - 1 == up_len {
self.stack.pop();
self.depth = up_len;
debug_assert!(!self.stack.is_empty());
continue;
}
}
let key = self.stack[self.stack.len()-1].1.key();
self.depth -= 1;
if key.get(self.depth) {
} else {
let mut key = key.clone();
key.clip(self.depth+1);
key.flip(self.depth);
return Some((key, None));
}
}
loop {
let top = self.stack.len() - 1;
let (dir, node) = self.stack[top];
debug_assert!(!self.stack.is_empty());
match dir {
Down => loop {
let key = node.key();
let key_len = key.len();
if self.depth == key_len {
self.stack[top].0 = Left;
break;
}
debug_assert!(self.depth < key_len);
if key.get(self.depth) {
let mut key = key.clone();
key.flip(self.depth);
self.depth += 1;
key.clip(self.depth);
return Some((key, None));
} else {
self.depth += 1;
}
},
Left => {
debug_assert_eq!(self.depth, node.key().len());
match *node {
Node::InnerNode(ref inner) => {
self.stack[top].0 = Right;
self.stack.push((Down, inner.left()));
self.depth += 1;
},
Node::Leaf(ref leaf) => {
self.stack[top].0 = Up;
return Some((leaf.key.clone(), Some(&leaf.value)));
}
}
},
Right => {
debug_assert_eq!(self.depth, node.key().len());
match *node {
Node::InnerNode(ref inner) => {
self.stack[top].0 = Up;
self.stack.push((Down, inner.right()));
self.depth += 1;
},
Node::Leaf(_) => unreachable!(),
}
},
Up => unreachable!(),
}
}
}
}