1 use super::plumbing::*; 2 use super::*; 3 use 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)] 12 pub struct Rev<I: IndexedParallelIterator> { 13 base: I, 14 } 15 16 impl<I> Rev<I> 17 where 18 I: IndexedParallelIterator, 19 { 20 /// Creates a new `Rev` iterator. new(base: I) -> Self21 pub(super) fn new(base: I) -> Self { 22 Rev { base } 23 } 24 } 25 26 impl<I> ParallelIterator for Rev<I> 27 where 28 I: IndexedParallelIterator, 29 { 30 type Item = I::Item; 31 drive_unindexed<C>(self, consumer: C) -> C::Result where C: UnindexedConsumer<Self::Item>,32 fn drive_unindexed<C>(self, consumer: C) -> C::Result 33 where 34 C: UnindexedConsumer<Self::Item>, 35 { 36 bridge(self, consumer) 37 } 38 opt_len(&self) -> Option<usize>39 fn opt_len(&self) -> Option<usize> { 40 Some(self.len()) 41 } 42 } 43 44 impl<I> IndexedParallelIterator for Rev<I> 45 where 46 I: IndexedParallelIterator, 47 { drive<C: Consumer<Self::Item>>(self, consumer: C) -> C::Result48 fn drive<C: Consumer<Self::Item>>(self, consumer: C) -> C::Result { 49 bridge(self, consumer) 50 } 51 len(&self) -> usize52 fn len(&self) -> usize { 53 self.base.len() 54 } 55 with_producer<CB>(self, callback: CB) -> CB::Output where CB: ProducerCallback<Self::Item>,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 87 struct RevProducer<P> { 88 base: P, 89 len: usize, 90 } 91 92 impl<P> Producer for RevProducer<P> 93 where 94 P: Producer, 95 { 96 type Item = P::Item; 97 type IntoIter = iter::Rev<P::IntoIter>; 98 into_iter(self) -> Self::IntoIter99 fn into_iter(self) -> Self::IntoIter { 100 self.base.into_iter().rev() 101 } 102 min_len(&self) -> usize103 fn min_len(&self) -> usize { 104 self.base.min_len() 105 } max_len(&self) -> usize106 fn max_len(&self) -> usize { 107 self.base.max_len() 108 } 109 split_at(self, index: usize) -> (Self, Self)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