Skip to content

Commit dd6c4a8

Browse files
committed
Auto merge of #23293 - tbu-:pr_additive_multiplicative, r=alexcrichton
Previously it could not be implemented for types outside `libcore/iter.rs` due to coherence issues.
2 parents d9146bf + 97f24a8 commit dd6c4a8

File tree

16 files changed

+89
-133
lines changed

16 files changed

+89
-133
lines changed

Diff for: src/libcollections/slice.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,6 @@ use core::clone::Clone;
8585
use core::cmp::Ordering::{self, Greater, Less};
8686
use core::cmp::{self, Ord, PartialEq};
8787
use core::iter::Iterator;
88-
use core::iter::MultiplicativeIterator;
8988
use core::marker::Sized;
9089
use core::mem::size_of;
9190
use core::mem;
@@ -1182,7 +1181,7 @@ impl Iterator for ElementSwaps {
11821181
#[inline]
11831182
fn size_hint(&self) -> (usize, Option<usize>) {
11841183
// For a vector of size n, there are exactly n! permutations.
1185-
let n = (2..self.sdir.len() + 1).product();
1184+
let n: usize = (2..self.sdir.len() + 1).product();
11861185
(n - self.swaps_made, Some(n - self.swaps_made))
11871186
}
11881187
}

Diff for: src/libcollections/str.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,6 @@ use self::RecompositionState::*;
5353
use self::DecompositionType::*;
5454

5555
use core::clone::Clone;
56-
use core::iter::AdditiveIterator;
5756
use core::iter::{Iterator, Extend};
5857
use core::option::Option::{self, Some, None};
5958
use core::result::Result;
@@ -116,7 +115,7 @@ impl<S: AsRef<str>> SliceConcatExt<str, String> for [S] {
116115
// this is wrong without the guarantee that `self` is non-empty
117116
// `len` calculation may overflow but push_str but will check boundaries
118117
let len = sep.len() * (self.len() - 1)
119-
+ self.iter().map(|s| s.as_ref().len()).sum();
118+
+ self.iter().map(|s| s.as_ref().len()).sum::<usize>();
120119
let mut result = String::with_capacity(len);
121120
let mut first = true;
122121

Diff for: src/libcollectionstest/str.rs

-1
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@
99
// except according to those terms.
1010

1111
use std::cmp::Ordering::{Equal, Greater, Less};
12-
use std::iter::AdditiveIterator;
1312
use std::str::{Utf8Error, from_utf8};
1413

1514
#[test]

Diff for: src/libcore/iter.rs

+48-97
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ use default::Default;
6565
use marker;
6666
use mem;
6767
use num::{Int, Zero, One};
68-
use ops::{self, Add, Sub, FnMut, RangeFrom};
68+
use ops::{self, Add, Sub, FnMut, Mul, RangeFrom};
6969
use option::Option::{self, Some, None};
7070
use marker::Sized;
7171
use usize;
@@ -489,15 +489,14 @@ pub trait Iterator {
489489
///
490490
/// ```
491491
/// # #![feature(core)]
492-
/// use std::iter::AdditiveIterator;
493492
///
494493
/// let a = [1, 4, 2, 3, 8, 9, 6];
495-
/// let sum = a.iter()
496-
/// .map(|x| *x)
497-
/// .inspect(|&x| println!("filtering {}", x))
498-
/// .filter(|&x| x % 2 == 0)
499-
/// .inspect(|&x| println!("{} made it through", x))
500-
/// .sum();
494+
/// let sum: i32 = a.iter()
495+
/// .map(|x| *x)
496+
/// .inspect(|&x| println!("filtering {}", x))
497+
/// .filter(|&x| x % 2 == 0)
498+
/// .inspect(|&x| println!("{} made it through", x))
499+
/// .sum();
501500
/// println!("{}", sum);
502501
/// ```
503502
#[inline]
@@ -1022,6 +1021,47 @@ pub trait Iterator {
10221021
}
10231022
}
10241023
}
1024+
1025+
/// Iterates over the entire iterator, summing up all the elements
1026+
///
1027+
/// # Examples
1028+
///
1029+
/// ```
1030+
/// # #![feature(core)]
1031+
///
1032+
/// let a = [1, 2, 3, 4, 5];
1033+
/// let mut it = a.iter().cloned();
1034+
/// assert!(it.sum::<i32>() == 15);
1035+
/// ```
1036+
#[unstable(feature="core")]
1037+
fn sum<S=<Self as Iterator>::Item>(self) -> S where
1038+
S: Add<Self::Item, Output=S> + Zero,
1039+
Self: Sized,
1040+
{
1041+
self.fold(Zero::zero(), |s, e| s + e)
1042+
}
1043+
1044+
/// Iterates over the entire iterator, multiplying all the elements
1045+
///
1046+
/// # Examples
1047+
///
1048+
/// ```
1049+
/// # #![feature(core)]
1050+
///
1051+
/// fn factorial(n: u32) -> u32 {
1052+
/// (1..).take_while(|&i| i <= n).product()
1053+
/// }
1054+
/// assert!(factorial(0) == 1);
1055+
/// assert!(factorial(1) == 1);
1056+
/// assert!(factorial(5) == 120);
1057+
/// ```
1058+
#[unstable(feature="core")]
1059+
fn product<P=<Self as Iterator>::Item>(self) -> P where
1060+
P: Mul<Self::Item, Output=P> + One,
1061+
Self: Sized,
1062+
{
1063+
self.fold(One::one(), |p, e| p * e)
1064+
}
10251065
}
10261066

