rayon/
array.rs

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
11use crate::iter::plumbing::*;
12use crate::iter::*;
13use crate::slice::{Iter, IterMut};
14use crate::vec::DrainProducer;
15use std::mem::ManuallyDrop;
16
17/// This implementation requires const generics, stabilized in Rust 1.51.
18impl<'data, T: Sync + 'data, const N: usize> IntoParallelIterator for &'data [T; N] {
19    type Item = &'data T;
20    type Iter = Iter<'data, T>;
21
22    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.
28impl<'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
32    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.
38impl<T: Send, const N: usize> IntoParallelIterator for [T; N] {
39    type Item = T;
40    type Iter = IntoIter<T, N>;
41
42    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)]
49pub struct IntoIter<T: Send, const N: usize> {
50    array: [T; N],
51}
52
53impl<T: Send, const N: usize> ParallelIterator for IntoIter<T, N> {
54    type Item = T;
55
56    fn drive_unindexed<C>(self, consumer: C) -> C::Result
57    where
58        C: UnindexedConsumer<Self::Item>,
59    {
60        bridge(self, consumer)
61    }
62
63    fn opt_len(&self) -> Option<usize> {
64        Some(N)
65    }
66}
67
68impl<T: Send, const N: usize> IndexedParallelIterator for IntoIter<T, N> {
69    fn drive<C>(self, consumer: C) -> C::Result
70    where
71        C: Consumer<Self::Item>,
72    {
73        bridge(self, consumer)
74    }
75
76    fn len(&self) -> usize {
77        N
78    }
79
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}