]> git.proxmox.com Git - rustc.git/blame - vendor/rayon/src/iter/enumerate.rs
New upstream version 1.32.0~beta.2+dfsg1
[rustc.git] / vendor / rayon / src / iter / enumerate.rs
CommitLineData
2c00a5a8
XL
1use super::plumbing::*;
2use super::*;
3use std::iter;
4use std::ops::Range;
5use std::usize;
6
7/// `Enumerate` is an iterator that returns the current count along with the element.
8/// This struct is created by the [`enumerate()`] method on [`IndexedParallelIterator`]
9///
10/// [`enumerate()`]: trait.IndexedParallelIterator.html#method.enumerate
11/// [`IndexedParallelIterator`]: trait.IndexedParallelIterator.html
12#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
13#[derive(Debug, Clone)]
14pub struct Enumerate<I: IndexedParallelIterator> {
15 base: I,
16}
17
18/// Create a new `Enumerate` iterator.
19///
20/// NB: a free fn because it is NOT part of the end-user API.
21pub fn new<I>(base: I) -> Enumerate<I>
22 where I: IndexedParallelIterator
23{
24 Enumerate { base: base }
25}
26
27impl<I> ParallelIterator for Enumerate<I>
28 where I: IndexedParallelIterator
29{
30 type Item = (usize, I::Item);
31
32 fn drive_unindexed<C>(self, consumer: C) -> C::Result
33 where C: UnindexedConsumer<Self::Item>
34 {
35 bridge(self, consumer)
36 }
37
38 fn opt_len(&self) -> Option<usize> {
39 Some(self.len())
40 }
41}
42
43impl<I> IndexedParallelIterator for Enumerate<I>
44 where I: IndexedParallelIterator
45{
46 fn drive<C: Consumer<Self::Item>>(self, consumer: C) -> C::Result {
47 bridge(self, consumer)
48 }
49
50 fn len(&self) -> usize {
51 self.base.len()
52 }
53
54 fn with_producer<CB>(self, callback: CB) -> CB::Output
55 where CB: ProducerCallback<Self::Item>
56 {
57 return self.base.with_producer(Callback { callback: callback });
58
59 struct Callback<CB> {
60 callback: CB,
61 }
62
63 impl<I, CB> ProducerCallback<I> for Callback<CB>
64 where CB: ProducerCallback<(usize, I)>
65 {
66 type Output = CB::Output;
67 fn callback<P>(self, base: P) -> CB::Output
68 where P: Producer<Item = I>
69 {
70 let producer = EnumerateProducer {
71 base: base,
72 offset: 0,
73 };
74 self.callback.callback(producer)
75 }
76 }
77 }
78}
79
80/// ////////////////////////////////////////////////////////////////////////
81/// Producer implementation
82
83struct EnumerateProducer<P> {
84 base: P,
85 offset: usize,
86}
87
88impl<P> Producer for EnumerateProducer<P>
89 where P: Producer
90{
91 type Item = (usize, P::Item);
92 type IntoIter = iter::Zip<Range<usize>, P::IntoIter>;
93
94 fn into_iter(self) -> Self::IntoIter {
95 // Enumerate only works for IndexedParallelIterators. Since those
96 // have a max length of usize::MAX, their max index is
97 // usize::MAX - 1, so the range 0..usize::MAX includes all
98 // possible indices.
99 //
100 // However, we should to use a precise end to the range, otherwise
101 // reversing the iterator may have to walk back a long ways before
102 // `Zip::next_back` can produce anything.
103 let base = self.base.into_iter();
104 let end = self.offset + base.len();
105 (self.offset..end).zip(base)
106 }
107
108 fn min_len(&self) -> usize {
109 self.base.min_len()
110 }
111 fn max_len(&self) -> usize {
112 self.base.max_len()
113 }
114
115 fn split_at(self, index: usize) -> (Self, Self) {
116 let (left, right) = self.base.split_at(index);
117 (EnumerateProducer {
118 base: left,
119 offset: self.offset,
120 },
121 EnumerateProducer {
122 base: right,
123 offset: self.offset + index,
124 })
125 }
126}