10271067
#[stable(feature = "rust1", since = "1.0.0")]
@@ -1222,95 +1262,6 @@ impl<I> RandomAccessIterator for Rev<I>
12221262
}
12231263
}
12241264

1225-
/// A trait for iterators over elements which can be added together
1226-
#[unstable(feature = "core",
1227-
reason = "needs to be re-evaluated as part of numerics reform")]
1228-
pub trait AdditiveIterator<A> {
1229-
/// Iterates over the entire iterator, summing up all the elements
1230-
///
1231-
/// # Examples
1232-
///
1233-
/// ```
1234-
/// # #![feature(core)]
1235-
/// use std::iter::AdditiveIterator;
1236-
///
1237-
/// let a = [1, 2, 3, 4, 5];
1238-
/// let mut it = a.iter().cloned();
1239-
/// assert!(it.sum() == 15);
1240-
/// ```
1241-
fn sum(self) -> A;
1242-
}
1243-
1244-
macro_rules! impl_additive {
1245-
($A:ty, $init:expr) => {
1246-
#[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-
}
1252-
}
1253-
};
1254-
}
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 }
1264-
impl_additive! { usize, 0 }
1265-
impl_additive! { f32, 0.0 }
1266-
impl_additive! { f64, 0.0 }
1267-
1268-
/// A trait for iterators over elements which can be multiplied together.
1269-
#[unstable(feature = "core",
1270-
reason = "needs to be re-evaluated as part of numerics reform")]
1271-
pub trait MultiplicativeIterator<A> {
1272-
/// Iterates over the entire iterator, multiplying all the elements
1273-
///
1274-
/// # Examples
1275-
///
1276-
/// ```
1277-
/// # #![feature(core)]
1278-
/// use std::iter::MultiplicativeIterator;
1279-
///
1280-
/// fn factorial(n: usize) -> usize {
1281-
/// (1..).take_while(|&i| i <= n).product()
1282-
/// }
1283-
/// assert!(factorial(0) == 1);
1284-
/// assert!(factorial(1) == 1);
1285-
/// assert!(factorial(5) == 120);
1286-
/// ```
1287-
fn product(self) -> A;
1288-
}
1289-
1290-
macro_rules! impl_multiplicative {
1291-
($A:ty, $init:expr) => {
1292-
#[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-
}
1298-
}
1299-
};
1300-
}
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 }
1310-
impl_multiplicative! { usize, 1 }
1311-
impl_multiplicative! { f32, 1.0 }
1312-
impl_multiplicative! { f64, 1.0 }
1313-
13141265
/// `MinMaxResult` is an enum returned by `min_max`. See `Iterator::min_max` for
13151266
/// more detail.
13161267
#[derive(Clone, PartialEq, Debug)]

Diff for: src/libcore/num/mod.rs

+14
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,20 @@ macro_rules! zero_one_impl {
8686
}
8787
zero_one_impl! { u8 u16 u32 u64 usize i8 i16 i32 i64 isize }
8888

