Skip to content

Commit 73714f8

Browse files
committed
add dedicated fold and rfold impls
add test for `fold` also add test for treemap use closures directly
1 parent 3fa2e73 commit 73714f8

File tree

4 files changed

+132
-0
lines changed

4 files changed

+132
-0
lines changed

src/bitmap/iter.rs

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,13 +46,30 @@ impl Iterator for Iter<'_> {
4646
(usize::MAX, None)
4747
}
4848
}
49+
50+
#[inline]
51+
fn fold<B, F>(self, init: B, f: F) -> B
52+
where
53+
Self: Sized,
54+
F: FnMut(B, Self::Item) -> B,
55+
{
56+
self.inner.fold(init, f)
57+
}
4958
}
5059

5160
impl DoubleEndedIterator for Iter<'_> {
5261
fn next_back(&mut self) -> Option<Self::Item> {
5362
self.size_hint = self.size_hint.saturating_sub(1);
5463
self.inner.next_back()
5564
}
65+
66+
#[inline]
67+
fn rfold<Acc, Fold>(self, init: Acc, fold: Fold) -> Acc
68+
where
69+
Fold: FnMut(Acc, Self::Item) -> Acc,
70+
{
71+
self.inner.rfold(init, fold)
72+
}
5673
}
5774

5875
#[cfg(target_pointer_width = "64")]
@@ -77,13 +94,30 @@ impl Iterator for IntoIter {
7794
(usize::MAX, None)
7895
}
7996
}
97+
98+
#[inline]
99+
fn fold<B, F>(self, init: B, f: F) -> B
100+
where
101+
Self: Sized,
102+
F: FnMut(B, Self::Item) -> B,
103+
{
104+
self.inner.fold(init, f)
105+
}
80106
}
81107

82108
impl DoubleEndedIterator for IntoIter {
83109
fn next_back(&mut self) -> Option<Self::Item> {
84110
self.size_hint = self.size_hint.saturating_sub(1);
85111
self.inner.next_back()
86112
}
113+
114+
#[inline]
115+
fn rfold<Acc, Fold>(self, init: Acc, fold: Fold) -> Acc
116+
where
117+
Fold: FnMut(Acc, Self::Item) -> Acc,
118+
{
119+
self.inner.rfold(init, fold)
120+
}
87121
}
88122

89123
#[cfg(target_pointer_width = "64")]

src/treemap/iter.rs

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,30 @@ impl<'a> Iterator for To64Iter<'a> {
1616
fn next(&mut self) -> Option<u64> {
1717
self.inner.next().map(|n| util::join(self.hi, n))
1818
}
19+
20+
#[inline]
21+
fn fold<B, F>(self, init: B, mut f: F) -> B
22+
where
23+
Self: Sized,
24+
F: FnMut(B, Self::Item) -> B,
25+
{
26+
self.inner.fold(init, move |b, lo| f(b, ((self.hi as u64) << 32) + (lo as u64)))
27+
}
1928
}
2029

2130
impl DoubleEndedIterator for To64Iter<'_> {
2231
fn next_back(&mut self) -> Option<Self::Item> {
2332
self.inner.next_back().map(|n| util::join(self.hi, n))
2433
}
34+
35+
#[inline]
36+
fn rfold<B, F>(self, init: B, mut f: F) -> B
37+
where
38+
Self: Sized,
39+
F: FnMut(B, Self::Item) -> B,
40+
{
41+
self.inner.rfold(init, move |b, lo| f(b, ((self.hi as u64) << 32) + (lo as u64)))
42+
}
2543
}
2644

