auto merge of #7707 : thestinger/rust/double, r=cmr

00da76d r=cmr
6e75f2d r=cmr

This implements the trait for vector iterators, replacing the reverse
iterator types. The methods will stay, for implementing the future
reverse Iterable traits and convenience.

This can also be trivially implemented for circular buffers and other
variants of arrays like strings.

The `DoubleEndedIterator` trait will allow for implementing algorithms
like in-place reverse on generic mutable iterators.

The naming (`Range` vs. `Iterator`, `Bidirectional` vs. `DoubleEnded`)
can be bikeshedded in the future.
This commit is contained in:
bors
2013-07-11 13:28:38 -07:00
5 changed files with 119 additions and 63 deletions

View File

@@ -18,7 +18,7 @@ use container::{Container, Mutable};
use cmp;
use cmp::{Eq, TotalEq, TotalOrd, Ordering, Less, Equal, Greater};
use clone::Clone;
use iterator::{FromIterator, Iterator, IteratorUtil};
use iterator::*;
use kinds::Copy;
use libc::c_void;
use num::Zero;
@@ -762,12 +762,7 @@ impl<'self,T> ImmutableVector<'self, T> for &'self [T] {
}
#[inline]
fn rev_iter(self) -> VecRevIterator<'self, T> {
unsafe {
let p = vec::raw::to_ptr(self);
VecRevIterator{ptr: p.offset(self.len() - 1),
end: p.offset(-1),
lifetime: cast::transmute(p)}
}
self.iter().invert()
}
/// Returns an iterator over the subslices of the vector which are
@@ -1143,7 +1138,6 @@ impl<T> OwnedVector<T> for ~[T] {
*
* * n - The number of elements to reserve space for
*/
#[inline]
#[cfg(stage0)]
fn reserve(&mut self, n: uint) {
// Only make the (slow) call into the runtime if we have to
@@ -1177,7 +1171,6 @@ impl<T> OwnedVector<T> for ~[T] {
*
* * n - The number of elements to reserve space for
*/
#[inline]
#[cfg(not(stage0))]
fn reserve(&mut self, n: uint) {
// Only make the (slow) call into the runtime if we have to
@@ -1235,21 +1228,12 @@ impl<T> OwnedVector<T> for ~[T] {
let repr: **raw::VecRepr = transmute(&mut *self);
let fill = (**repr).unboxed.fill;
if (**repr).unboxed.alloc <= fill {
// need more space
reserve_no_inline(self);
let new_len = self.len() + 1;
self.reserve_at_least(new_len);
}
self.push_fast(t);
}
// this peculiar function is because reserve_at_least is very
// large (because of reserve), and will be inlined, which
// makes push too large.
#[inline(never)]
fn reserve_no_inline<T>(v: &mut ~[T]) {
let new_len = v.len() + 1;
v.reserve_at_least(new_len);
}
}
// This doesn't bother to make sure we have space.
@@ -1737,13 +1721,9 @@ impl<'self,T> MutableVector<'self, T> for &'self mut [T] {
}
}
#[inline]
fn mut_rev_iter(self) -> VecMutRevIterator<'self, T> {
unsafe {
let p = vec::raw::to_mut_ptr(self);
VecMutRevIterator{ptr: p.offset(self.len() - 1),
end: p.offset(-1),
lifetime: cast::transmute(p)}
}
self.mut_iter().invert()
}
/**
@@ -2103,17 +2083,17 @@ macro_rules! iterator {
priv lifetime: $elem // FIXME: #5922
}
};*/
(impl $name:ident -> $elem:ty, $step:expr) => {
// could be implemented with &[T] with .slice(), but this avoids bounds checks
(impl $name:ident -> $elem:ty) => {
impl<'self, T> Iterator<$elem> for $name<'self, T> {
#[inline]
fn next(&mut self) -> Option<$elem> {
// could be implemented with slices, but this avoids bounds checks
unsafe {
if self.ptr == self.end {
None
} else {
let old = self.ptr;
self.ptr = self.ptr.offset($step);
self.ptr = self.ptr.offset(1);
Some(cast::transmute(old))
}
}
@@ -2121,11 +2101,7 @@ macro_rules! iterator {
#[inline]
fn size_hint(&self) -> (uint, Option<uint>) {
let diff = if $step > 0 {
(self.end as uint) - (self.ptr as uint)
} else {
(self.ptr as uint) - (self.end as uint)
};
let diff = (self.end as uint) - (self.ptr as uint);
let exact = diff / size_of::<$elem>();
(exact, Some(exact))
}
@@ -2133,6 +2109,25 @@ macro_rules! iterator {
}
}
macro_rules! double_ended_iterator {
(impl $name:ident -> $elem:ty) => {
impl<'self, T> DoubleEndedIterator<$elem> for $name<'self, T> {
#[inline]
fn next_back(&mut self) -> Option<$elem> {
// could be implemented with slices, but this avoids bounds checks
unsafe {
if self.end == self.ptr {
None
} else {
self.end = self.end.offset(-1);
Some(cast::transmute(self.end))
}
}
}
}
}
}
//iterator!{struct VecIterator -> *T, &'self T}
/// An iterator for iterating over a vector.
pub struct VecIterator<'self, T> {
@@ -2140,16 +2135,9 @@ pub struct VecIterator<'self, T> {
priv end: *T,
priv lifetime: &'self T // FIXME: #5922
}
iterator!{impl VecIterator -> &'self T, 1}
//iterator!{struct VecRevIterator -> *T, &'self T}
/// An iterator for iterating over a vector in reverse.
pub struct VecRevIterator<'self, T> {
priv ptr: *T,
priv end: *T,
priv lifetime: &'self T // FIXME: #5922
}
iterator!{impl VecRevIterator -> &'self T, -1}
iterator!{impl VecIterator -> &'self T}
double_ended_iterator!{impl VecIterator -> &'self T}
pub type VecRevIterator<'self, T> = InvertIterator<&'self T, VecIterator<'self, T>>;
//iterator!{struct VecMutIterator -> *mut T, &'self mut T}
/// An iterator for mutating the elements of a vector.
@@ -2158,16 +2146,9 @@ pub struct VecMutIterator<'self, T> {
priv end: *mut T,
priv lifetime: &'self mut T // FIXME: #5922
}
iterator!{impl VecMutIterator -> &'self mut T, 1}
//iterator!{struct VecMutRevIterator -> *mut T, &'self mut T}
/// An iterator for mutating the elements of a vector in reverse.
pub struct VecMutRevIterator<'self, T> {
priv ptr: *mut T,
priv end: *mut T,
priv lifetime: &'self mut T // FIXME: #5922
}
iterator!{impl VecMutRevIterator -> &'self mut T, -1}
iterator!{impl VecMutIterator -> &'self mut T}
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.
pub struct VecConsumeIterator<T> {