par_iter/iter/
rev.rs

1use std::iter;
2
3use super::{plumbing::*, *};
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
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}