Skip to content

Commit b5fbfe2

Browse files
committed
Merge pull request #19770 from csouth3/iterator-wrapperstructs
Use wrapper structs for iterators in BTreeMap/Set and HashMap/Set Reviewed-by: Gankro
2 parents a198d8a + e38de8a commit b5fbfe2

File tree

4 files changed

+145
-69
lines changed

4 files changed

+145
-69
lines changed

src/libcollections/btree/map.rs

Lines changed: 28 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ use std::hash::{Writer, Hash};
2929
use core::default::Default;
3030
use core::{iter, fmt, mem};
3131
use core::fmt::Show;
32+
use core::iter::Map;
3233

3334
use ring_buf::RingBuf;
3435

@@ -110,12 +111,14 @@ pub struct MoveEntries<K, V> {
110111
}
111112

112113
/// An iterator over a BTreeMap's keys.
113-
pub type Keys<'a, K, V> =
114-
iter::Map<(&'a K, &'a V), &'a K, Entries<'a, K, V>, fn((&'a K, &'a V)) -> &'a K>;
114+
pub struct Keys<'a, K: 'a, V: 'a> {
115+
inner: Map<(&'a K, &'a V), &'a K, Entries<'a, K, V>, fn((&'a K, &'a V)) -> &'a K>
116+
}
115117

116118
/// An iterator over a BTreeMap's values.
117-
pub type Values<'a, K, V> =
118-
iter::Map<(&'a K, &'a V), &'a V, Entries<'a, K, V>, fn((&'a K, &'a V)) -> &'a V>;
119+
pub struct Values<'a, K: 'a, V: 'a> {
120+
inner: Map<(&'a K, &'a V), &'a V, Entries<'a, K, V>, fn((&'a K, &'a V)) -> &'a V>
121+
}
119122

120123
/// A view into a single entry in a map, which may either be vacant or occupied.
121124
pub enum Entry<'a, K:'a, V:'a> {
@@ -1054,6 +1057,25 @@ impl<K, V> DoubleEndedIterator<(K, V)> for MoveEntries<K, V> {
10541057
impl<K, V> ExactSizeIterator<(K, V)> for MoveEntries<K, V> {}
10551058

10561059

1060+
impl<'a, K, V> Iterator<&'a K> for Keys<'a, K, V> {
1061+
fn next(&mut self) -> Option<(&'a K)> { self.inner.next() }
1062+
fn size_hint(&self) -> (uint, Option<uint>) { self.inner.size_hint() }
1063+
}
1064+
impl<'a, K, V> DoubleEndedIterator<&'a K> for Keys<'a, K, V> {
1065+
fn next_back(&mut self) -> Option<(&'a K)> { self.inner.next_back() }
1066+
}
1067+
impl<'a, K, V> ExactSizeIterator<&'a K> for Keys<'a, K, V> {}
1068+
1069+
1070+
impl<'a, K, V> Iterator<&'a V> for Values<'a, K, V> {
1071+
fn next(&mut self) -> Option<(&'a V)> { self.inner.next() }
1072+
fn size_hint(&self) -> (uint, Option<uint>) { self.inner.size_hint() }
1073+
}
1074+
impl<'a, K, V> DoubleEndedIterator<&'a V> for Values<'a, K, V> {
1075+
fn next_back(&mut self) -> Option<(&'a V)> { self.inner.next_back() }
1076+
}
1077+
impl<'a, K, V> ExactSizeIterator<&'a V> for Values<'a, K, V> {}
1078+
10571079

10581080
impl<'a, K: Ord, V> VacantEntry<'a, K, V> {
10591081
/// Sets the value of the entry with the VacantEntry's key,
@@ -1204,7 +1226,7 @@ impl<K, V> BTreeMap<K, V> {
12041226
pub fn keys<'a>(&'a self) -> Keys<'a, K, V> {
12051227
fn first<A, B>((a, _): (A, B)) -> A { a }
12061228

1207-
self.iter().map(first)
1229+
Keys { inner: self.iter().map(first) }
12081230
}
12091231

12101232
/// Gets an iterator over the values of the map.
@@ -1225,7 +1247,7 @@ impl<K, V> BTreeMap<K, V> {
12251247
pub fn values<'a>(&'a self) -> Values<'a, K, V> {
12261248
fn second<A, B>((_, b): (A, B)) -> B { b }
12271249

1228-
self.iter().map(second)
1250+
Values { inner: self.iter().map(second) }
12291251
}
12301252

12311253
/// Return the number of elements in the map.

