Skip to content

Commit 899217c

Browse files
committed
auto merge of #10757 : TeXitoi/rust/mut-split-iter, r=alexcrichton
I've renamed `MutableVector::mut_split(at)` to `MutableVector::mut_split_at(at)` to be coherent with ImmutableVector. As specified in the commit log, The `size_hint` method is not optimal because of #9629.
2 parents e2d192c + 44fc3c6 commit 899217c

File tree

3 files changed

+121
-15
lines changed

3 files changed

+121
-15
lines changed

src/libextra/ringbuf.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -207,14 +207,14 @@ impl<T> RingBuf<T> {
207207
// start_index to self.elts.len()
208208
// and then
209209
// 0 to end_index
210-
let (temp, remaining1) = self.elts.mut_split(start_index);
211-
let (remaining2, _) = temp.mut_split(end_index);
210+
let (temp, remaining1) = self.elts.mut_split_at(start_index);
211+
let (remaining2, _) = temp.mut_split_at(end_index);
212212
RingBufMutIterator { remaining1: remaining1,
213213
remaining2: remaining2,
214214
nelts: self.nelts }
215215
} else {
216216
// Items to iterate goes from start_index to end_index:
217-
let (empty, elts) = self.elts.mut_split(0);
217+
let (empty, elts) = self.elts.mut_split_at(0);
218218
let remaining1 = elts.mut_slice(start_index, end_index);
219219
RingBufMutIterator { remaining1: remaining1,
220220
remaining2: empty,

src/librustc/middle/borrowck/doc.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -666,8 +666,8 @@ The current rules could use some correction:
666666
function will fail to compile:
667667
668668
fn mut_shift_ref<'a,T>(x: &mut &'a mut [T]) -> &'a mut T {
669-
// `mut_split` will restrict mutation against *x:
670-
let (head, tail) = (*x).mut_split(1);
669+
// `mut_split_at` will restrict mutation against *x:
670+
let (head, tail) = (*x).mut_split_at(1);
671671
672672
// Hence mutating `*x` yields an error here:
673673
*x = tail;

src/libstd/vec.rs

Lines changed: 116 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -858,20 +858,24 @@ pub trait ImmutableVector<'self, T> {
858858
/// Returns a reversed iterator over a vector
859859
fn rev_iter(self) -> RevIterator<'self, T>;
860860
/// Returns an iterator over the subslices of the vector which are
861-
/// separated by elements that match `pred`.
861+
/// separated by elements that match `pred`. The matched element
862+
/// is not contained in the subslices.
862863
fn split(self, pred: 'self |&T| -> bool) -> SplitIterator<'self, T>;
863864
/// Returns an iterator over the subslices of the vector which are
864865
/// separated by elements that match `pred`, limited to splitting
865-
/// at most `n` times.
866+
/// at most `n` times. The matched element is not contained in
867+
/// the subslices.
866868
fn splitn(self, n: uint, pred: 'self |&T| -> bool) -> SplitIterator<'self, T>;
867869
/// Returns an iterator over the subslices of the vector which are
868870
/// separated by elements that match `pred`. This starts at the
869-
/// end of the vector and works backwards.
871+
/// end of the vector and works backwards. The matched element is
872+
/// not contained in the subslices.
870873
fn rsplit(self, pred: 'self |&T| -> bool) -> RSplitIterator<'self, T>;
871874
/// Returns an iterator over the subslices of the vector which are
872875
/// separated by elements that match `pred` limited to splitting
873876
/// at most `n` times. This starts at the end of the vector and
874-
/// works backwards.
877+
/// works backwards. The matched element is not contained in the
878+
/// subslices.
875879
fn rsplitn(self, n: uint, pred: 'self |&T| -> bool) -> RSplitIterator<'self, T>;
876880

877881
/**
@@ -1933,6 +1937,11 @@ pub trait MutableVector<'self, T> {
19331937
/// Returns a reversed iterator that allows modifying each value
19341938
fn mut_rev_iter(self) -> MutRevIterator<'self, T>;
19351939

1940+
/// Returns an iterator over the mutable subslices of the vector
1941+
/// which are separated by elements that match `pred`. The
1942+
/// matched element is not contained in the subslices.
1943+
fn mut_split(self, pred: 'self |&T| -> bool) -> MutSplitIterator<'self, T>;
1944+
19361945
/**
19371946
* Returns an iterator over `size` elements of the vector at a time.
19381947
* The chunks are mutable and do not overlap. If `size` does not divide the
@@ -1995,7 +2004,7 @@ pub trait MutableVector<'self, T> {
19952004
* itself) and the second will contain all indices from
19962005
* `mid..len` (excluding the index `len` itself).
19972006
*/
1998-
fn mut_split(self, mid: uint) -> (&'self mut [T],
2007+
fn mut_split_at(self, mid: uint) -> (&'self mut [T],
19992008
&'self mut [T]);
20002009

20012010
/// Reverse the order of elements in a vector, in place
@@ -2052,7 +2061,7 @@ impl<'self,T> MutableVector<'self, T> for &'self mut [T] {
20522061
}
20532062

20542063
#[inline]
2055-
fn mut_split(self, mid: uint) -> (&'self mut [T], &'self mut [T]) {
2064+
fn mut_split_at(self, mid: uint) -> (&'self mut [T], &'self mut [T]) {
20562065
unsafe {
20572066
let len = self.len();
20582067
let self2: &'self mut [T] = cast::transmute_copy(&self);
@@ -2081,6 +2090,11 @@ impl<'self,T> MutableVector<'self, T> for &'self mut [T] {
20812090
self.mut_iter().invert()
20822091
}
20832092

2093+
#[inline]
2094+
fn mut_split(self, pred: 'self |&T| -> bool) -> MutSplitIterator<'self, T> {
2095+
MutSplitIterator { v: self, pred: pred, finished: false }
2096+
}
2097+
20842098
#[inline]
20852099
fn mut_chunks(self, chunk_size: uint) -> MutChunkIter<'self, T> {
20862100
assert!(chunk_size > 0);
@@ -2575,6 +2589,73 @@ impl<'self, T> Clone for VecIterator<'self, T> {
25752589
iterator!{struct VecMutIterator -> *mut T, &'self mut T}
25762590
pub type MutRevIterator<'self, T> = Invert<VecMutIterator<'self, T>>;
25772591

2592+
/// An iterator over the subslices of the vector which are separated
2593+
/// by elements that match `pred`.
2594+
pub struct MutSplitIterator<'self, T> {
2595+
priv v: &'self mut [T],
2596+
priv pred: 'self |t: &T| -> bool,
2597+
priv finished: bool
2598+
}
2599+
2600+
impl<'self, T> Iterator<&'self mut [T]> for MutSplitIterator<'self, T> {
2601+
#[inline]
2602+
fn next(&mut self) -> Option<&'self mut [T]> {
2603+
if self.finished { return None; }
2604+
2605+
match self.v.iter().position(|x| (self.pred)(x)) {
2606+
None => {
2607+
self.finished = true;
2608+
let tmp = util::replace(&mut self.v, &mut []);
2609+
let len = tmp.len();
2610+
let (head, tail) = tmp.mut_split_at(len);
2611+
self.v = tail;
2612+
Some(head)
2613+
}
2614+
Some(idx) => {
2615+
let tmp = util::replace(&mut self.v, &mut []);
2616+
let (head, tail) = tmp.mut_split_at(idx);
2617+
self.v = tail.mut_slice_from(1);
2618+
Some(head)
2619+
}
2620+
}
2621+
}
2622+
2623+
#[inline]
2624+
fn size_hint(&self) -> (uint, Option<uint>) {
2625+
if self.finished { return (0, Some(0)) }
2626+
2627+
// if the predicate doesn't match anything, we yield one slice
2628+
// if it matches every element, we yield len+1 empty slices.
2629+
// FIXME #9629
2630+
//(1, Some(self.v.len() + 1))
2631+
(1, None)
2632+
}
2633+
}
2634+
2635+
impl<'self, T> DoubleEndedIterator<&'self mut [T]> for MutSplitIterator<'self, T> {
2636+
#[inline]
2637+
fn next_back(&mut self) -> Option<&'self mut [T]> {
2638+
if self.finished { return None; }
2639+
2640+
match self.v.iter().rposition(|x| (self.pred)(x)) {
2641+
None => {
2642+
self.finished = true;
2643+
let tmp = util::replace(&mut self.v, &mut []);
2644+
let len = tmp.len();
2645+
let (head, tail) = tmp.mut_split_at(len);
2646+
self.v = tail;
2647+
Some(head)
2648+
}
2649+
Some(idx) => {
2650+
let tmp = util::replace(&mut self.v, &mut []);
2651+
let (head, tail) = tmp.mut_split_at(idx);
2652+
self.v = head;
2653+
Some(tail.mut_slice_from(1))
2654+
}
2655+
}
2656+
}
2657+
}
2658+
25782659
/// An iterator over a vector in (non-overlapping) mutable chunks (`size` elements at a time). When
25792660
/// the vector len is not evenly divided by the chunk size, the last slice of the iteration will be
25802661
/// the remainder.
@@ -2592,7 +2673,7 @@ impl<'self, T> Iterator<&'self mut [T]> for MutChunkIter<'self, T> {
25922673
} else {
25932674
let sz = cmp::min(self.remaining, self.chunk_size);
25942675
let tmp = util::replace(&mut self.v, &mut []);
2595-
let (head, tail) = tmp.mut_split(sz);
2676+
let (head, tail) = tmp.mut_split_at(sz);
25962677
self.v = tail;
25972678
self.remaining -= sz;
25982679
Some(head)
@@ -2620,7 +2701,7 @@ impl<'self, T> DoubleEndedIterator<&'self mut [T]> for MutChunkIter<'self, T> {
26202701
let remainder = self.remaining % self.chunk_size;
26212702
let sz = if remainder != 0 { remainder } else { self.chunk_size };
26222703
let tmp = util::replace(&mut self.v, &mut []);
2623-
let (head, tail) = tmp.mut_split(self.remaining - sz);
2704+
let (head, tail) = tmp.mut_split_at(self.remaining - sz);
26242705
self.v = head;
26252706
self.remaining -= sz;
26262707
Some(tail)
@@ -3898,10 +3979,10 @@ mod tests {
38983979
}
38993980

39003981
#[test]
3901-
fn test_mut_split() {
3982+
fn test_mut_split_at() {
39023983
let mut values = [1u8,2,3,4,5];
39033984
{
3904-
let (left, right) = values.mut_split(2);
3985+
let (left, right) = values.mut_split_at(2);
39053986
assert_eq!(left.slice(0, left.len()), [1, 2]);
39063987
for p in left.mut_iter() {
39073988
*p += 1;
@@ -4038,6 +4119,31 @@ mod tests {
40384119
x.pop_ref();
40394120
}
40404121

4122+
#[test]
4123+
fn test_mut_splitator() {
4124+
let mut xs = [0,1,0,2,3,0,0,4,5,0];
4125+
assert_eq!(xs.mut_split(|x| *x == 0).len(), 6);
4126+
for slice in xs.mut_split(|x| *x == 0) {
4127+
slice.reverse();
4128+
}
4129+
assert_eq!(xs, [0,1,0,3,2,0,0,5,4,0]);
4130+
4131+
let mut xs = [0,1,0,2,3,0,0,4,5,0,6,7];
4132+
for slice in xs.mut_split(|x| *x == 0).take(5) {
4133+
slice.reverse();
4134+
}
4135+
assert_eq!(xs, [0,1,0,3,2,0,0,5,4,0,6,7]);
4136+
}
4137+
4138+
#[test]
4139+
fn test_mut_splitator_invert() {
4140+
let mut xs = [1,2,0,3,4,0,0,5,6,0];
4141+
for slice in xs.mut_split(|x| *x == 0).invert().take(4) {
4142+
slice.reverse();
4143+
}
4144+
assert_eq!(xs, [1,2,0,4,3,0,0,6,5,0]);
4145+
}
4146+
40414147
#[test]
40424148
fn test_mut_chunks() {
40434149
let mut v = [0u8, 1, 2, 3, 4, 5, 6];

0 commit comments

Comments
 (0)