auto merge of #8120 : blake2-ppc/rust/iterator-fixes, r=thestinger
Implement RandomAccessIterator (RAI) where possible, for Iterator adaptors such as Map, Enumerate, Peek, Skip, Take, Cycle, where the adapted iterator is already RAI, and for collections where it is relevant (ringbuf and bitv). After discussion with thestinger, remove the RAI impl for VecMutIterator, we cannot soundly provide mutable access with this trait. Implement Extendable everywhere FromIterator is already implemented. Fixes issue #8108.
This commit is contained in:
commit
e94e4d51ca
10 changed files with 487 additions and 118 deletions
|
@ -12,11 +12,13 @@
|
||||||
|
|
||||||
|
|
||||||
use std::cmp;
|
use std::cmp;
|
||||||
|
use std::iterator::{DoubleEndedIterator, RandomAccessIterator, Invert};
|
||||||
use std::num;
|
use std::num;
|
||||||
use std::ops;
|
use std::ops;
|
||||||
use std::uint;
|
use std::uint;
|
||||||
use std::vec;
|
use std::vec;
|
||||||
|
|
||||||
|
|
||||||
#[deriving(Clone)]
|
#[deriving(Clone)]
|
||||||
struct SmallBitv {
|
struct SmallBitv {
|
||||||
/// only the lowest nbits of this value are used. the rest is undefined.
|
/// only the lowest nbits of this value are used. the rest is undefined.
|
||||||
|
@ -404,7 +406,12 @@ impl Bitv {
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn iter<'a>(&'a self) -> BitvIterator<'a> {
|
pub fn iter<'a>(&'a self) -> BitvIterator<'a> {
|
||||||
BitvIterator {bitv: self, next_idx: 0}
|
BitvIterator {bitv: self, next_idx: 0, end_idx: self.nbits}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub fn rev_liter<'a>(&'a self) -> Invert<BitvIterator<'a>> {
|
||||||
|
self.iter().invert()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns true if all bits are 0
|
/// Returns true if all bits are 0
|
||||||
|
@ -564,13 +571,14 @@ fn iterate_bits(base: uint, bits: uint, f: &fn(uint) -> bool) -> bool {
|
||||||
/// An iterator for Bitv
|
/// An iterator for Bitv
|
||||||
pub struct BitvIterator<'self> {
|
pub struct BitvIterator<'self> {
|
||||||
priv bitv: &'self Bitv,
|
priv bitv: &'self Bitv,
|
||||||
priv next_idx: uint
|
priv next_idx: uint,
|
||||||
|
priv end_idx: uint,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'self> Iterator<bool> for BitvIterator<'self> {
|
impl<'self> Iterator<bool> for BitvIterator<'self> {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn next(&mut self) -> Option<bool> {
|
fn next(&mut self) -> Option<bool> {
|
||||||
if self.next_idx < self.bitv.nbits {
|
if self.next_idx != self.end_idx {
|
||||||
let idx = self.next_idx;
|
let idx = self.next_idx;
|
||||||
self.next_idx += 1;
|
self.next_idx += 1;
|
||||||
Some(self.bitv.get(idx))
|
Some(self.bitv.get(idx))
|
||||||
|
@ -580,11 +588,39 @@ impl<'self> Iterator<bool> for BitvIterator<'self> {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn size_hint(&self) -> (uint, Option<uint>) {
|
fn size_hint(&self) -> (uint, Option<uint>) {
|
||||||
let rem = self.bitv.nbits - self.next_idx;
|
let rem = self.end_idx - self.next_idx;
|
||||||
(rem, Some(rem))
|
(rem, Some(rem))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<'self> DoubleEndedIterator<bool> for BitvIterator<'self> {
|
||||||
|
#[inline]
|
||||||
|
fn next_back(&mut self) -> Option<bool> {
|
||||||
|
if self.next_idx != self.end_idx {
|
||||||
|
self.end_idx -= 1;
|
||||||
|
Some(self.bitv.get(self.end_idx))
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'self> RandomAccessIterator<bool> for BitvIterator<'self> {
|
||||||
|
#[inline]
|
||||||
|
fn indexable(&self) -> uint {
|
||||||
|
self.end_idx - self.next_idx
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn idx(&self, index: uint) -> Option<bool> {
|
||||||
|
if index >= self.indexable() {
|
||||||
|
None
|
||||||
|
} else {
|
||||||
|
Some(self.bitv.get(index))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// An implementation of a set using a bit vector as an underlying
|
/// An implementation of a set using a bit vector as an underlying
|
||||||
/// representation for holding numerical elements.
|
/// representation for holding numerical elements.
|
||||||
///
|
///
|
||||||
|
|
|
@ -25,7 +25,7 @@
|
||||||
use std::cast;
|
use std::cast;
|
||||||
use std::ptr;
|
use std::ptr;
|
||||||
use std::util;
|
use std::util;
|
||||||
use std::iterator::{FromIterator, Invert};
|
use std::iterator::{FromIterator, Extendable, Invert};
|
||||||
|
|
||||||
use container::Deque;
|
use container::Deque;
|
||||||
|
|
||||||
|
@ -541,11 +541,17 @@ impl<A> DoubleEndedIterator<A> for ConsumeIterator<A> {
|
||||||
impl<A, T: Iterator<A>> FromIterator<A, T> for DList<A> {
|
impl<A, T: Iterator<A>> FromIterator<A, T> for DList<A> {
|
||||||
fn from_iterator(iterator: &mut T) -> DList<A> {
|
fn from_iterator(iterator: &mut T) -> DList<A> {
|
||||||
let mut ret = DList::new();
|
let mut ret = DList::new();
|
||||||
for iterator.advance |elt| { ret.push_back(elt); }
|
ret.extend(iterator);
|
||||||
ret
|
ret
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<A, T: Iterator<A>> Extendable<A, T> for DList<A> {
|
||||||
|
fn extend(&mut self, iterator: &mut T) {
|
||||||
|
for iterator.advance |elt| { self.push_back(elt); }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<A: Eq> Eq for DList<A> {
|
impl<A: Eq> Eq for DList<A> {
|
||||||
fn eq(&self, other: &DList<A>) -> bool {
|
fn eq(&self, other: &DList<A>) -> bool {
|
||||||
self.len() == other.len() &&
|
self.len() == other.len() &&
|
||||||
|
|
|
@ -16,7 +16,7 @@ use std::clone::Clone;
|
||||||
use std::unstable::intrinsics::{move_val_init, init};
|
use std::unstable::intrinsics::{move_val_init, init};
|
||||||
use std::util::{replace, swap};
|
use std::util::{replace, swap};
|
||||||
use std::vec;
|
use std::vec;
|
||||||
use std::iterator::FromIterator;
|
use std::iterator::{FromIterator, Extendable};
|
||||||
|
|
||||||
/// A priority queue implemented with a binary heap
|
/// A priority queue implemented with a binary heap
|
||||||
#[deriving(Clone)]
|
#[deriving(Clone)]
|
||||||
|
@ -191,20 +191,27 @@ impl<'self, T> Iterator<&'self T> for PriorityQueueIterator<'self, T> {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: Ord, Iter: Iterator<T>> FromIterator<T, Iter> for PriorityQueue<T> {
|
impl<T: Ord, Iter: Iterator<T>> FromIterator<T, Iter> for PriorityQueue<T> {
|
||||||
pub fn from_iterator(iter: &mut Iter) -> PriorityQueue<T> {
|
fn from_iterator(iter: &mut Iter) -> PriorityQueue<T> {
|
||||||
let (lower, _) = iter.size_hint();
|
|
||||||
|
|
||||||
let mut q = PriorityQueue::new();
|
let mut q = PriorityQueue::new();
|
||||||
q.reserve_at_least(lower);
|
q.extend(iter);
|
||||||
|
|
||||||
for iter.advance |elem| {
|
|
||||||
q.push(elem);
|
|
||||||
}
|
|
||||||
|
|
||||||
q
|
q
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<T: Ord, Iter: Iterator<T>> Extendable<T, Iter> for PriorityQueue<T> {
|
||||||
|
fn extend(&mut self, iter: &mut Iter) {
|
||||||
|
let (lower, _) = iter.size_hint();
|
||||||
|
|
||||||
|
let len = self.capacity();
|
||||||
|
self.reserve_at_least(len + lower);
|
||||||
|
|
||||||
|
for iter.advance |elem| {
|
||||||
|
self.push(elem);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use sort::merge_sort;
|
use sort::merge_sort;
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
use std::num;
|
use std::num;
|
||||||
use std::uint;
|
use std::uint;
|
||||||
use std::vec;
|
use std::vec;
|
||||||
use std::iterator::{FromIterator, Invert};
|
use std::iterator::{FromIterator, Invert, RandomAccessIterator, Extendable};
|
||||||
|
|
||||||
use container::Deque;
|
use container::Deque;
|
||||||
|
|
||||||
|
@ -176,8 +176,7 @@ impl<T> RingBuf<T> {
|
||||||
|
|
||||||
/// Front-to-back iterator.
|
/// Front-to-back iterator.
|
||||||
pub fn iter<'a>(&'a self) -> RingBufIterator<'a, T> {
|
pub fn iter<'a>(&'a self) -> RingBufIterator<'a, T> {
|
||||||
RingBufIterator{index: 0, rindex: self.nelts - 1,
|
RingBufIterator{index: 0, rindex: self.nelts, lo: self.lo, elts: self.elts}
|
||||||
nelts: self.nelts, elts: self.elts, lo: self.lo}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Back-to-front iterator.
|
/// Back-to-front iterator.
|
||||||
|
@ -187,8 +186,7 @@ impl<T> RingBuf<T> {
|
||||||
|
|
||||||
/// Front-to-back iterator which returns mutable values.
|
/// Front-to-back iterator which returns mutable values.
|
||||||
pub fn mut_iter<'a>(&'a mut self) -> RingBufMutIterator<'a, T> {
|
pub fn mut_iter<'a>(&'a mut self) -> RingBufMutIterator<'a, T> {
|
||||||
RingBufMutIterator{index: 0, rindex: self.nelts - 1,
|
RingBufMutIterator{index: 0, rindex: self.nelts, lo: self.lo, elts: self.elts}
|
||||||
nelts: self.nelts, elts: self.elts, lo: self.lo}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Back-to-front iterator which returns mutable values.
|
/// Back-to-front iterator which returns mutable values.
|
||||||
|
@ -202,18 +200,18 @@ macro_rules! iterator {
|
||||||
impl<'self, T> Iterator<$elem> for $name<'self, T> {
|
impl<'self, T> Iterator<$elem> for $name<'self, T> {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn next(&mut self) -> Option<$elem> {
|
fn next(&mut self) -> Option<$elem> {
|
||||||
if self.nelts == 0 {
|
if self.index == self.rindex {
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
let raw_index = raw_index(self.lo, self.elts.len(), self.index);
|
let raw_index = raw_index(self.lo, self.elts.len(), self.index);
|
||||||
self.index += 1;
|
self.index += 1;
|
||||||
self.nelts -= 1;
|
Some(self.elts[raw_index] . $getter ())
|
||||||
Some(self.elts[raw_index]. $getter ())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn size_hint(&self) -> (uint, Option<uint>) {
|
fn size_hint(&self) -> (uint, Option<uint>) {
|
||||||
(self.nelts, Some(self.nelts))
|
let len = self.rindex - self.index;
|
||||||
|
(len, Some(len))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -224,22 +222,21 @@ macro_rules! iterator_rev {
|
||||||
impl<'self, T> DoubleEndedIterator<$elem> for $name<'self, T> {
|
impl<'self, T> DoubleEndedIterator<$elem> for $name<'self, T> {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn next_back(&mut self) -> Option<$elem> {
|
fn next_back(&mut self) -> Option<$elem> {
|
||||||
if self.nelts == 0 {
|
if self.index == self.rindex {
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
let raw_index = raw_index(self.lo, self.elts.len(), self.rindex);
|
|
||||||
self.rindex -= 1;
|
self.rindex -= 1;
|
||||||
self.nelts -= 1;
|
let raw_index = raw_index(self.lo, self.elts.len(), self.rindex);
|
||||||
Some(self.elts[raw_index]. $getter ())
|
Some(self.elts[raw_index] . $getter ())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/// RingBuf iterator
|
/// RingBuf iterator
|
||||||
pub struct RingBufIterator<'self, T> {
|
pub struct RingBufIterator<'self, T> {
|
||||||
priv lo: uint,
|
priv lo: uint,
|
||||||
priv nelts: uint,
|
|
||||||
priv index: uint,
|
priv index: uint,
|
||||||
priv rindex: uint,
|
priv rindex: uint,
|
||||||
priv elts: &'self [Option<T>],
|
priv elts: &'self [Option<T>],
|
||||||
|
@ -247,10 +244,24 @@ pub struct RingBufIterator<'self, T> {
|
||||||
iterator!{impl RingBufIterator -> &'self T, get_ref}
|
iterator!{impl RingBufIterator -> &'self T, get_ref}
|
||||||
iterator_rev!{impl RingBufIterator -> &'self T, get_ref}
|
iterator_rev!{impl RingBufIterator -> &'self T, get_ref}
|
||||||
|
|
||||||
|
impl<'self, T> RandomAccessIterator<&'self T> for RingBufIterator<'self, T> {
|
||||||
|
#[inline]
|
||||||
|
fn indexable(&self) -> uint { self.rindex - self.index }
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn idx(&self, j: uint) -> Option<&'self T> {
|
||||||
|
if j >= self.indexable() {
|
||||||
|
None
|
||||||
|
} else {
|
||||||
|
let raw_index = raw_index(self.lo, self.elts.len(), self.index + j);
|
||||||
|
Some(self.elts[raw_index].get_ref())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// RingBuf mutable iterator
|
/// RingBuf mutable iterator
|
||||||
pub struct RingBufMutIterator<'self, T> {
|
pub struct RingBufMutIterator<'self, T> {
|
||||||
priv lo: uint,
|
priv lo: uint,
|
||||||
priv nelts: uint,
|
|
||||||
priv index: uint,
|
priv index: uint,
|
||||||
priv rindex: uint,
|
priv rindex: uint,
|
||||||
priv elts: &'self mut [Option<T>],
|
priv elts: &'self mut [Option<T>],
|
||||||
|
@ -314,14 +325,21 @@ impl<A: Eq> Eq for RingBuf<A> {
|
||||||
|
|
||||||
impl<A, T: Iterator<A>> FromIterator<A, T> for RingBuf<A> {
|
impl<A, T: Iterator<A>> FromIterator<A, T> for RingBuf<A> {
|
||||||
fn from_iterator(iterator: &mut T) -> RingBuf<A> {
|
fn from_iterator(iterator: &mut T) -> RingBuf<A> {
|
||||||
let mut deq = RingBuf::new();
|
let (lower, _) = iterator.size_hint();
|
||||||
for iterator.advance |elt| {
|
let mut deq = RingBuf::with_capacity(lower);
|
||||||
deq.push_back(elt);
|
deq.extend(iterator);
|
||||||
}
|
|
||||||
deq
|
deq
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<A, T: Iterator<A>> Extendable<A, T> for RingBuf<A> {
|
||||||
|
fn extend(&mut self, iterator: &mut T) {
|
||||||
|
for iterator.advance |elt| {
|
||||||
|
self.push_back(elt);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
|
@ -15,7 +15,7 @@
|
||||||
|
|
||||||
use std::num;
|
use std::num;
|
||||||
use std::util::{swap, replace};
|
use std::util::{swap, replace};
|
||||||
use std::iterator::FromIterator;
|
use std::iterator::{FromIterator, Extendable};
|
||||||
|
|
||||||
// This is implemented as an AA tree, which is a simplified variation of
|
// This is implemented as an AA tree, which is a simplified variation of
|
||||||
// a red-black tree where red (horizontal) nodes can only be added
|
// a red-black tree where red (horizontal) nodes can only be added
|
||||||
|
@ -753,29 +753,39 @@ fn remove<K: TotalOrd, V>(node: &mut Option<~TreeNode<K, V>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<K: TotalOrd, V, T: Iterator<(K, V)>> FromIterator<(K, V), T> for TreeMap<K, V> {
|
impl<K: TotalOrd, V, T: Iterator<(K, V)>> FromIterator<(K, V), T> for TreeMap<K, V> {
|
||||||
pub fn from_iterator(iter: &mut T) -> TreeMap<K, V> {
|
fn from_iterator(iter: &mut T) -> TreeMap<K, V> {
|
||||||
let mut map = TreeMap::new();
|
let mut map = TreeMap::new();
|
||||||
|
map.extend(iter);
|
||||||
for iter.advance |(k, v)| {
|
|
||||||
map.insert(k, v);
|
|
||||||
}
|
|
||||||
|
|
||||||
map
|
map
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<K: TotalOrd, V, T: Iterator<(K, V)>> Extendable<(K, V), T> for TreeMap<K, V> {
|
||||||
|
#[inline]
|
||||||
|
fn extend(&mut self, iter: &mut T) {
|
||||||
|
for iter.advance |(k, v)| {
|
||||||
|
self.insert(k, v);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<T: TotalOrd, Iter: Iterator<T>> FromIterator<T, Iter> for TreeSet<T> {
|
impl<T: TotalOrd, Iter: Iterator<T>> FromIterator<T, Iter> for TreeSet<T> {
|
||||||
pub fn from_iterator(iter: &mut Iter) -> TreeSet<T> {
|
pub fn from_iterator(iter: &mut Iter) -> TreeSet<T> {
|
||||||
let mut set = TreeSet::new();
|
let mut set = TreeSet::new();
|
||||||
|
set.extend(iter);
|
||||||
for iter.advance |elem| {
|
|
||||||
set.insert(elem);
|
|
||||||
}
|
|
||||||
|
|
||||||
set
|
set
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<T: TotalOrd, Iter: Iterator<T>> Extendable<T, Iter> for TreeSet<T> {
|
||||||
|
#[inline]
|
||||||
|
fn extend(&mut self, iter: &mut Iter) {
|
||||||
|
for iter.advance |elem| {
|
||||||
|
self.insert(elem);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod test_treemap {
|
mod test_treemap {
|
||||||
|
|
||||||
|
|
|
@ -19,7 +19,7 @@ use container::{Container, Mutable, Map, MutableMap, Set, MutableSet};
|
||||||
use clone::Clone;
|
use clone::Clone;
|
||||||
use cmp::{Eq, Equiv};
|
use cmp::{Eq, Equiv};
|
||||||
use hash::Hash;
|
use hash::Hash;
|
||||||
use iterator::{Iterator, IteratorUtil, FromIterator, Chain};
|
use iterator::{Iterator, IteratorUtil, FromIterator, Extendable, Chain};
|
||||||
use num;
|
use num;
|
||||||
use option::{None, Option, Some};
|
use option::{None, Option, Some};
|
||||||
use rand::RngUtil;
|
use rand::RngUtil;
|
||||||
|
@ -618,18 +618,22 @@ impl<K> Iterator<K> for HashSetConsumeIterator<K> {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<K: Eq + Hash, V, T: Iterator<(K, V)>> FromIterator<(K, V), T> for HashMap<K, V> {
|
impl<K: Eq + Hash, V, T: Iterator<(K, V)>> FromIterator<(K, V), T> for HashMap<K, V> {
|
||||||
pub fn from_iterator(iter: &mut T) -> HashMap<K, V> {
|
fn from_iterator(iter: &mut T) -> HashMap<K, V> {
|
||||||
let (lower, _) = iter.size_hint();
|
let (lower, _) = iter.size_hint();
|
||||||
let mut map = HashMap::with_capacity(lower);
|
let mut map = HashMap::with_capacity(lower);
|
||||||
|
map.extend(iter);
|
||||||
for iter.advance |(k, v)| {
|
|
||||||
map.insert(k, v);
|
|
||||||
}
|
|
||||||
|
|
||||||
map
|
map
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<K: Eq + Hash, V, T: Iterator<(K, V)>> Extendable<(K, V), T> for HashMap<K, V> {
|
||||||
|
fn extend(&mut self, iter: &mut T) {
|
||||||
|
for iter.advance |(k, v)| {
|
||||||
|
self.insert(k, v);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// An implementation of a hash set using the underlying representation of a
|
/// An implementation of a hash set using the underlying representation of a
|
||||||
/// HashMap where the value is (). As with the `HashMap` type, a `HashSet`
|
/// HashMap where the value is (). As with the `HashMap` type, a `HashSet`
|
||||||
/// requires that the elements implement the `Eq` and `Hash` traits.
|
/// requires that the elements implement the `Eq` and `Hash` traits.
|
||||||
|
@ -771,18 +775,22 @@ impl<T:Hash + Eq> HashSet<T> {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<K: Eq + Hash, T: Iterator<K>> FromIterator<K, T> for HashSet<K> {
|
impl<K: Eq + Hash, T: Iterator<K>> FromIterator<K, T> for HashSet<K> {
|
||||||
pub fn from_iterator(iter: &mut T) -> HashSet<K> {
|
fn from_iterator(iter: &mut T) -> HashSet<K> {
|
||||||
let (lower, _) = iter.size_hint();
|
let (lower, _) = iter.size_hint();
|
||||||
let mut set = HashSet::with_capacity(lower);
|
let mut set = HashSet::with_capacity(lower);
|
||||||
|
set.extend(iter);
|
||||||
for iter.advance |k| {
|
|
||||||
set.insert(k);
|
|
||||||
}
|
|
||||||
|
|
||||||
set
|
set
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<K: Eq + Hash, T: Iterator<K>> Extendable<K, T> for HashSet<K> {
|
||||||
|
fn extend(&mut self, iter: &mut T) {
|
||||||
|
for iter.advance |k| {
|
||||||
|
self.insert(k);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// FIXME #7814: use std::iterator::FilterIterator
|
// FIXME #7814: use std::iterator::FilterIterator
|
||||||
/// Building block for Set operation iterators
|
/// Building block for Set operation iterators
|
||||||
pub struct EnvFilterIterator<A, Env, I> {
|
pub struct EnvFilterIterator<A, Env, I> {
|
||||||
|
|
|
@ -529,7 +529,7 @@ impl<A, T: Iterator<A>> IteratorUtil<A> for T {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn flat_map_<'r, B, U: Iterator<B>>(self, f: &'r fn(A) -> U)
|
fn flat_map_<'r, B, U: Iterator<B>>(self, f: &'r fn(A) -> U)
|
||||||
-> FlatMap<'r, A, T, U> {
|
-> FlatMap<'r, A, T, U> {
|
||||||
FlatMap{iter: self, f: f, subiter: None }
|
FlatMap{iter: self, f: f, frontiter: None, backiter: None }
|
||||||
}
|
}
|
||||||
|
|
||||||
// FIXME: #5898: should be called `peek`
|
// FIXME: #5898: should be called `peek`
|
||||||
|
@ -811,6 +811,30 @@ impl<A, T: Clone + Iterator<A>> Iterator<A> for Cycle<T> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<A, T: Clone + RandomAccessIterator<A>> RandomAccessIterator<A> for Cycle<T> {
|
||||||
|
#[inline]
|
||||||
|
fn indexable(&self) -> uint {
|
||||||
|
if self.orig.indexable() > 0 {
|
||||||
|
uint::max_value
|
||||||
|
} else {
|
||||||
|
0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn idx(&self, index: uint) -> Option<A> {
|
||||||
|
let liter = self.iter.indexable();
|
||||||
|
let lorig = self.orig.indexable();
|
||||||
|
if lorig == 0 {
|
||||||
|
None
|
||||||
|
} else if index < liter {
|
||||||
|
self.iter.idx(index)
|
||||||
|
} else {
|
||||||
|
self.orig.idx((index - liter) % lorig)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// An iterator which strings two iterators together
|
/// An iterator which strings two iterators together
|
||||||
#[deriving(Clone)]
|
#[deriving(Clone)]
|
||||||
pub struct Chain<T, U> {
|
pub struct Chain<T, U> {
|
||||||
|
@ -924,20 +948,44 @@ impl<A, B, T: Iterator<A>, U: Iterator<B>> Iterator<(A, B)> for Zip<T, U> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<A, B, T: RandomAccessIterator<A>, U: RandomAccessIterator<B>>
|
||||||
|
RandomAccessIterator<(A, B)> for Zip<T, U> {
|
||||||
|
#[inline]
|
||||||
|
fn indexable(&self) -> uint {
|
||||||
|
cmp::min(self.a.indexable(), self.b.indexable())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn idx(&self, index: uint) -> Option<(A, B)> {
|
||||||
|
match (self.a.idx(index), self.b.idx(index)) {
|
||||||
|
(Some(x), Some(y)) => Some((x, y)),
|
||||||
|
_ => None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// An iterator which maps the values of `iter` with `f`
|
/// An iterator which maps the values of `iter` with `f`
|
||||||
pub struct Map<'self, A, B, T> {
|
pub struct Map<'self, A, B, T> {
|
||||||
priv iter: T,
|
priv iter: T,
|
||||||
priv f: &'self fn(A) -> B
|
priv f: &'self fn(A) -> B
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'self, A, B, T: Iterator<A>> Iterator<B> for Map<'self, A, B, T> {
|
impl<'self, A, B, T> Map<'self, A, B, T> {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn next(&mut self) -> Option<B> {
|
fn do_map(&self, elt: Option<A>) -> Option<B> {
|
||||||
match self.iter.next() {
|
match elt {
|
||||||
Some(a) => Some((self.f)(a)),
|
Some(a) => Some((self.f)(a)),
|
||||||
_ => None
|
_ => None
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'self, A, B, T: Iterator<A>> Iterator<B> for Map<'self, A, B, T> {
|
||||||
|
#[inline]
|
||||||
|
fn next(&mut self) -> Option<B> {
|
||||||
|
let next = self.iter.next();
|
||||||
|
self.do_map(next)
|
||||||
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn size_hint(&self) -> (uint, Option<uint>) {
|
fn size_hint(&self) -> (uint, Option<uint>) {
|
||||||
|
@ -949,10 +997,21 @@ impl<'self, A, B, T: DoubleEndedIterator<A>> DoubleEndedIterator<B>
|
||||||
for Map<'self, A, B, T> {
|
for Map<'self, A, B, T> {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn next_back(&mut self) -> Option<B> {
|
fn next_back(&mut self) -> Option<B> {
|
||||||
match self.iter.next_back() {
|
let next = self.iter.next_back();
|
||||||
Some(a) => Some((self.f)(a)),
|
self.do_map(next)
|
||||||
_ => None
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<'self, A, B, T: RandomAccessIterator<A>> RandomAccessIterator<B>
|
||||||
|
for Map<'self, A, B, T> {
|
||||||
|
#[inline]
|
||||||
|
fn indexable(&self) -> uint {
|
||||||
|
self.iter.indexable()
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn idx(&self, index: uint) -> Option<B> {
|
||||||
|
self.do_map(self.iter.idx(index))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1069,6 +1128,21 @@ impl<A, T: Iterator<A>> Iterator<(uint, A)> for Enumerate<T> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<A, T: RandomAccessIterator<A>> RandomAccessIterator<(uint, A)> for Enumerate<T> {
|
||||||
|
#[inline]
|
||||||
|
fn indexable(&self) -> uint {
|
||||||
|
self.iter.indexable()
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn idx(&self, index: uint) -> Option<(uint, A)> {
|
||||||
|
match self.iter.idx(index) {
|
||||||
|
Some(a) => Some((self.count + index, a)),
|
||||||
|
_ => None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// An iterator which rejects elements while `predicate` is true
|
/// An iterator which rejects elements while `predicate` is true
|
||||||
pub struct SkipWhile<'self, A, T> {
|
pub struct SkipWhile<'self, A, T> {
|
||||||
priv iter: T,
|
priv iter: T,
|
||||||
|
@ -1189,6 +1263,27 @@ impl<A, T: Iterator<A>> Iterator<A> for Skip<T> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<A, T: RandomAccessIterator<A>> RandomAccessIterator<A> for Skip<T> {
|
||||||
|
#[inline]
|
||||||
|
fn indexable(&self) -> uint {
|
||||||
|
let N = self.iter.indexable();
|
||||||
|
if N < self.n {
|
||||||
|
0
|
||||||
|
} else {
|
||||||
|
N - self.n
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn idx(&self, index: uint) -> Option<A> {
|
||||||
|
if index >= self.indexable() {
|
||||||
|
None
|
||||||
|
} else {
|
||||||
|
self.iter.idx(index + self.n)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// An iterator which only iterates over the first `n` iterations of `iter`.
|
/// An iterator which only iterates over the first `n` iterations of `iter`.
|
||||||
#[deriving(Clone)]
|
#[deriving(Clone)]
|
||||||
pub struct Take<T> {
|
pub struct Take<T> {
|
||||||
|
@ -1223,6 +1318,23 @@ impl<A, T: Iterator<A>> Iterator<A> for Take<T> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<A, T: RandomAccessIterator<A>> RandomAccessIterator<A> for Take<T> {
|
||||||
|
#[inline]
|
||||||
|
fn indexable(&self) -> uint {
|
||||||
|
cmp::min(self.iter.indexable(), self.n)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn idx(&self, index: uint) -> Option<A> {
|
||||||
|
if index >= self.n {
|
||||||
|
None
|
||||||
|
} else {
|
||||||
|
self.iter.idx(index)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/// An iterator to maintain state while iterating another iterator
|
/// An iterator to maintain state while iterating another iterator
|
||||||
pub struct Scan<'self, A, B, T, St> {
|
pub struct Scan<'self, A, B, T, St> {
|
||||||
priv iter: T,
|
priv iter: T,
|
||||||
|
@ -1251,7 +1363,8 @@ impl<'self, A, B, T: Iterator<A>, St> Iterator<B> for Scan<'self, A, B, T, St> {
|
||||||
pub struct FlatMap<'self, A, T, U> {
|
pub struct FlatMap<'self, A, T, U> {
|
||||||
priv iter: T,
|
priv iter: T,
|
||||||
priv f: &'self fn(A) -> U,
|
priv f: &'self fn(A) -> U,
|
||||||
priv subiter: Option<U>,
|
priv frontiter: Option<U>,
|
||||||
|
priv backiter: Option<U>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'self, A, T: Iterator<A>, B, U: Iterator<B>> Iterator<B> for
|
impl<'self, A, T: Iterator<A>, B, U: Iterator<B>> Iterator<B> for
|
||||||
|
@ -1259,14 +1372,45 @@ impl<'self, A, T: Iterator<A>, B, U: Iterator<B>> Iterator<B> for
|
||||||
#[inline]
|
#[inline]
|
||||||
fn next(&mut self) -> Option<B> {
|
fn next(&mut self) -> Option<B> {
|
||||||
loop {
|
loop {
|
||||||
for self.subiter.mut_iter().advance |inner| {
|
for self.frontiter.mut_iter().advance |inner| {
|
||||||
for inner.advance |x| {
|
for inner.advance |x| {
|
||||||
return Some(x)
|
return Some(x)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
match self.iter.next().map_consume(|x| (self.f)(x)) {
|
match self.iter.next().map_consume(|x| (self.f)(x)) {
|
||||||
None => return None,
|
None => return self.backiter.chain_mut_ref(|it| it.next()),
|
||||||
next => self.subiter = next,
|
next => self.frontiter = next,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn size_hint(&self) -> (uint, Option<uint>) {
|
||||||
|
let (flo, fhi) = self.frontiter.map_default((0, Some(0)), |it| it.size_hint());
|
||||||
|
let (blo, bhi) = self.backiter.map_default((0, Some(0)), |it| it.size_hint());
|
||||||
|
match (self.iter.size_hint(), fhi, bhi) {
|
||||||
|
((0, Some(0)), Some(a), Some(b)) => (flo + blo, Some(a + b)),
|
||||||
|
_ => (flo + blo, None)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'self,
|
||||||
|
A, T: DoubleEndedIterator<A>,
|
||||||
|
B, U: DoubleEndedIterator<B>> DoubleEndedIterator<B>
|
||||||
|
for FlatMap<'self, A, T, U> {
|
||||||
|
#[inline]
|
||||||
|
fn next_back(&mut self) -> Option<B> {
|
||||||
|
loop {
|
||||||
|
for self.backiter.mut_iter().advance |inner| {
|
||||||
|
match inner.next_back() {
|
||||||
|
None => (),
|
||||||
|
y => return y
|
||||||
|
}
|
||||||
|
}
|
||||||
|
match self.iter.next_back().map_consume(|x| (self.f)(x)) {
|
||||||
|
None => return self.frontiter.chain_mut_ref(|it| it.next_back()),
|
||||||
|
next => self.backiter = next,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1279,17 +1423,23 @@ pub struct Peek<'self, A, T> {
|
||||||
priv f: &'self fn(&A)
|
priv f: &'self fn(&A)
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'self, A, T: Iterator<A>> Iterator<A> for Peek<'self, A, T> {
|
impl<'self, A, T> Peek<'self, A, T> {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn next(&mut self) -> Option<A> {
|
fn do_peek(&self, elt: Option<A>) -> Option<A> {
|
||||||
let next = self.iter.next();
|
match elt {
|
||||||
|
|
||||||
match next {
|
|
||||||
Some(ref a) => (self.f)(a),
|
Some(ref a) => (self.f)(a),
|
||||||
None => ()
|
None => ()
|
||||||
}
|
}
|
||||||
|
|
||||||
next
|
elt
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'self, A, T: Iterator<A>> Iterator<A> for Peek<'self, A, T> {
|
||||||
|
#[inline]
|
||||||
|
fn next(&mut self) -> Option<A> {
|
||||||
|
let next = self.iter.next();
|
||||||
|
self.do_peek(next)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
|
@ -1302,13 +1452,19 @@ impl<'self, A, T: DoubleEndedIterator<A>> DoubleEndedIterator<A> for Peek<'self,
|
||||||
#[inline]
|
#[inline]
|
||||||
fn next_back(&mut self) -> Option<A> {
|
fn next_back(&mut self) -> Option<A> {
|
||||||
let next = self.iter.next_back();
|
let next = self.iter.next_back();
|
||||||
|
self.do_peek(next)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
match next {
|
impl<'self, A, T: RandomAccessIterator<A>> RandomAccessIterator<A> for Peek<'self, A, T> {
|
||||||
Some(ref a) => (self.f)(a),
|
#[inline]
|
||||||
None => ()
|
fn indexable(&self) -> uint {
|
||||||
}
|
self.iter.indexable()
|
||||||
|
}
|
||||||
|
|
||||||
next
|
#[inline]
|
||||||
|
fn idx(&self, index: uint) -> Option<A> {
|
||||||
|
self.do_peek(self.iter.idx(index))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1376,6 +1532,7 @@ mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
use prelude::*;
|
use prelude::*;
|
||||||
|
|
||||||
|
use cmp;
|
||||||
use uint;
|
use uint;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
@ -1768,6 +1925,43 @@ mod tests {
|
||||||
assert_eq!(it.next_back(), None)
|
assert_eq!(it.next_back(), None)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
fn check_randacc_iter<A: Eq, T: Clone + RandomAccessIterator<A>>(a: T, len: uint)
|
||||||
|
{
|
||||||
|
let mut b = a.clone();
|
||||||
|
assert_eq!(len, b.indexable());
|
||||||
|
let mut n = 0;
|
||||||
|
for a.enumerate().advance |(i, elt)| {
|
||||||
|
assert_eq!(Some(elt), b.idx(i));
|
||||||
|
n += 1;
|
||||||
|
}
|
||||||
|
assert_eq!(n, len);
|
||||||
|
assert_eq!(None, b.idx(n));
|
||||||
|
// call recursively to check after picking off an element
|
||||||
|
if len > 0 {
|
||||||
|
b.next();
|
||||||
|
check_randacc_iter(b, len-1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_double_ended_flat_map() {
|
||||||
|
let u = [0u,1];
|
||||||
|
let v = [5,6,7,8];
|
||||||
|
let mut it = u.iter().flat_map_(|x| v.slice(*x, v.len()).iter());
|
||||||
|
assert_eq!(it.next_back().unwrap(), &8);
|
||||||
|
assert_eq!(it.next().unwrap(), &5);
|
||||||
|
assert_eq!(it.next_back().unwrap(), &7);
|
||||||
|
assert_eq!(it.next_back().unwrap(), &6);
|
||||||
|
assert_eq!(it.next_back().unwrap(), &8);
|
||||||
|
assert_eq!(it.next().unwrap(), &6);
|
||||||
|
assert_eq!(it.next_back().unwrap(), &7);
|
||||||
|
assert_eq!(it.next_back(), None);
|
||||||
|
assert_eq!(it.next(), None);
|
||||||
|
assert_eq!(it.next_back(), None);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_random_access_chain() {
|
fn test_random_access_chain() {
|
||||||
let xs = [1, 2, 3, 4, 5];
|
let xs = [1, 2, 3, 4, 5];
|
||||||
|
@ -1785,5 +1979,71 @@ mod tests {
|
||||||
assert_eq!(it.idx(0).unwrap(), &3);
|
assert_eq!(it.idx(0).unwrap(), &3);
|
||||||
assert_eq!(it.idx(4).unwrap(), &9);
|
assert_eq!(it.idx(4).unwrap(), &9);
|
||||||
assert!(it.idx(6).is_none());
|
assert!(it.idx(6).is_none());
|
||||||
|
|
||||||
|
check_randacc_iter(it, xs.len() + ys.len() - 3);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_random_access_enumerate() {
|
||||||
|
let xs = [1, 2, 3, 4, 5];
|
||||||
|
check_randacc_iter(xs.iter().enumerate(), xs.len());
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_random_access_zip() {
|
||||||
|
let xs = [1, 2, 3, 4, 5];
|
||||||
|
let ys = [7, 9, 11];
|
||||||
|
check_randacc_iter(xs.iter().zip(ys.iter()), cmp::min(xs.len(), ys.len()));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_random_access_take() {
|
||||||
|
let xs = [1, 2, 3, 4, 5];
|
||||||
|
let empty: &[int] = [];
|
||||||
|
check_randacc_iter(xs.iter().take_(3), 3);
|
||||||
|
check_randacc_iter(xs.iter().take_(20), xs.len());
|
||||||
|
check_randacc_iter(xs.iter().take_(0), 0);
|
||||||
|
check_randacc_iter(empty.iter().take_(2), 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_random_access_skip() {
|
||||||
|
let xs = [1, 2, 3, 4, 5];
|
||||||
|
let empty: &[int] = [];
|
||||||
|
check_randacc_iter(xs.iter().skip(2), xs.len() - 2);
|
||||||
|
check_randacc_iter(empty.iter().skip(2), 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_random_access_peek() {
|
||||||
|
let xs = [1, 2, 3, 4, 5];
|
||||||
|
|
||||||
|
// test .transform and .peek_ that don't implement Clone
|
||||||
|
let it = xs.iter().peek_(|_| {});
|
||||||
|
assert_eq!(xs.len(), it.indexable());
|
||||||
|
for xs.iter().enumerate().advance |(i, elt)| {
|
||||||
|
assert_eq!(Some(elt), it.idx(i));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_random_access_transform() {
|
||||||
|
let xs = [1, 2, 3, 4, 5];
|
||||||
|
|
||||||
|
// test .transform and .peek_ that don't implement Clone
|
||||||
|
let it = xs.iter().transform(|x| *x);
|
||||||
|
assert_eq!(xs.len(), it.indexable());
|
||||||
|
for xs.iter().enumerate().advance |(i, elt)| {
|
||||||
|
assert_eq!(Some(*elt), it.idx(i));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_random_access_cycle() {
|
||||||
|
let xs = [1, 2, 3, 4, 5];
|
||||||
|
let empty: &[int] = [];
|
||||||
|
check_randacc_iter(xs.iter().cycle().take_(27), 27);
|
||||||
|
check_randacc_iter(empty.iter().cycle(), 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,7 +23,8 @@ use char::Char;
|
||||||
use clone::Clone;
|
use clone::Clone;
|
||||||
use container::{Container, Mutable};
|
use container::{Container, Mutable};
|
||||||
use iter::Times;
|
use iter::Times;
|
||||||
use iterator::{Iterator, FromIterator, IteratorUtil, Filter, AdditiveIterator, Map};
|
use iterator::{Iterator, FromIterator, Extendable, IteratorUtil};
|
||||||
|
use iterator::{Filter, AdditiveIterator, Map};
|
||||||
use libc;
|
use libc;
|
||||||
use num::Zero;
|
use num::Zero;
|
||||||
use option::{None, Option, Some};
|
use option::{None, Option, Some};
|
||||||
|
@ -2323,13 +2324,23 @@ impl<T: Iterator<char>> FromIterator<char, T> for ~str {
|
||||||
fn from_iterator(iterator: &mut T) -> ~str {
|
fn from_iterator(iterator: &mut T) -> ~str {
|
||||||
let (lower, _) = iterator.size_hint();
|
let (lower, _) = iterator.size_hint();
|
||||||
let mut buf = with_capacity(lower);
|
let mut buf = with_capacity(lower);
|
||||||
for iterator.advance |ch| {
|
buf.extend(iterator);
|
||||||
buf.push_char(ch)
|
|
||||||
}
|
|
||||||
buf
|
buf
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<T: Iterator<char>> Extendable<char, T> for ~str {
|
||||||
|
#[inline]
|
||||||
|
fn extend(&mut self, iterator: &mut T) {
|
||||||
|
let (lower, _) = iterator.size_hint();
|
||||||
|
let reserve = lower + self.len();
|
||||||
|
self.reserve_at_least(reserve);
|
||||||
|
for iterator.advance |ch| {
|
||||||
|
self.push_char(ch)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// This works because every lifetime is a sub-lifetime of 'static
|
// This works because every lifetime is a sub-lifetime of 'static
|
||||||
impl<'self> Zero for &'self str {
|
impl<'self> Zero for &'self str {
|
||||||
fn zero() -> &'self str { "" }
|
fn zero() -> &'self str { "" }
|
||||||
|
@ -2503,6 +2514,16 @@ mod tests {
|
||||||
assert_eq!(data, s.as_slice());
|
assert_eq!(data, s.as_slice());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_extend() {
|
||||||
|
let data = ~"ประเทศไทย中";
|
||||||
|
let mut cpy = data.clone();
|
||||||
|
let other = "abc";
|
||||||
|
let mut it = other.iter();
|
||||||
|
cpy.extend(&mut it);
|
||||||
|
assert_eq!(cpy, data + other);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_clear() {
|
fn test_clear() {
|
||||||
let mut empty = ~"";
|
let mut empty = ~"";
|
||||||
|
|
|
@ -11,7 +11,7 @@
|
||||||
//! An ordered map and set for integer keys implemented as a radix trie
|
//! An ordered map and set for integer keys implemented as a radix trie
|
||||||
|
|
||||||
use prelude::*;
|
use prelude::*;
|
||||||
use iterator::{IteratorUtil, FromIterator};
|
use iterator::{IteratorUtil, FromIterator, Extendable};
|
||||||
use uint;
|
use uint;
|
||||||
use util::{swap, replace};
|
use util::{swap, replace};
|
||||||
|
|
||||||
|
@ -155,17 +155,21 @@ impl<T> TrieMap<T> {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T, Iter: Iterator<(uint, T)>> FromIterator<(uint, T), Iter> for TrieMap<T> {
|
impl<T, Iter: Iterator<(uint, T)>> FromIterator<(uint, T), Iter> for TrieMap<T> {
|
||||||
pub fn from_iterator(iter: &mut Iter) -> TrieMap<T> {
|
fn from_iterator(iter: &mut Iter) -> TrieMap<T> {
|
||||||
let mut map = TrieMap::new();
|
let mut map = TrieMap::new();
|
||||||
|
map.extend(iter);
|
||||||
for iter.advance |(k, v)| {
|
|
||||||
map.insert(k, v);
|
|
||||||
}
|
|
||||||
|
|
||||||
map
|
map
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<T, Iter: Iterator<(uint, T)>> Extendable<(uint, T), Iter> for TrieMap<T> {
|
||||||
|
fn extend(&mut self, iter: &mut Iter) {
|
||||||
|
for iter.advance |(k, v)| {
|
||||||
|
self.insert(k, v);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[allow(missing_doc)]
|
#[allow(missing_doc)]
|
||||||
pub struct TrieSet {
|
pub struct TrieSet {
|
||||||
priv map: TrieMap<()>
|
priv map: TrieMap<()>
|
||||||
|
@ -222,17 +226,21 @@ impl TrieSet {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<Iter: Iterator<uint>> FromIterator<uint, Iter> for TrieSet {
|
impl<Iter: Iterator<uint>> FromIterator<uint, Iter> for TrieSet {
|
||||||
pub fn from_iterator(iter: &mut Iter) -> TrieSet {
|
fn from_iterator(iter: &mut Iter) -> TrieSet {
|
||||||
let mut set = TrieSet::new();
|
let mut set = TrieSet::new();
|
||||||
|
set.extend(iter);
|
||||||
for iter.advance |elem| {
|
|
||||||
set.insert(elem);
|
|
||||||
}
|
|
||||||
|
|
||||||
set
|
set
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<Iter: Iterator<uint>> Extendable<uint, Iter> for TrieSet {
|
||||||
|
fn extend(&mut self, iter: &mut Iter) {
|
||||||
|
for iter.advance |elem| {
|
||||||
|
self.insert(elem);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
struct TrieNode<T> {
|
struct TrieNode<T> {
|
||||||
count: uint,
|
count: uint,
|
||||||
children: [Child<T>, ..SIZE]
|
children: [Child<T>, ..SIZE]
|
||||||
|
|
|
@ -2106,7 +2106,8 @@ macro_rules! iterator {
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn size_hint(&self) -> (uint, Option<uint>) {
|
fn size_hint(&self) -> (uint, Option<uint>) {
|
||||||
let exact = self.indexable();
|
let diff = (self.end as uint) - (self.ptr as uint);
|
||||||
|
let exact = diff / sys::nonzero_size_of::<T>();
|
||||||
(exact, Some(exact))
|
(exact, Some(exact))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2134,23 +2135,19 @@ macro_rules! double_ended_iterator {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
macro_rules! random_access_iterator {
|
impl<'self, T> RandomAccessIterator<&'self T> for VecIterator<'self, T> {
|
||||||
(impl $name:ident -> $elem:ty) => {
|
#[inline]
|
||||||
impl<'self, T> RandomAccessIterator<$elem> for $name<'self, T> {
|
fn indexable(&self) -> uint {
|
||||||
#[inline]
|
let (exact, _) = self.size_hint();
|
||||||
fn indexable(&self) -> uint {
|
exact
|
||||||
let diff = (self.end as uint) - (self.ptr as uint);
|
}
|
||||||
diff / sys::nonzero_size_of::<T>()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn idx(&self, index: uint) -> Option<$elem> {
|
fn idx(&self, index: uint) -> Option<&'self T> {
|
||||||
unsafe {
|
unsafe {
|
||||||
if index < self.indexable() {
|
if index < self.indexable() {
|
||||||
cast::transmute(self.ptr.offset(index))
|
cast::transmute(self.ptr.offset(index))
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2165,7 +2162,6 @@ pub struct VecIterator<'self, T> {
|
||||||
}
|
}
|
||||||
iterator!{impl VecIterator -> &'self T}
|
iterator!{impl VecIterator -> &'self T}
|
||||||
double_ended_iterator!{impl VecIterator -> &'self T}
|
double_ended_iterator!{impl VecIterator -> &'self T}
|
||||||
random_access_iterator!{impl VecIterator -> &'self T}
|
|
||||||
pub type RevIterator<'self, T> = Invert<VecIterator<'self, T>>;
|
pub type RevIterator<'self, T> = Invert<VecIterator<'self, T>>;
|
||||||
|
|
||||||
impl<'self, T> Clone for VecIterator<'self, T> {
|
impl<'self, T> Clone for VecIterator<'self, T> {
|
||||||
|
@ -2181,7 +2177,6 @@ pub struct VecMutIterator<'self, T> {
|
||||||
}
|
}
|
||||||
iterator!{impl VecMutIterator -> &'self mut T}
|
iterator!{impl VecMutIterator -> &'self mut T}
|
||||||
double_ended_iterator!{impl VecMutIterator -> &'self mut T}
|
double_ended_iterator!{impl VecMutIterator -> &'self mut T}
|
||||||
random_access_iterator!{impl VecMutIterator -> &'self mut T}
|
|
||||||
pub type MutRevIterator<'self, T> = Invert<VecMutIterator<'self, T>>;
|
pub type MutRevIterator<'self, T> = Invert<VecMutIterator<'self, T>>;
|
||||||
|
|
||||||
/// An iterator that moves out of a vector.
|
/// An iterator that moves out of a vector.
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue