@@ -1141,7 +1141,10 @@ impl<I> RandomAccessIterator for Rev<I> where I: DoubleEndedIterator + RandomAcc
1141
1141
/// A trait for iterators over elements which can be added together
1142
1142
#[ unstable( feature = "core" ,
1143
1143
reason = "needs to be re-evaluated as part of numerics reform" ) ]
1144
- pub trait AdditiveIterator < A > {
1144
+ pub trait AdditiveIterator {
1145
+ /// The result of summing over the iterator.
1146
+ type SumResult ;
1147
+
1145
1148
/// Iterates over the entire iterator, summing up all the elements
1146
1149
///
1147
1150
/// # Examples
@@ -1153,37 +1156,65 @@ pub trait AdditiveIterator<A> {
1153
1156
/// let mut it = a.iter().cloned();
1154
1157
/// assert!(it.sum() == 15);
1155
1158
/// ```
1156
- fn sum ( self ) -> A ;
1159
+ fn sum ( self ) -> Self :: SumResult ;
1160
+ }
1161
+
1162
+ /// The sum operation of an iterator's item type. Implementing this allows
1163
+ /// calling `.sum()` on the iterator.
1164
+ #[ unstable( feature = "core" , reason = "trait is experimental" ) ]
1165
+ pub trait AdditiveIteratorItem {
1166
+ /// The type of the intermediate sums.
1167
+ type SumResult ;
1168
+ /// The start value of the sum, usually something like `0`.
1169
+ fn start ( ) -> Self :: SumResult ;
1170
+ /// Adds another element of the iterator to the intermediate sum.
1171
+ fn combine ( self , other : Self :: SumResult ) -> Self :: SumResult ;
1172
+ }
1173
+
1174
+ #[ unstable( feature = "core" , reason = "trait is experimental" ) ]
1175
+ impl < I : Iterator > AdditiveIterator for I where
1176
+ <I as Iterator >:: Item : AdditiveIteratorItem
1177
+ {
1178
+ type SumResult = <<I as Iterator >:: Item as AdditiveIteratorItem >:: SumResult ;
1179
+ fn sum ( self ) -> <I as AdditiveIterator >:: SumResult {
1180
+ let mut sum = <<I as Iterator >:: Item as AdditiveIteratorItem >:: start ( ) ;
1181
+ for x in self {
1182
+ sum = x. combine ( sum) ;
1183
+ }
1184
+ sum
1185
+ }
1157
1186
}
1158
1187
1159
1188
macro_rules! impl_additive {
1160
- ( $A : ty, $init: expr) => {
1189
+ ( $T : ty, $init: expr) => {
1161
1190
#[ unstable( feature = "core" , reason = "trait is experimental" ) ]
1162
- impl <T : Iterator <Item =$A>> AdditiveIterator <$A> for T {
1163
- #[ inline]
1164
- fn sum( self ) -> $A {
1165
- self . fold( $init, |acc, x| acc + x)
1166
- }
1191
+ impl AdditiveIteratorItem for $T {
1192
+ type SumResult = $T;
1193
+ fn start( ) -> $T { $init }
1194
+ fn combine( self , other: $T) -> $T { self + other }
1167
1195
}
1168
1196
} ;
1169
1197
}
1170
- impl_additive ! { i8 , 0 }
1171
- impl_additive ! { i16 , 0 }
1172
- impl_additive ! { i32 , 0 }
1173
- impl_additive ! { i64 , 0 }
1174
- impl_additive ! { isize , 0 }
1175
- impl_additive ! { u8 , 0 }
1176
- impl_additive ! { u16 , 0 }
1177
- impl_additive ! { u32 , 0 }
1178
- impl_additive ! { u64 , 0 }
1198
+ impl_additive ! { i8 , 0 }
1199
+ impl_additive ! { i16 , 0 }
1200
+ impl_additive ! { i32 , 0 }
1201
+ impl_additive ! { i64 , 0 }
1202
+ impl_additive ! { isize , 0 }
1203
+ impl_additive ! { u8 , 0 }
1204
+ impl_additive ! { u16 , 0 }
1205
+ impl_additive ! { u32 , 0 }
1206
+ impl_additive ! { u64 , 0 }
1179
1207
impl_additive ! { usize , 0 }
1180
- impl_additive ! { f32 , 0.0 }
1181
- impl_additive ! { f64 , 0.0 }
1208
+ impl_additive ! { f32 , 0.0 }
1209
+ impl_additive ! { f64 , 0.0 }
1182
1210
1183
1211
/// A trait for iterators over elements which can be multiplied together.
1184
1212
#[ unstable( feature = "core" ,
1185
1213
reason = "needs to be re-evaluated as part of numerics reform" ) ]
1186
- pub trait MultiplicativeIterator < A > {
1214
+ pub trait MultiplicativeIterator {
1215
+ /// The result of multiplying the elements of the iterator.
1216
+ type ProductResult ;
1217
+
1187
1218
/// Iterates over the entire iterator, multiplying all the elements
1188
1219
///
1189
1220
/// # Examples
@@ -1198,29 +1229,54 @@ pub trait MultiplicativeIterator<A> {
1198
1229
/// assert!(factorial(1) == 1);
1199
1230
/// assert!(factorial(5) == 120);
1200
1231
/// ```
1201
- fn product ( self ) -> A ;
1232
+ fn product ( self ) -> Self :: ProductResult ;
1233
+ }
1234
+
1235
+ /// The product operation of an iterator's item type. Implementing this allows
1236
+ /// calling `.product()` on the iterator.
1237
+ #[ unstable( feature = "core" , reason = "trait is experimental" ) ]
1238
+ pub trait MultiplicativeIteratorItem {
1239
+ /// The type of the intermediate products.
1240
+ type ProductResult ;
1241
+ /// The start value of the product, usually something like `1`.
1242
+ fn start ( ) -> Self :: ProductResult ;
1243
+ /// Multiplies another element of the iterator to the intermediate product.
1244
+ fn combine ( self , other : Self :: ProductResult ) -> Self :: ProductResult ;
1245
+ }
1246
+
1247
+ #[ unstable( feature = "core" , reason = "trait is experimental" ) ]
1248
+ impl < I : Iterator > MultiplicativeIterator for I where
1249
+ <I as Iterator >:: Item : MultiplicativeIteratorItem
1250
+ {
1251
+ type ProductResult = <<I as Iterator >:: Item as MultiplicativeIteratorItem >:: ProductResult ;
1252
+ fn product ( self ) -> <I as MultiplicativeIterator >:: ProductResult {
1253
+ let mut product = <<I as Iterator >:: Item as MultiplicativeIteratorItem >:: start ( ) ;
1254
+ for x in self {
1255
+ product = x. combine ( product) ;
1256
+ }
1257
+ product
1258
+ }
1202
1259
}
1203
1260
1204
- macro_rules! impl_multiplicative {
1205
- ( $A : ty, $init: expr) => {
1261
+ macro_rules! impl_multiplicative {
1262
+ ( $T : ty, $init: expr) => {
1206
1263
#[ unstable( feature = "core" , reason = "trait is experimental" ) ]
1207
- impl <T : Iterator <Item =$A>> MultiplicativeIterator <$A> for T {
1208
- #[ inline]
1209
- fn product( self ) -> $A {
1210
- self . fold( $init, |acc, x| acc * x)
1211
- }
1264
+ impl MultiplicativeIteratorItem for $T {
1265
+ type ProductResult = $T;
1266
+ fn start( ) -> $T { $init }
1267
+ fn combine( self , other: $T) -> $T { self * other }
1212
1268
}
1213
1269
} ;
1214
1270
}
1215
- impl_multiplicative ! { i8 , 1 }
1216
- impl_multiplicative ! { i16 , 1 }
1217
- impl_multiplicative ! { i32 , 1 }
1218
- impl_multiplicative ! { i64 , 1 }
1219
- impl_multiplicative ! { isize , 1 }
1220
- impl_multiplicative ! { u8 , 1 }
1221
- impl_multiplicative ! { u16 , 1 }
1222
- impl_multiplicative ! { u32 , 1 }
1223
- impl_multiplicative ! { u64 , 1 }
1271
+ impl_multiplicative ! { i8 , 1 }
1272
+ impl_multiplicative ! { i16 , 1 }
1273
+ impl_multiplicative ! { i32 , 1 }
1274
+ impl_multiplicative ! { i64 , 1 }
1275
+ impl_multiplicative ! { isize , 1 }
1276
+ impl_multiplicative ! { u8 , 1 }
1277
+ impl_multiplicative ! { u16 , 1 }
1278
+ impl_multiplicative ! { u32 , 1 }
1279
+ impl_multiplicative ! { u64 , 1 }
1224
1280
impl_multiplicative ! { usize , 1 }
1225
1281
impl_multiplicative ! { f32 , 1.0 }
1226
1282
impl_multiplicative ! { f64 , 1.0 }
0 commit comments