use crate::util::*;
pub fn shrink_stable_merge<T, F: Cmp<T>>(
left: &[T],
right: &[T],
is_less: &mut F,
) -> Option<(usize, usize)> {
if let (Some(l_last), Some(r_first)) = (left.last(), right.first()) {
if is_less(r_first, l_last) {
let first_l_to_r = left.iter().position(|l| is_less(r_first, l));
let last_r_to_l = right.iter().rposition(|r| is_less(r, l_last));
if let (Some(l), Some(r)) = (first_l_to_r, last_r_to_l) {
return Some((l, r + 1));
}
}
}
None
}
pub fn crossover_point<T, F: Cmp<T>>(left: &[T], right: &[T], is_less: &mut F) -> usize {
let n = left.len();
assert!(right.len() == n);
let mut lo = 0;
let mut maybe = n;
while maybe > 0 {
let step = maybe / 2;
let i = lo + step;
let i_valid = unsafe {
is_less(right.get_unchecked(n - 1 - i), left.get_unchecked(i))
};
if i_valid {
maybe = step;
} else {
lo += step + 1;
maybe -= step + 1;
}
}
lo
}
pub fn merge_splitpoints<T, F: Cmp<T>>(left: &[T], right: &[T], is_less: &mut F) -> (usize, usize) {
let minlen = left.len().min(right.len());
let left_skip = left.len() - minlen;
let i = crossover_point(&left[left_skip..], &right[..minlen], is_less);
(left_skip + i, minlen - i)
}