Special case .fold() for VecDeque's iterators
This commit is contained in:
parent
0c429872a3
commit
15a95866b4
|
@ -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) {
|
||||
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")]
|
||||
|
|
Loading…
Reference in New Issue