about summary refs log tree commit diff
path: root/src/liballoc
diff options
context:
space:
mode:
authorJonas Schievink <jonasschievink@gmail.com>2019-09-18 23:41:57 +0200
committerJonas Schievink <jonasschievink@gmail.com>2019-10-05 15:33:25 +0200
commit02f36e52a656f1baa717538e18ae96137cbc83f9 (patch)
treeb79265039e37d9b574c0ad16efa7eefba23844dd /src/liballoc
parent55277d4a6ebbf1de00437c268cbf6caf07ddf458 (diff)
downloadrust-02f36e52a656f1baa717538e18ae96137cbc83f9.tar.gz
rust-02f36e52a656f1baa717538e18ae96137cbc83f9.zip
Hide the `Iterator` specialization behind a trait
Diffstat (limited to 'src/liballoc')
-rw-r--r--src/liballoc/boxed.rs27
1 files changed, 22 insertions, 5 deletions
diff --git a/src/liballoc/boxed.rs b/src/liballoc/boxed.rs
index adbc0e6ba2c..9b5d9431ae2 100644
--- a/src/liballoc/boxed.rs
+++ b/src/liballoc/boxed.rs
@@ -871,16 +871,33 @@ impl<I: Iterator + ?Sized> Iterator for Box<I> {
     fn nth(&mut self, n: usize) -> Option<I::Item> {
         (**self).nth(n)
     }
+    fn last(self) -> Option<I::Item> {
+        BoxIter::last(self)
+    }
+}
+
+trait BoxIter {
+    type Item;
+    fn last(self) -> Option<Self::Item>;
+}
+
+impl<I: Iterator + ?Sized> BoxIter for Box<I> {
+    type Item = I::Item;
     default fn last(self) -> Option<I::Item> {
-        let mut last = None;
-        for x in self { last = Some(x); }
-        last
+        #[inline]
+        fn some<T>(_: Option<T>, x: T) -> Option<T> {
+            Some(x)
+        }
+
+        self.fold(None, some)
     }
 }
 
+/// Specialization for sized `I`s that uses `I`s implementation of `last()`
+/// instead of the default.
 #[stable(feature = "rust1", since = "1.0.0")]
-impl<I: Iterator + Sized> Iterator for Box<I> {
-    fn last(self) -> Option<I::Item> where I: Sized {
+impl<I: Iterator> BoxIter for Box<I> {
+    fn last(self) -> Option<I::Item> {
         (*self).last()
     }
 }