-
Notifications
You must be signed in to change notification settings - Fork 13.5k
Implement Iterator::fold for .chain(), .cloned(), .map() and the VecDeque iterators. #37315
New issue
Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? # to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -743,16 +743,8 @@ impl<T> VecDeque<T> { | |
#[stable(feature = "deque_extras_15", since = "1.5.0")] | ||
pub fn as_slices(&self) -> (&[T], &[T]) { | ||
unsafe { | ||
let contiguous = self.is_contiguous(); | ||
let buf = self.buffer_as_slice(); | ||
if contiguous { | ||
let (empty, buf) = buf.split_at(0); | ||
(&buf[self.tail..self.head], empty) | ||
} else { | ||
let (mid, right) = buf.split_at(self.tail); | ||
let (left, _) = mid.split_at(self.head); | ||
(right, left) | ||
} | ||
RingSlices::ring_slices(buf, self.head, self.tail) | ||
} | ||
} | ||
|
||
|
@@ -780,20 +772,10 @@ impl<T> VecDeque<T> { | |
#[stable(feature = "deque_extras_15", since = "1.5.0")] | ||
pub fn as_mut_slices(&mut self) -> (&mut [T], &mut [T]) { | ||
unsafe { | ||
let contiguous = self.is_contiguous(); | ||
let head = self.head; | ||
let tail = self.tail; | ||
let buf = self.buffer_as_mut_slice(); | ||
|
||
if contiguous { | ||
let (empty, buf) = buf.split_at_mut(0); | ||
(&mut buf[tail..head], empty) | ||
} else { | ||
let (mid, right) = buf.split_at_mut(tail); | ||
let (left, _) = mid.split_at_mut(head); | ||
|
||
(right, left) | ||
} | ||
RingSlices::ring_slices(buf, head, tail) | ||
} | ||
} | ||
|
||
|
@@ -1829,6 +1811,42 @@ fn wrap_index(index: usize, size: usize) -> usize { | |
index & (size - 1) | ||
} | ||
|
||
/// Returns the two slices that cover the VecDeque's valid range | ||
trait RingSlices : Sized { | ||
fn slice(self, from: usize, to: usize) -> Self; | ||
fn split_at(self, i: usize) -> (Self, Self); | ||
|
||
fn ring_slices(buf: Self, head: usize, tail: usize) -> (Self, Self) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Maybe some There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Since it is generic it should not matter I think. It is sort of a higher level operation anyway. |
||
let contiguous = tail <= head; | ||
if contiguous { | ||
let (empty, buf) = buf.split_at(0); | ||
(buf.slice(tail, head), empty) | ||
} else { | ||
let (mid, right) = buf.split_at(tail); | ||
let (left, _) = mid.split_at(head); | ||
(right, left) | ||
} | ||
} | ||
} | ||
|
||
impl<'a, T> RingSlices for &'a [T] { | ||
fn slice(self, from: usize, to: usize) -> Self { | ||
&self[from..to] | ||
} | ||
fn split_at(self, i: usize) -> (Self, Self) { | ||
(*self).split_at(i) | ||
} | ||
} | ||
|
||
impl<'a, T> RingSlices for &'a mut [T] { | ||
fn slice(self, from: usize, to: usize) -> Self { | ||
&mut self[from..to] | ||
} | ||
fn split_at(self, i: usize) -> (Self, Self) { | ||
(*self).split_at_mut(i) | ||
} | ||
} | ||
|
||
/// Calculate the number of elements left to be read in the buffer | ||
#[inline] | ||
fn count(tail: usize, head: usize, size: usize) -> usize { | ||
|
@@ -1875,6 +1893,14 @@ impl<'a, T> Iterator for Iter<'a, T> { | |
let len = count(self.tail, self.head, self.ring.len()); | ||
(len, Some(len)) | ||
} | ||
|
||
fn fold<Acc, F>(self, mut accum: Acc, mut f: F) -> Acc | ||
where F: FnMut(Acc, Self::Item) -> Acc, | ||
{ | ||
let (front, back) = RingSlices::ring_slices(self.ring, self.head, self.tail); | ||
accum = front.iter().fold(accum, &mut f); | ||
back.iter().fold(accum, &mut f) | ||
} | ||
} | ||
|
||
#[stable(feature = "rust1", since = "1.0.0")] | ||
|
@@ -1927,6 +1953,14 @@ impl<'a, T> Iterator for IterMut<'a, T> { | |
let len = count(self.tail, self.head, self.ring.len()); | ||
(len, Some(len)) | ||
} | ||
|
||
fn fold<Acc, F>(self, mut accum: Acc, mut f: F) -> Acc | ||
where F: FnMut(Acc, Self::Item) -> Acc, | ||
{ | ||
let (front, back) = RingSlices::ring_slices(self.ring, self.head, self.tail); | ||
accum = front.iter_mut().fold(accum, &mut f); | ||
back.iter_mut().fold(accum, &mut f) | ||
} | ||
} | ||
|
||
#[stable(feature = "rust1", since = "1.0.0")] | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could this be replaced with a bound on Index?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No, we're using either Index or IndexMut