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