11use std:: iter:: Step ;
22use std:: marker:: PhantomData ;
3- use std:: ops:: { Bound , Range , RangeBounds } ;
3+ use std:: ops:: { Bound , RangeBounds } ;
4+ use std:: range:: RangeInclusive ;
45
56use smallvec:: SmallVec ;
67
@@ -59,11 +60,14 @@ impl<I: Idx> IntervalSet<I> {
5960 }
6061
6162 /// Iterates through intervals stored in the set, in order.
62- pub fn iter_intervals ( & self ) -> impl Iterator < Item = std :: ops :: Range < I > >
63+ pub fn iter_intervals ( & self ) -> impl Iterator < Item = RangeInclusive < I > >
6364 where
6465 I : Step ,
6566 {
66- self . map . iter ( ) . map ( |& ( start, end) | I :: new ( start as usize ) ..I :: new ( end as usize + 1 ) )
67+ self . map . iter ( ) . map ( |& ( start, end) | RangeInclusive {
68+ start : I :: new ( start as usize ) ,
69+ last : I :: new ( end as usize ) ,
70+ } )
6771 }
6872
6973 /// Returns true if we increased the number of elements present.
@@ -164,6 +168,35 @@ impl<I: Idx> IntervalSet<I> {
164168 ) ;
165169 }
166170
171+ /// Specialized version of `insert` when we know that the inserted range is
172+ /// *after* any contained.
173+ pub fn append_range ( & mut self , range : impl RangeBounds < I > + Clone ) {
174+ let start = inclusive_start ( range. clone ( ) ) ;
175+ let Some ( end) = inclusive_end ( self . domain , range) else {
176+ // empty range
177+ return ;
178+ } ;
179+ if start > end {
180+ return ;
181+ }
182+
183+ if let Some ( ( _, last_end) ) = self . map . last_mut ( ) {
184+ assert ! ( * last_end < start) ;
185+ if start == * last_end + 1 {
186+ * last_end = end;
187+ } else {
188+ self . map . push ( ( start, end) ) ;
189+ }
190+ } else {
191+ self . map . push ( ( start, end) ) ;
192+ }
193+
194+ debug_assert ! (
195+ self . check_invariants( ) ,
196+ "wrong intervals after append {start:?}..={end:?} to {self:?}"
197+ ) ;
198+ }
199+
167200 pub fn contains ( & self , needle : I ) -> bool {
168201 let needle = needle. index ( ) as u32 ;
169202 let Some ( last) = self . map . partition_point ( |r| r. 0 <= needle) . checked_sub ( 1 ) else {
@@ -174,17 +207,38 @@ impl<I: Idx> IntervalSet<I> {
174207 needle <= * prev_end
175208 }
176209
210+ /// Returns whether any point in `range` is contained in the set.
211+ pub fn intersects_range ( & self , range : impl RangeBounds < I > + Clone ) -> bool {
212+ let start = inclusive_start ( range. clone ( ) ) ;
213+ let Some ( end) = inclusive_end ( self . domain , range) else {
214+ // empty range
215+ return false ;
216+ } ;
217+ if start > end {
218+ return false ;
219+ }
220+
221+ // Find the last interval whose start is <= end.
222+ let Some ( last) = self . map . partition_point ( |r| r. 0 <= end) . checked_sub ( 1 ) else {
223+ // All ranges in the map start after the new range's end
224+ return false ;
225+ } ;
226+ let ( _, prev_end) = & self . map [ last] ;
227+ start <= * prev_end
228+ }
229+
177230 pub fn superset ( & self , other : & IntervalSet < I > ) -> bool
178231 where
179232 I : Step ,
180233 {
181234 let mut sup_iter = self . iter_intervals ( ) ;
182235 let mut current = None ;
183- let contains = |sup : Range < I > , sub : Range < I > , current : & mut Option < Range < I > > | {
184- if sup. end < sub. start {
185- // if `sup.end == sub.start`, the next sup doesn't contain `sub.start`
236+ let contains = |sup : RangeInclusive < I > ,
237+ sub : RangeInclusive < I > ,
238+ current : & mut Option < RangeInclusive < I > > | {
239+ if sup. last < sub. start {
186240 None // continue to the next sup
187- } else if sup. end >= sub. end && sup. start <= sub. start {
241+ } else if sup. last >= sub. last && sup. start <= sub. start {
188242 * current = Some ( sup) ; // save the current sup
189243 Some ( true )
190244 } else {
@@ -194,8 +248,8 @@ impl<I: Idx> IntervalSet<I> {
194248 other. iter_intervals ( ) . all ( |sub| {
195249 current
196250 . take ( )
197- . and_then ( |sup| contains ( sup, sub. clone ( ) , & mut current) )
198- . or_else ( || sup_iter. find_map ( |sup| contains ( sup, sub. clone ( ) , & mut current) ) )
251+ . and_then ( |sup| contains ( sup, sub, & mut current) )
252+ . or_else ( || sup_iter. find_map ( |sup| contains ( sup, sub, & mut current) ) )
199253 . unwrap_or ( false )
200254 } )
201255 }
@@ -212,11 +266,11 @@ impl<I: Idx> IntervalSet<I> {
212266 let mut other_current = other_iter. next ( ) ?;
213267
214268 loop {
215- if self_current. end <= other_current. start {
269+ if self_current. last < other_current. start {
216270 self_current = self_iter. next ( ) ?;
217271 continue ;
218272 }
219- if other_current. end <= self_current. start {
273+ if other_current. last < self_current. start {
220274 other_current = other_iter. next ( ) ?;
221275 continue ;
222276 }
@@ -340,6 +394,12 @@ impl<R: Idx, C: Step + Idx> SparseIntervalMatrix<R, C> {
340394 self . rows . get ( row)
341395 }
342396
397+ pub fn clear_row ( & mut self , row : R ) {
398+ if let Some ( row) = self . rows . get_mut ( row) {
399+ row. clear ( ) ;
400+ }
401+ }
402+
343403 fn ensure_row ( & mut self , row : R ) -> & mut IntervalSet < C > {
344404 self . rows . ensure_contains_elem ( row, || IntervalSet :: new ( self . column_size ) )
345405 }
@@ -363,6 +423,16 @@ impl<R: Idx, C: Step + Idx> SparseIntervalMatrix<R, C> {
363423 write_row. union ( read_row)
364424 }
365425
426+ pub fn disjoint_rows ( & self , a : R , b : R ) -> bool
427+ where
428+ C : Step ,
429+ {
430+ let ( Some ( a) , Some ( b) ) = ( self . rows . get ( a) , self . rows . get ( b) ) else {
431+ return true ;
432+ } ;
433+ a. disjoint ( b)
434+ }
435+
366436 pub fn insert_all_into_row ( & mut self , row : R ) {
367437 self . ensure_row ( row) . insert_all ( ) ;
368438 }
@@ -379,6 +449,10 @@ impl<R: Idx, C: Step + Idx> SparseIntervalMatrix<R, C> {
379449 self . ensure_row ( row) . append ( point)
380450 }
381451
452+ pub fn append_range ( & mut self , row : R , range : impl RangeBounds < C > + Clone ) {
453+ self . ensure_row ( row) . append_range ( range)
454+ }
455+
382456 pub fn contains ( & self , row : R , point : C ) -> bool {
383457 self . row ( row) . is_some_and ( |r| r. contains ( point) )
384458 }
0 commit comments