Skip to content

Commit c09aac2

Browse files
author
Gianmarco Garrisi
committed
Fix iterators
1 parent f8c95d2 commit c09aac2

File tree

5 files changed

+212
-34
lines changed

5 files changed

+212
-34
lines changed

src/core_iterators.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,9 @@ impl<'a, I: 'a, P: 'a> Iterator for Drain<'a, I, P> {
5151
fn next(&mut self) -> Option<(I, P)> {
5252
self.iter.next()
5353
}
54+
fn size_hint(&self) -> (usize, Option<usize>) {
55+
self.iter.size_hint()
56+
}
5457
}
5558

5659
impl<I, P> DoubleEndedIterator for Drain<'_, I, P> {
@@ -80,6 +83,9 @@ impl<'a, I: 'a, P: 'a> Iterator for Iter<'a, I, P> {
8083
fn next(&mut self) -> Option<(&'a I, &'a P)> {
8184
self.iter.next()
8285
}
86+
fn size_hint(&self) -> (usize, Option<usize>) {
87+
self.iter.size_hint()
88+
}
8389
}
8490

8591
impl<I, P> DoubleEndedIterator for Iter<'_, I, P> {
@@ -109,6 +115,9 @@ impl<I, P> Iterator for IntoIter<I, P> {
109115
fn next(&mut self) -> Option<(I, P)> {
110116
self.iter.next()
111117
}
118+
fn size_hint(&self) -> (usize, Option<usize>) {
119+
self.iter.size_hint()
120+
}
112121
}
113122

114123
impl<I, P> DoubleEndedIterator for IntoIter<I, P> {

src/double_priority_queue/iterators.rs

Lines changed: 28 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,7 @@ where
141141
{
142142
pq: &'a mut DoublePriorityQueue<I, P, H>,
143143
pos: usize,
144+
pos_back: usize,
144145
}
145146

146147
#[cfg(not(feature = "std"))]
@@ -150,14 +151,20 @@ where
150151
{
151152
pq: &'a mut DoublePriorityQueue<I, P, H>,
152153
pos: usize,
154+
pos_back: usize,
153155
}
154156

155157
impl<'a, I: 'a, P: 'a, H: 'a> IterMut<'a, I, P, H>
156158
where
157159
P: Ord,
158160
{
159161
pub(crate) fn new(pq: &'a mut DoublePriorityQueue<I, P, H>) -> Self {
160-
IterMut { pq, pos: 0 }
162+
let pos_back = pq.len();
163+
IterMut {
164+
pq,
165+
pos: 0,
166+
pos_back,
167+
}
161168
}
162169
}
163170

@@ -169,6 +176,9 @@ where
169176
type Item = (&'a mut I, &'a mut P);
170177
fn next(&mut self) -> Option<Self::Item> {
171178
use indexmap::map::MutableKeys;
179+
if self.pos == self.pos_back {
180+
return None;
181+
}
172182
let r: Option<(&'a mut I, &'a mut P)> = self
173183
.pq
174184
.store
@@ -179,6 +189,11 @@ where
179189
self.pos += 1;
180190
r
181191
}
192+
193+
fn size_hint(&self) -> (usize, Option<usize>) {
194+
let len = self.pos_back - self.pos;
195+
(len, Some(len))
196+
}
182197
}
183198

184199
impl<'a, I: 'a, P: 'a, H: 'a> DoubleEndedIterator for IterMut<'a, I, P, H>
@@ -188,15 +203,16 @@ where
188203
{
189204
fn next_back(&mut self) -> Option<Self::Item> {
190205
use indexmap::map::MutableKeys;
191-
let r: Option<(&'a mut I, &'a mut P)> = self
192-
.pq
206+
if self.pos == self.pos_back {
207+
return None;
208+
}
209+
self.pos_back -= 1;
210+
self.pq
193211
.store
194212
.map
195-
.get_index_mut2(self.pos)
213+
.get_index_mut2(self.pos_back)
196214
.map(|(i, p)| (i as *mut I, p as *mut P))
197-
.map(|(i, p)| unsafe { (i.as_mut().unwrap(), p.as_mut().unwrap()) });
198-
self.pos -= 1;
199-
r
215+
.map(|(i, p)| unsafe { (i.as_mut().unwrap(), p.as_mut().unwrap()) })
200216
}
201217
}
202218

@@ -205,9 +221,6 @@ where
205221
P: Ord,
206222
H: BuildHasher,
207223
{
208-
fn len(&self) -> usize {
209-
self.pq.len()
210-
}
211224
}
212225

213226
impl<I, P, H> FusedIterator for IterMut<'_, I, P, H>
@@ -258,6 +271,10 @@ where
258271
fn next(&mut self) -> Option<(I, P)> {
259272
self.pq.pop_min()
260273
}
274+
fn size_hint(&self) -> (usize, Option<usize>) {
275+
let len = self.pq.len();
276+
(len, Some(len))
277+
}
261278
}
262279

263280
impl<I, P, H> DoubleEndedIterator for IntoSortedIter<I, P, H>
@@ -269,13 +286,6 @@ where
269286
}
270287
}
271288

272-
impl<I, P, H> ExactSizeIterator for IntoSortedIter<I, P, H>
273-
where
274-
P: Ord,
275-
{
276-
fn len(&self) -> usize {
277-
self.pq.len()
278-
}
279-
}
289+
impl<I, P, H> ExactSizeIterator for IntoSortedIter<I, P, H> where P: Ord {}
280290

281291
impl<I, P, H> FusedIterator for IntoSortedIter<I, P, H> where P: Ord {}

src/priority_queue/iterators.rs

