1use crate::iter;
2use crate::num::{Saturating, Wrapping};
34/// Trait to represent types that can be created by summing up an iterator.
5///
6/// This trait is used to implement [`Iterator::sum()`]. Types which implement
7/// this trait can be generated by using the [`sum()`] method on an iterator.
8/// Like [`FromIterator`], this trait should rarely be called directly.
9///
10/// [`sum()`]: Iterator::sum
11/// [`FromIterator`]: iter::FromIterator
12#[stable(feature = "iter_arith_traits", since = "1.12.0")]
13#[rustc_const_unstable(feature = "const_iter", issue = "92476")]
14#[diagnostic::on_unimplemented(
15 message = "a value of type `{Self}` cannot be made by summing an iterator over elements of type `{A}`",
16 label = "value of type `{Self}` cannot be made by summing a `std::iter::Iterator<Item={A}>`"
17)]
18pub const trait Sum<A = Self>: Sized {
19/// Takes an iterator and generates `Self` from the elements by "summing up"
20 /// the items.
21#[stable(feature = "iter_arith_traits", since = "1.12.0")]
22fn sum<I: Iterator<Item = A>>(iter: I) -> Self;
23}
2425/// Trait to represent types that can be created by multiplying elements of an
26/// iterator.
27///
28/// This trait is used to implement [`Iterator::product()`]. Types which implement
29/// this trait can be generated by using the [`product()`] method on an iterator.
30/// Like [`FromIterator`], this trait should rarely be called directly.
31///
32/// [`product()`]: Iterator::product
33/// [`FromIterator`]: iter::FromIterator
34#[stable(feature = "iter_arith_traits", since = "1.12.0")]
35#[rustc_const_unstable(feature = "const_iter", issue = "92476")]
36#[diagnostic::on_unimplemented(
37 message = "a value of type `{Self}` cannot be made by multiplying all elements of type `{A}` from an iterator",
38 label = "value of type `{Self}` cannot be made by multiplying all elements from a `std::iter::Iterator<Item={A}>`"
39)]
40pub const trait Product<A = Self>: Sized {
41/// Takes an iterator and generates `Self` from the elements by multiplying
42 /// the items.
43#[stable(feature = "iter_arith_traits", since = "1.12.0")]
44fn product<I: Iterator<Item = A>>(iter: I) -> Self;
45}
4647macro_rules!integer_sum_product {
48 (@impls $zero:expr, $one:expr, #[$attr:meta], $($a:ty)*) => ($(
49#[$attr]
50impl Sum for $a {
51fn sum<I: Iterator<Item=Self>>(iter: I) -> Self {
52 iter.fold(
53$zero,
54#[rustc_inherit_overflow_checks]
55|a, b| a + b,
56 )
57 }
58 }
5960#[$attr]
61impl Product for $a {
62fn product<I: Iterator<Item=Self>>(iter: I) -> Self {
63 iter.fold(
64$one,
65#[rustc_inherit_overflow_checks]
66|a, b| a * b,
67 )
68 }
69 }
7071#[$attr]
72impl<'a> Sum<&'a $a> for $a {
73fn sum<I: Iterator<Item=&'a Self>>(iter: I) -> Self {
74 iter.fold(
75$zero,
76#[rustc_inherit_overflow_checks]
77|a, b| a + b,
78 )
79 }
80 }
8182#[$attr]
83impl<'a> Product<&'a $a> for $a {
84fn product<I: Iterator<Item=&'a Self>>(iter: I) -> Self {
85 iter.fold(
86$one,
87#[rustc_inherit_overflow_checks]
88|a, b| a * b,
89 )
90 }
91 }
92 )*);
93 ($($a:ty)*) => (
94integer_sum_product!(@impls 0, 1,
95#[stable(feature = "iter_arith_traits", since = "1.12.0")],
96 $($a)*);
97integer_sum_product!(@impls Wrapping(0), Wrapping(1),
98#[stable(feature = "wrapping_iter_arith", since = "1.14.0")],
99 $(Wrapping<$a>)*);
100 );
101}
102103macro_rules!saturating_integer_sum_product {
104 (@impls $zero:expr, $one:expr, $doc:expr, #[$attr:meta], $($a:ty)*) => ($(
105#[$attr]
106 #[doc = $doc]
107impl Sum for $a {
108fn sum<I: Iterator<Item=Self>>(iter: I) -> Self {
109 iter.fold(
110$zero,
111 |a, b| a + b,
112 )
113 }
114 }
115116#[$attr]
117 #[doc = $doc]
118impl Product for $a {
119fn product<I: Iterator<Item=Self>>(iter: I) -> Self {
120 iter.fold(
121$one,
122 |a, b| a * b,
123 )
124 }
125 }
126127#[$attr]
128 #[doc = $doc]
129impl<'a> Sum<&'a $a> for $a {
130fn sum<I: Iterator<Item=&'a Self>>(iter: I) -> Self {
131 iter.fold(
132$zero,
133 |a, b| a + b,
134 )
135 }
136 }
137138#[$attr]
139 #[doc = $doc]
140impl<'a> Product<&'a $a> for $a {
141fn product<I: Iterator<Item=&'a Self>>(iter: I) -> Self {
142 iter.fold(
143$one,
144 |a, b| a * b,
145 )
146 }
147 }
148 )*);
149 ($($a:ty)*) => (
150saturating_integer_sum_product!(@impls Saturating(0), Saturating(1),
151"The short-circuiting behavior of this implementation is unspecified. If you care about \
152 short-circuiting, use [`Iterator::fold`] directly.",
153#[stable(feature = "saturating_iter_arith", since = "1.91.0")],
154 $(Saturating<$a>)*);
155 );
156}
157158macro_rules!float_sum_product {
159 ($($a:ident)*) => ($(
160#[stable(feature = "iter_arith_traits", since = "1.12.0")]
161impl Sum for $a {
162fn sum<I: Iterator<Item=Self>>(iter: I) -> Self {
163 iter.fold(
164 -0.0,
165#[rustc_inherit_overflow_checks]
166|a, b| a + b,
167 )
168 }
169 }
170171#[stable(feature = "iter_arith_traits", since = "1.12.0")]
172impl Product for $a {
173fn product<I: Iterator<Item=Self>>(iter: I) -> Self {
174 iter.fold(
1751.0,
176#[rustc_inherit_overflow_checks]
177|a, b| a * b,
178 )
179 }
180 }
181182#[stable(feature = "iter_arith_traits", since = "1.12.0")]
183impl<'a> Sum<&'a $a> for $a {
184fn sum<I: Iterator<Item=&'a Self>>(iter: I) -> Self {
185 iter.fold(
186 -0.0,
187#[rustc_inherit_overflow_checks]
188|a, b| a + b,
189 )
190 }
191 }
192193#[stable(feature = "iter_arith_traits", since = "1.12.0")]
194impl<'a> Product<&'a $a> for $a {
195fn product<I: Iterator<Item=&'a Self>>(iter: I) -> Self {
196 iter.fold(
1971.0,
198#[rustc_inherit_overflow_checks]
199|a, b| a * b,
200 )
201 }
202 }
203 )*)
204}
205206#[stable(feature = "wrapping_iter_arith", since = "1.14.0")]
impl Sum for Wrapping<usize> {
fn sum<I: Iterator<Item = Self>>(iter: I) -> Self {
iter.fold(Wrapping(0), #[rustc_inherit_overflow_checks] |a, b| a + b)
}
}
#[stable(feature = "wrapping_iter_arith", since = "1.14.0")]
impl Product for Wrapping<usize> {
fn product<I: Iterator<Item = Self>>(iter: I) -> Self {
iter.fold(Wrapping(1), #[rustc_inherit_overflow_checks] |a, b| a * b)
}
}
#[stable(feature = "wrapping_iter_arith", since = "1.14.0")]
impl<'a> Sum<&'a Wrapping<usize>> for Wrapping<usize> {
fn sum<I: Iterator<Item = &'a Self>>(iter: I) -> Self {
iter.fold(Wrapping(0), #[rustc_inherit_overflow_checks] |a, b| a + b)
}
}
#[stable(feature = "wrapping_iter_arith", since = "1.14.0")]
impl<'a> Product<&'a Wrapping<usize>> for Wrapping<usize> {
fn product<I: Iterator<Item = &'a Self>>(iter: I) -> Self {
iter.fold(Wrapping(1), #[rustc_inherit_overflow_checks] |a, b| a * b)
}
}integer_sum_product! { i8i16i32i64i128isizeu8u16u32u64u128usize }207#[stable(feature = "saturating_iter_arith", since = "1.91.0")]
#[doc =
"The short-circuiting behavior of this implementation is unspecified. If you care about \
short-circuiting, use [`Iterator::fold`] directly."]
impl Sum for Saturating<usize> {
fn sum<I: Iterator<Item = Self>>(iter: I) -> Self {
iter.fold(Saturating(0), |a, b| a + b)
}
}
#[stable(feature = "saturating_iter_arith", since = "1.91.0")]
#[doc =
"The short-circuiting behavior of this implementation is unspecified. If you care about \
short-circuiting, use [`Iterator::fold`] directly."]
impl Product for Saturating<usize> {
fn product<I: Iterator<Item = Self>>(iter: I) -> Self {
iter.fold(Saturating(1), |a, b| a * b)
}
}
#[stable(feature = "saturating_iter_arith", since = "1.91.0")]
#[doc =
"The short-circuiting behavior of this implementation is unspecified. If you care about \
short-circuiting, use [`Iterator::fold`] directly."]
impl<'a> Sum<&'a Saturating<usize>> for Saturating<usize> {
fn sum<I: Iterator<Item = &'a Self>>(iter: I) -> Self {
iter.fold(Saturating(0), |a, b| a + b)
}
}
#[stable(feature = "saturating_iter_arith", since = "1.91.0")]
#[doc =
"The short-circuiting behavior of this implementation is unspecified. If you care about \
short-circuiting, use [`Iterator::fold`] directly."]
impl<'a> Product<&'a Saturating<usize>> for Saturating<usize> {
fn product<I: Iterator<Item = &'a Self>>(iter: I) -> Self {
iter.fold(Saturating(1), |a, b| a * b)
}
}saturating_integer_sum_product! { u8 u16 u32 u64 u128 usize }208#[stable(feature = "iter_arith_traits", since = "1.12.0")]
impl Sum for f128 {
fn sum<I: Iterator<Item = Self>>(iter: I) -> Self {
iter.fold(-0.0, #[rustc_inherit_overflow_checks] |a, b| a + b)
}
}
#[stable(feature = "iter_arith_traits", since = "1.12.0")]
impl Product for f128 {
fn product<I: Iterator<Item = Self>>(iter: I) -> Self {
iter.fold(1.0, #[rustc_inherit_overflow_checks] |a, b| a * b)
}
}
#[stable(feature = "iter_arith_traits", since = "1.12.0")]
impl<'a> Sum<&'a f128> for f128 {
fn sum<I: Iterator<Item = &'a Self>>(iter: I) -> Self {
iter.fold(-0.0, #[rustc_inherit_overflow_checks] |a, b| a + b)
}
}
#[stable(feature = "iter_arith_traits", since = "1.12.0")]
impl<'a> Product<&'a f128> for f128 {
fn product<I: Iterator<Item = &'a Self>>(iter: I) -> Self {
iter.fold(1.0, #[rustc_inherit_overflow_checks] |a, b| a * b)
}
}float_sum_product! { f16 f32 f64 f128 }209210#[stable(feature = "iter_arith_traits_result", since = "1.16.0")]
211impl<T, U, E> Sum<Result<U, E>> for Result<T, E>
212where
213T: Sum<U>,
214{
215/// Takes each element in the [`Iterator`]: if it is an [`Err`], no further
216 /// elements are taken, and the [`Err`] is returned. Should no [`Err`]
217 /// occur, the sum of all elements is returned.
218 ///
219 /// # Examples
220 ///
221 /// This sums up every integer in a vector, rejecting the sum if a negative
222 /// element is encountered:
223 ///
224 /// ```
225 /// let f = |&x: &i32| if x < 0 { Err("Negative element found") } else { Ok(x) };
226 /// let v = vec![1, 2];
227 /// let res: Result<i32, _> = v.iter().map(f).sum();
228 /// assert_eq!(res, Ok(3));
229 /// let v = vec![1, -2];
230 /// let res: Result<i32, _> = v.iter().map(f).sum();
231 /// assert_eq!(res, Err("Negative element found"));
232 /// ```
233fn sum<I>(iter: I) -> Result<T, E>
234where
235I: Iterator<Item = Result<U, E>>,
236 {
237 iter::try_process(iter, |i| i.sum())
238 }
239}
240241#[stable(feature = "iter_arith_traits_result", since = "1.16.0")]
242impl<T, U, E> Product<Result<U, E>> for Result<T, E>
243where
244T: Product<U>,
245{
246/// Takes each element in the [`Iterator`]: if it is an [`Err`], no further
247 /// elements are taken, and the [`Err`] is returned. Should no [`Err`]
248 /// occur, the product of all elements is returned.
249 ///
250 /// # Examples
251 ///
252 /// This multiplies each number in a vector of strings,
253 /// if a string could not be parsed the operation returns `Err`:
254 ///
255 /// ```
256 /// let nums = vec!["5", "10", "1", "2"];
257 /// let total: Result<usize, _> = nums.iter().map(|w| w.parse::<usize>()).product();
258 /// assert_eq!(total, Ok(100));
259 /// let nums = vec!["5", "10", "one", "2"];
260 /// let total: Result<usize, _> = nums.iter().map(|w| w.parse::<usize>()).product();
261 /// assert!(total.is_err());
262 /// ```
263fn product<I>(iter: I) -> Result<T, E>
264where
265I: Iterator<Item = Result<U, E>>,
266 {
267 iter::try_process(iter, |i| i.product())
268 }
269}
270271#[stable(feature = "iter_arith_traits_option", since = "1.37.0")]
272impl<T, U> Sum<Option<U>> for Option<T>
273where
274T: Sum<U>,
275{
276/// Takes each element in the [`Iterator`]: if it is a [`None`], no further
277 /// elements are taken, and the [`None`] is returned. Should no [`None`]
278 /// occur, the sum of all elements is returned.
279 ///
280 /// # Examples
281 ///
282 /// This sums up the position of the character 'a' in a vector of strings,
283 /// if a word did not have the character 'a' the operation returns `None`:
284 ///
285 /// ```
286 /// let words = vec!["have", "a", "great", "day"];
287 /// let total: Option<usize> = words.iter().map(|w| w.find('a')).sum();
288 /// assert_eq!(total, Some(5));
289 /// let words = vec!["have", "a", "good", "day"];
290 /// let total: Option<usize> = words.iter().map(|w| w.find('a')).sum();
291 /// assert_eq!(total, None);
292 /// ```
293fn sum<I>(iter: I) -> Option<T>
294where
295I: Iterator<Item = Option<U>>,
296 {
297 iter::try_process(iter, |i| i.sum())
298 }
299}
300301#[stable(feature = "iter_arith_traits_option", since = "1.37.0")]
302impl<T, U> Product<Option<U>> for Option<T>
303where
304T: Product<U>,
305{
306/// Takes each element in the [`Iterator`]: if it is a [`None`], no further
307 /// elements are taken, and the [`None`] is returned. Should no [`None`]
308 /// occur, the product of all elements is returned.
309 ///
310 /// # Examples
311 ///
312 /// This multiplies each number in a vector of strings,
313 /// if a string could not be parsed the operation returns `None`:
314 ///
315 /// ```
316 /// let nums = vec!["5", "10", "1", "2"];
317 /// let total: Option<usize> = nums.iter().map(|w| w.parse::<usize>().ok()).product();
318 /// assert_eq!(total, Some(100));
319 /// let nums = vec!["5", "10", "one", "2"];
320 /// let total: Option<usize> = nums.iter().map(|w| w.parse::<usize>().ok()).product();
321 /// assert_eq!(total, None);
322 /// ```
323fn product<I>(iter: I) -> Option<T>
324where
325I: Iterator<Item = Option<U>>,
326 {
327 iter::try_process(iter, |i| i.product())
328 }
329}