1use crate::{Idx, IndexSlice};
2
3mod private_slice_index {
4 pub trait Sealed {}
5}
6
7pub trait IdxSliceIndex<I: Idx, T>: private_slice_index::Sealed {
11 type Output: ?Sized;
12
13 fn get(self, slice: &IndexSlice<I, [T]>) -> Option<&Self::Output>;
14 fn get_mut(self, slice: &mut IndexSlice<I, [T]>) -> Option<&mut Self::Output>;
15
16 fn index(self, slice: &IndexSlice<I, [T]>) -> &Self::Output;
17 fn index_mut(self, slice: &mut IndexSlice<I, [T]>) -> &mut Self::Output;
18}
19
20impl<I: Idx> private_slice_index::Sealed for I {}
22
23impl<I: Idx, T> IdxSliceIndex<I, T> for I {
24 type Output = T;
25
26 #[inline]
27 fn get(self, slice: &IndexSlice<I, [T]>) -> Option<&Self::Output> {
28 slice.raw.get(self.index())
29 }
30 #[inline]
31 fn get_mut(self, slice: &mut IndexSlice<I, [T]>) -> Option<&mut Self::Output> {
32 slice.raw.get_mut(self.index())
33 }
34
35 #[inline]
36 fn index(self, slice: &IndexSlice<I, [T]>) -> &Self::Output {
37 &slice.raw[self.index()]
38 }
39
40 #[inline]
41 fn index_mut(self, slice: &mut IndexSlice<I, [T]>) -> &mut Self::Output {
42 &mut slice.raw[self.index()]
43 }
44}
45
46macro_rules! range_slice {
47 ($r:ty) => {
48 impl<I: Idx, T> IdxSliceIndex<I, T> for $r {
49 type Output = IndexSlice<I, [T]>;
50
51 #[inline]
52 fn get(self, slice: &IndexSlice<I, [T]>) -> Option<&Self::Output> {
53 slice.raw.get(self.into_range()).map(IndexSlice::new)
54 }
55 #[inline]
56 fn get_mut(self, slice: &mut IndexSlice<I, [T]>) -> Option<&mut Self::Output> {
57 slice
58 .raw
59 .get_mut(self.into_range())
60 .map(IndexSlice::new_mut)
61 }
62
63 #[inline]
64 fn index(self, slice: &IndexSlice<I, [T]>) -> &Self::Output {
65 IndexSlice::new(&slice.raw[self.into_range()])
66 }
67 #[inline]
68 fn index_mut(self, slice: &mut IndexSlice<I, [T]>) -> &mut Self::Output {
69 IndexSlice::new_mut(&mut slice.raw[self.into_range()])
70 }
71 }
72 };
73}
74
75impl<I: Idx> private_slice_index::Sealed for core::ops::Range<I> {}
76impl<I: Idx> private_slice_index::Sealed for core::ops::RangeFrom<I> {}
77impl<I: Idx> private_slice_index::Sealed for core::ops::RangeTo<I> {}
78impl<I: Idx> private_slice_index::Sealed for core::ops::RangeInclusive<I> {}
79impl<I: Idx> private_slice_index::Sealed for core::ops::RangeToInclusive<I> {}
80
81range_slice!(core::ops::Range<I>);
82range_slice!(core::ops::RangeFrom<I>);
83range_slice!(core::ops::RangeTo<I>);
84range_slice!(core::ops::RangeInclusive<I>);
85range_slice!(core::ops::RangeToInclusive<I>);
86impl private_slice_index::Sealed for core::ops::RangeFull {}
88impl<I: Idx, T> IdxSliceIndex<I, T> for core::ops::RangeFull {
89 type Output = IndexSlice<I, [T]>;
90
91 #[inline]
92 fn get(self, slice: &IndexSlice<I, [T]>) -> Option<&Self::Output> {
93 Some(slice)
94 }
95
96 #[inline]
97 fn get_mut(self, slice: &mut IndexSlice<I, [T]>) -> Option<&mut Self::Output> {
98 Some(slice)
99 }
100
101 #[inline]
102 fn index(self, slice: &IndexSlice<I, [T]>) -> &Self::Output {
103 slice
104 }
105
106 #[inline]
107 fn index_mut(self, slice: &mut IndexSlice<I, [T]>) -> &mut Self::Output {
108 slice
109 }
110}
111
112impl private_slice_index::Sealed for usize {}
113impl<I: Idx, T> IdxSliceIndex<I, T> for usize {
115 type Output = T;
116
117 #[inline]
118 fn get(self, slice: &IndexSlice<I, [T]>) -> Option<&Self::Output> {
119 slice.raw.get(self)
120 }
121 #[inline]
122 fn get_mut(self, slice: &mut IndexSlice<I, [T]>) -> Option<&mut Self::Output> {
123 slice.raw.get_mut(self)
124 }
125
126 #[inline]
127 fn index(self, slice: &IndexSlice<I, [T]>) -> &Self::Output {
128 &slice.raw[self]
129 }
130 #[inline]
131 fn index_mut(self, slice: &mut IndexSlice<I, [T]>) -> &mut Self::Output {
132 &mut slice.raw[self]
133 }
134}
135
136pub trait IdxRangeBounds<I>: private_range_bounds::Sealed
144where
145 I: Idx,
146{
147 type Range: core::ops::RangeBounds<usize>;
148 fn into_range(self) -> Self::Range;
149}
150
151mod private_range_bounds {
152 pub trait Sealed {}
153}
154
155impl<I: Idx> private_range_bounds::Sealed for core::ops::Range<I> {}
156impl<I: Idx> private_range_bounds::Sealed for core::ops::RangeFrom<I> {}
157impl<I: Idx> private_range_bounds::Sealed for core::ops::RangeTo<I> {}
158impl<I: Idx> private_range_bounds::Sealed for core::ops::RangeInclusive<I> {}
159impl<I: Idx> private_range_bounds::Sealed for core::ops::RangeToInclusive<I> {}
160impl private_range_bounds::Sealed for core::ops::RangeFull {}
161
162impl<I: Idx> IdxRangeBounds<I> for core::ops::Range<I> {
163 type Range = core::ops::Range<usize>;
164 #[inline]
165 fn into_range(self) -> Self::Range {
166 self.start.index()..self.end.index()
167 }
168}
169
170impl<I: Idx> IdxRangeBounds<I> for core::ops::RangeFrom<I> {
171 type Range = core::ops::RangeFrom<usize>;
172 #[inline]
173 fn into_range(self) -> Self::Range {
174 self.start.index()..
175 }
176}
177
178impl<I: Idx> IdxRangeBounds<I> for core::ops::RangeFull {
179 type Range = core::ops::RangeFull;
180 #[inline]
181 fn into_range(self) -> Self::Range {
182 self
183 }
184}
185
186impl<I: Idx> IdxRangeBounds<I> for core::ops::RangeTo<I> {
187 type Range = core::ops::RangeTo<usize>;
188 #[inline]
189 fn into_range(self) -> Self::Range {
190 ..self.end.index()
191 }
192}
193
194impl<I: Idx> IdxRangeBounds<I> for core::ops::RangeInclusive<I> {
195 type Range = core::ops::RangeInclusive<usize>;
196 #[inline]
197 fn into_range(self) -> Self::Range {
198 self.start().index()..=self.end().index()
199 }
200}
201
202impl<I: Idx> IdxRangeBounds<I> for core::ops::RangeToInclusive<I> {
203 type Range = core::ops::RangeToInclusive<usize>;
204 #[inline]
205 fn into_range(self) -> Self::Range {
206 ..=self.end.index()
207 }
208}
209
210impl<I, R, T> core::ops::Index<R> for IndexSlice<I, [T]>
211where
212 I: Idx,
213 R: IdxSliceIndex<I, T>,
214{
215 type Output = R::Output;
216 #[inline]
217 fn index(&self, index: R) -> &R::Output {
218 index.index(self)
219 }
220}
221
222impl<I, R, T> core::ops::IndexMut<R> for IndexSlice<I, [T]>
223where
224 I: Idx,
225 R: IdxSliceIndex<I, T>,
226{
227 #[inline]
228 fn index_mut(&mut self, index: R) -> &mut R::Output {
229 index.index_mut(self)
230 }
231}