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 #[track_caller]
243 unsafe fn get_unchecked(self, slice: *const [T]) -> *const T {
244 assert_unsafe_precondition!(
245 check_language_ub,
246 "slice::get_unchecked requires that the index is within the slice",
247 (this: usize = self, len: usize = slice.len()) => this < len
248 );
249 unsafe {
254 crate::intrinsics::assume(self < slice.len());
257 get_noubcheck(slice, self)
258 }
259 }
260
261 #[inline]
262 #[track_caller]
263 unsafe fn get_unchecked_mut(self, slice: *mut [T]) -> *mut T {
264 assert_unsafe_precondition!(
265 check_library_ub,
266 "slice::get_unchecked_mut requires that the index is within the slice",
267 (this: usize = self, len: usize = slice.len()) => this < len
268 );
269 unsafe { get_mut_noubcheck(slice, self) }
271 }
272
273 #[inline]
274 fn index(self, slice: &[T]) -> &T {
275 &(*slice)[self]
277 }
278
279 #[inline]
280 fn index_mut(self, slice: &mut [T]) -> &mut T {
281 &mut (*slice)[self]
283 }
284}
285
286unsafe impl<T> SliceIndex<[T]> for ops::IndexRange {
289 type Output = [T];
290
291 #[inline]
292 fn get(self, slice: &[T]) -> Option<&[T]> {
293 if self.end() <= slice.len() {
294 unsafe { Some(&*get_offset_len_noubcheck(slice, self.start(), self.len())) }
296 } else {
297 None
298 }
299 }
300
301 #[inline]
302 fn get_mut(self, slice: &mut [T]) -> Option<&mut [T]> {
303 if self.end() <= slice.len() {
304 unsafe { Some(&mut *get_offset_len_mut_noubcheck(slice, self.start(), self.len())) }
306 } else {
307 None
308 }
309 }
310
311 #[inline]
312 #[track_caller]
313 unsafe fn get_unchecked(self, slice: *const [T]) -> *const [T] {
314 assert_unsafe_precondition!(
315 check_library_ub,
316 "slice::get_unchecked requires that the index is within the slice",
317 (end: usize = self.end(), len: usize = slice.len()) => end <= len
318 );
319 unsafe { get_offset_len_noubcheck(slice, self.start(), self.len()) }
324 }
325
326 #[inline]
327 #[track_caller]
328 unsafe fn get_unchecked_mut(self, slice: *mut [T]) -> *mut [T] {
329 assert_unsafe_precondition!(
330 check_library_ub,
331 "slice::get_unchecked_mut requires that the index is within the slice",
332 (end: usize = self.end(), len: usize = slice.len()) => end <= len
333 );
334
335 unsafe { get_offset_len_mut_noubcheck(slice, self.start(), self.len()) }
337 }
338
339 #[inline]
340 fn index(self, slice: &[T]) -> &[T] {
341 if self.end() <= slice.len() {
342 unsafe { &*get_offset_len_noubcheck(slice, self.start(), self.len()) }
344 } else {
345 slice_end_index_len_fail(self.end(), slice.len())
346 }
347 }
348
349 #[inline]
350 fn index_mut(self, slice: &mut [T]) -> &mut [T] {
351 if self.end() <= slice.len() {
352 unsafe { &mut *get_offset_len_mut_noubcheck(slice, self.start(), self.len()) }
354 } else {
355 slice_end_index_len_fail(self.end(), slice.len())
356 }
357 }
358}
359
360#[stable(feature = "slice_get_slice_impls", since = "1.15.0")]
364unsafe impl<T> 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")]
463unsafe impl<T> SliceIndex<[T]> for range::Range<usize> {
464 type Output = [T];
465
466 #[inline]
467 fn get(self, slice: &[T]) -> Option<&[T]> {
468 ops::Range::from(self).get(slice)
469 }
470
471 #[inline]
472 fn get_mut(self, slice: &mut [T]) -> Option<&mut [T]> {
473 ops::Range::from(self).get_mut(slice)
474 }
475
476 #[inline]
477 unsafe fn get_unchecked(self, slice: *const [T]) -> *const [T] {
478 unsafe { ops::Range::from(self).get_unchecked(slice) }
480 }
481
482 #[inline]
483 unsafe fn get_unchecked_mut(self, slice: *mut [T]) -> *mut [T] {
484 unsafe { ops::Range::from(self).get_unchecked_mut(slice) }
486 }
487
488 #[inline(always)]
489 fn index(self, slice: &[T]) -> &[T] {
490 ops::Range::from(self).index(slice)
491 }
492
493 #[inline]
494 fn index_mut(self, slice: &mut [T]) -> &mut [T] {
495 ops::Range::from(self).index_mut(slice)
496 }
497}
498
499#[stable(feature = "slice_get_slice_impls", since = "1.15.0")]
501unsafe impl<T> SliceIndex<[T]> for ops::RangeTo<usize> {
502 type Output = [T];
503
504 #[inline]
505 fn get(self, slice: &[T]) -> Option<&[T]> {
506 (0..self.end).get(slice)
507 }
508
509 #[inline]
510 fn get_mut(self, slice: &mut [T]) -> Option<&mut [T]> {
511 (0..self.end).get_mut(slice)
512 }
513
514 #[inline]
515 unsafe fn get_unchecked(self, slice: *const [T]) -> *const [T] {
516 unsafe { (0..self.end).get_unchecked(slice) }
518 }
519
520 #[inline]
521 unsafe fn get_unchecked_mut(self, slice: *mut [T]) -> *mut [T] {
522 unsafe { (0..self.end).get_unchecked_mut(slice) }
524 }
525
526 #[inline(always)]
527 fn index(self, slice: &[T]) -> &[T] {
528 (0..self.end).index(slice)
529 }
530
531 #[inline]
532 fn index_mut(self, slice: &mut [T]) -> &mut [T] {
533 (0..self.end).index_mut(slice)
534 }
535}
536
537#[stable(feature = "slice_get_slice_impls", since = "1.15.0")]
539unsafe impl<T> SliceIndex<[T]> for ops::RangeFrom<usize> {
540 type Output = [T];
541
542 #[inline]
543 fn get(self, slice: &[T]) -> Option<&[T]> {
544 (self.start..slice.len()).get(slice)
545 }
546
547 #[inline]
548 fn get_mut(self, slice: &mut [T]) -> Option<&mut [T]> {
549 (self.start..slice.len()).get_mut(slice)
550 }
551
552 #[inline]
553 unsafe fn get_unchecked(self, slice: *const [T]) -> *const [T] {
554 unsafe { (self.start..slice.len()).get_unchecked(slice) }
556 }
557
558 #[inline]
559 unsafe fn get_unchecked_mut(self, slice: *mut [T]) -> *mut [T] {
560 unsafe { (self.start..slice.len()).get_unchecked_mut(slice) }
562 }
563
564 #[inline]
565 fn index(self, slice: &[T]) -> &[T] {
566 if self.start > slice.len() {
567 slice_start_index_len_fail(self.start, slice.len());
568 }
569 unsafe { &*self.get_unchecked(slice) }
571 }
572
573 #[inline]
574 fn index_mut(self, slice: &mut [T]) -> &mut [T] {
575 if self.start > slice.len() {
576 slice_start_index_len_fail(self.start, slice.len());
577 }
578 unsafe { &mut *self.get_unchecked_mut(slice) }
580 }
581}
582
583#[unstable(feature = "new_range_api", issue = "125687")]
584unsafe impl<T> SliceIndex<[T]> for range::RangeFrom<usize> {
585 type Output = [T];
586
587 #[inline]
588 fn get(self, slice: &[T]) -> Option<&[T]> {
589 ops::RangeFrom::from(self).get(slice)
590 }
591
592 #[inline]
593 fn get_mut(self, slice: &mut [T]) -> Option<&mut [T]> {
594 ops::RangeFrom::from(self).get_mut(slice)
595 }
596
597 #[inline]
598 unsafe fn get_unchecked(self, slice: *const [T]) -> *const [T] {
599 unsafe { ops::RangeFrom::from(self).get_unchecked(slice) }
601 }
602
603 #[inline]
604 unsafe fn get_unchecked_mut(self, slice: *mut [T]) -> *mut [T] {
605 unsafe { ops::RangeFrom::from(self).get_unchecked_mut(slice) }
607 }
608
609 #[inline]
610 fn index(self, slice: &[T]) -> &[T] {
611 ops::RangeFrom::from(self).index(slice)
612 }
613
614 #[inline]
615 fn index_mut(self, slice: &mut [T]) -> &mut [T] {
616 ops::RangeFrom::from(self).index_mut(slice)
617 }
618}
619
620#[stable(feature = "slice_get_slice_impls", since = "1.15.0")]
621unsafe impl<T> SliceIndex<[T]> for ops::RangeFull {
622 type Output = [T];
623
624 #[inline]
625 fn get(self, slice: &[T]) -> Option<&[T]> {
626 Some(slice)
627 }
628
629 #[inline]
630 fn get_mut(self, slice: &mut [T]) -> Option<&mut [T]> {
631 Some(slice)
632 }
633
634 #[inline]
635 unsafe fn get_unchecked(self, slice: *const [T]) -> *const [T] {
636 slice
637 }
638
639 #[inline]
640 unsafe fn get_unchecked_mut(self, slice: *mut [T]) -> *mut [T] {
641 slice
642 }
643
644 #[inline]
645 fn index(self, slice: &[T]) -> &[T] {
646 slice
647 }
648
649 #[inline]
650 fn index_mut(self, slice: &mut [T]) -> &mut [T] {
651 slice
652 }
653}
654
655#[stable(feature = "inclusive_range", since = "1.26.0")]
660unsafe impl<T> SliceIndex<[T]> for ops::RangeInclusive<usize> {
661 type Output = [T];
662
663 #[inline]
664 fn get(self, slice: &[T]) -> Option<&[T]> {
665 if *self.end() == usize::MAX { None } else { self.into_slice_range().get(slice) }
666 }
667
668 #[inline]
669 fn get_mut(self, slice: &mut [T]) -> Option<&mut [T]> {
670 if *self.end() == usize::MAX { None } else { self.into_slice_range().get_mut(slice) }
671 }
672
673 #[inline]
674 unsafe fn get_unchecked(self, slice: *const [T]) -> *const [T] {
675 unsafe { self.into_slice_range().get_unchecked(slice) }
677 }
678
679 #[inline]
680 unsafe fn get_unchecked_mut(self, slice: *mut [T]) -> *mut [T] {
681 unsafe { self.into_slice_range().get_unchecked_mut(slice) }
683 }
684
685 #[inline]
686 fn index(self, slice: &[T]) -> &[T] {
687 if *self.end() == usize::MAX {
688 slice_end_index_overflow_fail();
689 }
690 self.into_slice_range().index(slice)
691 }
692
693 #[inline]
694 fn index_mut(self, slice: &mut [T]) -> &mut [T] {
695 if *self.end() == usize::MAX {
696 slice_end_index_overflow_fail();
697 }
698 self.into_slice_range().index_mut(slice)
699 }
700}
701
702#[unstable(feature = "new_range_api", issue = "125687")]
703unsafe impl<T> SliceIndex<[T]> for range::RangeInclusive<usize> {
704 type Output = [T];
705
706 #[inline]
707 fn get(self, slice: &[T]) -> Option<&[T]> {
708 ops::RangeInclusive::from(self).get(slice)
709 }
710
711 #[inline]
712 fn get_mut(self, slice: &mut [T]) -> Option<&mut [T]> {
713 ops::RangeInclusive::from(self).get_mut(slice)
714 }
715
716 #[inline]
717 unsafe fn get_unchecked(self, slice: *const [T]) -> *const [T] {
718 unsafe { ops::RangeInclusive::from(self).get_unchecked(slice) }
720 }
721
722 #[inline]
723 unsafe fn get_unchecked_mut(self, slice: *mut [T]) -> *mut [T] {
724 unsafe { ops::RangeInclusive::from(self).get_unchecked_mut(slice) }
726 }
727
728 #[inline]
729 fn index(self, slice: &[T]) -> &[T] {
730 ops::RangeInclusive::from(self).index(slice)
731 }
732
733 #[inline]
734 fn index_mut(self, slice: &mut [T]) -> &mut [T] {
735 ops::RangeInclusive::from(self).index_mut(slice)
736 }
737}
738
739#[stable(feature = "inclusive_range", since = "1.26.0")]
741unsafe impl<T> SliceIndex<[T]> for ops::RangeToInclusive<usize> {
742 type Output = [T];
743
744 #[inline]
745 fn get(self, slice: &[T]) -> Option<&[T]> {
746 (0..=self.end).get(slice)
747 }
748
749 #[inline]
750 fn get_mut(self, slice: &mut [T]) -> Option<&mut [T]> {
751 (0..=self.end).get_mut(slice)
752 }
753
754 #[inline]
755 unsafe fn get_unchecked(self, slice: *const [T]) -> *const [T] {
756 unsafe { (0..=self.end).get_unchecked(slice) }
758 }
759
760 #[inline]
761 unsafe fn get_unchecked_mut(self, slice: *mut [T]) -> *mut [T] {
762 unsafe { (0..=self.end).get_unchecked_mut(slice) }
764 }
765
766 #[inline]
767 fn index(self, slice: &[T]) -> &[T] {
768 (0..=self.end).index(slice)
769 }
770
771 #[inline]
772 fn index_mut(self, slice: &mut [T]) -> &mut [T] {
773 (0..=self.end).index_mut(slice)
774 }
775}
776
777#[track_caller]
839#[unstable(feature = "slice_range", issue = "76393")]
840#[must_use]
841pub fn range<R>(range: R, bounds: ops::RangeTo<usize>) -> ops::Range<usize>
842where
843 R: ops::RangeBounds<usize>,
844{
845 let len = bounds.end;
846
847 let start = match range.start_bound() {
848 ops::Bound::Included(&start) => start,
849 ops::Bound::Excluded(start) => {
850 start.checked_add(1).unwrap_or_else(|| slice_start_index_overflow_fail())
851 }
852 ops::Bound::Unbounded => 0,
853 };
854
855 let end = match range.end_bound() {
856 ops::Bound::Included(end) => {
857 end.checked_add(1).unwrap_or_else(|| slice_end_index_overflow_fail())
858 }
859 ops::Bound::Excluded(&end) => end,
860 ops::Bound::Unbounded => len,
861 };
862
863 if start > end {
864 slice_index_order_fail(start, end);
865 }
866 if end > len {
867 slice_end_index_len_fail(end, len);
868 }
869
870 ops::Range { start, end }
871}
872
873#[unstable(feature = "slice_range", issue = "76393")]
904#[must_use]
905pub fn try_range<R>(range: R, bounds: ops::RangeTo<usize>) -> Option<ops::Range<usize>>
906where
907 R: ops::RangeBounds<usize>,
908{
909 let len = bounds.end;
910
911 let start = match range.start_bound() {
912 ops::Bound::Included(&start) => start,
913 ops::Bound::Excluded(start) => start.checked_add(1)?,
914 ops::Bound::Unbounded => 0,
915 };
916
917 let end = match range.end_bound() {
918 ops::Bound::Included(end) => end.checked_add(1)?,
919 ops::Bound::Excluded(&end) => end,
920 ops::Bound::Unbounded => len,
921 };
922
923 if start > end || end > len { None } else { Some(ops::Range { start, end }) }
924}
925
926pub(crate) fn into_range_unchecked(
929 len: usize,
930 (start, end): (ops::Bound<usize>, ops::Bound<usize>),
931) -> ops::Range<usize> {
932 use ops::Bound;
933 let start = match start {
934 Bound::Included(i) => i,
935 Bound::Excluded(i) => i + 1,
936 Bound::Unbounded => 0,
937 };
938 let end = match end {
939 Bound::Included(i) => i + 1,
940 Bound::Excluded(i) => i,
941 Bound::Unbounded => len,
942 };
943 start..end
944}
945
946pub(crate) fn into_range(
949 len: usize,
950 (start, end): (ops::Bound<usize>, ops::Bound<usize>),
951) -> Option<ops::Range<usize>> {
952 use ops::Bound;
953 let start = match start {
954 Bound::Included(start) => start,
955 Bound::Excluded(start) => start.checked_add(1)?,
956 Bound::Unbounded => 0,
957 };
958
959 let end = match end {
960 Bound::Included(end) => end.checked_add(1)?,
961 Bound::Excluded(end) => end,
962 Bound::Unbounded => len,
963 };
964
965 Some(start..end)
969}
970
971pub(crate) fn into_slice_range(
974 len: usize,
975 (start, end): (ops::Bound<usize>, ops::Bound<usize>),
976) -> ops::Range<usize> {
977 use ops::Bound;
978 let start = match start {
979 Bound::Included(start) => start,
980 Bound::Excluded(start) => {
981 start.checked_add(1).unwrap_or_else(|| slice_start_index_overflow_fail())
982 }
983 Bound::Unbounded => 0,
984 };
985
986 let end = match end {
987 Bound::Included(end) => {
988 end.checked_add(1).unwrap_or_else(|| slice_end_index_overflow_fail())
989 }
990 Bound::Excluded(end) => end,
991 Bound::Unbounded => len,
992 };
993
994 start..end
998}
999
1000#[stable(feature = "slice_index_with_ops_bound_pair", since = "1.53.0")]
1001unsafe impl<T> SliceIndex<[T]> for (ops::Bound<usize>, ops::Bound<usize>) {
1002 type Output = [T];
1003
1004 #[inline]
1005 fn get(self, slice: &[T]) -> Option<&Self::Output> {
1006 into_range(slice.len(), self)?.get(slice)
1007 }
1008
1009 #[inline]
1010 fn get_mut(self, slice: &mut [T]) -> Option<&mut Self::Output> {
1011 into_range(slice.len(), self)?.get_mut(slice)
1012 }
1013
1014 #[inline]
1015 unsafe fn get_unchecked(self, slice: *const [T]) -> *const Self::Output {
1016 unsafe { into_range_unchecked(slice.len(), self).get_unchecked(slice) }
1018 }
1019
1020 #[inline]
1021 unsafe fn get_unchecked_mut(self, slice: *mut [T]) -> *mut Self::Output {
1022 unsafe { into_range_unchecked(slice.len(), self).get_unchecked_mut(slice) }
1024 }
1025
1026 #[inline]
1027 fn index(self, slice: &[T]) -> &Self::Output {
1028 into_slice_range(slice.len(), self).index(slice)
1029 }
1030
1031 #[inline]
1032 fn index_mut(self, slice: &mut [T]) -> &mut Self::Output {
1033 into_slice_range(slice.len(), self).index_mut(slice)
1034 }
1035}