rayon/iter/
rev.rs

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