vsrg 0.3.0

Data structures for vertical scrolling rhythm games
Documentation
/// Sort a list, and synchronize swapping to other parallel vecs.
///
/// This is used internally by [`crate::notes::ShortNoteGroup`] to keep its struct-of-arrays
/// components in the same order after sorting one index slice.
///
/// This currently allocates temporary permutation storage proportional to `list.len()`.
///
/// # Examples
/// ```
/// use vsrg::collections::sort_multi;
///
/// let mut keys = vec![3, 1, 2];
/// let mut values = vec!["three", "one", "two"];
///
/// sort_multi(&mut keys, |i, j| values.swap(i, j));
///
/// assert_eq!(keys, [1, 2, 3]);
/// assert_eq!(values, ["one", "two", "three"]);
/// ```
pub fn sort_multi<T: Ord>(list: &mut [T], mut swap: impl FnMut(usize, usize)) {
    let n = list.len();
    if n <= 1 {
        return;
    }

    let mut perm: Vec<usize> = (0..n).collect();
    perm.sort_by(|&a, &b| list[a].cmp(&list[b]));

    for i in 0..n {
        let mut j = i;
        loop {
            let k = perm[j];
            perm[j] = j;
            if k == i {
                break;
            }
            list.swap(j, k);
            swap(j, k);
            j = k;
        }
    }
}