1use core::ops::{Range, RangeFrom, RangeFull, RangeInclusive, RangeTo, RangeToInclusive};
2
3use crate::{PointerLength, SliceLike};
4
5pub unsafe trait SlicePointerIndex<T>where
14 T: SliceLike + ?Sized,
15{
16 type Output: ?Sized;
18
19 fn get(self, slice: *const T) -> Option<*const Self::Output>;
21
22 fn get_mut(self, slice: *mut T) -> Option<*mut Self::Output>;
24
25 unsafe fn get_unchecked(self, slice: *const T) -> *const Self::Output;
32
33 unsafe fn get_unchecked_mut(self, slice: *mut T) -> *mut Self::Output;
40
41 #[track_caller]
44 fn index(self, slice: *const T) -> *const Self::Output;
45
46 #[track_caller]
49 fn index_mut(self, slice: *mut T) -> *mut Self::Output;
50}
51
52#[inline(never)]
53#[cold]
54#[track_caller]
55fn slice_start_index_len_fail(index: usize, len: usize) -> ! {
56 panic!("range start index {} out of range for slice pointer of length {}", index, len);
57}
58
59#[inline(never)]
60#[cold]
61#[track_caller]
62fn slice_end_index_len_fail(index: usize, len: usize) -> ! {
63 panic!("range end index {} out of range for slice pointer of length {}", index, len);
64}
65
66#[inline(never)]
67#[cold]
68#[track_caller]
69fn slice_index_order_fail(index: usize, end: usize) -> ! {
70 panic!("slice pointer index starts at {} but ends at {}", index, end);
71}
72
73#[inline(never)]
81#[cold]
82#[track_caller]
83fn slice_end_index_overflow_fail() -> ! {
84 panic!("attempted to index slice pointer up to maximum usize");
85}
86
87#[inline(never)]
88#[cold]
89#[track_caller]
90fn slice_index_overflow_fail(index: usize, len: usize) -> ! {
91 panic!("index {} out of range for slice pointer of length {}", index, len);
92}
93
94unsafe impl<T> SlicePointerIndex<T> for usize
95where
96 T: SliceLike + ?Sized,
97{
98 type Output = T::Element;
99
100 #[inline]
101 fn get(self, slice: *const T) -> Option<*const Self::Output> {
102 if self < PointerLength::len(slice) { unsafe { Some(self.get_unchecked(slice)) } } else { None }
104 }
105
106 #[inline]
107 fn get_mut(self, slice: *mut T) -> Option<*mut Self::Output> {
108 if self < PointerLength::len(slice) { unsafe { Some(self.get_unchecked_mut(slice)) } } else { None }
110 }
111
112 #[inline]
113 unsafe fn get_unchecked(self, slice: *const T) -> *const Self::Output {
114 (slice as *const T::Element).add(self)
119 }
120
121 #[inline]
122 unsafe fn get_unchecked_mut(self, slice: *mut T) -> *mut Self::Output {
123 (slice as *mut T::Element).add(self)
125 }
126
127 #[inline]
128 fn index(self, slice: *const T) -> *const Self::Output {
129 if self > PointerLength::len(slice) {
130 slice_index_overflow_fail(self, PointerLength::len(slice))
131 }
132 unsafe {
134 self.get_unchecked(slice)
135 }
136 }
137
138 #[inline]
139 fn index_mut(self, slice: *mut T) -> *mut Self::Output {
140 if self > PointerLength::len(slice) {
141 slice_index_overflow_fail(self, PointerLength::len(slice))
142 }
143 unsafe {
145 self.get_unchecked_mut(slice)
146 }
147 }
148}
149
150unsafe impl<T> SlicePointerIndex<T> for Range<usize>
151where
152 T: SliceLike + ?Sized,
153{
154 type Output = [T::Element];
155
156 #[inline]
157 fn get(self, slice: *const T) -> Option<*const Self::Output> {
158 if self.start > self.end || self.end > PointerLength::len(slice) {
159 None
160 } else {
161 unsafe { Some(self.get_unchecked(slice)) }
163 }
164 }
165
166 #[inline]
167 fn get_mut(self, slice: *mut T) -> Option<*mut Self::Output> {
168 if self.start > self.end || self.end > PointerLength::len(slice) {
169 None
170 } else {
171 unsafe { Some(self.get_unchecked_mut(slice)) }
173 }
174 }
175
176 #[inline]
177 unsafe fn get_unchecked(self, slice: *const T) -> *const Self::Output {
178 core::ptr::slice_from_raw_parts((slice as *const T::Element).add(self.start), self.end - self.start)
183 }
184
185 #[inline]
186 unsafe fn get_unchecked_mut(self, slice: *mut T) -> *mut Self::Output {
187 core::ptr::slice_from_raw_parts_mut((slice as *mut T::Element).add(self.start), self.end - self.start)
189 }
190
191 #[inline]
192 fn index(self, slice: *const T) -> *const Self::Output {
193 if self.start > self.end {
194 slice_index_order_fail(self.start, self.end);
195 } else if self.end > PointerLength::len(slice) {
196 slice_end_index_len_fail(self.end, PointerLength::len(slice));
197 }
198 unsafe { self.get_unchecked(slice) }
200 }
201
202 #[inline]
203 fn index_mut(self, slice: *mut T) -> *mut Self::Output {
204 if self.start > self.end {
205 slice_index_order_fail(self.start, self.end);
206 } else if self.end > PointerLength::len(slice) {
207 slice_end_index_len_fail(self.end, PointerLength::len(slice));
208 }
209 unsafe { self.get_unchecked_mut(slice) }
211 }
212}
213
214unsafe impl<T> SlicePointerIndex<T> for RangeTo<usize>
215where
216 T: SliceLike + ?Sized,
217{
218 type Output = [T::Element];
219
220 #[inline]
221 fn get(self, slice: *const T) -> Option<*const Self::Output> {
222 (0..self.end).get(slice)
223 }
224
225 #[inline]
226 fn get_mut(self, slice: *mut T) -> Option<*mut Self::Output> {
227 (0..self.end).get_mut(slice)
228 }
229
230 #[inline]
231 unsafe fn get_unchecked(self, slice: *const T) -> *const Self::Output {
232 (0..self.end).get_unchecked(slice)
234 }
235
236 #[inline]
237 unsafe fn get_unchecked_mut(self, slice: *mut T) -> *mut Self::Output {
238 (0..self.end).get_unchecked_mut(slice)
240 }
241
242 #[inline]
243 fn index(self, slice: *const T) -> *const Self::Output {
244 (0..self.end).index(slice)
245 }
246
247 #[inline]
248 fn index_mut(self, slice: *mut T) -> *mut Self::Output {
249 (0..self.end).index_mut(slice)
250 }
251}
252
253unsafe impl<T> SlicePointerIndex<T> for RangeFrom<usize>
254where
255 T: SliceLike + ?Sized,
256{
257 type Output = [T::Element];
258
259 #[inline]
260 fn get(self, slice: *const T) -> Option<*const Self::Output> {
261 (self.start..PointerLength::len(slice)).get(slice)
262 }
263
264 #[inline]
265 fn get_mut(self, slice: *mut T) -> Option<*mut Self::Output> {
266 (self.start..PointerLength::len(slice)).get_mut(slice)
267 }
268
269 #[inline]
270 unsafe fn get_unchecked(self, slice: *const T) -> *const Self::Output {
271 (self.start..PointerLength::len(slice)).get_unchecked(slice)
273 }
274
275 #[inline]
276 unsafe fn get_unchecked_mut(self, slice: *mut T) -> *mut Self::Output {
277 (self.start..PointerLength::len(slice)).get_unchecked_mut(slice)
279 }
280
281 #[inline]
282 fn index(self, slice: *const T) -> *const Self::Output {
283 if self.start > PointerLength::len(slice) {
284 slice_start_index_len_fail(self.start, PointerLength::len(slice));
285 }
286 unsafe { self.get_unchecked(slice) }
288 }
289
290 #[inline]
291 fn index_mut(self, slice: *mut T) -> *mut Self::Output {
292 if self.start > PointerLength::len(slice) {
293 slice_start_index_len_fail(self.start, PointerLength::len(slice));
294 }
295 unsafe { self.get_unchecked_mut(slice) }
297 }
298}
299
300unsafe impl<T> SlicePointerIndex<[T]> for RangeFull {
301 type Output = [T];
302
303 #[inline]
304 fn get(self, slice: *const [T]) -> Option<*const [T]> {
305 Some(slice)
306 }
307
308 #[inline]
309 fn get_mut(self, slice: *mut [T]) -> Option<*mut [T]> {
310 Some(slice)
311 }
312
313 #[inline]
314 unsafe fn get_unchecked(self, slice: *const [T]) -> *const [T] {
315 slice
316 }
317
318 #[inline]
319 unsafe fn get_unchecked_mut(self, slice: *mut [T]) -> *mut [T] {
320 slice
321 }
322
323 #[inline]
324 fn index(self, slice: *const [T]) -> *const [T] {
325 slice
326 }
327
328 #[inline]
329 fn index_mut(self, slice: *mut [T]) -> *mut [T] {
330 slice
331 }
332}
333
334unsafe impl<T, const N: usize> SlicePointerIndex<[T; N]> for RangeFull {
335 type Output = [T];
336
337 #[inline]
338 fn get(self, slice: *const [T; N]) -> Option<*const [T]> {
339 Some(slice)
340 }
341
342 #[inline]
343 fn get_mut(self, slice: *mut [T; N]) -> Option<*mut [T]> {
344 Some(slice)
345 }
346
347 #[inline]
348 unsafe fn get_unchecked(self, slice: *const [T; N]) -> *const [T] {
349 slice
350 }
351
352 #[inline]
353 unsafe fn get_unchecked_mut(self, slice: *mut [T; N]) -> *mut [T] {
354 slice
355 }
356
357 #[inline]
358 fn index(self, slice: *const [T; N]) -> *const [T] {
359 slice
360 }
361
362 #[inline]
363 fn index_mut(self, slice: *mut [T; N]) -> *mut [T] {
364 slice
365 }
366}
367
368#[inline]
371fn into_slice_range(range_inclusive: RangeInclusive<usize>) -> Range<usize> {
372 let exclusive_end = *range_inclusive.end() + 1;
376 let start = if range_inclusive.is_empty() { exclusive_end } else { *range_inclusive.start() };
377 start..exclusive_end
378}
379
380unsafe impl<T> SlicePointerIndex<T> for RangeInclusive<usize>
381where
382 T: SliceLike + ?Sized,
383{
384 type Output = [T::Element];
385
386 #[inline]
387 fn get(self, slice: *const T) -> Option<*const Self::Output> {
388 if *self.end() == usize::MAX { None } else { into_slice_range(self).get(slice) }
389 }
390
391 #[inline]
392 fn get_mut(self, slice: *mut T) -> Option<*mut Self::Output> {
393 if *self.end() == usize::MAX { None } else { into_slice_range(self).get_mut(slice) }
394 }
395
396 #[inline]
397 unsafe fn get_unchecked(self, slice: *const T) -> *const Self::Output {
398 into_slice_range(self).get_unchecked(slice)
400 }
401
402 #[inline]
403 unsafe fn get_unchecked_mut(self, slice: *mut T) -> *mut Self::Output {
404 into_slice_range(self).get_unchecked_mut(slice)
406 }
407
408 #[inline]
409 fn index(self, slice: *const T) -> *const Self::Output {
410 if *self.end() == usize::MAX {
411 slice_end_index_overflow_fail();
412 }
413 into_slice_range(self).index(slice)
414 }
415
416 #[inline]
417 fn index_mut(self, slice: *mut T) -> *mut Self::Output {
418 if *self.end() == usize::MAX {
419 slice_end_index_overflow_fail();
420 }
421 into_slice_range(self).index_mut(slice)
422 }
423}
424
425unsafe impl<T> SlicePointerIndex<T> for RangeToInclusive<usize>
426where
427 T: SliceLike + ?Sized,
428{
429 type Output = [T::Element];
430
431 #[inline]
432 fn get(self, slice: *const T) -> Option<*const Self::Output> {
433 (0..=self.end).get(slice)
434 }
435
436 #[inline]
437 fn get_mut(self, slice: *mut T) -> Option<*mut Self::Output> {
438 (0..=self.end).get_mut(slice)
439 }
440
441 #[inline]
442 unsafe fn get_unchecked(self, slice: *const T) -> *const Self::Output {
443 (0..=self.end).get_unchecked(slice)
445 }
446
447 #[inline]
448 unsafe fn get_unchecked_mut(self, slice: *mut T) -> *mut Self::Output {
449 (0..=self.end).get_unchecked_mut(slice)
451 }
452
453 #[inline]
454 fn index(self, slice: *const T) -> *const Self::Output {
455 (0..=self.end).index(slice)
456 }
457
458 #[inline]
459 fn index_mut(self, slice: *mut T) -> *mut Self::Output {
460 (0..=self.end).index_mut(slice)
461 }
462}