about summary refs log tree commit diff
diff options
context:
space:
mode:
authorHuon Wilson <dbau.pp+github@gmail.com>2014-12-30 21:01:36 +1100
committerHuon Wilson <dbau.pp+github@gmail.com>2014-12-30 21:01:36 +1100
commitb7832ed0b42a2d6512e3f8d09605986237f02ed5 (patch)
tree313e9f72ae737775db85764279a79122f4d8b458
parentfea5aa656ff4349f4d3e1fea1447d26986762ae1 (diff)
downloadrust-b7832ed0b42a2d6512e3f8d09605986237f02ed5.tar.gz
rust-b7832ed0b42a2d6512e3f8d09605986237f02ed5.zip
Implement `Clone` for a large number of iterators & other adaptors.
It's useful to be able to save state.
-rw-r--r--src/libcollections/binary_heap.rs7
-rw-r--r--src/libcollections/bit.rs3
-rw-r--r--src/libcollections/enum_set.rs10
-rw-r--r--src/libcollections/ring_buf.rs11
-rw-r--r--src/libcollections/slice.rs6
-rw-r--r--src/libcollections/vec_map.rs29
-rw-r--r--src/libcore/char.rs5
-rw-r--r--src/libregex/re.rs7
-rw-r--r--src/libstd/c_str.rs2
-rw-r--r--src/libstd/collections/hash/map.rs27
-rw-r--r--src/libstd/collections/hash/table.rs23
-rw-r--r--src/libstd/io/fs.rs1
-rw-r--r--src/libstd/io/util.rs2
13 files changed, 130 insertions, 3 deletions
diff --git a/src/libcollections/binary_heap.rs b/src/libcollections/binary_heap.rs
index a2f38bb6674..b2dba59c977 100644
--- a/src/libcollections/binary_heap.rs
+++ b/src/libcollections/binary_heap.rs
@@ -563,6 +563,13 @@ pub struct Iter <'a, T: 'a> {
     iter: slice::Iter<'a, T>,
 }
 
+// FIXME(#19839) Remove in favor of `#[deriving(Clone)]`
+impl<'a, T> Clone for Iter<'a, T> {
+    fn clone(&self) -> Iter<'a, T> {
+        Iter { iter: self.iter.clone() }
+    }
+}
+
 impl<'a, T> Iterator<&'a T> for Iter<'a, T> {
     #[inline]
     fn next(&mut self) -> Option<&'a T> { self.iter.next() }
diff --git a/src/libcollections/bit.rs b/src/libcollections/bit.rs
index 430d7210bf6..04ee2a0339d 100644
--- a/src/libcollections/bit.rs
+++ b/src/libcollections/bit.rs
@@ -1010,6 +1010,7 @@ impl cmp::PartialEq for Bitv {
 impl cmp::Eq for Bitv {}
 
 /// An iterator for `Bitv`.
+#[deriving(Clone)]
 pub struct Bits<'a> {
     bitv: &'a Bitv,
     next_idx: uint,
@@ -1739,12 +1740,14 @@ impl<S: hash::Writer> hash::Hash<S> for BitvSet {
 }
 
 /// An iterator for `BitvSet`.
+#[deriving(Clone)]
 pub struct BitPositions<'a> {
     set: &'a BitvSet,
     next_idx: uint
 }
 
 /// An iterator combining two `BitvSet` iterators.
+#[deriving(Clone)]
 pub struct TwoBitPositions<'a> {
     set: &'a BitvSet,
     other: &'a BitvSet,
diff --git a/src/libcollections/enum_set.rs b/src/libcollections/enum_set.rs
index fd04ce94247..b484fc41ff6 100644
--- a/src/libcollections/enum_set.rs
+++ b/src/libcollections/enum_set.rs
@@ -213,6 +213,16 @@ pub struct Iter<E> {
     bits: uint,
 }
 
