Implement `Clone` for a large number of iterators & other adaptors.

It's useful to be able to save state.
This commit is contained in:
Huon Wilson 2014-12-30 21:01:36 +11:00
parent fea5aa656f
commit b7832ed0b4
13 changed files with 130 additions and 3 deletions

View File

@ -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() }

View File

@ -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,

View File

@ -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 }

View File

@ -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> {

View File

@ -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>,

View File

@ -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<

View File

@ -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 {
}
}
}

View File

@ -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,

View File

@ -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>,

View File

@ -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<

View File

@ -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>,

View File

@ -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>,
}

View File

@ -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,
}