1use super::plumbing::*;
2use super::*;
3use 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)]
12pub struct Rev<I: IndexedParallelIterator> {
13 base: I,
14}
15
16impl<I> Rev<I>
17where
18 I: IndexedParallelIterator,
19{
20 /// Creates a new `Rev` iterator.
21 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 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
87struct RevProducer<P> {
88 base: P,
89 len: usize,
90}
91
92impl<P> Producer for RevProducer<P>
93where
94 P: Producer,
95{
96 type Item = P::Item;
97 type IntoIter = iter::Rev<P::IntoIter>;
98
99 fn into_iter(self) -> Self::IntoIter {
100 self.base.into_iter().rev()
101 }
102
103 fn min_len(&self) -> usize {
104 self.base.min_len()
105 }
106 fn max_len(&self) -> usize {
107 self.base.max_len()
108 }
109
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