1 use std::collections::BTreeSet;
2 use std::ops::Bound::{self, *};
3 
4 use quickcheck::{quickcheck, TestResult};
5 
6 /// Covers every `std::ops::Range*` plus variants with exclusive start.
7 type RangeAny<T> = (Bound<T>, Bound<T>);
8 
9 /// Mimic `RangeBounds::contains`, stabilized in Rust 1.35.
10 trait RangeBounds<T> {
contains(&self, _: &T) -> bool11     fn contains(&self, _: &T) -> bool;
12 }
13 
14 impl<T: PartialOrd> RangeBounds<T> for RangeAny<T> {
contains(&self, item: &T) -> bool15     fn contains(&self, item: &T) -> bool {
16         (match &self.0 {
17             Included(start) => start <= item,
18             Excluded(start) => start < item,
19             Unbounded => true,
20         }) && (match &self.1 {
21             Included(end) => item <= end,
22             Excluded(end) => item < end,
23             Unbounded => true,
24         })
25     }
26 }
27 
28 /// Checks conditions where `BTreeSet::range` panics:
29 /// - Panics if range start > end.
30 /// - Panics if range start == end and both bounds are Excluded.
panics<T: PartialOrd>(range: RangeAny<T>) -> bool31 fn panics<T: PartialOrd>(range: RangeAny<T>) -> bool {
32     match (&range.0, &range.1) {
33         (Excluded(start), Excluded(end)) => start >= end,
34         (Included(start), Excluded(end))
35         | (Excluded(start), Included(end))
36         | (Included(start), Included(end)) => start > end,
37         (Unbounded, _) | (_, Unbounded) => false,
38     }
39 }
40 
41 /// Checks that `BTreeSet::range` returns all items contained in the given `range`.
check_range(set: BTreeSet<i32>, range: RangeAny<i32>) -> TestResult42 fn check_range(set: BTreeSet<i32>, range: RangeAny<i32>) -> TestResult {
43     if panics(range) {
44         TestResult::discard()
45     } else {
46         let xs: BTreeSet<_> = set.range(range).cloned().collect();
47         TestResult::from_bool(
48             set.iter().all(|x| range.contains(x) == xs.contains(x)),
49         )
50     }
51 }
52 
main()53 fn main() {
54     quickcheck(check_range as fn(_, _) -> TestResult);
55 }
56