@@ -50,6 +50,7 @@ impl Normalizable for Timespec {
5050 }
5151}
5252
53+ #[ deriving( Eq ) ]
5354enum BoundSide {
5455 Upper ,
5556 Lower
@@ -128,6 +129,19 @@ impl<S: BoundSided, T: Ord> RangeBound<S, T> {
128129 }
129130}
130131
132+ struct OptBound < ' self , S , T > ( & ' self Option < RangeBound < S , T > > ) ;
133+
134+ impl < ' self , S : BoundSided , T : Ord > Ord for OptBound < ' self , S , T > {
135+ fn lt ( & self , other : & OptBound < ' self , S , T > ) -> bool {
136+ match ( * * self , * * other) {
137+ ( & None , & None ) => false ,
138+ ( & None , _) => BoundSided :: side ( None :: < S > ) == Lower ,
139+ ( _, & None ) => BoundSided :: side ( None :: < S > ) == Upper ,
140+ ( & Some ( ref a) , & Some ( ref b) ) => a < b
141+ }
142+ }
143+ }
144+
131145/// Represents a range of values.
132146#[ deriving( Eq , Clone ) ]
133147pub enum Range < T > {
@@ -200,6 +214,20 @@ impl<T: Ord+Normalizable> Range<T> {
200214 }
201215 }
202216 }
217+
218+ /// Determines if a range lies completely within this range.
219+ pub fn contains_range ( & self , other : & Range < T > ) -> bool {
220+ if other. is_empty ( ) {
221+ return true ;
222+ }
223+
224+ if self . is_empty ( ) {
225+ return false ;
226+ }
227+
228+ OptBound ( self . lower ( ) ) <= OptBound ( other. lower ( ) ) &&
229+ OptBound ( self . upper ( ) ) >= OptBound ( other. upper ( ) )
230+ }
203231}
204232
205233impl < T : Ord +Normalizable +Clone > Range < T > {
@@ -209,19 +237,10 @@ impl<T: Ord+Normalizable+Clone> Range<T> {
209237 return Range :: empty ( ) ;
210238 }
211239
212- let lower = match ( self . lower ( ) , other. lower ( ) ) {
213- ( & Some ( ref a) , & Some ( ref b) ) => Some ( cmp:: max ( a, b) . clone ( ) ) ,
214- ( & Some ( ref a) , & None ) => Some ( a. clone ( ) ) ,
215- ( & None , & Some ( ref b) ) => Some ( b. clone ( ) ) ,
216- ( & None , & None ) => None
217- } ;
218-
219- let upper = match ( self . upper ( ) , other. upper ( ) ) {
220- ( & Some ( ref a) , & Some ( ref b) ) => Some ( cmp:: min ( a, b) . clone ( ) ) ,
221- ( & Some ( ref a) , & None ) => Some ( a. clone ( ) ) ,
222- ( & None , & Some ( ref b) ) => Some ( b. clone ( ) ) ,
223- ( & None , & None ) => None
224- } ;
240+ let lower = cmp:: max ( OptBound ( self . lower ( ) ) , OptBound ( other. lower ( ) ) )
241+ . clone ( ) ;
242+ let upper = cmp:: min ( OptBound ( self . upper ( ) ) , OptBound ( other. upper ( ) ) )
243+ . clone ( ) ;
225244
226245 Range :: new ( lower, upper)
227246 }
@@ -391,4 +410,23 @@ mod test {
391410 assert_eq ! ( r2, r1. intersect( & r2) ) ;
392411 assert_eq ! ( r2, r2. intersect( & r1) ) ;
393412 }
413+
414+ #[ test]
415+ fn test_contains_range ( ) {
416+ assert ! ( Range :: <i32 >:: empty( ) . contains_range( & Range :: empty( ) ) ) ;
417+
418+ let r1 = Range :: new ( Some ( RangeBound :: new ( 10i32 , Inclusive ) ) ,
419+ Some ( RangeBound :: new ( 15i32 , Exclusive ) ) ) ;
420+ assert ! ( r1. contains_range( & r1) ) ;
421+
422+ let r2 = Range :: new ( Some ( RangeBound :: new ( 10i32 , Exclusive ) ) ,
423+ None ) ;
424+ assert ! ( !r1. contains_range( & r2) ) ;
425+ assert ! ( !r2. contains_range( & r1) ) ;
426+
427+ let r2 = Range :: new ( None ,
428+ Some ( RangeBound :: new ( 15i32 , Inclusive ) ) ) ;
429+ assert ! ( !r1. contains_range( & r2) ) ;
430+ assert ! ( r2. contains_range( & r1) ) ;
431+ }
394432}
0 commit comments