1use std::ops::{Range, RangeFrom, RangeTo};
4
5pub trait Bisect {
43 type Input;
44 type Output;
45 fn bisect(&self, pred: impl FnMut(&Self::Input) -> bool) -> Self::Output;
46}
47
48macro_rules! impl_bisect_int {
49 ($t:ty) => {
50 impl Bisect for Range<$t> {
51 type Input = $t;
52 type Output = $t;
53 fn bisect(&self, mut pred: impl FnMut(&$t) -> bool) -> $t {
54 let Range { start: mut ok, end: mut bad } = *self;
55 if !pred(&ok) {
56 return ok;
57 }
58 while bad - ok > 1 {
59 let mid = ok + (bad - ok) / 2;
60 *(if pred(&mid) { &mut ok } else { &mut bad }) = mid;
61 }
62 bad
63 }
64 }
65
66 impl Bisect for RangeFrom<$t> {
67 type Input = $t;
68 type Output = $t;
69 fn bisect(&self, mut pred: impl FnMut(&$t) -> bool) -> $t {
70 let RangeFrom { start: ok } = *self;
71 if !pred(&ok) {
72 return ok;
73 }
74 let mut w = 1;
75 while pred(&(ok + w)) {
76 w *= 2;
77 }
78 (ok..ok + w).bisect(pred)
79 }
80 }
81
82 impl Bisect for RangeTo<$t> {
83 type Input = $t;
84 type Output = $t;
85 fn bisect(&self, mut pred: impl FnMut(&$t) -> bool) -> $t {
86 let RangeTo { end: bad } = *self;
87 if pred(&bad) {
88 return bad;
89 }
90 let mut w = 1;
91 while !pred(&(bad - w)) {
92 w *= 2;
93 }
94 (bad - w..bad).bisect(pred)
95 }
96 }
97
98 };
99 ( $( $t:ty )* ) => { $( impl_bisect_int! { $t } )* };
100}
101
102impl_bisect_int! { i8 i16 i32 i64 i128 isize u8 u16 u32 u64 u128 usize }
103
104macro_rules! impl_bisect_float {
105 (
106 $(
107 (
108 $fty:ty, $ity:ty, $uty:ty, $w:literal,
109 $f2u:ident, $u2f:ident, $mask:ident
110 ),
111 )*
112 ) => { $(
113 impl Bisect for Range<$fty> {
114 type Input = $fty;
115 type Output = $fty;
116 fn bisect(&self, mut pred: impl FnMut(&$fty) -> bool) -> $fty {
117 let Range { start, end } = *self;
118 let start = $f2u(start);
119 let end = $f2u(end);
120 $u2f((start..end).bisect(|&u| pred(&$u2f(u))))
121 }
122 }
123 fn $mask(u: $uty) -> $uty {
124 ((u as $ity >> ($w - 1)) as $uty >> 1) | 1 << ($w - 1)
125 }
126 fn $f2u(f: $fty) -> $uty {
127 let u = f.to_bits();
128 u ^ $mask(u)
129 }
130 fn $u2f(u: $uty) -> $fty { <$fty>::from_bits(u ^ $mask(!u)) }
131 )* };
132}
133
134impl_bisect_float! {
135 (f32, i32, u32, 32, f2u32, u2f32, mask32),
136 (f64, i64, u64, 64, f2u64, u2f64, mask64),
137}
138
139impl<T> Bisect for [T] {
140 type Input = T;
141 type Output = usize;
142 fn bisect(&self, mut pred: impl FnMut(&T) -> bool) -> usize {
143 if self.is_empty() || !pred(&self[0]) {
144 return 0;
145 }
146 let mut ok = 0;
147 let mut bad = self.len();
148 while bad - ok > 1 {
149 let mid = ok + (bad - ok) / 2;
150 *(if pred(&self[mid]) { &mut ok } else { &mut bad }) = mid;
151 }
152 bad
153 }
154}
155
156#[test]
157fn test() {
158 {
159 let pred = |&x: &i64| x < 100;
160 assert_eq!((0_i64..200).bisect(pred), 100);
161 assert_eq!((0_i64..).bisect(pred), 100);
162 assert_eq!((..200_i64).bisect(pred), 100);
163 }
164
165 {
166 let pred = |&x: &i64| x.abs() < 100;
167 assert_eq!((0_i64..200).bisect(pred), 100);
168 assert_eq!((0_i64..).bisect(pred), 100);
169 assert_eq!((..0_i64).bisect(|x| !pred(x)), -99);
170 }
171
172 {
173 let pred = |&x: &i64| x < 5;
174 let a = vec![0, 1, 4, 5, 5, 9];
175 assert_eq!(a.bisect(pred), 3);
176 assert_eq!(a[4..].bisect(pred), 0);
177 }
178
179 {
180 let pred = |&x: &f64| 2.0_f64.powf(x) < 3.0;
181 assert!(((1.0_f64..2.0).bisect(pred) - 3.0_f64.log2()) <= 5.0e-324);
182 }
185 {
186 assert_eq!([0, 1, 4, 5, 9].bisect(|&x: &i32| x < 5), 3);
187 assert_eq!((0..100).bisect(|&x: &i32| x * x < 200), 15);
188 assert_eq!((0..).bisect(|&x: &i32| x * x < 200), 15);
189 }
190 {
191 let pred = |&x: &i32| x * x < 200;
192 assert_eq!((0..100).bisect(pred), 15);
193 assert_eq!((0..).bisect(pred), 15);
194 }
195}