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.
This commit is contained in:
commit
43df65fb3f
@ -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 {
|
||||
|
@ -178,6 +178,43 @@ fn test_range_small() {
|
||||
assert_eq!(j, size - 2);
|
||||
}
|
||||
|
||||
#[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();
|
||||
|
@ -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)]
|
||||
|
@ -507,6 +507,56 @@ fn test_drain_range() {
|
||||
assert_eq!(v, &[(), ()]);
|
||||
}
|
||||
|
||||
#[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];
|
||||
|
Loading…
Reference in New Issue
Block a user