1use crate::panic::const_panic;
4use crate::ub_checks::assert_unsafe_precondition;
5use crate::{ops, range};
6
7#[stable(feature = "rust1", since = "1.0.0")]
8impl<T, I> ops::Index<I> for [T]
9where
10 I: SliceIndex<[T]>,
11{
12 type Output = I::Output;
13
14 #[inline(always)]
15 fn index(&self, index: I) -> &I::Output {
16 index.index(self)
17 }
18}
19
20#[stable(feature = "rust1", since = "1.0.0")]
21impl<T, I> ops::IndexMut<I> for [T]
22where
23 I: SliceIndex<[T]>,
24{
25 #[inline(always)]
26 fn index_mut(&mut self, index: I) -> &mut I::Output {
27 index.index_mut(self)
28 }
29}
30
31#[cfg_attr(not(feature = "panic_immediate_abort"), inline(never), cold)]
32#[cfg_attr(feature = "panic_immediate_abort", inline)]
33#[track_caller]
34const fn slice_start_index_len_fail(index: usize, len: usize) -> ! {
35 const_panic!(
36 "slice start index is out of range for slice",
37 "range start index {index} out of range for slice of length {len}",
38 index: usize,
39 len: usize,
40 )
41}
42
43#[cfg_attr(not(feature = "panic_immediate_abort"), inline(never), cold)]
44#[cfg_attr(feature = "panic_immediate_abort", inline)]
45#[track_caller]
46const fn slice_end_index_len_fail(index: usize, len: usize) -> ! {
47 const_panic!(
48 "slice end index is out of range for slice",
49 "range end index {index} out of range for slice of length {len}",
50 index: usize,
51 len: usize,
52 )
53}
54
55#[cfg_attr(not(feature = "panic_immediate_abort"), inline(never), cold)]
56#[cfg_attr(feature = "panic_immediate_abort", inline)]
57#[track_caller]
58const fn slice_index_order_fail(index: usize, end: usize) -> ! {
59 const_panic!(
60 "slice index start is larger than end",
61 "slice index starts at {index} but ends at {end}",
62 index: usize,
63 end: usize,
64 )
65}
66
67#[cfg_attr(not(feature = "panic_immediate_abort"), inline(never), cold)]
68#[cfg_attr(feature = "panic_immediate_abort", inline)]
69#[track_caller]
70const fn slice_start_index_overflow_fail() -> ! {
71 panic!("attempted to index slice from after maximum usize");
72}
73
74#[cfg_attr(not(feature = "panic_immediate_abort"), inline(never), cold)]
75#[cfg_attr(feature = "panic_immediate_abort", inline)]
76#[track_caller]
77const fn slice_end_index_overflow_fail() -> ! {
78 panic!("attempted to index slice up to maximum usize");
79}
80
81#[inline(always)]
87const unsafe fn get_noubcheck<T>(ptr: *const [T], index: usize) -> *const T {
88 let ptr = ptr as *const T;
89 unsafe { crate::intrinsics::offset(ptr, index) }
91}
92
93#[inline(always)]
94const unsafe fn get_mut_noubcheck<T>(ptr: *mut [T], index: usize) -> *mut T {
95 let ptr = ptr as *mut T;
96 unsafe { crate::intrinsics::offset(ptr, index) }
98}
99
100#[inline(always)]
101const unsafe fn get_offset_len_noubcheck<T>(
102 ptr: *const [T],
103 offset: usize,
104 len: usize,
105) -> *const [T] {
106 let ptr = unsafe { get_noubcheck(ptr, offset) };
108 crate::intrinsics::aggregate_raw_ptr(ptr, len)
109}
110
111#[inline(always)]
112const unsafe fn get_offset_len_mut_noubcheck<T>(
113 ptr: *mut [T],
114 offset: usize,
115 len: usize,
116) -> *mut [T] {
117 let ptr = unsafe { get_mut_noubcheck(ptr, offset) };
119 crate::intrinsics::aggregate_raw_ptr(ptr, len)
120}
121
122mod private_slice_index {
123 use super::{ops, range};
124
125 #[stable(feature = "slice_get_slice", since = "1.28.0")]
126 pub trait Sealed {}
127
128 #[stable(feature = "slice_get_slice", since = "1.28.0")]
129 impl Sealed for usize {}
130 #[stable(feature = "slice_get_slice", since = "1.28.0")]
131 impl Sealed for ops::Range<usize> {}
132 #[stable(feature = "slice_get_slice", since = "1.28.0")]
133 impl Sealed for ops::RangeTo<usize> {}
134 #[stable(feature = "slice_get_slice", since = "1.28.0")]
135 impl Sealed for ops::RangeFrom<usize> {}
136 #[stable(feature = "slice_get_slice", since = "1.28.0")]
137 impl Sealed for ops::RangeFull {}
138 #[stable(feature = "slice_get_slice", since = "1.28.0")]
139 impl Sealed for ops::RangeInclusive<usize> {}
140 #[stable(feature = "slice_get_slice", since = "1.28.0")]
141 impl Sealed for ops::RangeToInclusive<usize> {}
142 #[stable(feature = "slice_index_with_ops_bound_pair", since = "1.53.0")]
143 impl Sealed for (ops::Bound<usize>, ops::Bound<usize>) {}
144
145 #[unstable(feature = "new_range_api", issue = "125687")]
146 impl Sealed for range::Range<usize> {}
147 #[unstable(feature = "new_range_api", issue = "125687")]
148 impl Sealed for range::RangeInclusive<usize> {}
149 #[unstable(feature = "new_range_api", issue = "125687")]
150 impl Sealed for range::RangeFrom<usize> {}
151
152 impl Sealed for ops::IndexRange {}
153}
154
155#[stable(feature = "slice_get_slice", since = "1.28.0")]
160#[rustc_diagnostic_item = "SliceIndex"]
161#[rustc_on_unimplemented(
162 on(T = "str", label = "string indices are ranges of `usize`",),
163 on(
164 all(any(T = "str", T = "&str", T = "alloc::string::String"), _Self = "{integer}"),
165 note = "you can use `.chars().nth()` or `.bytes().nth()`\n\
166 for more information, see chapter 8 in The Book: \
167 <https://doc.rust-lang.org/book/ch08-02-strings.html#indexing-into-strings>"
168 ),
169 message = "the type `{T}` cannot be indexed by `{Self}`",
170 label = "slice indices are of type `usize` or ranges of `usize`"
171)]
172pub unsafe trait SliceIndex<T: ?Sized>: private_slice_index::Sealed {
173 #[stable(feature = "slice_get_slice", since = "1.28.0")]
175 type Output: ?Sized;
176
177 #[unstable(feature = "slice_index_methods", issue = "none")]
180 fn get(self, slice: &T) -> Option<&Self::Output>;
181
182 #[unstable(feature = "slice_index_methods", issue = "none")]
185 fn get_mut(self, slice: &mut T) -> Option<&mut Self::Output>;
186
187 #[unstable(feature = "slice_index_methods", issue = "none")]
195 unsafe fn get_unchecked(self, slice: *const T) -> *const Self::Output;
196
197 #[unstable(feature = "slice_index_methods", issue = "none")]
205 unsafe fn get_unchecked_mut(self, slice: *mut T) -> *mut Self::Output;
206
207 #[unstable(feature = "slice_index_methods", issue = "none")]
210 #[track_caller]
211 fn index(self, slice: &T) -> &Self::Output;
212
213 #[unstable(feature = "slice_index_methods", issue = "none")]
216 #[track_caller]
217 fn index_mut(self, slice: &mut T) -> &mut Self::Output;
218}
219
220#[stable(feature = "slice_get_slice_impls", since = "1.15.0")]
222unsafe impl<T> SliceIndex<[T]> for usize {
223 type Output = T;
224
225 #[inline]
226 fn get(self, slice: &[T]) -> Option<&T> {
227 if self < slice.len() { unsafe { Some(&*get_noubcheck(slice, self)) } } else { None }
229 }
230
231 #[inline]
232 fn get_mut(self, slice: &mut [T]) -> Option<&mut T> {
233 if self < slice.len() {
234 unsafe { Some(&mut *get_mut_noubcheck(slice, self)) }
236 } else {
237 None
238 }
239 }
240
241 #[inline]
242 unsafe fn get_unchecked(self, slice: *const [T]) -> *const T {
243 assert_unsafe_precondition!(
244 check_language_ub,
245 "slice::get_unchecked requires that the index is within the slice",
246 (this: usize = self, len: usize = slice.len()) => this < len
247 );
248 unsafe {
253 crate::intrinsics::assume(self < slice.len());
256 get_noubcheck(slice, self)
257 }
258 }
259
260 #[inline]
261 unsafe fn get_unchecked_mut(self, slice: *mut [T]) -> *mut T {
262 assert_unsafe_precondition!(
263 check_library_ub,
264 "slice::get_unchecked_mut requires that the index is within the slice",
265 (this: usize = self, len: usize = slice.len()) => this < len
266 );
267 unsafe { get_mut_noubcheck(slice, self) }
269 }
270
271 #[inline]
272 fn index(self, slice: &[T]) -> &T {
273 &(*slice)[self]
275 }
276
277 #[inline]
278 fn index_mut(self, slice: &mut [T]) -> &mut T {
279 &mut (*slice)[self]
281 }
282}
283
284unsafe impl<T> SliceIndex<[T]> for ops::IndexRange {
287 type Output = [T];
288
289 #[inline]
290 fn get(self, slice: &[T]) -> Option<&[T]> {
291 if self.end() <= slice.len() {
292 unsafe { Some(&*get_offset_len_noubcheck(slice, self.start(), self.len())) }
294 } else {
295 None
296 }
297 }
298
299 #[inline]
300 fn get_mut(self, slice: &mut [T]) -> Option<&mut [T]> {
301 if self.end() <= slice.len() {
302 unsafe { Some(&mut *get_offset_len_mut_noubcheck(slice, self.start(), self.len())) }
304 } else {
305 None
306 }
307 }
308
309 #[inline]
310 unsafe fn get_unchecked(self, slice: *const [T]) -> *const [T] {
311 assert_unsafe_precondition!(
312 check_library_ub,
313 "slice::get_unchecked requires that the index is within the slice",
314 (end: usize = self.end(), len: usize = slice.len()) => end <= len
315 );
316 unsafe { get_offset_len_noubcheck(slice, self.start(), self.len()) }
321 }
322
323 #[inline]
324 unsafe fn get_unchecked_mut(self, slice: *mut [T]) -> *mut [T] {
325 assert_unsafe_precondition!(
326 check_library_ub,
327 "slice::get_unchecked_mut requires that the index is within the slice",
328 (end: usize = self.end(), len: usize = slice.len()) => end <= len
329 );
330
331 unsafe { get_offset_len_mut_noubcheck(slice, self.start(), self.len()) }
333 }
334
335 #[inline]
336 fn index(self, slice: &[T]) -> &[T] {
337 if self.end() <= slice.len() {
338 unsafe { &*get_offset_len_noubcheck(slice, self.start(), self.len()) }
340 } else {
341 slice_end_index_len_fail(self.end(), slice.len())
342 }
343 }
344
345 #[inline]
346 fn index_mut(self, slice: &mut [T]) -> &mut [T] {
347 if self.end() <= slice.len() {
348 unsafe { &mut *get_offset_len_mut_noubcheck(slice, self.start(), self.len()) }
350 } else {
351 slice_end_index_len_fail(self.end(), slice.len())
352 }
353 }
354}
355
356#[stable(feature = "slice_get_slice_impls", since = "1.15.0")]
360unsafe impl<T> SliceIndex<[T]> for ops::Range<usize> {
361 type Output = [T];
362
363 #[inline]
364 fn get(self, slice: &[T]) -> Option<&[T]> {
365 if let Some(new_len) = usize::checked_sub(self.end, self.start)
367 && self.end <= slice.len()
368 {
369 unsafe { Some(&*get_offset_len_noubcheck(slice, self.start, new_len)) }
371 } else {
372 None
373 }
374 }
375
376 #[inline]
377 fn get_mut(self, slice: &mut [T]) -> Option<&mut [T]> {
378 if let Some(new_len) = usize::checked_sub(self.end, self.start)
379 && self.end <= slice.len()
380 {
381 unsafe { Some(&mut *get_offset_len_mut_noubcheck(slice, self.start, new_len)) }
383 } else {
384 None
385 }
386 }
387
388 #[inline]
389 unsafe fn get_unchecked(self, slice: *const [T]) -> *const [T] {
390 assert_unsafe_precondition!(
391 check_library_ub,
392 "slice::get_unchecked requires that the range is within the slice",
393 (
394 start: usize = self.start,
395 end: usize = self.end,
396 len: usize = slice.len()
397 ) => end >= start && end <= len
398 );
399
400 unsafe {
405 let new_len = crate::intrinsics::unchecked_sub(self.end, self.start);
408 get_offset_len_noubcheck(slice, self.start, new_len)
409 }
410 }
411
412 #[inline]
413 unsafe fn get_unchecked_mut(self, slice: *mut [T]) -> *mut [T] {
414 assert_unsafe_precondition!(
415 check_library_ub,
416 "slice::get_unchecked_mut requires that the range is within the slice",
417 (
418 start: usize = self.start,
419 end: usize = self.end,
420 len: usize = slice.len()
421 ) => end >= start && end <= len
422 );
423 unsafe {
425 let new_len = crate::intrinsics::unchecked_sub(self.end, self.start);
426 get_offset_len_mut_noubcheck(slice, self.start, new_len)
427 }
428 }
429
430 #[inline(always)]
431 fn index(self, slice: &[T]) -> &[T] {
432 let Some(new_len) = usize::checked_sub(self.end, self.start) else {
434 slice_index_order_fail(self.start, self.end)
435 };
436 if self.end > slice.len() {
437 slice_end_index_len_fail(self.end, slice.len());
438 }
439 unsafe { &*get_offset_len_noubcheck(slice, self.start, new_len) }
441 }
442
443 #[inline]
444 fn index_mut(self, slice: &mut [T]) -> &mut [T] {
445 let Some(new_len) = usize::checked_sub(self.end, self.start) else {
446 slice_index_order_fail(self.start, self.end)
447 };
448 if self.end > slice.len() {
449 slice_end_index_len_fail(self.end, slice.len());
450 }
451 unsafe { &mut *get_offset_len_mut_noubcheck(slice, self.start, new_len) }
453 }
454}
455
456#[unstable(feature = "new_range_api", issue = "125687")]
457unsafe impl<T> SliceIndex<[T]> for range::Range<usize> {
458 type Output = [T];
459
460 #[inline]
461 fn get(self, slice: &[T]) -> Option<&[T]> {
462 ops::Range::from(self).get(slice)
463 }
464
465 #[inline]
466 fn get_mut(self, slice: &mut [T]) -> Option<&mut [T]> {
467 ops::Range::from(self).get_mut(slice)
468 }
469
470 #[inline]
471 unsafe fn get_unchecked(self, slice: *const [T]) -> *const [T] {
472 unsafe { ops::Range::from(self).get_unchecked(slice) }
474 }
475
476 #[inline]
477 unsafe fn get_unchecked_mut(self, slice: *mut [T]) -> *mut [T] {
478 unsafe { ops::Range::from(self).get_unchecked_mut(slice) }
480 }
481
482 #[inline(always)]
483 fn index(self, slice: &[T]) -> &[T] {
484 ops::Range::from(self).index(slice)
485 }
486
487 #[inline]
488 fn index_mut(self, slice: &mut [T]) -> &mut [T] {
489 ops::Range::from(self).index_mut(slice)
490 }
491}
492
493#[stable(feature = "slice_get_slice_impls", since = "1.15.0")]
495unsafe impl<T> SliceIndex<[T]> for ops::RangeTo<usize> {
496 type Output = [T];
497
498 #[inline]
499 fn get(self, slice: &[T]) -> Option<&[T]> {
500 (0..self.end).get(slice)
501 }
502
503 #[inline]
504 fn get_mut(self, slice: &mut [T]) -> Option<&mut [T]> {
505 (0..self.end).get_mut(slice)
506 }
507
508 #[inline]
509 unsafe fn get_unchecked(self, slice: *const [T]) -> *const [T] {
510 unsafe { (0..self.end).get_unchecked(slice) }
512 }
513
514 #[inline]
515 unsafe fn get_unchecked_mut(self, slice: *mut [T]) -> *mut [T] {
516 unsafe { (0..self.end).get_unchecked_mut(slice) }
518 }
519
520 #[inline(always)]
521 fn index(self, slice: &[T]) -> &[T] {
522 (0..self.end).index(slice)
523 }
524
525 #[inline]
526 fn index_mut(self, slice: &mut [T]) -> &mut [T] {
527 (0..self.end).index_mut(slice)
528 }
529}
530
531#[stable(feature = "slice_get_slice_impls", since = "1.15.0")]
533unsafe impl<T> SliceIndex<[T]> for ops::RangeFrom<usize> {
534 type Output = [T];
535
536 #[inline]
537 fn get(self, slice: &[T]) -> Option<&[T]> {
538 (self.start..slice.len()).get(slice)
539 }
540
541 #[inline]
542 fn get_mut(self, slice: &mut [T]) -> Option<&mut [T]> {
543 (self.start..slice.len()).get_mut(slice)
544 }
545
546 #[inline]
547 unsafe fn get_unchecked(self, slice: *const [T]) -> *const [T] {
548 unsafe { (self.start..slice.len()).get_unchecked(slice) }
550 }
551
552 #[inline]
553 unsafe fn get_unchecked_mut(self, slice: *mut [T]) -> *mut [T] {
554 unsafe { (self.start..slice.len()).get_unchecked_mut(slice) }
556 }
557
558 #[inline]
559 fn index(self, slice: &[T]) -> &[T] {
560 if self.start > slice.len() {
561 slice_start_index_len_fail(self.start, slice.len());
562 }
563 unsafe { &*self.get_unchecked(slice) }
565 }
566
567 #[inline]
568 fn index_mut(self, slice: &mut [T]) -> &mut [T] {
569 if self.start > slice.len() {
570 slice_start_index_len_fail(self.start, slice.len());
571 }
572 unsafe { &mut *self.get_unchecked_mut(slice) }
574 }
575}
576
577#[unstable(feature = "new_range_api", issue = "125687")]
578unsafe impl<T> SliceIndex<[T]> for range::RangeFrom<usize> {
579 type Output = [T];
580
581 #[inline]
582 fn get(self, slice: &[T]) -> Option<&[T]> {
583 ops::RangeFrom::from(self).get(slice)
584 }
585
586 #[inline]
587 fn get_mut(self, slice: &mut [T]) -> Option<&mut [T]> {
588 ops::RangeFrom::from(self).get_mut(slice)
589 }
590
591 #[inline]
592 unsafe fn get_unchecked(self, slice: *const [T]) -> *const [T] {
593 unsafe { ops::RangeFrom::from(self).get_unchecked(slice) }
595 }
596
597 #[inline]
598 unsafe fn get_unchecked_mut(self, slice: *mut [T]) -> *mut [T] {
599 unsafe { ops::RangeFrom::from(self).get_unchecked_mut(slice) }
601 }
602
603 #[inline]
604 fn index(self, slice: &[T]) -> &[T] {
605 ops::RangeFrom::from(self).index(slice)
606 }
607
608 #[inline]
609 fn index_mut(self, slice: &mut [T]) -> &mut [T] {
610 ops::RangeFrom::from(self).index_mut(slice)
611 }
612}
613
614#[stable(feature = "slice_get_slice_impls", since = "1.15.0")]
615unsafe impl<T> SliceIndex<[T]> for ops::RangeFull {
616 type Output = [T];
617
618 #[inline]
619 fn get(self, slice: &[T]) -> Option<&[T]> {
620 Some(slice)
621 }
622
623 #[inline]
624 fn get_mut(self, slice: &mut [T]) -> Option<&mut [T]> {
625 Some(slice)
626 }
627
628 #[inline]
629 unsafe fn get_unchecked(self, slice: *const [T]) -> *const [T] {
630 slice
631 }
632
633 #[inline]
634 unsafe fn get_unchecked_mut(self, slice: *mut [T]) -> *mut [T] {
635 slice
636 }
637
638 #[inline]
639 fn index(self, slice: &[T]) -> &[T] {
640 slice
641 }
642
643 #[inline]
644 fn index_mut(self, slice: &mut [T]) -> &mut [T] {
645 slice
646 }
647}
648
649#[stable(feature = "inclusive_range", since = "1.26.0")]
654unsafe impl<T> SliceIndex<[T]> for ops::RangeInclusive<usize> {
655 type Output = [T];
656
657 #[inline]
658 fn get(self, slice: &[T]) -> Option<&[T]> {
659 if *self.end() == usize::MAX { None } else { self.into_slice_range().get(slice) }
660 }
661
662 #[inline]
663 fn get_mut(self, slice: &mut [T]) -> Option<&mut [T]> {
664 if *self.end() == usize::MAX { None } else { self.into_slice_range().get_mut(slice) }
665 }
666
667 #[inline]
668 unsafe fn get_unchecked(self, slice: *const [T]) -> *const [T] {
669 unsafe { self.into_slice_range().get_unchecked(slice) }
671 }
672
673 #[inline]
674 unsafe fn get_unchecked_mut(self, slice: *mut [T]) -> *mut [T] {
675 unsafe { self.into_slice_range().get_unchecked_mut(slice) }
677 }
678
679 #[inline]
680 fn index(self, slice: &[T]) -> &[T] {
681 if *self.end() == usize::MAX {
682 slice_end_index_overflow_fail();
683 }
684 self.into_slice_range().index(slice)
685 }
686
687 #[inline]
688 fn index_mut(self, slice: &mut [T]) -> &mut [T] {
689 if *self.end() == usize::MAX {
690 slice_end_index_overflow_fail();
691 }
692 self.into_slice_range().index_mut(slice)
693 }
694}
695
696#[unstable(feature = "new_range_api", issue = "125687")]
697unsafe impl<T> SliceIndex<[T]> for range::RangeInclusive<usize> {
698 type Output = [T];
699
700 #[inline]
701 fn get(self, slice: &[T]) -> Option<&[T]> {
702 ops::RangeInclusive::from(self).get(slice)
703 }
704
705 #[inline]
706 fn get_mut(self, slice: &mut [T]) -> Option<&mut [T]> {
707 ops::RangeInclusive::from(self).get_mut(slice)
708 }
709
710 #[inline]
711 unsafe fn get_unchecked(self, slice: *const [T]) -> *const [T] {
712 unsafe { ops::RangeInclusive::from(self).get_unchecked(slice) }
714 }
715
716 #[inline]
717 unsafe fn get_unchecked_mut(self, slice: *mut [T]) -> *mut [T] {
718 unsafe { ops::RangeInclusive::from(self).get_unchecked_mut(slice) }
720 }
721
722 #[inline]
723 fn index(self, slice: &[T]) -> &[T] {
724 ops::RangeInclusive::from(self).index(slice)
725 }
726
727 #[inline]
728 fn index_mut(self, slice: &mut [T]) -> &mut [T] {
729 ops::RangeInclusive::from(self).index_mut(slice)
730 }
731}
732
733#[stable(feature = "inclusive_range", since = "1.26.0")]
735unsafe impl<T> SliceIndex<[T]> for ops::RangeToInclusive<usize> {
736 type Output = [T];
737
738 #[inline]
739 fn get(self, slice: &[T]) -> Option<&[T]> {
740 (0..=self.end).get(slice)
741 }
742
743 #[inline]
744 fn get_mut(self, slice: &mut [T]) -> Option<&mut [T]> {
745 (0..=self.end).get_mut(slice)
746 }
747
748 #[inline]
749 unsafe fn get_unchecked(self, slice: *const [T]) -> *const [T] {
750 unsafe { (0..=self.end).get_unchecked(slice) }
752 }
753
754 #[inline]
755 unsafe fn get_unchecked_mut(self, slice: *mut [T]) -> *mut [T] {
756 unsafe { (0..=self.end).get_unchecked_mut(slice) }
758 }
759
760 #[inline]
761 fn index(self, slice: &[T]) -> &[T] {
762 (0..=self.end).index(slice)
763 }
764
765 #[inline]
766 fn index_mut(self, slice: &mut [T]) -> &mut [T] {
767 (0..=self.end).index_mut(slice)
768 }
769}
770
771#[track_caller]
833#[unstable(feature = "slice_range", issue = "76393")]
834#[must_use]
835pub fn range<R>(range: R, bounds: ops::RangeTo<usize>) -> ops::Range<usize>
836where
837 R: ops::RangeBounds<usize>,
838{
839 let len = bounds.end;
840
841 let start = match range.start_bound() {
842 ops::Bound::Included(&start) => start,
843 ops::Bound::Excluded(start) => {
844 start.checked_add(1).unwrap_or_else(|| slice_start_index_overflow_fail())
845 }
846 ops::Bound::Unbounded => 0,
847 };
848
849 let end = match range.end_bound() {
850 ops::Bound::Included(end) => {
851 end.checked_add(1).unwrap_or_else(|| slice_end_index_overflow_fail())
852 }
853 ops::Bound::Excluded(&end) => end,
854 ops::Bound::Unbounded => len,
855 };
856
857 if start > end {
858 slice_index_order_fail(start, end);
859 }
860 if end > len {
861 slice_end_index_len_fail(end, len);
862 }
863
864 ops::Range { start, end }
865}
866
867#[unstable(feature = "slice_range", issue = "76393")]
898#[must_use]
899pub fn try_range<R>(range: R, bounds: ops::RangeTo<usize>) -> Option<ops::Range<usize>>
900where
901 R: ops::RangeBounds<usize>,
902{
903 let len = bounds.end;
904
905 let start = match range.start_bound() {
906 ops::Bound::Included(&start) => start,
907 ops::Bound::Excluded(start) => start.checked_add(1)?,
908 ops::Bound::Unbounded => 0,
909 };
910
911 let end = match range.end_bound() {
912 ops::Bound::Included(end) => end.checked_add(1)?,
913 ops::Bound::Excluded(&end) => end,
914 ops::Bound::Unbounded => len,
915 };
916
917 if start > end || end > len { None } else { Some(ops::Range { start, end }) }
918}
919
920pub(crate) fn into_range_unchecked(
923 len: usize,
924 (start, end): (ops::Bound<usize>, ops::Bound<usize>),
925) -> ops::Range<usize> {
926 use ops::Bound;
927 let start = match start {
928 Bound::Included(i) => i,
929 Bound::Excluded(i) => i + 1,
930 Bound::Unbounded => 0,
931 };
932 let end = match end {
933 Bound::Included(i) => i + 1,
934 Bound::Excluded(i) => i,
935 Bound::Unbounded => len,
936 };
937 start..end
938}
939
940pub(crate) fn into_range(
943 len: usize,
944 (start, end): (ops::Bound<usize>, ops::Bound<usize>),
945) -> Option<ops::Range<usize>> {
946 use ops::Bound;
947 let start = match start {
948 Bound::Included(start) => start,
949 Bound::Excluded(start) => start.checked_add(1)?,
950 Bound::Unbounded => 0,
951 };
952
953 let end = match end {
954 Bound::Included(end) => end.checked_add(1)?,
955 Bound::Excluded(end) => end,
956 Bound::Unbounded => len,
957 };
958
959 Some(start..end)
963}
964
965pub(crate) fn into_slice_range(
968 len: usize,
969 (start, end): (ops::Bound<usize>, ops::Bound<usize>),
970) -> ops::Range<usize> {
971 use ops::Bound;
972 let start = match start {
973 Bound::Included(start) => start,
974 Bound::Excluded(start) => {
975 start.checked_add(1).unwrap_or_else(|| slice_start_index_overflow_fail())
976 }
977 Bound::Unbounded => 0,
978 };
979
980 let end = match end {
981 Bound::Included(end) => {
982 end.checked_add(1).unwrap_or_else(|| slice_end_index_overflow_fail())
983 }
984 Bound::Excluded(end) => end,
985 Bound::Unbounded => len,
986 };
987
988 start..end
992}
993
994#[stable(feature = "slice_index_with_ops_bound_pair", since = "1.53.0")]
995unsafe impl<T> SliceIndex<[T]> for (ops::Bound<usize>, ops::Bound<usize>) {
996 type Output = [T];
997
998 #[inline]
999 fn get(self, slice: &[T]) -> Option<&Self::Output> {
1000 into_range(slice.len(), self)?.get(slice)
1001 }
1002
1003 #[inline]
1004 fn get_mut(self, slice: &mut [T]) -> Option<&mut Self::Output> {
1005 into_range(slice.len(), self)?.get_mut(slice)
1006 }
1007
1008 #[inline]
1009 unsafe fn get_unchecked(self, slice: *const [T]) -> *const Self::Output {
1010 unsafe { into_range_unchecked(slice.len(), self).get_unchecked(slice) }
1012 }
1013
1014 #[inline]
1015 unsafe fn get_unchecked_mut(self, slice: *mut [T]) -> *mut Self::Output {
1016 unsafe { into_range_unchecked(slice.len(), self).get_unchecked_mut(slice) }
1018 }
1019
1020 #[inline]
1021 fn index(self, slice: &[T]) -> &Self::Output {
1022 into_slice_range(slice.len(), self).index(slice)
1023 }
1024
1025 #[inline]
1026 fn index_mut(self, slice: &mut [T]) -> &mut Self::Output {
1027 into_slice_range(slice.len(), self).index_mut(slice)
1028 }
1029}