foyer_common/utils/
range.rs1use std::ops::{Add, Bound, Range, RangeBounds, Sub};
16
17mod private {
18
19 pub trait ZeroOne {
20 fn zero() -> Self;
21 fn one() -> Self;
22 }
23
24 macro_rules! impl_one {
25 ($($t:ty),*) => {
26 $(
27 impl ZeroOne for $t {
28 fn zero() -> Self {
29 0 as $t
30 }
31
32 fn one() -> Self {
33 1 as $t
34 }
35 }
36 )*
37 };
38 }
39
40 macro_rules! for_all_num_type {
41 ($macro:ident) => {
42 $macro! { u8, u16, u32, u64, usize, i8, i16, i32, i64, isize, f32, f64 }
43 };
44 }
45
46 for_all_num_type! { impl_one }
47}
48
49use private::ZeroOne;
50
51pub trait RangeBoundsExt<
53 T: PartialOrd<T> + Add<Output = T> + Sub<Output = T> + Clone + Copy + Send + Sync + 'static + ZeroOne,
54>: RangeBounds<T>
55{
56 fn start(&self) -> Option<T> {
58 match self.start_bound() {
59 Bound::Included(v) => Some(*v),
60 Bound::Excluded(v) => Some(*v + ZeroOne::one()),
61 Bound::Unbounded => None,
62 }
63 }
64
65 fn end(&self) -> Option<T> {
67 match self.end_bound() {
68 Bound::Included(v) => Some(*v + ZeroOne::one()),
69 Bound::Excluded(v) => Some(*v),
70 Bound::Unbounded => None,
71 }
72 }
73
74 fn start_with_bound(&self, bound: T) -> T {
76 self.start().unwrap_or(bound)
77 }
78
79 fn end_with_bound(&self, bound: T) -> T {
81 self.end().unwrap_or(bound)
82 }
83
84 fn bounds(&self, range: Range<T>) -> Range<T> {
86 let start = self.start_with_bound(range.start);
87 let end = self.end_with_bound(range.end);
88 start..end
89 }
90
91 fn size(&self) -> Option<T> {
93 let start = self.start()?;
94 let end = self.end()?;
95 Some(end - start)
96 }
97
98 fn is_empty(&self) -> bool {
100 match self.size() {
101 Some(len) => len == ZeroOne::zero(),
102 None => false,
103 }
104 }
105
106 fn is_full(&self) -> bool {
108 self.start_bound() == Bound::Unbounded && self.end_bound() == Bound::Unbounded
109 }
110
111 fn map<F, R>(&self, f: F) -> (Bound<R>, Bound<R>)
113 where
114 F: Fn(&T) -> R,
115 {
116 (self.start_bound().map(&f), self.end_bound().map(&f))
117 }
118}
119
120impl<
121 T: PartialOrd<T> + Add<Output = T> + Sub<Output = T> + Clone + Copy + Send + Sync + 'static + ZeroOne,
122 RB: RangeBounds<T>,
123 > RangeBoundsExt<T> for RB
124{
125}