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()`]: 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}