select_indices 3.0.0

Iterators for taking multiple shared/exclusive references from a slice
Documentation
use crate::{
    prelude::*,
    mutable::iter::ParSelectIndicesMutIter,
    indexed_type::{ Unindexed, Indexed },
};
use rayon::{
    prelude::*,
    iter::plumbing::{ Consumer, UnindexedConsumer },
};
use force_send_sync::Sync as ForceSync;

mod unindexed {
    use super::*;

    impl<'a, Data, Indices> ParallelIterator for ParSelectIndicesMutIter<'a, Data, Indices, Unindexed>
    where
        Indices: ParallelIterator,
        Indices::Item: Copy,
        Data: Send + OneToOne<Indices::Item>,
        Data::Output: 'a + Send,
    {
        type Item = &'a mut Data::Output;

        fn drive_unindexed<C>(self, consumer: C) -> C::Result
        where
            C: UnindexedConsumer<Self::Item>
        {
            let ptr: ForceSync<*mut _> = unsafe { ForceSync::new(self.data) };
            let visited_refs = self.visited_refs;
            self.indices.map(|index| {
                let data = unsafe { (*ptr).as_mut().unwrap() };
                
                let val_ref = data.index_mut(index);

                let val_ptr_num = (val_ref as *mut Data::Output).cast::<*mut ()>() as usize;

                assert!(visited_refs.lock().unwrap().insert(val_ptr_num), "par_select_indices_mut was passed duplicate indices!");

                val_ref
            }).drive_unindexed(consumer)
        }
    }

    impl<'a, Data, Indices> IndexedParallelIterator for ParSelectIndicesMutIter<'a, Data, Indices, Unindexed>
    where
        Indices: IndexedParallelIterator,
        Indices::Item: Copy,
        Data: Send + OneToOne<Indices::Item>,
        Data::Output: 'a + Send,
    {
        fn len(&self) -> usize {
            self.indices.len()
        }

        fn drive<C: Consumer<Self::Item>>(self, consumer: C) -> C::Result {
            let ptr: ForceSync<*mut _> = unsafe { ForceSync::new(self.data) };
            let visited_refs = self.visited_refs;
            self.indices.map(|index| {
                let data = unsafe { (*ptr).as_mut().unwrap() };
                
                let val_ref = data.index_mut(index);

                let val_ptr_num = (val_ref as *mut Data::Output).cast::<*mut ()>() as usize;

                assert!(visited_refs.lock().unwrap().insert(val_ptr_num), "par_select_indices_mut was passed duplicate indices!");

                val_ref
            }).drive(consumer)
        }

        fn with_producer<CB: rayon::iter::plumbing::ProducerCallback<Self::Item>>(self, callback: CB) -> CB::Output {
            let ptr: ForceSync<*mut _> = unsafe { ForceSync::new(self.data) };
            let visited_refs = self.visited_refs;
            self.indices.map(|index| {
                let data = unsafe { (*ptr).as_mut().unwrap() };
                
                let val_ref = data.index_mut(index);

                let val_ptr_num = (val_ref as *mut Data::Output).cast::<*mut ()>() as usize;

                assert!(visited_refs.lock().unwrap().insert(val_ptr_num), "par_select_indices_mut was passed duplicate indices!");

                val_ref
            }).with_producer(callback)
        }
    }
}
mod indexed {
    use super::*;

    impl<'a, Data, Indices> ParallelIterator for ParSelectIndicesMutIter<'a, Data, Indices, Indexed>
    where
        Indices: ParallelIterator,
        Indices::Item: Copy,
        Data: Send + OneToOne<Indices::Item>,
        Data::Output: 'a + Send,
    {
        type Item = (Indices::Item, &'a mut Data::Output);

        fn drive_unindexed<C>(self, consumer: C) -> C::Result
        where
            C: UnindexedConsumer<Self::Item>
        {
            let ptr: ForceSync<*mut _> = unsafe { ForceSync::new(self.data) };
            let visited_refs = self.visited_refs;
            self.indices.map(|index| {
                let data = unsafe { (*ptr).as_mut().unwrap() };
                
                let val_ref = data.index_mut(index);

                let val_ptr_num = (val_ref as *mut Data::Output).cast::<*mut ()>() as usize;

                assert!(visited_refs.lock().unwrap().insert(val_ptr_num), "par_select_indices_mut was passed duplicate indices!");

                (index, val_ref)
            }).drive_unindexed(consumer)
        }
    }

    impl<'a, Data, Indices> IndexedParallelIterator for ParSelectIndicesMutIter<'a, Data, Indices, Indexed>
    where
        Indices: IndexedParallelIterator,
        Indices::Item: Copy,
        Data: Send + OneToOne<Indices::Item>,
        Data::Output: 'a + Send,
    {
        fn len(&self) -> usize {
            self.indices.len()
        }

        fn drive<C: Consumer<Self::Item>>(self, consumer: C) -> C::Result {
            let ptr: ForceSync<*mut _> = unsafe { ForceSync::new(self.data) };
            let visited_refs = self.visited_refs;
            self.indices.map(|index| {
                let data = unsafe { (*ptr).as_mut().unwrap() };
                
                let val_ref = data.index_mut(index);

                let val_ptr_num = (val_ref as *mut Data::Output).cast::<*mut ()>() as usize;

                assert!(visited_refs.lock().unwrap().insert(val_ptr_num), "par_select_indices_mut was passed duplicate indices!");

                (index, val_ref)
            }).drive(consumer)
        }

        fn with_producer<CB: rayon::iter::plumbing::ProducerCallback<Self::Item>>(self, callback: CB) -> CB::Output {
            let ptr: ForceSync<*mut _> = unsafe { ForceSync::new(self.data) };
            let visited_refs = self.visited_refs;
            self.indices.map(|index| {
                let data = unsafe { (*ptr).as_mut().unwrap() };
                
                let val_ref = data.index_mut(index);

                let val_ptr_num = (val_ref as *mut Data::Output).cast::<*mut ()>() as usize;

                assert!(visited_refs.lock().unwrap().insert(val_ptr_num), "par_select_indices_mut was passed duplicate indices!");

                (index, val_ref)
            }).with_producer(callback)
        }
    }
}