about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorCorey Farwell <coreyf@rwell.org>2017-02-28 22:55:27 -0500
committerGitHub <noreply@github.com>2017-02-28 22:55:27 -0500
commit43df65fb3fe554d451ea88ec75ec8cc2991d1a3e (patch)
treeba1fb2f32f65317f8ab67f5288fd716313029a14 /src
parent4ba49ab39f942af3846cf0d8599674b0adde94b5 (diff)
parent43382903a19ce209dee136e5f983003062b7ce78 (diff)
downloadrust-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.rs28
-rw-r--r--src/libcollectionstest/btree/map.rs37
-rw-r--r--src/libcollectionstest/lib.rs1
-rw-r--r--src/libcollectionstest/vec.rs50
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();