rayon/iter/
copied.rs

1use super::plumbing::*;
2use super::*;
3
4use std::iter;
5
6/// `Copied` is an iterator that copies the elements of an underlying iterator.
7///
8/// This struct is created by the [`copied()`] method on [`ParallelIterator`]
9///
10/// [`copied()`]: trait.ParallelIterator.html#method.copied
11/// [`ParallelIterator`]: trait.ParallelIterator.html
12#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
13#[derive(Debug, Clone)]
14pub struct Copied<I: ParallelIterator> {
15    base: I,
16}
17
18impl<I> Copied<I>
19where
20    I: ParallelIterator,
21{
22    /// Creates a new `Copied` iterator.
23    pub(super) fn new(base: I) -> Self {
24        Copied { base }
25    }
26}
27
28impl<'a, T, I> ParallelIterator for Copied<I>
29where
30    I: ParallelIterator<Item = &'a T>,
31    T: 'a + Copy + Send + Sync,
32{
33    type Item = T;
34
35    fn drive_unindexed<C>(self, consumer: C) -> C::Result
36    where
37        C: UnindexedConsumer<Self::Item>,
38    {
39        let consumer1 = CopiedConsumer::new(consumer);
40        self.base.drive_unindexed(consumer1)
41    }
42
43    fn opt_len(&self) -> Option<usize> {
44        self.base.opt_len()
45    }
46}
47
48impl<'a, T, I> IndexedParallelIterator for Copied<I>
49where
50    I: IndexedParallelIterator<Item = &'a T>,
51    T: 'a + Copy + Send + Sync,
52{
53    fn drive<C>(self, consumer: C) -> C::Result
54    where
55        C: Consumer<Self::Item>,
56    {
57        let consumer1 = CopiedConsumer::new(consumer);
58        self.base.drive(consumer1)
59    }
60
61    fn len(&self) -> usize {
62        self.base.len()
63    }
64
65    fn with_producer<CB>(self, callback: CB) -> CB::Output
66    where
67        CB: ProducerCallback<Self::Item>,
68    {
69        return self.base.with_producer(Callback { callback });
70
71        struct Callback<CB> {
72            callback: CB,
73        }
74
75        impl<'a, T, CB> ProducerCallback<&'a T> for Callback<CB>
76        where
77            CB: ProducerCallback<T>,
78            T: 'a + Copy + Send,
79        {
80            type Output = CB::Output;
81
82            fn callback<P>(self, base: P) -> CB::Output
83            where
84                P: Producer<Item = &'a T>,
85            {
86                let producer = CopiedProducer { base };
87                self.callback.callback(producer)
88            }
89        }
90    }
91}
92
93/// ////////////////////////////////////////////////////////////////////////
94
95struct CopiedProducer<P> {
96    base: P,
97}
98
99impl<'a, T, P> Producer for CopiedProducer<P>
100where
101    P: Producer<Item = &'a T>,
102    T: 'a + Copy,
103{
104    type Item = T;
105    type IntoIter = iter::Copied<P::IntoIter>;
106
107    fn into_iter(self) -> Self::IntoIter {
108        self.base.into_iter().copied()
109    }
110
111    fn min_len(&self) -> usize {
112        self.base.min_len()
113    }
114
115    fn max_len(&self) -> usize {
116        self.base.max_len()
117    }
118
119    fn split_at(self, index: usize) -> (Self, Self) {
120        let (left, right) = self.base.split_at(index);
121        (
122            CopiedProducer { base: left },
123            CopiedProducer { base: right },
124        )
125    }
126
127    fn fold_with<F>(self, folder: F) -> F
128    where
129        F: Folder<Self::Item>,
130    {
131        self.base.fold_with(CopiedFolder { base: folder }).base
132    }
133}
134
135/// ////////////////////////////////////////////////////////////////////////
136/// Consumer implementation
137
138struct CopiedConsumer<C> {
139    base: C,
140}
141
142impl<C> CopiedConsumer<C> {
143    fn new(base: C) -> Self {
144        CopiedConsumer { base }
145    }
146}
147
148impl<'a, T, C> Consumer<&'a T> for CopiedConsumer<C>
149where
150    C: Consumer<T>,
151    T: 'a + Copy,
152{
153    type Folder = CopiedFolder<C::Folder>;
154    type Reducer = C::Reducer;
155    type Result = C::Result;
156
157    fn split_at(self, index: usize) -> (Self, Self, Self::Reducer) {
158        let (left, right, reducer) = self.base.split_at(index);
159        (
160            CopiedConsumer::new(left),
161            CopiedConsumer::new(right),
162            reducer,
163        )
164    }
165
166    fn into_folder(self) -> Self::Folder {
167        CopiedFolder {
168            base: self.base.into_folder(),
169        }
170    }
171
172    fn full(&self) -> bool {
173        self.base.full()
174    }
175}
176
177impl<'a, T, C> UnindexedConsumer<&'a T> for CopiedConsumer<C>
178where
179    C: UnindexedConsumer<T>,
180    T: 'a + Copy,
181{
182    fn split_off_left(&self) -> Self {
183        CopiedConsumer::new(self.base.split_off_left())
184    }
185
186    fn to_reducer(&self) -> Self::Reducer {
187        self.base.to_reducer()
188    }
189}
190
191struct CopiedFolder<F> {
192    base: F,
193}
194
195impl<'a, T, F> Folder<&'a T> for CopiedFolder<F>
196where
197    F: Folder<T>,
198    T: 'a + Copy,
199{
200    type Result = F::Result;
201
202    fn consume(self, &item: &'a T) -> Self {
203        CopiedFolder {
204            base: self.base.consume(item),
205        }
206    }
207
208    fn consume_iter<I>(mut self, iter: I) -> Self
209    where
210        I: IntoIterator<Item = &'a T>,
211    {
212        self.base = self.base.consume_iter(iter.into_iter().copied());
213        self
214    }
215
216    fn complete(self) -> F::Result {
217        self.base.complete()
218    }
219
220    fn full(&self) -> bool {
221        self.base.full()
222    }
223}