use crate::mut_slice::states::AlwaysInit;
use crate::mut_slice::MutSlice;
use crate::util::*;
#[inline]
pub fn select_pivot<'l, 'r, BL, BR, T, F: Cmp<T>>(
left: MutSlice<'l, BL, T, AlwaysInit>,
right: MutSlice<'r, BR, T, AlwaysInit>,
is_less: &mut F,
) -> *mut T {
unsafe {
let left = left.raw();
let right = right.raw();
let n = left.len() + right.len();
let a = if left.len() >= n / 8 {
left.begin()
} else {
right.begin()
};
let b = if left.len() >= n / 2 {
left.begin().add(n / 2).sub(n / 8)
} else {
right.end().sub(n / 2)
};
let c = if right.len() >= n / 8 {
right.end().sub(n / 8)
} else {
left.end().sub(n / 8)
};
if n < crate::PSEUDO_MEDIAN_REC_THRESHOLD {
median3(a, b, c, is_less)
} else {
median3_rec(a, b, c, n / 8, is_less)
}
}
}
#[cold]
pub unsafe fn median3_rec<T, F: Cmp<T>>(
mut a: *mut T,
mut b: *mut T,
mut c: *mut T,
n: usize,
is_less: &mut F,
) -> *mut T {
unsafe {
if n * 8 >= crate::PSEUDO_MEDIAN_REC_THRESHOLD {
let n8 = n / 8;
a = median3_rec(a, a.add(n8 * 4), a.add(n8 * 7), n8, is_less);
b = median3_rec(b, b.add(n8 * 4), b.add(n8 * 7), n8, is_less);
c = median3_rec(c, c.add(n8 * 4), c.add(n8 * 7), n8, is_less);
}
median3(a, b, c, is_less)
}
}
#[inline(always)]
unsafe fn median3<T, F: Cmp<T>>(a: *mut T, b: *mut T, c: *mut T, is_less: &mut F) -> *mut T {
unsafe {
let x = is_less(&*a, &*b);
let y = is_less(&*a, &*c);
if x == y {
let z = is_less(&*b, &*c);
select(z ^ x, c, b)
} else {
a
}
}
}