|
63 | 63 |
|
64 | 64 | use core::borrow::Borrow;
|
65 | 65 | use core::cmp::Ordering;
|
| 66 | +use core::ops::{Bound, RangeBounds}; |
66 | 67 |
|
67 | 68 | /// Key equivalence trait.
|
68 | 69 | ///
|
@@ -111,3 +112,39 @@ where
|
111 | 112 | Ord::cmp(self, key.borrow())
|
112 | 113 | }
|
113 | 114 | }
|
| 115 | + |
| 116 | +/// `ComparableRangeBounds` is implemented as an extention to `RangeBounds` to |
| 117 | +/// allow for comparison of items with range bounds. |
| 118 | +pub trait ComparableRangeBounds<T>: RangeBounds<T> { |
| 119 | + /// Returns `true` if `item` is contained in the range. |
| 120 | + /// |
| 121 | + /// # Examples |
| 122 | + /// |
| 123 | + /// ``` |
| 124 | + /// assert!( (3..5).comparable_contains(&4)); |
| 125 | + /// assert!(!(3..5).comparable_contains(&2)); |
| 126 | + /// |
| 127 | + /// assert!( (0.0..1.0).comparable_contains(&0.5)); |
| 128 | + /// assert!(!(0.0..1.0).comparable_contains(&f32::NAN)); |
| 129 | + /// assert!(!(0.0..f32::NAN).comparable_contains(&0.5)); |
| 130 | + /// assert!(!(f32::NAN..1.0).comparable_contains(&0.5)); |
| 131 | + /// ``` |
| 132 | + fn comparable_contains<U>(&self, item: &U) -> bool |
| 133 | + where |
| 134 | + U: ?Sized + Comparable<T>, |
| 135 | + { |
| 136 | + (match self.start_bound() { |
| 137 | + Bound::Included(start) => { |
| 138 | + matches!(item.compare(start), Ordering::Greater | Ordering::Equal) |
| 139 | + } |
| 140 | + Bound::Excluded(start) => item.compare(start) == Ordering::Greater, |
| 141 | + Bound::Unbounded => true, |
| 142 | + }) && (match self.end_bound() { |
| 143 | + Bound::Included(end) => matches!(item.compare(end), Ordering::Less | Ordering::Equal), |
| 144 | + Bound::Excluded(end) => item.compare(end) == Ordering::Less, |
| 145 | + Bound::Unbounded => true, |
| 146 | + }) |
| 147 | + } |
| 148 | +} |
| 149 | + |
| 150 | +impl<R, T> ComparableRangeBounds<T> for R where R: RangeBounds<T> {} |
0 commit comments