]>
git.proxmox.com Git - rustc.git/blob - src/vendor/itertools/src/tuple_impl.rs
1 //! Some iterator that produces tuples
5 /// An iterator over a incomplete tuple.
7 /// See [`.tuples()`](../trait.Itertools.html#method.tuples) and
8 /// [`Tuples::into_buffer()`](struct.Tuples.html#method.into_buffer).
9 pub struct TupleBuffer
<T
>
16 impl<T
> TupleBuffer
<T
>
19 fn new(buf
: T
::Buffer
) -> Self {
27 impl<T
> Iterator
for TupleBuffer
<T
>
32 fn next(&mut self) -> Option
<Self::Item
> {
33 let s
= self.buf
.as_mut();
34 if let Some(ref mut item
) = s
.get_mut(self.cur
) {
42 fn size_hint(&self) -> (usize, Option
<usize>) {
43 let buffer
= &self.buf
.as_ref()[self.cur
..];
44 let len
= if buffer
.len() == 0 {
48 .position(|x
| x
.is_none())
49 .unwrap_or(buffer
.len())
55 impl<T
> ExactSizeIterator
for TupleBuffer
<T
>
60 /// An iterator that groups the items in tuples of a specific size.
62 /// See [`.tuples()`](../trait.Itertools.html#method.tuples) for more information.
63 #[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
64 pub struct Tuples
<I
, T
>
65 where I
: Iterator
<Item
= T
::Item
>,
72 /// Create a new tuples iterator.
73 pub fn tuples
<I
, T
>(iter
: I
) -> Tuples
<I
, T
>
74 where I
: Iterator
<Item
= T
::Item
>,
79 buf
: Default
::default(),
83 impl<I
, T
> Iterator
for Tuples
<I
, T
>
84 where I
: Iterator
<Item
= T
::Item
>,
89 fn next(&mut self) -> Option
<T
> {
90 T
::collect_from_iter(&mut self.iter
, &mut self.buf
)
94 impl<I
, T
> Tuples
<I
, T
>
95 where I
: Iterator
<Item
= T
::Item
>,
98 /// Return a buffer with the produced items that was not enough to be grouped in a tuple.
101 /// use itertools::Itertools;
103 /// let mut iter = (0..5).tuples();
104 /// assert_eq!(Some((0, 1, 2)), iter.next());
105 /// assert_eq!(None, iter.next());
106 /// itertools::assert_equal(vec![3, 4], iter.into_buffer());
108 pub fn into_buffer(self) -> TupleBuffer
<T
> {
109 TupleBuffer
::new(self.buf
)
114 /// An iterator over all contiguous windows that produces tuples of a specific size.
116 /// See [`.tuple_windows()`](../trait.Itertools.html#method.tuple_windows) for more
118 #[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
119 pub struct TupleWindows
<I
, T
>
120 where I
: Iterator
<Item
= T
::Item
>,
127 /// Create a new tuple windows iterator.
128 pub fn tuple_windows
<I
, T
>(mut iter
: I
) -> TupleWindows
<I
, T
>
129 where I
: Iterator
<Item
= T
::Item
>,
136 if T
::num_items() != 1 {
137 // put in a duplicate item in front of the tuple; this simplifies
139 if let Some(item
) = iter
.next() {
140 let iter
= once(item
.clone()).chain(once(item
)).chain(&mut iter
);
141 last
= T
::collect_from_iter_no_buf(iter
);
151 impl<I
, T
> Iterator
for TupleWindows
<I
, T
>
152 where I
: Iterator
<Item
= T
::Item
>,
153 T
: TupleCollect
+ Clone
,
158 fn next(&mut self) -> Option
<T
> {
159 if T
::num_items() == 1 {
160 return T
::collect_from_iter_no_buf(&mut self.iter
)
162 if let Some(ref mut last
) = self.last
{
163 if let Some(new
) = self.iter
.next() {
164 last
.left_shift_push(new
);
165 return Some(last
.clone());
172 pub trait TupleCollect
: Sized
{
174 type Buffer
: Default
+ AsRef
<[Option
<Self::Item
>]> + AsMut
<[Option
<Self::Item
>]>;
176 fn collect_from_iter
<I
>(iter
: I
, buf
: &mut Self::Buffer
) -> Option
<Self>
177 where I
: IntoIterator
<Item
= Self::Item
>;
179 fn collect_from_iter_no_buf
<I
>(iter
: I
) -> Option
<Self>
180 where I
: IntoIterator
<Item
= Self::Item
>;
182 fn num_items() -> usize;
184 fn left_shift_push(&mut self, item
: Self::Item
);
187 macro_rules
! impl_tuple_collect
{
189 ($N
:expr
; $A
:ident
; $
($X
:ident
),* ; $
($Y
:ident
),* ; $
($Y_rev
:ident
),*) => (
190 impl<$A
> TupleCollect
for ($
($X
),*,) {
192 type Buffer
= [Option
<$A
>; $N
- 1];
194 #[allow(unused_assignments, unused_mut)]
195 fn collect_from_iter
<I
>(iter
: I
, buf
: &mut Self::Buffer
) -> Option
<Self>
196 where I
: IntoIterator
<Item
= $A
>
198 let mut iter
= iter
.into_iter();
210 return Some(($
($Y
.unwrap()),*,))
214 let mut s
= buf
.as_mut();
224 #[allow(unused_assignments)]
225 fn collect_from_iter_no_buf
<I
>(iter
: I
) -> Option
<Self>
226 where I
: IntoIterator
<Item
= $A
>
228 let mut iter
= iter
.into_iter();
231 let $Y
= if let Some($Y
) = iter
.next() {
237 return Some(($
($Y
),*,))
243 fn num_items() -> usize {
247 fn left_shift_push(&mut self, item
: $A
) {
248 use std
::mem
::replace
;
250 let &mut ($
(ref mut $Y
),*,) = self;
253 let tmp
= replace($Y_rev
, tmp
);
261 impl_tuple_collect
!(1; A
; A
; a
; a
);
262 impl_tuple_collect
!(2; A
; A
, A
; a
, b
; b
, a
);
263 impl_tuple_collect
!(3; A
; A
, A
, A
; a
, b
, c
; c
, b
, a
);
264 impl_tuple_collect
!(4; A
; A
, A
, A
, A
; a
, b
, c
, d
; d
, c
, b
, a
);