about summary refs log tree commit diff
path: root/src/libcore/iter/traits/mod.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/libcore/iter/traits/mod.rs')
-rw-r--r--src/libcore/iter/traits/mod.rs228
1 files changed, 2 insertions, 226 deletions
diff --git a/src/libcore/iter/traits/mod.rs b/src/libcore/iter/traits/mod.rs
index 093799d7bce..25637ef9f4e 100644
--- a/src/libcore/iter/traits/mod.rs
+++ b/src/libcore/iter/traits/mod.rs
@@ -1,238 +1,14 @@
-use ops::{Mul, Add};
-use num::Wrapping;
-
 mod iterator;
 mod double_ended;
 mod exact_size;
 mod collect;
+mod accum;
 
 pub use self::iterator::Iterator;
 pub use self::double_ended::DoubleEndedIterator;
 pub use self::exact_size::ExactSizeIterator;
 pub use self::collect::{FromIterator, IntoIterator, Extend};
-
-/// Trait to represent types that can be created by summing up an iterator.
-///
-/// This trait is used to implement the [`sum`] method on iterators. Types which
-/// implement the trait can be generated by the [`sum`] method. Like
-/// [`FromIterator`] this trait should rarely be called directly and instead
-/// interacted with through [`Iterator::sum`].
-///
-/// [`sum`]: ../../std/iter/trait.Sum.html#tymethod.sum
-/// [`FromIterator`]: ../../std/iter/trait.FromIterator.html
-/// [`Iterator::sum`]: ../../std/iter/trait.Iterator.html#method.sum
-#[stable(feature = "iter_arith_traits", since = "1.12.0")]
-pub trait Sum<A = Self>: Sized {
-    /// Method which takes an iterator and generates `Self` from the elements by
-    /// "summing up" the items.
-    #[stable(feature = "iter_arith_traits", since = "1.12.0")]
-    fn sum<I: Iterator<Item=A>>(iter: I) -> Self;
-}
-
-/// Trait to represent types that can be created by multiplying elements of an
-/// iterator.
-///
-/// This trait is used to implement the [`product`] method on iterators. Types
-/// which implement the trait can be generated by the [`product`] method. Like
-/// [`FromIterator`] this trait should rarely be called directly and instead
-/// interacted with through [`Iterator::product`].
-///
-/// [`product`]: ../../std/iter/trait.Product.html#tymethod.product
-/// [`FromIterator`]: ../../std/iter/trait.FromIterator.html
-/// [`Iterator::product`]: ../../std/iter/trait.Iterator.html#method.product
-#[stable(feature = "iter_arith_traits", since = "1.12.0")]
-pub trait Product<A = Self>: Sized {
-    /// Method which takes an iterator and generates `Self` from the elements by
-    /// multiplying the items.
-    #[stable(feature = "iter_arith_traits", since = "1.12.0")]
-    fn product<I: Iterator<Item=A>>(iter: I) -> Self;
-}
-
-// N.B., explicitly use Add and Mul here to inherit overflow checks
-macro_rules! integer_sum_product {
-    (@impls $zero:expr, $one:expr, #[$attr:meta], $($a:ty)*) => ($(
-        #[$attr]
-        impl Sum for $a {
-            fn sum<I: Iterator<Item=$a>>(iter: I) -> $a {
-                iter.fold($zero, Add::add)
-            }
-        }
-
-        #[$attr]
-        impl Product for $a {
-            fn product<I: Iterator<Item=$a>>(iter: I) -> $a {
-                iter.fold($one, Mul::mul)
-            }
-        }
-
-        #[$attr]
-        impl<'a> Sum<&'a $a> for $a {
-            fn sum<I: Iterator<Item=&'a $a>>(iter: I) -> $a {
-                iter.fold($zero, Add::add)
-            }
-        }
-
-        #[$attr]
-        impl<'a> Product<&'a $a> for $a {
-            fn product<I: Iterator<Item=&'a $a>>(iter: I) -> $a {
-                iter.fold($one, Mul::mul)
-            }
-        }
-    )*);
-    ($($a:ty)*) => (
-        integer_sum_product!(@impls 0, 1,
-                #[stable(feature = "iter_arith_traits", since = "1.12.0")],
-                $($a)+);
-        integer_sum_product!(@impls Wrapping(0), Wrapping(1),
-                #[stable(feature = "wrapping_iter_arith", since = "1.14.0")],
-                $(Wrapping<$a>)+);
-    );
-}
-
-macro_rules! float_sum_product {
-    ($($a:ident)*) => ($(
-        #[stable(feature = "iter_arith_traits", since = "1.12.0")]
-        impl Sum for $a {
-            fn sum<I: Iterator<Item=$a>>(iter: I) -> $a {
-                iter.fold(0.0, |a, b| a + b)
-            }
-        }
-
-        #[stable(feature = "iter_arith_traits", since = "1.12.0")]
-        impl Product for $a {
-            fn product<I: Iterator<Item=$a>>(iter: I) -> $a {
-                iter.fold(1.0, |a, b| a * b)
-            }
-        }
-
-        #[stable(feature = "iter_arith_traits", since = "1.12.0")]
-        impl<'a> Sum<&'a $a> for $a {
-            fn sum<I: Iterator<Item=&'a $a>>(iter: I) -> $a {
-                iter.fold(0.0, |a, b| a + *b)
-            }
-        }
-
-        #[stable(feature = "iter_arith_traits", since = "1.12.0")]
-        impl<'a> Product<&'a $a> for $a {
-            fn product<I: Iterator<Item=&'a $a>>(iter: I) -> $a {
-                iter.fold(1.0, |a, b| a * *b)
-            }
-        }
-    )*)
-}
-
-integer_sum_product! { i8 i16 i32 i64 i128 isize u8 u16 u32 u64 u128 usize }
-float_sum_product! { f32 f64 }
-
-/// An iterator adapter that produces output as long as the underlying
-/// iterator produces `Result::Ok` values.
-///
-/// If an error is encountered, the iterator stops and the error is
-/// stored. The error may be recovered later via `reconstruct`.
-struct ResultShunt<I, E> {
-    iter: I,
-    error: Option<E>,
-}
-
-impl<I, T, E> ResultShunt<I, E>
-    where I: Iterator<Item = Result<T, E>>
-{
-    /// Process the given iterator as if it yielded a `T` instead of a
-    /// `Result<T, _>`. Any errors will stop the inner iterator and
-    /// the overall result will be an error.
-    pub fn process<F, U>(iter: I, mut f: F) -> Result<U, E>
-        where F: FnMut(&mut Self) -> U
-    {
-        let mut shunt = ResultShunt::new(iter);
-        let value = f(shunt.by_ref());
-        shunt.reconstruct(value)
-    }
-
-    fn new(iter: I) -> Self {
-        ResultShunt {
-            iter,
-            error: None,
-        }
-    }
-
-    /// Consume the adapter and rebuild a `Result` value. This should
-    /// *always* be called, otherwise any potential error would be
-    /// lost.
-    fn reconstruct<U>(self, val: U) -> Result<U, E> {
-        match self.error {
-            None => Ok(val),
-            Some(e) => Err(e),
-        }
-    }
-}
-
-impl<I, T, E> Iterator for ResultShunt<I, E>
-    where I: Iterator<Item = Result<T, E>>
-{
-    type Item = T;
-
-    fn next(&mut self) -> Option<Self::Item> {
-        match self.iter.next() {
-            Some(Ok(v)) => Some(v),
-            Some(Err(e)) => {
-                self.error = Some(e);
-                None
-            }
-            None => None,
-        }
-    }
-
-    fn size_hint(&self) -> (usize, Option<usize>) {
-        if self.error.is_some() {
-            (0, Some(0))
-        } else {
-            let (_, upper) = self.iter.size_hint();
-            (0, upper)
-        }
-    }
-}
-
-#[stable(feature = "iter_arith_traits_result", since="1.16.0")]
-impl<T, U, E> Sum<Result<U, E>> for Result<T, E>
-    where T: Sum<U>,
-{
-    /// Takes each element in the `Iterator`: if it is an `Err`, no further
-    /// elements are taken, and the `Err` is returned. Should no `Err` occur,
-    /// the sum of all elements is returned.
-    ///
-    /// # Examples
-    ///
-    /// This sums up every integer in a vector, rejecting the sum if a negative
-    /// element is encountered:
-    ///
-    /// ```
-    /// let v = vec![1, 2];
-    /// let res: Result<i32, &'static str> = v.iter().map(|&x: &i32|
-    ///     if x < 0 { Err("Negative element found") }
-    ///     else { Ok(x) }
-    /// ).sum();
-    /// assert_eq!(res, Ok(3));
-    /// ```
-    fn sum<I>(iter: I) -> Result<T, E>
-        where I: Iterator<Item = Result<U, E>>,
-    {
-        ResultShunt::process(iter, |i| i.sum())
-    }
-}
-
-#[stable(feature = "iter_arith_traits_result", since="1.16.0")]
-impl<T, U, E> Product<Result<U, E>> for Result<T, E>
-    where T: Product<U>,
-{
-    /// Takes each element in the `Iterator`: if it is an `Err`, no further
-    /// elements are taken, and the `Err` is returned. Should no `Err` occur,
-    /// the product of all elements is returned.
-    fn product<I>(iter: I) -> Result<T, E>
-        where I: Iterator<Item = Result<U, E>>,
-    {
-        ResultShunt::process(iter, |i| i.product())
-    }
-}
+pub use self::accum::{Sum, Product};
 
 /// An iterator that always continues to yield `None` when exhausted.
 ///