about summary refs log tree commit diff
diff options
context:
space:
mode:
authorClar Fon <them@lightdark.xyz>2018-12-17 20:24:52 -0500
committerClar Fon <them@lightdark.xyz>2019-01-22 17:45:11 -0500
commitfb974df28157f205f81d59ab3fc9cb96d78bf590 (patch)
tree3c53db70ad0f106eb5c5032ec406f6f1cda86dce
parentebfd08312522b85a5b4085aa0a2bf6fb9b9873d7 (diff)
downloadrust-fb974df28157f205f81d59ab3fc9cb96d78bf590.tar.gz
rust-fb974df28157f205f81d59ab3fc9cb96d78bf590.zip
Move Flatten and FlatMap to own module
-rw-r--r--src/libcore/iter/adapters/flatten.rs318
-rw-r--r--src/libcore/iter/adapters/mod.rs316
2 files changed, 321 insertions, 313 deletions
diff --git a/src/libcore/iter/adapters/flatten.rs b/src/libcore/iter/adapters/flatten.rs
new file mode 100644
index 00000000000..b88e91fad3b
--- /dev/null
+++ b/src/libcore/iter/adapters/flatten.rs
@@ -0,0 +1,318 @@
+use fmt;
+use ops::Try;
+use super::super::{Iterator, DoubleEndedIterator, FusedIterator};
+use super::Map;
+
+/// An iterator that maps each element to an iterator, and yields the elements
+/// of the produced iterators.
+///
+/// This `struct` is created by the [`flat_map`] method on [`Iterator`]. See its
+/// documentation for more.
+///
+/// [`flat_map`]: trait.Iterator.html#method.flat_map
+/// [`Iterator`]: trait.Iterator.html
+#[must_use = "iterators are lazy and do nothing unless consumed"]
+#[stable(feature = "rust1", since = "1.0.0")]
+pub struct FlatMap<I, U: IntoIterator, F> {
+    pub(in super::super) inner: FlattenCompat<Map<I, F>, <U as IntoIterator>::IntoIter>
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<I: Clone, U: Clone + IntoIterator, F: Clone> Clone for FlatMap<I, U, F>
+    where <U as IntoIterator>::IntoIter: Clone
+{
+    fn clone(&self) -> Self { FlatMap { inner: self.inner.clone() } }
+}
+
+#[stable(feature = "core_impl_debug", since = "1.9.0")]
+impl<I: fmt::Debug, U: IntoIterator, F> fmt::Debug for FlatMap<I, U, F>
+    where U::IntoIter: fmt::Debug
+{
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        f.debug_struct("FlatMap").field("inner", &self.inner).finish()
+    }
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<I: Iterator, U: IntoIterator, F> Iterator for FlatMap<I, U, F>
+    where F: FnMut(I::Item) -> U,
+{
+    type Item = U::Item;
+
+    #[inline]
+    fn next(&mut self) -> Option<U::Item> { self.inner.next() }
+
+    #[inline]
+    fn size_hint(&self) -> (usize, Option<usize>) { self.inner.size_hint() }
+
+    #[inline]
+    fn try_fold<Acc, Fold, R>(&mut self, init: Acc, fold: Fold) -> R where
+        Self: Sized, Fold: FnMut(Acc, Self::Item) -> R, R: Try<Ok=Acc>
+    {
+        self.inner.try_fold(init, fold)
+    }
+
+    #[inline]
+    fn fold<Acc, Fold>(self, init: Acc, fold: Fold) -> Acc
+        where Fold: FnMut(Acc, Self::Item) -> Acc,
+    {
+        self.inner.fold(init, fold)
+    }
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<I: DoubleEndedIterator, U, F> DoubleEndedIterator for FlatMap<I, U, F>
+    where F: FnMut(I::Item) -> U,
+          U: IntoIterator,
+          U::IntoIter: DoubleEndedIterator
+{
+    #[inline]
+    fn next_back(&mut self) -> Option<U::Item> { self.inner.next_back() }
+
+    #[inline]
+    fn try_rfold<Acc, Fold, R>(&mut self, init: Acc, fold: Fold) -> R where
+        Self: Sized, Fold: FnMut(Acc, Self::Item) -> R, R: Try<Ok=Acc>
+    {
+        self.inner.try_rfold(init, fold)
+    }
+
+    #[inline]
+    fn rfold<Acc, Fold>(self, init: Acc, fold: Fold) -> Acc
+        where Fold: FnMut(Acc, Self::Item) -> Acc,
+    {
+        self.inner.rfold(init, fold)
+    }
+}
+
+#[stable(feature = "fused", since = "1.26.0")]
+impl<I, U, F> FusedIterator for FlatMap<I, U, F>
+    where I: FusedIterator, U: IntoIterator, F: FnMut(I::Item) -> U {}
+
+/// An iterator that flattens one level of nesting in an iterator of things
+/// that can be turned into iterators.
+///
+/// This `struct` is created by the [`flatten`] method on [`Iterator`]. See its
+/// documentation for more.
+///
+/// [`flatten`]: trait.Iterator.html#method.flatten
+/// [`Iterator`]: trait.Iterator.html
+#[must_use = "iterators are lazy and do nothing unless consumed"]
+#[stable(feature = "iterator_flatten", since = "1.29.0")]
+pub struct Flatten<I: Iterator>
+where I::Item: IntoIterator {
+    pub(in super::super) inner: FlattenCompat<I, <I::Item as IntoIterator>::IntoIter>,
+}
+
+#[stable(feature = "iterator_flatten", since = "1.29.0")]
+impl<I, U> fmt::Debug for Flatten<I>
+    where I: Iterator + fmt::Debug, U: Iterator + fmt::Debug,
+          I::Item: IntoIterator<IntoIter = U, Item = U::Item>,
+{
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        f.debug_struct("Flatten").field("inner", &self.inner).finish()
+    }
+}
+
+#[stable(feature = "iterator_flatten", since = "1.29.0")]
+impl<I, U> Clone for Flatten<I>
+    where I: Iterator + Clone, U: Iterator + Clone,
+          I::Item: IntoIterator<IntoIter = U, Item = U::Item>,
+{
+    fn clone(&self) -> Self { Flatten { inner: self.inner.clone() } }
+}
+
+#[stable(feature = "iterator_flatten", since = "1.29.0")]
+impl<I, U> Iterator for Flatten<I>
+    where I: Iterator, U: Iterator,
+          I::Item: IntoIterator<IntoIter = U, Item = U::Item>
+{
+    type Item = U::Item;
+
+    #[inline]
+    fn next(&mut self) -> Option<U::Item> { self.inner.next() }
+
+    #[inline]
+    fn size_hint(&self) -> (usize, Option<usize>) { self.inner.size_hint() }
+
+    #[inline]
+    fn try_fold<Acc, Fold, R>(&mut self, init: Acc, fold: Fold) -> R where
+        Self: Sized, Fold: FnMut(Acc, Self::Item) -> R, R: Try<Ok=Acc>
+    {
+        self.inner.try_fold(init, fold)
+    }
+
+    #[inline]
+    fn fold<Acc, Fold>(self, init: Acc, fold: Fold) -> Acc
+        where Fold: FnMut(Acc, Self::Item) -> Acc,
+    {
+        self.inner.fold(init, fold)
+    }
+}
+
+#[stable(feature = "iterator_flatten", since = "1.29.0")]
+impl<I, U> DoubleEndedIterator for Flatten<I>
+    where I: DoubleEndedIterator, U: DoubleEndedIterator,
+          I::Item: IntoIterator<IntoIter = U, Item = U::Item>
+{
+    #[inline]
+    fn next_back(&mut self) -> Option<U::Item> { self.inner.next_back() }
+
+    #[inline]
+    fn try_rfold<Acc, Fold, R>(&mut self, init: Acc, fold: Fold) -> R where
+        Self: Sized, Fold: FnMut(Acc, Self::Item) -> R, R: Try<Ok=Acc>
+    {
+        self.inner.try_rfold(init, fold)
+    }
+
+    #[inline]
+    fn rfold<Acc, Fold>(self, init: Acc, fold: Fold) -> Acc
+        where Fold: FnMut(Acc, Self::Item) -> Acc,
+    {
+        self.inner.rfold(init, fold)
+    }
+}
+
+#[stable(feature = "iterator_flatten", since = "1.29.0")]
+impl<I, U> FusedIterator for Flatten<I>
+    where I: FusedIterator, U: Iterator,
+          I::Item: IntoIterator<IntoIter = U, Item = U::Item> {}
+
+/// Adapts an iterator by flattening it, for use in `flatten()` and `flat_map()`.
+pub(in super::super) fn flatten_compat<I, U>(iter: I) -> FlattenCompat<I, U> {
+    FlattenCompat { iter, frontiter: None, backiter: None }
+}
+
+/// Real logic of both `Flatten` and `FlatMap` which simply delegate to
+/// this type.
+#[derive(Clone, Debug)]
+pub(in super::super) struct FlattenCompat<I, U> {
+    iter: I,
+    frontiter: Option<U>,
+    backiter: Option<U>,
+}
+
+impl<I, U> Iterator for FlattenCompat<I, U>
+    where I: Iterator, U: Iterator,
+          I::Item: IntoIterator<IntoIter = U, Item = U::Item>
+{
+    type Item = U::Item;
+
+    #[inline]
+    fn next(&mut self) -> Option<U::Item> {
+        loop {
+            if let Some(ref mut inner) = self.frontiter {
+                if let elt@Some(_) = inner.next() { return elt }
+            }
+            match self.iter.next() {
+                None => return self.backiter.as_mut().and_then(|it| it.next()),
+                Some(inner) => self.frontiter = Some(inner.into_iter()),
+            }
+        }
+    }
+
+    #[inline]
+    fn size_hint(&self) -> (usize, Option<usize>) {
+        let (flo, fhi) = self.frontiter.as_ref().map_or((0, Some(0)), |it| it.size_hint());
+        let (blo, bhi) = self.backiter.as_ref().map_or((0, Some(0)), |it| it.size_hint());
+        let lo = flo.saturating_add(blo);
+        match (self.iter.size_hint(), fhi, bhi) {
+            ((0, Some(0)), Some(a), Some(b)) => (lo, a.checked_add(b)),
+            _ => (lo, None)
+        }
+    }
+
+    #[inline]
+    fn try_fold<Acc, Fold, R>(&mut self, mut init: Acc, mut fold: Fold) -> R where
+        Self: Sized, Fold: FnMut(Acc, Self::Item) -> R, R: Try<Ok=Acc>
+    {
+        if let Some(ref mut front) = self.frontiter {
+            init = front.try_fold(init, &mut fold)?;
+        }
+        self.frontiter = None;
+
+        {
+            let frontiter = &mut self.frontiter;
+            init = self.iter.try_fold(init, |acc, x| {
+                let mut mid = x.into_iter();
+                let r = mid.try_fold(acc, &mut fold);
+                *frontiter = Some(mid);
+                r
+            })?;
+        }
+        self.frontiter = None;
+
+        if let Some(ref mut back) = self.backiter {
+            init = back.try_fold(init, &mut fold)?;
+        }
+        self.backiter = None;
+
+        Try::from_ok(init)
+    }
+
+    #[inline]
+    fn fold<Acc, Fold>(self, init: Acc, mut fold: Fold) -> Acc
+        where Fold: FnMut(Acc, Self::Item) -> Acc,
+    {
+        self.frontiter.into_iter()
+            .chain(self.iter.map(IntoIterator::into_iter))
+            .chain(self.backiter)
+            .fold(init, |acc, iter| iter.fold(acc, &mut fold))
+    }
+}
+
+impl<I, U> DoubleEndedIterator for FlattenCompat<I, U>
+    where I: DoubleEndedIterator, U: DoubleEndedIterator,
+          I::Item: IntoIterator<IntoIter = U, Item = U::Item>
+{
+    #[inline]
+    fn next_back(&mut self) -> Option<U::Item> {
+        loop {
+            if let Some(ref mut inner) = self.backiter {
+                if let elt@Some(_) = inner.next_back() { return elt }
+            }
+            match self.iter.next_back() {
+                None => return self.frontiter.as_mut().and_then(|it| it.next_back()),
+                next => self.backiter = next.map(IntoIterator::into_iter),
+            }
+        }
+    }
+
+    #[inline]
+    fn try_rfold<Acc, Fold, R>(&mut self, mut init: Acc, mut fold: Fold) -> R where
+        Self: Sized, Fold: FnMut(Acc, Self::Item) -> R, R: Try<Ok=Acc>
+    {
+        if let Some(ref mut back) = self.backiter {
+            init = back.try_rfold(init, &mut fold)?;
+        }
+        self.backiter = None;
+
+        {
+            let backiter = &mut self.backiter;
+            init = self.iter.try_rfold(init, |acc, x| {
+                let mut mid = x.into_iter();
+                let r = mid.try_rfold(acc, &mut fold);
+                *backiter = Some(mid);
+                r
+            })?;
+        }
+        self.backiter = None;
+
+        if let Some(ref mut front) = self.frontiter {
+            init = front.try_rfold(init, &mut fold)?;
+        }
+        self.frontiter = None;
+
+        Try::from_ok(init)
+    }
+
+    #[inline]
+    fn rfold<Acc, Fold>(self, init: Acc, mut fold: Fold) -> Acc
+        where Fold: FnMut(Acc, Self::Item) -> Acc,
+    {
+        self.frontiter.into_iter()
+            .chain(self.iter.map(IntoIterator::into_iter))
+            .chain(self.backiter)
+            .rfold(init, |acc, iter| iter.rfold(acc, &mut fold))
+    }
+}
+
diff --git a/src/libcore/iter/adapters/mod.rs b/src/libcore/iter/adapters/mod.rs
index 67c7c7a0566..a3e0696d215 100644
--- a/src/libcore/iter/adapters/mod.rs
+++ b/src/libcore/iter/adapters/mod.rs
@@ -7,11 +7,14 @@ use super::{Iterator, DoubleEndedIterator, ExactSizeIterator, FusedIterator, Tru
 use super::LoopState;
 
 mod chain;
+mod flatten;
 mod zip;
 
 pub use self::chain::Chain;
+pub use self::flatten::{FlatMap, Flatten};
 pub use self::zip::Zip;
 pub(super) use self::chain::ChainState;
+pub(super) use self::flatten::{FlattenCompat, flatten_compat};
 pub(super) use self::zip::ZipImpl;
 pub(crate) use self::zip::TrustedRandomAccess;
 
@@ -1620,319 +1623,6 @@ impl<B, I, St, F> Iterator for Scan<I, St, F> where
     }
 }
 