89+
macro_rules! zero_one_impl_float {
90+
($($t:ty)*) => ($(
91+
impl Zero for $t {
92+
#[inline]
93+
fn zero() -> $t { 0.0 }
94+
}
95+
impl One for $t {
96+
#[inline]
97+
fn one() -> $t { 1.0 }
98+
}
99+
)*)
100+
}
101+
zero_one_impl_float! { f32 f64 }
102+
89103
/// A built-in signed or unsigned integer.
90104
#[stable(feature = "rust1", since = "1.0.0")]
91105
#[deprecated(since = "1.0.0",

Diff for: src/libcoretest/iter.rs

+6-6
Original file line numberDiff line numberDiff line change
@@ -329,17 +329,17 @@ fn test_iterator_len() {
329329
#[test]
330330
fn test_iterator_sum() {
331331
let v: &[i32] = &[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
332-
assert_eq!(v[..4].iter().cloned().sum(), 6);
333-
assert_eq!(v.iter().cloned().sum(), 55);
334-
assert_eq!(v[..0].iter().cloned().sum(), 0);
332+
assert_eq!(v[..4].iter().cloned().sum::<i32>(), 6);
333+
assert_eq!(v.iter().cloned().sum::<i32>(), 55);
334+
assert_eq!(v[..0].iter().cloned().sum::<i32>(), 0);
335335
}
336336

337337
#[test]
338338
fn test_iterator_product() {
339339
let v: &[i32] = &[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
340-
assert_eq!(v[..4].iter().cloned().product(), 0);
341-
assert_eq!(v[1..5].iter().cloned().product(), 24);
342-
assert_eq!(v[..0].iter().cloned().product(), 1);
340+
assert_eq!(v[..4].iter().cloned().product::<i32>(), 0);
341+
assert_eq!(v[1..5].iter().cloned().product::<i32>(), 24);
342+
assert_eq!(v[..0].iter().cloned().product::<i32>(), 1);
343343
}
344344

345345
#[test]

Diff for: src/librustc/middle/check_match.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ use middle::ty::*;
2626
use middle::ty;
2727
use std::cmp::Ordering;
2828
use std::fmt;
29-
use std::iter::{range_inclusive, AdditiveIterator, FromIterator, IntoIterator, repeat};
29+
use std::iter::{range_inclusive, FromIterator, IntoIterator, repeat};
3030
use std::slice;
3131
use syntax::ast::{self, DUMMY_NODE_ID, NodeId, Pat};
3232
use syntax::ast_util;
@@ -76,7 +76,7 @@ impl<'a> fmt::Debug for Matrix<'a> {
7676
pretty_printed_matrix.iter().map(|row| row[col].len()).max().unwrap_or(0)
7777
}).collect();
7878

79-
let total_width = column_widths.iter().cloned().sum() + column_count * 3 + 1;
79+
let total_width = column_widths.iter().cloned().sum::<usize>() + column_count * 3 + 1;
8080
let br = repeat('+').take(total_width).collect::<String>();
8181
try!(write!(f, "{}\n", br));
8282
for row in pretty_printed_matrix {

Diff for: src/librustc_trans/trans/_match.rs

-1
Original file line numberDiff line numberDiff line change
@@ -220,7 +220,6 @@ use util::ppaux::{Repr, vec_map_to_string};
220220

221221
use std;
222222
use std::cmp::Ordering;
223-
use std::iter::AdditiveIterator;
224223
use std::rc::Rc;
225224
use syntax::ast;
226225
use syntax::ast::{DUMMY_NODE_ID, NodeId};

Diff for: src/librustc_typeck/astconv.rs

+8-7
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ use rscope::{self, UnelidableRscope, RegionScope, ElidableRscope,
6161
use util::common::{ErrorReported, FN_OUTPUT_NAME};
6262
use util::ppaux::{self, Repr, UserString};
6363

64-
use std::iter::{repeat, AdditiveIterator};
64+
use std::iter::repeat;
6565
use std::rc::Rc;
6666
use std::slice;
6767
use syntax::{abi, ast, ast_util};
@@ -517,12 +517,13 @@ fn find_implied_output_region(input_tys: &[Ty], input_pats: Vec<String>)
517517
lifetimes_for_params.push((input_pat, accumulator.len()));
518518
}
519519

520-
let implied_output_region = if lifetimes_for_params.iter().map(|&(_, n)| n).sum() == 1 {
521-
assert!(possible_implied_output_region.is_some());
522-
possible_implied_output_region
523-
} else {
524-
None
525-
};
520+
let implied_output_region =
521+
if lifetimes_for_params.iter().map(|&(_, n)| n).sum::<usize>() == 1 {
522+
assert!(possible_implied_output_region.is_some());
523+
possible_implied_output_region
524+
} else {
525+
None
526+
};
526527
(implied_output_region, lifetimes_for_params)
527528
}
528529

Diff for: src/libstd/old_path/posix.rs

+2-3
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,7 @@ use cmp::{Ordering, Eq, Ord, PartialEq, PartialOrd};
1515
use fmt;
1616
use hash;
1717
use old_io::Writer;
18-
use iter::{AdditiveIterator, Extend};
19-
use iter::{Iterator, Map};
18+
use iter::{Extend, Iterator, Map};
2019
use marker::Sized;
2120
use option::Option::{self, Some, None};
2221
use result::Result::{self, Ok, Err};
@@ -351,7 +350,7 @@ impl Path {
351350
Some(vec![SEP_BYTE])
352351
} else {
353352
let n = if is_abs { comps.len() } else { comps.len() - 1} +
354-
comps.iter().map(|v| v.len()).sum();
353+
comps.iter().map(|v| v.len()).sum::<usize>();
355354
let mut v = Vec::with_capacity(n);
356355
let mut it = comps.into_iter();
357356
if !is_abs {

Diff for: src/libstd/old_path/windows.rs

+2-3
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,7 @@ use cmp::{Ordering, Eq, Ord, PartialEq, PartialOrd};
2020
use fmt;
2121
use hash;
2222
use old_io::Writer;
23-
use iter::{AdditiveIterator, Extend};
24-
use iter::{Iterator, Map, repeat};
23+
use iter::{Extend, Iterator, Map, repeat};
2524
use mem;
2625
use option::Option::{self, Some, None};
2726
use result::Result::{self, Ok, Err};
@@ -785,7 +784,7 @@ impl Path {
785784
let prefix_ = &s[..prefix_len(prefix)];
786785
let n = prefix_.len() +
787786
if is_abs { comps.len() } else { comps.len() - 1} +
788-
comps.iter().map(|v| v.len()).sum();
787+
comps.iter().map(|v| v.len()).sum::<usize>();
789788
let mut s = String::with_capacity(n);
790789
match prefix {
791790
Some(DiskPrefix) => {

Diff for: src/libunicode/u_str.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ use core::prelude::*;
2020

2121
use core::char;
2222
use core::cmp;
23-
use core::iter::{Filter, AdditiveIterator};
23+
use core::iter::Filter;
2424
use core::mem;
2525
use core::slice;
2626
use core::str::Split;

Diff for: src/rustbook/book.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@
1313
use std::io::prelude::*;
1414
use std::io::BufReader;
1515
use std::iter;
16-
use std::iter::AdditiveIterator;
1716
use std::path::{Path, PathBuf};
1817

1918
pub struct BookItem {
@@ -151,7 +150,7 @@ pub fn parse_summary(input: &mut Read, src: &Path) -> Result<Book, Vec<String>>
151150
'\t' => 4,
152151
_ => unreachable!()
153152
}
154-
}).sum() / 4 + 1;
153+
}).sum::<usize>() / 4 + 1;
155154

156155
if level > stack.len() + 1 {
157156
errors.push(format!("section '{}' is indented too deeply; \

Diff for: src/test/bench/shootout-spectralnorm.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@
4343
#![allow(non_snake_case)]
4444
#![feature(unboxed_closures, core, os)]
4545

46-
use std::iter::{repeat, AdditiveIterator};
46+
use std::iter::repeat;
4747
use std::thread;
4848
use std::mem;
4949
use std::num::Float;

Diff for: src/test/run-pass/issue-15673.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,7 @@
1212

1313
#![feature(core)]
1414

15-
use std::iter::AdditiveIterator;
1615
fn main() {
1716
let x: [u64; 3] = [1, 2, 3];
18-
assert_eq!(6, (0..3).map(|i| x[i]).sum());
17+
assert_eq!(6, (0..3).map(|i| x[i]).sum::<u64>());
1918
}

0 commit comments

Comments
 (0)