1 | use crate::iter; |
2 | use crate::num::Wrapping; |
3 | |
4 | /// 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_on_unimplemented ( |
14 | message = "a value of type `{Self}` cannot be made by summing an iterator over elements of type `{A}`" , |
15 | label = "value of type `{Self}` cannot be made by summing a `std::iter::Iterator<Item={A}>`" |
16 | )] |
17 | pub trait Sum<A = Self>: Sized { |
18 | /// Method which takes an iterator and generates `Self` from the elements by |
19 | /// "summing up" the items. |
20 | #[stable (feature = "iter_arith_traits" , since = "1.12.0" )] |
21 | fn sum<I: Iterator<Item = A>>(iter: I) -> Self; |
22 | } |
23 | |
24 | /// Trait to represent types that can be created by multiplying elements of an |
25 | /// iterator. |
26 | /// |
27 | /// This trait is used to implement [`Iterator::product()`]. Types which implement |
28 | /// this trait can be generated by using the [`product()`] method on an iterator. |
29 | /// Like [`FromIterator`], this trait should rarely be called directly. |
30 | /// |
31 | /// [`product()`]: Iterator::product |
32 | /// [`FromIterator`]: iter::FromIterator |
33 | #[stable (feature = "iter_arith_traits" , since = "1.12.0" )] |
34 | #[rustc_on_unimplemented ( |
35 | message = "a value of type `{Self}` cannot be made by multiplying all elements of type `{A}` from an iterator" , |
36 | label = "value of type `{Self}` cannot be made by multiplying all elements from a `std::iter::Iterator<Item={A}>`" |
37 | )] |
38 | pub trait Product<A = Self>: Sized { |
39 | /// Method which takes an iterator and generates `Self` from the elements by |
40 | /// multiplying the items. |
41 | #[stable (feature = "iter_arith_traits" , since = "1.12.0" )] |
42 | fn product<I: Iterator<Item = A>>(iter: I) -> Self; |
43 | } |
44 | |
45 | macro_rules! integer_sum_product { |
46 | (@impls $zero:expr, $one:expr, #[$attr:meta], $($a:ty)*) => ($( |
47 | #[$attr] |
48 | impl Sum for $a { |
49 | fn sum<I: Iterator<Item=Self>>(iter: I) -> Self { |
50 | iter.fold( |
51 | $zero, |
52 | #[rustc_inherit_overflow_checks] |
53 | |a, b| a + b, |
54 | ) |
55 | } |
56 | } |
57 | |
58 | #[$attr] |
59 | impl Product for $a { |
60 | fn product<I: Iterator<Item=Self>>(iter: I) -> Self { |
61 | iter.fold( |
62 | $one, |
63 | #[rustc_inherit_overflow_checks] |
64 | |a, b| a * b, |
65 | ) |
66 | } |
67 | } |
68 | |
69 | #[$attr] |
70 | impl<'a> Sum<&'a $a> for $a { |
71 | fn sum<I: Iterator<Item=&'a Self>>(iter: I) -> Self { |
72 | iter.fold( |
73 | $zero, |
74 | #[rustc_inherit_overflow_checks] |
75 | |a, b| a + b, |
76 | ) |
77 | } |
78 | } |
79 | |
80 | #[$attr] |
81 | impl<'a> Product<&'a $a> for $a { |
82 | fn product<I: Iterator<Item=&'a Self>>(iter: I) -> Self { |
83 | iter.fold( |
84 | $one, |
85 | #[rustc_inherit_overflow_checks] |
86 | |a, b| a * b, |
87 | ) |
88 | } |
89 | } |
90 | )*); |
91 | ($($a:ty)*) => ( |
92 | integer_sum_product!(@impls 0, 1, |
93 | #[stable(feature = "iter_arith_traits" , since = "1.12.0" )], |
94 | $($a)*); |
95 | integer_sum_product!(@impls Wrapping(0), Wrapping(1), |
96 | #[stable(feature = "wrapping_iter_arith" , since = "1.14.0" )], |
97 | $(Wrapping<$a>)*); |
98 | ); |
99 | } |
100 | |
101 | macro_rules! float_sum_product { |
102 | ($($a:ident)*) => ($( |
103 | #[stable(feature = "iter_arith_traits" , since = "1.12.0" )] |
104 | impl Sum for $a { |
105 | fn sum<I: Iterator<Item=Self>>(iter: I) -> Self { |
106 | iter.fold( |
107 | 0.0, |
108 | #[rustc_inherit_overflow_checks] |
109 | |a, b| a + b, |
110 | ) |
111 | } |
112 | } |
113 | |
114 | #[stable(feature = "iter_arith_traits" , since = "1.12.0" )] |
115 | impl Product for $a { |
116 | fn product<I: Iterator<Item=Self>>(iter: I) -> Self { |
117 | iter.fold( |
118 | 1.0, |
119 | #[rustc_inherit_overflow_checks] |
120 | |a, b| a * b, |
121 | ) |
122 | } |
123 | } |
124 | |
125 | #[stable(feature = "iter_arith_traits" , since = "1.12.0" )] |
126 | impl<'a> Sum<&'a $a> for $a { |
127 | fn sum<I: Iterator<Item=&'a Self>>(iter: I) -> Self { |
128 | iter.fold( |
129 | 0.0, |
130 | #[rustc_inherit_overflow_checks] |
131 | |a, b| a + b, |
132 | ) |
133 | } |
134 | } |
135 | |
136 | #[stable(feature = "iter_arith_traits" , since = "1.12.0" )] |
137 | impl<'a> Product<&'a $a> for $a { |
138 | fn product<I: Iterator<Item=&'a Self>>(iter: I) -> Self { |
139 | iter.fold( |
140 | 1.0, |
141 | #[rustc_inherit_overflow_checks] |
142 | |a, b| a * b, |
143 | ) |
144 | } |
145 | } |
146 | )*) |
147 | } |
148 | |
149 | integer_sum_product! { i8 i16 i32 i64 i128 isize u8 u16 u32 u64 u128 usize } |
150 | float_sum_product! { f32 f64 } |
151 | |
152 | #[stable (feature = "iter_arith_traits_result" , since = "1.16.0" )] |
153 | impl<T, U, E> Sum<Result<U, E>> for Result<T, E> |
154 | where |
155 | T: Sum<U>, |
156 | { |
157 | /// Takes each element in the [`Iterator`]: if it is an [`Err`], no further |
158 | /// elements are taken, and the [`Err`] is returned. Should no [`Err`] |
159 | /// occur, the sum of all elements is returned. |
160 | /// |
161 | /// # Examples |
162 | /// |
163 | /// This sums up every integer in a vector, rejecting the sum if a negative |
164 | /// element is encountered: |
165 | /// |
166 | /// ``` |
167 | /// let f = |&x: &i32| if x < 0 { Err("Negative element found" ) } else { Ok(x) }; |
168 | /// let v = vec![1, 2]; |
169 | /// let res: Result<i32, _> = v.iter().map(f).sum(); |
170 | /// assert_eq!(res, Ok(3)); |
171 | /// let v = vec![1, -2]; |
172 | /// let res: Result<i32, _> = v.iter().map(f).sum(); |
173 | /// assert_eq!(res, Err("Negative element found" )); |
174 | /// ``` |
175 | fn sum<I>(iter: I) -> Result<T, E> |
176 | where |
177 | I: Iterator<Item = Result<U, E>>, |
178 | { |
179 | iter::try_process(iter, |i| i.sum()) |
180 | } |
181 | } |
182 | |
183 | #[stable (feature = "iter_arith_traits_result" , since = "1.16.0" )] |
184 | impl<T, U, E> Product<Result<U, E>> for Result<T, E> |
185 | where |
186 | T: Product<U>, |
187 | { |
188 | /// Takes each element in the [`Iterator`]: if it is an [`Err`], no further |
189 | /// elements are taken, and the [`Err`] is returned. Should no [`Err`] |
190 | /// occur, the product of all elements is returned. |
191 | /// |
192 | /// # Examples |
193 | /// |
194 | /// This multiplies each number in a vector of strings, |
195 | /// if a string could not be parsed the operation returns `Err`: |
196 | /// |
197 | /// ``` |
198 | /// let nums = vec!["5" , "10" , "1" , "2" ]; |
199 | /// let total: Result<usize, _> = nums.iter().map(|w| w.parse::<usize>()).product(); |
200 | /// assert_eq!(total, Ok(100)); |
201 | /// let nums = vec!["5" , "10" , "one" , "2" ]; |
202 | /// let total: Result<usize, _> = nums.iter().map(|w| w.parse::<usize>()).product(); |
203 | /// assert!(total.is_err()); |
204 | /// ``` |
205 | fn product<I>(iter: I) -> Result<T, E> |
206 | where |
207 | I: Iterator<Item = Result<U, E>>, |
208 | { |
209 | iter::try_process(iter, |i| i.product()) |
210 | } |
211 | } |
212 | |
213 | #[stable (feature = "iter_arith_traits_option" , since = "1.37.0" )] |
214 | impl<T, U> Sum<Option<U>> for Option<T> |
215 | where |
216 | T: Sum<U>, |
217 | { |
218 | /// Takes each element in the [`Iterator`]: if it is a [`None`], no further |
219 | /// elements are taken, and the [`None`] is returned. Should no [`None`] |
220 | /// occur, the sum of all elements is returned. |
221 | /// |
222 | /// # Examples |
223 | /// |
224 | /// This sums up the position of the character 'a' in a vector of strings, |
225 | /// if a word did not have the character 'a' the operation returns `None`: |
226 | /// |
227 | /// ``` |
228 | /// let words = vec!["have" , "a" , "great" , "day" ]; |
229 | /// let total: Option<usize> = words.iter().map(|w| w.find('a' )).sum(); |
230 | /// assert_eq!(total, Some(5)); |
231 | /// let words = vec!["have" , "a" , "good" , "day" ]; |
232 | /// let total: Option<usize> = words.iter().map(|w| w.find('a' )).sum(); |
233 | /// assert_eq!(total, None); |
234 | /// ``` |
235 | fn sum<I>(iter: I) -> Option<T> |
236 | where |
237 | I: Iterator<Item = Option<U>>, |
238 | { |
239 | iter::try_process(iter, |i| i.sum()) |
240 | } |
241 | } |
242 | |
243 | #[stable (feature = "iter_arith_traits_option" , since = "1.37.0" )] |
244 | impl<T, U> Product<Option<U>> for Option<T> |
245 | where |
246 | T: Product<U>, |
247 | { |
248 | /// Takes each element in the [`Iterator`]: if it is a [`None`], no further |
249 | /// elements are taken, and the [`None`] is returned. Should no [`None`] |
250 | /// occur, the product of all elements is returned. |
251 | /// |
252 | /// # Examples |
253 | /// |
254 | /// This multiplies each number in a vector of strings, |
255 | /// if a string could not be parsed the operation returns `None`: |
256 | /// |
257 | /// ``` |
258 | /// let nums = vec!["5" , "10" , "1" , "2" ]; |
259 | /// let total: Option<usize> = nums.iter().map(|w| w.parse::<usize>().ok()).product(); |
260 | /// assert_eq!(total, Some(100)); |
261 | /// let nums = vec!["5" , "10" , "one" , "2" ]; |
262 | /// let total: Option<usize> = nums.iter().map(|w| w.parse::<usize>().ok()).product(); |
263 | /// assert_eq!(total, None); |
264 | /// ``` |
265 | fn product<I>(iter: I) -> Option<T> |
266 | where |
267 | I: Iterator<Item = Option<U>>, |
268 | { |
269 | iter::try_process(iter, |i| i.product()) |
270 | } |
271 | } |
272 | |