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
8use crate::iter::plumbing::*;
9use crate::iter::*;
10use crate::slice::{Iter, IterMut};
11use crate::vec::DrainProducer;
12use std::mem::ManuallyDrop;
13
14impl<'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
23impl<'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
32impl<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)]
43pub struct IntoIter<T: Send, const N: usize> {
44 array: [T; N],
45}
46
47impl<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
62impl<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