@@ -92,6 +92,100 @@ fn advance_to_impl<'a, It>(
9292 }
9393}
9494
95+ fn next_range_impl < ' a , It > (
96+ front_iter : & mut Option < container:: Iter < ' a > > ,
97+ containers : & mut It ,
98+ back_iter : & mut Option < container:: Iter < ' a > > ,
99+ ) -> Option < core:: ops:: RangeInclusive < u32 > >
100+ where
101+ It : Iterator + Clone ,
102+ It : AsRef < [ Container ] > ,
103+ It :: Item : IntoIterator < IntoIter = container:: Iter < ' a > > ,
104+ {
105+ let range = loop {
106+ if let Some ( r) = and_then_or_clear ( front_iter, container:: Iter :: next_range) {
107+ break r;
108+ }
109+ * front_iter = match containers. next ( ) {
110+ Some ( inner) => Some ( inner. into_iter ( ) ) ,
111+ None => return and_then_or_clear ( back_iter, container:: Iter :: next_range) ,
112+ }
113+ } ;
114+ let ( range_start, mut range_end) = ( * range. start ( ) , * range. end ( ) ) ;
115+ while range_end & 0xFFFF == 0xFFFF {
116+ let Some ( after_end) = range_end. checked_add ( 1 ) else {
117+ return Some ( range_start..=range_end) ;
118+ } ;
119+ let ( next_key, _) = util:: split ( after_end) ;
120+
121+ if containers. as_ref ( ) . first ( ) . is_some_and ( |c| c. key == next_key && c. contains ( 0 ) ) {
122+ let mut iter = containers. next ( ) . unwrap ( ) . into_iter ( ) ;
123+ let next_range = iter. next_range ( ) . unwrap ( ) ;
124+ * front_iter = Some ( iter) ;
125+ debug_assert_eq ! ( * next_range. start( ) , after_end) ;
126+ range_end = * next_range. end ( ) ;
127+ } else {
128+ if let Some ( iter) = back_iter {
129+ if iter. peek ( ) == Some ( after_end) {
130+ let next_range = iter. next_range ( ) . unwrap ( ) ;
131+ debug_assert_eq ! ( * next_range. start( ) , after_end) ;
132+ range_end = * next_range. end ( ) ;
133+ }
134+ }
135+ break ;
136+ }
137+ }
138+
139+ Some ( range_start..=range_end)
140+ }
141+
142+ fn next_range_back_impl < ' a , It > (
143+ front_iter : & mut Option < container:: Iter < ' a > > ,
144+ containers : & mut It ,
145+ back_iter : & mut Option < container:: Iter < ' a > > ,
146+ ) -> Option < core:: ops:: RangeInclusive < u32 > >
147+ where
148+ It : DoubleEndedIterator ,
149+ It : AsRef < [ Container ] > ,
150+ It :: Item : IntoIterator < IntoIter = container:: Iter < ' a > > ,
151+ {
152+ let range = loop {
153+ if let Some ( r) = and_then_or_clear ( back_iter, container:: Iter :: next_range_back) {
154+ break r;
155+ }
156+ * back_iter = match containers. next_back ( ) {
157+ Some ( inner) => Some ( inner. into_iter ( ) ) ,
158+ None => return and_then_or_clear ( front_iter, container:: Iter :: next_range_back) ,
159+ }
160+ } ;
161+ let ( mut range_start, range_end) = ( * range. start ( ) , * range. end ( ) ) ;
162+ while range_start & 0xFFFF == 0 {
163+ let Some ( before_start) = range_start. checked_sub ( 1 ) else {
164+ return Some ( range_start..=range_end) ;
165+ } ;
166+ let ( prev_key, _) = util:: split ( before_start) ;
167+
168+ if containers. as_ref ( ) . last ( ) . is_some_and ( |c| c. key == prev_key && c. contains ( u16:: MAX ) ) {
169+ let mut iter = containers. next_back ( ) . unwrap ( ) . into_iter ( ) ;
170+ let next_range = iter. next_range_back ( ) . unwrap ( ) ;
171+ * back_iter = Some ( iter) ;
172+ debug_assert_eq ! ( * next_range. end( ) , before_start) ;
173+ range_start = * next_range. start ( ) ;
174+ } else {
175+ if let Some ( iter) = front_iter {
176+ if iter. key == prev_key && iter. peek_back ( ) == Some ( before_start) {
177+ let next_range = iter. next_range_back ( ) . unwrap ( ) ;
178+ debug_assert_eq ! ( * next_range. end( ) , before_start) ;
179+ range_start = * next_range. start ( ) ;
180+ }
181+ }
182+ break ;
183+ }
184+ }
185+
186+ Some ( range_start..=range_end)
187+ }
188+
95189fn advance_back_to_impl < ' a , It > (
96190 n : u32 ,
97191 front_iter : & mut Option < container:: Iter < ' a > > ,
@@ -197,6 +291,46 @@ impl Iter<'_> {
197291 pub fn advance_back_to ( & mut self , n : u32 ) {
198292 advance_back_to_impl ( n, & mut self . front , & mut self . containers , & mut self . back ) ;
199293 }
294+
295+ /// Returns the range of consecutive set bits from the current position to the end of the current run
296+ ///
297+ /// After this call, the iterator will be positioned at the first item after the returned range.
298+ /// Returns `None` if the iterator is exhausted.
299+ ///
300+ /// # Examples
301+ ///
302+ /// ```rust
303+ /// use roaring::RoaringBitmap;
304+ ///
305+ /// let bm = RoaringBitmap::from([1, 2, 4, 5]);
306+ /// let mut iter = bm.iter();
307+ /// assert_eq!(iter.next_range(), Some(1..=2));
308+ /// assert_eq!(iter.next(), Some(4));
309+ /// assert_eq!(iter.next_range(), Some(5..=5));
310+ /// ```
311+ pub fn next_range ( & mut self ) -> Option < core:: ops:: RangeInclusive < u32 > > {
312+ next_range_impl ( & mut self . front , & mut self . containers , & mut self . back )
313+ }
314+
315+ /// Returns the range of consecutive set bits from the start of the current run to the current back position
316+ ///
317+ /// After this call, the back of the iterator will be positioned at the last item before the returned range.
318+ /// Returns `None` if the iterator is exhausted.
319+ ///
320+ /// # Examples
321+ ///
322+ /// ```rust
323+ /// use roaring::RoaringBitmap;
324+ ///
325+ /// let bm = RoaringBitmap::from([1, 2, 4, 5]);
326+ /// let mut iter = bm.iter();
327+ /// assert_eq!(iter.next_range_back(), Some(4..=5));
328+ /// assert_eq!(iter.next_back(), Some(2));
329+ /// assert_eq!(iter.next_range_back(), Some(1..=1));
330+ /// ```
331+ pub fn next_range_back ( & mut self ) -> Option < core:: ops:: RangeInclusive < u32 > > {
332+ next_range_back_impl ( & mut self . front , & mut self . containers , & mut self . back )
333+ }
200334}
201335
202336impl IntoIter {
@@ -245,6 +379,46 @@ impl IntoIter {
245379 pub fn advance_back_to ( & mut self , n : u32 ) {
246380 advance_back_to_impl ( n, & mut self . front , & mut self . containers , & mut self . back ) ;
247381 }
382+
383+ /// Returns the range of consecutive set bits from the current position to the end of the current run
384+ ///
385+ /// After this call, the iterator will be positioned at the first item after the returned range.
386+ /// Returns `None` if the iterator is exhausted.
387+ ///
388+ /// # Examples
389+ ///
390+ /// ```rust
391+ /// use roaring::RoaringBitmap;
392+ ///
393+ /// let bm = RoaringBitmap::from([1, 2, 4, 5]);
394+ /// let mut iter = bm.into_iter();
395+ /// assert_eq!(iter.next_range(), Some(1..=2));
396+ /// assert_eq!(iter.next(), Some(4));
397+ /// assert_eq!(iter.next_range(), Some(5..=5));
398+ /// ```
399+ pub fn next_range ( & mut self ) -> Option < core:: ops:: RangeInclusive < u32 > > {
400+ next_range_impl ( & mut self . front , & mut self . containers , & mut self . back )
401+ }
402+
403+ /// Returns the range of consecutive set bits from the start of the current run to the current back position
404+ ///
405+ /// After this call, the back of the iterator will be positioned at the last item before the returned range.
406+ /// Returns `None` if the iterator is exhausted.
407+ ///
408+ /// # Examples
409+ ///
410+ /// ```rust
411+ /// use roaring::RoaringBitmap;
412+ ///
413+ /// let bm = RoaringBitmap::from([1, 2, 4, 5]);
414+ /// let mut iter = bm.into_iter();
415+ /// assert_eq!(iter.next_range_back(), Some(4..=5));
416+ /// assert_eq!(iter.next_back(), Some(2));
417+ /// assert_eq!(iter.next_range_back(), Some(1..=1));
418+ /// ```
419+ pub fn next_range_back ( & mut self ) -> Option < core:: ops:: RangeInclusive < u32 > > {
420+ next_range_back_impl ( & mut self . front , & mut self . containers , & mut self . back )
421+ }
248422}
249423
250424fn size_hint_impl (
0 commit comments