Skip to content

Commit 147311c

Browse files
committed
Auto merge of #57974 - llogiq:vec-deque-try-fold, r=alexcrichton
override `VecDeque`'s `Iter::try_fold` This should improve performance (wherever it is used), but I haven't found the time to benchmark it yet.
2 parents d9a2e3b + b062b75 commit 147311c

File tree

3 files changed

+47
-1
lines changed

3 files changed

+47
-1
lines changed

src/liballoc/collections/vec_deque.rs

+9-1
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ use core::fmt;
1212
use core::iter::{repeat_with, FromIterator, FusedIterator};
1313
use core::mem;
1414
use core::ops::Bound::{Excluded, Included, Unbounded};
15-
use core::ops::{Index, IndexMut, RangeBounds};
15+
use core::ops::{Index, IndexMut, RangeBounds, Try};
1616
use core::ptr;
1717
use core::ptr::NonNull;
1818
use core::slice;
@@ -2172,6 +2172,14 @@ impl<'a, T> Iterator for Iter<'a, T> {
21722172
accum = front.iter().fold(accum, &mut f);
21732173
back.iter().fold(accum, &mut f)
21742174
}
2175+
2176+
fn try_fold<B, F, R>(&mut self, init: B, mut f: F) -> R where
2177+
Self: Sized, F: FnMut(B, Self::Item) -> R, R: Try<Ok=B>
2178+
{
2179+
let (front, back) = RingSlices::ring_slices(self.ring, self.head, self.tail);
2180+
let accum = front.iter().try_fold(init, &mut f)?;
2181+
back.iter().try_fold(accum, &mut f)
2182+
}
21752183
}
21762184

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

src/liballoc/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,7 @@
113113
#![feature(slice_partition_dedup)]
114114
#![feature(maybe_uninit)]
115115
#![feature(alloc_layout_extra)]
116+
#![feature(try_trait)]
116117

117118
// Allow testing this library
118119

src/liballoc/tests/vec_deque.rs

+37
Original file line numberDiff line numberDiff line change
@@ -1433,3 +1433,40 @@ fn test_rotate_right_random() {
14331433
}
14341434
}
14351435
}
1436+
1437+
#[test]
1438+
fn test_try_fold_empty() {
1439+
assert_eq!(Some(0), VecDeque::<u32>::new().iter().try_fold(0, |_, _| None));
1440+
}
1441+
1442+
#[test]
1443+
fn test_try_fold_none() {
1444+
let v: VecDeque<u32> = (0..12).collect();
1445+
assert_eq!(None, v.into_iter().try_fold(0, |a, b|
1446+
if b < 11 { Some(a + b) } else { None }));
1447+
}
1448+
1449+
#[test]
1450+
fn test_try_fold_ok() {
1451+
let v: VecDeque<u32> = (0..12).collect();
1452+
assert_eq!(Ok::<_, ()>(66), v.into_iter().try_fold(0, |a, b| Ok(a + b)));
1453+
}
1454+
1455+
#[test]
1456+
fn test_try_fold_unit() {
1457+
let v: VecDeque<()> = std::iter::repeat(()).take(42).collect();
1458+
assert_eq!(Some(()), v.into_iter().try_fold((), |(), ()| Some(())));
1459+
}
1460+
1461+
#[test]
1462+
fn test_try_fold_rotated() {
1463+
let mut v: VecDeque<_> = (0..12).collect();
1464+
for n in 0..10 {
1465+
if n & 1 == 0 {
1466+
v.rotate_left(n);
1467+
} else {
1468+
v.rotate_right(n);
1469+
}
1470+
assert_eq!(Ok::<_, ()>(66), v.iter().try_fold(0, |a, b| Ok(a + b)));
1471+
}
1472+
}

0 commit comments

Comments
 (0)