@@ -1141,7 +1141,10 @@ impl<I> RandomAccessIterator for Rev<I> where I: DoubleEndedIterator + RandomAcc
11411141/// A trait for iterators over elements which can be added together
11421142#[ unstable( feature = "core" ,
11431143 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+
11451148 /// Iterates over the entire iterator, summing up all the elements
11461149 ///
11471150 /// # Examples
@@ -1153,37 +1156,65 @@ pub trait AdditiveIterator<A> {
11531156 /// let mut it = a.iter().cloned();
11541157 /// assert!(it.sum() == 15);
11551158 /// ```
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+ }
11571186}
11581187
11591188macro_rules! impl_additive {
1160- ( $A : ty, $init: expr) => {
1189+ ( $T : ty, $init: expr) => {
11611190 #[ 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 }
11671195 }
11681196 } ;
11691197}
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 }
11791207impl_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 }
11821210
11831211/// A trait for iterators over elements which can be multiplied together.
11841212#[ unstable( feature = "core" ,
11851213 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+
11871218 /// Iterates over the entire iterator, multiplying all the elements
11881219 ///
11891220 /// # Examples
@@ -1198,29 +1229,54 @@ pub trait MultiplicativeIterator<A> {
11981229 /// assert!(factorial(1) == 1);
11991230 /// assert!(factorial(5) == 120);
12001231 /// ```
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+ }
12021259}
12031260
1204- macro_rules! impl_multiplicative {
1205- ( $A : ty, $init: expr) => {
1261+ macro_rules! impl_multiplicative {
1262+ ( $T : ty, $init: expr) => {
12061263 #[ 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 }
12121268 }
12131269 } ;
12141270}
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 }
12241280impl_multiplicative ! { usize , 1 }
12251281impl_multiplicative ! { f32 , 1.0 }
12261282impl_multiplicative ! { f64 , 1.0 }
0 commit comments