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.
@@ -204,17 +208,38 @@ impl<I: Idx> IntervalSet<I> {
204208 needle <= * prev_end
205209 }
206210
211+ /// Returns whether any point in `range` is contained in the set.
212+ pub fn intersects_range ( & self , range : impl RangeBounds < I > + Clone ) -> bool {
213+ let start = inclusive_start ( range. clone ( ) ) ;
214+ let Some ( end) = inclusive_end ( self . domain , range) else {
215+ // empty range
216+ return false ;
217+ } ;
218+ if start > end {
219+ return false ;
220+ }
221+
222+ // Find the last interval whose start is <= end.
223+ let Some ( last) = self . map . partition_point ( |r| r. 0 <= end) . checked_sub ( 1 ) else {
224+ // All ranges in the map start after the new range's end
225+ return false ;
226+ } ;
227+ let ( _, prev_end) = & self . map [ last] ;
228+ start <= * prev_end
229+ }
230+
207231 pub fn superset ( & self , other : & IntervalSet < I > ) -> bool
208232 where
209233 I : Step ,
210234 {
211235 let mut sup_iter = self . iter_intervals ( ) ;
212236 let mut current = None ;
213- let contains = |sup : Range < I > , sub : Range < I > , current : & mut Option < Range < I > > | {
214- if sup. end < sub. start {
215- // if `sup.end == sub.start`, the next sup doesn't contain `sub.start`
237+ let contains = |sup : RangeInclusive < I > ,
238+ sub : RangeInclusive < I > ,
239+ current : & mut Option < RangeInclusive < I > > | {
240+ if sup. last < sub. start {
216241 None // continue to the next sup
217- } else if sup. end >= sub. end && sup. start <= sub. start {
242+ } else if sup. last >= sub. last && sup. start <= sub. start {
218243 * current = Some ( sup) ; // save the current sup
219244 Some ( true )
220245 } else {
@@ -224,8 +249,8 @@ impl<I: Idx> IntervalSet<I> {
224249 other. iter_intervals ( ) . all ( |sub| {
225250 current
226251 . take ( )
227- . and_then ( |sup| contains ( sup, sub. clone ( ) , & mut current) )
228- . or_else ( || sup_iter. find_map ( |sup| contains ( sup, sub. clone ( ) , & mut current) ) )
252+ . and_then ( |sup| contains ( sup, sub, & mut current) )
253+ . or_else ( || sup_iter. find_map ( |sup| contains ( sup, sub, & mut current) ) )
229254 . unwrap_or ( false )
230255 } )
231256 }
@@ -242,11 +267,11 @@ impl<I: Idx> IntervalSet<I> {
242267 let mut other_current = other_iter. next ( ) ?;
243268
244269 loop {
245- if self_current. end <= other_current. start {
270+ if self_current. last < other_current. start {
246271 self_current = self_iter. next ( ) ?;
247272 continue ;
248273 }
249- if other_current. end <= self_current. start {
274+ if other_current. last < self_current. start {
250275 other_current = other_iter. next ( ) ?;
251276 continue ;
252277 }
0 commit comments