Skip to content

Commit 515c878

Browse files
committed
Make AdditiveIterator and MultiplicativeIterator extensible
Previously it could not be implemented for types outside `libcore/iter.rs` due to coherence issues.
1 parent f899513 commit 515c878

File tree

2 files changed

+95
-39
lines changed

2 files changed

+95
-39
lines changed

src/libcore/iter.rs

+93-37
Original file line numberDiff line numberDiff line change
@@ -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

11591188
macro_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 }
11791207
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 }
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 }
12241280
impl_multiplicative! { usize, 1 }
12251281
impl_multiplicative! { f32, 1.0 }
12261282
impl_multiplicative! { f64, 1.0 }

src/libstd/sync/task_pool.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -156,7 +156,7 @@ mod test {
156156
for _ in 0..TEST_TASKS {
157157
let tx = tx.clone();
158158
pool.execute(move|| {
159-
tx.send(1).unwrap();
159+
tx.send(1us).unwrap();
160160
});
161161
}
162162

@@ -185,7 +185,7 @@ mod test {
185185
for _ in 0..TEST_TASKS {
186186
let tx = tx.clone();
187187
pool.execute(move|| {
188-
tx.send(1).unwrap();
188+
tx.send(1us).unwrap();
189189
});
190190
}
191191

0 commit comments

Comments
 (0)