rayon/iter/
cloned.rs

1use super::plumbing::*;
2use super::*;
3
4use std::iter;
5
6/// `Cloned` is an iterator that clones the elements of an underlying iterator.
7///
8/// This struct is created by the [`cloned()`] method on [`ParallelIterator`]
9///
10/// [`cloned()`]: trait.ParallelIterator.html#method.cloned
11/// [`ParallelIterator`]: trait.ParallelIterator.html
12#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
13#[derive(Debug, Clone)]
14pub struct Cloned<I: ParallelIterator> {
15    base: I,
16}
17
18impl<I> Cloned<I>
19where
20    I: ParallelIterator,
21{
22    /// Creates a new `Cloned` iterator.
23    pub(super) fn new(base: I) -> Self {
24        Cloned { base }
25    }
26}
27
28impl<'a, T, I> ParallelIterator for Cloned<I>
29where
30    I: ParallelIterator<Item = &'a T>,
31    T: 'a + Clone + 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 = ClonedConsumer::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 Cloned<I>
49where
50    I: IndexedParallelIterator<Item = &'a T>,
51    T: 'a + Clone + Send + Sync,
52{
53    fn drive<C>(self, consumer: C) -> C::Result
54    where
55        C: Consumer<Self::Item>,
56    {
57        let consumer1 = ClonedConsumer::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 + Clone + 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 = ClonedProducer { base };
87                self.callback.callback(producer)
88            }
89        }
90    }
91}
92
93/// ////////////////////////////////////////////////////////////////////////
94
95struct ClonedProducer<P> {
96    base: P,
97}
98
99impl<'a, T, P> Producer for ClonedProducer<P>
100where
101    P: Producer<Item = &'a T>,
102    T: 'a + Clone,
103{
104    type Item = T;
105    type IntoIter = iter::Cloned<P::IntoIter>;
106
107    fn into_iter(self) -> Self::IntoIter {
108        self.base.into_iter().cloned()
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            ClonedProducer { base: left },
123            ClonedProducer { 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(ClonedFolder { base: folder }).base
132    }
133}
134
135/// ////////////////////////////////////////////////////////////////////////
136/// Consumer implementation
137
138struct ClonedConsumer<C> {
139    base: C,
140}
141
142impl<C> ClonedConsumer<C> {
143    fn new(base: C) -> Self {
144        ClonedConsumer { base }
145    }
146}
147
148impl<'a, T, C> Consumer<&'a T> for ClonedConsumer<C>
149where
150    C: Consumer<T>,
151    T: 'a + Clone,
152{
153    type Folder = ClonedFolder<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            ClonedConsumer::new(left),
161            ClonedConsumer::new(right),
162            reducer,
163        )
164    }
165
166    fn into_folder(self) -> Self::Folder {
167        ClonedFolder {
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 ClonedConsumer<C>
178where
179    C: UnindexedConsumer<T>,
180    T: 'a + Clone,
181{
182    fn split_off_left(&self) -> Self {
183        ClonedConsumer::new(self.base.split_off_left())
184    }
185
186    fn to_reducer(&self) -> Self::Reducer {
187        self.base.to_reducer()
188    }
189}
190
191struct ClonedFolder<F> {
192    base: F,
193}
194
195impl<'a, T, F> Folder<&'a T> for ClonedFolder<F>
196where
197    F: Folder<T>,
198    T: 'a + Clone,
199{
200    type Result = F::Result;
201
202    fn consume(self, item: &'a T) -> Self {
203        ClonedFolder {
204            base: self.base.consume(item.clone()),
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().cloned());
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}