1#![no_std]
2#[cfg(feature = "alloc")]
24extern crate alloc;
25
26use core::ops::{
27 Bound, Index, IndexMut, Range, RangeBounds, RangeFrom, RangeFull,
28 RangeInclusive, RangeTo, RangeToInclusive,
29};
30
31#[derive(Clone, Copy, Default, PartialEq, Eq, Hash)]
37pub struct CopyRange<Idx> {
38 pub start: Idx,
39 pub end: Idx,
40}
41
42impl<Idx: core::fmt::Debug> core::fmt::Debug for CopyRange<Idx> {
43 fn fmt(&self, fmt: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
44 self.start.fmt(fmt)?;
45 write!(fmt, "..")?;
46 self.end.fmt(fmt)?;
47 Ok(())
48 }
49}
50
51impl<Idx> CopyRange<Idx> {
52 pub fn contains<U>(&self, item: &U) -> bool
56 where
57 Idx: PartialOrd<U>,
58 U: ?Sized + PartialOrd<Idx>,
59 {
60 <Self as RangeBounds<Idx>>::contains(self, item)
61 }
62
63 pub fn from_std(range: Range<Idx>) -> Self {
65 range.into()
66 }
67
68 pub fn into_std(self) -> Range<Idx> {
70 self.into()
71 }
72
73 pub fn is_empty(&self) -> bool
77 where
78 Idx: PartialOrd,
79 {
80 self.start >= self.end
81 }
82
83 pub fn len(&self) -> usize
85 where
86 core::ops::Range<Idx>: ExactSizeIterator,
87 Self: Copy,
88 {
89 self.into_std().len()
90 }
91}
92
93impl<Idx> From<Range<Idx>> for CopyRange<Idx> {
95 fn from(Range { start, end }: Range<Idx>) -> Self {
96 Self { start, end }
97 }
98}
99
100impl<Idx> From<CopyRange<Idx>> for Range<Idx> {
102 fn from(value: CopyRange<Idx>) -> Self {
103 value.start..value.end
104 }
105}
106
107#[derive(Clone, Copy, PartialEq, Eq, Hash)]
112pub struct CopyRangeFrom<Idx> {
113 pub start: Idx,
114}
115
116impl<Idx: core::fmt::Debug> core::fmt::Debug for CopyRangeFrom<Idx> {
117 fn fmt(&self, fmt: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
118 self.start.fmt(fmt)?;
119 write!(fmt, "..")?;
120 Ok(())
121 }
122}
123
124impl<Idx> CopyRangeFrom<Idx> {
125 pub fn contains<U>(&self, item: &U) -> bool
129 where
130 Idx: PartialOrd<U>,
131 U: ?Sized + PartialOrd<Idx>,
132 {
133 <Self as RangeBounds<Idx>>::contains(self, item)
134 }
135
136 pub fn from_std(range: RangeFrom<Idx>) -> Self {
138 range.into()
139 }
140
141 pub fn into_std(self) -> RangeFrom<Idx> {
143 self.into()
144 }
145}
146
147impl<Idx> From<RangeFrom<Idx>> for CopyRangeFrom<Idx> {
149 fn from(RangeFrom { start }: RangeFrom<Idx>) -> Self {
150 Self { start }
151 }
152}
153
154impl<Idx> From<CopyRangeFrom<Idx>> for RangeFrom<Idx> {
156 fn from(value: CopyRangeFrom<Idx>) -> Self {
157 value.start..
158 }
159}
160
161#[derive(Clone, Copy, PartialEq, Eq, Hash)]
167pub struct CopyRangeInclusive<Idx> {
168 pub start: Idx,
169 pub end: Idx,
170}
171
172impl<Idx: core::fmt::Debug> core::fmt::Debug for CopyRangeInclusive<Idx> {
173 fn fmt(&self, fmt: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
174 self.start.fmt(fmt)?;
175 write!(fmt, "..=")?;
176 self.end.fmt(fmt)?;
177 Ok(())
178 }
179}
180
181impl<Idx> CopyRangeInclusive<Idx> {
182 pub fn contains<U>(&self, item: &U) -> bool
186 where
187 Idx: PartialOrd<U>,
188 U: ?Sized + PartialOrd<Idx>,
189 {
190 <Self as RangeBounds<Idx>>::contains(self, item)
191 }
192
193 pub fn is_empty(&self) -> bool
197 where
198 Idx: PartialOrd,
199 {
200 !(self.start <= self.end)
201 }
202
203 pub fn from_std(range: RangeInclusive<Idx>) -> Self {
208 range.into()
209 }
210
211 pub fn into_std(self) -> RangeInclusive<Idx> {
213 self.into()
214 }
215
216 pub fn len(&self) -> usize
218 where
219 core::ops::RangeInclusive<Idx>: ExactSizeIterator,
220 Self: Copy,
221 {
222 self.into_std().len()
223 }
224}
225
226impl<Idx> From<RangeInclusive<Idx>> for CopyRangeInclusive<Idx> {
231 fn from(range: RangeInclusive<Idx>) -> Self {
232 let (start, end) = range.into_inner();
233 Self { start, end }
234 }
235}
236
237impl<Idx> From<CopyRangeInclusive<Idx>> for RangeInclusive<Idx> {
239 fn from(value: CopyRangeInclusive<Idx>) -> Self {
240 value.start..=value.end
241 }
242}
243
244impl<Idx> RangeBounds<Idx> for CopyRange<Idx> {
245 fn start_bound(&self) -> Bound<&Idx> {
246 Bound::Included(&self.start)
247 }
248
249 fn end_bound(&self) -> Bound<&Idx> {
250 Bound::Excluded(&self.end)
251 }
252}
253
254impl<Idx> RangeBounds<Idx> for CopyRange<&Idx> {
255 fn start_bound(&self) -> Bound<&Idx> {
256 Bound::Included(self.start)
257 }
258
259 fn end_bound(&self) -> Bound<&Idx> {
260 Bound::Excluded(self.end)
261 }
262}
263
264impl<Idx> IntoIterator for CopyRange<Idx>
265where
266 Range<Idx>: Iterator<Item = Idx>,
267{
268 type Item = Idx;
269
270 type IntoIter = Range<Idx>;
271
272 fn into_iter(self) -> Self::IntoIter {
273 self.start..self.end
274 }
275}
276
277impl<Idx> RangeBounds<Idx> for CopyRangeFrom<Idx> {
278 fn start_bound(&self) -> Bound<&Idx> {
279 Bound::Included(&self.start)
280 }
281
282 fn end_bound(&self) -> Bound<&Idx> {
283 Bound::Unbounded
284 }
285}
286
287impl<Idx> RangeBounds<Idx> for CopyRangeFrom<&Idx> {
288 fn start_bound(&self) -> Bound<&Idx> {
289 Bound::Included(self.start)
290 }
291
292 fn end_bound(&self) -> Bound<&Idx> {
293 Bound::Unbounded
294 }
295}
296
297impl<Idx> IntoIterator for CopyRangeFrom<Idx>
298where
299 RangeFrom<Idx>: Iterator<Item = Idx>,
300{
301 type Item = Idx;
302
303 type IntoIter = RangeFrom<Idx>;
304
305 fn into_iter(self) -> Self::IntoIter {
306 self.start..
307 }
308}
309
310impl<Idx> RangeBounds<Idx> for CopyRangeInclusive<Idx> {
311 fn start_bound(&self) -> Bound<&Idx> {
312 Bound::Included(&self.start)
313 }
314
315 fn end_bound(&self) -> Bound<&Idx> {
316 Bound::Included(&self.end)
317 }
318}
319
320impl<Idx> RangeBounds<Idx> for CopyRangeInclusive<&Idx> {
321 fn start_bound(&self) -> Bound<&Idx> {
322 Bound::Included(self.start)
323 }
324
325 fn end_bound(&self) -> Bound<&Idx> {
326 Bound::Included(self.end)
327 }
328}
329
330impl<Idx> IntoIterator for CopyRangeInclusive<Idx>
331where
332 RangeInclusive<Idx>: Iterator<Item = Idx>,
333{
334 type Item = Idx;
335
336 type IntoIter = RangeInclusive<Idx>;
337
338 fn into_iter(self) -> Self::IntoIter {
339 self.start..=self.end
340 }
341}
342
343pub type CopyRangeFull = RangeFull;
345pub type CopyRangeTo<Idx> = RangeTo<Idx>;
348pub type CopyRangeToInclusive<Idx> = RangeToInclusive<Idx>;
351
352macro_rules! impl_index {
353 ([$($generics:tt)*], $ty:ty) => {
354 impl<$($generics)*> Index<CopyRange<usize>> for $ty
355 where
356 $ty: Index<Range<usize>>,
357 {
358 type Output = <$ty as Index<Range<usize>>>::Output;
359
360 fn index(&self, index: CopyRange<usize>) -> &Self::Output {
361 self.index(index.into_std())
362 }
363 }
364 impl<$($generics)*> IndexMut<CopyRange<usize>> for $ty
365 where
366 $ty: IndexMut<Range<usize>>,
367 {
368 fn index_mut(&mut self, index: CopyRange<usize>) -> &mut Self::Output {
369 self.index_mut(index.into_std())
370 }
371 }
372 impl<$($generics)*> Index<CopyRangeFrom<usize>> for $ty
373 where
374 $ty: Index<RangeFrom<usize>>,
375 {
376 type Output = <$ty as Index<RangeFrom<usize>>>::Output;
377
378 fn index(&self, index: CopyRangeFrom<usize>) -> &Self::Output {
379 self.index(index.into_std())
380 }
381 }
382 impl<$($generics)*> IndexMut<CopyRangeFrom<usize>> for $ty
383 where
384 $ty: IndexMut<RangeFrom<usize>>,
385 {
386 fn index_mut(&mut self, index: CopyRangeFrom<usize>) -> &mut Self::Output {
387 self.index_mut(index.into_std())
388 }
389 }
390 impl<$($generics)*> Index<CopyRangeInclusive<usize>> for $ty
391 where
392 $ty: Index<RangeInclusive<usize>>,
393 {
394 type Output = <$ty as Index<RangeInclusive<usize>>>::Output;
395
396 fn index(&self, index: CopyRangeInclusive<usize>) -> &Self::Output {
397 self.index(index.into_std())
398 }
399 }
400 impl<$($generics)*> IndexMut<CopyRangeInclusive<usize>> for $ty
401 where
402 $ty: IndexMut<RangeInclusive<usize>>,
403 {
404 fn index_mut(&mut self, index: CopyRangeInclusive<usize>) -> &mut Self::Output {
405 self.index_mut(index.into_std())
406 }
407 }
408 };
409}
410
411impl_index!([T], [T]);
412impl_index!([], str);
413#[cfg(feature = "alloc")]
414impl_index!([T], ::alloc::vec::Vec<T>);
415#[cfg(feature = "alloc")]
416impl_index!([], ::alloc::string::String);