+// FIXME(#19839) Remove in favor of `#[deriving(Clone)]`
+impl<E> Clone for Iter<E> {
+    fn clone(&self) -> Iter<E> {
+        Iter {
+            index: self.index,
+            bits: self.bits,
+        }
+    }
+}
+
 impl<E:CLike> Iter<E> {
     fn new(bits: uint) -> Iter<E> {
         Iter { index: 0, bits: bits }
diff --git a/src/libcollections/ring_buf.rs b/src/libcollections/ring_buf.rs
index df8e08f07a3..65ca34f3e93 100644
--- a/src/libcollections/ring_buf.rs
+++ b/src/libcollections/ring_buf.rs
@@ -1129,6 +1129,17 @@ pub struct Iter<'a, T:'a> {
     head: uint
 }
 
+// FIXME(#19839) Remove in favor of `#[deriving(Clone)]`
+impl<'a, T> Clone for Iter<'a, T> {
+    fn clone(&self) -> Iter<'a, T> {
+        Iter {
+            ring: self.ring,
+            tail: self.tail,
+            head: self.head
+        }
+    }
+}
+
 impl<'a, T> Iterator<&'a T> for Iter<'a, T> {
     #[inline]
     fn next(&mut self) -> Option<&'a T> {
diff --git a/src/libcollections/slice.rs b/src/libcollections/slice.rs
index 404804cd91d..9a58ba75b08 100644
--- a/src/libcollections/slice.rs
+++ b/src/libcollections/slice.rs
@@ -155,6 +155,7 @@ impl<'a, T: Clone, V: AsSlice<T>> VectorVector<T> for [V] {
 ///
 /// The last generated swap is always (0, 1), and it returns the
 /// sequence to its initial order.
+#[deriving(Clone)]
 pub struct ElementSwaps {
     sdir: Vec<SizeDirection>,
     /// If `true`, emit the last swap that returns the sequence to initial
@@ -177,11 +178,11 @@ impl ElementSwaps {
     }
 }
 
-#[deriving(Copy)]
+#[deriving(Copy, Clone)]
 enum Direction { Pos, Neg }
 
 /// An `Index` and `Direction` together.
-#[deriving(Copy)]
+#[deriving(Copy, Clone)]
 struct SizeDirection {
     size: uint,
     dir: Direction,
@@ -247,6 +248,7 @@ impl Iterator<(uint, uint)> for ElementSwaps {
 /// swap applied.
 ///
 /// Generates even and odd permutations alternately.
+#[deriving(Clone)]
 pub struct Permutations<T> {
     swaps: ElementSwaps,
     v: Vec<T>,
diff --git a/src/libcollections/vec_map.rs b/src/libcollections/vec_map.rs
index 5ebcc736624..fc02fbd13ea 100644
--- a/src/libcollections/vec_map.rs
+++ b/src/libcollections/vec_map.rs
@@ -667,6 +667,17 @@ pub struct Iter<'a, V:'a> {
     iter: slice::Iter<'a, Option<V>>
 }
 
+// FIXME(#19839) Remove in favor of `#[deriving(Clone)]`
+impl<'a, V> Clone for Iter<'a, V> {
+    fn clone(&self) -> Iter<'a, V> {
+        Iter {
+            front: self.front,
+            back: self.back,
+            iter: self.iter.clone()
+        }
+    }
+}
+
 iterator! { impl Iter -> (uint, &'a V), as_ref }
 double_ended_iterator! { impl Iter -> (uint, &'a V), as_ref }
 
@@ -686,11 +697,29 @@ pub struct Keys<'a, V: 'a> {
     iter: Map<(uint, &'a V), uint, Iter<'a, V>, fn((uint, &'a V)) -> uint>
 }
 
+// FIXME(#19839) Remove in favor of `#[deriving(Clone)]`
+impl<'a, V> Clone for Keys<'a, V> {
+    fn clone(&self) -> Keys<'a, V> {
+        Keys {
+            iter: self.iter.clone()
+        }
+    }
+}
+
 /// An iterator over the values of a map.
 pub struct Values<'a, V: 'a> {
     iter: Map<(uint, &'a V), &'a V, Iter<'a, V>, fn((uint, &'a V)) -> &'a V>
 }
 
+// FIXME(#19839) Remove in favor of `#[deriving(Clone)]`
+impl<'a, V> Clone for Values<'a, V> {
+    fn clone(&self) -> Values<'a, V> {
+        Values {
+            iter: self.iter.clone()
+        }
+    }
+}
+
 /// A consuming iterator over the key-value pairs of a map.
 pub struct IntoIter<V> {
     iter: FilterMap<
diff --git a/src/libcore/char.rs b/src/libcore/char.rs
index 9c12b3f68d3..f0151dda8d7 100644
--- a/src/libcore/char.rs
+++ b/src/libcore/char.rs
@@ -430,11 +430,13 @@ impl Char for char {
 
 /// An iterator over the characters that represent a `char`, as escaped by
 /// Rust's unicode escaping rules.
+#[deriving(Clone)]
 pub struct EscapeUnicode {
     c: char,
     state: EscapeUnicodeState
 }
 
+#[deriving(Clone)]
 enum EscapeUnicodeState {
     Backslash,
     Type,
@@ -486,10 +488,12 @@ impl Iterator<char> for EscapeUnicode {
 
 /// An iterator over the characters that represent a `char`, escaped
 /// for maximum portability.
+#[deriving(Clone)]
 pub struct EscapeDefault {
     state: EscapeDefaultState
 }
 
+#[deriving(Clone)]
 enum EscapeDefaultState {
     Backslash(char),
     Char(char),
@@ -513,4 +517,3 @@ impl Iterator<char> for EscapeDefault {
         }
     }
 }
-
diff --git a/src/libregex/re.rs b/src/libregex/re.rs
index 4383192edaf..51c23463155 100644
--- a/src/libregex/re.rs
+++ b/src/libregex/re.rs
@@ -539,6 +539,7 @@ impl Regex {
 
 }
 
+#[deriving(Clone)]
 pub enum NamesIter<'a> {
     NamesIterNative(::std::slice::Iter<'a, Option<&'static str>>),
     NamesIterDynamic(::std::slice::Iter<'a, Option<String>>)
@@ -595,6 +596,7 @@ impl<F> Replacer for F where F: FnMut(&Captures) -> String {
 ///
 /// `'r` is the lifetime of the compiled expression and `'t` is the lifetime
 /// of the string being split.
+#[deriving(Clone)]
 pub struct RegexSplits<'r, 't> {
     finder: FindMatches<'r, 't>,
     last: uint,
@@ -628,6 +630,7 @@ impl<'r, 't> Iterator<&'t str> for RegexSplits<'r, 't> {
 ///
 /// `'r` is the lifetime of the compiled expression and `'t` is the lifetime
 /// of the string being split.
+#[deriving(Clone)]
 pub struct RegexSplitsN<'r, 't> {
     splits: RegexSplits<'r, 't>,
     cur: uint,
@@ -791,6 +794,7 @@ impl<'t> Captures<'t> {
 /// expression.
 ///
 /// `'t` is the lifetime of the matched text.
+#[deriving(Clone)]
 pub struct SubCaptures<'t> {
     idx: uint,
     caps: &'t Captures<'t>,
@@ -813,6 +817,7 @@ impl<'t> Iterator<&'t str> for SubCaptures<'t> {
 /// Positions are byte indices in terms of the original string matched.
 ///
 /// `'t` is the lifetime of the matched text.
+#[deriving(Clone)]
 pub struct SubCapturesPos<'t> {
     idx: uint,
     caps: &'t Captures<'t>,
@@ -836,6 +841,7 @@ impl<'t> Iterator<Option<(uint, uint)>> for SubCapturesPos<'t> {
 ///
 /// `'r` is the lifetime of the compiled expression and `'t` is the lifetime
 /// of the matched string.
+#[deriving(Clone)]
 pub struct FindCaptures<'r, 't> {
     re: &'r Regex,
     search: &'t str,
@@ -878,6 +884,7 @@ impl<'r, 't> Iterator<Captures<'t>> for FindCaptures<'r, 't> {
 ///
 /// `'r` is the lifetime of the compiled expression and `'t` is the lifetime
 /// of the matched string.
+#[deriving(Clone)]
 pub struct FindMatches<'r, 't> {
     re: &'r Regex,
     search: &'t str,
diff --git a/src/libstd/c_str.rs b/src/libstd/c_str.rs
index ffe19203769..fa3bb2e8cfb 100644
--- a/src/libstd/c_str.rs
+++ b/src/libstd/c_str.rs
@@ -486,6 +486,8 @@ fn check_for_null(v: &[u8], buf: *mut libc::c_char) {
 /// External iterator for a CString's bytes.
 ///
 /// Use with the `std::iter` module.
+#[allow(raw_pointer_deriving)]
+#[deriving(Clone)]
 pub struct CChars<'a> {
     ptr: *const libc::c_char,
     marker: marker::ContravariantLifetime<'a>,
diff --git a/src/libstd/collections/hash/map.rs b/src/libstd/collections/hash/map.rs
index d749cd77cef..c095ebe4f65 100644
--- a/src/libstd/collections/hash/map.rs
+++ b/src/libstd/collections/hash/map.rs
@@ -1309,6 +1309,15 @@ pub struct Entries<'a, K: 'a, V: 'a> {
     inner: table::Entries<'a, K, V>
 }
 
+// FIXME(#19839) Remove in favor of `#[deriving(Clone)]`
+impl<'a, K, V> Clone for Entries<'a, K, V> {
+    fn clone(&self) -> Entries<'a, K, V> {
+        Entries {
+            inner: self.inner.clone()
+        }
+    }
+}
+
 /// HashMap mutable values iterator
 pub struct IterMut<'a, K: 'a, V: 'a> {
     inner: table::IterMut<'a, K, V>
@@ -1329,11 +1338,29 @@ pub struct Keys<'a, K: 'a, V: 'a> {
     inner: Map<(&'a K, &'a V), &'a K, Entries<'a, K, V>, fn((&'a K, &'a V)) -> &'a K>
 }
 
+// FIXME(#19839) Remove in favor of `#[deriving(Clone)]`
+impl<'a, K, V> Clone for Keys<'a, K, V> {
+    fn clone(&self) -> Keys<'a, K, V> {
+        Keys {
+            inner: self.inner.clone()
+        }
+    }
+}
+
 /// HashMap values iterator
 pub struct Values<'a, K: 'a, V: 'a> {
     inner: Map<(&'a K, &'a V), &'a V, Entries<'a, K, V>, fn((&'a K, &'a V)) -> &'a V>
 }
 
+// FIXME(#19839) Remove in favor of `#[deriving(Clone)]`
+impl<'a, K, V> Clone for Values<'a, K, V> {
+    fn clone(&self) -> Values<'a, K, V> {
+        Values {
+            inner: self.inner.clone()
+        }
+    }
+}
+
 /// HashMap drain iterator
 pub struct Drain<'a, K: 'a, V: 'a> {
     inner: iter::Map<
diff --git a/src/libstd/collections/hash/table.rs b/src/libstd/collections/hash/table.rs
index 3ae3a8ffbad..3f5047cf748 100644
--- a/src/libstd/collections/hash/table.rs
+++ b/src/libstd/collections/hash/table.rs
@@ -718,6 +718,18 @@ struct RawBuckets<'a, K, V> {
     marker: marker::ContravariantLifetime<'a>,
 }
 
+// FIXME(#19839) Remove in favor of `#[deriving(Clone)]`
+impl<'a, K, V> Clone for RawBuckets<'a, K, V> {
+    fn clone(&self) -> RawBuckets<'a, K, V> {
+        RawBuckets {
+            raw: self.raw,
+            hashes_end: self.hashes_end,
+            marker: marker::ContravariantLifetime,
+        }
+    }
+}
+
+
 impl<'a, K, V> Iterator<RawBucket<K, V>> for RawBuckets<'a, K, V> {
     fn next(&mut self) -> Option<RawBucket<K, V>> {
         while self.raw.hash != self.hashes_end {
@@ -775,6 +787,17 @@ pub struct Entries<'a, K: 'a, V: 'a> {
     elems_left: uint,
 }
 
+// FIXME(#19839) Remove in favor of `#[deriving(Clone)]`
+impl<'a, K, V> Clone for Entries<'a, K, V> {
+    fn clone(&self) -> Entries<'a, K, V> {
+        Entries {
+            iter: self.iter.clone(),
+            elems_left: self.elems_left
+        }
+    }
+}
+
+
 /// Iterator over mutable references to entries in a table.
 pub struct IterMut<'a, K: 'a, V: 'a> {
     iter: RawBuckets<'a, K, V>,
diff --git a/src/libstd/io/fs.rs b/src/libstd/io/fs.rs
index f2db2875ebf..5b5c1fbcec7 100644
--- a/src/libstd/io/fs.rs
+++ b/src/libstd/io/fs.rs
@@ -558,6 +558,7 @@ pub fn walk_dir(path: &Path) -> IoResult<Directories> {
 }
 
 /// An iterator that walks over a directory
+#[deriving(Clone)]
 pub struct Directories {
     stack: Vec<Path>,
 }
diff --git a/src/libstd/io/util.rs b/src/libstd/io/util.rs
index 43893ca0126..3624f14e440 100644
--- a/src/libstd/io/util.rs
+++ b/src/libstd/io/util.rs
@@ -163,6 +163,7 @@ impl Writer for MultiWriter {
 
 /// A `Reader` which chains input from multiple `Reader`s, reading each to
 /// completion before moving onto the next.
+#[deriving(Clone)]
 pub struct ChainedReader<I, R> {
     readers: I,
     cur_reader: Option<R>,
@@ -246,6 +247,7 @@ pub fn copy<R: Reader, W: Writer>(r: &mut R, w: &mut W) -> io::IoResult<()> {
 }
 
 /// An adaptor converting an `Iterator<u8>` to a `Reader`.
+#[deriving(Clone)]
 pub struct IterReader<T> {
     iter: T,
 }