orx-parallel 4.0.0

Performant parallel computations with an expressive iterator API.
Documentation
use crate::runner::ParRunner;
use alloc::vec::Vec;

pub fn into_outer_par<'a, T, M, F, R>(
    outer: &'a mut Vec<T>,
    locals: &'a mut [M],
    local_data: F,
    runner: &mut R,
) where
    R: ParRunner,
    F: Fn(&'a mut M) -> &'a mut Vec<T>,
{
    use crate::*;
    struct Cpy<T> {
        src: *mut T,
        dst: *mut T,
        len: usize,
    }
    unsafe impl<T> Send for Cpy<T> {}
    unsafe impl<T> Sync for Cpy<T> {}

    let total_len: usize = {
        let locals = unsafe { &mut *(locals as *mut [M]) };
        locals.iter_mut().map(|x| local_data(x).len()).sum()
    };
    outer.reserve(total_len);

    let ops = {
        let locals = unsafe { &mut *(locals as *mut [M]) };
        let mut ptrs = Vec::with_capacity(locals.len());
        let mut begin = outer.len();
        for local in locals {
            let local = local_data(local);
            let (src, len) = (local.as_mut_ptr(), local.len());
            let dst = unsafe { outer.as_mut_ptr().add(begin) };
            ptrs.push(Cpy { src, dst, len });
            begin += len;
            unsafe { local.set_len(0) };
        }
        ptrs
    };

    let par = ops.into_par().runner(runner);
    par.for_each(|op: Cpy<T>| {
        let Cpy { src, dst, len } = op;
        unsafe { src.copy_to_nonoverlapping(dst, len) };
    });

    unsafe { outer.set_len(outer.len() + total_len) };
}