use std::mem::MaybeUninit;
use crate::{Item, Key};
unsafe fn stable_partition_linear<T, F>(slice: &mut [T], mut predicate: F) -> usize
where
F: FnMut(&T) -> bool,
{
unsafe {
let len = slice.len();
if len == 0 {
return 0;
}
let mut false_buf = Vec::<MaybeUninit<T>>::with_capacity(len);
let slice_ptr = slice.as_mut_ptr();
let false_ptr = false_buf.as_mut_ptr() as *mut T;
let mut true_idx = 0;
let mut false_idx = 0;
for i in 0..len {
let item_ptr = slice_ptr.add(i);
if predicate(&*item_ptr) {
if i != true_idx {
std::ptr::copy_nonoverlapping(item_ptr, slice_ptr.add(true_idx), 1);
}
true_idx += 1;
} else {
std::ptr::copy_nonoverlapping(item_ptr, false_ptr.add(false_idx), 1);
false_idx += 1;
}
}
std::ptr::copy_nonoverlapping(false_ptr, slice_ptr.add(true_idx), false_idx);
true_idx
}
}
pub(crate) fn ensure_body_order(entries: &mut [(Key<'_>, Item<'_>)]) {
let mut seen_sub = false;
let mut needs_reorder = false;
for (_, item) in entries.iter() {
if item.is_subsection() {
seen_sub = true;
} else if seen_sub {
needs_reorder = true;
break;
}
}
if !needs_reorder {
return;
}
unsafe {
stable_partition_linear(entries, |(_, item)| !item.is_subsection());
}
}