1 #![cfg(min_const_generics)] 2 //! Parallel iterator types for [arrays] (`[T; N]`) 3 //! 4 //! You will rarely need to interact with this module directly unless you need 5 //! to name one of the iterator types. 6 //! 7 //! Everything in this module requires const generics, stabilized in Rust 1.51. 8 //! 9 //! [arrays]: https://doc.rust-lang.org/std/primitive.array.html 10 11 use crate::iter::plumbing::*; 12 use crate::iter::*; 13 use crate::slice::{Iter, IterMut}; 14 use crate::vec::DrainProducer; 15 use std::mem::ManuallyDrop; 16 17 /// This implementation requires const generics, stabilized in Rust 1.51. 18 impl<'data, T: Sync + 'data, const N: usize> IntoParallelIterator for &'data [T; N] { 19 type Item = &'data T; 20 type Iter = Iter<'data, T>; 21 into_par_iter(self) -> Self::Iter22 fn into_par_iter(self) -> Self::Iter { 23 <&[T]>::into_par_iter(self) 24 } 25 } 26 27 /// This implementation requires const generics, stabilized in Rust 1.51. 28 impl<'data, T: Send + 'data, const N: usize> IntoParallelIterator for &'data mut [T; N] { 29 type Item = &'data mut T; 30 type Iter = IterMut<'data, T>; 31 into_par_iter(self) -> Self::Iter32 fn into_par_iter(self) -> Self::Iter { 33 <&mut [T]>::into_par_iter(self) 34 } 35 } 36 37 /// This implementation requires const generics, stabilized in Rust 1.51. 38 impl<T: Send, const N: usize> IntoParallelIterator for [T; N] { 39 type Item = T; 40 type Iter = IntoIter<T, N>; 41 into_par_iter(self) -> Self::Iter42 fn into_par_iter(self) -> Self::Iter { 43 IntoIter { array: self } 44 } 45 } 46 47 /// Parallel iterator that moves out of an array. 48 #[derive(Debug, Clone)] 49 pub struct IntoIter<T: Send, const N: usize> { 50 array: [T; N], 51 } 52 53 impl<T: Send, const N: usize> ParallelIterator for IntoIter<T, N> { 54 type Item = T; 55 drive_unindexed<C>(self, consumer: C) -> C::Result where C: UnindexedConsumer<Self::Item>,56 fn drive_unindexed<C>(self, consumer: C) -> C::Result 57 where 58 C: UnindexedConsumer<Self::Item>, 59 { 60 bridge(self, consumer) 61 } 62 opt_len(&self) -> Option<usize>63 fn opt_len(&self) -> Option<usize> { 64 Some(N) 65 } 66 } 67 68 impl<T: Send, const N: usize> IndexedParallelIterator for IntoIter<T, N> { drive<C>(self, consumer: C) -> C::Result where C: Consumer<Self::Item>,69 fn drive<C>(self, consumer: C) -> C::Result 70 where 71 C: Consumer<Self::Item>, 72 { 73 bridge(self, consumer) 74 } 75 len(&self) -> usize76 fn len(&self) -> usize { 77 N 78 } 79 with_producer<CB>(self, callback: CB) -> CB::Output where CB: ProducerCallback<Self::Item>,80 fn with_producer<CB>(self, callback: CB) -> CB::Output 81 where 82 CB: ProducerCallback<Self::Item>, 83 { 84 unsafe { 85 // Drain every item, and then the local array can just fall out of scope. 86 let mut array = ManuallyDrop::new(self.array); 87 callback.callback(DrainProducer::new(&mut *array)) 88 } 89 } 90 } 91