-
Notifications
You must be signed in to change notification settings - Fork 13.3k
Implement Iterator::fold for .chain(), .cloned(), .map() and the VecDeque iterators. #37315
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in 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