about summary refs log tree commit diff
path: root/src/libcore/iter
diff options
context:
space:
mode:
authorClar Fon <them@lightdark.xyz>2018-12-17 19:28:40 -0500
committerClar Fon <them@lightdark.xyz>2019-01-22 17:45:11 -0500
commitebfd08312522b85a5b4085aa0a2bf6fb9b9873d7 (patch)
treeb9cb55d0eb3d48b6df5df62a826bd7de186adc05 /src/libcore/iter
parent520e8b001ef7c49dcf1ad8f1f7817f2b16ad709b (diff)
downloadrust-ebfd08312522b85a5b4085aa0a2bf6fb9b9873d7.tar.gz
rust-ebfd08312522b85a5b4085aa0a2bf6fb9b9873d7.zip
Move Chain and ChainState to own module
Diffstat (limited to 'src/libcore/iter')
-rw-r--r--src/libcore/iter/adapters/chain.rs255
-rw-r--r--src/libcore/iter/adapters/mod.rs254
2 files changed, 258 insertions, 251 deletions
diff --git a/src/libcore/iter/adapters/chain.rs b/src/libcore/iter/adapters/chain.rs
new file mode 100644
index 00000000000..5defb857d50
--- /dev/null
+++ b/src/libcore/iter/adapters/chain.rs
@@ -0,0 +1,255 @@
+use ops::Try;
+use usize;
+use super::super::{Iterator, DoubleEndedIterator, FusedIterator, TrustedLen};
+
+/// An iterator that strings two iterators together.
+///
+/// This `struct` is created by the [`chain`] method on [`Iterator`]. See its
+/// documentation for more.
+///
+/// [`chain`]: trait.Iterator.html#method.chain
+/// [`Iterator`]: trait.Iterator.html
+#[derive(Clone, Debug)]
+#[must_use = "iterators are lazy and do nothing unless consumed"]
+#[stable(feature = "rust1", since = "1.0.0")]
+pub struct Chain<A, B> {
+    pub(in super::super) a: A,
+    pub(in super::super) b: B,
+    pub(in super::super) state: ChainState,
+}
+
+// The iterator protocol specifies that iteration ends with the return value
+// `None` from `.next()` (or `.next_back()`) and it is unspecified what
+// further calls return. The chain adaptor must account for this since it uses
+// two subiterators.
+//
+//  It uses three states:
+//
+//  - Both: `a` and `b` are remaining
+//  - Front: `a` remaining
+//  - Back: `b` remaining
+//
+//  The fourth state (neither iterator is remaining) only occurs after Chain has
+//  returned None once, so we don't need to store this state.
+#[derive(Clone, Debug)]
+pub(in super::super) enum ChainState {
+    // both front and back iterator are remaining
+    Both,
+    // only front is remaining
+    Front,
+    // only back is remaining
+    Back,
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<A, B> Iterator for Chain<A, B> where
+    A: Iterator,
+    B: Iterator<Item = A::Item>
+{
+    type Item = A::Item;
+
+    #[inline]
+    fn next(&mut self) -> Option<A::Item> {
+        match self.state {
+            ChainState::Both => match self.a.next() {
+                elt @ Some(..) => elt,
+                None => {
+                    self.state = ChainState::Back;
+                    self.b.next()
+                }
+            },
+            ChainState::Front => self.a.next(),
+            ChainState::Back => self.b.next(),
+        }
+    }
+
+    #[inline]
+    #[rustc_inherit_overflow_checks]
+    fn count(self) -> usize {
+        match self.state {
+            ChainState::Both => self.a.count() + self.b.count(),
+            ChainState::Front => self.a.count(),
+            ChainState::Back => self.b.count(),
+        }
+    }
+
+    fn try_fold<Acc, F, R>(&mut self, init: Acc, mut f: F) -> R where
+        Self: Sized, F: FnMut(Acc, Self::Item) -> R, R: Try<Ok=Acc>
+    {
+        let mut accum = init;
+        match self.state {
+            ChainState::Both | ChainState::Front => {
+                accum = self.a.try_fold(accum, &mut f)?;
+                if let ChainState::Both = self.state {
+                    self.state = ChainState::Back;
+                }
+            }
+            _ => { }
+        }
+        if let ChainState::Back = self.state {
+            accum = self.b.try_fold(accum, &mut f)?;
+        }
+        Try::from_ok(accum)
+    }
+
+    fn fold<Acc, F>(self, init: Acc, mut f: F) -> Acc
+        where F: FnMut(Acc, Self::Item) -> Acc,
+    {
+        let mut accum = init;
+        match self.state {
+            ChainState::Both | ChainState::Front => {
+                accum = self.a.fold(accum, &mut f);
+            }
+            _ => { }
+        }
+        match self.state {
+            ChainState::Both | ChainState::Back => {
+                accum = self.b.fold(accum, &mut f);
+            }
+            _ => { }
+        }
+        accum
+    }
+
+    #[inline]
+    fn nth(&mut self, mut n: usize) -> Option<A::Item> {
+        match self.state {
+            ChainState::Both | ChainState::Front => {
+                for x in self.a.by_ref() {
+                    if n == 0 {
+                        return Some(x)
+                    }
+                    n -= 1;
+                }
+                if let ChainState::Both = self.state {
+                    self.state = ChainState::Back;
+                }
+            }
+            ChainState::Back => {}
+        }
+        if let ChainState::Back = self.state {
+            self.b.nth(n)
+        } else {
+            None
+        }
+    }
+
+    #[inline]
+    fn find<P>(&mut self, mut predicate: P) -> Option<Self::Item> where
+        P: FnMut(&Self::Item) -> bool,
+    {
+        match self.state {
+            ChainState::Both => match self.a.find(&mut predicate) {
+                None => {
+                    self.state = ChainState::Back;
+                    self.b.find(predicate)
+                }
+                v => v
+            },
+            ChainState::Front => self.a.find(predicate),
+            ChainState::Back => self.b.find(predicate),
+        }
+    }
+
+    #[inline]
+    fn last(self) -> Option<A::Item> {
+        match self.state {
+            ChainState::Both => {
+                // Must exhaust a before b.
+                let a_last = self.a.last();
+                let b_last = self.b.last();
+                b_last.or(a_last)
+            },
+            ChainState::Front => self.a.last(),
+            ChainState::Back => self.b.last()
+        }
+    }
+
+    #[inline]
+    fn size_hint(&self) -> (usize, Option<usize>) {
+        let (a_lower, a_upper) = self.a.size_hint();
+        let (b_lower, b_upper) = self.b.size_hint();
+
+        let lower = a_lower.saturating_add(b_lower);
+
+        let upper = match (a_upper, b_upper) {
+            (Some(x), Some(y)) => x.checked_add(y),
+            _ => None
+        };
+
+        (lower, upper)
+    }
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<A, B> DoubleEndedIterator for Chain<A, B> where
+    A: DoubleEndedIterator,
+    B: DoubleEndedIterator<Item=A::Item>,
+{
+    #[inline]
+    fn next_back(&mut self) -> Option<A::Item> {
+        match self.state {
+            ChainState::Both => match self.b.next_back() {
+                elt @ Some(..) => elt,
+                None => {
+                    self.state = ChainState::Front;
+                    self.a.next_back()
+                }
+            },
+            ChainState::Front => self.a.next_back(),
+            ChainState::Back => self.b.next_back(),
+        }
+    }
+
+    fn try_rfold<Acc, F, R>(&mut self, init: Acc, mut f: F) -> R where
+        Self: Sized, F: FnMut(Acc, Self::Item) -> R, R: Try<Ok=Acc>
+    {
+        let mut accum = init;
+        match self.state {
+            ChainState::Both | ChainState::Back => {
+                accum = self.b.try_rfold(accum, &mut f)?;
+                if let ChainState::Both = self.state {
+                    self.state = ChainState::Front;
+                }
+            }
+            _ => { }
+        }
+        if let ChainState::Front = self.state {
+            accum = self.a.try_rfold(accum, &mut f)?;
+        }
+        Try::from_ok(accum)
+    }
+
+    fn rfold<Acc, F>(self, init: Acc, mut f: F) -> Acc
+        where F: FnMut(Acc, Self::Item) -> Acc,
+    {
+        let mut accum = init;
+        match self.state {
+            ChainState::Both | ChainState::Back => {
+                accum = self.b.rfold(accum, &mut f);
+            }
+            _ => { }
+        }
+        match self.state {
+            ChainState::Both | ChainState::Front => {
+                accum = self.a.rfold(accum, &mut f);
+            }
+            _ => { }
+        }
+        accum
+    }
+
+}
+
+// Note: *both* must be fused to handle double-ended iterators.
+#[stable(feature = "fused", since = "1.26.0")]
+impl<A, B> FusedIterator for Chain<A, B>
+    where A: FusedIterator,
+          B: FusedIterator<Item=A::Item>,
+{}
+
+#[unstable(feature = "trusted_len", issue = "37572")]
+unsafe impl<A, B> TrustedLen for Chain<A, B>
+    where A: TrustedLen, B: TrustedLen<Item=A::Item>,
+{}
+
diff --git a/src/libcore/iter/adapters/mod.rs b/src/libcore/iter/adapters/mod.rs
index f2bedf390e3..67c7c7a0566 100644
--- a/src/libcore/iter/adapters/mod.rs
+++ b/src/libcore/iter/adapters/mod.rs
@@ -6,9 +6,12 @@ use intrinsics;
 use super::{Iterator, DoubleEndedIterator, ExactSizeIterator, FusedIterator, TrustedLen};
 use super::LoopState;
 
+mod chain;
 mod zip;
 
+pub use self::chain::Chain;
 pub use self::zip::Zip;
+pub(super) use self::chain::ChainState;
 pub(super) use self::zip::ZipImpl;
 pub(crate) use self::zip::TrustedRandomAccess;
 
@@ -457,257 +460,6 @@ impl<I> Iterator for StepBy<I> where I: Iterator {
 #[stable(feature = "iterator_step_by", since = "1.28.0")]
 impl<I> ExactSizeIterator for StepBy<I> where I: ExactSizeIterator {}
 
-/// An iterator that strings two iterators together.
-///
-/// This `struct` is created by the [`chain`] method on [`Iterator`]. See its
-/// documentation for more.
-///
-/// [`chain`]: trait.Iterator.html#method.chain
-/// [`Iterator`]: trait.Iterator.html
-#[derive(Clone, Debug)]
-#[must_use = "iterators are lazy and do nothing unless consumed"]
-#[stable(feature = "rust1", since = "1.0.0")]
-pub struct Chain<A, B> {
-    pub(super) a: A,
-    pub(super) b: B,
-    pub(super) state: ChainState,
-}
-
-// The iterator protocol specifies that iteration ends with the return value
-// `None` from `.next()` (or `.next_back()`) and it is unspecified what
-// further calls return. The chain adaptor must account for this since it uses
-// two subiterators.
-//
-//  It uses three states:
-//
-//  - Both: `a` and `b` are remaining
-//  - Front: `a` remaining
-//  - Back: `b` remaining
-//
-//  The fourth state (neither iterator is remaining) only occurs after Chain has
-//  returned None once, so we don't need to store this state.
-#[derive(Clone, Debug)]
-pub(super) enum ChainState {
-    // both front and back iterator are remaining
-    Both,
-    // only front is remaining
-    Front,
-    // only back is remaining
-    Back,
-}
-
-#[stable(feature = "rust1", since = "1.0.0")]
-impl<A, B> Iterator for Chain<A, B> where
-    A: Iterator,
-    B: Iterator<Item = A::Item>
-{
-    type Item = A::Item;
-
-    #[inline]
-    fn next(&mut self) -> Option<A::Item> {
-        match self.state {
-            ChainState::Both => match self.a.next() {
-                elt @ Some(..) => elt,
-                None => {
-                    self.state = ChainState::Back;
-                    self.b.next()
-                }
-            },
-            ChainState::Front => self.a.next(),
-            ChainState::Back => self.b.next(),
-        }
-    }
-
-    #[inline]
-    #[rustc_inherit_overflow_checks]
-    fn count(self) -> usize {
-        match self.state {
-            ChainState::Both => self.a.count() + self.b.count(),
-            ChainState::Front => self.a.count(),
-            ChainState::Back => self.b.count(),
-        }
-    }
-
-    fn try_fold<Acc, F, R>(&mut self, init: Acc, mut f: F) -> R where
-        Self: Sized, F: FnMut(Acc, Self::Item) -> R, R: Try<Ok=Acc>
-    {
-        let mut accum = init;
-        match self.state {
-            ChainState::Both | ChainState::Front => {
-                accum = self.a.try_fold(accum, &mut f)?;
-                if let ChainState::Both = self.state {
-                    self.state = ChainState::Back;
-                }
-            }
-            _ => { }
-        }
-        if let ChainState::Back = self.state {
-            accum = self.b.try_fold(accum, &mut f)?;
-        }
-        Try::from_ok(accum)
-    }
-
-    fn fold<Acc, F>(self, init: Acc, mut f: F) -> Acc
-        where F: FnMut(Acc, Self::Item) -> Acc,
-    {
-        let mut accum = init;
-        match self.state {
-            ChainState::Both | ChainState::Front => {
-                accum = self.a.fold(accum, &mut f);
-            }
-            _ => { }
-        }
-        match self.state {
-            ChainState::Both | ChainState::Back => {
-                accum = self.b.fold(accum, &mut f);
-            }
-            _ => { }
-        }
-        accum
-    }
-
-    #[inline]
-    fn nth(&mut self, mut n: usize) -> Option<A::Item> {
-        match self.state {
-            ChainState::Both | ChainState::Front => {
-                for x in self.a.by_ref() {
-                    if n == 0 {
-                        return Some(x)
-                    }
-                    n -= 1;
-                }
-                if let ChainState::Both = self.state {
-                    self.state = ChainState::Back;
-                }
-            }
-            ChainState::Back => {}
-        }
-        if let ChainState::Back = self.state {
-            self.b.nth(n)
-        } else {
-            None
-        }
-    }
-
-    #[inline]
-    fn find<P>(&mut self, mut predicate: P) -> Option<Self::Item> where
-        P: FnMut(&Self::Item) -> bool,
-    {
-        match self.state {
-            ChainState::Both => match self.a.find(&mut predicate) {
-                None => {
-                    self.state = ChainState::Back;
-                    self.b.find(predicate)
-                }
-                v => v
-            },
-            ChainState::Front => self.a.find(predicate),
-            ChainState::Back => self.b.find(predicate),
-        }
-    }
-
-    #[inline]
-    fn last(self) -> Option<A::Item> {
-        match self.state {
-            ChainState::Both => {
-                // Must exhaust a before b.
-                let a_last = self.a.last();
-                let b_last = self.b.last();
-                b_last.or(a_last)
-            },
-            ChainState::Front => self.a.last(),
-            ChainState::Back => self.b.last()
-        }
-    }
-
-    #[inline]
-    fn size_hint(&self) -> (usize, Option<usize>) {
-        let (a_lower, a_upper) = self.a.size_hint();
-        let (b_lower, b_upper) = self.b.size_hint();
-
-        let lower = a_lower.saturating_add(b_lower);
-
-        let upper = match (a_upper, b_upper) {
-            (Some(x), Some(y)) => x.checked_add(y),
-            _ => None
-        };
-
-        (lower, upper)
-    }
-}
-
-#[stable(feature = "rust1", since = "1.0.0")]
-impl<A, B> DoubleEndedIterator for Chain<A, B> where
-    A: DoubleEndedIterator,
-    B: DoubleEndedIterator<Item=A::Item>,
-{
-    #[inline]
-    fn next_back(&mut self) -> Option<A::Item> {
-        match self.state {
-            ChainState::Both => match self.b.next_back() {
-                elt @ Some(..) => elt,
-                None => {
-                    self.state = ChainState::Front;
-                    self.a.next_back()
-                }
-            },
-            ChainState::Front => self.a.next_back(),
-            ChainState::Back => self.b.next_back(),
-        }
-    }
-
-    fn try_rfold<Acc, F, R>(&mut self, init: Acc, mut f: F) -> R where
-        Self: Sized, F: FnMut(Acc, Self::Item) -> R, R: Try<Ok=Acc>
-    {
-        let mut accum = init;
-        match self.state {
-            ChainState::Both | ChainState::Back => {
-                accum = self.b.try_rfold(accum, &mut f)?;
-                if let ChainState::Both = self.state {
-                    self.state = ChainState::Front;
-                }
-            }
-            _ => { }
-        }
-        if let ChainState::Front = self.state {
-            accum = self.a.try_rfold(accum, &mut f)?;
-        }
-        Try::from_ok(accum)
-    }
-
-    fn rfold<Acc, F>(self, init: Acc, mut f: F) -> Acc
-        where F: FnMut(Acc, Self::Item) -> Acc,
-    {
-        let mut accum = init;
-        match self.state {
-            ChainState::Both | ChainState::Back => {
-                accum = self.b.rfold(accum, &mut f);
-            }
-            _ => { }
-        }
-        match self.state {
-            ChainState::Both | ChainState::Front => {
-                accum = self.a.rfold(accum, &mut f);
-            }
-            _ => { }
-        }
-        accum
-    }
-
-}
-
-// Note: *both* must be fused to handle double-ended iterators.
-#[stable(feature = "fused", since = "1.26.0")]
-impl<A, B> FusedIterator for Chain<A, B>
-    where A: FusedIterator,
-          B: FusedIterator<Item=A::Item>,
-{}
-
-#[unstable(feature = "trusted_len", issue = "37572")]
-unsafe impl<A, B> TrustedLen for Chain<A, B>
-    where A: TrustedLen, B: TrustedLen<Item=A::Item>,
-{}
-
 /// An iterator that maps the values of `iter` with `f`.
 ///
 /// This `struct` is created by the [`map`] method on [`Iterator`]. See its