Revert the need for initial values with arithmetic iterators

This commit is contained in:
Brendan Zabarauskas 2014-11-14 15:35:44 +11:00
parent 064e84e30b
commit c9e6bda9c7
13 changed files with 69 additions and 38 deletions

View File

@ -228,7 +228,7 @@ impl Iterator<(uint, uint)> for ElementSwaps {
#[inline]
fn size_hint(&self) -> (uint, Option<uint>) {
// For a vector of size n, there are exactly n! permutations.
let n = range(2, self.sdir.len() + 1).product(1);
let n = range(2, self.sdir.len() + 1).product();
(n - self.swaps_made, Some(n - self.swaps_made))
}
}

View File

@ -116,7 +116,7 @@ impl<S: Str> StrVector for [S] {
}
// `len` calculation may overflow but push_str will check boundaries
let len = self.iter().map(|s| s.as_slice().len()).sum(0);
let len = self.iter().map(|s| s.as_slice().len()).sum();
let mut result = String::with_capacity(len);
@ -140,7 +140,7 @@ impl<S: Str> StrVector for [S] {
// this is wrong without the guarantee that `self` is non-empty
// `len` calculation may overflow but push_str but will check boundaries
let len = sep.len() * (self.len() - 1)
+ self.iter().map(|s| s.as_slice().len()).sum(0);
+ self.iter().map(|s| s.as_slice().len()).sum();
let mut result = String::with_capacity(len);
let mut first = true;
@ -2151,7 +2151,7 @@ mod tests {
#[test]
fn test_str_container() {
fn sum_len(v: &[&str]) -> uint {
v.iter().map(|x| x.len()).sum(0)
v.iter().map(|x| x.len()).sum()
}
let s = String::from_str("01234");

View File

@ -63,7 +63,7 @@ use cmp;
use cmp::Ord;
use mem;
use num::{ToPrimitive, Int};
use ops::{Add, Mul};
use ops::Add;
use option::{Option, Some, None};
use uint;
#[deprecated = "renamed to Extend"] pub use self::Extend as Extendable;
@ -402,7 +402,7 @@ pub trait Iterator<A> {
/// .inspect(|&x| println!("filtering {}", x))
/// .filter(|&x| x % 2 == 0)
/// .inspect(|&x| println!("{} made it through", x))
/// .sum(0);
/// .sum();
/// println!("{}", sum);
/// ```
#[inline]
@ -784,17 +784,33 @@ pub trait AdditiveIterator<A> {
///
/// let a = [1i, 2, 3, 4, 5];
/// let mut it = a.iter().map(|&x| x);
/// assert!(it.sum(0) == 15);
/// assert!(it.sum() == 15);
/// ```
fn sum(&mut self, init: A) -> A;
fn sum(&mut self) -> A;
}
impl<A: Add<A, A>, T: Iterator<A>> AdditiveIterator<A> for T {
#[inline]
fn sum(&mut self, init: A) -> A {
self.fold(init, |s, x| s + x)
}
macro_rules! impl_additive {
($A:ty, $init:expr) => {
impl<T: Iterator<$A>> AdditiveIterator<$A> for T {
#[inline]
fn sum(&mut self) -> $A {
self.fold($init, |acc, x| acc + x)
}
}
};
}
impl_additive!(i8, 0)
impl_additive!(i16, 0)
impl_additive!(i32, 0)
impl_additive!(i64, 0)
impl_additive!(int, 0)
impl_additive!(u8, 0)
impl_additive!(u16, 0)
impl_additive!(u32, 0)
impl_additive!(u64, 0)
impl_additive!(uint, 0)
impl_additive!(f32, 0.0)
impl_additive!(f64, 0.0)
/// A trait for iterators over elements which can be multiplied together.
pub trait MultiplicativeIterator<A> {
@ -806,21 +822,37 @@ pub trait MultiplicativeIterator<A> {
/// use std::iter::{count, MultiplicativeIterator};
///
/// fn factorial(n: uint) -> uint {
/// count(1u, 1).take_while(|&i| i <= n).product(1)
/// count(1u, 1).take_while(|&i| i <= n).product()
/// }
/// assert!(factorial(0) == 1);
/// assert!(factorial(1) == 1);
/// assert!(factorial(5) == 120);
/// ```
fn product(&mut self, init: A) -> A;
fn product(&mut self) -> A;
}
impl<A: Mul<A, A>, T: Iterator<A>> MultiplicativeIterator<A> for T {
#[inline]
fn product(&mut self, init: A) -> A {
self.fold(init, |p, x| p * x)
}
macro_rules! impl_multiplicative {
($A:ty, $init:expr) => {
impl<T: Iterator<$A>> MultiplicativeIterator<$A> for T {
#[inline]
fn product(&mut self) -> $A {
self.fold($init, |acc, x| acc * x)
}
}
};
}
impl_multiplicative!(i8, 1)
impl_multiplicative!(i16, 1)
impl_multiplicative!(i32, 1)
impl_multiplicative!(i64, 1)
impl_multiplicative!(int, 1)
impl_multiplicative!(u8, 1)
impl_multiplicative!(u16, 1)
impl_multiplicative!(u32, 1)
impl_multiplicative!(u64, 1)
impl_multiplicative!(uint, 1)
impl_multiplicative!(f32, 1.0)
impl_multiplicative!(f64, 1.0)
/// A trait for iterators over elements which can be compared to one another.
pub trait OrdIterator<A> {

View File

@ -294,17 +294,17 @@ fn test_iterator_len() {
#[test]
fn test_iterator_sum() {
let v: &[_] = &[0i, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
assert_eq!(v[0..4].iter().map(|&x| x).sum(0), 6);
assert_eq!(v.iter().map(|&x| x).sum(0), 55);
assert_eq!(v[0..0].iter().map(|&x| x).sum(0), 0);
assert_eq!(v[0..4].iter().map(|&x| x).sum(), 6);
assert_eq!(v.iter().map(|&x| x).sum(), 55);
assert_eq!(v[0..0].iter().map(|&x| x).sum(), 0);
}
#[test]
fn test_iterator_product() {
let v: &[_] = &[0i, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
assert_eq!(v[0..4].iter().map(|&x| x).product(1), 0);
assert_eq!(v[1..5].iter().map(|&x| x).product(1), 24);
assert_eq!(v[0..0].iter().map(|&x| x).product(1), 1);
assert_eq!(v[0..4].iter().map(|&x| x).product(), 0);
assert_eq!(v[1..5].iter().map(|&x| x).product(), 24);
assert_eq!(v[0..0].iter().map(|&x| x).product(), 1);
}
#[test]

View File

@ -70,7 +70,7 @@ impl<'a> fmt::Show for Matrix<'a> {
pretty_printed_matrix.iter().map(|row| row[col].len()).max().unwrap_or(0u)
}).collect();
let total_width = column_widths.iter().map(|n| *n).sum(0) + column_count * 3 + 1;
let total_width = column_widths.iter().map(|n| *n).sum() + column_count * 3 + 1;
let br = String::from_char(total_width, '+');
try!(write!(f, "{}\n", br));
for row in pretty_printed_matrix.into_iter() {

View File

@ -756,7 +756,7 @@ fn pick_column_to_specialize(def_map: &DefMap, m: &[Match]) -> Option<uint> {
let total_score = m.iter()
.map(|row| row.pats[col])
.map(|pat| pat_score(def_map, pat))
.sum(0);
.sum();
// Irrefutable columns always go first, they'd only be duplicated in the branches.
if total_score == 0 {

View File

@ -1194,7 +1194,7 @@ fn ty_of_method_or_bare_fn<'tcx, AC: AstConv<'tcx>>(
lifetimes_for_params.push((input_pat, accumulator));
}
if lifetimes_for_params.iter().map(|&(_, ref x)| x.len()).sum(0) == 1 {
if lifetimes_for_params.iter().map(|&(_, ref x)| x.len()).sum() == 1 {
implied_output_region =
Some(lifetimes_for_params.iter()
.filter_map(|&(_, ref x)|

View File

@ -15,7 +15,6 @@
use std::ops::Add;
use std::num::Zero;
use std::iter::AdditiveIterator;
use syntax::attr::{Deprecated, Experimental, Unstable, Stable, Frozen, Locked};
use syntax::ast::Public;
@ -152,14 +151,14 @@ fn summarize_item(item: &Item) -> (Counts, Option<ModuleSummary>) {
let subcounts = subitems.iter().filter(|i| visible(*i))
.map(summarize_item)
.map(|s| s.val0())
.sum(Counts::zero());
.fold(Counts::zero(), |acc, x| acc + x);
(item_counts + subcounts, None)
}
// `pub` automatically
EnumItem(Enum { variants: ref subitems, .. }) => {
let subcounts = subitems.iter().map(summarize_item)
.map(|s| s.val0())
.sum(Counts::zero());
.fold(Counts::zero(), |acc, x| acc + x);
(item_counts + subcounts, None)
}
TraitItem(Trait {
@ -177,7 +176,7 @@ fn summarize_item(item: &Item) -> (Counts, Option<ModuleSummary>) {
.map(extract_item)
.map(summarize_item)
.map(|s| s.val0())
.sum(Counts::zero());
.fold(Counts::zero(), |acc, x| acc + x);
(item_counts + subcounts, None)
}
ModuleItem(Module { ref items, .. }) => {

View File

@ -356,7 +356,7 @@ impl Path {
Some(vec![SEP_BYTE])
} else {
let n = if is_abs { comps.len() } else { comps.len() - 1} +
comps.iter().map(|v| v.len()).sum(0);
comps.iter().map(|v| v.len()).sum();
let mut v = Vec::with_capacity(n);
let mut it = comps.into_iter();
if !is_abs {

View File

@ -781,7 +781,7 @@ impl Path {
let prefix_ = s.slice_to(prefix_len(prefix));
let n = prefix_.len() +
if is_abs { comps.len() } else { comps.len() - 1} +
comps.iter().map(|v| v.len()).sum(0);
comps.iter().map(|v| v.len()).sum();
let mut s = String::with_capacity(n);
match prefix {
Some(DiskPrefix) => {

View File

@ -153,7 +153,7 @@ impl UnicodeStrPrelude for str {
#[inline]
fn width(&self, is_cjk: bool) -> uint {
self.chars().map(|c| c.width(is_cjk).unwrap_or(0)).sum(0)
self.chars().map(|c| c.width(is_cjk).unwrap_or(0)).sum()
}
#[inline]

View File

@ -105,7 +105,7 @@ fn A(i: uint, j: uint) -> f64 {
}
fn dot(v: &[f64], u: &[f64]) -> f64 {
v.iter().zip(u.iter()).map(|(a, b)| *a * *b).sum(0.0)
v.iter().zip(u.iter()).map(|(a, b)| *a * *b).sum()
}
// Executes a closure in parallel over the given mutable slice. The closure `f`

View File

@ -11,5 +11,5 @@
use std::iter::AdditiveIterator;
fn main() {
let x: [u64, ..3] = [1, 2, 3];
assert_eq!(6, range(0, 3).map(|i| x[i]).sum(0));
assert_eq!(6, range(0, 3).map(|i| x[i]).sum());
}