From 7e22cb27563810596fdd55748dba0e1d0daa77be Mon Sep 17 00:00:00 2001 From: Andre Bogus Date: Tue, 29 Jan 2019 16:15:02 +0100 Subject: [PATCH] override `VecDeque`'s `Iter::try_fold` --- src/liballoc/collections/vec_deque.rs | 10 ++++++- src/liballoc/lib.rs | 1 + src/liballoc/tests/vec_deque.rs | 38 +++++++++++++++++++++++++++ 3 files changed, 48 insertions(+), 1 deletion(-) diff --git a/src/liballoc/collections/vec_deque.rs b/src/liballoc/collections/vec_deque.rs index b3f7ef5fd6ecc..579d7de96e6da 100644 --- a/src/liballoc/collections/vec_deque.rs +++ b/src/liballoc/collections/vec_deque.rs @@ -12,7 +12,7 @@ use core::fmt; use core::iter::{repeat_with, FromIterator, FusedIterator}; use core::mem; use core::ops::Bound::{Excluded, Included, Unbounded}; -use core::ops::{Index, IndexMut, RangeBounds}; +use core::ops::{Index, IndexMut, RangeBounds, Try}; use core::ptr; use core::ptr::NonNull; use core::slice; @@ -2172,6 +2172,14 @@ impl<'a, T> Iterator for Iter<'a, T> { accum = front.iter().fold(accum, &mut f); back.iter().fold(accum, &mut f) } + + fn try_fold(&mut self, init: B, mut f: F) -> R where + Self: Sized, F: FnMut(B, Self::Item) -> R, R: Try + { + let (front, back) = RingSlices::ring_slices(self.ring, self.head, self.tail); + let accum = front.iter().try_fold(init, &mut f)?; + back.iter().try_fold(accum, &mut f) + } } #[stable(feature = "rust1", since = "1.0.0")] diff --git a/src/liballoc/lib.rs b/src/liballoc/lib.rs index d2ff1bae63561..5165a7ca5a8f3 100644 --- a/src/liballoc/lib.rs +++ b/src/liballoc/lib.rs @@ -113,6 +113,7 @@ #![feature(slice_partition_dedup)] #![feature(maybe_uninit)] #![feature(alloc_layout_extra)] +#![feature(try_trait)] // Allow testing this library diff --git a/src/liballoc/tests/vec_deque.rs b/src/liballoc/tests/vec_deque.rs index 76831ba65e3b8..e2896cffea092 100644 --- a/src/liballoc/tests/vec_deque.rs +++ b/src/liballoc/tests/vec_deque.rs @@ -1433,3 +1433,41 @@ fn test_rotate_right_random() { } } } + +#[test] +fn test_try_fold_empty() { + assert_eq!(Some(0), VecDeque::::new().iter().try_fold(0, |_, _| None)); +} + +#[test] +fn test_try_fold_none() { + let v: VecDeque = (0..12).collect(); + assert_eq!(None, v.into_iter().try_fold(0, |a, b| + if b < 11 { Some(a + b) } else { None })); +} + +#[test] +fn test_try_fold_ok() { + let v: VecDeque = (0..12).collect(); + assert_eq!(Ok::<_, ()>(66), v.into_iter().try_fold(0, |a, b| Ok(a + b))); +} + +#[test] +fn test_try_fold_unit() { + let v: VecDeque<()> = std::iter::repeat(()).take(42).collect(); + assert_eq!(Some(()), v.into_iter().try_fold((), |(), ()| Some(()))); +} + +#[test] +fn test_try_fold_rotated() { + let mut v: VecDeque<_> = (0..12).collect(); + for n in 0..30 { + if n & 1 == 0 { + let r = v[n]; + v.rotate_left(n ^ r); + } else { + v.rotate_right(n % 11); + } + assert_eq!(Ok::<_, ()>(66), v.into_iter().try_fold(0, |a, b| Ok(a + b))); + } +}