use std::cmp::Ordering;
pub fn sort_by_with_control<T, E>(
values: &mut [T],
poll: &mut dyn FnMut() -> Result<(), E>,
mut compare: impl FnMut(&T, &T, &mut dyn FnMut() -> Result<(), E>) -> Result<Ordering, E>,
) -> Result<(), E> {
fn sift<T, E>(
values: &mut [T],
mut root: usize,
poll: &mut dyn FnMut() -> Result<(), E>,
compare: &mut impl FnMut(&T, &T, &mut dyn FnMut() -> Result<(), E>) -> Result<Ordering, E>,
) -> Result<(), E> {
while root < values.len() / 2 {
poll()?;
let mut child = root * 2 + 1;
if child + 1 < values.len()
&& compare(&values[child], &values[child + 1], poll)?.is_lt()
{
child += 1;
}
if !compare(&values[root], &values[child], poll)?.is_lt() {
break;
}
values.swap(root, child);
root = child;
}
Ok(())
}
poll()?;
for root in (0..values.len() / 2).rev() {
sift(values, root, poll, &mut compare)?;
}
for end in (1..values.len()).rev() {
poll()?;
values.swap(0, end);
sift(&mut values[..end], 0, poll, &mut compare)?;
}
poll()
}
#[cfg(test)]
mod tests;