diff options
| author | Corey Farwell <coreyf@rwell.org> | 2017-02-28 22:55:27 -0500 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2017-02-28 22:55:27 -0500 |
| commit | 43df65fb3fe554d451ea88ec75ec8cc2991d1a3e (patch) | |
| tree | ba1fb2f32f65317f8ab67f5288fd716313029a14 /src | |
| parent | 4ba49ab39f942af3846cf0d8599674b0adde94b5 (diff) | |
| parent | 43382903a19ce209dee136e5f983003062b7ce78 (diff) | |
| download | rust-43df65fb3fe554d451ea88ec75ec8cc2991d1a3e.tar.gz rust-43df65fb3fe554d451ea88ec75ec8cc2991d1a3e.zip | |
Rollup merge of #39936 - djzin:inclusive_rangeargument, r=alexcrichton
impl RangeArgument for RangeInclusive and add appropriate tests Now that `RangeArgument` returns a `Bound`, the impl for `RangeInclusive` is natural to implement and all that's required are tests around it.
Diffstat (limited to 'src')
| -rw-r--r-- | src/libcollections/range.rs | 28 | ||||
| -rw-r--r-- | src/libcollectionstest/btree/map.rs | 37 | ||||
| -rw-r--r-- | src/libcollectionstest/lib.rs | 1 | ||||
| -rw-r--r-- | src/libcollectionstest/vec.rs | 50 |
4 files changed, 115 insertions, 1 deletions
diff --git a/src/libcollections/range.rs b/src/libcollections/range.rs index 1df4ace3777..e4b94a1d70e 100644 --- a/src/libcollections/range.rs +++ b/src/libcollections/range.rs @@ -14,7 +14,7 @@ //! Range syntax. -use core::ops::{RangeFull, Range, RangeTo, RangeFrom}; +use core::ops::{RangeFull, Range, RangeTo, RangeFrom, RangeInclusive, RangeToInclusive}; use Bound::{self, Excluded, Included, Unbounded}; /// **RangeArgument** is implemented by Rust's built-in range types, produced @@ -105,6 +105,32 @@ impl<T> RangeArgument<T> for Range<T> { } } +#[unstable(feature = "inclusive_range", reason = "recently added, follows RFC", issue = "28237")] +impl<T> RangeArgument<T> for RangeInclusive<T> { + fn start(&self) -> Bound<&T> { + match *self { + RangeInclusive::Empty{ ref at } => Included(at), + RangeInclusive::NonEmpty { ref start, .. } => Included(start), + } + } + fn end(&self) -> Bound<&T> { + match *self { + RangeInclusive::Empty{ ref at } => Excluded(at), + RangeInclusive::NonEmpty { ref end, .. } => Included(end), + } + } +} + +#[unstable(feature = "inclusive_range", reason = "recently added, follows RFC", issue = "28237")] +impl<T> RangeArgument<T> for RangeToInclusive<T> { + fn start(&self) -> Bound<&T> { + Unbounded + } + fn end(&self) -> Bound<&T> { + Included(&self.end) + } +} + impl<T> RangeArgument<T> for (Bound<T>, Bound<T>) { fn start(&self) -> Bound<&T> { match *self { diff --git a/src/libcollectionstest/btree/map.rs b/src/libcollectionstest/btree/map.rs index f33923f9963..2c899d96940 100644 --- a/src/libcollectionstest/btree/map.rs +++ b/src/libcollectionstest/btree/map.rs @@ -179,6 +179,43 @@ fn test_range_small() { } #[test] +fn test_range_inclusive() { + let size = 500; + + let map: BTreeMap<_, _> = (0...size).map(|i| (i, i)).collect(); + + fn check<'a, L, R>(lhs: L, rhs: R) + where L: IntoIterator<Item=(&'a i32, &'a i32)>, + R: IntoIterator<Item=(&'a i32, &'a i32)>, + { + let lhs: Vec<_> = lhs.into_iter().collect(); + let rhs: Vec<_> = rhs.into_iter().collect(); + assert_eq!(lhs, rhs); + } + + check(map.range(size + 1...size + 1), vec![]); + check(map.range(size...size), vec![(&size, &size)]); + check(map.range(size...size + 1), vec![(&size, &size)]); + check(map.range(0...0), vec![(&0, &0)]); + check(map.range(0...size - 1), map.range(..size)); + check(map.range(-1...-1), vec![]); + check(map.range(-1...size), map.range(..)); + check(map.range(...size), map.range(..)); + check(map.range(...200), map.range(..201)); + check(map.range(5...8), vec![(&5, &5), (&6, &6), (&7, &7), (&8, &8)]); + check(map.range(-1...0), vec![(&0, &0)]); + check(map.range(-1...2), vec![(&0, &0), (&1, &1), (&2, &2)]); +} + +#[test] +fn test_range_inclusive_max_value() { + let max = ::std::usize::MAX; + let map: BTreeMap<_, _> = vec![(max, 0)].into_iter().collect(); + + assert_eq!(map.range(max...max).collect::<Vec<_>>(), &[(&max, &0)]); +} + +#[test] fn test_range_equal_empty_cases() { let map: BTreeMap<_, _> = (0..5).map(|i| (i, i)).collect(); assert_eq!(map.range((Included(2), Excluded(2))).next(), None); diff --git a/src/libcollectionstest/lib.rs b/src/libcollectionstest/lib.rs index 57e3c2df059..849d2401691 100644 --- a/src/libcollectionstest/lib.rs +++ b/src/libcollectionstest/lib.rs @@ -14,6 +14,7 @@ #![feature(binary_heap_peek_mut_pop)] #![feature(box_syntax)] #![feature(btree_range)] +#![feature(inclusive_range_syntax)] #![feature(collection_placement)] #![feature(collections)] #![feature(collections_bound)] diff --git a/src/libcollectionstest/vec.rs b/src/libcollectionstest/vec.rs index edeedf1d40b..06d70800d39 100644 --- a/src/libcollectionstest/vec.rs +++ b/src/libcollectionstest/vec.rs @@ -508,6 +508,56 @@ fn test_drain_range() { } #[test] +fn test_drain_inclusive_range() { + let mut v = vec!['a', 'b', 'c', 'd', 'e']; + for _ in v.drain(1...3) { + } + assert_eq!(v, &['a', 'e']); + + let mut v: Vec<_> = (0...5).map(|x| x.to_string()).collect(); + for _ in v.drain(1...5) { + } + assert_eq!(v, &["0".to_string()]); + + let mut v: Vec<String> = (0...5).map(|x| x.to_string()).collect(); + for _ in v.drain(0...5) { + } + assert_eq!(v, Vec::<String>::new()); + + let mut v: Vec<_> = (0...5).map(|x| x.to_string()).collect(); + for _ in v.drain(0...3) { + } + assert_eq!(v, &["4".to_string(), "5".to_string()]); + + let mut v: Vec<_> = (0...1).map(|x| x.to_string()).collect(); + for _ in v.drain(...0) { + } + assert_eq!(v, &["1".to_string()]); +} + +#[test] +fn test_drain_max_vec_size() { + let mut v = Vec::<()>::with_capacity(usize::max_value()); + unsafe { v.set_len(usize::max_value()); } + for _ in v.drain(usize::max_value() - 1..) { + } + assert_eq!(v.len(), usize::max_value() - 1); + + let mut v = Vec::<()>::with_capacity(usize::max_value()); + unsafe { v.set_len(usize::max_value()); } + for _ in v.drain(usize::max_value() - 1...usize::max_value() - 1) { + } + assert_eq!(v.len(), usize::max_value() - 1); +} + +#[test] +#[should_panic] +fn test_drain_inclusive_out_of_bounds() { + let mut v = vec![1, 2, 3, 4, 5]; + v.drain(5...5); +} + +#[test] fn test_into_boxed_slice() { let xs = vec![1, 2, 3]; let ys = xs.into_boxed_slice(); |