src/libcollections/btree/set.rs

Lines changed: 28 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ use std::hash::Hash;
1818
use core::borrow::BorrowFrom;
1919
use core::default::Default;
2020
use core::{iter, fmt};
21-
use core::iter::Peekable;
21+
use core::iter::{Peekable, Map};
2222
use core::fmt::Show;
2323

2424
// FIXME(conventions): implement bounded iterators
@@ -33,11 +33,14 @@ pub struct BTreeSet<T>{
3333
}
3434

3535
/// An iterator over a BTreeSet's items.
36-
pub type Items<'a, T> = Keys<'a, T, ()>;
36+
pub struct Items<'a, T: 'a> {
37+
iter: Keys<'a, T, ()>
38+
}
3739

3840
/// An owning iterator over a BTreeSet's items.
39-
pub type MoveItems<T> =
40-
iter::Map<(T, ()), T, MoveEntries<T, ()>, fn((T, ())) -> T>;
41+
pub struct MoveItems<T> {
42+
iter: Map<(T, ()), T, MoveEntries<T, ()>, fn((T, ())) -> T>
43+
}
4144

4245
/// A lazy iterator producing elements in the set difference (in-order).
4346
pub struct DifferenceItems<'a, T:'a> {
@@ -82,15 +85,15 @@ impl<T> BTreeSet<T> {
8285
/// Gets an iterator over the BTreeSet's contents.
8386
#[unstable = "matches collection reform specification, waiting for dust to settle"]
8487
pub fn iter<'a>(&'a self) -> Items<'a, T> {
85-
self.map.keys()
88+
Items { iter: self.map.keys() }
8689
}
8790

8891
/// Gets an iterator for moving out the BtreeSet's contents.
8992
#[unstable = "matches collection reform specification, waiting for dust to settle"]
9093
pub fn into_iter(self) -> MoveItems<T> {
9194
fn first<A, B>((a, _): (A, B)) -> A { a }
9295

93-
self.map.into_iter().map(first)
96+
MoveItems { iter: self.map.into_iter().map(first) }
9497
}
9598
}
9699

@@ -505,6 +508,25 @@ impl<T: Show> Show for BTreeSet<T> {
505508
}
506509
}
507510

