@@ -1225,7 +1225,10 @@ impl<I> RandomAccessIterator for Rev<I>
1225
1225
/// A trait for iterators over elements which can be added together
1226
1226
#[ unstable( feature = "core" ,
1227
1227
reason = "needs to be re-evaluated as part of numerics reform" ) ]
1228
- pub trait AdditiveIterator < A > {
1228
+ pub trait AdditiveIterator {
1229
+ /// The result of summing over the iterator.
1230
+ type SumResult ;
1231
+
1229
1232
/// Iterates over the entire iterator, summing up all the elements
1230
1233
///
1231
1234
/// # Examples
@@ -1238,37 +1241,65 @@ pub trait AdditiveIterator<A> {
1238
1241
/// let mut it = a.iter().cloned();
1239
1242
/// assert!(it.sum() == 15);
1240
1243
/// ```
1241
- fn sum ( self ) -> A ;
1244
+ fn sum ( self ) -> Self :: SumResult ;
1245
+ }
1246
+
1247
+ /// The sum operation of an iterator's item type. Implementing this allows
1248
+ /// calling `.sum()` on the iterator.
1249
+ #[ unstable( feature = "core" , reason = "trait is experimental" ) ]
1250
+ pub trait AdditiveIteratorItem {
1251
+ /// The type of the intermediate sums.
1252
+ type SumResult ;
1253
+ /// The start value of the sum, usually something like `0`.
1254
+ fn start ( ) -> Self :: SumResult ;
1255
+ /// Adds another element of the iterator to the intermediate sum.
1256
+ fn combine ( self , other : Self :: SumResult ) -> Self :: SumResult ;
1257
+ }
1258
+
1259
+ #[ unstable( feature = "core" , reason = "trait is experimental" ) ]
1260
+ impl < I : Iterator > AdditiveIterator for I where
1261
+ <I as Iterator >:: Item : AdditiveIteratorItem
1262
+ {
1263
+ type SumResult = <<I as Iterator >:: Item as AdditiveIteratorItem >:: SumResult ;
1264
+ fn sum ( self ) -> <I as AdditiveIterator >:: SumResult {
1265
+ let mut sum = <<I as Iterator >:: Item as AdditiveIteratorItem >:: start ( ) ;
1266
+ for x in self {
1267
+ sum = x. combine ( sum) ;
1268
+ }
1269
+ sum
1270
+ }
1242
1271
}
1243
1272
1244
1273
macro_rules! impl_additive {
1245
- ( $A : ty, $init: expr) => {
1274
+ ( $T : ty, $init: expr) => {
1246
1275
#[ unstable( feature = "core" , reason = "trait is experimental" ) ]
1247
- impl <T : Iterator <Item =$A>> AdditiveIterator <$A> for T {
1248
- #[ inline]
1249
- fn sum( self ) -> $A {
1250
- self . fold( $init, |acc, x| acc + x)
1251
- }
1276
+ impl AdditiveIteratorItem for $T {
1277
+ type SumResult = $T;
1278
+ fn start( ) -> $T { $init }
1279
+ fn combine( self , other: $T) -> $T { self + other }
1252
1280
}
1253
1281
} ;
1254
1282
}
1255
- impl_additive ! { i8 , 0 }
1256
- impl_additive ! { i16 , 0 }
1257
- impl_additive ! { i32 , 0 }
1258
- impl_additive ! { i64 , 0 }
1259
- impl_additive ! { isize , 0 }
1260
- impl_additive ! { u8 , 0 }
1261
- impl_additive ! { u16 , 0 }
1262
- impl_additive ! { u32 , 0 }
1263
- impl_additive ! { u64 , 0 }
1283
+ impl_additive ! { i8 , 0 }
1284
+ impl_additive ! { i16 , 0 }
1285
+ impl_additive ! { i32 , 0 }
1286
+ impl_additive ! { i64 , 0 }
1287
+ impl_additive ! { isize , 0 }
1288
+ impl_additive ! { u8 , 0 }
1289
+ impl_additive ! { u16 , 0 }
1290
+ impl_additive ! { u32 , 0 }
1291
+ impl_additive ! { u64 , 0 }
1264
1292
impl_additive ! { usize , 0 }
1265
- impl_additive ! { f32 , 0.0 }
1266
- impl_additive ! { f64 , 0.0 }
1293
+ impl_additive ! { f32 , 0.0 }
1294
+ impl_additive ! { f64 , 0.0 }
1267
1295
1268
1296
/// A trait for iterators over elements which can be multiplied together.
1269
1297
#[ unstable( feature = "core" ,
1270
1298
reason = "needs to be re-evaluated as part of numerics reform" ) ]
1271
- pub trait MultiplicativeIterator < A > {
1299
+ pub trait MultiplicativeIterator {
1300
+ /// The result of multiplying the elements of the iterator.
1301
+ type ProductResult ;
1302
+
1272
1303
/// Iterates over the entire iterator, multiplying all the elements
1273
1304
///
1274
1305
/// # Examples
@@ -1284,29 +1315,54 @@ pub trait MultiplicativeIterator<A> {
1284
1315
/// assert!(factorial(1) == 1);
1285
1316
/// assert!(factorial(5) == 120);
1286
1317
/// ```
1287
- fn product ( self ) -> A ;
1318
+ fn product ( self ) -> Self :: ProductResult ;
1319
+ }
1320
+
1321
+ /// The product operation of an iterator's item type. Implementing this allows
1322
+ /// calling `.product()` on the iterator.
1323
+ #[ unstable( feature = "core" , reason = "trait is experimental" ) ]
1324
+ pub trait MultiplicativeIteratorItem {
1325
+ /// The type of the intermediate products.
1326
+ type ProductResult ;
1327
+ /// The start value of the product, usually something like `1`.
1328
+ fn start ( ) -> Self :: ProductResult ;
1329
+ /// Multiplies another element of the iterator to the intermediate product.
1330
+ fn combine ( self , other : Self :: ProductResult ) -> Self :: ProductResult ;
1288
1331
}
1289
1332
1290
- macro_rules! impl_multiplicative {
1291
- ( $A: ty, $init: expr) => {
1333
+ #[ unstable( feature = "core" , reason = "trait is experimental" ) ]
1334
+ impl < I : Iterator > MultiplicativeIterator for I where
1335
+ <I as Iterator >:: Item : MultiplicativeIteratorItem
1336
+ {
1337
+ type ProductResult = <<I as Iterator >:: Item as MultiplicativeIteratorItem >:: ProductResult ;
1338
+ fn product ( self ) -> <I as MultiplicativeIterator >:: ProductResult {
1339
+ let mut product = <<I as Iterator >:: Item as MultiplicativeIteratorItem >:: start ( ) ;
1340
+ for x in self {
1341
+ product = x. combine ( product) ;
1342
+ }
1343
+ product
1344
+ }
1345
+ }
1346
+
1347
+ macro_rules! impl_multiplicative {
1348
+ ( $T: ty, $init: expr) => {
1292
1349
#[ unstable( feature = "core" , reason = "trait is experimental" ) ]
1293
- impl <T : Iterator <Item =$A>> MultiplicativeIterator <$A> for T {
1294
- #[ inline]
1295
- fn product( self ) -> $A {
1296
- self . fold( $init, |acc, x| acc * x)
1297
- }
1350
+ impl MultiplicativeIteratorItem for $T {
1351
+ type ProductResult = $T;
1352
+ fn start( ) -> $T { $init }
1353
+ fn combine( self , other: $T) -> $T { self * other }
1298
1354
}
1299
1355
} ;
1300
1356
}
1301
- impl_multiplicative ! { i8 , 1 }
1302
- impl_multiplicative ! { i16 , 1 }
1303
- impl_multiplicative ! { i32 , 1 }
1304
- impl_multiplicative ! { i64 , 1 }
1305
- impl_multiplicative ! { isize , 1 }
1306
- impl_multiplicative ! { u8 , 1 }
1307
- impl_multiplicative ! { u16 , 1 }
1308
- impl_multiplicative ! { u32 , 1 }
1309
- impl_multiplicative ! { u64 , 1 }
1357
+ impl_multiplicative ! { i8 , 1 }
1358
+ impl_multiplicative ! { i16 , 1 }
1359
+ impl_multiplicative ! { i32 , 1 }
1360
+ impl_multiplicative ! { i64 , 1 }
1361
+ impl_multiplicative ! { isize , 1 }
1362
+ impl_multiplicative ! { u8 , 1 }
1363
+ impl_multiplicative ! { u16 , 1 }
1364
+ impl_multiplicative ! { u32 , 1 }
1365
+ impl_multiplicative ! { u64 , 1 }
1310
1366
impl_multiplicative ! { usize , 1 }
1311
1367
impl_multiplicative ! { f32 , 1.0 }
1312
1368
impl_multiplicative ! { f64 , 1.0 }
0 commit comments