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 | |
18 | 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 | |
27 | 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 | |
36 | 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 | |
50 | fn drive_unindexed<C>(self, consumer: C) -> C::Result |
51 | where |
52 | C: UnindexedConsumer<Self::Item>, |
53 | { |
54 | bridge(self, consumer) |
55 | } |
56 | |
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> { |
63 | fn drive<C>(self, consumer: C) -> C::Result |
64 | where |
65 | C: Consumer<Self::Item>, |
66 | { |
67 | bridge(self, consumer) |
68 | } |
69 | |
70 | fn len(&self) -> usize { |
71 | N |
72 | } |
73 | |
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<[T; N]> = ManuallyDrop::new(self.array); |
81 | let producer: DrainProducer<'_, T> = DrainProducer::new(array.as_mut_slice()); |
82 | callback.callback(producer) |
83 | } |
84 | } |
85 | } |
86 | |