Skip to content

Commit 8b3d25f

Browse files
committed
Implement DoubleEndedIterator for Iter
1 parent e143c37 commit 8b3d25f

File tree

3 files changed

+96
-16
lines changed

3 files changed

+96
-16
lines changed

src/btree_multiset.rs

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -62,13 +62,7 @@ where
6262
/// assert_eq!(3, multiset.iter().count());
6363
/// ```
6464
pub fn iter(&self) -> Iter<&K, &usize, btree_map::Iter<K, usize>> {
65-
Iter {
66-
iter: self.elem_counts.iter(),
67-
duplicate: None,
68-
duplicate_index: 0,
69-
len: self.size,
70-
_ghost: std::marker::PhantomData,
71-
}
65+
Iter::new(self.elem_counts.iter(), self.size)
7266
}
7367

7468
/// Returns true if the multiset contains no elements.

src/hash_multiset.rs

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -63,13 +63,7 @@ where
6363
/// assert_eq!(3, multiset.iter().count());
6464
/// ```
6565
pub fn iter(&self) -> Iter<&K, &usize, hash_map::Iter<K, usize>> {
66-
Iter {
67-
iter: self.elem_counts.iter(),
68-
duplicate: None,
69-
duplicate_index: 0,
70-
len: self.size,
71-
_ghost: std::marker::PhantomData,
72-
}
66+
Iter::new(self.elem_counts.iter(), self.size)
7367
}
7468

7569
/// Returns true if the multiset contains no elements.

src/iter.rs

Lines changed: 94 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,28 @@ pub struct Iter<K: Clone, V: Borrow<usize>, InnerIter: Iterator<Item = (K, V)>>
1818
pub(crate) iter: InnerIter,
1919
pub(crate) duplicate: Option<<InnerIter as Iterator>::Item>,
2020
pub(crate) duplicate_index: usize,
21+
pub(crate) duplicate_back: Option<<InnerIter as Iterator>::Item>,
22+
pub(crate) duplicate_index_back: usize,
2123
pub(crate) len: usize,
2224
pub(crate) _ghost: PhantomData<*const (K, V)>,
2325
}
2426

27+
impl<K: Clone, V: Borrow<usize>, InnerIter: Iterator<Item = (K, V)> + ExactSizeIterator>
28+
Iter<K, V, InnerIter>
29+
{
30+
pub(crate) fn new(iter: InnerIter, len: usize) -> Self {
31+
Iter {
32+
iter,
33+
duplicate: None,
34+
duplicate_index: 0,
35+
duplicate_back: None,
36+
duplicate_index_back: 0,
37+
len,
38+
_ghost: PhantomData,
39+
}
40+
}
41+
}
42+
2543
impl<K: Clone, V: Borrow<usize>, InnerIter: Iterator<Item = (K, V)> + Clone> Clone
2644
for Iter<K, V, InnerIter>
2745
where
@@ -32,6 +50,8 @@ where
3250
iter: self.iter.clone(),
3351
duplicate: self.duplicate.clone(),
3452
duplicate_index: self.duplicate_index,
53+
duplicate_back: self.duplicate_back.clone(),
54+
duplicate_index_back: self.duplicate_index_back,
3555
len: self.len,
3656
_ghost: PhantomData,
3757
}
@@ -50,14 +70,24 @@ impl<K: Clone, V: Borrow<usize>, InnerIter: Iterator<Item = (K, V)>> Iterator
5070
if let Some((key, count)) = self.duplicate.as_ref() {
5171
self.duplicate_index += 1;
5272
let key = key.clone();
53-
if &self.duplicate_index >= count.borrow() {
73+
if self.duplicate_index >= *count.borrow() {
5474
self.duplicate = None;
5575
self.duplicate_index = 0;
5676
}
5777
self.len -= 1;
5878
Some(key)
5979
} else {
60-
None
80+
if let Some((key, count)) = self.duplicate_back.as_ref() {
81+
self.duplicate_index_back += 1;
82+
let key = key.clone();
83+
if self.duplicate_index_back >= *count.borrow() {
84+
self.duplicate_back = None;
85+
}
86+
self.len -= 1;
87+
Some(key)
88+
} else {
89+
None
90+
}
6191
}
6292
}
6393

@@ -70,10 +100,16 @@ impl<K: Clone, V: Borrow<usize>, InnerIter: Iterator<Item = (K, V)>> Iterator
70100
F: FnMut(B, Self::Item) -> B,
71101
{
72102
let duplicate_index = self.duplicate_index;
103+
let duplicate_index_back = self.duplicate_index_back;
73104
self.duplicate
74105
.map(move |(val, count)| (val, *count.borrow() - duplicate_index))
75106
.into_iter()
76107
.chain(self.iter.map(move |(val, count)| (val, *count.borrow())))
108+
.chain(
109+
self.duplicate_back
110+
.map(move |(val, count)| (val, *count.borrow() - duplicate_index_back))
111+
.into_iter(),
112+
)
77113
.fold(init, move |acc, (val, count)| {
78114
(0..count).fold(acc, |acc, _| f(acc, val.clone()))
79115
})
@@ -92,3 +128,59 @@ impl<K: Clone, V: Borrow<usize>, InnerIter: Iterator<Item = (K, V)>> ExactSizeIt
92128
self.len
93129
}
94130
}
131+
132+
impl<K: Clone, V: Borrow<usize>, InnerIter: Iterator<Item = (K, V)> + DoubleEndedIterator>
133+
DoubleEndedIterator for Iter<K, V, InnerIter>
134+
{
135+
fn next_back(&mut self) -> Option<Self::Item> {
136+
if self.duplicate_back.is_none() {
137+
self.duplicate_back = self.iter.next_back();
138+
}
139+
if let Some((key, count)) = self.duplicate_back.as_ref() {
140+
self.duplicate_index_back += 1;
141+
let key = key.clone();
142+
if self.duplicate_index_back >= *count.borrow() {
143+
self.duplicate_back = None;
144+
self.duplicate_index_back = 0;
145+
}
146+
self.len -= 1;
147+
Some(key)
148+
} else {
149+
if let Some((key, count)) = self.duplicate.as_ref() {
150+
self.duplicate_index += 1;
151+
let key = key.clone();
152+
if self.duplicate_index >= *count.borrow() {
153+
self.duplicate = None;
154+
}
155+
self.len -= 1;
156+
Some(key)
157+
} else {
158+
None
159+
}
160+
}
161+
}
162+
163+
fn rfold<B, F>(self, init: B, mut f: F) -> B
164+
where
165+
F: FnMut(B, Self::Item) -> B,
166+
{
167+
let duplicate_index = self.duplicate_index;
168+
let duplicate_index_back = self.duplicate_index_back;
169+
self.duplicate_back
170+
.map(move |(val, count)| (val, *count.borrow() - duplicate_index_back))
171+
.into_iter()
172+
.chain(
173+
self.iter
174+
.rev()
175+
.map(move |(val, count)| (val, *count.borrow())),
176+
)
177+
.chain(
178+
self.duplicate
179+
.map(move |(val, count)| (val, *count.borrow() - duplicate_index))
180+
.into_iter(),
181+
)
182+
.fold(init, move |acc, (val, count)| {
183+
(0..count).fold(acc, |acc, _| f(acc, val.clone()))
184+
})
185+
}
186+
}

0 commit comments

Comments
 (0)