1use {Id, IntegerHandle, FromUsize};
2use core::marker::PhantomData;
3use core::fmt;
4use core::ops;
5use core::cmp;
6use num_traits::Zero;
7
8pub struct IdRange<T, H = u32> {
9 pub start: H,
10 pub end: H,
11 _marker: PhantomData<T>,
12}
13
14impl<T, H: fmt::Display> fmt::Debug for IdRange<T, H> {
15 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
16 write!(f, "Id#[{}..{}]", self.start, self.end)
17 }
18}
19
20impl<T, H: Copy> Copy for IdRange<T, H> {}
21
22impl<T, H: Copy> Clone for IdRange<T, H> {
23 fn clone(&self) -> IdRange<T, H> {
24 *self
25 }
26}
27
28impl<T, H: PartialEq> PartialEq for IdRange<T, H> {
29 fn eq(&self, other: &IdRange<T, H>) -> bool {
30 self.start.eq(&other.start) && self.end.eq(&other.end)
31 }
32}
33
34impl<T, H: Copy + Eq> Eq for IdRange<T, H> {}
35
36impl<T, H: IntegerHandle> IdRange<T, H> {
37 #[inline]
38 pub fn new(range: ops::Range<H>) -> Self {
39 IdRange {
40 start: range.start,
41 end: range.end,
42 _marker: PhantomData,
43 }
44 }
45
46 #[inline]
47 pub fn len(self) -> H {
48 self.end - self.start
49 }
50
51 #[inline]
52 pub fn empty() -> Self {
53 IdRange::new(Zero::zero()..Zero::zero())
54 }
55
56 #[inline]
57 pub fn is_empty(self) -> bool
58 where
59 H: Zero,
60 {
61 self.len() == Zero::zero()
62 }
63
64 #[inline]
65 pub fn nth(self, i: H) -> Id<T, H> {
66 debug_assert!(i < self.len());
67 return Id {
68 handle: self.start + i,
69 _marker: PhantomData,
70 };
71 }
72
73 #[inline]
74 pub fn start(&self) -> Id<T, H> {
75 Id::new(self.start)
76 }
77
78 #[inline]
79 pub fn usize_start(&self) -> usize {
80 self.start.to_usize()
81 }
82
83 #[inline]
84 pub fn usize_end(&self) -> usize {
85 self.end.to_usize()
86 }
87
88 #[inline]
89 pub fn usize_range(&self) -> ops::Range<usize> {
90 self.usize_start()..self.usize_end()
91 }
92
93 #[inline]
94 pub fn untyped(&self) -> ops::Range<H> {
95 self.start..self.end
96 }
97
98 #[inline]
99 pub fn shrinked_left(self) -> Option<IdRange<T, H>> {
101 if self.is_empty() {
102 return None;
103 }
104 return Some(IdRange::new((self.start + H::one())..self.end));
105 }
106
107 #[inline]
108 pub fn shrinked_right(self) -> Option<IdRange<T, H>> {
110 if self.is_empty() {
111 return None;
112 }
113 return Some(IdRange::new(
114 self.start..FromUsize::from_usize(self.end.to_usize() - 1),
115 ));
116 }
117
118 #[inline]
119 pub fn intersection(&self, other: Self) -> Self {
120 let start = cmp::max(self.start, other.start);
121 let end = cmp::min(self.end, other.end);
122 if end < start {
123 return IdRange::empty();
124 }
125 return IdRange::new(start..end);
126 }
127}
128
129impl<T, H: IntegerHandle> Iterator for IdRange<T, H> {
130 type Item = Id<T, H>;
131 fn next(&mut self) -> Option<Id<T, H>> {
132 if let Some(new_range) = self.shrinked_left() {
133 let first = self.start();
134 *self = new_range;
135 return Some(first);
136 }
137 return None;
138 }
139
140 fn size_hint(&self) -> (usize, Option<usize>) {
141 return (self.len().to_usize(), Some(self.len().to_usize()));
142 }
143
144 fn count(self) -> usize {
145 self.len().to_usize()
146 }
147}
148
149pub struct ReverseIdRange<T, H> {
150 range: IdRange<T, H>,
151}
152
153impl<T, H: fmt::Display> fmt::Debug for ReverseIdRange<T, H> {
154 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
155 write!(f, "ReverseId#[{}..{}]", self.range.start, self.range.end)
156 }
157}
158
159impl<T, H: Copy> Copy for ReverseIdRange<T, H> {}
160
161impl<T, H: Copy> Clone for ReverseIdRange<T, H> {
162 fn clone(&self) -> ReverseIdRange<T, H> {
163 *self
164 }
165}
166
167impl<T, H: PartialEq> PartialEq for ReverseIdRange<T, H> {
168 fn eq(&self, other: &ReverseIdRange<T, H>) -> bool {
169 self.range.eq(&other.range)
170 }
171}
172
173impl<T, H: Copy + Eq> Eq for ReverseIdRange<T, H> {}
174
175impl<T, H: IntegerHandle> ReverseIdRange<T, H> {
176 pub fn new(range: IdRange<T, H>) -> ReverseIdRange<T, H> {
177 ReverseIdRange { range: range }
178 }
179
180 pub fn len(&self) -> H {
181 self.range.len()
182 }
183
184 pub fn is_empty(self) -> bool {
185 self.len() == Zero::zero()
186 }
187
188 pub fn nth(self, i: H) -> Id<T, H> {
189 self.range.nth(i)
190 }
191}
192
193impl<T, H: IntegerHandle> Iterator for ReverseIdRange<T, H> {
194 type Item = Id<T, H>;
195 fn next(&mut self) -> Option<Id<T, H>> {
196 if let Some(new_range) = self.range.shrinked_right() {
197 self.range = new_range;
198 return Some(Id::new(self.range.end));
199 }
200 return None;
201 }
202
203 fn size_hint(&self) -> (usize, Option<usize>) {
204 self.range.size_hint()
205 }
206
207 fn count(self) -> usize {
208 self.range.count()
209 }
210}