-/// An iterator that maps each element to an iterator, and yields the elements
-/// of the produced iterators.
-///
-/// This `struct` is created by the [`flat_map`] method on [`Iterator`]. See its
-/// documentation for more.
-///
-/// [`flat_map`]: trait.Iterator.html#method.flat_map
-/// [`Iterator`]: trait.Iterator.html
-#[must_use = "iterators are lazy and do nothing unless consumed"]
-#[stable(feature = "rust1", since = "1.0.0")]
-pub struct FlatMap<I, U: IntoIterator, F> {
-    pub(super) inner: FlattenCompat<Map<I, F>, <U as IntoIterator>::IntoIter>
-}
-
-#[stable(feature = "rust1", since = "1.0.0")]
-impl<I: Clone, U: Clone + IntoIterator, F: Clone> Clone for FlatMap<I, U, F>
-    where <U as IntoIterator>::IntoIter: Clone
-{
-    fn clone(&self) -> Self { FlatMap { inner: self.inner.clone() } }
-}
-
-#[stable(feature = "core_impl_debug", since = "1.9.0")]
-impl<I: fmt::Debug, U: IntoIterator, F> fmt::Debug for FlatMap<I, U, F>
-    where U::IntoIter: fmt::Debug
-{
-    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-        f.debug_struct("FlatMap").field("inner", &self.inner).finish()
-    }
-}
-
-#[stable(feature = "rust1", since = "1.0.0")]
-impl<I: Iterator, U: IntoIterator, F> Iterator for FlatMap<I, U, F>
-    where F: FnMut(I::Item) -> U,
-{
-    type Item = U::Item;
-
-    #[inline]
-    fn next(&mut self) -> Option<U::Item> { self.inner.next() }
-
-    #[inline]
-    fn size_hint(&self) -> (usize, Option<usize>) { self.inner.size_hint() }
-
-    #[inline]
-    fn try_fold<Acc, Fold, R>(&mut self, init: Acc, fold: Fold) -> R where
-        Self: Sized, Fold: FnMut(Acc, Self::Item) -> R, R: Try<Ok=Acc>
-    {
-        self.inner.try_fold(init, fold)
-    }
-
-    #[inline]
-    fn fold<Acc, Fold>(self, init: Acc, fold: Fold) -> Acc
-        where Fold: FnMut(Acc, Self::Item) -> Acc,
-    {
-        self.inner.fold(init, fold)
-    }
-}
-
-#[stable(feature = "rust1", since = "1.0.0")]
-impl<I: DoubleEndedIterator, U, F> DoubleEndedIterator for FlatMap<I, U, F>
-    where F: FnMut(I::Item) -> U,
-          U: IntoIterator,
-          U::IntoIter: DoubleEndedIterator
-{
-    #[inline]
-    fn next_back(&mut self) -> Option<U::Item> { self.inner.next_back() }
-
-    #[inline]
-    fn try_rfold<Acc, Fold, R>(&mut self, init: Acc, fold: Fold) -> R where
-        Self: Sized, Fold: FnMut(Acc, Self::Item) -> R, R: Try<Ok=Acc>
-    {
-        self.inner.try_rfold(init, fold)
-    }
-
-    #[inline]
-    fn rfold<Acc, Fold>(self, init: Acc, fold: Fold) -> Acc
-        where Fold: FnMut(Acc, Self::Item) -> Acc,
-    {
-        self.inner.rfold(init, fold)
-    }
-}
-
-#[stable(feature = "fused", since = "1.26.0")]
-impl<I, U, F> FusedIterator for FlatMap<I, U, F>
-    where I: FusedIterator, U: IntoIterator, F: FnMut(I::Item) -> U {}
-
-/// An iterator that flattens one level of nesting in an iterator of things
-/// that can be turned into iterators.
-///
-/// This `struct` is created by the [`flatten`] method on [`Iterator`]. See its
-/// documentation for more.
-///
-/// [`flatten`]: trait.Iterator.html#method.flatten
-/// [`Iterator`]: trait.Iterator.html
-#[must_use = "iterators are lazy and do nothing unless consumed"]
-#[stable(feature = "iterator_flatten", since = "1.29.0")]
-pub struct Flatten<I: Iterator>
-where I::Item: IntoIterator {
-    pub(super) inner: FlattenCompat<I, <I::Item as IntoIterator>::IntoIter>,
-}
-
-#[stable(feature = "iterator_flatten", since = "1.29.0")]
-impl<I, U> fmt::Debug for Flatten<I>
-    where I: Iterator + fmt::Debug, U: Iterator + fmt::Debug,
-          I::Item: IntoIterator<IntoIter = U, Item = U::Item>,
-{
-    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-        f.debug_struct("Flatten").field("inner", &self.inner).finish()
-    }
-}
-
-#[stable(feature = "iterator_flatten", since = "1.29.0")]
-impl<I, U> Clone for Flatten<I>
-    where I: Iterator + Clone, U: Iterator + Clone,
-          I::Item: IntoIterator<IntoIter = U, Item = U::Item>,
-{
-    fn clone(&self) -> Self { Flatten { inner: self.inner.clone() } }
-}
-
-#[stable(feature = "iterator_flatten", since = "1.29.0")]
-impl<I, U> Iterator for Flatten<I>
-    where I: Iterator, U: Iterator,
-          I::Item: IntoIterator<IntoIter = U, Item = U::Item>
-{
-    type Item = U::Item;
-
-    #[inline]
-    fn next(&mut self) -> Option<U::Item> { self.inner.next() }
-
-    #[inline]
-    fn size_hint(&self) -> (usize, Option<usize>) { self.inner.size_hint() }
-
-    #[inline]
-    fn try_fold<Acc, Fold, R>(&mut self, init: Acc, fold: Fold) -> R where
-        Self: Sized, Fold: FnMut(Acc, Self::Item) -> R, R: Try<Ok=Acc>
-    {
-        self.inner.try_fold(init, fold)
-    }
-
-    #[inline]
-    fn fold<Acc, Fold>(self, init: Acc, fold: Fold) -> Acc
-        where Fold: FnMut(Acc, Self::Item) -> Acc,
-    {
-        self.inner.fold(init, fold)
-    }
-}
-
-#[stable(feature = "iterator_flatten", since = "1.29.0")]
-impl<I, U> DoubleEndedIterator for Flatten<I>
-    where I: DoubleEndedIterator, U: DoubleEndedIterator,
-          I::Item: IntoIterator<IntoIter = U, Item = U::Item>
-{
-    #[inline]
-    fn next_back(&mut self) -> Option<U::Item> { self.inner.next_back() }
-
-    #[inline]
-    fn try_rfold<Acc, Fold, R>(&mut self, init: Acc, fold: Fold) -> R where
-        Self: Sized, Fold: FnMut(Acc, Self::Item) -> R, R: Try<Ok=Acc>
-    {
-        self.inner.try_rfold(init, fold)
-    }
-
-    #[inline]
-    fn rfold<Acc, Fold>(self, init: Acc, fold: Fold) -> Acc
-        where Fold: FnMut(Acc, Self::Item) -> Acc,
-    {
-        self.inner.rfold(init, fold)
-    }
-}
-
-#[stable(feature = "iterator_flatten", since = "1.29.0")]
-impl<I, U> FusedIterator for Flatten<I>
-    where I: FusedIterator, U: Iterator,
-          I::Item: IntoIterator<IntoIter = U, Item = U::Item> {}
-
-/// Adapts an iterator by flattening it, for use in `flatten()` and `flat_map()`.
-pub(super) fn flatten_compat<I, U>(iter: I) -> FlattenCompat<I, U> {
-    FlattenCompat { iter, frontiter: None, backiter: None }
-}
-
-/// Real logic of both `Flatten` and `FlatMap` which simply delegate to
-/// this type.
-#[derive(Clone, Debug)]
-pub(super) struct FlattenCompat<I, U> {
-    iter: I,
-    frontiter: Option<U>,
-    backiter: Option<U>,
-}
-
-impl<I, U> Iterator for FlattenCompat<I, U>
-    where I: Iterator, U: Iterator,
-          I::Item: IntoIterator<IntoIter = U, Item = U::Item>
-{
-    type Item = U::Item;
-
-    #[inline]
-    fn next(&mut self) -> Option<U::Item> {
-        loop {
-            if let Some(ref mut inner) = self.frontiter {
-                if let elt@Some(_) = inner.next() { return elt }
-            }
-            match self.iter.next() {
-                None => return self.backiter.as_mut().and_then(|it| it.next()),
-                Some(inner) => self.frontiter = Some(inner.into_iter()),
-            }
-        }
-    }
-
-    #[inline]
-    fn size_hint(&self) -> (usize, Option<usize>) {
-        let (flo, fhi) = self.frontiter.as_ref().map_or((0, Some(0)), |it| it.size_hint());
-        let (blo, bhi) = self.backiter.as_ref().map_or((0, Some(0)), |it| it.size_hint());
-        let lo = flo.saturating_add(blo);
-        match (self.iter.size_hint(), fhi, bhi) {
-            ((0, Some(0)), Some(a), Some(b)) => (lo, a.checked_add(b)),
-            _ => (lo, None)
-        }
-    }
-
-    #[inline]
-    fn try_fold<Acc, Fold, R>(&mut self, mut init: Acc, mut fold: Fold) -> R where
-        Self: Sized, Fold: FnMut(Acc, Self::Item) -> R, R: Try<Ok=Acc>
-    {
-        if let Some(ref mut front) = self.frontiter {
-            init = front.try_fold(init, &mut fold)?;
-        }
-        self.frontiter = None;
-
-        {
-            let frontiter = &mut self.frontiter;
-            init = self.iter.try_fold(init, |acc, x| {
-                let mut mid = x.into_iter();
-                let r = mid.try_fold(acc, &mut fold);
-                *frontiter = Some(mid);
-                r
-            })?;
-        }
-        self.frontiter = None;
-
-        if let Some(ref mut back) = self.backiter {
-            init = back.try_fold(init, &mut fold)?;
-        }
-        self.backiter = None;
-
-        Try::from_ok(init)
-    }
-
-    #[inline]
-    fn fold<Acc, Fold>(self, init: Acc, mut fold: Fold) -> Acc
-        where Fold: FnMut(Acc, Self::Item) -> Acc,
-    {
-        self.frontiter.into_iter()
-            .chain(self.iter.map(IntoIterator::into_iter))
-            .chain(self.backiter)
-            .fold(init, |acc, iter| iter.fold(acc, &mut fold))
-    }
-}
-
-impl<I, U> DoubleEndedIterator for FlattenCompat<I, U>
-    where I: DoubleEndedIterator, U: DoubleEndedIterator,
-          I::Item: IntoIterator<IntoIter = U, Item = U::Item>
-{
-    #[inline]
-    fn next_back(&mut self) -> Option<U::Item> {
-        loop {
-            if let Some(ref mut inner) = self.backiter {
-                if let elt@Some(_) = inner.next_back() { return elt }
-            }
-            match self.iter.next_back() {
-                None => return self.frontiter.as_mut().and_then(|it| it.next_back()),
-                next => self.backiter = next.map(IntoIterator::into_iter),
-            }
-        }
-    }
-
-    #[inline]
-    fn try_rfold<Acc, Fold, R>(&mut self, mut init: Acc, mut fold: Fold) -> R where
-        Self: Sized, Fold: FnMut(Acc, Self::Item) -> R, R: Try<Ok=Acc>
-    {
-        if let Some(ref mut back) = self.backiter {
-            init = back.try_rfold(init, &mut fold)?;
-        }
-        self.backiter = None;
-
-        {
-            let backiter = &mut self.backiter;
-            init = self.iter.try_rfold(init, |acc, x| {
-                let mut mid = x.into_iter();
-                let r = mid.try_rfold(acc, &mut fold);
-                *backiter = Some(mid);
-                r
-            })?;
-        }
-        self.backiter = None;
-
-        if let Some(ref mut front) = self.frontiter {
-            init = front.try_rfold(init, &mut fold)?;
-        }
-        self.frontiter = None;
-
-        Try::from_ok(init)
-    }
-
-    #[inline]
-    fn rfold<Acc, Fold>(self, init: Acc, mut fold: Fold) -> Acc
-        where Fold: FnMut(Acc, Self::Item) -> Acc,
-    {
-        self.frontiter.into_iter()
-            .chain(self.iter.map(IntoIterator::into_iter))
-            .chain(self.backiter)
-            .rfold(init, |acc, iter| iter.rfold(acc, &mut fold))
-    }
-}
-
 /// An iterator that yields `None` forever after the underlying iterator
 /// yields `None` once.
 ///