Skip to content

Commit 48d4ee3

Browse files
author
blake2-ppc
committed
extra: Implement .rev_iter() in treemap
Implement reverse iterators for TreeMap and TreeSet, that produce the keys in backward order.
1 parent 6a43fc6 commit 48d4ee3

File tree

1 file changed

+60
-21
lines changed

1 file changed

+60
-21
lines changed

src/libextra/treemap.rs

Lines changed: 60 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@
1313
//! `TotalOrd`.
1414
1515

16-
use std::num;
1716
use std::util::{swap, replace};
1817
use std::iterator::{FromIterator, Extendable};
1918

@@ -152,7 +151,7 @@ impl<K: TotalOrd, V> TreeMap<K, V> {
152151

153152
/// Visit all key-value pairs in reverse order
154153
pub fn each_reverse<'a>(&'a self, f: &fn(&'a K, &'a V) -> bool) -> bool {
155-
each_reverse(&self.root, f)
154+
self.rev_iter().advance(|(k,v)| f(k, v))
156155
}
157156

158157
/// Visit all keys in reverse order
@@ -176,6 +175,12 @@ impl<K: TotalOrd, V> TreeMap<K, V> {
176175
}
177176
}
178177

178+
/// Get a lazy reverse iterator over the key-value pairs in the map.
179+
/// Requires that it be frozen (immutable).
180+
pub fn rev_iter<'a>(&'a self) -> TreeMapRevIterator<'a, K, V> {
181+
TreeMapRevIterator{iter: self.iter()}
182+
}
183+
179184
/// Get a lazy iterator that should be initialized using
180185
/// `iter_traverse_left`/`iter_traverse_right`/`iter_traverse_complete`.
181186
fn iter_for_traversal<'a>(&'a self) -> TreeMapIterator<'a, K, V> {
@@ -254,20 +259,18 @@ pub struct TreeMapIterator<'self, K, V> {
254259
priv remaining_max: uint
255260
}
256261

257-
impl<'self, K, V> Iterator<(&'self K, &'self V)> for TreeMapIterator<'self, K, V> {
258-
/// Advance the iterator to the next node (in order) and return a
259-
/// tuple with a reference to the key and value. If there are no
260-
/// more nodes, return `None`.
261-
fn next(&mut self) -> Option<(&'self K, &'self V)> {
262+
impl<'self, K, V> TreeMapIterator<'self, K, V> {
263+
#[inline(always)]
264+
fn next_(&mut self, forward: bool) -> Option<(&'self K, &'self V)> {
262265
while !self.stack.is_empty() || self.node.is_some() {
263266
match *self.node {
264267
Some(ref x) => {
265268
self.stack.push(x);
266-
self.node = &x.left;
269+
self.node = if forward { &x.left } else { &x.right };
267270
}
268271
None => {
269272
let res = self.stack.pop();
270-
self.node = &res.right;
273+
self.node = if forward { &res.right } else { &res.left };
271274
self.remaining_max -= 1;
272275
if self.remaining_min > 0 {
273276
self.remaining_min -= 1;
@@ -278,13 +281,41 @@ impl<'self, K, V> Iterator<(&'self K, &'self V)> for TreeMapIterator<'self, K, V
278281
}
279282
None
280283
}
284+
}
285+
286+
impl<'self, K, V> Iterator<(&'self K, &'self V)> for TreeMapIterator<'self, K, V> {
287+
/// Advance the iterator to the next node (in order) and return a
288+
/// tuple with a reference to the key and value. If there are no
289+
/// more nodes, return `None`.
290+
fn next(&mut self) -> Option<(&'self K, &'self V)> {
291+
self.next_(true)
292+
}
281293

282294
#[inline]
283295
fn size_hint(&self) -> (uint, Option<uint>) {
284296
(self.remaining_min, Some(self.remaining_max))
285297
}
286298
}
287299

300+
/// Lazy backward iterator over a map
301+
pub struct TreeMapRevIterator<'self, K, V> {
302+
priv iter: TreeMapIterator<'self, K, V>,
303+
}
304+
305+
impl<'self, K, V> Iterator<(&'self K, &'self V)> for TreeMapRevIterator<'self, K, V> {
306+
/// Advance the iterator to the next node (in order) and return a
307+
/// tuple with a reference to the key and value. If there are no
308+
/// more nodes, return `None`.
309+
fn next(&mut self) -> Option<(&'self K, &'self V)> {
310+
self.iter.next_(false)
311+
}
312+
313+
#[inline]
314+
fn size_hint(&self) -> (uint, Option<uint>) {
315+
self.iter.size_hint()
316+
}
317+
}
318+
288319
/// iter_traverse_left, iter_traverse_right and iter_traverse_complete are used to
289320
/// initialize TreeMapIterator pointing to element inside tree structure.
290321
///
@@ -382,6 +413,14 @@ impl<'self, T> Iterator<&'self T> for TreeSetIterator<'self, T> {
382413
}
383414
}
384415

416+
impl<'self, T> Iterator<&'self T> for TreeSetRevIterator<'self, T> {
417+
/// Advance the iterator to the next node (in order). If there are no more nodes, return `None`.
418+
#[inline]
419+
fn next(&mut self) -> Option<&'self T> {
420+
do self.iter.next().map |&(value, _)| { value }
421+
}
422+
}
423+
385424
/// A implementation of the `Set` trait on top of the `TreeMap` container. The
386425
/// only requirement is that the type of the elements contained ascribes to the
387426
/// `TotalOrd` trait.
@@ -492,6 +531,13 @@ impl<T: TotalOrd> TreeSet<T> {
492531
TreeSetIterator{iter: self.map.iter()}
493532
}
494533

