]>
git.proxmox.com Git - rustc.git/blob - vendor/rustc-rayon/src/iter/chunks.rs
3 use super::plumbing
::*;
5 use crate::math
::div_round_up
;
7 /// `Chunks` is an iterator that groups elements of an underlying iterator.
9 /// This struct is created by the [`chunks()`] method on [`IndexedParallelIterator`]
11 /// [`chunks()`]: trait.IndexedParallelIterator.html#method.chunks
12 /// [`IndexedParallelIterator`]: trait.IndexedParallelIterator.html
13 #[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
14 #[derive(Debug, Clone)]
17 I
: IndexedParallelIterator
,
25 I
: IndexedParallelIterator
,
27 /// Creates a new `Chunks` iterator
28 pub(super) fn new(i
: I
, size
: usize) -> Self {
33 impl<I
> ParallelIterator
for Chunks
<I
>
35 I
: IndexedParallelIterator
,
37 type Item
= Vec
<I
::Item
>;
39 fn drive_unindexed
<C
>(self, consumer
: C
) -> C
::Result
41 C
: Consumer
<Vec
<I
::Item
>>,
43 bridge(self, consumer
)
46 fn opt_len(&self) -> Option
<usize> {
51 impl<I
> IndexedParallelIterator
for Chunks
<I
>
53 I
: IndexedParallelIterator
,
55 fn drive
<C
>(self, consumer
: C
) -> C
::Result
57 C
: Consumer
<Self::Item
>,
59 bridge(self, consumer
)
62 fn len(&self) -> usize {
63 div_round_up(self.i
.len(), self.size
)
66 fn with_producer
<CB
>(self, callback
: CB
) -> CB
::Output
68 CB
: ProducerCallback
<Self::Item
>,
70 let len
= self.i
.len();
71 return self.i
.with_producer(Callback
{
83 impl<T
, CB
> ProducerCallback
<T
> for Callback
<CB
>
85 CB
: ProducerCallback
<Vec
<T
>>,
87 type Output
= CB
::Output
;
89 fn callback
<P
>(self, base
: P
) -> CB
::Output
91 P
: Producer
<Item
= T
>,
93 self.callback
.callback(ChunkProducer
{
94 chunk_size
: self.size
,
103 struct ChunkProducer
<P
>
112 impl<P
> Producer
for ChunkProducer
<P
>
116 type Item
= Vec
<P
::Item
>;
117 type IntoIter
= ChunkSeq
<P
>;
119 fn into_iter(self) -> Self::IntoIter
{
121 chunk_size
: self.chunk_size
,
123 inner
: if self.len
> 0 { Some(self.base) }
else { None }
,
127 fn split_at(self, index
: usize) -> (Self, Self) {
128 let elem_index
= min(index
* self.chunk_size
, self.len
);
129 let (left
, right
) = self.base
.split_at(elem_index
);
132 chunk_size
: self.chunk_size
,
137 chunk_size
: self.chunk_size
,
138 len
: self.len
- elem_index
,
144 fn min_len(&self) -> usize {
145 div_round_up(self.base
.min_len(), self.chunk_size
)
148 fn max_len(&self) -> usize {
149 self.base
.max_len() / self.chunk_size
159 impl<P
> Iterator
for ChunkSeq
<P
>
163 type Item
= Vec
<P
::Item
>;
165 fn next(&mut self) -> Option
<Self::Item
> {
166 let producer
= self.inner
.take()?
;
167 if self.len
> self.chunk_size
{
168 let (left
, right
) = producer
.split_at(self.chunk_size
);
169 self.inner
= Some(right
);
170 self.len
-= self.chunk_size
;
171 Some(left
.into_iter().collect())
173 debug_assert
!(self.len
> 0);
175 Some(producer
.into_iter().collect())
179 fn size_hint(&self) -> (usize, Option
<usize>) {
180 let len
= self.len();
185 impl<P
> ExactSizeIterator
for ChunkSeq
<P
>
190 fn len(&self) -> usize {
191 div_round_up(self.len
, self.chunk_size
)
195 impl<P
> DoubleEndedIterator
for ChunkSeq
<P
>
199 fn next_back(&mut self) -> Option
<Self::Item
> {
200 let producer
= self.inner
.take()?
;
201 if self.len
> self.chunk_size
{
202 let mut size
= self.len
% self.chunk_size
;
204 size
= self.chunk_size
;
206 let (left
, right
) = producer
.split_at(self.len
- size
);
207 self.inner
= Some(left
);
209 Some(right
.into_iter().collect())
211 debug_assert
!(self.len
> 0);
213 Some(producer
.into_iter().collect())