1
Fork 0

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>, 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> { impl<'a, T> Iterator<&'a T> for Iter<'a, T> {
#[inline] #[inline]
fn next(&mut self) -> Option<&'a T> { self.iter.next() } 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 {} impl cmp::Eq for Bitv {}
/// An iterator for `Bitv`. /// An iterator for `Bitv`.
#[deriving(Clone)]
pub struct Bits<'a> { pub struct Bits<'a> {
bitv: &'a Bitv, bitv: &'a Bitv,
next_idx: uint, next_idx: uint,
@ -1739,12 +1740,14 @@ impl<S: hash::Writer> hash::Hash<S> for BitvSet {
} }
/// An iterator for `BitvSet`. /// An iterator for `BitvSet`.
#[deriving(Clone)]
pub struct BitPositions<'a> { pub struct BitPositions<'a> {
set: &'a BitvSet, set: &'a BitvSet,
next_idx: uint next_idx: uint
} }
/// An iterator combining two `BitvSet` iterators. /// An iterator combining two `BitvSet` iterators.
#[deriving(Clone)]
pub struct TwoBitPositions<'a> { pub struct TwoBitPositions<'a> {
set: &'a BitvSet, set: &'a BitvSet,
other: &'a BitvSet, other: &'a BitvSet,

View file

@ -213,6 +213,16 @@ pub struct Iter<E> {
bits: uint, 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> { impl<E:CLike> Iter<E> {
fn new(bits: uint) -> Iter<E> { fn new(bits: uint) -> Iter<E> {
Iter { index: 0, bits: bits } Iter { index: 0, bits: bits }

View file

@ -1129,6 +1129,17 @@ pub struct Iter<'a, T:'a> {
head: uint 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> { impl<'a, T> Iterator<&'a T> for Iter<'a, T> {
#[inline] #[inline]
fn next(&mut self) -> Option<&'a T> { 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 /// The last generated swap is always (0, 1), and it returns the
/// sequence to its initial order. /// sequence to its initial order.
#[deriving(Clone)]
pub struct ElementSwaps { pub struct ElementSwaps {
sdir: Vec<SizeDirection>, sdir: Vec<SizeDirection>,
/// If `true`, emit the last swap that returns the sequence to initial /// 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 } enum Direction { Pos, Neg }
/// An `Index` and `Direction` together. /// An `Index` and `Direction` together.
#[deriving(Copy)] #[deriving(Copy, Clone)]
struct SizeDirection { struct SizeDirection {
size: uint, size: uint,
dir: Direction, dir: Direction,
@ -247,6 +248,7 @@ impl Iterator<(uint, uint)> for ElementSwaps {
/// swap applied. /// swap applied.
/// ///
/// Generates even and odd permutations alternately. /// Generates even and odd permutations alternately.
#[deriving(Clone)]
pub struct Permutations<T> { pub struct Permutations<T> {
swaps: ElementSwaps, swaps: ElementSwaps,
v: Vec<T>, v: Vec<T>,

View file

@ -667,6 +667,17 @@ pub struct Iter<'a, V:'a> {
iter: slice::Iter<'a, Option<V>> 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 } iterator! { impl Iter -> (uint, &'a V), as_ref }
double_ended_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> 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. /// An iterator over the values of a map.
pub struct Values<'a, V: 'a> { pub struct Values<'a, V: 'a> {
iter: Map<(uint, &'a V), &'a V, Iter<'a, V>, fn((uint, &'a V)) -> &'a V> 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. /// A consuming iterator over the key-value pairs of a map.
pub struct IntoIter<V> { pub struct IntoIter<V> {
iter: FilterMap< iter: FilterMap<

View file

@ -430,11 +430,13 @@ impl Char for char {
/// An iterator over the characters that represent a `char`, as escaped by /// An iterator over the characters that represent a `char`, as escaped by
/// Rust's unicode escaping rules. /// Rust's unicode escaping rules.
#[deriving(Clone)]
pub struct EscapeUnicode { pub struct EscapeUnicode {
c: char, c: char,
state: EscapeUnicodeState state: EscapeUnicodeState
} }
#[deriving(Clone)]
enum EscapeUnicodeState { enum EscapeUnicodeState {
Backslash, Backslash,
Type, Type,
@ -486,10 +488,12 @@ impl Iterator<char> for EscapeUnicode {
/// An iterator over the characters that represent a `char`, escaped /// An iterator over the characters that represent a `char`, escaped
/// for maximum portability. /// for maximum portability.
#[deriving(Clone)]
pub struct EscapeDefault { pub struct EscapeDefault {
state: EscapeDefaultState state: EscapeDefaultState
} }
#[deriving(Clone)]
enum EscapeDefaultState { enum EscapeDefaultState {
Backslash(char), Backslash(char),
Char(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> { pub enum NamesIter<'a> {
NamesIterNative(::std::slice::Iter<'a, Option<&'static str>>), NamesIterNative(::std::slice::Iter<'a, Option<&'static str>>),
NamesIterDynamic(::std::slice::Iter<'a, Option<String>>) 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 /// `'r` is the lifetime of the compiled expression and `'t` is the lifetime
/// of the string being split. /// of the string being split.
#[deriving(Clone)]
pub struct RegexSplits<'r, 't> { pub struct RegexSplits<'r, 't> {
finder: FindMatches<'r, 't>, finder: FindMatches<'r, 't>,
last: uint, 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 /// `'r` is the lifetime of the compiled expression and `'t` is the lifetime
/// of the string being split. /// of the string being split.
#[deriving(Clone)]
pub struct RegexSplitsN<'r, 't> { pub struct RegexSplitsN<'r, 't> {
splits: RegexSplits<'r, 't>, splits: RegexSplits<'r, 't>,
cur: uint, cur: uint,
@ -791,6 +794,7 @@ impl<'t> Captures<'t> {
/// expression. /// expression.
/// ///
/// `'t` is the lifetime of the matched text. /// `'t` is the lifetime of the matched text.
#[deriving(Clone)]
pub struct SubCaptures<'t> { pub struct SubCaptures<'t> {
idx: uint, idx: uint,
caps: &'t Captures<'t>, 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. /// Positions are byte indices in terms of the original string matched.
/// ///
/// `'t` is the lifetime of the matched text. /// `'t` is the lifetime of the matched text.
#[deriving(Clone)]
pub struct SubCapturesPos<'t> { pub struct SubCapturesPos<'t> {
idx: uint, idx: uint,
caps: &'t Captures<'t>, 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 /// `'r` is the lifetime of the compiled expression and `'t` is the lifetime
/// of the matched string. /// of the matched string.
#[deriving(Clone)]
pub struct FindCaptures<'r, 't> { pub struct FindCaptures<'r, 't> {
re: &'r Regex, re: &'r Regex,
search: &'t str, 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 /// `'r` is the lifetime of the compiled expression and `'t` is the lifetime
/// of the matched string. /// of the matched string.
#[deriving(Clone)]
pub struct FindMatches<'r, 't> { pub struct FindMatches<'r, 't> {
re: &'r Regex, re: &'r Regex,
search: &'t str, 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. /// External iterator for a CString's bytes.
/// ///
/// Use with the `std::iter` module. /// Use with the `std::iter` module.
#[allow(raw_pointer_deriving)]
#[deriving(Clone)]
pub struct CChars<'a> { pub struct CChars<'a> {
ptr: *const libc::c_char, ptr: *const libc::c_char,
marker: marker::ContravariantLifetime<'a>, marker: marker::ContravariantLifetime<'a>,

View file

@ -1309,6 +1309,15 @@ pub struct Entries<'a, K: 'a, V: 'a> {
inner: table::Entries<'a, K, V> 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 /// HashMap mutable values iterator
pub struct IterMut<'a, K: 'a, V: 'a> { pub struct IterMut<'a, K: 'a, V: 'a> {
inner: table::IterMut<'a, K, V> 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> 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 /// HashMap values iterator
pub struct Values<'a, K: 'a, V: 'a> { 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> 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 /// HashMap drain iterator
pub struct Drain<'a, K: 'a, V: 'a> { pub struct Drain<'a, K: 'a, V: 'a> {
inner: iter::Map< inner: iter::Map<

View file

@ -718,6 +718,18 @@ struct RawBuckets<'a, K, V> {
marker: marker::ContravariantLifetime<'a>, 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> { impl<'a, K, V> Iterator<RawBucket<K, V>> for RawBuckets<'a, K, V> {
fn next(&mut self) -> Option<RawBucket<K, V>> { fn next(&mut self) -> Option<RawBucket<K, V>> {
while self.raw.hash != self.hashes_end { while self.raw.hash != self.hashes_end {
@ -775,6 +787,17 @@ pub struct Entries<'a, K: 'a, V: 'a> {
elems_left: uint, 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. /// Iterator over mutable references to entries in a table.
pub struct IterMut<'a, K: 'a, V: 'a> { pub struct IterMut<'a, K: 'a, V: 'a> {
iter: RawBuckets<'a, K, V>, 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 /// An iterator that walks over a directory
#[deriving(Clone)]
pub struct Directories { pub struct Directories {
stack: Vec<Path>, 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 /// A `Reader` which chains input from multiple `Reader`s, reading each to
/// completion before moving onto the next. /// completion before moving onto the next.
#[deriving(Clone)]
pub struct ChainedReader<I, R> { pub struct ChainedReader<I, R> {
readers: I, readers: I,
cur_reader: Option<R>, 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`. /// An adaptor converting an `Iterator<u8>` to a `Reader`.
#[deriving(Clone)]
pub struct IterReader<T> { pub struct IterReader<T> {
iter: T, iter: T,
} }