Skip to content

Commit f8cf234

Browse files
committed
auto merge of #8265 : blake2-ppc/rust/std-iter, r=thestinger
Fix #8228 by replacing .iter() and .iter_err() in Result by external iterators. Implement random access for `iterator::Invert` and `vec::ChunkIter` (and bidirectionality). Implement Repeat iterator.
2 parents 6f88f4d + 45085b9 commit f8cf234

File tree

8 files changed

+198
-164
lines changed

8 files changed

+198
-164
lines changed

src/libextra/bitv.rs

+22-48
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313

1414
use std::cmp;
1515
use std::iterator::RandomAccessIterator;
16-
use std::iterator::{Invert, Enumerate};
16+
use std::iterator::{Invert, Enumerate, Repeat, Map, Zip};
1717
use std::num;
1818
use std::ops;
1919
use std::uint;
@@ -206,14 +206,13 @@ impl BigBitv {
206206
#[inline]
207207
pub fn equals(&self, b: &BigBitv, nbits: uint) -> bool {
208208
let len = b.storage.len();
209-
do uint::iterate(0, len) |i| {
209+
for i in range(0, len) {
210210
let mask = big_mask(nbits, i);
211211
if mask & self.storage[i] != mask & b.storage[i] {
212-
false
213-
} else {
214-
true
212+
return false;
215213
}
216214
}
215+
true
217216
}
218217
}
219218

@@ -864,13 +863,12 @@ impl BitvSet {
864863
/// w1, w2) where the bit location is the number of bits offset so far,
865864
/// and w1/w2 are the words coming from the two vectors self, other.
866865
fn common_iter<'a>(&'a self, other: &'a BitvSet)
867-
-> MapE<(uint,&uint),(uint,uint,uint), &'a ~[uint],Enumerate<vec::VecIterator<'a,uint>>> {
868-
let min = num::min(self.bitv.storage.len(),
869-
other.bitv.storage.len());
870-
MapE{iter: self.bitv.storage.slice(0, min).iter().enumerate(),
871-
env: &other.bitv.storage,
872-
f: |(i, &w): (uint, &uint), o_store| (i * uint::bits, w, o_store[i])
873-
}
866+
-> Map<'static, ((uint, &'a uint), &'a ~[uint]), (uint, uint, uint),
867+
Zip<Enumerate<vec::VecIterator<'a, uint>>, Repeat<&'a ~[uint]>>> {
868+
let min = num::min(self.bitv.storage.len(), other.bitv.storage.len());
869+
self.bitv.storage.slice(0, min).iter().enumerate()
870+
.zip(Repeat::new(&other.bitv.storage))
871+
.transform(|((i, &w), o_store)| (i * uint::bits, w, o_store[i]))
874872
}
875873

876874
/// Visits each word in self or other that extends beyond the other. This
@@ -881,45 +879,21 @@ impl BitvSet {
881879
/// is true if the word comes from 'self', and false if it comes from
882880
/// 'other'.
883881
fn outlier_iter<'a>(&'a self, other: &'a BitvSet)
884-
-> MapE<(uint, &uint),(bool, uint, uint), uint, Enumerate<vec::VecIterator<'a, uint>>> {
885-
let len1 = self.bitv.storage.len();
886-
let len2 = other.bitv.storage.len();
887-
let min = num::min(len1, len2);
888-
889-
if min < len1 {
890-
MapE{iter: self.bitv.storage.slice(min, len1).iter().enumerate(),
891-
env: min,
892-
f: |(i, &w): (uint, &uint), min| (true, (i + min) * uint::bits, w)
893-
}
882+
-> Map<'static, ((uint, &'a uint), uint), (bool, uint, uint),
883+
Zip<Enumerate<vec::VecIterator<'a, uint>>, Repeat<uint>>> {
884+
let slen = self.bitv.storage.len();
885+
let olen = other.bitv.storage.len();
886+
887+
if olen < slen {
888+
self.bitv.storage.slice_from(olen).iter().enumerate()
889+
.zip(Repeat::new(olen))
890+
.transform(|((i, &w), min)| (true, (i + min) * uint::bits, w))
894891
} else {
895-
MapE{iter: other.bitv.storage.slice(min, len2).iter().enumerate(),
896-
env: min,
897-
f: |(i, &w): (uint, &uint), min| (false, (i + min) * uint::bits, w)
898-
}
899-
}
900-
}
901-
}
902-
903-
/// Like iterator::Map with explicit env capture
904-
struct MapE<A, B, Env, I> {
905-
priv env: Env,
906-
priv f: &'static fn(A, Env) -> B,
907-
priv iter: I,
908-
}
909-
910-
impl<'self, A, B, Env: Clone, I: Iterator<A>> Iterator<B> for MapE<A, B, Env, I> {
911-
#[inline]
912-
fn next(&mut self) -> Option<B> {
913-
match self.iter.next() {
914-
Some(elt) => Some((self.f)(elt, self.env.clone())),
915-
None => None
892+
other.bitv.storage.slice_from(slen).iter().enumerate()
893+
.zip(Repeat::new(slen))
894+
.transform(|((i, &w), min)| (false, (i + min) * uint::bits, w))
916895
}
917896
}
918-
919-
#[inline]
920-
fn size_hint(&self) -> (uint, Option<uint>) {
921-
self.iter.size_hint()
922-
}
923897
}
924898

