From edbdb3f63489db17ed0edb85a863a96572141db7 Mon Sep 17 00:00:00 2001 From: aobatact Date: Tue, 8 Feb 2022 00:58:48 +0900 Subject: [PATCH 1/4] Fix tuple_windows as lazy --- src/tuple_impl.rs | 26 ++++++++++++-------------- 1 file changed, 12 insertions(+), 14 deletions(-) diff --git a/src/tuple_impl.rs b/src/tuple_impl.rs index c0b39d79d..a902f2553 100644 --- a/src/tuple_impl.rs +++ b/src/tuple_impl.rs @@ -167,30 +167,21 @@ where I: Iterator, T: HomogeneousTuple, { - iter: I, + iter: Fuse, last: Option, } /// Create a new tuple windows iterator. -pub fn tuple_windows(mut iter: I) -> TupleWindows +pub fn tuple_windows(iter: I) -> TupleWindows where I: Iterator, T: HomogeneousTuple, T::Item: Clone, { - use std::iter::once; - - let mut last = None; - if T::num_items() != 1 { - // put in a duplicate item in front of the tuple; this simplifies - // .next() function. - if let Some(item) = iter.next() { - let iter = once(item.clone()).chain(once(item)).chain(&mut iter); - last = T::collect_from_iter_no_buf(iter); - } + TupleWindows { + last : None, + iter : iter.fuse(), } - - TupleWindows { iter, last } } impl Iterator for TupleWindows @@ -210,6 +201,13 @@ where last.left_shift_push(new); return Some(last.clone()); } + } else { + use std::iter::once; + if let Some(item) = self.iter.next() { + let iter = once(item).chain(&mut self.iter); + self.last = T::collect_from_iter_no_buf(iter); + return self.last.clone(); + } } None } From cdca988c684b52d777732cd398a33333b796db30 Mon Sep 17 00:00:00 2001 From: aobatact Date: Fri, 11 Feb 2022 11:36:43 +0900 Subject: [PATCH 2/4] Fix remove use of fuse at tuple_windows --- src/tuple_impl.rs | 23 +++++++++++------------ 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/src/tuple_impl.rs b/src/tuple_impl.rs index a902f2553..df1842065 100644 --- a/src/tuple_impl.rs +++ b/src/tuple_impl.rs @@ -167,7 +167,7 @@ where I: Iterator, T: HomogeneousTuple, { - iter: Fuse, + iter: I, last: Option, } @@ -180,7 +180,7 @@ where { TupleWindows { last : None, - iter : iter.fuse(), + iter, } } @@ -196,20 +196,19 @@ where if T::num_items() == 1 { return T::collect_from_iter_no_buf(&mut self.iter); } - if let Some(ref mut last) = self.last { - if let Some(new) = self.iter.next() { + if let Some(new) = self.iter.next() { + if let Some(ref mut last) = self.last { last.left_shift_push(new); - return Some(last.clone()); - } - } else { - use std::iter::once; - if let Some(item) = self.iter.next() { - let iter = once(item).chain(&mut self.iter); + Some(last.clone()) + } else { + use std::iter::once; + let iter = once(new).chain(&mut self.iter); self.last = T::collect_from_iter_no_buf(iter); - return self.last.clone(); + self.last.clone() } + } else { + None } - None } fn size_hint(&self) -> (usize, Option) { From 22603cc6631bfd666a1117538a9182355c870363 Mon Sep 17 00:00:00 2001 From: Jack Wrenn Date: Tue, 3 Oct 2023 19:30:16 +0000 Subject: [PATCH 3/4] rustfmt --- src/tuple_impl.rs | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/tuple_impl.rs b/src/tuple_impl.rs index df1842065..9769300a7 100644 --- a/src/tuple_impl.rs +++ b/src/tuple_impl.rs @@ -178,10 +178,7 @@ where T: HomogeneousTuple, T::Item: Clone, { - TupleWindows { - last : None, - iter, - } + TupleWindows { last: None, iter } } impl Iterator for TupleWindows From e21c46a4ef9ac0c0c21a9ae1faf39c864d7de4e8 Mon Sep 17 00:00:00 2001 From: Philippe-Cholet Date: Fri, 6 Oct 2023 15:46:59 +0200 Subject: [PATCH 4/4] Adjust `TupleWindows::size_hint` Now that `TupleWindows` is lazy, we must adjust the size hint accordingly. --- src/size_hint.rs | 1 - src/tuple_impl.rs | 12 +++++++++--- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/src/size_hint.rs b/src/size_hint.rs index d592ca925..857e0c4c6 100644 --- a/src/size_hint.rs +++ b/src/size_hint.rs @@ -29,7 +29,6 @@ pub fn add_scalar(sh: SizeHint, x: usize) -> SizeHint { } /// Subtract `x` correctly from a `SizeHint`. -#[cfg(feature = "use_alloc")] #[inline] pub fn sub_scalar(sh: SizeHint, x: usize) -> SizeHint { let (mut low, mut hi) = sh; diff --git a/src/tuple_impl.rs b/src/tuple_impl.rs index 9769300a7..688df448e 100644 --- a/src/tuple_impl.rs +++ b/src/tuple_impl.rs @@ -5,6 +5,8 @@ use std::iter::Fuse; use std::iter::FusedIterator; use std::marker::PhantomData; +use crate::size_hint; + // `HomogeneousTuple` is a public facade for `TupleCollect`, allowing // tuple-related methods to be used by clients in generic contexts, while // hiding the implementation details of `TupleCollect`. @@ -209,9 +211,13 @@ where } fn size_hint(&self) -> (usize, Option) { - // At definition, `T::num_items() - 1` are collected - // so each remaining item in `iter` will lead to an item. - self.iter.size_hint() + let mut sh = self.iter.size_hint(); + // Adjust the size hint at the beginning + // OR when `num_items == 1` (but it does not change the size hint). + if self.last.is_none() { + sh = size_hint::sub_scalar(sh, T::num_items() - 1); + } + sh } }