1#[cfg(not(bootstrap))]
4use crate::intrinsics::slice_get_unchecked;
5use crate::panic::const_panic;
6use crate::ub_checks::assert_unsafe_precondition;
7use crate::{ops, range};
8
9#[stable(feature = "rust1", since = "1.0.0")]
10impl<T, I> ops::Index<I> for [T]
11where
12 I: SliceIndex<[T]>,
13{
14 type Output = I::Output;
15
16 #[inline(always)]
17 fn index(&self, index: I) -> &I::Output {
18 index.index(self)
19 }
20}
21
22#[stable(feature = "rust1", since = "1.0.0")]
23impl<T, I> ops::IndexMut<I> for [T]
24where
25 I: SliceIndex<[T]>,
26{
27 #[inline(always)]
28 fn index_mut(&mut self, index: I) -> &mut I::Output {
29 index.index_mut(self)
30 }
31}
32
33#[cfg_attr(not(feature = "panic_immediate_abort"), inline(never), cold)]
34#[cfg_attr(feature = "panic_immediate_abort", inline)]
35#[track_caller]
36const fn slice_start_index_len_fail(index: usize, len: usize) -> ! {
37 const_panic!(
38 "slice start index is out of range for slice",
39 "range start index {index} out of range for slice of length {len}",
40 index: usize,
41 len: usize,
42 )
43}
44
45#[cfg_attr(not(feature = "panic_immediate_abort"), inline(never), cold)]
46#[cfg_attr(feature = "panic_immediate_abort", inline)]
47#[track_caller]
48const fn slice_end_index_len_fail(index: usize, len: usize) -> ! {
49 const_panic!(
50 "slice end index is out of range for slice",
51 "range end index {index} out of range for slice of length {len}",
52 index: usize,
53 len: usize,
54 )
55}
56
57#[cfg_attr(not(feature = "panic_immediate_abort"), inline(never), cold)]
58#[cfg_attr(feature = "panic_immediate_abort", inline)]
59#[track_caller]
60const fn slice_index_order_fail(index: usize, end: usize) -> ! {
61 const_panic!(
62 "slice index start is larger than end",
63 "slice index starts at {index} but ends at {end}",
64 index: usize,
65 end: usize,
66 )
67}
68
69#[cfg_attr(not(feature = "panic_immediate_abort"), inline(never), cold)]
70#[cfg_attr(feature = "panic_immediate_abort", inline)]
71#[track_caller]
72const fn slice_start_index_overflow_fail() -> ! {
73 panic!("attempted to index slice from after maximum usize");
74}
75
76#[cfg_attr(not(feature = "panic_immediate_abort"), inline(never), cold)]
77#[cfg_attr(feature = "panic_immediate_abort", inline)]
78#[track_caller]
79const fn slice_end_index_overflow_fail() -> ! {
80 panic!("attempted to index slice up to maximum usize");
81}
82
83#[cfg(bootstrap)]
89#[inline(always)]
90const unsafe fn get_noubcheck<T>(ptr: *const [T], index: usize) -> *const T {
91 let ptr = ptr as *const T;
92 unsafe { crate::intrinsics::offset(ptr, index) }
94}
95
96#[cfg(bootstrap)]
97#[inline(always)]
98const unsafe fn get_mut_noubcheck<T>(ptr: *mut [T], index: usize) -> *mut T {
99 let ptr = ptr as *mut T;
100 unsafe { crate::intrinsics::offset(ptr, index) }
102}
103
104#[inline(always)]
105const unsafe fn get_offset_len_noubcheck<T>(
106 ptr: *const [T],
107 offset: usize,
108 len: usize,
109) -> *const [T] {
110 let ptr = ptr as *const T;
111 let ptr = unsafe { crate::intrinsics::offset(ptr, offset) };
113 crate::intrinsics::aggregate_raw_ptr(ptr, len)
114}
115
116#[inline(always)]
117const unsafe fn get_offset_len_mut_noubcheck<T>(
118 ptr: *mut [T],
119 offset: usize,
120 len: usize,
121) -> *mut [T] {
122 let ptr = ptr as *mut T;
123 let ptr = unsafe { crate::intrinsics::offset(ptr, offset) };
125 crate::intrinsics::aggregate_raw_ptr(ptr, len)
126}
127
128mod private_slice_index {
129 use super::{ops, range};
130
131 #[stable(feature = "slice_get_slice", since = "1.28.0")]
132 pub trait Sealed {}
133
134 #[stable(feature = "slice_get_slice", since = "1.28.0")]
135 impl Sealed for usize {}
136 #[stable(feature = "slice_get_slice", since = "1.28.0")]
137 impl Sealed for ops::Range<usize> {}
138 #[stable(feature = "slice_get_slice", since = "1.28.0")]
139 impl Sealed for ops::RangeTo<usize> {}
140 #[stable(feature = "slice_get_slice", since = "1.28.0")]
141 impl Sealed for ops::RangeFrom<usize> {}
142 #[stable(feature = "slice_get_slice", since = "1.28.0")]
143 impl Sealed for ops::RangeFull {}
144 #[stable(feature = "slice_get_slice", since = "1.28.0")]
145 impl Sealed for ops::RangeInclusive<usize> {}
146 #[stable(feature = "slice_get_slice", since = "1.28.0")]
147 impl Sealed for ops::RangeToInclusive<usize> {}
148 #[stable(feature = "slice_index_with_ops_bound_pair", since = "1.53.0")]
149 impl Sealed for (ops::Bound<usize>, ops::Bound<usize>) {}
150
151 #[unstable(feature = "new_range_api", issue = "125687")]
152 impl Sealed for range::Range<usize> {}
153 #[unstable(feature = "new_range_api", issue = "125687")]
154 impl Sealed for range::RangeInclusive<usize> {}
155 #[unstable(feature = "new_range_api", issue = "125687")]
156 impl Sealed for range::RangeFrom<usize> {}
157
158 impl Sealed for ops::IndexRange {}
159}
160
161#[stable(feature = "slice_get_slice", since = "1.28.0")]
166#[rustc_diagnostic_item = "SliceIndex"]
167#[rustc_on_unimplemented(
168 on(T = "str", label = "string indices are ranges of `usize`",),
169 on(
170 all(any(T = "str", T = "&str", T = "alloc::string::String"), Self = "{integer}"),
171 note = "you can use `.chars().nth()` or `.bytes().nth()`\n\
172 for more information, see chapter 8 in The Book: \
173 <https://doc.rust-lang.org/book/ch08-02-strings.html#indexing-into-strings>"
174 ),
175 message = "the type `{T}` cannot be indexed by `{Self}`",
176 label = "slice indices are of type `usize` or ranges of `usize`"
177)]
178pub unsafe trait SliceIndex<T: ?Sized>: private_slice_index::Sealed {
179 #[stable(feature = "slice_get_slice", since = "1.28.0")]
181 type Output: ?Sized;
182
183 #[unstable(feature = "slice_index_methods", issue = "none")]
186 fn get(self, slice: &T) -> Option<&Self::Output>;
187
188 #[unstable(feature = "slice_index_methods", issue = "none")]
191 fn get_mut(self, slice: &mut T) -> Option<&mut Self::Output>;
192
193 #[unstable(feature = "slice_index_methods", issue = "none")]
201 unsafe fn get_unchecked(self, slice: *const T) -> *const Self::Output;
202
203 #[unstable(feature = "slice_index_methods", issue = "none")]
211 unsafe fn get_unchecked_mut(self, slice: *mut T) -> *mut Self::Output;
212
213 #[unstable(feature = "slice_index_methods", issue = "none")]
216 #[track_caller]
217 fn index(self, slice: &T) -> &Self::Output;
218
219 #[unstable(feature = "slice_index_methods", issue = "none")]
222 #[track_caller]
223 fn index_mut(self, slice: &mut T) -> &mut Self::Output;
224}
225
226#[stable(feature = "slice_get_slice_impls", since = "1.15.0")]
228unsafe impl<T> SliceIndex<[T]> for usize {
229 type Output = T;
230
231 #[inline]
232 fn get(self, slice: &[T]) -> Option<&T> {
233 if self < slice.len() {
234 #[cfg(bootstrap)]
235 unsafe {
237 Some(&*get_noubcheck(slice, self))
238 }
239 #[cfg(not(bootstrap))]
240 unsafe {
242 Some(slice_get_unchecked(slice, self))
243 }
244 } else {
245 None
246 }
247 }
248
249 #[inline]
250 fn get_mut(self, slice: &mut [T]) -> Option<&mut T> {
251 if self < slice.len() {
252 #[cfg(bootstrap)]
253 unsafe {
255 Some(&mut *get_mut_noubcheck(slice, self))
256 }
257 #[cfg(not(bootstrap))]
258 unsafe {
260 Some(slice_get_unchecked(slice, self))
261 }
262 } else {
263 None
264 }
265 }
266
267 #[inline]
268 #[track_caller]
269 unsafe fn get_unchecked(self, slice: *const [T]) -> *const T {
270 assert_unsafe_precondition!(
271 check_language_ub,
272 "slice::get_unchecked requires that the index is within the slice",
273 (this: usize = self, len: usize = slice.len()) => this < len
274 );
275 unsafe {
280 crate::intrinsics::assume(self < slice.len());
283 #[cfg(bootstrap)]
284 {
285 get_noubcheck(slice, self)
286 }
287 #[cfg(not(bootstrap))]
288 {
289 slice_get_unchecked(slice, self)
290 }
291 }
292 }
293
294 #[inline]
295 #[track_caller]
296 unsafe fn get_unchecked_mut(self, slice: *mut [T]) -> *mut T {
297 assert_unsafe_precondition!(
298 check_library_ub,
299 "slice::get_unchecked_mut requires that the index is within the slice",
300 (this: usize = self, len: usize = slice.len()) => this < len
301 );
302 unsafe {
304 #[cfg(bootstrap)]
305 {
306 get_mut_noubcheck(slice, self)
307 }
308 #[cfg(not(bootstrap))]
309 {
310 slice_get_unchecked(slice, self)
311 }
312 }
313 }
314
315 #[inline]
316 fn index(self, slice: &[T]) -> &T {
317 &(*slice)[self]
319 }
320
321 #[inline]
322 fn index_mut(self, slice: &mut [T]) -> &mut T {
323 &mut (*slice)[self]
325 }
326}
327
328unsafe impl<T> SliceIndex<[T]> for ops::IndexRange {
331 type Output = [T];
332
333 #[inline]
334 fn get(self, slice: &[T]) -> Option<&[T]> {
335 if self.end() <= slice.len() {
336 unsafe { Some(&*get_offset_len_noubcheck(slice, self.start(), self.len())) }
338 } else {
339 None
340 }
341 }
342
343 #[inline]
344 fn get_mut(self, slice: &mut [T]) -> Option<&mut [T]> {
345 if self.end() <= slice.len() {
346 unsafe { Some(&mut *get_offset_len_mut_noubcheck(slice, self.start(), self.len())) }
348 } else {
349 None
350 }
351 }
352
353 #[inline]
354 #[track_caller]
355 unsafe fn get_unchecked(self, slice: *const [T]) -> *const [T] {
356 assert_unsafe_precondition!(
357 check_library_ub,
358 "slice::get_unchecked requires that the index is within the slice",
359 (end: usize = self.end(), len: usize = slice.len()) => end <= len
360 );
361 unsafe { get_offset_len_noubcheck(slice, self.start(), self.len()) }
366 }
367
368 #[inline]
369 #[track_caller]
370 unsafe fn get_unchecked_mut(self, slice: *mut [T]) -> *mut [T] {
371 assert_unsafe_precondition!(
372 check_library_ub,
373 "slice::get_unchecked_mut requires that the index is within the slice",
374 (end: usize = self.end(), len: usize = slice.len()) => end <= len
375 );
376
377 unsafe { get_offset_len_mut_noubcheck(slice, self.start(), self.len()) }
379 }
380
381 #[inline]
382 fn index(self, slice: &[T]) -> &[T] {
383 if self.end() <= slice.len() {
384 unsafe { &*get_offset_len_noubcheck(slice, self.start(), self.len()) }
386 } else {
387 slice_end_index_len_fail(self.end(), slice.len())
388 }
389 }
390
391 #[inline]
392 fn index_mut(self, slice: &mut [T]) -> &mut [T] {
393 if self.end() <= slice.len() {
394 unsafe { &mut *get_offset_len_mut_noubcheck(slice, self.start(), self.len()) }
396 } else {
397 slice_end_index_len_fail(self.end(), slice.len())
398 }
399 }
400}
401
402#[stable(feature = "slice_get_slice_impls", since = "1.15.0")]
406unsafe impl<T> SliceIndex<[T]> for ops::Range<usize> {
407 type Output = [T];
408
409 #[inline]
410 fn get(self, slice: &[T]) -> Option<&[T]> {
411 if let Some(new_len) = usize::checked_sub(self.end, self.start)
413 && self.end <= slice.len()
414 {
415 unsafe { Some(&*get_offset_len_noubcheck(slice, self.start, new_len)) }
417 } else {
418 None
419 }
420 }
421
422 #[inline]
423 fn get_mut(self, slice: &mut [T]) -> Option<&mut [T]> {
424 if let Some(new_len) = usize::checked_sub(self.end, self.start)
425 && self.end <= slice.len()
426 {
427 unsafe { Some(&mut *get_offset_len_mut_noubcheck(slice, self.start, new_len)) }
429 } else {
430 None
431 }
432 }
433
434 #[inline]
435 #[track_caller]
436 unsafe fn get_unchecked(self, slice: *const [T]) -> *const [T] {
437 assert_unsafe_precondition!(
438 check_library_ub,
439 "slice::get_unchecked requires that the range is within the slice",
440 (
441 start: usize = self.start,
442 end: usize = self.end,
443 len: usize = slice.len()
444 ) => end >= start && end <= len
445 );
446
447 unsafe {
452 let new_len = crate::intrinsics::unchecked_sub(self.end, self.start);
455 get_offset_len_noubcheck(slice, self.start, new_len)
456 }
457 }
458
459 #[inline]
460 #[track_caller]
461 unsafe fn get_unchecked_mut(self, slice: *mut [T]) -> *mut [T] {
462 assert_unsafe_precondition!(
463 check_library_ub,
464 "slice::get_unchecked_mut requires that the range is within the slice",
465 (
466 start: usize = self.start,
467 end: usize = self.end,
468 len: usize = slice.len()
469 ) => end >= start && end <= len
470 );
471 unsafe {
473 let new_len = crate::intrinsics::unchecked_sub(self.end, self.start);
474 get_offset_len_mut_noubcheck(slice, self.start, new_len)
475 }
476 }
477
478 #[inline(always)]
479 fn index(self, slice: &[T]) -> &[T] {
480 let Some(new_len) = usize::checked_sub(self.end, self.start) else {
482 slice_index_order_fail(self.start, self.end)
483 };
484 if self.end > slice.len() {
485 slice_end_index_len_fail(self.end, slice.len());
486 }
487 unsafe { &*get_offset_len_noubcheck(slice, self.start, new_len) }
489 }
490
491 #[inline]
492 fn index_mut(self, slice: &mut [T]) -> &mut [T] {
493 let Some(new_len) = usize::checked_sub(self.end, self.start) else {
494 slice_index_order_fail(self.start, self.end)
495 };
496 if self.end > slice.len() {
497 slice_end_index_len_fail(self.end, slice.len());
498 }
499 unsafe { &mut *get_offset_len_mut_noubcheck(slice, self.start, new_len) }
501 }
502}
503
504#[unstable(feature = "new_range_api", issue = "125687")]
505unsafe impl<T> SliceIndex<[T]> for range::Range<usize> {
506 type Output = [T];
507
508 #[inline]
509 fn get(self, slice: &[T]) -> Option<&[T]> {
510 ops::Range::from(self).get(slice)
511 }
512
513 #[inline]
514 fn get_mut(self, slice: &mut [T]) -> Option<&mut [T]> {
515 ops::Range::from(self).get_mut(slice)
516 }
517
518 #[inline]
519 unsafe fn get_unchecked(self, slice: *const [T]) -> *const [T] {
520 unsafe { ops::Range::from(self).get_unchecked(slice) }
522 }
523
524 #[inline]
525 unsafe fn get_unchecked_mut(self, slice: *mut [T]) -> *mut [T] {
526 unsafe { ops::Range::from(self).get_unchecked_mut(slice) }
528 }
529
530 #[inline(always)]
531 fn index(self, slice: &[T]) -> &[T] {
532 ops::Range::from(self).index(slice)
533 }
534
535 #[inline]
536 fn index_mut(self, slice: &mut [T]) -> &mut [T] {
537 ops::Range::from(self).index_mut(slice)
538 }
539}
540
541#[stable(feature = "slice_get_slice_impls", since = "1.15.0")]
543unsafe impl<T> SliceIndex<[T]> for ops::RangeTo<usize> {
544 type Output = [T];
545
546 #[inline]
547 fn get(self, slice: &[T]) -> Option<&[T]> {
548 (0..self.end).get(slice)
549 }
550
551 #[inline]
552 fn get_mut(self, slice: &mut [T]) -> Option<&mut [T]> {
553 (0..self.end).get_mut(slice)
554 }
555
556 #[inline]
557 unsafe fn get_unchecked(self, slice: *const [T]) -> *const [T] {
558 unsafe { (0..self.end).get_unchecked(slice) }
560 }
561
562 #[inline]
563 unsafe fn get_unchecked_mut(self, slice: *mut [T]) -> *mut [T] {
564 unsafe { (0..self.end).get_unchecked_mut(slice) }
566 }
567
568 #[inline(always)]
569 fn index(self, slice: &[T]) -> &[T] {
570 (0..self.end).index(slice)
571 }
572
573 #[inline]
574 fn index_mut(self, slice: &mut [T]) -> &mut [T] {
575 (0..self.end).index_mut(slice)
576 }
577}
578
579#[stable(feature = "slice_get_slice_impls", since = "1.15.0")]
581unsafe impl<T> SliceIndex<[T]> for ops::RangeFrom<usize> {
582 type Output = [T];
583
584 #[inline]
585 fn get(self, slice: &[T]) -> Option<&[T]> {
586 (self.start..slice.len()).get(slice)
587 }
588
589 #[inline]
590 fn get_mut(self, slice: &mut [T]) -> Option<&mut [T]> {
591 (self.start..slice.len()).get_mut(slice)
592 }
593
594 #[inline]
595 unsafe fn get_unchecked(self, slice: *const [T]) -> *const [T] {
596 unsafe { (self.start..slice.len()).get_unchecked(slice) }
598 }
599
600 #[inline]
601 unsafe fn get_unchecked_mut(self, slice: *mut [T]) -> *mut [T] {
602 unsafe { (self.start..slice.len()).get_unchecked_mut(slice) }
604 }
605
606 #[inline]
607 fn index(self, slice: &[T]) -> &[T] {
608 if self.start > slice.len() {
609 slice_start_index_len_fail(self.start, slice.len());
610 }
611 unsafe { &*self.get_unchecked(slice) }
613 }
614
615 #[inline]
616 fn index_mut(self, slice: &mut [T]) -> &mut [T] {
617 if self.start > slice.len() {
618 slice_start_index_len_fail(self.start, slice.len());
619 }
620 unsafe { &mut *self.get_unchecked_mut(slice) }
622 }
623}
624
625#[unstable(feature = "new_range_api", issue = "125687")]
626unsafe impl<T> SliceIndex<[T]> for range::RangeFrom<usize> {
627 type Output = [T];
628
629 #[inline]
630 fn get(self, slice: &[T]) -> Option<&[T]> {
631 ops::RangeFrom::from(self).get(slice)
632 }
633
634 #[inline]
635 fn get_mut(self, slice: &mut [T]) -> Option<&mut [T]> {
636 ops::RangeFrom::from(self).get_mut(slice)
637 }
638
639 #[inline]
640 unsafe fn get_unchecked(self, slice: *const [T]) -> *const [T] {
641 unsafe { ops::RangeFrom::from(self).get_unchecked(slice) }
643 }
644
645 #[inline]
646 unsafe fn get_unchecked_mut(self, slice: *mut [T]) -> *mut [T] {
647 unsafe { ops::RangeFrom::from(self).get_unchecked_mut(slice) }
649 }
650
651 #[inline]
652 fn index(self, slice: &[T]) -> &[T] {
653 ops::RangeFrom::from(self).index(slice)
654 }
655
656 #[inline]
657 fn index_mut(self, slice: &mut [T]) -> &mut [T] {
658 ops::RangeFrom::from(self).index_mut(slice)
659 }
660}
661
662#[stable(feature = "slice_get_slice_impls", since = "1.15.0")]
663unsafe impl<T> SliceIndex<[T]> for ops::RangeFull {
664 type Output = [T];
665
666 #[inline]
667 fn get(self, slice: &[T]) -> Option<&[T]> {
668 Some(slice)
669 }
670
671 #[inline]
672 fn get_mut(self, slice: &mut [T]) -> Option<&mut [T]> {
673 Some(slice)
674 }
675
676 #[inline]
677 unsafe fn get_unchecked(self, slice: *const [T]) -> *const [T] {
678 slice
679 }
680
681 #[inline]
682 unsafe fn get_unchecked_mut(self, slice: *mut [T]) -> *mut [T] {
683 slice
684 }
685
686 #[inline]
687 fn index(self, slice: &[T]) -> &[T] {
688 slice
689 }
690
691 #[inline]
692 fn index_mut(self, slice: &mut [T]) -> &mut [T] {
693 slice
694 }
695}
696
697#[stable(feature = "inclusive_range", since = "1.26.0")]
702unsafe impl<T> SliceIndex<[T]> for ops::RangeInclusive<usize> {
703 type Output = [T];
704
705 #[inline]
706 fn get(self, slice: &[T]) -> Option<&[T]> {
707 if *self.end() == usize::MAX { None } else { self.into_slice_range().get(slice) }
708 }
709
710 #[inline]
711 fn get_mut(self, slice: &mut [T]) -> Option<&mut [T]> {
712 if *self.end() == usize::MAX { None } else { self.into_slice_range().get_mut(slice) }
713 }
714
715 #[inline]
716 unsafe fn get_unchecked(self, slice: *const [T]) -> *const [T] {
717 unsafe { self.into_slice_range().get_unchecked(slice) }
719 }
720
721 #[inline]
722 unsafe fn get_unchecked_mut(self, slice: *mut [T]) -> *mut [T] {
723 unsafe { self.into_slice_range().get_unchecked_mut(slice) }
725 }
726
727 #[inline]
728 fn index(self, slice: &[T]) -> &[T] {
729 if *self.end() == usize::MAX {
730 slice_end_index_overflow_fail();
731 }
732 self.into_slice_range().index(slice)
733 }
734
735 #[inline]
736 fn index_mut(self, slice: &mut [T]) -> &mut [T] {
737 if *self.end() == usize::MAX {
738 slice_end_index_overflow_fail();
739 }
740 self.into_slice_range().index_mut(slice)
741 }
742}
743
744#[unstable(feature = "new_range_api", issue = "125687")]
745unsafe impl<T> SliceIndex<[T]> for range::RangeInclusive<usize> {
746 type Output = [T];
747
748 #[inline]
749 fn get(self, slice: &[T]) -> Option<&[T]> {
750 ops::RangeInclusive::from(self).get(slice)
751 }
752
753 #[inline]
754 fn get_mut(self, slice: &mut [T]) -> Option<&mut [T]> {
755 ops::RangeInclusive::from(self).get_mut(slice)
756 }
757
758 #[inline]
759 unsafe fn get_unchecked(self, slice: *const [T]) -> *const [T] {
760 unsafe { ops::RangeInclusive::from(self).get_unchecked(slice) }
762 }
763
764 #[inline]
765 unsafe fn get_unchecked_mut(self, slice: *mut [T]) -> *mut [T] {
766 unsafe { ops::RangeInclusive::from(self).get_unchecked_mut(slice) }
768 }
769
770 #[inline]
771 fn index(self, slice: &[T]) -> &[T] {
772 ops::RangeInclusive::from(self).index(slice)
773 }
774
775 #[inline]
776 fn index_mut(self, slice: &mut [T]) -> &mut [T] {
777 ops::RangeInclusive::from(self).index_mut(slice)
778 }
779}
780
781#[stable(feature = "inclusive_range", since = "1.26.0")]
783unsafe impl<T> SliceIndex<[T]> for ops::RangeToInclusive<usize> {
784 type Output = [T];
785
786 #[inline]
787 fn get(self, slice: &[T]) -> Option<&[T]> {
788 (0..=self.end).get(slice)
789 }
790
791 #[inline]
792 fn get_mut(self, slice: &mut [T]) -> Option<&mut [T]> {
793 (0..=self.end).get_mut(slice)
794 }
795
796 #[inline]
797 unsafe fn get_unchecked(self, slice: *const [T]) -> *const [T] {
798 unsafe { (0..=self.end).get_unchecked(slice) }
800 }
801
802 #[inline]
803 unsafe fn get_unchecked_mut(self, slice: *mut [T]) -> *mut [T] {
804 unsafe { (0..=self.end).get_unchecked_mut(slice) }
806 }
807
808 #[inline]
809 fn index(self, slice: &[T]) -> &[T] {
810 (0..=self.end).index(slice)
811 }
812
813 #[inline]
814 fn index_mut(self, slice: &mut [T]) -> &mut [T] {
815 (0..=self.end).index_mut(slice)
816 }
817}
818
819#[track_caller]
881#[unstable(feature = "slice_range", issue = "76393")]
882#[must_use]
883pub fn range<R>(range: R, bounds: ops::RangeTo<usize>) -> ops::Range<usize>
884where
885 R: ops::RangeBounds<usize>,
886{
887 let len = bounds.end;
888
889 let start = match range.start_bound() {
890 ops::Bound::Included(&start) => start,
891 ops::Bound::Excluded(start) => {
892 start.checked_add(1).unwrap_or_else(|| slice_start_index_overflow_fail())
893 }
894 ops::Bound::Unbounded => 0,
895 };
896
897 let end = match range.end_bound() {
898 ops::Bound::Included(end) => {
899 end.checked_add(1).unwrap_or_else(|| slice_end_index_overflow_fail())
900 }
901 ops::Bound::Excluded(&end) => end,
902 ops::Bound::Unbounded => len,
903 };
904
905 if start > end {
906 slice_index_order_fail(start, end);
907 }
908 if end > len {
909 slice_end_index_len_fail(end, len);
910 }
911
912 ops::Range { start, end }
913}
914
915#[unstable(feature = "slice_range", issue = "76393")]
946#[must_use]
947pub fn try_range<R>(range: R, bounds: ops::RangeTo<usize>) -> Option<ops::Range<usize>>
948where
949 R: ops::RangeBounds<usize>,
950{
951 let len = bounds.end;
952
953 let start = match range.start_bound() {
954 ops::Bound::Included(&start) => start,
955 ops::Bound::Excluded(start) => start.checked_add(1)?,
956 ops::Bound::Unbounded => 0,
957 };
958
959 let end = match range.end_bound() {
960 ops::Bound::Included(end) => end.checked_add(1)?,
961 ops::Bound::Excluded(&end) => end,
962 ops::Bound::Unbounded => len,
963 };
964
965 if start > end || end > len { None } else { Some(ops::Range { start, end }) }
966}
967
968pub(crate) fn into_range_unchecked(
971 len: usize,
972 (start, end): (ops::Bound<usize>, ops::Bound<usize>),
973) -> ops::Range<usize> {
974 use ops::Bound;
975 let start = match start {
976 Bound::Included(i) => i,
977 Bound::Excluded(i) => i + 1,
978 Bound::Unbounded => 0,
979 };
980 let end = match end {
981 Bound::Included(i) => i + 1,
982 Bound::Excluded(i) => i,
983 Bound::Unbounded => len,
984 };
985 start..end
986}
987
988pub(crate) fn into_range(
991 len: usize,
992 (start, end): (ops::Bound<usize>, ops::Bound<usize>),
993) -> Option<ops::Range<usize>> {
994 use ops::Bound;
995 let start = match start {
996 Bound::Included(start) => start,
997 Bound::Excluded(start) => start.checked_add(1)?,
998 Bound::Unbounded => 0,
999 };
1000
1001 let end = match end {
1002 Bound::Included(end) => end.checked_add(1)?,
1003 Bound::Excluded(end) => end,
1004 Bound::Unbounded => len,
1005 };
1006
1007 Some(start..end)
1011}
1012
1013pub(crate) fn into_slice_range(
1016 len: usize,
1017 (start, end): (ops::Bound<usize>, ops::Bound<usize>),
1018) -> ops::Range<usize> {
1019 use ops::Bound;
1020 let start = match start {
1021 Bound::Included(start) => start,
1022 Bound::Excluded(start) => {
1023 start.checked_add(1).unwrap_or_else(|| slice_start_index_overflow_fail())
1024 }
1025 Bound::Unbounded => 0,
1026 };
1027
1028 let end = match end {
1029 Bound::Included(end) => {
1030 end.checked_add(1).unwrap_or_else(|| slice_end_index_overflow_fail())
1031 }
1032 Bound::Excluded(end) => end,
1033 Bound::Unbounded => len,
1034 };
1035
1036 start..end
1040}
1041
1042#[stable(feature = "slice_index_with_ops_bound_pair", since = "1.53.0")]
1043unsafe impl<T> SliceIndex<[T]> for (ops::Bound<usize>, ops::Bound<usize>) {
1044 type Output = [T];
1045
1046 #[inline]
1047 fn get(self, slice: &[T]) -> Option<&Self::Output> {
1048 into_range(slice.len(), self)?.get(slice)
1049 }
1050
1051 #[inline]
1052 fn get_mut(self, slice: &mut [T]) -> Option<&mut Self::Output> {
1053 into_range(slice.len(), self)?.get_mut(slice)
1054 }
1055
1056 #[inline]
1057 unsafe fn get_unchecked(self, slice: *const [T]) -> *const Self::Output {
1058 unsafe { into_range_unchecked(slice.len(), self).get_unchecked(slice) }
1060 }
1061
1062 #[inline]
1063 unsafe fn get_unchecked_mut(self, slice: *mut [T]) -> *mut Self::Output {
1064 unsafe { into_range_unchecked(slice.len(), self).get_unchecked_mut(slice) }
1066 }
1067
1068 #[inline]
1069 fn index(self, slice: &[T]) -> &Self::Output {
1070 into_slice_range(slice.len(), self).index(slice)
1071 }
1072
1073 #[inline]
1074 fn index_mut(self, slice: &mut [T]) -> &mut Self::Output {
1075 into_slice_range(slice.len(), self).index_mut(slice)
1076 }
1077}