diff --git a/src/libcore/iter/iterator.rs b/src/libcore/iter/iterator.rs index afc273d265b9c..177cee443d7fe 100644 --- a/src/libcore/iter/iterator.rs +++ b/src/libcore/iter/iterator.rs @@ -17,6 +17,7 @@ use super::{Flatten, FlatMap, flatten_compat}; use super::{Inspect, Map, Peekable, Scan, Skip, SkipWhile, StepBy, Take, TakeWhile, Rev}; use super::{Zip, Sum, Product}; use super::{ChainState, FromIterator, ZipImpl}; +use super::sources::once; fn _assert_is_object_safe(_: &Iterator) {} @@ -2265,6 +2266,37 @@ pub trait Iterator { Sum::sum(self) } + /// Iterates over the entire iterator, adding all the elements + /// + /// An empty iterator returns `None`, otherwise `Some(sum)`. + /// + /// # Panics + /// + /// When calling `sum_nonempty()` and a primitive integer type is being returned, this + /// method will panic if the computation overflows and debug assertions are + /// enabled. + /// + /// # Examples + /// + /// ``` + /// #![feature(nonempty_iter_arith)] + /// let empty_sum = (1..1).sum_nonempty::(); + /// assert_eq!(empty_sum, None); + /// + /// let nonempty_sum = (1..=10).sum_nonempty::(); + /// assert_eq!(nonempty_sum, Some(55)); + /// ``` + #[unstable(feature = "nonempty_iter_arith", + reason = "recently added unstable API", + issue = "0")] + fn sum_nonempty(mut self) -> Option + where Self: Sized, + S: Sum, + { + self.next() + .map(|first| once(first).chain(self).sum()) + } + /// Iterates over the entire iterator, multiplying all the elements /// /// An empty iterator returns the one value of the type. @@ -2293,6 +2325,36 @@ pub trait Iterator { Product::product(self) } + /// Iterates over the entire iterator, multiplying all the elements + /// + /// An empty iterator returns `None`, otherwise `Some(product)`. + /// + /// # Panics + /// + /// When calling `product_nonempty()` and a primitive integer type is being returned, + /// method will panic if the computation overflows and debug assertions are + /// enabled. + /// + /// # Examples + /// ``` + /// #![feature(nonempty_iter_arith)] + /// let empty_product = (1..1).product_nonempty::(); + /// assert_eq!(empty_product, None); + /// + /// let nonempty_product = (1..=10).product_nonempty::(); + /// assert_eq!(nonempty_product, Some(3628800)); + /// ``` + #[unstable(feature = "nonempty_iter_arith", + reason = "recently added unstable API", + issue = "0")] + fn product_nonempty

(mut self) -> Option

+ where Self: Sized, + P: Product, + { + self.next() + .map(|first| once(first).chain(self).product()) + } + /// Lexicographically compares the elements of this `Iterator` with those /// of another. #[stable(feature = "iter_order", since = "1.5.0")] diff --git a/src/libcore/tests/iter.rs b/src/libcore/tests/iter.rs index 72b115f8b5f77..e33fd9f38da1e 100644 --- a/src/libcore/tests/iter.rs +++ b/src/libcore/tests/iter.rs @@ -1035,6 +1035,15 @@ fn test_iterator_sum() { assert_eq!(v[..0].iter().cloned().sum::(), 0); } +#[test] +fn test_iterator_sum_nonempty() { + let v: &[i32] = &[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]; + assert_eq!(v[..0].iter().cloned().sum_nonempty::(), None); + assert_eq!(v[1..2].iter().cloned().sum_nonempty::(), Some(1)); + assert_eq!(v[1..3].iter().cloned().sum_nonempty::(), Some(3)); + assert_eq!(v.iter().cloned().sum_nonempty::(), Some(55)); +} + #[test] fn test_iterator_sum_result() { let v: &[Result] = &[Ok(1), Ok(2), Ok(3), Ok(4)]; @@ -1051,6 +1060,15 @@ fn test_iterator_product() { assert_eq!(v[..0].iter().cloned().product::(), 1); } +#[test] +fn test_iterator_product_nonempty() { + let v: &[i32] = &[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]; + assert_eq!(v[..0].iter().cloned().product_nonempty::(), None); + assert_eq!(v[..1].iter().cloned().product_nonempty::(), Some(0)); + assert_eq!(v[1..3].iter().cloned().product_nonempty::(), Some(2)); + assert_eq!(v[1..5].iter().cloned().product_nonempty::(), Some(24)); +} + #[test] fn test_iterator_product_result() { let v: &[Result] = &[Ok(1), Ok(2), Ok(3), Ok(4)]; diff --git a/src/libcore/tests/lib.rs b/src/libcore/tests/lib.rs index ca7db6e4639a5..da6df95579a09 100644 --- a/src/libcore/tests/lib.rs +++ b/src/libcore/tests/lib.rs @@ -23,6 +23,7 @@ #![feature(flt2dec)] #![feature(fmt_internals)] #![feature(hashmap_internals)] +#![feature(nonempty_iter_arith)] #![feature(pattern)] #![feature(range_is_empty)] #![feature(raw)]