1 use super::plumbing::*;
2 use super::*;
3 use std::iter;
4 
5 /// `Rev` is an iterator that produces elements in reverse order. This struct
6 /// is created by the [`rev()`] method on [`IndexedParallelIterator`]
7 ///
8 /// [`rev()`]: trait.IndexedParallelIterator.html#method.rev
9 /// [`IndexedParallelIterator`]: trait.IndexedParallelIterator.html
10 #[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
11 #[derive(Debug, Clone)]
12 pub struct Rev<I: IndexedParallelIterator> {
13     base: I,
14 }
15 
16 impl<I> Rev<I>
17 where
18     I: IndexedParallelIterator,
19 {
20     /// Creates a new `Rev` iterator.
new(base: I) -> Self21     pub(super) fn new(base: I) -> Self {
22         Rev { base }
23     }
24 }
25 
26 impl<I> ParallelIterator for Rev<I>
27 where
28     I: IndexedParallelIterator,
29 {
30     type Item = I::Item;
31 
drive_unindexed<C>(self, consumer: C) -> C::Result where C: UnindexedConsumer<Self::Item>,32     fn drive_unindexed<C>(self, consumer: C) -> C::Result
33     where
34         C: UnindexedConsumer<Self::Item>,
35     {
36         bridge(self, consumer)
37     }
38 
opt_len(&self) -> Option<usize>39     fn opt_len(&self) -> Option<usize> {
40         Some(self.len())
41     }
42 }
43 
44 impl<I> IndexedParallelIterator for Rev<I>
45 where
46     I: IndexedParallelIterator,
47 {
drive<C: Consumer<Self::Item>>(self, consumer: C) -> C::Result48     fn drive<C: Consumer<Self::Item>>(self, consumer: C) -> C::Result {
49         bridge(self, consumer)
50     }
51 
len(&self) -> usize52     fn len(&self) -> usize {
53         self.base.len()
54     }
55 
with_producer<CB>(self, callback: CB) -> CB::Output where CB: ProducerCallback<Self::Item>,56     fn with_producer<CB>(self, callback: CB) -> CB::Output
57     where
58         CB: ProducerCallback<Self::Item>,
59     {
60         let len = self.base.len();
61         return self.base.with_producer(Callback { callback, len });
62 
63         struct Callback<CB> {
64             callback: CB,
65             len: usize,
66         }
67 
68         impl<T, CB> ProducerCallback<T> for Callback<CB>
69         where
70             CB: ProducerCallback<T>,
71         {
72             type Output = CB::Output;
73             fn callback<P>(self, base: P) -> CB::Output
74             where
75                 P: Producer<Item = T>,
76             {
77                 let producer = RevProducer {
78                     base,
79                     len: self.len,
80                 };
81                 self.callback.callback(producer)
82             }
83         }
84     }
85 }
86 
87 struct RevProducer<P> {
88     base: P,
89     len: usize,
90 }
91 
92 impl<P> Producer for RevProducer<P>
93 where
94     P: Producer,
95 {
96     type Item = P::Item;
97     type IntoIter = iter::Rev<P::IntoIter>;
98 
into_iter(self) -> Self::IntoIter99     fn into_iter(self) -> Self::IntoIter {
100         self.base.into_iter().rev()
101     }
102 
min_len(&self) -> usize103     fn min_len(&self) -> usize {
104         self.base.min_len()
105     }
max_len(&self) -> usize106     fn max_len(&self) -> usize {
107         self.base.max_len()
108     }
109 
split_at(self, index: usize) -> (Self, Self)110     fn split_at(self, index: usize) -> (Self, Self) {
111         let (left, right) = self.base.split_at(self.len - index);
112         (
113             RevProducer {
114                 base: right,
115                 len: index,
116             },
117             RevProducer {
118                 base: left,
119                 len: self.len - index,
120             },
121         )
122     }
123 }
124