]>
git.proxmox.com Git - rustc.git/blob - 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).
10 pub struct TupleBuffer
<T
>
17 impl<T
> TupleBuffer
<T
>
20 fn new(buf
: T
::Buffer
) -> Self {
28 impl<T
> Iterator
for TupleBuffer
<T
>
33 fn next(&mut self) -> Option
<Self::Item
> {
34 let s
= self.buf
.as_mut();
35 if let Some(ref mut item
) = s
.get_mut(self.cur
) {
43 fn size_hint(&self) -> (usize, Option
<usize>) {
44 let buffer
= &self.buf
.as_ref()[self.cur
..];
45 let len
= if buffer
.len() == 0 {
49 .position(|x
| x
.is_none())
50 .unwrap_or(buffer
.len())
56 impl<T
> ExactSizeIterator
for TupleBuffer
<T
>
61 /// An iterator that groups the items in tuples of a specific size.
63 /// See [`.tuples()`](../trait.Itertools.html#method.tuples) for more information.
64 #[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
65 pub struct Tuples
<I
, T
>
66 where I
: Iterator
<Item
= T
::Item
>,
73 /// Create a new tuples iterator.
74 pub fn tuples
<I
, T
>(iter
: I
) -> Tuples
<I
, T
>
75 where I
: Iterator
<Item
= T
::Item
>,
80 buf
: Default
::default(),
84 impl<I
, T
> Iterator
for Tuples
<I
, T
>
85 where I
: Iterator
<Item
= T
::Item
>,
90 fn next(&mut self) -> Option
<T
> {
91 T
::collect_from_iter(&mut self.iter
, &mut self.buf
)
95 impl<I
, T
> Tuples
<I
, T
>
96 where I
: Iterator
<Item
= T
::Item
>,
99 /// Return a buffer with the produced items that was not enough to be grouped in a tuple.
102 /// use itertools::Itertools;
104 /// let mut iter = (0..5).tuples();
105 /// assert_eq!(Some((0, 1, 2)), iter.next());
106 /// assert_eq!(None, iter.next());
107 /// itertools::assert_equal(vec![3, 4], iter.into_buffer());
109 pub fn into_buffer(self) -> TupleBuffer
<T
> {
110 TupleBuffer
::new(self.buf
)
115 /// An iterator over all contiguous windows that produces tuples of a specific size.
117 /// See [`.tuple_windows()`](../trait.Itertools.html#method.tuple_windows) for more
119 #[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
121 pub struct TupleWindows
<I
, T
>
122 where I
: Iterator
<Item
= T
::Item
>,
129 /// Create a new tuple windows iterator.
130 pub fn tuple_windows
<I
, T
>(mut iter
: I
) -> TupleWindows
<I
, T
>
131 where I
: Iterator
<Item
= T
::Item
>,
138 if T
::num_items() != 1 {
139 // put in a duplicate item in front of the tuple; this simplifies
141 if let Some(item
) = iter
.next() {
142 let iter
= once(item
.clone()).chain(once(item
)).chain(&mut iter
);
143 last
= T
::collect_from_iter_no_buf(iter
);
153 impl<I
, T
> Iterator
for TupleWindows
<I
, T
>
154 where I
: Iterator
<Item
= T
::Item
>,
155 T
: TupleCollect
+ Clone
,
160 fn next(&mut self) -> Option
<T
> {
161 if T
::num_items() == 1 {
162 return T
::collect_from_iter_no_buf(&mut self.iter
)
164 if let Some(ref mut last
) = self.last
{
165 if let Some(new
) = self.iter
.next() {
166 last
.left_shift_push(new
);
167 return Some(last
.clone());
174 pub trait TupleCollect
: Sized
{
176 type Buffer
: Default
+ AsRef
<[Option
<Self::Item
>]> + AsMut
<[Option
<Self::Item
>]>;
178 fn collect_from_iter
<I
>(iter
: I
, buf
: &mut Self::Buffer
) -> Option
<Self>
179 where I
: IntoIterator
<Item
= Self::Item
>;
181 fn collect_from_iter_no_buf
<I
>(iter
: I
) -> Option
<Self>
182 where I
: IntoIterator
<Item
= Self::Item
>;
184 fn num_items() -> usize;
186 fn left_shift_push(&mut self, item
: Self::Item
);
189 macro_rules
! impl_tuple_collect
{
191 ($N
:expr
; $A
:ident
; $
($X
:ident
),* ; $
($Y
:ident
),* ; $
($Y_rev
:ident
),*) => (
192 impl<$A
> TupleCollect
for ($
($X
),*,) {
194 type Buffer
= [Option
<$A
>; $N
- 1];
196 #[allow(unused_assignments, unused_mut)]
197 fn collect_from_iter
<I
>(iter
: I
, buf
: &mut Self::Buffer
) -> Option
<Self>
198 where I
: IntoIterator
<Item
= $A
>
200 let mut iter
= iter
.into_iter();
212 return Some(($
($Y
.unwrap()),*,))
216 let mut s
= buf
.as_mut();
226 #[allow(unused_assignments)]
227 fn collect_from_iter_no_buf
<I
>(iter
: I
) -> Option
<Self>
228 where I
: IntoIterator
<Item
= $A
>
230 let mut iter
= iter
.into_iter();
233 let $Y
= if let Some($Y
) = iter
.next() {
239 return Some(($
($Y
),*,))
245 fn num_items() -> usize {
249 fn left_shift_push(&mut self, item
: $A
) {
250 use std
::mem
::replace
;
252 let &mut ($
(ref mut $Y
),*,) = self;
255 let tmp
= replace($Y_rev
, tmp
);
263 impl_tuple_collect
!(1; A
; A
; a
; a
);
264 impl_tuple_collect
!(2; A
; A
, A
; a
, b
; b
, a
);
265 impl_tuple_collect
!(3; A
; A
, A
, A
; a
, b
, c
; c
, b
, a
);
266 impl_tuple_collect
!(4; A
; A
, A
, A
, A
; a
, b
, c
, d
; d
, c
, b
, a
);