Skip to content

Commit 81f9a31

Browse files
committed
Change VecMap's iterators to use wrapper structs instead of typedefs.
Using a type alias for iterator implementations is fragile since this exposes the implementation to users of the iterator, and any changes could break existing code. This commit changes the iterators of `VecMap` to use proper new types, rather than type aliases. However, since it is fair-game to treat a type-alias as the aliased type, this is a: [breaking-change].
1 parent 444fa1b commit 81f9a31

File tree

1 file changed

+45
-14
lines changed

1 file changed

+45
-14
lines changed

src/libcollections/vec_map.rs

+45-14
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ use core::prelude::*;
1818
use core::default::Default;
1919
use core::fmt;
2020
use core::iter;
21-
use core::iter::{Enumerate, FilterMap};
21+
use core::iter::{Enumerate, FilterMap, Map};
2222
use core::mem::replace;
2323
use core::ops::FnOnce;
2424

@@ -144,7 +144,7 @@ impl<V> VecMap<V> {
144144
pub fn keys<'r>(&'r self) -> Keys<'r, V> {
145145
fn first<A, B>((a, _): (A, B)) -> A { a }
146146

147-
self.iter().map(first)
147+
Keys { iter: self.iter().map(first) }
148148
}
149149

150150
/// Returns an iterator visiting all values in ascending order by the keys.
@@ -153,7 +153,7 @@ impl<V> VecMap<V> {
153153
pub fn values<'r>(&'r self) -> Values<'r, V> {
154154
fn second<A, B>((_, b): (A, B)) -> B { b }
155155

156-
self.iter().map(second)
156+
Values { iter: self.iter().map(second) }
157157
}
158158

159159
/// Returns an iterator visiting all key-value pairs in ascending order by the keys.
@@ -240,7 +240,7 @@ impl<V> VecMap<V> {
240240
}
241241

242242
let values = replace(&mut self.v, vec!());
243-
values.into_iter().enumerate().filter_map(filter)
243+
MoveItems { iter: values.into_iter().enumerate().filter_map(filter) }
244244
}
245245

246246
/// Return the number of elements in the map.
@@ -603,7 +603,7 @@ macro_rules! double_ended_iterator {
603603
}
604604
}
605605

606-
/// Forward iterator over a map.
606+
/// An iterator over the key-value pairs of a map.
607607
pub struct Entries<'a, V:'a> {
608608
front: uint,
609609
back: uint,
@@ -613,7 +613,7 @@ pub struct Entries<'a, V:'a> {
613613
iterator!(impl Entries -> (uint, &'a V), as_ref)
614614
double_ended_iterator!(impl Entries -> (uint, &'a V), as_ref)
615615

616-
/// Forward iterator over the key-value pairs of a map, with the
616+
/// An iterator over the key-value pairs of a map, with the
617617
/// values being mutable.
618618
pub struct MutEntries<'a, V:'a> {
619619
front: uint,
@@ -624,19 +624,50 @@ pub struct MutEntries<'a, V:'a> {
624624
iterator!(impl MutEntries -> (uint, &'a mut V), as_mut)
625625
double_ended_iterator!(impl MutEntries -> (uint, &'a mut V), as_mut)
626626

627-
/// Forward iterator over the keys of a map
628-
pub type Keys<'a, V> = iter::Map<(uint, &'a V), uint, Entries<'a, V>, fn((uint, &'a V)) -> uint>;
627+
/// An iterator over the keys of a map.
628+
pub struct Keys<'a, V: 'a> {
629+
iter: Map<(uint, &'a V), uint, Entries<'a, V>, fn((uint, &'a V)) -> uint>
630+
}
629631

630-
/// Forward iterator over the values of a map
631-
pub type Values<'a, V> =
632-
iter::Map<(uint, &'a V), &'a V, Entries<'a, V>, fn((uint, &'a V)) -> &'a V>;
632+
/// An iterator over the values of a map.
633+
pub struct Values<'a, V: 'a> {
634+
iter: Map<(uint, &'a V), &'a V, Entries<'a, V>, fn((uint, &'a V)) -> &'a V>
635+
}
633636

634-
/// Iterator over the key-value pairs of a map, the iterator consumes the map
635-
pub type MoveItems<V> = FilterMap<
637+
/// A consuming iterator over the key-value pairs of a map.
638+
pub struct MoveItems<V> {
639+
iter: FilterMap<
636640
(uint, Option<V>),
637641
(uint, V),
638642
Enumerate<vec::MoveItems<Option<V>>>,
639-
fn((uint, Option<V>)) -> Option<(uint, V)>>;
643+
fn((uint, Option<V>)) -> Option<(uint, V)>>
644+
}
645+
646+
impl<'a, V> Iterator<uint> for Keys<'a, V> {
647+
fn next(&mut self) -> Option<uint> { self.iter.next() }
648+
fn size_hint(&self) -> (uint, Option<uint>) { self.iter.size_hint() }
649+
}
650+
impl<'a, V> DoubleEndedIterator<uint> for Keys<'a, V> {
651+
fn next_back(&mut self) -> Option<uint> { self.iter.next_back() }
652+
}
653+
654+
655+
impl<'a, V> Iterator<&'a V> for Values<'a, V> {
656+
fn next(&mut self) -> Option<(&'a V)> { self.iter.next() }
657+
fn size_hint(&self) -> (uint, Option<uint>) { self.iter.size_hint() }
658+
}
659+
impl<'a, V> DoubleEndedIterator<&'a V> for Values<'a, V> {
660+
fn next_back(&mut self) -> Option<(&'a V)> { self.iter.next_back() }
661+
}
662+
663+
664+
impl<V> Iterator<(uint, V)> for MoveItems<V> {
665+
fn next(&mut self) -> Option<(uint, V)> { self.iter.next() }
666+
fn size_hint(&self) -> (uint, Option<uint>) { self.iter.size_hint() }
667+
}
668+
impl<V> DoubleEndedIterator<(uint, V)> for MoveItems<V> {
669+
fn next_back(&mut self) -> Option<(uint, V)> { self.iter.next_back() }
670+
}
640671

641672
#[cfg(test)]
642673
mod test_map {

0 commit comments

Comments
 (0)