Skip to content

Commit 15a9586

Browse files
committed
Special case .fold() for VecDeque's iterators
1 parent 0c42987 commit 15a9586

File tree

1 file changed

+54
-20
lines changed

1 file changed

+54
-20
lines changed

src/libcollections/vec_deque.rs

Lines changed: 54 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -743,16 +743,8 @@ impl<T> VecDeque<T> {
743743
#[stable(feature = "deque_extras_15", since = "1.5.0")]
744744
pub fn as_slices(&self) -> (&[T], &[T]) {
745745
unsafe {
746-
let contiguous = self.is_contiguous();
747746
let buf = self.buffer_as_slice();
748-
if contiguous {
749-
let (empty, buf) = buf.split_at(0);
750-
(&buf[self.tail..self.head], empty)
751-
} else {
752-
let (mid, right) = buf.split_at(self.tail);
753-
let (left, _) = mid.split_at(self.head);
754-
(right, left)
755-
}
747+
RingSlices::ring_slices(buf, self.head, self.tail)
756748
}
757749
}
758750

@@ -780,20 +772,10 @@ impl<T> VecDeque<T> {
780772
#[stable(feature = "deque_extras_15", since = "1.5.0")]
781773
pub fn as_mut_slices(&mut self) -> (&mut [T], &mut [T]) {
782774
unsafe {
783-
let contiguous = self.is_contiguous();
784775
let head = self.head;
785776
let tail = self.tail;
786777
let buf = self.buffer_as_mut_slice();
787-
788-
if contiguous {
789-
let (empty, buf) = buf.split_at_mut(0);
790-
(&mut buf[tail..head], empty)
791-
} else {
792-
let (mid, right) = buf.split_at_mut(tail);
793-
let (left, _) = mid.split_at_mut(head);
794-
795-
(right, left)
796-
}
778+
RingSlices::ring_slices(buf, head, tail)
797779
}
798780
}
799781

@@ -1829,6 +1811,42 @@ fn wrap_index(index: usize, size: usize) -> usize {
18291811
index & (size - 1)
18301812
}
18311813

1814+
/// Returns the two slices that cover the VecDeque's valid range
1815+
trait RingSlices : Sized {
1816+
fn slice(self, from: usize, to: usize) -> Self;
1817+
fn split_at(self, i: usize) -> (Self, Self);
1818+
1819+
fn ring_slices(buf: Self, head: usize, tail: usize) -> (Self, Self) {
1820+
let contiguous = tail <= head;
1821+
if contiguous {
1822+
let (empty, buf) = buf.split_at(0);
1823+
(buf.slice(tail, head), empty)
1824+
} else {
1825+
let (mid, right) = buf.split_at(tail);
1826+
let (left, _) = mid.split_at(head);
1827+
(right, left)
1828+
}
1829+
}
1830+
}
1831+
1832+
impl<'a, T> RingSlices for &'a [T] {
1833+
fn slice(self, from: usize, to: usize) -> Self {
1834+
&self[from..to]
1835+
}
1836+
fn split_at(self, i: usize) -> (Self, Self) {
1837+
(*self).split_at(i)
1838+
}
1839+
}
1840+
1841+
impl<'a, T> RingSlices for &'a mut [T] {
1842+
fn slice(self, from: usize, to: usize) -> Self {
1843+
&mut self[from..to]
1844+
}
1845+
fn split_at(self, i: usize) -> (Self, Self) {
1846+
(*self).split_at_mut(i)
1847+
}
1848+
}
1849+
18321850
/// Calculate the number of elements left to be read in the buffer
18331851
#[inline]
18341852
fn count(tail: usize, head: usize, size: usize) -> usize {
@@ -1875,6 +1893,14 @@ impl<'a, T> Iterator for Iter<'a, T> {
18751893
let len = count(self.tail, self.head, self.ring.len());
18761894
(len, Some(len))
18771895
}
1896+
1897+
fn fold<Acc, F>(self, mut accum: Acc, mut f: F) -> Acc
1898+
where F: FnMut(Acc, Self::Item) -> Acc,
1899+
{
1900+
let (front, back) = RingSlices::ring_slices(self.ring, self.head, self.tail);
1901+
accum = front.iter().fold(accum, &mut f);
1902+
back.iter().fold(accum, &mut f)
1903+
}
18781904
}
18791905

18801906
#[stable(feature = "rust1", since = "1.0.0")]
@@ -1927,6 +1953,14 @@ impl<'a, T> Iterator for IterMut<'a, T> {
19271953
let len = count(self.tail, self.head, self.ring.len());
19281954
(len, Some(len))
19291955
}
1956+
1957+
fn fold<Acc, F>(self, mut accum: Acc, mut f: F) -> Acc
1958+
where F: FnMut(Acc, Self::Item) -> Acc,
1959+
{
1960+
let (front, back) = RingSlices::ring_slices(self.ring, self.head, self.tail);
1961+
accum = front.iter_mut().fold(accum, &mut f);
1962+
back.iter_mut().fold(accum, &mut f)
1963+
}
19301964
}
19311965

19321966
#[stable(feature = "rust1", since = "1.0.0")]

0 commit comments

Comments
 (0)