use super::scout::ScoutResult;
use crate::view::{Arr, reverse_range};
#[inline]
pub fn reverse_all<V: Arr>(a: V, n: usize) {
#[cfg(all(target_arch = "x86_64", not(brainsort_no_simd)))]
{
use crate::view::Hooks;
let sz = core::mem::size_of::<V::T>();
if !<V::H as Hooks>::COUNTED && (sz == 4 || sz == 8 || sz == 16) && crate::cpu::have_avx2() {
unsafe { crate::simd::x86::reverse_avx2::<V::T>(a.data(), n) };
return;
}
}
reverse_range(a, 0, n);
}
pub fn stable_reverse<V: Arr>(a: V, n: usize, s: &ScoutResult) {
reverse_all(a, n);
if s.descents == n - 1 {
return; }
if s.tracking {
for j in 0..s.runs {
let (lo, hi);
if s.dir[j] > 0 {
lo = if j > 0 && s.dir[j - 1] < 0 { s.bound[j] - 1 } else { s.bound[j] };
hi = s.bound[j + 1];
} else if j + 1 < s.runs && s.dir[j + 1] < 0 {
lo = s.bound[j + 1] - 1;
hi = lo + 2;
} else {
continue;
}
if hi - lo > 1 {
reverse_range(a, n - hi, n - lo); }
}
return;
}
let mut i = 0;
while i < n {
let mut j = i + 1;
let first = a.get(i);
while j < n {
let cur = a.get(j);
if a.less(first, cur) || a.less(cur, first) {
break;
}
j += 1;
}
if j - i > 1 {
reverse_range(a, i, j);
}
i = j;
}
}