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