Skip to content

Commit ca8df94

Browse files
bors[bot]phimuemue
andauthored
Merge #463
463: Implement intersperse in terms of intersperse_with r=jswrenn a=phimuemue This de-copy-pastes Intersperse/IntersperseWith, similar to what we do in other iterator adaptors. Co-authored-by: philipp <[email protected]>
2 parents 49e4880 + 69823de commit ca8df94

File tree

1 file changed

+22
-64
lines changed

1 file changed

+22
-64
lines changed

src/intersperse.rs

Lines changed: 22 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,19 @@
11
use std::iter::Fuse;
22
use super::size_hint;
33

4+
pub trait IntersperseElement<Item> {
5+
fn generate(&mut self) -> Item;
6+
}
7+
8+
#[derive(Debug, Clone)]
9+
pub struct IntersperseElementSimple<Item>(Item);
10+
11+
impl<Item: Clone> IntersperseElement<Item> for IntersperseElementSimple<Item> {
12+
fn generate(&mut self) -> Item {
13+
self.0.clone()
14+
}
15+
}
16+
417
/// An iterator adaptor to insert a particular value
518
/// between each element of the adapted iterator.
619
///
@@ -9,71 +22,18 @@ use super::size_hint;
922
/// This iterator is *fused*.
1023
///
1124
/// See [`.intersperse()`](../trait.Itertools.html#method.intersperse) for more information.
12-
#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
13-
#[derive(Clone, Debug)]
14-
pub struct Intersperse<I>
15-
where I: Iterator
16-
{
17-
element: I::Item,
18-
iter: Fuse<I>,
19-
peek: Option<I::Item>,
20-
}
25+
pub type Intersperse<I> = IntersperseWith<I, IntersperseElementSimple<<I as Iterator>::Item>>;
2126

2227
/// Create a new Intersperse iterator
2328
pub fn intersperse<I>(iter: I, elt: I::Item) -> Intersperse<I>
24-
where I: Iterator
25-
{
26-
let mut iter = iter.fuse();
27-
Intersperse {
28-
peek: iter.next(),
29-
iter,
30-
element: elt,
31-
}
32-
}
33-
34-
impl<I> Iterator for Intersperse<I>
3529
where I: Iterator,
36-
I::Item: Clone
3730
{
38-
type Item = I::Item;
39-
#[inline]
40-
fn next(&mut self) -> Option<Self::Item> {
41-
if self.peek.is_some() {
42-
self.peek.take()
43-
} else {
44-
self.peek = self.iter.next();
45-
if self.peek.is_some() {
46-
Some(self.element.clone())
47-
} else {
48-
None
49-
}
50-
}
51-
}
52-
53-
fn size_hint(&self) -> (usize, Option<usize>) {
54-
// 2 * SH + { 1 or 0 }
55-
let has_peek = self.peek.is_some() as usize;
56-
let sh = self.iter.size_hint();
57-
size_hint::add_scalar(size_hint::add(sh, sh), has_peek)
58-
}
59-
60-
fn fold<B, F>(mut self, init: B, mut f: F) -> B where
61-
Self: Sized, F: FnMut(B, Self::Item) -> B,
62-
{
63-
let mut accum = init;
64-
65-
if let Some(x) = self.peek.take() {
66-
accum = f(accum, x);
67-
}
68-
69-
let element = &self.element;
31+
intersperse_with(iter, IntersperseElementSimple(elt))
32+
}
7033

71-
self.iter.fold(accum,
72-
|accum, x| {
73-
let accum = f(accum, element.clone());
74-
let accum = f(accum, x);
75-
accum
76-
})
34+
impl<Item, F: FnMut()->Item> IntersperseElement<Item> for F {
35+
fn generate(&mut self) -> Item {
36+
self()
7737
}
7838
}
7939

@@ -89,7 +49,6 @@ impl<I> Iterator for Intersperse<I>
8949
#[derive(Clone, Debug)]
9050
pub struct IntersperseWith<I, ElemF>
9151
where I: Iterator,
92-
ElemF: FnMut() -> I::Item,
9352
{
9453
element: ElemF,
9554
iter: Fuse<I>,
@@ -99,7 +58,6 @@ pub struct IntersperseWith<I, ElemF>
9958
/// Create a new IntersperseWith iterator
10059
pub fn intersperse_with<I, ElemF>(iter: I, elt: ElemF) -> IntersperseWith<I, ElemF>
10160
where I: Iterator,
102-
ElemF: FnMut() -> I::Item
10361
{
10462
let mut iter = iter.fuse();
10563
IntersperseWith {
@@ -111,7 +69,7 @@ pub fn intersperse_with<I, ElemF>(iter: I, elt: ElemF) -> IntersperseWith<I, Ele
11169

11270
impl<I, ElemF> Iterator for IntersperseWith<I, ElemF>
11371
where I: Iterator,
114-
ElemF: FnMut() -> I::Item
72+
ElemF: IntersperseElement<I::Item>
11573
{
11674
type Item = I::Item;
11775
#[inline]
@@ -121,7 +79,7 @@ impl<I, ElemF> Iterator for IntersperseWith<I, ElemF>
12179
} else {
12280
self.peek = self.iter.next();
12381
if self.peek.is_some() {
124-
Some((self.element)())
82+
Some(self.element.generate())
12583
} else {
12684
None
12785
}
@@ -148,7 +106,7 @@ impl<I, ElemF> Iterator for IntersperseWith<I, ElemF>
148106

149107
self.iter.fold(accum,
150108
|accum, x| {
151-
let accum = f(accum, (element)());
109+
let accum = f(accum, element.generate());
152110
let accum = f(accum, x);
153111
accum
154112
})

0 commit comments

Comments
 (0)