From efd619467df28b48b97250b2857b18a032b5dab6 Mon Sep 17 00:00:00 2001 From: Palmer Cox Date: Wed, 11 Dec 2013 20:40:27 -0500 Subject: [PATCH 1/3] Remove remainder field from MutChunkIter This field is no longer necessary now that #9629 is fixed since we can just access the length of the remaining slice directly. --- src/libstd/vec.rs | 23 ++++++++++------------- 1 file changed, 10 insertions(+), 13 deletions(-) diff --git a/src/libstd/vec.rs b/src/libstd/vec.rs index 6eef640d91233..17e961723cfdc 100644 --- a/src/libstd/vec.rs +++ b/src/libstd/vec.rs @@ -2127,8 +2127,7 @@ impl<'a,T> MutableVector<'a, T> for &'a mut [T] { #[inline] fn mut_chunks(self, chunk_size: uint) -> MutChunkIter<'a, T> { assert!(chunk_size > 0); - let len = self.len(); - MutChunkIter { v: self, chunk_size: chunk_size, remaining: len } + MutChunkIter { v: self, chunk_size: chunk_size } } fn mut_shift_ref(&mut self) -> &'a mut T { @@ -2568,31 +2567,29 @@ impl<'a, T> DoubleEndedIterator<&'a mut [T]> for MutSplitIterator<'a, T> { /// the remainder. pub struct MutChunkIter<'a, T> { priv v: &'a mut [T], - priv chunk_size: uint, - priv remaining: uint + priv chunk_size: uint } impl<'a, T> Iterator<&'a mut [T]> for MutChunkIter<'a, T> { #[inline] fn next(&mut self) -> Option<&'a mut [T]> { - if self.remaining == 0 { + if self.v.len() == 0 { None } else { - let sz = cmp::min(self.remaining, self.chunk_size); + let sz = cmp::min(self.v.len(), self.chunk_size); let tmp = util::replace(&mut self.v, &mut []); let (head, tail) = tmp.mut_split_at(sz); self.v = tail; - self.remaining -= sz; Some(head) } } #[inline] fn size_hint(&self) -> (uint, Option) { - if self.remaining == 0 { + if self.v.len() == 0 { (0, Some(0)) } else { - let (n, rem) = self.remaining.div_rem(&self.chunk_size); + let (n, rem) = self.v.len().div_rem(&self.chunk_size); let n = if rem > 0 { n + 1 } else { n }; (n, Some(n)) } @@ -2602,15 +2599,15 @@ impl<'a, T> Iterator<&'a mut [T]> for MutChunkIter<'a, T> { impl<'a, T> DoubleEndedIterator<&'a mut [T]> for MutChunkIter<'a, T> { #[inline] fn next_back(&mut self) -> Option<&'a mut [T]> { - if self.remaining == 0 { + if self.v.len() == 0 { None } else { - let remainder = self.remaining % self.chunk_size; + let remainder = self.v.len() % self.chunk_size; let sz = if remainder != 0 { remainder } else { self.chunk_size }; let tmp = util::replace(&mut self.v, &mut []); - let (head, tail) = tmp.mut_split_at(self.remaining - sz); + let tmp_len = tmp.len(); + let (head, tail) = tmp.mut_split_at(tmp_len - sz); self.v = head; - self.remaining -= sz; Some(tail) } } From 2c539d4eecec3c63f878a3798e0ea4df79b46f19 Mon Sep 17 00:00:00 2001 From: Palmer Cox Date: Wed, 11 Dec 2013 20:51:22 -0500 Subject: [PATCH 2/3] Update next() and size_hint() for MutSpliterIterator Update the next() method to just return self.v in the case that we've reached the last element that the iterator will yield. This produces equivalent behavior as before, but without the cost of updating the field. Update the size_hint() method to return a better hint now that #9629 is fixed. --- src/libstd/vec.rs | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) diff --git a/src/libstd/vec.rs b/src/libstd/vec.rs index 17e961723cfdc..b03cef0935043 100644 --- a/src/libstd/vec.rs +++ b/src/libstd/vec.rs @@ -2528,13 +2528,13 @@ impl<'a, T> Iterator<&'a mut [T]> for MutSplitIterator<'a, T> { #[inline] fn size_hint(&self) -> (uint, Option) { - if self.finished { return (0, Some(0)) } - - // if the predicate doesn't match anything, we yield one slice - // if it matches every element, we yield len+1 empty slices. - // FIXME #9629 - //(1, Some(self.v.len() + 1)) - (1, None) + if self.finished { + (0, Some(0)) + } else { + // if the predicate doesn't match anything, we yield one slice + // if it matches every element, we yield len+1 empty slices. + (1, Some(self.v.len() + 1)) + } } } @@ -2547,10 +2547,7 @@ impl<'a, T> DoubleEndedIterator<&'a mut [T]> for MutSplitIterator<'a, T> { None => { self.finished = true; let tmp = util::replace(&mut self.v, &mut []); - let len = tmp.len(); - let (head, tail) = tmp.mut_split_at(len); - self.v = tail; - Some(head) + Some(tmp) } Some(idx) => { let tmp = util::replace(&mut self.v, &mut []); From 765bc9064f9b38ae227a2c61a8ed34f67f0afd0f Mon Sep 17 00:00:00 2001 From: Palmer Cox Date: Wed, 11 Dec 2013 21:37:45 -0500 Subject: [PATCH 3/3] Implement size_hint() for ByRef iterator --- src/libstd/iter.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/libstd/iter.rs b/src/libstd/iter.rs index 5fbb09eadcb09..f16e9b5392977 100644 --- a/src/libstd/iter.rs +++ b/src/libstd/iter.rs @@ -795,7 +795,8 @@ pub struct ByRef<'a, T> { impl<'a, A, T: Iterator> Iterator for ByRef<'a, T> { #[inline] fn next(&mut self) -> Option { self.iter.next() } - // FIXME: #9629 we cannot implement &self methods like size_hint on ByRef + #[inline] + fn size_hint(&self) -> (uint, Option) { self.iter.size_hint() } } impl<'a, A, T: DoubleEndedIterator> DoubleEndedIterator for ByRef<'a, T> {