par_iter/
array.rs

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 std::mem::ManuallyDrop;
9
10use crate::{
11    iter::{plumbing::*, *},
12    slice::{Iter, IterMut},
13    vec::DrainProducer,
14};
15
16impl<'data, T: Sync + 'data, const N: usize> IntoParallelIterator for &'data [T; N] {
17    type Item = &'data T;
18    type Iter = Iter<'data, T>;
19
20    fn into_par_iter(self) -> Self::Iter {
21        <&[T]>::into_par_iter(self)
22    }
23}
24
25impl<'data, T: Send + 'data, const N: usize> IntoParallelIterator for &'data mut [T; N] {
26    type Item = &'data mut T;
27    type Iter = IterMut<'data, T>;
28
29    fn into_par_iter(self) -> Self::Iter {
30        <&mut [T]>::into_par_iter(self)
31    }
32}
33
34impl<T: Send, const N: usize> IntoParallelIterator for [T; N] {
35    type Item = T;
36    type Iter = IntoIter<T, N>;
37
38    fn into_par_iter(self) -> Self::Iter {
39        IntoIter { array: self }
40    }
41}
42
43/// Parallel iterator that moves out of an array.
44#[derive(Debug, Clone)]
45pub struct IntoIter<T: Send, const N: usize> {
46    array: [T; N],
47}
48
49impl<T: Send, const N: usize> ParallelIterator for IntoIter<T, N> {
50    type Item = T;
51
52    fn drive_unindexed<C>(self, consumer: C) -> C::Result
53    where
54        C: UnindexedConsumer<Self::Item>,
55    {
56        bridge(self, consumer)
57    }
58
59    fn opt_len(&self) -> Option<usize> {
60        Some(N)
61    }
62}
63
64impl<T: Send, const N: usize> IndexedParallelIterator for IntoIter<T, N> {
65    fn drive<C>(self, consumer: C) -> C::Result
66    where
67        C: Consumer<Self::Item>,
68    {
69        bridge(self, consumer)
70    }
71
72    fn len(&self) -> usize {
73        N
74    }
75
76    fn with_producer<CB>(self, callback: CB) -> CB::Output
77    where
78        CB: ProducerCallback<Self::Item>,
79    {
80        unsafe {
81            // Drain every item, and then the local array can just fall out of scope.
82            let mut array = ManuallyDrop::new(self.array);
83            let producer = DrainProducer::new(array.as_mut_slice());
84            callback.callback(producer)
85        }
86    }
87}