511+
impl<'a, T> Iterator<&'a T> for Items<'a, T> {
512+
fn next(&mut self) -> Option<&'a T> { self.iter.next() }
513+
fn size_hint(&self) -> (uint, Option<uint>) { self.iter.size_hint() }
514+
}
515+
impl<'a, T> DoubleEndedIterator<&'a T> for Items<'a, T> {
516+
fn next_back(&mut self) -> Option<&'a T> { self.iter.next_back() }
517+
}
518+
impl<'a, T> ExactSizeIterator<&'a T> for Items<'a, T> {}
519+
520+
521+
impl<T> Iterator<T> for MoveItems<T> {
522+
fn next(&mut self) -> Option<T> { self.iter.next() }
523+
fn size_hint(&self) -> (uint, Option<uint>) { self.iter.size_hint() }
524+
}
525+
impl<T> DoubleEndedIterator<T> for MoveItems<T> {
526+
fn next_back(&mut self) -> Option<T> { self.iter.next_back() }
527+
}
528+
impl<T> ExactSizeIterator<T> for MoveItems<T> {}
529+
508530
/// Compare `x` and `y`, but return `short` if x is None and `long` if y is None
509531
fn cmp_opt<T: Ord>(x: Option<&T>, y: Option<&T>,
510532
short: Ordering, long: Ordering) -> Ordering {

src/libstd/collections/hash/map.rs

Lines changed: 29 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ use cmp::{max, Eq, Equiv, PartialEq};
2020
use default::Default;
2121
use fmt::{mod, Show};
2222
use hash::{Hash, Hasher, RandomSipHasher};
23-
use iter::{mod, Iterator, IteratorExt, FromIterator, Extend};
23+
use iter::{mod, Iterator, IteratorExt, FromIterator, Extend, Map};
2424
use kinds::Sized;
2525
use mem::{mod, replace};
2626
use num::{Int, UnsignedInt};
@@ -859,7 +859,7 @@ impl<K: Eq + Hash<S>, V, S, H: Hasher<S>> HashMap<K, V, H> {
859859
pub fn keys(&self) -> Keys<K, V> {
860860
fn first<A, B>((a, _): (A, B)) -> A { a }
861861

862-
self.iter().map(first)
862+
Keys { inner: self.iter().map(first) }
863863
}
864864

865865
/// An iterator visiting all values in arbitrary order.
@@ -883,7 +883,7 @@ impl<K: Eq + Hash<S>, V, S, H: Hasher<S>> HashMap<K, V, H> {
883883
pub fn values(&self) -> Values<K, V> {
884884
fn second<A, B>((_, b): (A, B)) -> B { b }
885885

886-
self.iter().map(second)
886+
Values { inner: self.iter().map(second) }
887887
}
888888

889889
/// An iterator visiting all key-value pairs in arbitrary order.
@@ -1335,6 +1335,16 @@ pub struct MoveEntries<K, V> {
13351335
>
13361336
}
13371337

1338+
/// HashMap keys iterator
1339+
pub struct Keys<'a, K: 'a, V: 'a> {
1340+
inner: Map<(&'a K, &'a V), &'a K, Entries<'a, K, V>, fn((&'a K, &'a V)) -> &'a K>
1341+
}
1342+
1343+
/// HashMap values iterator
1344+
pub struct Values<'a, K: 'a, V: 'a> {
1345+
inner: Map<(&'a K, &'a V), &'a V, Entries<'a, K, V>, fn((&'a K, &'a V)) -> &'a V>
1346+
}
1347+
13381348
/// A view into a single occupied location in a HashMap
13391349
pub struct OccupiedEntry<'a, K:'a, V:'a> {
13401350
elem: FullBucket<K, V, &'a mut RawTable<K, V>>,
@@ -1365,36 +1375,28 @@ enum VacantEntryState<K, V, M> {
13651375
}
13661376

13671377
impl<'a, K, V> Iterator<(&'a K, &'a V)> for Entries<'a, K, V> {
1368-
#[inline]
1369-
fn next(&mut self) -> Option<(&'a K, &'a V)> {
1370-
self.inner.next()
1371-
}
1372-
#[inline]
1373-
fn size_hint(&self) -> (uint, Option<uint>) {
1374-
self.inner.size_hint()
1375-
}
1378+
#[inline] fn next(&mut self) -> Option<(&'a K, &'a V)> { self.inner.next() }
1379+
#[inline] fn size_hint(&self) -> (uint, Option<uint>) { self.inner.size_hint() }
13761380
}
13771381

13781382
impl<'a, K, V> Iterator<(&'a K, &'a mut V)> for MutEntries<'a, K, V> {
1379-
#[inline]
1380-
fn next(&mut self) -> Option<(&'a K, &'a mut V)> {
1381-
self.inner.next()
1382-
}
1383-
#[inline]
1384-
fn size_hint(&self) -> (uint, Option<uint>) {
1385-
self.inner.size_hint()
1386-
}
1383+
#[inline] fn next(&mut self) -> Option<(&'a K, &'a mut V)> { self.inner.next() }
1384+
#[inline] fn size_hint(&self) -> (uint, Option<uint>) { self.inner.size_hint() }
13871385
}
13881386

13891387
impl<K, V> Iterator<(K, V)> for MoveEntries<K, V> {
1390-
#[inline]
1391-
fn next(&mut self) -> Option<(K, V)> {
1392-
self.inner.next()
1393-
}
1394-
#[inline]
1395-
fn size_hint(&self) -> (uint, Option<uint>) {
1396-
self.inner.size_hint()
1397-
}
1388+
#[inline] fn next(&mut self) -> Option<(K, V)> { self.inner.next() }
1389+
#[inline] fn size_hint(&self) -> (uint, Option<uint>) { self.inner.size_hint() }
1390+
}
1391+
1392+
impl<'a, K, V> Iterator<&'a K> for Keys<'a, K, V> {
1393+
#[inline] fn next(&mut self) -> Option<(&'a K)> { self.inner.next() }
1394+
#[inline] fn size_hint(&self) -> (uint, Option<uint>) { self.inner.size_hint() }
1395+
}
1396+
1397+
impl<'a, K, V> Iterator<&'a V> for Values<'a, K, V> {
1398+
#[inline] fn next(&mut self) -> Option<(&'a V)> { self.inner.next() }
1399+
#[inline] fn size_hint(&self) -> (uint, Option<uint>) { self.inner.size_hint() }
13981400
}
13991401

14001402
impl<'a, K, V> OccupiedEntry<'a, K, V> {
@@ -1448,14 +1450,6 @@ impl<'a, K, V> VacantEntry<'a, K, V> {
14481450
}
14491451
}
14501452

