std: Implement Clone for VecIterator and iterators using it

The theory is simple, the immutable iterators simply hold state
variables (indicies or pointers) into frozen containers. We can freely
clone these iterators, just like we can clone borrowed pointers.

VecIterator needs a manual impl to handle the lifetime struct member.
This commit is contained in:
blake2-ppc
2013-07-18 17:38:17 +02:00
parent ffe2623e47
commit 24b6901b26
3 changed files with 26 additions and 0 deletions

View File

@@ -548,6 +548,7 @@ impl<K:Hash + Eq + Clone,V:Clone> Clone for HashMap<K,V> {
} }
/// HashMap iterator /// HashMap iterator
#[deriving(Clone)]
pub struct HashMapIterator<'self, K, V> { pub struct HashMapIterator<'self, K, V> {
priv iter: vec::VecIterator<'self, Option<Bucket<K, V>>>, priv iter: vec::VecIterator<'self, Option<Bucket<K, V>>>,
} }
@@ -563,6 +564,7 @@ pub struct HashMapConsumeIterator<K, V> {
} }
/// HashSet iterator /// HashSet iterator
#[deriving(Clone)]
pub struct HashSetIterator<'self, K> { pub struct HashSetIterator<'self, K> {
priv iter: vec::VecIterator<'self, Option<Bucket<K, ()>>>, priv iter: vec::VecIterator<'self, Option<Bucket<K, ()>>>,
} }

View File

@@ -288,6 +288,7 @@ impl<'self, C: CharEq> CharEq for &'self [C] {
/// An iterator over the substrings of a string, separated by `sep`. /// An iterator over the substrings of a string, separated by `sep`.
#[deriving(Clone)]
pub struct StrCharSplitIterator<'self,Sep> { pub struct StrCharSplitIterator<'self,Sep> {
priv string: &'self str, priv string: &'self str,
priv position: uint, priv position: uint,
@@ -355,6 +356,7 @@ impl<'self, Sep: CharEq> Iterator<&'self str> for StrCharSplitIterator<'self, Se
/// An iterator over the start and end indicies of the matches of a /// An iterator over the start and end indicies of the matches of a
/// substring within a larger string /// substring within a larger string
#[deriving(Clone)]
pub struct StrMatchesIndexIterator<'self> { pub struct StrMatchesIndexIterator<'self> {
priv haystack: &'self str, priv haystack: &'self str,
priv needle: &'self str, priv needle: &'self str,
@@ -363,6 +365,7 @@ pub struct StrMatchesIndexIterator<'self> {
/// An iterator over the substrings of a string separated by a given /// An iterator over the substrings of a string separated by a given
/// search string /// search string
#[deriving(Clone)]
pub struct StrStrSplitIterator<'self> { pub struct StrStrSplitIterator<'self> {
priv it: StrMatchesIndexIterator<'self>, priv it: StrMatchesIndexIterator<'self>,
priv last_end: uint, priv last_end: uint,
@@ -2269,6 +2272,7 @@ impl Clone for @str {
/// External iterator for a string's characters. Use with the `std::iterator` /// External iterator for a string's characters. Use with the `std::iterator`
/// module. /// module.
#[deriving(Clone)]
pub struct StrCharIterator<'self> { pub struct StrCharIterator<'self> {
priv index: uint, priv index: uint,
priv string: &'self str, priv string: &'self str,
@@ -2288,6 +2292,7 @@ impl<'self> Iterator<char> for StrCharIterator<'self> {
} }
/// External iterator for a string's characters in reverse order. Use /// External iterator for a string's characters in reverse order. Use
/// with the `std::iterator` module. /// with the `std::iterator` module.
#[deriving(Clone)]
pub struct StrCharRevIterator<'self> { pub struct StrCharRevIterator<'self> {
priv index: uint, priv index: uint,
priv string: &'self str, priv string: &'self str,
@@ -2308,6 +2313,7 @@ impl<'self> Iterator<char> for StrCharRevIterator<'self> {
/// External iterator for a string's bytes. Use with the `std::iterator` /// External iterator for a string's bytes. Use with the `std::iterator`
/// module. /// module.
#[deriving(Clone)]
pub struct StrBytesIterator<'self> { pub struct StrBytesIterator<'self> {
priv it: vec::VecIterator<'self, u8> priv it: vec::VecIterator<'self, u8>
} }
@@ -2321,6 +2327,7 @@ impl<'self> Iterator<u8> for StrBytesIterator<'self> {
/// External iterator for a string's bytes in reverse order. Use with /// External iterator for a string's bytes in reverse order. Use with
/// the `std::iterator` module. /// the `std::iterator` module.
#[deriving(Clone)]
pub struct StrBytesRevIterator<'self> { pub struct StrBytesRevIterator<'self> {
priv it: vec::VecRevIterator<'self, u8> priv it: vec::VecRevIterator<'self, u8>
} }

View File

@@ -2232,6 +2232,10 @@ iterator!{impl VecIterator -> &'self T}
double_ended_iterator!{impl VecIterator -> &'self T} double_ended_iterator!{impl VecIterator -> &'self T}
pub type VecRevIterator<'self, T> = InvertIterator<&'self T, VecIterator<'self, T>>; pub type VecRevIterator<'self, T> = InvertIterator<&'self T, VecIterator<'self, T>>;
impl<'self, T> Clone for VecIterator<'self, T> {
fn clone(&self) -> VecIterator<'self, T> { *self }
}
//iterator!{struct VecMutIterator -> *mut T, &'self mut T} //iterator!{struct VecMutIterator -> *mut T, &'self mut T}
/// An iterator for mutating the elements of a vector. /// An iterator for mutating the elements of a vector.
pub struct VecMutIterator<'self, T> { pub struct VecMutIterator<'self, T> {
@@ -2244,6 +2248,7 @@ double_ended_iterator!{impl VecMutIterator -> &'self mut T}
pub type VecMutRevIterator<'self, T> = InvertIterator<&'self mut T, VecMutIterator<'self, T>>; pub type VecMutRevIterator<'self, T> = InvertIterator<&'self mut T, VecMutIterator<'self, T>>;
/// An iterator that moves out of a vector. /// An iterator that moves out of a vector.
#[deriving(Clone)]
pub struct VecConsumeIterator<T> { pub struct VecConsumeIterator<T> {
priv v: ~[T], priv v: ~[T],
priv idx: uint, priv idx: uint,
@@ -2270,6 +2275,7 @@ impl<T> Iterator<T> for VecConsumeIterator<T> {
} }
/// An iterator that moves out of a vector in reverse order. /// An iterator that moves out of a vector in reverse order.
#[deriving(Clone)]
pub struct VecConsumeRevIterator<T> { pub struct VecConsumeRevIterator<T> {
priv v: ~[T] priv v: ~[T]
} }
@@ -3185,6 +3191,17 @@ mod tests {
assert_eq!(xs.mut_rev_iter().size_hint(), (5, Some(5))); assert_eq!(xs.mut_rev_iter().size_hint(), (5, Some(5)));
} }
#[test]
fn test_iter_clone() {
let xs = [1, 2, 5];
let mut it = xs.iter();
it.next();
let mut jt = it.clone();
assert_eq!(it.next(), jt.next());
assert_eq!(it.next(), jt.next());
assert_eq!(it.next(), jt.next());
}
#[test] #[test]
fn test_mut_iterator() { fn test_mut_iterator() {
use iterator::*; use iterator::*;