about summary refs log tree commit diff
path: root/src/libstd
diff options
context:
space:
mode:
authorblake2-ppc <blake2-ppc>2013-07-18 17:38:17 +0200
committerblake2-ppc <blake2-ppc>2013-07-20 20:30:57 +0200
commit24b6901b26f0bde00706a5cbc16ffc29296ea40d (patch)
treef3eece8ac0576df1f1e57119a94a78944c2eedc6 /src/libstd
parentffe2623e47d9c5a5914865a9556cb1298ca00058 (diff)
downloadrust-24b6901b26f0bde00706a5cbc16ffc29296ea40d.tar.gz
rust-24b6901b26f0bde00706a5cbc16ffc29296ea40d.zip
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.
Diffstat (limited to 'src/libstd')
-rw-r--r--src/libstd/hashmap.rs2
-rw-r--r--src/libstd/str.rs7
-rw-r--r--src/libstd/vec.rs17
3 files changed, 26 insertions, 0 deletions
diff --git a/src/libstd/hashmap.rs b/src/libstd/hashmap.rs
index 182ee37202a..56774560d1d 100644
--- a/src/libstd/hashmap.rs
+++ b/src/libstd/hashmap.rs
@@ -548,6 +548,7 @@ impl<K:Hash + Eq + Clone,V:Clone> Clone for HashMap<K,V> {
 }
 
 /// HashMap iterator
+#[deriving(Clone)]
 pub struct HashMapIterator<'self, K, V> {
     priv iter: vec::VecIterator<'self, Option<Bucket<K, V>>>,
 }
@@ -563,6 +564,7 @@ pub struct HashMapConsumeIterator<K, V> {
 }
 
 /// HashSet iterator
+#[deriving(Clone)]
 pub struct HashSetIterator<'self, K> {
     priv iter: vec::VecIterator<'self, Option<Bucket<K, ()>>>,
 }
diff --git a/src/libstd/str.rs b/src/libstd/str.rs
index 0811dab407e..c74c1e18e6d 100644
--- a/src/libstd/str.rs
+++ b/src/libstd/str.rs
@@ -288,6 +288,7 @@ impl<'self, C: CharEq> CharEq for &'self [C] {
 
 
 /// An iterator over the substrings of a string, separated by `sep`.
+#[deriving(Clone)]
 pub struct StrCharSplitIterator<'self,Sep> {
     priv string: &'self str,
     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
 /// substring within a larger string
+#[deriving(Clone)]
 pub struct StrMatchesIndexIterator<'self> {
     priv haystack: &'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
 /// search string
+#[deriving(Clone)]
 pub struct StrStrSplitIterator<'self> {
     priv it: StrMatchesIndexIterator<'self>,
     priv last_end: uint,
@@ -2269,6 +2272,7 @@ impl Clone for @str {
 
 /// External iterator for a string's characters. Use with the `std::iterator`
 /// module.
+#[deriving(Clone)]
 pub struct StrCharIterator<'self> {
     priv index: uint,
     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
 /// with the `std::iterator` module.
+#[deriving(Clone)]
 pub struct StrCharRevIterator<'self> {
     priv index: uint,
     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`
 /// module.
+#[deriving(Clone)]
 pub struct StrBytesIterator<'self> {
     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
 /// the `std::iterator` module.
+#[deriving(Clone)]
 pub struct StrBytesRevIterator<'self> {
     priv it: vec::VecRevIterator<'self, u8>
 }
diff --git a/src/libstd/vec.rs b/src/libstd/vec.rs
index 03e94a902c1..877ee65b4d6 100644
--- a/src/libstd/vec.rs
+++ b/src/libstd/vec.rs
@@ -2232,6 +2232,10 @@ iterator!{impl VecIterator -> &'self T}
 double_ended_iterator!{impl 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}
 /// An iterator for mutating the elements of a vector.
 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>>;
 
 /// An iterator that moves out of a vector.
+#[deriving(Clone)]
 pub struct VecConsumeIterator<T> {
     priv v: ~[T],
     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.
+#[deriving(Clone)]
 pub struct VecConsumeRevIterator<T> {
     priv v: ~[T]
 }
@@ -3186,6 +3192,17 @@ mod tests {
     }
 
     #[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]
     fn test_mut_iterator() {
         use iterator::*;
         let mut xs = [1, 2, 3, 4, 5];