Lines changed: 66 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,10 @@ where
112112
}
113113
}
114114
}
115+
116+
fn size_hint(&self) -> (usize, Option<usize>) {
117+
(0, Some(self.pq.len()))
118+
}
115119
}
116120

117121
impl<'a, I: 'a, P: 'a, F, H: 'a> Drop for ExtractIf<'a, I, P, F, H>
@@ -141,6 +145,7 @@ where
141145
{
142146
pq: &'a mut PriorityQueue<I, P, H>,
143147
pos: usize,
148+
pos_back: usize,
144149
}
145150

146151
#[cfg(not(feature = "std"))]
@@ -150,14 +155,20 @@ where
150155
{
151156
pq: &'a mut PriorityQueue<I, P, H>,
152157
pos: usize,
158+
pos_back: usize,
153159
}
154160

155161
impl<'a, I: 'a, P: 'a, H: 'a> IterMut<'a, I, P, H>
156162
where
157163
P: Ord,
158164
{
159165
pub(crate) fn new(pq: &'a mut PriorityQueue<I, P, H>) -> Self {
160-
IterMut { pq, pos: 0 }
166+
let pos_back = pq.len();
167+
IterMut {
168+
pq,
169+
pos: 0,
170+
pos_back,
171+
}
161172
}
162173
}
163174

@@ -170,6 +181,10 @@ where
170181
fn next(&mut self) -> Option<Self::Item> {
171182
use indexmap::map::MutableKeys;
172183

184+
if self.pos == self.pos_back {
185+
return None;
186+
}
187+
173188
let r: Option<(&'a mut I, &'a mut P)> = self
174189
.pq
175190
.store
@@ -180,6 +195,47 @@ where
180195
self.pos += 1;
181196
r
182197
}
198+
199+
fn size_hint(&self) -> (usize, Option<usize>) {
200+
let len = self.pos_back - self.pos;
201+
(len, Some(len))
202+
}
203+
}
204+
205+
impl<'a, I: 'a, P: 'a, H: 'a> DoubleEndedIterator for IterMut<'a, I, P, H>
206+
where
207+
P: Ord,
208+
H: BuildHasher,
209+
{
210+
fn next_back(&mut self) -> Option<Self::Item> {
211+
use indexmap::map::MutableKeys;
212+
213+
if self.pos == self.pos_back {
214+
return None;
215+
}
216+
217+
self.pos_back -= 1;
218+
self.pq
219+
.store
220+
.map
221+
.get_index_mut2(self.pos_back)
222+
.map(|(i, p)| (i as *mut I, p as *mut P))
223+
.map(|(i, p)| unsafe { (i.as_mut().unwrap(), p.as_mut().unwrap()) })
224+
}
225+
}
226+
227+
impl<'a, I: 'a, P: 'a, H: 'a> ExactSizeIterator for IterMut<'a, I, P, H>
228+
where
229+
P: Ord,
230+
H: BuildHasher,
231+
{
232+
}
233+
234+
impl<'a, I: 'a, P: 'a, H: 'a> FusedIterator for IterMut<'a, I, P, H>
235+
where
236+
P: Ord,
237+
H: BuildHasher,
238+
{
183239
}
184240

185241
impl<'a, I: 'a, P: 'a, H: 'a> Drop for IterMut<'a, I, P, H>
@@ -213,4 +269,13 @@ where
213269
fn next(&mut self) -> Option<(I, P)> {
214270
self.pq.pop()
215271
}
272+
273+
fn size_hint(&self) -> (usize, Option<usize>) {
274+
let len = self.pq.len();
275+
(len, Some(len))
276+
}
216277
}
278+
279+
impl<I, P, H> ExactSizeIterator for IntoSortedIter<I, P, H> where P: Ord {}
280+
281+
impl<I, P, H> FusedIterator for IntoSortedIter<I, P, H> where P: Ord {}

tests/double_priority_queue.rs

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -782,7 +782,9 @@ mod doublepq_tests {
782782
pq.push("b", 2);
783783
pq.push("f", 7);
784784

785-
assert_eq!(pq.iter().count(), 3);
785+
let iter = pq.iter();
786+
assert_eq!(iter.size_hint(), (3, Some(3)));
787+
assert_eq!(iter.count(), 3);
786788
}
787789

788790
#[test]
@@ -794,14 +796,20 @@ mod doublepq_tests {
794796
pq.push("g", 4);
795797
pq.push("h", 3);
796798

797-
for (i, p) in &mut pq {
799+
let iter = pq.iter_mut();
800+
assert_eq!(iter.size_hint(), (5, Some(5)));
801+
assert_eq!(iter.len(), 5);
802+
803+
for (i, p) in iter {
798804
if *i < "f" {
799805
*p += 18;
800806
}
801807
}
802808

803809
assert_eq!(pq.pop_max(), Some(("b", 20)));
804810

811+
assert_eq!(pq.iter_mut().rev().count(), 4);
812+
805813
/*
806814
// As expected, this does not compile
807815
let iter_mut = pq.iter_mut();
@@ -810,6 +818,19 @@ mod doublepq_tests {
810818
iter_mut.for_each(|(_, p)| {*p += 2}); */
811819
}
812820

821+
#[test]
822+
fn iter_mut_next_back() {
823+
let mut pq = DoublePriorityQueue::new();
824+
pq.push("a", 1);
825+
pq.push("b", 2);
826+
pq.push("f", 7);
827+
pq.push("g", 4);
828+
pq.push("h", 3);
829+
830+
let mut iter = pq.iter_mut();
831+
assert_eq!(iter.next_back(), Some((&mut "h", &mut 3)));
832+
}
833+
813834
#[test]
814835
fn retain() {
815836
#[derive(Hash, PartialEq, Eq, Debug)]

0 commit comments

Comments
 (0)