1 // RangeBounds support for older Rust versions. 2 3 use lib::ops::{Range, RangeFrom, RangeTo, RangeFull}; 4 use super::bound::*; 5 6 #[cfg(has_full_range_inclusive)] 7 use lib::ops::{RangeInclusive, RangeToInclusive}; 8 9 // The compiler does not have RangeBounds defined, this is code 10 // adopted from Rust: 11 // https://doc.rust-lang.org/src/core/ops/range.rs.html 12 // 13 // All copyright for the remainder of this file remains with the 14 // Rust contributors: 15 // https://github.com/rust-lang/rust/blob/master/COPYRIGHT 16 17 #[cfg(has_range_bounds)] 18 pub use lib::ops::RangeBounds; 19 20 #[cfg(not(has_range_bounds))] 21 pub trait RangeBounds<T: ?Sized> { 22 /// Start index bound. start_bound(&self) -> Bound<&T>23 fn start_bound(&self) -> Bound<&T>; 24 25 /// End index bound. end_bound(&self) -> Bound<&T>26 fn end_bound(&self) -> Bound<&T>; 27 28 /// Detect if item is in range. contains<U>(&self, item: &U) -> bool where T: PartialOrd<U>, U: ?Sized + PartialOrd<T>,29 fn contains<U>(&self, item: &U) -> bool 30 where 31 T: PartialOrd<U>, 32 U: ?Sized + PartialOrd<T>, 33 { 34 (match self.start_bound() { 35 Included(ref start) => *start <= item, 36 Excluded(ref start) => *start < item, 37 Unbounded => true, 38 }) && (match self.end_bound() { 39 Included(ref end) => item <= *end, 40 Excluded(ref end) => item < *end, 41 Unbounded => true, 42 }) 43 } 44 } 45 46 #[cfg(not(has_range_bounds))] 47 impl<T: ?Sized> RangeBounds<T> for RangeFull { start_bound(&self) -> Bound<&T>48 fn start_bound(&self) -> Bound<&T> { 49 Unbounded 50 } end_bound(&self) -> Bound<&T>51 fn end_bound(&self) -> Bound<&T> { 52 Unbounded 53 } 54 } 55 56 #[cfg(not(has_range_bounds))] 57 impl<T> RangeBounds<T> for RangeFrom<T> { start_bound(&self) -> Bound<&T>58 fn start_bound(&self) -> Bound<&T> { 59 Included(&self.start) 60 } end_bound(&self) -> Bound<&T>61 fn end_bound(&self) -> Bound<&T> { 62 Unbounded 63 } 64 } 65 66 #[cfg(not(has_range_bounds))] 67 impl<T> RangeBounds<T> for RangeTo<T> { start_bound(&self) -> Bound<&T>68 fn start_bound(&self) -> Bound<&T> { 69 Unbounded 70 } end_bound(&self) -> Bound<&T>71 fn end_bound(&self) -> Bound<&T> { 72 Excluded(&self.end) 73 } 74 } 75 76 #[cfg(not(has_range_bounds))] 77 impl<T> RangeBounds<T> for Range<T> { start_bound(&self) -> Bound<&T>78 fn start_bound(&self) -> Bound<&T> { 79 Included(&self.start) 80 } end_bound(&self) -> Bound<&T>81 fn end_bound(&self) -> Bound<&T> { 82 Excluded(&self.end) 83 } 84 } 85 86 #[cfg(all(not(has_range_bounds), has_full_range_inclusive))] 87 impl<T> RangeBounds<T> for RangeInclusive<T> { start_bound(&self) -> Bound<&T>88 fn start_bound(&self) -> Bound<&T> { 89 Included(self.start()) 90 } end_bound(&self) -> Bound<&T>91 fn end_bound(&self) -> Bound<&T> { 92 Included(self.end()) 93 } 94 } 95 96 #[cfg(all(not(has_range_bounds), has_full_range_inclusive))] 97 impl<T> RangeBounds<T> for RangeToInclusive<T> { start_bound(&self) -> Bound<&T>98 fn start_bound(&self) -> Bound<&T> { 99 Unbounded 100 } end_bound(&self) -> Bound<&T>101 fn end_bound(&self) -> Bound<&T> { 102 Included(&self.end) 103 } 104 } 105