From dd3e63aea5680b8c55a165d51691b426b86d657a Mon Sep 17 00:00:00 2001 From: Ulrik Sverdrup Date: Sat, 3 Dec 2016 21:43:51 +0100 Subject: [PATCH 1/6] core: Forward ExactSizeIterator::is_empty for Bytes --- src/libcore/str/mod.rs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/libcore/str/mod.rs b/src/libcore/str/mod.rs index b4cd52e59f658..de418b831cc88 100644 --- a/src/libcore/str/mod.rs +++ b/src/libcore/str/mod.rs @@ -618,6 +618,11 @@ impl<'a> ExactSizeIterator for Bytes<'a> { fn len(&self) -> usize { self.0.len() } + + #[inline] + fn is_empty(&self) -> bool { + self.0.is_empty() + } } #[unstable(feature = "fused", issue = "35602")] From 7ba762253ccf487ae61b2be45a9edfdf19b79cc0 Mon Sep 17 00:00:00 2001 From: Ulrik Sverdrup Date: Sat, 3 Dec 2016 21:59:00 +0100 Subject: [PATCH 2/6] std: Forward ExactSizeIterator::is_empty for Args, ArgsOs iterators --- src/libstd/env.rs | 2 ++ src/libstd/lib.rs | 1 + 2 files changed, 3 insertions(+) diff --git a/src/libstd/env.rs b/src/libstd/env.rs index baa2b5d284622..ee6a907f6160e 100644 --- a/src/libstd/env.rs +++ b/src/libstd/env.rs @@ -630,6 +630,7 @@ impl Iterator for Args { #[stable(feature = "env", since = "1.0.0")] impl ExactSizeIterator for Args { fn len(&self) -> usize { self.inner.len() } + fn is_empty(&self) -> bool { self.inner.is_empty() } } #[stable(feature = "env_iterators", since = "1.11.0")] @@ -649,6 +650,7 @@ impl Iterator for ArgsOs { #[stable(feature = "env", since = "1.0.0")] impl ExactSizeIterator for ArgsOs { fn len(&self) -> usize { self.inner.len() } + fn is_empty(&self) -> bool { self.inner.is_empty() } } #[stable(feature = "env_iterators", since = "1.11.0")] diff --git a/src/libstd/lib.rs b/src/libstd/lib.rs index 8132b1392602f..1f40d3fd1d35f 100644 --- a/src/libstd/lib.rs +++ b/src/libstd/lib.rs @@ -250,6 +250,7 @@ #![feature(core_float)] #![feature(core_intrinsics)] #![feature(dropck_parametricity)] +#![feature(exact_size_is_empty)] #![feature(float_extras)] #![feature(float_from_str_radix)] #![feature(fn_traits)] From 343b4c321d9ab0e1efc7953a15ee0dbc62c722a9 Mon Sep 17 00:00:00 2001 From: Ulrik Sverdrup Date: Sat, 3 Dec 2016 22:11:06 +0100 Subject: [PATCH 3/6] collections: Simplify VecDeque::is_empty Improve is_empty on the VecDeque and its iterators by just comparing tail and head; this saves a few instructions (to be able to remove the `& (size - 1)` computation, it would have to know that size is a power of two). --- src/libcollections/vec_deque.rs | 20 ++++++++++++++++---- src/libcollectionstest/vec_deque.rs | 21 +++++++++++++++++++++ 2 files changed, 37 insertions(+), 4 deletions(-) diff --git a/src/libcollections/vec_deque.rs b/src/libcollections/vec_deque.rs index 5397193cab40f..dbe3fec205cb2 100644 --- a/src/libcollections/vec_deque.rs +++ b/src/libcollections/vec_deque.rs @@ -810,7 +810,7 @@ impl VecDeque { /// ``` #[stable(feature = "rust1", since = "1.0.0")] pub fn is_empty(&self) -> bool { - self.len() == 0 + self.tail == self.head } /// Create a draining iterator that removes the specified range in the @@ -1916,7 +1916,11 @@ impl<'a, T> DoubleEndedIterator for Iter<'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.head == self.tail + } +} #[unstable(feature = "fused", issue = "35602")] impl<'a, T> FusedIterator for Iter<'a, T> {} @@ -1980,7 +1984,11 @@ impl<'a, T> DoubleEndedIterator for IterMut<'a, 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.head == self.tail + } +} #[unstable(feature = "fused", issue = "35602")] impl<'a, T> FusedIterator for IterMut<'a, T> {} @@ -2017,7 +2025,11 @@ impl DoubleEndedIterator for IntoIter { } #[stable(feature = "rust1", since = "1.0.0")] -impl ExactSizeIterator for IntoIter {} +impl ExactSizeIterator for IntoIter { + fn is_empty(&self) -> bool { + self.inner.is_empty() + } +} #[unstable(feature = "fused", issue = "35602")] impl FusedIterator for IntoIter {} diff --git a/src/libcollectionstest/vec_deque.rs b/src/libcollectionstest/vec_deque.rs index f1ea85a6c5bed..cdf022e4f02f3 100644 --- a/src/libcollectionstest/vec_deque.rs +++ b/src/libcollectionstest/vec_deque.rs @@ -1007,3 +1007,24 @@ fn assert_covariance() { d } } + +#[test] +fn test_is_empty() { + let mut v = VecDeque::::new(); + assert!(v.is_empty()); + assert!(v.iter().is_empty()); + assert!(v.iter_mut().is_empty()); + v.extend(&[2, 3, 4]); + assert!(!v.is_empty()); + assert!(!v.iter().is_empty()); + assert!(!v.iter_mut().is_empty()); + while let Some(_) = v.pop_front() { + assert_eq!(v.is_empty(), v.len() == 0); + assert_eq!(v.iter().is_empty(), v.iter().len() == 0); + assert_eq!(v.iter_mut().is_empty(), v.iter_mut().len() == 0); + } + assert!(v.is_empty()); + assert!(v.iter().is_empty()); + assert!(v.iter_mut().is_empty()); + assert!(v.into_iter().is_empty()); +} From 28852c3c7cec558307e4bd775127c08816ab3c3f Mon Sep 17 00:00:00 2001 From: Ulrik Sverdrup Date: Sat, 3 Dec 2016 22:44:57 +0100 Subject: [PATCH 4/6] binary_heap: Forward ExactSizeIterator::is_empty --- src/libcollections/binary_heap.rs | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/src/libcollections/binary_heap.rs b/src/libcollections/binary_heap.rs index b4be8a43213d8..8d0c76c36468c 100644 --- a/src/libcollections/binary_heap.rs +++ b/src/libcollections/binary_heap.rs @@ -986,7 +986,11 @@ impl<'a, T> DoubleEndedIterator for Iter<'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.iter.is_empty() + } +} #[unstable(feature = "fused", issue = "35602")] impl<'a, T> FusedIterator for Iter<'a, T> {} @@ -1022,7 +1026,11 @@ impl DoubleEndedIterator for IntoIter { } #[stable(feature = "rust1", since = "1.0.0")] -impl ExactSizeIterator for IntoIter {} +impl ExactSizeIterator for IntoIter { + fn is_empty(&self) -> bool { + self.iter.is_empty() + } +} #[unstable(feature = "fused", issue = "35602")] impl FusedIterator for IntoIter {} @@ -1057,7 +1065,11 @@ impl<'a, T: 'a> DoubleEndedIterator for Drain<'a, T> { } #[stable(feature = "drain", since = "1.6.0")] -impl<'a, T: 'a> ExactSizeIterator for Drain<'a, T> {} +impl<'a, T: 'a> ExactSizeIterator for Drain<'a, T> { + fn is_empty(&self) -> bool { + self.iter.is_empty() + } +} #[unstable(feature = "fused", issue = "35602")] impl<'a, T: 'a> FusedIterator for Drain<'a, T> {} From 705e295b7b93c0861c9d8af4177f6701126683a9 Mon Sep 17 00:00:00 2001 From: Ulrik Sverdrup Date: Sat, 3 Dec 2016 22:47:33 +0100 Subject: [PATCH 5/6] iter: Forward ExactSizeIterator methods for &mut I --- src/libcore/iter/traits.rs | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/libcore/iter/traits.rs b/src/libcore/iter/traits.rs index e94582cda7c34..c5465549adf70 100644 --- a/src/libcore/iter/traits.rs +++ b/src/libcore/iter/traits.rs @@ -552,7 +552,14 @@ pub trait ExactSizeIterator: Iterator { } #[stable(feature = "rust1", since = "1.0.0")] -impl<'a, I: ExactSizeIterator + ?Sized> ExactSizeIterator for &'a mut I {} +impl<'a, I: ExactSizeIterator + ?Sized> ExactSizeIterator for &'a mut I { + fn len(&self) -> usize { + (**self).len() + } + fn is_empty(&self) -> bool { + (**self).is_empty() + } +} /// Trait to represent types that can be created by summing up an iterator. /// From d53f82c1d037bf224a72a11747e7788f14b52db5 Mon Sep 17 00:00:00 2001 From: Ulrik Sverdrup Date: Sat, 3 Dec 2016 21:42:03 +0100 Subject: [PATCH 6/6] alloc: Forward ExactSizeIterator methods in Iterator for Box --- src/liballoc/boxed.rs | 9 ++++++++- src/liballoc/lib.rs | 1 + 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/src/liballoc/boxed.rs b/src/liballoc/boxed.rs index 28f4dda140883..6d7a9b1d1f9d6 100644 --- a/src/liballoc/boxed.rs +++ b/src/liballoc/boxed.rs @@ -532,7 +532,14 @@ impl DoubleEndedIterator for Box { } } #[stable(feature = "rust1", since = "1.0.0")] -impl ExactSizeIterator for Box {} +impl ExactSizeIterator for Box { + fn len(&self) -> usize { + (**self).len() + } + fn is_empty(&self) -> bool { + (**self).is_empty() + } +} #[unstable(feature = "fused", issue = "35602")] impl FusedIterator for Box {} diff --git a/src/liballoc/lib.rs b/src/liballoc/lib.rs index 0d450184ed877..acce4ce035890 100644 --- a/src/liballoc/lib.rs +++ b/src/liballoc/lib.rs @@ -79,6 +79,7 @@ #![feature(core_intrinsics)] #![feature(custom_attribute)] #![feature(dropck_parametricity)] +#![cfg_attr(not(test), feature(exact_size_is_empty))] #![feature(fundamental)] #![feature(lang_items)] #![feature(needs_allocator)]