From 74cde120e5edb8d62fb63e8ab738ba0c67ec4d5c Mon Sep 17 00:00:00 2001 From: Ulrik Sverdrup Date: Tue, 22 Nov 2016 23:31:31 +0100 Subject: [PATCH] core, collections: Implement better .is_empty() for slice and vec iterators These iterators can use a pointer comparison instead of computing the length. --- src/libcollections/lib.rs | 1 + src/libcollections/vec.rs | 12 ++++++++++-- src/libcollectionstest/lib.rs | 1 + src/libcollectionstest/slice.rs | 10 ++++++++++ src/libcore/slice.rs | 12 ++++++++++-- 5 files changed, 32 insertions(+), 4 deletions(-) diff --git a/src/libcollections/lib.rs b/src/libcollections/lib.rs index 23d6edd6d79..f6d83b25b0d 100644 --- a/src/libcollections/lib.rs +++ b/src/libcollections/lib.rs @@ -36,6 +36,7 @@ #![cfg_attr(not(test), feature(char_escape_debug))] #![feature(core_intrinsics)] #![feature(dropck_parametricity)] +#![feature(exact_size_is_empty)] #![feature(fmt_internals)] #![feature(fused)] #![feature(heap_api)] diff --git a/src/libcollections/vec.rs b/src/libcollections/vec.rs index 24f8e3a2d91..f2632412700 100644 --- a/src/libcollections/vec.rs +++ b/src/libcollections/vec.rs @@ -1988,7 +1988,11 @@ fn next_back(&mut self) -> Option { } #[stable(feature = "rust1", since = "1.0.0")] -impl ExactSizeIterator for IntoIter {} +impl ExactSizeIterator for IntoIter { + fn is_empty(&self) -> bool { + self.ptr == self.end + } +} #[unstable(feature = "fused", issue = "35602")] impl FusedIterator for IntoIter {} @@ -2082,7 +2086,11 @@ fn drop(&mut self) { #[stable(feature = "drain", since = "1.6.0")] -impl<'a, T> ExactSizeIterator for Drain<'a, T> {} +impl<'a, T> ExactSizeIterator for Drain<'a, T> { + fn is_empty(&self) -> bool { + self.iter.is_empty() + } +} #[unstable(feature = "fused", issue = "35602")] impl<'a, T> FusedIterator for Drain<'a, T> {} diff --git a/src/libcollectionstest/lib.rs b/src/libcollectionstest/lib.rs index 14ec8d58bef..1e08074b14d 100644 --- a/src/libcollectionstest/lib.rs +++ b/src/libcollectionstest/lib.rs @@ -18,6 +18,7 @@ #![feature(const_fn)] #![feature(dedup_by)] #![feature(enumset)] +#![feature(exact_size_is_empty)] #![feature(pattern)] #![feature(rand)] #![feature(repeat_str)] diff --git a/src/libcollectionstest/slice.rs b/src/libcollectionstest/slice.rs index a6230ef471c..0e63e8d4a1e 100644 --- a/src/libcollectionstest/slice.rs +++ b/src/libcollectionstest/slice.rs @@ -633,6 +633,16 @@ fn test_iter_clone() { assert_eq!(it.next(), jt.next()); } +#[test] +fn test_iter_is_empty() { + let xs = [1, 2, 5, 10, 11]; + for i in 0..xs.len() { + for j in i..xs.len() { + assert_eq!(xs[i..j].iter().is_empty(), xs[i..j].is_empty()); + } + } +} + #[test] fn test_mut_iterator() { let mut xs = [1, 2, 3, 4, 5]; diff --git a/src/libcore/slice.rs b/src/libcore/slice.rs index 871b63145ca..ede45111ebb 100644 --- a/src/libcore/slice.rs +++ b/src/libcore/slice.rs @@ -983,7 +983,11 @@ fn iter_nth(&mut self, n: usize) -> Option<&'a T> { iterator!{struct Iter -> *const T, &'a T} #[stable(feature = "rust1", since = "1.0.0")] -impl<'a, T> ExactSizeIterator for Iter<'a, T> {} +impl<'a, T> ExactSizeIterator for Iter<'a, T> { + fn is_empty(&self) -> bool { + self.ptr == self.end + } +} #[unstable(feature = "fused", issue = "35602")] impl<'a, T> FusedIterator for Iter<'a, T> {} @@ -1107,7 +1111,11 @@ fn iter_nth(&mut self, n: usize) -> Option<&'a mut T> { iterator!{struct IterMut -> *mut T, &'a mut T} #[stable(feature = "rust1", since = "1.0.0")] -impl<'a, T> ExactSizeIterator for IterMut<'a, T> {} +impl<'a, T> ExactSizeIterator for IterMut<'a, T> { + fn is_empty(&self) -> bool { + self.ptr == self.end + } +} #[unstable(feature = "fused", issue = "35602")] impl<'a, T> FusedIterator for IterMut<'a, T> {}