2745
fn to64iter<'a>(t: (&'a u32, &'a RoaringBitmap)) -> To64Iter<'a> {
@@ -38,12 +56,30 @@ impl Iterator for To64IntoIter {
3856
fn next(&mut self) -> Option<u64> {
3957
self.inner.next().map(|n| util::join(self.hi, n))
4058
}
59+
60+
#[inline]
61+
fn fold<B, F>(self, init: B, mut f: F) -> B
62+
where
63+
Self: Sized,
64+
F: FnMut(B, Self::Item) -> B,
65+
{
66+
self.inner.fold(init, move |b, lo| f(b, ((self.hi as u64) << 32) + (lo as u64)))
67+
}
4168
}
4269

4370
impl DoubleEndedIterator for To64IntoIter {
4471
fn next_back(&mut self) -> Option<Self::Item> {
4572
self.inner.next_back().map(|n| util::join(self.hi, n))
4673
}
74+
75+
#[inline]
76+
fn rfold<B, F>(self, init: B, mut f: F) -> B
77+
where
78+
Self: Sized,
79+
F: FnMut(B, Self::Item) -> B,
80+
{
81+
self.inner.rfold(init, move |b, lo| f(b, ((self.hi as u64) << 32) + (lo as u64)))
82+
}
4783
}
4884

4985
fn to64intoiter(t: (u32, RoaringBitmap)) -> To64IntoIter {
@@ -104,13 +140,30 @@ impl<'a> Iterator for Iter<'a> {
104140
(usize::MAX, None)
105141
}
106142
}
143+
144+
#[inline]
145+
fn fold<B, F>(self, init: B, f: F) -> B
146+
where
147+
Self: Sized,
148+
F: FnMut(B, Self::Item) -> B,
149+
{
150+
self.inner.fold(init, f)
151+
}
107152
}
108153

109154
impl DoubleEndedIterator for Iter<'_> {
110155
fn next_back(&mut self) -> Option<Self::Item> {
111156
self.size_hint = self.size_hint.saturating_sub(1);
112157
self.inner.next_back()
113158
}
159+
160+
#[inline]
161+
fn rfold<Acc, Fold>(self, init: Acc, fold: Fold) -> Acc
162+
where
163+
Fold: FnMut(Acc, Self::Item) -> Acc,
164+
{
165+
self.inner.rfold(init, fold)
166+
}
114167
}
115168

116169
#[cfg(target_pointer_width = "64")]
@@ -135,13 +188,30 @@ impl Iterator for IntoIter {
135188
(usize::MAX, None)
136189
}
137190
}
191+
192+
#[inline]
193+
fn fold<B, F>(self, init: B, f: F) -> B
194+
where
195+
Self: Sized,
196+
F: FnMut(B, Self::Item) -> B,
197+
{
198+
self.inner.fold(init, f)
199+
}
138200
}
139201

140202
impl DoubleEndedIterator for IntoIter {
141203
fn next_back(&mut self) -> Option<Self::Item> {
142204
self.size_hint = self.size_hint.saturating_sub(1);
143205
self.inner.next_back()
144206
}
207+
208+
#[inline]
209+
fn rfold<Acc, Fold>(self, init: Acc, fold: Fold) -> Acc
210+
where
211+
Fold: FnMut(Acc, Self::Item) -> Acc,
212+
{
213+
self.inner.rfold(init, fold)
214+
}
145215
}
146216

147217
#[cfg(target_pointer_width = "64")]

tests/iter.rs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,20 @@ proptest! {
6767
}
6868
}
6969

70+
proptest! {
71+
#[test]
72+
fn fold(values in btree_set(any::<u32>(), ..=10_000)) {
73+
let bitmap = RoaringBitmap::from_sorted_iter(values.iter().cloned()).unwrap();
74+
let mut val_iter = values.into_iter();
75+
// `Iterator::all` uses currently unimplementable `try_fold`, we test `fold`
76+
#[allow(clippy::unnecessary_fold)]
77+
let r = bitmap.into_iter().fold(true, |b, i| {
78+
b && i == val_iter.next().unwrap()
79+
});
80+
assert!(r)
81+
}
82+
}
83+
7084
#[test]
7185
fn rev_array() {
7286
let values = 0..100;

tests/treemap_iter.rs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,20 @@ proptest! {
7777
}
7878
}
7979

80+
proptest! {
81+
#[test]
82+
fn fold(values in btree_set(any::<u64>(), ..=10_000)) {
83+
let bitmap = RoaringTreemap::from_sorted_iter(values.iter().cloned()).unwrap();
84+
let mut val_iter = values.into_iter();
85+
// `Iterator::all` uses currently unimplementable `try_fold`, we test `fold`
86+
#[allow(clippy::unnecessary_fold)]
87+
let r = bitmap.into_iter().fold(true, |b, i| {
88+
b && i == val_iter.next().unwrap()
89+
});
90+
assert!(r)
91+
}
92+
}
93+
8094
#[test]
8195
fn rev() {
8296
let values = (1..3)

0 commit comments

Comments
 (0)