925899
pub struct BitvSetIterator<'self> {

src/libstd/hashmap.rs

+17-37
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,8 @@ use container::{Container, Mutable, Map, MutableMap, Set, MutableSet};
1919
use clone::Clone;
2020
use cmp::{Eq, Equiv};
2121
use hash::Hash;
22-
use iterator::{Iterator, IteratorUtil, FromIterator, Extendable, Chain, range};
22+
use iterator::{Iterator, IteratorUtil, FromIterator, Extendable, range};
23+
use iterator::{FilterMap, Chain, Repeat, Zip};
2324
use num;
2425
use option::{None, Option, Some};
2526
use rand::RngUtil;
@@ -712,10 +713,12 @@ impl<T:Hash + Eq> HashSet<T> {
712713
}
713714

714715
/// Visit the values representing the difference
715-
pub fn difference_iter<'a>(&'a self, other: &'a HashSet<T>)
716-
-> SetAlgebraIter<'a, T> {
717-
EnvFilterIterator{iter: self.iter(), env: other,
718-
filter: |elt, other| !other.contains(elt) }
716+
pub fn difference_iter<'a>(&'a self, other: &'a HashSet<T>) -> SetAlgebraIter<'a, T> {
717+
Repeat::new(other)
718+
.zip(self.iter())
719+
.filter_map(|(other, elt)| {
720+
if !other.contains(elt) { Some(elt) } else { None }
721+
})
719722
}
720723

721724
/// Visit the values representing the symmetric difference
@@ -727,8 +730,11 @@ impl<T:Hash + Eq> HashSet<T> {
727730
/// Visit the values representing the intersection
728731
pub fn intersection_iter<'a>(&'a self, other: &'a HashSet<T>)
729732
-> SetAlgebraIter<'a, T> {
730-
EnvFilterIterator{iter: self.iter(), env: other,
731-
filter: |elt, other| other.contains(elt) }
733+
Repeat::new(other)
734+
.zip(self.iter())
735+
.filter_map(|(other, elt)| {
736+
if other.contains(elt) { Some(elt) } else { None }
737+
})
732738
}
733739

734740
/// Visit the values representing the union
@@ -756,38 +762,12 @@ impl<K: Eq + Hash, T: Iterator<K>> Extendable<K, T> for HashSet<K> {
756762
}
757763
}
758764

759-
// FIXME #7814: use std::iterator::FilterIterator
760-
/// Building block for Set operation iterators
761-
pub struct EnvFilterIterator<A, Env, I> {
762-
priv env: Env,
763-
priv filter: &'static fn(&A, Env) -> bool,
764-
priv iter: I,
765-
}
766-
767-
impl<'self, A, Env: Clone, I: Iterator<&'self A>> Iterator<&'self A>
768-
for EnvFilterIterator<A, Env, I> {
769-
#[inline]
770-
fn next(&mut self) -> Option<&'self A> {
771-
loop {
772-
match self.iter.next() {
773-
Some(elt) => if (self.filter)(elt, self.env.clone()) {
774-
return Some(elt)
775-
},
776-
None => return None,
777-
}
778-
}
779-
}
780-
781-
#[inline]
782-
fn size_hint(&self) -> (uint, Option<uint>) {
783-
let (_, upper) = self.iter.size_hint();
784-
(0, upper)
785-
}
786-
}
787-
765+
// `Repeat` is used to feed the filter closure an explicit capture
766+
// of a reference to the other set
788767
/// Set operations iterator
789768
pub type SetAlgebraIter<'self, T> =
790-
EnvFilterIterator<T, &'self HashSet<T>, HashSetIterator<'self, T>>;
769+
FilterMap<'static,(&'self HashSet<T>, &'self T), &'self T,
770+
Zip<Repeat<&'self HashSet<T>>,HashSetIterator<'self,T>>>;
791771