534+
/// Get a lazy iterator over the values in the set.
535+
/// Requires that it be frozen (immutable).
536+
#[inline]
537+
pub fn rev_iter<'a>(&'a self) -> TreeSetRevIterator<'a, T> {
538+
TreeSetRevIterator{iter: self.map.rev_iter()}
539+
}
540+
495541
/// Get a lazy iterator pointing to the first value not less than `v` (greater or equal).
496542
/// If all elements in the set are less than `v` empty iterator is returned.
497543
#[inline]
@@ -540,6 +586,11 @@ pub struct TreeSetIterator<'self, T> {
540586
priv iter: TreeMapIterator<'self, T, ()>
541587
}
542588

589+
/// Lazy backward iterator over a set
590+
pub struct TreeSetRevIterator<'self, T> {
591+
priv iter: TreeMapRevIterator<'self, T, ()>
592+
}
593+
543594
// Encapsulate an iterator and hold its latest value until stepped forward
544595
struct Focus<A, T> {
545596
priv iter: T,
@@ -691,18 +742,6 @@ impl<K: TotalOrd, V> TreeNode<K, V> {
691742
}
692743
}
693744

694-
fn each<'r, K: TotalOrd, V>(node: &'r Option<~TreeNode<K, V>>,
695-
f: &fn(&'r K, &'r V) -> bool) -> bool {
696-
node.iter().advance(|x| each(&x.left, |k,v| f(k,v)) && f(&x.key, &x.value) &&
697-
each(&x.right, |k,v| f(k,v)))
698-
}
699-
700-
fn each_reverse<'r, K: TotalOrd, V>(node: &'r Option<~TreeNode<K, V>>,
701-
f: &fn(&'r K, &'r V) -> bool) -> bool {
702-
node.iter().advance(|x| each_reverse(&x.right, |k,v| f(k,v)) && f(&x.key, &x.value) &&
703-
each_reverse(&x.left, |k,v| f(k,v)))
704-
}
705-
706745
fn mutate_values<'r, K: TotalOrd, V>(node: &'r mut Option<~TreeNode<K, V>>,
707746
f: &fn(&'r K, &'r mut V) -> bool)
708747
-> bool {

0 commit comments

Comments
 (0)