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.
This commit is contained in:
bors
2015-04-08 00:42:10 +00:00
16 changed files with 89 additions and 133 deletions

View File

@@ -65,7 +65,7 @@ use default::Default;
use marker;
use mem;
use num::{Int, Zero, One};
use ops::{self, Add, Sub, FnMut, RangeFrom};
use ops::{self, Add, Sub, FnMut, Mul, RangeFrom};
use option::Option::{self, Some, None};
use marker::Sized;
use usize;
@@ -489,15 +489,14 @@ pub trait Iterator {
///
/// ```
/// # #![feature(core)]
/// use std::iter::AdditiveIterator;
///
/// let a = [1, 4, 2, 3, 8, 9, 6];
/// let sum = a.iter()
/// .map(|x| *x)
/// .inspect(|&x| println!("filtering {}", x))
/// .filter(|&x| x % 2 == 0)
/// .inspect(|&x| println!("{} made it through", x))
/// .sum();
/// let sum: i32 = a.iter()
/// .map(|x| *x)
/// .inspect(|&x| println!("filtering {}", x))
/// .filter(|&x| x % 2 == 0)
/// .inspect(|&x| println!("{} made it through", x))
/// .sum();
/// println!("{}", sum);
/// ```
#[inline]
@@ -1022,6 +1021,47 @@ pub trait Iterator {
}
}
}
/// Iterates over the entire iterator, summing up all the elements
///
/// # Examples
///
/// ```
/// # #![feature(core)]
///
/// let a = [1, 2, 3, 4, 5];
/// let mut it = a.iter().cloned();
/// assert!(it.sum::<i32>() == 15);
/// ```
#[unstable(feature="core")]
fn sum<S=<Self as Iterator>::Item>(self) -> S where
S: Add<Self::Item, Output=S> + Zero,
Self: Sized,
{
self.fold(Zero::zero(), |s, e| s + e)
}
/// Iterates over the entire iterator, multiplying all the elements
///
/// # Examples
///
/// ```
/// # #![feature(core)]
///
/// fn factorial(n: u32) -> u32 {
/// (1..).take_while(|&i| i <= n).product()
/// }
/// assert!(factorial(0) == 1);
/// assert!(factorial(1) == 1);
/// assert!(factorial(5) == 120);
/// ```
#[unstable(feature="core")]
fn product<P=<Self as Iterator>::Item>(self) -> P where
P: Mul<Self::Item, Output=P> + One,
Self: Sized,
{
self.fold(One::one(), |p, e| p * e)
}
}
#[stable(feature = "rust1", since = "1.0.0")]
@@ -1222,95 +1262,6 @@ impl<I> RandomAccessIterator for Rev<I>
}
}
/// A trait for iterators over elements which can be added together
#[unstable(feature = "core",
reason = "needs to be re-evaluated as part of numerics reform")]
pub trait AdditiveIterator<A> {
/// Iterates over the entire iterator, summing up all the elements
///
/// # Examples
///
/// ```
/// # #![feature(core)]
/// use std::iter::AdditiveIterator;
///
/// let a = [1, 2, 3, 4, 5];
/// let mut it = a.iter().cloned();
/// assert!(it.sum() == 15);
/// ```
fn sum(self) -> A;
}
macro_rules! impl_additive {
($A:ty, $init:expr) => {
#[unstable(feature = "core", reason = "trait is experimental")]
impl<T: Iterator<Item=$A>> AdditiveIterator<$A> for T {
#[inline]
fn sum(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! { isize, 0 }
impl_additive! { u8, 0 }
impl_additive! { u16, 0 }
impl_additive! { u32, 0 }
impl_additive! { u64, 0 }
impl_additive! { usize, 0 }
impl_additive! { f32, 0.0 }
impl_additive! { f64, 0.0 }
/// A trait for iterators over elements which can be multiplied together.
#[unstable(feature = "core",
reason = "needs to be re-evaluated as part of numerics reform")]
pub trait MultiplicativeIterator<A> {
/// Iterates over the entire iterator, multiplying all the elements
///
/// # Examples
///
/// ```
/// # #![feature(core)]
/// use std::iter::MultiplicativeIterator;
///
/// fn factorial(n: usize) -> usize {
/// (1..).take_while(|&i| i <= n).product()
/// }
/// assert!(factorial(0) == 1);
/// assert!(factorial(1) == 1);
/// assert!(factorial(5) == 120);
/// ```
fn product(self) -> A;
}
macro_rules! impl_multiplicative {
($A:ty, $init:expr) => {
#[unstable(feature = "core", reason = "trait is experimental")]
impl<T: Iterator<Item=$A>> MultiplicativeIterator<$A> for T {
#[inline]
fn product(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! { isize, 1 }
impl_multiplicative! { u8, 1 }
impl_multiplicative! { u16, 1 }
impl_multiplicative! { u32, 1 }
impl_multiplicative! { u64, 1 }
impl_multiplicative! { usize, 1 }
impl_multiplicative! { f32, 1.0 }
impl_multiplicative! { f64, 1.0 }
/// `MinMaxResult` is an enum returned by `min_max`. See `Iterator::min_max` for
/// more detail.
#[derive(Clone, PartialEq, Debug)]

View File

@@ -86,6 +86,20 @@ macro_rules! zero_one_impl {
}
zero_one_impl! { u8 u16 u32 u64 usize i8 i16 i32 i64 isize }
macro_rules! zero_one_impl_float {
($($t:ty)*) => ($(
impl Zero for $t {
#[inline]
fn zero() -> $t { 0.0 }
}
impl One for $t {
#[inline]
fn one() -> $t { 1.0 }
}
)*)
}
zero_one_impl_float! { f32 f64 }
/// A built-in signed or unsigned integer.
#[stable(feature = "rust1", since = "1.0.0")]
#[deprecated(since = "1.0.0",