1use std::iter;
2
3use super::{plumbing::*, *};
4
5#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
11#[derive(Debug, Clone)]
12pub struct Rev<I: IndexedParallelIterator> {
13 base: I,
14}
15
16impl<I> Rev<I>
17where
18 I: IndexedParallelIterator,
19{
20 pub(super) fn new(base: I) -> Self {
22 Rev { base }
23 }
24}
25
26impl<I> ParallelIterator for Rev<I>
27where
28 I: IndexedParallelIterator,
29{
30 type Item = I::Item;
31
32 fn drive_unindexed<C>(self, consumer: C) -> C::Result
33 where
34 C: UnindexedConsumer<Self::Item>,
35 {
36 bridge(self, consumer)
37 }
38
39 fn opt_len(&self) -> Option<usize> {
40 Some(self.len())
41 }
42}
43
44impl<I> IndexedParallelIterator for Rev<I>
45where
46 I: IndexedParallelIterator,
47{
48 fn drive<C: Consumer<Self::Item>>(self, consumer: C) -> C::Result {
49 bridge(self, consumer)
50 }
51
52 fn len(&self) -> usize {
53 self.base.len()
54 }
55
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
74 fn callback<P>(self, base: P) -> CB::Output
75 where
76 P: Producer<Item = T>,
77 {
78 let producer = RevProducer {
79 base,
80 len: self.len,
81 };
82 self.callback.callback(producer)
83 }
84 }
85 }
86}
87
88struct RevProducer<P> {
89 base: P,
90 len: usize,
91}
92
93impl<P> Producer for RevProducer<P>
94where
95 P: Producer,
96{
97 type IntoIter = iter::Rev<P::IntoIter>;
98 type Item = P::Item;
99
100 fn into_iter(self) -> Self::IntoIter {
101 self.base.into_iter().rev()
102 }
103
104 fn min_len(&self) -> usize {
105 self.base.min_len()
106 }
107
108 fn max_len(&self) -> usize {
109 self.base.max_len()
110 }
111
112 fn split_at(self, index: usize) -> (Self, Self) {
113 let (left, right) = self.base.split_at(self.len - index);
114 (
115 RevProducer {
116 base: right,
117 len: index,
118 },
119 RevProducer {
120 base: left,
121 len: self.len - index,
122 },
123 )
124 }
125}