#[cfg(test)]
mod tests;
pub fn binary_search_slice<'d, E, K>(data: &'d [E], key_fn: impl Fn(&E) -> K, key: &K) -> &'d [E]
where
K: Ord,
{
let size = data.len();
let start = data.partition_point(|x| key_fn(x) < *key);
if start == size || key_fn(&data[start]) != *key {
return &[];
};
let mut end = start;
let mut previous = start;
let mut step = 1;
loop {
end = end.saturating_add(step).min(size);
if end == size || key_fn(&data[end]) != *key {
break;
}
previous = end;
step *= 2;
}
step = end - previous;
while step > 1 {
let half = step / 2;
let mid = end - half;
if key_fn(&data[mid]) != *key {
end = mid;
}
step -= half;
}
&data[start..end]
}