From 4f8049a2b00c46cb1ac77cabaaf716895f185afe Mon Sep 17 00:00:00 2001 From: Scott McMurray Date: Fri, 9 Feb 2018 01:47:18 -0800 Subject: [PATCH] Add Range[Inclusive]::is_empty During the RFC, it was discussed that figuring out whether a range is empty was subtle, and thus there should be a clear and obvious way to do it. It can't just be ExactSizeIterator::is_empty (also unstable) because not all ranges are ExactSize -- not even Range or RangeInclusive. --- src/libcore/iter/traits.rs | 2 +- src/libcore/ops/range.rs | 36 ++++++++++++++++++++++++++++++++++-- src/libcore/tests/iter.rs | 4 ++-- src/libcore/tests/lib.rs | 1 + src/libcore/tests/ops.rs | 24 ++++++++++++++++++++++++ 5 files changed, 62 insertions(+), 5 deletions(-) diff --git a/src/libcore/iter/traits.rs b/src/libcore/iter/traits.rs index be4889f2487..860742d9eab 100644 --- a/src/libcore/iter/traits.rs +++ b/src/libcore/iter/traits.rs @@ -706,7 +706,7 @@ fn len(&self) -> usize { /// ``` /// #![feature(exact_size_is_empty)] /// - /// let mut one_element = 0..1; + /// let mut one_element = std::iter::once(0); /// assert!(!one_element.is_empty()); /// /// assert_eq!(one_element.next(), Some(0)); diff --git a/src/libcore/ops/range.rs b/src/libcore/ops/range.rs index 3f573f7c7eb..102e08362cb 100644 --- a/src/libcore/ops/range.rs +++ b/src/libcore/ops/range.rs @@ -92,7 +92,6 @@ fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { } } -#[unstable(feature = "range_contains", reason = "recently added as per RFC", issue = "32311")] impl> Range { /// Returns `true` if `item` is contained in the range. /// @@ -109,9 +108,26 @@ impl> Range { /// assert!(!(3..3).contains(3)); /// assert!(!(3..2).contains(3)); /// ``` + #[unstable(feature = "range_contains", reason = "recently added as per RFC", issue = "32311")] pub fn contains(&self, item: Idx) -> bool { (self.start <= item) && (item < self.end) } + + /// Returns `true` if the range contains no items. + /// + /// # Examples + /// + /// ``` + /// #![feature(range_is_empty)] + /// + /// assert!(!(3..5).is_empty()); + /// assert!( (3..3).is_empty()); + /// assert!( (3..2).is_empty()); + /// ``` + #[unstable(feature = "range_is_empty", reason = "recently added", issue = "123456789")] + pub fn is_empty(&self) -> bool { + !(self.start < self.end) + } } /// A range only bounded inclusively below (`start..`). @@ -280,7 +296,6 @@ fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { } } -#[unstable(feature = "range_contains", reason = "recently added as per RFC", issue = "32311")] impl> RangeInclusive { /// Returns `true` if `item` is contained in the range. /// @@ -298,9 +313,26 @@ impl> RangeInclusive { /// assert!( (3..=3).contains(3)); /// assert!(!(3..=2).contains(3)); /// ``` + #[unstable(feature = "range_contains", reason = "recently added as per RFC", issue = "32311")] pub fn contains(&self, item: Idx) -> bool { self.start <= item && item <= self.end } + + /// Returns `true` if the range contains no items. + /// + /// # Examples + /// + /// ``` + /// #![feature(range_is_empty,inclusive_range_syntax)] + /// + /// assert!(!(3..=5).is_empty()); + /// assert!(!(3..=3).is_empty()); + /// assert!( (3..=2).is_empty()); + /// ``` + #[unstable(feature = "range_is_empty", reason = "recently added", issue = "123456789")] + pub fn is_empty(&self) -> bool { + !(self.start <= self.end) + } } /// A range only bounded inclusively above (`..=end`). diff --git a/src/libcore/tests/iter.rs b/src/libcore/tests/iter.rs index b2a5243d5e6..062b6d4126e 100644 --- a/src/libcore/tests/iter.rs +++ b/src/libcore/tests/iter.rs @@ -1427,9 +1427,9 @@ fn test_range_inclusive_nth() { assert_eq!(r, 13..=20); assert_eq!(r.nth(2), Some(15)); assert_eq!(r, 16..=20); - assert_eq!(r.is_empty(), false); + assert_eq!(ExactSizeIterator::is_empty(&r), false); assert_eq!(r.nth(10), None); - assert_eq!(r.is_empty(), true); + assert_eq!(ExactSizeIterator::is_empty(&r), true); assert_eq!(r, 1..=0); // We may not want to document/promise this detail } diff --git a/src/libcore/tests/lib.rs b/src/libcore/tests/lib.rs index 1c32452f846..91b4f02594b 100644 --- a/src/libcore/tests/lib.rs +++ b/src/libcore/tests/lib.rs @@ -29,6 +29,7 @@ #![feature(iter_rfold)] #![feature(nonzero)] #![feature(pattern)] +#![feature(range_is_empty)] #![feature(raw)] #![feature(refcell_replace_swap)] #![feature(sip_hash_13)] diff --git a/src/libcore/tests/ops.rs b/src/libcore/tests/ops.rs index 9d2fa1abff6..68a692b24a3 100644 --- a/src/libcore/tests/ops.rs +++ b/src/libcore/tests/ops.rs @@ -68,3 +68,27 @@ fn test_range_inclusive() { assert_eq!(r.size_hint(), (0, Some(0))); assert_eq!(r.next(), None); } + + +#[test] +fn test_range_is_empty() { + use core::f32::*; + + assert!(!(0.0 .. 10.0).is_empty()); + assert!( (-0.0 .. 0.0).is_empty()); + assert!( (10.0 .. 0.0).is_empty()); + + assert!(!(NEG_INFINITY .. INFINITY).is_empty()); + assert!( (EPSILON .. NAN).is_empty()); + assert!( (NAN .. EPSILON).is_empty()); + assert!( (NAN .. NAN).is_empty()); + + assert!(!(0.0 ..= 10.0).is_empty()); + assert!(!(-0.0 ..= 0.0).is_empty()); + assert!( (10.0 ..= 0.0).is_empty()); + + assert!(!(NEG_INFINITY ..= INFINITY).is_empty()); + assert!( (EPSILON ..= NAN).is_empty()); + assert!( (NAN ..= EPSILON).is_empty()); + assert!( (NAN ..= NAN).is_empty()); +} \ No newline at end of file -- 2.44.0