2 use crate::num
::Wrapping
;
4 /// Trait to represent types that can be created by summing up an iterator.
6 /// This trait is used to implement the [`sum()`] method on iterators. Types which
7 /// implement the trait can be generated by the [`sum()`] method. Like
8 /// [`FromIterator`] this trait should rarely be called directly and instead
9 /// interacted with through [`Iterator::sum()`].
11 /// [`sum()`]: Sum::sum
12 /// [`FromIterator`]: iter::FromIterator
13 #[stable(feature = "iter_arith_traits", since = "1.12.0")]
14 pub trait Sum
<A
= Self>: Sized
{
15 /// Method which takes an iterator and generates `Self` from the elements by
16 /// "summing up" the items.
17 #[stable(feature = "iter_arith_traits", since = "1.12.0")]
18 fn sum
<I
: Iterator
<Item
= A
>>(iter
: I
) -> Self;
21 /// Trait to represent types that can be created by multiplying elements of an
24 /// This trait is used to implement the [`product()`] method on iterators. Types
25 /// which implement the trait can be generated by the [`product()`] method. Like
26 /// [`FromIterator`] this trait should rarely be called directly and instead
27 /// interacted with through [`Iterator::product()`].
29 /// [`product()`]: Product::product
30 /// [`FromIterator`]: iter::FromIterator
31 #[stable(feature = "iter_arith_traits", since = "1.12.0")]
32 pub trait Product
<A
= Self>: Sized
{
33 /// Method which takes an iterator and generates `Self` from the elements by
34 /// multiplying the items.
35 #[stable(feature = "iter_arith_traits", since = "1.12.0")]
36 fn product
<I
: Iterator
<Item
= A
>>(iter
: I
) -> Self;
39 macro_rules
! integer_sum_product
{
40 (@impls $zero
:expr
, $one
:expr
, #[$attr:meta], $($a:ty)*) => ($(
43 fn sum
<I
: Iterator
<Item
=Self>>(iter
: I
) -> Self {
46 #[rustc_inherit_overflow_checks]
54 fn product
<I
: Iterator
<Item
=Self>>(iter
: I
) -> Self {
57 #[rustc_inherit_overflow_checks]
64 impl<'a
> Sum
<&'a $a
> for $a
{
65 fn sum
<I
: Iterator
<Item
=&'a
Self>>(iter
: I
) -> Self {
68 #[rustc_inherit_overflow_checks]
75 impl<'a
> Product
<&'a $a
> for $a
{
76 fn product
<I
: Iterator
<Item
=&'a
Self>>(iter
: I
) -> Self {
79 #[rustc_inherit_overflow_checks]
86 integer_sum_product
!(@impls
0, 1,
87 #[stable(feature = "iter_arith_traits", since = "1.12.0")],
89 integer_sum_product
!(@impls
Wrapping(0), Wrapping(1),
90 #[stable(feature = "wrapping_iter_arith", since = "1.14.0")],
95 macro_rules
! float_sum_product
{
97 #[stable(feature = "iter_arith_traits", since = "1.12.0")]
99 fn sum
<I
: Iterator
<Item
=Self>>(iter
: I
) -> Self {
102 #[rustc_inherit_overflow_checks]
108 #[stable(feature = "iter_arith_traits", since = "1.12.0")]
109 impl Product
for $a
{
110 fn product
<I
: Iterator
<Item
=Self>>(iter
: I
) -> Self {
113 #[rustc_inherit_overflow_checks]
119 #[stable(feature = "iter_arith_traits", since = "1.12.0")]
120 impl<'a
> Sum
<&'a $a
> for $a
{
121 fn sum
<I
: Iterator
<Item
=&'a
Self>>(iter
: I
) -> Self {
124 #[rustc_inherit_overflow_checks]
130 #[stable(feature = "iter_arith_traits", since = "1.12.0")]
131 impl<'a
> Product
<&'a $a
> for $a
{
132 fn product
<I
: Iterator
<Item
=&'a
Self>>(iter
: I
) -> Self {
135 #[rustc_inherit_overflow_checks]
143 integer_sum_product
! { i8 i16 i32 i64 i128 isize u8 u16 u32 u64 u128 usize }
144 float_sum_product
! { f32 f64 }
146 #[stable(feature = "iter_arith_traits_result", since = "1.16.0")]
147 impl<T
, U
, E
> Sum
<Result
<U
, E
>> for Result
<T
, E
>
151 /// Takes each element in the [`Iterator`]: if it is an [`Err`], no further
152 /// elements are taken, and the [`Err`] is returned. Should no [`Err`]
153 /// occur, the sum of all elements is returned.
157 /// This sums up every integer in a vector, rejecting the sum if a negative
158 /// element is encountered:
161 /// let v = vec![1, 2];
162 /// let res: Result<i32, &'static str> = v.iter().map(|&x: &i32|
163 /// if x < 0 { Err("Negative element found") }
166 /// assert_eq!(res, Ok(3));
168 fn sum
<I
>(iter
: I
) -> Result
<T
, E
>
170 I
: Iterator
<Item
= Result
<U
, E
>>,
172 iter
::process_results(iter
, |i
| i
.sum())
176 #[stable(feature = "iter_arith_traits_result", since = "1.16.0")]
177 impl<T
, U
, E
> Product
<Result
<U
, E
>> for Result
<T
, E
>
181 /// Takes each element in the [`Iterator`]: if it is an [`Err`], no further
182 /// elements are taken, and the [`Err`] is returned. Should no [`Err`]
183 /// occur, the product of all elements is returned.
184 fn product
<I
>(iter
: I
) -> Result
<T
, E
>
186 I
: Iterator
<Item
= Result
<U
, E
>>,
188 iter
::process_results(iter
, |i
| i
.product())
192 #[stable(feature = "iter_arith_traits_option", since = "1.37.0")]
193 impl<T
, U
> Sum
<Option
<U
>> for Option
<T
>
197 /// Takes each element in the [`Iterator`]: if it is a [`None`], no further
198 /// elements are taken, and the [`None`] is returned. Should no [`None`]
199 /// occur, the sum of all elements is returned.
203 /// This sums up the position of the character 'a' in a vector of strings,
204 /// if a word did not have the character 'a' the operation returns `None`:
207 /// let words = vec!["have", "a", "great", "day"];
208 /// let total: Option<usize> = words.iter().map(|w| w.find('a')).sum();
209 /// assert_eq!(total, Some(5));
211 fn sum
<I
>(iter
: I
) -> Option
<T
>
213 I
: Iterator
<Item
= Option
<U
>>,
215 iter
.map(|x
| x
.ok_or(())).sum
::<Result
<_
, _
>>().ok()
219 #[stable(feature = "iter_arith_traits_option", since = "1.37.0")]
220 impl<T
, U
> Product
<Option
<U
>> for Option
<T
>
224 /// Takes each element in the [`Iterator`]: if it is a [`None`], no further
225 /// elements are taken, and the [`None`] is returned. Should no [`None`]
226 /// occur, the product of all elements is returned.
227 fn product
<I
>(iter
: I
) -> Option
<T
>
229 I
: Iterator
<Item
= Option
<U
>>,
231 iter
.map(|x
| x
.ok_or(())).product
::<Result
<_
, _
>>().ok()