rangemap/
range_wrapper.rs

1// Wrappers to allow storing (and sorting/searching)
2// ranges as the keys of a `BTreeMap`.
3//
4// This wraps the range in two layers: one that lets us
5// order ranges by their start (`RangeStartWrapper`),
6// and then within that, one that lets us order them by
7// their end (`RangeEndWrapper`). Ordinarily we'll use
8// the former, but there are a couple of cases where we
9// want to be able to do the latter for performance/convenience.
10//
11// This is made possible by a sneaky `Borrow` implementation
12// which skirts the law about the borrowed representation
13// having identical implementations of `Ord` etc., but shouldn't
14// be a problem in practice because users of the crate can't
15// access these special wrappers, and we are careful to uphold
16// invariants that prevent observing any states where the
17// differing implementations would produce different results.
18//
19// Specifically, we maintain the invariants
20// that the order of range starts is the same as the order
21// of range ends, and that no two stored ranges have the
22// same start or end as each other.
23//
24// NOTE: Be very careful not to accidentally use these
25// if you really do want to compare equality of the
26// inner range!
27
28use core::cmp::Ordering;
29use core::ops::{Deref, Range, RangeInclusive};
30
31//
32// Range start wrapper
33//
34
35#[derive(Debug, Clone)]
36pub struct RangeStartWrapper<T> {
37    pub end_wrapper: RangeEndWrapper<T>,
38}
39
40impl<T> RangeStartWrapper<T> {
41    pub fn new(range: Range<T>) -> RangeStartWrapper<T> {
42        RangeStartWrapper {
43            end_wrapper: RangeEndWrapper::new(range),
44        }
45    }
46}
47
48impl<T> PartialEq for RangeStartWrapper<T>
49where
50    T: PartialEq,
51{
52    fn eq(&self, other: &RangeStartWrapper<T>) -> bool {
53        self.start == other.start
54    }
55}
56
57impl<T> Eq for RangeStartWrapper<T> where T: Eq {}
58
59impl<T> Ord for RangeStartWrapper<T>
60where
61    T: Ord,
62{
63    fn cmp(&self, other: &RangeStartWrapper<T>) -> Ordering {
64        self.start.cmp(&other.start)
65    }
66}
67
68impl<T> PartialOrd for RangeStartWrapper<T>
69where
70    T: PartialOrd,
71{
72    fn partial_cmp(&self, other: &RangeStartWrapper<T>) -> Option<Ordering> {
73        self.start.partial_cmp(&other.start)
74    }
75}
76
77impl<T> core::borrow::Borrow<RangeEndWrapper<T>> for RangeStartWrapper<T> {
78    fn borrow(&self) -> &RangeEndWrapper<T> {
79        &self.end_wrapper
80    }
81}
82
83// Avoid the need to tediously plumb through the layers of wrapper structs
84// when you're just trying to access members of the inner range itself.
85impl<T> Deref for RangeStartWrapper<T> {
86    type Target = RangeEndWrapper<T>;
87
88    fn deref(&self) -> &Self::Target {
89        &self.end_wrapper
90    }
91}
92
93//
94// Range end wrapper
95//
96
97#[derive(Debug, Clone)]
98pub struct RangeEndWrapper<T> {
99    pub range: Range<T>,
100}
101
102impl<T> RangeEndWrapper<T> {
103    pub fn new(range: Range<T>) -> RangeEndWrapper<T> {
104        RangeEndWrapper { range }
105    }
106}
107
108impl<T> PartialEq for RangeEndWrapper<T>
109where
110    T: PartialEq,
111{
112    fn eq(&self, other: &RangeEndWrapper<T>) -> bool {
113        self.end == other.end
114    }
115}
116
117impl<T> Eq for RangeEndWrapper<T> where T: Eq {}
118
119impl<T> Ord for RangeEndWrapper<T>
120where
121    T: Ord,
122{
123    fn cmp(&self, other: &RangeEndWrapper<T>) -> Ordering {
124        self.end.cmp(&other.end)
125    }
126}
127
128impl<T> PartialOrd for RangeEndWrapper<T>
129where
130    T: PartialOrd,
131{
132    fn partial_cmp(&self, other: &RangeEndWrapper<T>) -> Option<Ordering> {
133        self.end.partial_cmp(&other.end)
134    }
135}
136
137// Avoid the need to tediously plumb through the layers of wrapper structs
138// when you're just trying to access members of the inner range itself.
139impl<T> Deref for RangeEndWrapper<T> {
140    type Target = Range<T>;
141
142    fn deref(&self) -> &Self::Target {
143        &self.range
144    }
145}
146
147//
148// RangeInclusive start wrapper
149//
150
151#[derive(Eq, Debug, Clone)]
152pub struct RangeInclusiveStartWrapper<T> {
153    pub end_wrapper: RangeInclusiveEndWrapper<T>,
154}
155
156impl<T> RangeInclusiveStartWrapper<T> {
157    pub fn new(range: RangeInclusive<T>) -> RangeInclusiveStartWrapper<T> {
158        RangeInclusiveStartWrapper {
159            end_wrapper: RangeInclusiveEndWrapper::new(range),
160        }
161    }
162}
163
164impl<T> PartialEq for RangeInclusiveStartWrapper<T>
165where
166    T: PartialEq,
167{
168    fn eq(&self, other: &RangeInclusiveStartWrapper<T>) -> bool {
169        self.start() == other.start()
170    }
171}
172
173impl<T> Ord for RangeInclusiveStartWrapper<T>
174where
175    T: Ord,
176{
177    fn cmp(&self, other: &RangeInclusiveStartWrapper<T>) -> Ordering {
178        self.start().cmp(other.start())
179    }
180}
181
182impl<T> PartialOrd for RangeInclusiveStartWrapper<T>
183where
184    T: PartialOrd,
185{
186    fn partial_cmp(&self, other: &RangeInclusiveStartWrapper<T>) -> Option<Ordering> {
187        self.start().partial_cmp(other.start())
188    }
189}
190
191impl<T> core::borrow::Borrow<RangeInclusiveEndWrapper<T>> for RangeInclusiveStartWrapper<T> {
192    fn borrow(&self) -> &RangeInclusiveEndWrapper<T> {
193        &self.end_wrapper
194    }
195}
196
197// Avoid the need to tediously plumb through the layers of wrapper structs
198// when you're just trying to access members of the inner range itself.
199impl<T> Deref for RangeInclusiveStartWrapper<T> {
200    type Target = RangeInclusiveEndWrapper<T>;
201
202    fn deref(&self) -> &Self::Target {
203        &self.end_wrapper
204    }
205}
206
207//
208// RangeInclusive end wrapper
209//
210
211#[derive(Eq, Debug, Clone)]
212pub struct RangeInclusiveEndWrapper<T> {
213    pub range: RangeInclusive<T>,
214}
215
216impl<T> RangeInclusiveEndWrapper<T> {
217    pub fn new(range: RangeInclusive<T>) -> RangeInclusiveEndWrapper<T> {
218        RangeInclusiveEndWrapper { range }
219    }
220}
221
222impl<T> PartialEq for RangeInclusiveEndWrapper<T>
223where
224    T: PartialEq,
225{
226    fn eq(&self, other: &RangeInclusiveEndWrapper<T>) -> bool {
227        self.end() == other.end()
228    }
229}
230
231impl<T> Ord for RangeInclusiveEndWrapper<T>
232where
233    T: Ord,
234{
235    fn cmp(&self, other: &RangeInclusiveEndWrapper<T>) -> Ordering {
236        self.end().cmp(other.end())
237    }
238}
239
240impl<T> PartialOrd for RangeInclusiveEndWrapper<T>
241where
242    T: PartialOrd,
243{
244    fn partial_cmp(&self, other: &RangeInclusiveEndWrapper<T>) -> Option<Ordering> {
245        self.end().partial_cmp(other.end())
246    }
247}
248
249// Avoid the need to tediously plumb through the layers of wrapper structs
250// when you're just trying to access members of the inner range itself.
251impl<T> Deref for RangeInclusiveEndWrapper<T> {
252    type Target = RangeInclusive<T>;
253
254    fn deref(&self) -> &Self::Target {
255        &self.range
256    }
257}