1use crate::intrinsics::slice_get_unchecked;
4use crate::panic::const_panic;
5use crate::ub_checks::assert_unsafe_precondition;
6use crate::{ops, range};
7
8#[stable(feature = "rust1", since = "1.0.0")]
9#[rustc_const_unstable(feature = "const_index", issue = "143775")]
10impl<T, I> const ops::Index<I> for [T]
11where
12 I: ~const 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")]
23#[rustc_const_unstable(feature = "const_index", issue = "143775")]
24impl<T, I> const ops::IndexMut<I> for [T]
25where
26 I: ~const SliceIndex<[T]>,
27{
28 #[inline(always)]
29 fn index_mut(&mut self, index: I) -> &mut I::Output {
30 index.index_mut(self)
31 }
32}
33
34#[cfg_attr(not(feature = "panic_immediate_abort"), inline(never), cold)]
35#[cfg_attr(feature = "panic_immediate_abort", inline)]
36#[track_caller]
37const fn slice_start_index_len_fail(index: usize, len: usize) -> ! {
38 const_panic!(
39 "slice start index is out of range for slice",
40 "range start index {index} out of range for slice of length {len}",
41 index: usize,
42 len: usize,
43 )
44}
45
46#[cfg_attr(not(feature = "panic_immediate_abort"), inline(never), cold)]
47#[cfg_attr(feature = "panic_immediate_abort", inline)]
48#[track_caller]
49const fn slice_end_index_len_fail(index: usize, len: usize) -> ! {
50 const_panic!(
51 "slice end index is out of range for slice",
52 "range end index {index} out of range for slice of length {len}",
53 index: usize,
54 len: usize,
55 )
56}
57
58#[cfg_attr(not(feature = "panic_immediate_abort"), inline(never), cold)]
59#[cfg_attr(feature = "panic_immediate_abort", inline)]
60#[track_caller]
61const fn slice_index_order_fail(index: usize, end: usize) -> ! {
62 const_panic!(
63 "slice index start is larger than end",
64 "slice index starts at {index} but ends at {end}",
65 index: usize,
66 end: usize,
67 )
68}
69
70#[cfg_attr(not(feature = "panic_immediate_abort"), inline(never), cold)]
71#[cfg_attr(feature = "panic_immediate_abort", inline)]
72#[track_caller]
73const fn slice_start_index_overflow_fail() -> ! {
74 panic!("attempted to index slice from after maximum usize");
75}
76
77#[cfg_attr(not(feature = "panic_immediate_abort"), inline(never), cold)]
78#[cfg_attr(feature = "panic_immediate_abort", inline)]
79#[track_caller]
80const fn slice_end_index_overflow_fail() -> ! {
81 panic!("attempted to index slice up to maximum usize");
82}
83
84#[inline(always)]
90const unsafe fn get_offset_len_noubcheck<T>(
91 ptr: *const [T],
92 offset: usize,
93 len: usize,
94) -> *const [T] {
95 let ptr = ptr as *const T;
96 let ptr = unsafe { crate::intrinsics::offset(ptr, offset) };
98 crate::intrinsics::aggregate_raw_ptr(ptr, len)
99}
100
101#[inline(always)]
102const unsafe fn get_offset_len_mut_noubcheck<T>(
103 ptr: *mut [T],
104 offset: usize,
105 len: usize,
106) -> *mut [T] {
107 let ptr = ptr as *mut T;
108 let ptr = unsafe { crate::intrinsics::offset(ptr, offset) };
110 crate::intrinsics::aggregate_raw_ptr(ptr, len)
111}
112
113mod private_slice_index {
114 use super::{ops, range};
115
116 #[stable(feature = "slice_get_slice", since = "1.28.0")]
117 pub trait Sealed {}
118
119 #[stable(feature = "slice_get_slice", since = "1.28.0")]
120 impl Sealed for usize {}
121 #[stable(feature = "slice_get_slice", since = "1.28.0")]
122 impl Sealed for ops::Range<usize> {}
123 #[stable(feature = "slice_get_slice", since = "1.28.0")]
124 impl Sealed for ops::RangeTo<usize> {}
125 #[stable(feature = "slice_get_slice", since = "1.28.0")]
126 impl Sealed for ops::RangeFrom<usize> {}
127 #[stable(feature = "slice_get_slice", since = "1.28.0")]
128 impl Sealed for ops::RangeFull {}
129 #[stable(feature = "slice_get_slice", since = "1.28.0")]
130 impl Sealed for ops::RangeInclusive<usize> {}
131 #[stable(feature = "slice_get_slice", since = "1.28.0")]
132 impl Sealed for ops::RangeToInclusive<usize> {}
133 #[stable(feature = "slice_index_with_ops_bound_pair", since = "1.53.0")]
134 impl Sealed for (ops::Bound<usize>, ops::Bound<usize>) {}
135
136 #[unstable(feature = "new_range_api", issue = "125687")]
137 impl Sealed for range::Range<usize> {}
138 #[unstable(feature = "new_range_api", issue = "125687")]
139 impl Sealed for range::RangeInclusive<usize> {}
140 #[unstable(feature = "new_range_api", issue = "125687")]
141 impl Sealed for range::RangeFrom<usize> {}
142
143 impl Sealed for ops::IndexRange {}
144}
145
146#[stable(feature = "slice_get_slice", since = "1.28.0")]
151#[rustc_diagnostic_item = "SliceIndex"]
152#[rustc_on_unimplemented(
153 on(T = "str", label = "string indices are ranges of `usize`",),
154 on(
155 all(any(T = "str", T = "&str", T = "alloc::string::String"), Self = "{integer}"),
156 note = "you can use `.chars().nth()` or `.bytes().nth()`\n\
157 for more information, see chapter 8 in The Book: \
158 <https://doc.rust-lang.org/book/ch08-02-strings.html#indexing-into-strings>"
159 ),
160 message = "the type `{T}` cannot be indexed by `{Self}`",
161 label = "slice indices are of type `usize` or ranges of `usize`"
162)]
163#[const_trait]
164#[rustc_const_unstable(feature = "const_index", issue = "143775")]
165pub unsafe trait SliceIndex<T: ?Sized>: private_slice_index::Sealed {
166 #[stable(feature = "slice_get_slice", since = "1.28.0")]
168 type Output: ?Sized;
169
170 #[unstable(feature = "slice_index_methods", issue = "none")]
173 fn get(self, slice: &T) -> Option<&Self::Output>;
174
175 #[unstable(feature = "slice_index_methods", issue = "none")]
178 fn get_mut(self, slice: &mut T) -> Option<&mut Self::Output>;
179
180 #[unstable(feature = "slice_index_methods", issue = "none")]
188 unsafe fn get_unchecked(self, slice: *const T) -> *const Self::Output;
189
190 #[unstable(feature = "slice_index_methods", issue = "none")]
198 unsafe fn get_unchecked_mut(self, slice: *mut T) -> *mut Self::Output;
199
200 #[unstable(feature = "slice_index_methods", issue = "none")]
203 #[track_caller]
204 fn index(self, slice: &T) -> &Self::Output;
205
206 #[unstable(feature = "slice_index_methods", issue = "none")]
209 #[track_caller]
210 fn index_mut(self, slice: &mut T) -> &mut Self::Output;
211}
212
213#[stable(feature = "slice_get_slice_impls", since = "1.15.0")]
215#[rustc_const_unstable(feature = "const_index", issue = "143775")]
216unsafe impl<T> const SliceIndex<[T]> for usize {
217 type Output = T;
218
219 #[inline]
220 fn get(self, slice: &[T]) -> Option<&T> {
221 if self < slice.len() {
222 unsafe { Some(slice_get_unchecked(slice, self)) }
224 } else {
225 None
226 }
227 }
228
229 #[inline]
230 fn get_mut(self, slice: &mut [T]) -> Option<&mut T> {
231 if self < slice.len() {
232 unsafe { Some(slice_get_unchecked(slice, self)) }
234 } else {
235 None
236 }
237 }
238
239 #[inline]
240 #[track_caller]
241 unsafe fn get_unchecked(self, slice: *const [T]) -> *const T {
242 assert_unsafe_precondition!(
243 check_language_ub,
244 "slice::get_unchecked requires that the index is within the slice",
245 (this: usize = self, len: usize = slice.len()) => this < len
246 );
247 unsafe {
252 crate::intrinsics::assume(self < slice.len());
255 slice_get_unchecked(slice, self)
256 }
257 }
258
259 #[inline]
260 #[track_caller]
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 { slice_get_unchecked(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
284#[rustc_const_unstable(feature = "const_index", issue = "143775")]
287unsafe impl<T> const SliceIndex<[T]> for ops::IndexRange {
288 type Output = [T];
289
290 #[inline]
291 fn get(self, slice: &[T]) -> Option<&[T]> {
292 if self.end() <= slice.len() {
293 unsafe { Some(&*get_offset_len_noubcheck(slice, self.start(), self.len())) }
295 } else {
296 None
297 }
298 }
299
300 #[inline]
301 fn get_mut(self, slice: &mut [T]) -> Option<&mut [T]> {
302 if self.end() <= slice.len() {
303 unsafe { Some(&mut *get_offset_len_mut_noubcheck(slice, self.start(), self.len())) }
305 } else {
306 None
307 }
308 }
309
310 #[inline]
311 #[track_caller]
312 unsafe fn get_unchecked(self, slice: *const [T]) -> *const [T] {
313 assert_unsafe_precondition!(
314 check_library_ub,
315 "slice::get_unchecked requires that the index is within the slice",
316 (end: usize = self.end(), len: usize = slice.len()) => end <= len
317 );
318 unsafe { get_offset_len_noubcheck(slice, self.start(), self.len()) }
323 }
324
325 #[inline]
326 #[track_caller]
327 unsafe fn get_unchecked_mut(self, slice: *mut [T]) -> *mut [T] {
328 assert_unsafe_precondition!(
329 check_library_ub,
330 "slice::get_unchecked_mut requires that the index is within the slice",
331 (end: usize = self.end(), len: usize = slice.len()) => end <= len
332 );
333
334 unsafe { get_offset_len_mut_noubcheck(slice, self.start(), self.len()) }
336 }
337
338 #[inline]
339 fn index(self, slice: &[T]) -> &[T] {
340 if self.end() <= slice.len() {
341 unsafe { &*get_offset_len_noubcheck(slice, self.start(), self.len()) }
343 } else {
344 slice_end_index_len_fail(self.end(), slice.len())
345 }
346 }
347
348 #[inline]
349 fn index_mut(self, slice: &mut [T]) -> &mut [T] {
350 if self.end() <= slice.len() {
351 unsafe { &mut *get_offset_len_mut_noubcheck(slice, self.start(), self.len()) }
353 } else {
354 slice_end_index_len_fail(self.end(), slice.len())
355 }
356 }
357}
358
359#[stable(feature = "slice_get_slice_impls", since = "1.15.0")]
363#[rustc_const_unstable(feature = "const_index", issue = "143775")]
364unsafe impl<T> const SliceIndex<[T]> for ops::Range<usize> {
365 type Output = [T];
366
367 #[inline]
368 fn get(self, slice: &[T]) -> Option<&[T]> {
369 if let Some(new_len) = usize::checked_sub(self.end, self.start)
371 && self.end <= slice.len()
372 {
373 unsafe { Some(&*get_offset_len_noubcheck(slice, self.start, new_len)) }
375 } else {
376 None
377 }
378 }
379
380 #[inline]
381 fn get_mut(self, slice: &mut [T]) -> Option<&mut [T]> {
382 if let Some(new_len) = usize::checked_sub(self.end, self.start)
383 && self.end <= slice.len()
384 {
385 unsafe { Some(&mut *get_offset_len_mut_noubcheck(slice, self.start, new_len)) }
387 } else {
388 None
389 }
390 }
391
392 #[inline]
393 #[track_caller]
394 unsafe fn get_unchecked(self, slice: *const [T]) -> *const [T] {
395 assert_unsafe_precondition!(
396 check_library_ub,
397 "slice::get_unchecked requires that the range is within the slice",
398 (
399 start: usize = self.start,
400 end: usize = self.end,
401 len: usize = slice.len()
402 ) => end >= start && end <= len
403 );
404
405 unsafe {
410 let new_len = crate::intrinsics::unchecked_sub(self.end, self.start);
413 get_offset_len_noubcheck(slice, self.start, new_len)
414 }
415 }
416
417 #[inline]
418 #[track_caller]
419 unsafe fn get_unchecked_mut(self, slice: *mut [T]) -> *mut [T] {
420 assert_unsafe_precondition!(
421 check_library_ub,
422 "slice::get_unchecked_mut requires that the range is within the slice",
423 (
424 start: usize = self.start,
425 end: usize = self.end,
426 len: usize = slice.len()
427 ) => end >= start && end <= len
428 );
429 unsafe {
431 let new_len = crate::intrinsics::unchecked_sub(self.end, self.start);
432 get_offset_len_mut_noubcheck(slice, self.start, new_len)
433 }
434 }
435
436 #[inline(always)]
437 fn index(self, slice: &[T]) -> &[T] {
438 let Some(new_len) = usize::checked_sub(self.end, self.start) else {
440 slice_index_order_fail(self.start, self.end)
441 };
442 if self.end > slice.len() {
443 slice_end_index_len_fail(self.end, slice.len());
444 }
445 unsafe { &*get_offset_len_noubcheck(slice, self.start, new_len) }
447 }
448
449 #[inline]
450 fn index_mut(self, slice: &mut [T]) -> &mut [T] {
451 let Some(new_len) = usize::checked_sub(self.end, self.start) else {
452 slice_index_order_fail(self.start, self.end)
453 };
454 if self.end > slice.len() {
455 slice_end_index_len_fail(self.end, slice.len());
456 }
457 unsafe { &mut *get_offset_len_mut_noubcheck(slice, self.start, new_len) }
459 }
460}
461
462#[unstable(feature = "new_range_api", issue = "125687")]
463#[rustc_const_unstable(feature = "const_index", issue = "143775")]
464unsafe impl<T> const SliceIndex<[T]> for range::Range<usize> {
465 type Output = [T];
466
467 #[inline]
468 fn get(self, slice: &[T]) -> Option<&[T]> {
469 ops::Range::from(self).get(slice)
470 }
471
472 #[inline]
473 fn get_mut(self, slice: &mut [T]) -> Option<&mut [T]> {
474 ops::Range::from(self).get_mut(slice)
475 }
476
477 #[inline]
478 unsafe fn get_unchecked(self, slice: *const [T]) -> *const [T] {
479 unsafe { ops::Range::from(self).get_unchecked(slice) }
481 }
482
483 #[inline]
484 unsafe fn get_unchecked_mut(self, slice: *mut [T]) -> *mut [T] {
485 unsafe { ops::Range::from(self).get_unchecked_mut(slice) }
487 }
488
489 #[inline(always)]
490 fn index(self, slice: &[T]) -> &[T] {
491 ops::Range::from(self).index(slice)
492 }
493
494 #[inline]
495 fn index_mut(self, slice: &mut [T]) -> &mut [T] {
496 ops::Range::from(self).index_mut(slice)
497 }
498}
499
500#[stable(feature = "slice_get_slice_impls", since = "1.15.0")]
502#[rustc_const_unstable(feature = "const_index", issue = "143775")]
503unsafe impl<T> const SliceIndex<[T]> for ops::RangeTo<usize> {
504 type Output = [T];
505
506 #[inline]
507 fn get(self, slice: &[T]) -> Option<&[T]> {
508 (0..self.end).get(slice)
509 }
510
511 #[inline]
512 fn get_mut(self, slice: &mut [T]) -> Option<&mut [T]> {
513 (0..self.end).get_mut(slice)
514 }
515
516 #[inline]
517 unsafe fn get_unchecked(self, slice: *const [T]) -> *const [T] {
518 unsafe { (0..self.end).get_unchecked(slice) }
520 }
521
522 #[inline]
523 unsafe fn get_unchecked_mut(self, slice: *mut [T]) -> *mut [T] {
524 unsafe { (0..self.end).get_unchecked_mut(slice) }
526 }
527
528 #[inline(always)]
529 fn index(self, slice: &[T]) -> &[T] {
530 (0..self.end).index(slice)
531 }
532
533 #[inline]
534 fn index_mut(self, slice: &mut [T]) -> &mut [T] {
535 (0..self.end).index_mut(slice)
536 }
537}
538
539#[stable(feature = "slice_get_slice_impls", since = "1.15.0")]
541#[rustc_const_unstable(feature = "const_index", issue = "143775")]
542unsafe impl<T> const SliceIndex<[T]> for ops::RangeFrom<usize> {
543 type Output = [T];
544
545 #[inline]
546 fn get(self, slice: &[T]) -> Option<&[T]> {
547 (self.start..slice.len()).get(slice)
548 }
549
550 #[inline]
551 fn get_mut(self, slice: &mut [T]) -> Option<&mut [T]> {
552 (self.start..slice.len()).get_mut(slice)
553 }
554
555 #[inline]
556 unsafe fn get_unchecked(self, slice: *const [T]) -> *const [T] {
557 unsafe { (self.start..slice.len()).get_unchecked(slice) }
559 }
560
561 #[inline]
562 unsafe fn get_unchecked_mut(self, slice: *mut [T]) -> *mut [T] {
563 unsafe { (self.start..slice.len()).get_unchecked_mut(slice) }
565 }
566
567 #[inline]
568 fn index(self, slice: &[T]) -> &[T] {
569 if self.start > slice.len() {
570 slice_start_index_len_fail(self.start, slice.len());
571 }
572 unsafe { &*self.get_unchecked(slice) }
574 }
575
576 #[inline]
577 fn index_mut(self, slice: &mut [T]) -> &mut [T] {
578 if self.start > slice.len() {
579 slice_start_index_len_fail(self.start, slice.len());
580 }
581 unsafe { &mut *self.get_unchecked_mut(slice) }
583 }
584}
585
586#[unstable(feature = "new_range_api", issue = "125687")]
587#[rustc_const_unstable(feature = "const_index", issue = "143775")]
588unsafe impl<T> const SliceIndex<[T]> for range::RangeFrom<usize> {
589 type Output = [T];
590
591 #[inline]
592 fn get(self, slice: &[T]) -> Option<&[T]> {
593 ops::RangeFrom::from(self).get(slice)
594 }
595
596 #[inline]
597 fn get_mut(self, slice: &mut [T]) -> Option<&mut [T]> {
598 ops::RangeFrom::from(self).get_mut(slice)
599 }
600
601 #[inline]
602 unsafe fn get_unchecked(self, slice: *const [T]) -> *const [T] {
603 unsafe { ops::RangeFrom::from(self).get_unchecked(slice) }
605 }
606
607 #[inline]
608 unsafe fn get_unchecked_mut(self, slice: *mut [T]) -> *mut [T] {
609 unsafe { ops::RangeFrom::from(self).get_unchecked_mut(slice) }
611 }
612
613 #[inline]
614 fn index(self, slice: &[T]) -> &[T] {
615 ops::RangeFrom::from(self).index(slice)
616 }
617
618 #[inline]
619 fn index_mut(self, slice: &mut [T]) -> &mut [T] {
620 ops::RangeFrom::from(self).index_mut(slice)
621 }
622}
623
624#[stable(feature = "slice_get_slice_impls", since = "1.15.0")]
625#[rustc_const_unstable(feature = "const_index", issue = "143775")]
626unsafe impl<T> const SliceIndex<[T]> for ops::RangeFull {
627 type Output = [T];
628
629 #[inline]
630 fn get(self, slice: &[T]) -> Option<&[T]> {
631 Some(slice)
632 }
633
634 #[inline]
635 fn get_mut(self, slice: &mut [T]) -> Option<&mut [T]> {
636 Some(slice)
637 }
638
639 #[inline]
640 unsafe fn get_unchecked(self, slice: *const [T]) -> *const [T] {
641 slice
642 }
643
644 #[inline]
645 unsafe fn get_unchecked_mut(self, slice: *mut [T]) -> *mut [T] {
646 slice
647 }
648
649 #[inline]
650 fn index(self, slice: &[T]) -> &[T] {
651 slice
652 }
653
654 #[inline]
655 fn index_mut(self, slice: &mut [T]) -> &mut [T] {
656 slice
657 }
658}
659
660#[stable(feature = "inclusive_range", since = "1.26.0")]
665#[rustc_const_unstable(feature = "const_index", issue = "143775")]
666unsafe impl<T> const SliceIndex<[T]> for ops::RangeInclusive<usize> {
667 type Output = [T];
668
669 #[inline]
670 fn get(self, slice: &[T]) -> Option<&[T]> {
671 if *self.end() == usize::MAX { None } else { self.into_slice_range().get(slice) }
672 }
673
674 #[inline]
675 fn get_mut(self, slice: &mut [T]) -> Option<&mut [T]> {
676 if *self.end() == usize::MAX { None } else { self.into_slice_range().get_mut(slice) }
677 }
678
679 #[inline]
680 unsafe fn get_unchecked(self, slice: *const [T]) -> *const [T] {
681 unsafe { self.into_slice_range().get_unchecked(slice) }
683 }
684
685 #[inline]
686 unsafe fn get_unchecked_mut(self, slice: *mut [T]) -> *mut [T] {
687 unsafe { self.into_slice_range().get_unchecked_mut(slice) }
689 }
690
691 #[inline]
692 fn index(self, slice: &[T]) -> &[T] {
693 if *self.end() == usize::MAX {
694 slice_end_index_overflow_fail();
695 }
696 self.into_slice_range().index(slice)
697 }
698
699 #[inline]
700 fn index_mut(self, slice: &mut [T]) -> &mut [T] {
701 if *self.end() == usize::MAX {
702 slice_end_index_overflow_fail();
703 }
704 self.into_slice_range().index_mut(slice)
705 }
706}
707
708#[unstable(feature = "new_range_api", issue = "125687")]
709#[rustc_const_unstable(feature = "const_index", issue = "143775")]
710unsafe impl<T> const SliceIndex<[T]> for range::RangeInclusive<usize> {
711 type Output = [T];
712
713 #[inline]
714 fn get(self, slice: &[T]) -> Option<&[T]> {
715 ops::RangeInclusive::from(self).get(slice)
716 }
717
718 #[inline]
719 fn get_mut(self, slice: &mut [T]) -> Option<&mut [T]> {
720 ops::RangeInclusive::from(self).get_mut(slice)
721 }
722
723 #[inline]
724 unsafe fn get_unchecked(self, slice: *const [T]) -> *const [T] {
725 unsafe { ops::RangeInclusive::from(self).get_unchecked(slice) }
727 }
728
729 #[inline]
730 unsafe fn get_unchecked_mut(self, slice: *mut [T]) -> *mut [T] {
731 unsafe { ops::RangeInclusive::from(self).get_unchecked_mut(slice) }
733 }
734
735 #[inline]
736 fn index(self, slice: &[T]) -> &[T] {
737 ops::RangeInclusive::from(self).index(slice)
738 }
739
740 #[inline]
741 fn index_mut(self, slice: &mut [T]) -> &mut [T] {
742 ops::RangeInclusive::from(self).index_mut(slice)
743 }
744}
745
746#[stable(feature = "inclusive_range", since = "1.26.0")]
748#[rustc_const_unstable(feature = "const_index", issue = "143775")]
749unsafe impl<T> const SliceIndex<[T]> for ops::RangeToInclusive<usize> {
750 type Output = [T];
751
752 #[inline]
753 fn get(self, slice: &[T]) -> Option<&[T]> {
754 (0..=self.end).get(slice)
755 }
756
757 #[inline]
758 fn get_mut(self, slice: &mut [T]) -> Option<&mut [T]> {
759 (0..=self.end).get_mut(slice)
760 }
761
762 #[inline]
763 unsafe fn get_unchecked(self, slice: *const [T]) -> *const [T] {
764 unsafe { (0..=self.end).get_unchecked(slice) }
766 }
767
768 #[inline]
769 unsafe fn get_unchecked_mut(self, slice: *mut [T]) -> *mut [T] {
770 unsafe { (0..=self.end).get_unchecked_mut(slice) }
772 }
773
774 #[inline]
775 fn index(self, slice: &[T]) -> &[T] {
776 (0..=self.end).index(slice)
777 }
778
779 #[inline]
780 fn index_mut(self, slice: &mut [T]) -> &mut [T] {
781 (0..=self.end).index_mut(slice)
782 }
783}
784
785#[track_caller]
847#[unstable(feature = "slice_range", issue = "76393")]
848#[must_use]
849pub fn range<R>(range: R, bounds: ops::RangeTo<usize>) -> ops::Range<usize>
850where
851 R: ops::RangeBounds<usize>,
852{
853 let len = bounds.end;
854
855 let start = match range.start_bound() {
856 ops::Bound::Included(&start) => start,
857 ops::Bound::Excluded(start) => {
858 start.checked_add(1).unwrap_or_else(|| slice_start_index_overflow_fail())
859 }
860 ops::Bound::Unbounded => 0,
861 };
862
863 let end = match range.end_bound() {
864 ops::Bound::Included(end) => {
865 end.checked_add(1).unwrap_or_else(|| slice_end_index_overflow_fail())
866 }
867 ops::Bound::Excluded(&end) => end,
868 ops::Bound::Unbounded => len,
869 };
870
871 if start > end {
872 slice_index_order_fail(start, end);
873 }
874 if end > len {
875 slice_end_index_len_fail(end, len);
876 }
877
878 ops::Range { start, end }
879}
880
881#[unstable(feature = "slice_range", issue = "76393")]
912#[must_use]
913pub fn try_range<R>(range: R, bounds: ops::RangeTo<usize>) -> Option<ops::Range<usize>>
914where
915 R: ops::RangeBounds<usize>,
916{
917 let len = bounds.end;
918
919 let start = match range.start_bound() {
920 ops::Bound::Included(&start) => start,
921 ops::Bound::Excluded(start) => start.checked_add(1)?,
922 ops::Bound::Unbounded => 0,
923 };
924
925 let end = match range.end_bound() {
926 ops::Bound::Included(end) => end.checked_add(1)?,
927 ops::Bound::Excluded(&end) => end,
928 ops::Bound::Unbounded => len,
929 };
930
931 if start > end || end > len { None } else { Some(ops::Range { start, end }) }
932}
933
934pub(crate) fn into_range_unchecked(
937 len: usize,
938 (start, end): (ops::Bound<usize>, ops::Bound<usize>),
939) -> ops::Range<usize> {
940 use ops::Bound;
941 let start = match start {
942 Bound::Included(i) => i,
943 Bound::Excluded(i) => i + 1,
944 Bound::Unbounded => 0,
945 };
946 let end = match end {
947 Bound::Included(i) => i + 1,
948 Bound::Excluded(i) => i,
949 Bound::Unbounded => len,
950 };
951 start..end
952}
953
954pub(crate) fn into_range(
957 len: usize,
958 (start, end): (ops::Bound<usize>, ops::Bound<usize>),
959) -> Option<ops::Range<usize>> {
960 use ops::Bound;
961 let start = match start {
962 Bound::Included(start) => start,
963 Bound::Excluded(start) => start.checked_add(1)?,
964 Bound::Unbounded => 0,
965 };
966
967 let end = match end {
968 Bound::Included(end) => end.checked_add(1)?,
969 Bound::Excluded(end) => end,
970 Bound::Unbounded => len,
971 };
972
973 Some(start..end)
977}
978
979pub(crate) fn into_slice_range(
982 len: usize,
983 (start, end): (ops::Bound<usize>, ops::Bound<usize>),
984) -> ops::Range<usize> {
985 use ops::Bound;
986 let start = match start {
987 Bound::Included(start) => start,
988 Bound::Excluded(start) => {
989 start.checked_add(1).unwrap_or_else(|| slice_start_index_overflow_fail())
990 }
991 Bound::Unbounded => 0,
992 };
993
994 let end = match end {
995 Bound::Included(end) => {
996 end.checked_add(1).unwrap_or_else(|| slice_end_index_overflow_fail())
997 }
998 Bound::Excluded(end) => end,
999 Bound::Unbounded => len,
1000 };
1001
1002 start..end
1006}
1007
1008#[stable(feature = "slice_index_with_ops_bound_pair", since = "1.53.0")]
1009unsafe impl<T> SliceIndex<[T]> for (ops::Bound<usize>, ops::Bound<usize>) {
1010 type Output = [T];
1011
1012 #[inline]
1013 fn get(self, slice: &[T]) -> Option<&Self::Output> {
1014 into_range(slice.len(), self)?.get(slice)
1015 }
1016
1017 #[inline]
1018 fn get_mut(self, slice: &mut [T]) -> Option<&mut Self::Output> {
1019 into_range(slice.len(), self)?.get_mut(slice)
1020 }
1021
1022 #[inline]
1023 unsafe fn get_unchecked(self, slice: *const [T]) -> *const Self::Output {
1024 unsafe { into_range_unchecked(slice.len(), self).get_unchecked(slice) }
1026 }
1027
1028 #[inline]
1029 unsafe fn get_unchecked_mut(self, slice: *mut [T]) -> *mut Self::Output {
1030 unsafe { into_range_unchecked(slice.len(), self).get_unchecked_mut(slice) }
1032 }
1033
1034 #[inline]
1035 fn index(self, slice: &[T]) -> &Self::Output {
1036 into_slice_range(slice.len(), self).index(slice)
1037 }
1038
1039 #[inline]
1040 fn index_mut(self, slice: &mut [T]) -> &mut Self::Output {
1041 into_slice_range(slice.len(), self).index_mut(slice)
1042 }
1043}