792772

793773
#[cfg(test)]

src/libstd/iterator.rs

+65
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,17 @@ pub trait DoubleEndedIteratorUtil {
8282
/// In the future these will be default methods instead of a utility trait.
8383
impl<A, T: DoubleEndedIterator<A>> DoubleEndedIteratorUtil for T {
8484
/// Flip the direction of the iterator
85+
///
86+
/// The inverted iterator flips the ends on an iterator that can already
87+
/// be iterated from the front and from the back.
88+
///
89+
///
90+
/// If the iterator also implements RandomAccessIterator, the inverted
91+
/// iterator is also random access, with the indices starting at the back
92+
/// of the original iterator.
93+
///
94+
/// Note: Random access with inverted indices still only applies to the first
95+
/// `uint::max_value` elements of the original iterator.
8596
#[inline]
8697
fn invert(self) -> Invert<T> {
8798
Invert{iter: self}
@@ -106,6 +117,16 @@ impl<A, T: DoubleEndedIterator<A>> DoubleEndedIterator<A> for Invert<T> {
106117
fn next_back(&mut self) -> Option<A> { self.iter.next() }
107118
}
108119

120+
impl<A, T: DoubleEndedIterator<A> + RandomAccessIterator<A>> RandomAccessIterator<A>
121+
for Invert<T> {
122+
#[inline]
123+
fn indexable(&self) -> uint { self.iter.indexable() }
124+
#[inline]
125+
fn idx(&self, index: uint) -> Option<A> {
126+
self.iter.idx(self.indexable() - index - 1)
127+
}
128+
}
129+
109130
/// Iterator adaptors provided for every `Iterator` implementation. The adaptor objects are also
110131
/// implementations of the `Iterator` trait.
111132
///
@@ -1555,6 +1576,39 @@ impl<A: Add<A, A> + Clone> Iterator<A> for Counter<A> {
15551576
}
15561577
}
15571578

1579+
/// An iterator that repeats an element endlessly
1580+
#[deriving(Clone, DeepClone)]
1581+
pub struct Repeat<A> {
1582+
priv element: A
1583+
}
1584+
1585+
impl<A: Clone> Repeat<A> {
1586+
/// Create a new `Repeat` that enlessly repeats the element `elt`.
1587+
#[inline]
1588+
pub fn new(elt: A) -> Repeat<A> {
1589+
Repeat{element: elt}
1590+
}
1591+
}
1592+
1593+
impl<A: Clone> Iterator<A> for Repeat<A> {
1594+
#[inline]
1595+
fn next(&mut self) -> Option<A> { self.idx(0) }
1596+
#[inline]
1597+
fn size_hint(&self) -> (uint, Option<uint>) { (uint::max_value, None) }
1598+
}
1599+
1600+
impl<A: Clone> DoubleEndedIterator<A> for Repeat<A> {
1601+
#[inline]
1602+
fn next_back(&mut self) -> Option<A> { self.idx(0) }
1603+
}
1604+
1605+
impl<A: Clone> RandomAccessIterator<A> for Repeat<A> {
1606+
#[inline]
1607+
fn indexable(&self) -> uint { uint::max_value }
1608+
#[inline]
1609+
fn idx(&self, _: uint) -> Option<A> { Some(self.element.clone()) }
1610+
}
1611+
15581612
#[cfg(test)]
15591613
mod tests {
15601614
use super::*;
@@ -2017,6 +2071,17 @@ mod tests {
20172071
check_randacc_iter(xs.iter().enumerate(), xs.len());
20182072
}
20192073

2074+
#[test]
2075+
fn test_random_access_invert() {
2076+
let xs = [1, 2, 3, 4, 5];
2077+
check_randacc_iter(xs.iter().invert(), xs.len());
2078+
let mut it = xs.iter().invert();
2079+
it.next();
2080+
it.next_back();
2081+
it.next();
2082+
check_randacc_iter(it, xs.len() - 3);
2083+
}
2084+
20202085
#[test]
20212086
fn test_random_access_zip() {
20222087
let xs = [1, 2, 3, 4, 5];

src/libstd/num/uint.rs

-24
Original file line numberDiff line numberDiff line change
@@ -70,30 +70,6 @@ pub fn div_round(x: uint, y: uint) -> uint {
7070
///
7171
pub fn div_floor(x: uint, y: uint) -> uint { return x / y; }
7272

73-
///
74-
/// Iterate over the range [`lo`..`hi`), or stop when requested
75-
///
76-
/// # Arguments
77-
///
78-
/// * lo - The integer at which to start the loop (included)
79-
/// * hi - The integer at which to stop the loop (excluded)
80-
/// * it - A block to execute with each consecutive integer of the range.
81-
/// Return `true` to continue, `false` to stop.
82-
///
83-
/// # Return value
84-
///
85-
/// `true` If execution proceeded correctly, `false` if it was interrupted,
86-
/// that is if `it` returned `false` at any point.
87-
///
88-
pub fn iterate(lo: uint, hi: uint, it: &fn(uint) -> bool) -> bool {
89-
let mut i = lo;
90-
while i < hi {
91-
if (!it(i)) { return false; }
92-
i += 1u;
93-
}
94-
return true;
95-
}
96-
9773
impl iter::Times for uint {
9874
#[inline]
9975
///

src/libstd/option.rs

+18-28
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,7 @@ impl<T: ToStr> ToStr for Option<T> {
116116
impl<T> Option<T> {
117117
/// Return an iterator over the possibly contained value
118118
#[inline]
119-
pub fn iter<'r>(&'r self) -> OptionIterator<'r, T> {
119+
pub fn iter<'r>(&'r self) -> OptionIterator<&'r T> {
120120
match *self {
121121
Some(ref x) => OptionIterator{opt: Some(x)},
122122
None => OptionIterator{opt: None}
@@ -125,13 +125,19 @@ impl<T> Option<T> {
125125

126126
/// Return a mutable iterator over the possibly contained value
127127
#[inline]
128-
pub fn mut_iter<'r>(&'r mut self) -> OptionMutIterator<'r, T> {
128+
pub fn mut_iter<'r>(&'r mut self) -> OptionIterator<&'r mut T> {
129129
match *self {
130-
Some(ref mut x) => OptionMutIterator{opt: Some(x)},
131-
None => OptionMutIterator{opt: None}
130+
Some(ref mut x) => OptionIterator{opt: Some(x)},
131+
None => OptionIterator{opt: None}
132132
}
133133
}
134134

135+
/// Return a consuming iterator over the possibly contained value
136+
#[inline]
137+
pub fn consume(self) -> OptionIterator<T> {
138+
OptionIterator{opt: self}
139+
}
140+
135141
/// Returns true if the option equals `None`
136142
#[inline]
137143
pub fn is_none(&self) -> bool {
@@ -404,34 +410,18 @@ impl<T> Zero for Option<T> {
404410
fn is_zero(&self) -> bool { self.is_none() }
405411
}
406412

407-
/// Immutable iterator over an `Option<A>`
408-
pub struct OptionIterator<'self, A> {
409-
priv opt: Option<&'self A>
410-
}
411-
412-
impl<'self, A> Iterator<&'self A> for OptionIterator<'self, A> {
413-
fn next(&mut self) -> Option<&'self A> {
414-
util::replace(&mut self.opt, None)
415-
}
416-
417-
fn size_hint(&self) -> (uint, Option<uint>) {
418-
match self.opt {
419-
Some(_) => (1, Some(1)),
420-
None => (0, Some(0)),
421-
}
422-
}
423-
}
424-
425-
/// Mutable iterator over an `Option<A>`
426-
pub struct OptionMutIterator<'self, A> {
427-
priv opt: Option<&'self mut A>
413+
/// An iterator that yields either one or zero elements
414+
pub struct OptionIterator<A> {
415+
priv opt: Option<A>
428416
}
429417

430-
impl<'self, A> Iterator<&'self mut A> for OptionMutIterator<'self, A> {
431-
fn next(&mut self) -> Option<&'self mut A> {
432-
util::replace(&mut self.opt, None)
418+
impl<A> Iterator<A> for OptionIterator<A> {
419+
#[inline]
420+
fn next(&mut self) -> Option<A> {
421+
self.opt.take()
433422
}
434423

424+
#[inline]
435425
fn size_hint(&self) -> (uint, Option<uint>) {
436426
match self.opt {
437427
Some(_) => (1, Some(1)),

0 commit comments

Comments
 (0)