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