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:
@@ -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)]
|
||||
|
||||
@@ -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",
|
||||
|
||||
Reference in New Issue
Block a user