1451-
/// HashMap keys iterator
1452-
pub type Keys<'a, K, V> =
1453-
iter::Map<(&'a K, &'a V), &'a K, Entries<'a, K, V>, fn((&'a K, &'a V)) -> &'a K>;
1454-
1455-
/// HashMap values iterator
1456-
pub type Values<'a, K, V> =
1457-
iter::Map<(&'a K, &'a V), &'a V, Entries<'a, K, V>, fn((&'a K, &'a V)) -> &'a V>;
1458-
14591453
impl<K: Eq + Hash<S>, V, S, H: Hasher<S> + Default> FromIterator<(K, V)> for HashMap<K, V, H> {
14601454
fn from_iter<T: Iterator<(K, V)>>(iter: T) -> HashMap<K, V, H> {
14611455
let (lower, _) = iter.size_hint();

src/libstd/collections/hash/set.rs

Lines changed: 60 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -17,12 +17,11 @@ use default::Default;
1717
use fmt::Show;
1818
use fmt;
1919
use hash::{Hash, Hasher, RandomSipHasher};
20-
use iter::{Iterator, IteratorExt, FromIterator, FilterMap, Chain, Repeat, Zip, Extend, repeat};
21-
use iter;
2220
use option::Option::{Some, None, mod};
21+
use iter::{Iterator, IteratorExt, FromIterator, Map, FilterMap, Chain, Repeat, Zip, Extend, repeat};
2322
use result::Result::{Ok, Err};
2423

25-
use super::map::{HashMap, Entries, MoveEntries, INITIAL_CAPACITY};
24+
use super::map::{HashMap, MoveEntries, Keys, INITIAL_CAPACITY};
2625

2726
// FIXME(conventions): implement BitOr, BitAnd, BitXor, and Sub
2827

@@ -252,7 +251,7 @@ impl<T: Eq + Hash<S>, S, H: Hasher<S>> HashSet<T, H> {
252251
/// ```
253252
#[unstable = "matches collection reform specification, waiting for dust to settle"]
254253
pub fn iter<'a>(&'a self) -> SetItems<'a, T> {
255-
self.map.keys()
254+
SetItems { iter: self.map.keys() }
256255
}
257256

258257
/// Creates a consuming iterator, that is, one that moves each value out
@@ -279,7 +278,7 @@ impl<T: Eq + Hash<S>, S, H: Hasher<S>> HashSet<T, H> {
279278
pub fn into_iter(self) -> SetMoveItems<T> {
280279
fn first<A, B>((a, _): (A, B)) -> A { a }
281280

282-
self.map.into_iter().map(first)
281+
SetMoveItems { iter: self.map.into_iter().map(first) }
283282
}
284283

285284
/// Visit the values representing the difference.
@@ -312,7 +311,7 @@ impl<T: Eq + Hash<S>, S, H: Hasher<S>> HashSet<T, H> {
312311
if !other.contains(elt) { Some(elt) } else { None }
313312
}
314313

315-
repeat(other).zip(self.iter()).filter_map(filter)
314+
SetAlgebraItems { iter: repeat(other).zip(self.iter()).filter_map(filter) }
316315
}
317316

318317
/// Visit the values representing the symmetric difference.
@@ -337,8 +336,8 @@ impl<T: Eq + Hash<S>, S, H: Hasher<S>> HashSet<T, H> {
337336
/// ```
338337
#[unstable = "matches collection reform specification, waiting for dust to settle"]
339338
pub fn symmetric_difference<'a>(&'a self, other: &'a HashSet<T, H>)
340-
-> Chain<SetAlgebraItems<'a, T, H>, SetAlgebraItems<'a, T, H>> {
341-
self.difference(other).chain(other.difference(self))
339+
-> SymDifferenceItems<'a, T, H> {
340+
SymDifferenceItems { iter: self.difference(other).chain(other.difference(self)) }
342341
}
343342

344343
/// Visit the values representing the intersection.
@@ -366,7 +365,7 @@ impl<T: Eq + Hash<S>, S, H: Hasher<S>> HashSet<T, H> {
366365
if other.contains(elt) { Some(elt) } else { None }
367366
}
368367

369-
repeat(other).zip(self.iter()).filter_map(filter)
368+
SetAlgebraItems { iter: repeat(other).zip(self.iter()).filter_map(filter) }
370369
}
371370

372371
/// Visit the values representing the union.
@@ -387,9 +386,8 @@ impl<T: Eq + Hash<S>, S, H: Hasher<S>> HashSet<T, H> {
387386
/// assert_eq!(diff, [1i, 2, 3, 4].iter().map(|&x| x).collect());
388387
/// ```
389388
#[unstable = "matches collection reform specification, waiting for dust to settle"]
390-
pub fn union<'a>(&'a self, other: &'a HashSet<T, H>)
391-
-> Chain<SetItems<'a, T>, SetAlgebraItems<'a, T, H>> {
392-
self.iter().chain(other.difference(self))
389+
pub fn union<'a>(&'a self, other: &'a HashSet<T, H>) -> UnionItems<'a, T, H> {
390+
UnionItems { iter: self.iter().chain(other.difference(self)) }
393391
}
394392

395393
/// Return the number of elements in the set
@@ -617,21 +615,61 @@ impl<T: Eq + Hash<S>, S, H: Hasher<S> + Default> Default for HashSet<T, H> {
617615
}
618616

619617
/// HashSet iterator
620-
pub type SetItems<'a, K> =
621-
iter::Map<(&'a K, &'a ()), &'a K, Entries<'a, K, ()>, fn((&'a K, &'a ())) -> &'a K>;
618+
pub struct SetItems<'a, K: 'a> {
619+
iter: Keys<'a, K, ()>
620+
}
622621

623622
/// HashSet move iterator
624-
pub type SetMoveItems<K> = iter::Map<(K, ()), K, MoveEntries<K, ()>, fn((K, ())) -> K>;
623+
pub struct SetMoveItems<K> {
624+
iter: Map<(K, ()), K, MoveEntries<K, ()>, fn((K, ())) -> K>
625+
}
625626

626627
// `Repeat` is used to feed the filter closure an explicit capture
627628
// of a reference to the other set
628-
/// Set operations iterator
629-
pub type SetAlgebraItems<'a, T, H> = FilterMap<
630-
(&'a HashSet<T, H>, &'a T),
631-
&'a T,
632-
Zip<Repeat<&'a HashSet<T, H>>, SetItems<'a, T>>,
633-
for<'b> fn((&HashSet<T, H>, &'b T)) -> Option<&'b T>,
634-
>;
629+
/// Set operations iterator, used directly for intersection and difference
630+
pub struct SetAlgebraItems<'a, T: 'a, H: 'a> {
631+
iter: FilterMap<
632+
(&'a HashSet<T, H>, &'a T),
633+
&'a T,
634+
Zip<Repeat<&'a HashSet<T, H>>, SetItems<'a, T>>,
635+
for<'b> fn((&HashSet<T, H>, &'b T)) -> Option<&'b T>,
636+
>
637+
}
638+
639+
/// Symmetric difference iterator.
640+
pub struct SymDifferenceItems<'a, T: 'a, H: 'a> {
641+
iter: Chain<SetAlgebraItems<'a, T, H>, SetAlgebraItems<'a, T, H>>
642+
}
643+
644+
/// Set union iterator.
645+
pub struct UnionItems<'a, T: 'a, H: 'a> {
646+
iter: Chain<SetItems<'a, T>, SetAlgebraItems<'a, T, H>>
647+
}
648+
649+
impl<'a, K> Iterator<&'a K> for SetItems<'a, K> {
650+
fn next(&mut self) -> Option<&'a K> { self.iter.next() }
651+
fn size_hint(&self) -> (uint, Option<uint>) { self.iter.size_hint() }
652+
}
653+
654+
impl<K> Iterator<K> for SetMoveItems<K> {
655+
fn next(&mut self) -> Option<K> { self.iter.next() }
656+
fn size_hint(&self) -> (uint, Option<uint>) { self.iter.size_hint() }
657+
}
658+
659+
impl<'a, T, H> Iterator<&'a T> for SetAlgebraItems<'a, T, H> {
660+
fn next(&mut self) -> Option<&'a T> { self.iter.next() }
661+
fn size_hint(&self) -> (uint, Option<uint>) { self.iter.size_hint() }
662+
}
663+
664+
impl<'a, T, H> Iterator<&'a T> for SymDifferenceItems<'a, T, H> {
665+
fn next(&mut self) -> Option<&'a T> { self.iter.next() }
666+
fn size_hint(&self) -> (uint, Option<uint>) { self.iter.size_hint() }
667+
}
668+
669+
impl<'a, T, H> Iterator<&'a T> for UnionItems<'a, T, H> {
670+
fn next(&mut self) -> Option<&'a T> { self.iter.next() }
671+
fn size_hint(&self) -> (uint, Option<uint>) { self.iter.size_hint() }
672+
}
635673

636674
#[cfg(test)]
637675
mod test_set {

0 commit comments

Comments
 (0)