Postpone .next() call until iteration
This commit is contained in:
parent
f9259d1b73
commit
b8d245e749
@ -11,6 +11,7 @@ pub struct Intersperse<I: Iterator>
|
|||||||
where
|
where
|
||||||
I::Item: Clone,
|
I::Item: Clone,
|
||||||
{
|
{
|
||||||
|
started: bool,
|
||||||
separator: I::Item,
|
separator: I::Item,
|
||||||
next_item: Option<I::Item>,
|
next_item: Option<I::Item>,
|
||||||
iter: Fuse<I>,
|
iter: Fuse<I>,
|
||||||
@ -29,8 +30,7 @@ where
|
|||||||
I::Item: Clone,
|
I::Item: Clone,
|
||||||
{
|
{
|
||||||
pub(in crate::iter) fn new(iter: I, separator: I::Item) -> Self {
|
pub(in crate::iter) fn new(iter: I, separator: I::Item) -> Self {
|
||||||
let mut iter = iter.fuse();
|
Self { started: false, separator, next_item: None, iter: iter.fuse() }
|
||||||
Self { separator, next_item: iter.next(), iter }
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -44,6 +44,7 @@ where
|
|||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn next(&mut self) -> Option<Self::Item> {
|
fn next(&mut self) -> Option<Self::Item> {
|
||||||
|
if self.started {
|
||||||
if let Some(v) = self.next_item.take() {
|
if let Some(v) = self.next_item.take() {
|
||||||
Some(v)
|
Some(v)
|
||||||
} else {
|
} else {
|
||||||
@ -55,10 +56,14 @@ where
|
|||||||
None
|
None
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
self.started = true;
|
||||||
|
self.iter.next()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn size_hint(&self) -> (usize, Option<usize>) {
|
fn size_hint(&self) -> (usize, Option<usize>) {
|
||||||
intersperse_size_hint(&self.iter, self.next_item.is_some())
|
intersperse_size_hint(&self.iter, self.started, self.next_item.is_some())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn fold<B, F>(self, init: B, f: F) -> B
|
fn fold<B, F>(self, init: B, f: F) -> B
|
||||||
@ -67,7 +72,7 @@ where
|
|||||||
F: FnMut(B, Self::Item) -> B,
|
F: FnMut(B, Self::Item) -> B,
|
||||||
{
|
{
|
||||||
let separator = self.separator;
|
let separator = self.separator;
|
||||||
intersperse_fold(self.iter, init, f, move || separator.clone(), self.next_item)
|
intersperse_fold(self.iter, init, f, move || separator.clone(), self.started,self.next_item)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -80,6 +85,7 @@ pub struct IntersperseWith<I, G>
|
|||||||
where
|
where
|
||||||
I: Iterator,
|
I: Iterator,
|
||||||
{
|
{
|
||||||
|
started: bool,
|
||||||
separator: G,
|
separator: G,
|
||||||
next_item: Option<I::Item>,
|
next_item: Option<I::Item>,
|
||||||
iter: Fuse<I>,
|
iter: Fuse<I>,
|
||||||
@ -102,6 +108,7 @@ where
|
|||||||
{
|
{
|
||||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
f.debug_struct("IntersperseWith")
|
f.debug_struct("IntersperseWith")
|
||||||
|
.field("started", &self.started)
|
||||||
.field("separator", &self.separator)
|
.field("separator", &self.separator)
|
||||||
.field("iter", &self.iter)
|
.field("iter", &self.iter)
|
||||||
.field("next_item", &self.next_item)
|
.field("next_item", &self.next_item)
|
||||||
@ -118,6 +125,7 @@ where
|
|||||||
{
|
{
|
||||||
fn clone(&self) -> Self {
|
fn clone(&self) -> Self {
|
||||||
Self {
|
Self {
|
||||||
|
started: self.started,
|
||||||
separator: self.separator.clone(),
|
separator: self.separator.clone(),
|
||||||
iter: self.iter.clone(),
|
iter: self.iter.clone(),
|
||||||
next_item: self.next_item.clone(),
|
next_item: self.next_item.clone(),
|
||||||
@ -131,8 +139,7 @@ where
|
|||||||
G: FnMut() -> I::Item,
|
G: FnMut() -> I::Item,
|
||||||
{
|
{
|
||||||
pub(in crate::iter) fn new(iter: I, separator: G) -> Self {
|
pub(in crate::iter) fn new(iter: I, separator: G) -> Self {
|
||||||
let mut iter = iter.fuse();
|
Self { started: false, separator, next_item: None, iter: iter.fuse() }
|
||||||
Self { separator, next_item: iter.next(), iter }
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -146,6 +153,7 @@ where
|
|||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn next(&mut self) -> Option<Self::Item> {
|
fn next(&mut self) -> Option<Self::Item> {
|
||||||
|
if self.started {
|
||||||
if let Some(v) = self.next_item.take() {
|
if let Some(v) = self.next_item.take() {
|
||||||
Some(v)
|
Some(v)
|
||||||
} else {
|
} else {
|
||||||
@ -157,10 +165,14 @@ where
|
|||||||
None
|
None
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
self.started = true;
|
||||||
|
self.iter.next()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn size_hint(&self) -> (usize, Option<usize>) {
|
fn size_hint(&self) -> (usize, Option<usize>) {
|
||||||
intersperse_size_hint(&self.iter, self.next_item.is_some())
|
intersperse_size_hint(&self.iter, self.started, self.next_item.is_some())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn fold<B, F>(self, init: B, f: F) -> B
|
fn fold<B, F>(self, init: B, f: F) -> B
|
||||||
@ -168,26 +180,33 @@ where
|
|||||||
Self: Sized,
|
Self: Sized,
|
||||||
F: FnMut(B, Self::Item) -> B,
|
F: FnMut(B, Self::Item) -> B,
|
||||||
{
|
{
|
||||||
intersperse_fold(self.iter, init, f, self.separator, self.next_item)
|
intersperse_fold(self.iter, init, f, self.separator, self.started, self.next_item)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn intersperse_size_hint<I>(iter: &I, next_is_elem: bool) -> (usize, Option<usize>)
|
fn intersperse_size_hint<I>(iter: &I, started: bool, next_is_some: bool) -> (usize, Option<usize>)
|
||||||
where
|
where
|
||||||
I: Iterator,
|
I: Iterator,
|
||||||
{
|
{
|
||||||
let (lo, hi) = iter.size_hint();
|
let (lo, hi) = iter.size_hint();
|
||||||
(
|
(
|
||||||
lo.saturating_add(next_is_elem as usize).saturating_add(lo),
|
lo.saturating_sub(!started as usize)
|
||||||
hi.map(|hi| hi.saturating_add(next_is_elem as usize).saturating_add(hi)),
|
.saturating_add(next_is_some as usize)
|
||||||
|
.saturating_add(lo),
|
||||||
|
hi.map(|hi| {
|
||||||
|
hi.saturating_sub(!started as usize)
|
||||||
|
.saturating_add(next_is_some as usize)
|
||||||
|
.saturating_add(hi)
|
||||||
|
}),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn intersperse_fold<I, B, F, G>(
|
fn intersperse_fold<I, B, F, G>(
|
||||||
iter: I,
|
mut iter: I,
|
||||||
init: B,
|
init: B,
|
||||||
mut f: F,
|
mut f: F,
|
||||||
mut separator: G,
|
mut separator: G,
|
||||||
|
started: bool,
|
||||||
mut next_item: Option<I::Item>,
|
mut next_item: Option<I::Item>,
|
||||||
) -> B
|
) -> B
|
||||||
where
|
where
|
||||||
@ -197,7 +216,8 @@ where
|
|||||||
{
|
{
|
||||||
let mut accum = init;
|
let mut accum = init;
|
||||||
|
|
||||||
if let Some(x) = next_item.take() {
|
let first = if started { next_item.take() } else { iter.next() };
|
||||||
|
if let Some(x) = first {
|
||||||
accum = f(accum, x);
|
accum = f(accum, x);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user