binary_search_range/
lib.rs1use std::ops;
2
3pub trait BinarySearchRange<T> {
5 fn range(&self, range: ops::Range<T>) -> ops::Range<usize>;
6}
7
8impl<T: Ord> BinarySearchRange<T> for [T] {
9 fn range(&self, range: ops::Range<T>) -> ops::Range<usize> {
23 assert!(!self.is_empty());
24 assert!(range.start < range.end);
25
26 let first_ge = |x: &T| {
27 if x.le(&self[0]) {
28 return 0;
29 }
30 let mut left = 0;
31 let mut right = self.len();
33 while right - left > 1 {
34 let mid = (right + left) / 2;
35 if self[mid].lt(x) {
36 left = mid;
37 } else {
38 right = mid;
39 }
40 }
41 assert!(self[left].lt(x));
42 assert!(right <= self.len());
43 if right < self.len() {
44 assert!(x.le(&self[right]));
45 }
46 right
47 };
48
49 let start_index = first_ge(&range.start);
50 let end_index = first_ge(&range.end);
51 start_index..end_index
52 }
53}
54
55#[cfg(test)]
56mod tests {
57 use crate::BinarySearchRange;
58
59 #[test]
60 #[should_panic]
61 fn test_panic() {
62 vec![].range(0..10);
63 }
64
65 #[test]
66 #[should_panic]
67 fn test_panic2() {
68 vec![1, 2, 3].range(2..2);
69 }
70
71 #[test]
72 fn test_empty() {
73 assert_eq!(vec![3, 4, 8].range(0..3), 0..0);
74 assert_eq!(vec![3, 4, 8].range(5..8), 2..2);
75 assert_eq!(vec![3, 4, 8].range(9..12), 3..3);
76 }
77
78 #[test]
79 fn test_whole() {
80 let a = vec![3, 4, 5];
81 assert_eq!(a.range(3..6), 0..a.len());
82 assert_eq!(a.range(1..6), 0..a.len());
83 assert_eq!(a.range(3..7), 0..a.len());
84 assert_eq!(a.range(0..8), 0..a.len());
85 }
86
87 #[test]
88 fn test() {
89 let a = vec![2, 2, 5, 5, 6, 7, 10];
90 assert_eq!(a.range(0..3), 0..2);
91 assert_eq!(a.range(0..5), 0..2);
92 assert_eq!(a.range(0..6), 0..4);
93 assert_eq!(a.range(0..7), 0..5);
94 assert_eq!(a.range(0..8), 0..6);
95 assert_eq!(a.range(3..5), 2..2);
96 assert_eq!(a.range(3..6), 2..4);
97 assert_eq!(a.range(3..7), 2..5);
98 assert_eq!(a.range(3..8), 2..6);
99 }
100}