1 //! Indexing implementations for `[T]`.
3 use crate::intrinsics::assert_unsafe_precondition;
4 use crate::intrinsics::const_eval_select;
8 #[stable(feature = "rust1", since = "1.0.0")]
9 #[rustc_const_unstable(feature = "const_slice_index", issue = "none")]
10 impl<T, I> const ops::Index<I> for [T]
12 I: ~const SliceIndex<[T]>,
14 type Output = I::Output;
17 fn index(&self, index: I) -> &I::Output {
22 #[stable(feature = "rust1", since = "1.0.0")]
23 #[rustc_const_unstable(feature = "const_slice_index", issue = "none")]
24 impl<T, I> const ops::IndexMut<I> for [T]
26 I: ~const SliceIndex<[T]>,
29 fn index_mut(&mut self, index: I) -> &mut I::Output {
34 #[cfg_attr(not(feature = "panic_immediate_abort"), inline(never))]
35 #[cfg_attr(feature = "panic_immediate_abort", inline)]
38 #[rustc_const_unstable(feature = "const_slice_index", issue = "none")]
39 const fn slice_start_index_len_fail(index: usize, len: usize) -> ! {
40 // SAFETY: we are just panicking here
44 slice_start_index_len_fail_ct,
45 slice_start_index_len_fail_rt,
52 fn slice_start_index_len_fail_rt(index: usize, len: usize) -> ! {
53 panic!("range start index {index} out of range for slice of length {len}");
57 const fn slice_start_index_len_fail_ct(_: usize, _: usize) -> ! {
58 panic!("slice start index is out of range for slice");
61 #[cfg_attr(not(feature = "panic_immediate_abort"), inline(never))]
62 #[cfg_attr(feature = "panic_immediate_abort", inline)]
65 #[rustc_const_unstable(feature = "const_slice_index", issue = "none")]
66 const fn slice_end_index_len_fail(index: usize, len: usize) -> ! {
67 // SAFETY: we are just panicking here
69 const_eval_select((index, len), slice_end_index_len_fail_ct, slice_end_index_len_fail_rt)
75 fn slice_end_index_len_fail_rt(index: usize, len: usize) -> ! {
76 panic!("range end index {index} out of range for slice of length {len}");
80 const fn slice_end_index_len_fail_ct(_: usize, _: usize) -> ! {
81 panic!("slice end index is out of range for slice");
84 #[cfg_attr(not(feature = "panic_immediate_abort"), inline(never))]
85 #[cfg_attr(feature = "panic_immediate_abort", inline)]
88 #[rustc_const_unstable(feature = "const_slice_index", issue = "none")]
89 const fn slice_index_order_fail(index: usize, end: usize) -> ! {
90 // SAFETY: we are just panicking here
91 unsafe { const_eval_select((index, end), slice_index_order_fail_ct, slice_index_order_fail_rt) }
96 fn slice_index_order_fail_rt(index: usize, end: usize) -> ! {
97 panic!("slice index starts at {index} but ends at {end}");
101 const fn slice_index_order_fail_ct(_: usize, _: usize) -> ! {
102 panic!("slice index start is larger than end");
105 #[cfg_attr(not(feature = "panic_immediate_abort"), inline(never))]
106 #[cfg_attr(feature = "panic_immediate_abort", inline)]
109 const fn slice_start_index_overflow_fail() -> ! {
110 panic!("attempted to index slice from after maximum usize");
113 #[cfg_attr(not(feature = "panic_immediate_abort"), inline(never))]
114 #[cfg_attr(feature = "panic_immediate_abort", inline)]
117 const fn slice_end_index_overflow_fail() -> ! {
118 panic!("attempted to index slice up to maximum usize");
121 mod private_slice_index {
123 #[stable(feature = "slice_get_slice", since = "1.28.0")]
126 #[stable(feature = "slice_get_slice", since = "1.28.0")]
127 impl Sealed for usize {}
128 #[stable(feature = "slice_get_slice", since = "1.28.0")]
129 impl Sealed for ops::Range<usize> {}
130 #[stable(feature = "slice_get_slice", since = "1.28.0")]
131 impl Sealed for ops::RangeTo<usize> {}
132 #[stable(feature = "slice_get_slice", since = "1.28.0")]
133 impl Sealed for ops::RangeFrom<usize> {}
134 #[stable(feature = "slice_get_slice", since = "1.28.0")]
135 impl Sealed for ops::RangeFull {}
136 #[stable(feature = "slice_get_slice", since = "1.28.0")]
137 impl Sealed for ops::RangeInclusive<usize> {}
138 #[stable(feature = "slice_get_slice", since = "1.28.0")]
139 impl Sealed for ops::RangeToInclusive<usize> {}
140 #[stable(feature = "slice_index_with_ops_bound_pair", since = "1.53.0")]
141 impl Sealed for (ops::Bound<usize>, ops::Bound<usize>) {}
143 impl Sealed for ops::IndexRange {}
146 /// A helper trait used for indexing operations.
148 /// Implementations of this trait have to promise that if the argument
149 /// to `get_unchecked(_mut)` is a safe reference, then so is the result.
150 #[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`",),
155 all(any(T = "str", T = "&str", T = "std::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>"
160 message = "the type `{T}` cannot be indexed by `{Self}`",
161 label = "slice indices are of type `usize` or ranges of `usize`"
164 pub unsafe trait SliceIndex<T: ?Sized>: private_slice_index::Sealed {
165 /// The output type returned by methods.
166 #[stable(feature = "slice_get_slice", since = "1.28.0")]
169 /// Returns a shared reference to the output at this location, if in
171 #[unstable(feature = "slice_index_methods", issue = "none")]
172 fn get(self, slice: &T) -> Option<&Self::Output>;
174 /// Returns a mutable reference to the output at this location, if in
176 #[unstable(feature = "slice_index_methods", issue = "none")]
177 fn get_mut(self, slice: &mut T) -> Option<&mut Self::Output>;
179 /// Returns a shared reference to the output at this location, without
180 /// performing any bounds checking.
181 /// Calling this method with an out-of-bounds index or a dangling `slice` pointer
182 /// is *[undefined behavior]* even if the resulting reference is not used.
184 /// [undefined behavior]: https://doc.rust-lang.org/reference/behavior-considered-undefined.html
185 #[unstable(feature = "slice_index_methods", issue = "none")]
186 unsafe fn get_unchecked(self, slice: *const T) -> *const Self::Output;
188 /// Returns a mutable reference to the output at this location, without
189 /// performing any bounds checking.
190 /// Calling this method with an out-of-bounds index or a dangling `slice` pointer
191 /// is *[undefined behavior]* even if the resulting reference is not used.
193 /// [undefined behavior]: https://doc.rust-lang.org/reference/behavior-considered-undefined.html
194 #[unstable(feature = "slice_index_methods", issue = "none")]
195 unsafe fn get_unchecked_mut(self, slice: *mut T) -> *mut Self::Output;
197 /// Returns a shared reference to the output at this location, panicking
198 /// if out of bounds.
199 #[unstable(feature = "slice_index_methods", issue = "none")]
201 fn index(self, slice: &T) -> &Self::Output;
203 /// Returns a mutable reference to the output at this location, panicking
204 /// if out of bounds.
205 #[unstable(feature = "slice_index_methods", issue = "none")]
207 fn index_mut(self, slice: &mut T) -> &mut Self::Output;
210 #[stable(feature = "slice_get_slice_impls", since = "1.15.0")]
211 #[rustc_const_unstable(feature = "const_slice_index", issue = "none")]
212 unsafe impl<T> const SliceIndex<[T]> for usize {
216 fn get(self, slice: &[T]) -> Option<&T> {
217 // SAFETY: `self` is checked to be in bounds.
218 if self < slice.len() { unsafe { Some(&*self.get_unchecked(slice)) } } else { None }
222 fn get_mut(self, slice: &mut [T]) -> Option<&mut T> {
223 // SAFETY: `self` is checked to be in bounds.
224 if self < slice.len() { unsafe { Some(&mut *self.get_unchecked_mut(slice)) } } else { None }
228 unsafe fn get_unchecked(self, slice: *const [T]) -> *const T {
230 // SAFETY: the caller guarantees that `slice` is not dangling, so it
231 // cannot be longer than `isize::MAX`. They also guarantee that
232 // `self` is in bounds of `slice` so `self` cannot overflow an `isize`,
233 // so the call to `add` is safe.
235 assert_unsafe_precondition!(
236 "slice::get_unchecked requires that the index is within the slice",
237 [T](this: usize, slice: *const [T]) => this < slice.len()
239 slice.as_ptr().add(self)
244 unsafe fn get_unchecked_mut(self, slice: *mut [T]) -> *mut T {
246 // SAFETY: see comments for `get_unchecked` above.
248 assert_unsafe_precondition!(
249 "slice::get_unchecked_mut requires that the index is within the slice",
250 [T](this: usize, slice: *mut [T]) => this < slice.len()
252 slice.as_mut_ptr().add(self)
257 fn index(self, slice: &[T]) -> &T {
258 // N.B., use intrinsic indexing
263 fn index_mut(self, slice: &mut [T]) -> &mut T {
264 // N.B., use intrinsic indexing
269 /// Because `IndexRange` guarantees `start <= end`, fewer checks are needed here
270 /// than there are for a general `Range<usize>` (which might be `100..3`).
271 #[rustc_const_unstable(feature = "const_index_range_slice_index", issue = "none")]
272 unsafe impl<T> const SliceIndex<[T]> for ops::IndexRange {
276 fn get(self, slice: &[T]) -> Option<&[T]> {
277 if self.end() <= slice.len() {
278 // SAFETY: `self` is checked to be valid and in bounds above.
279 unsafe { Some(&*self.get_unchecked(slice)) }
286 fn get_mut(self, slice: &mut [T]) -> Option<&mut [T]> {
287 if self.end() <= slice.len() {
288 // SAFETY: `self` is checked to be valid and in bounds above.
289 unsafe { Some(&mut *self.get_unchecked_mut(slice)) }
296 unsafe fn get_unchecked(self, slice: *const [T]) -> *const [T] {
297 let end = self.end();
298 // SAFETY: the caller guarantees that `slice` is not dangling, so it
299 // cannot be longer than `isize::MAX`. They also guarantee that
300 // `self` is in bounds of `slice` so `self` cannot overflow an `isize`,
301 // so the call to `add` is safe.
304 assert_unsafe_precondition!(
305 "slice::get_unchecked requires that the index is within the slice",
306 [T](end: usize, slice: *const [T]) => end <= slice.len()
308 ptr::slice_from_raw_parts(slice.as_ptr().add(self.start()), self.len())
313 unsafe fn get_unchecked_mut(self, slice: *mut [T]) -> *mut [T] {
314 let end = self.end();
315 // SAFETY: see comments for `get_unchecked` above.
317 assert_unsafe_precondition!(
318 "slice::get_unchecked_mut requires that the index is within the slice",
319 [T](end: usize, slice: *mut [T]) => end <= slice.len()
321 ptr::slice_from_raw_parts_mut(slice.as_mut_ptr().add(self.start()), self.len())
326 fn index(self, slice: &[T]) -> &[T] {
327 if self.end() <= slice.len() {
328 // SAFETY: `self` is checked to be valid and in bounds above.
329 unsafe { &*self.get_unchecked(slice) }
331 slice_end_index_len_fail(self.end(), slice.len())
336 fn index_mut(self, slice: &mut [T]) -> &mut [T] {
337 if self.end() <= slice.len() {
338 // SAFETY: `self` is checked to be valid and in bounds above.
339 unsafe { &mut *self.get_unchecked_mut(slice) }
341 slice_end_index_len_fail(self.end(), slice.len())
346 #[stable(feature = "slice_get_slice_impls", since = "1.15.0")]
347 #[rustc_const_unstable(feature = "const_slice_index", issue = "none")]
348 unsafe impl<T> const SliceIndex<[T]> for ops::Range<usize> {
352 fn get(self, slice: &[T]) -> Option<&[T]> {
353 if self.start > self.end || self.end > slice.len() {
356 // SAFETY: `self` is checked to be valid and in bounds above.
357 unsafe { Some(&*self.get_unchecked(slice)) }
362 fn get_mut(self, slice: &mut [T]) -> Option<&mut [T]> {
363 if self.start > self.end || self.end > slice.len() {
366 // SAFETY: `self` is checked to be valid and in bounds above.
367 unsafe { Some(&mut *self.get_unchecked_mut(slice)) }
372 unsafe fn get_unchecked(self, slice: *const [T]) -> *const [T] {
373 let this = ops::Range { start: self.start, end: self.end };
374 // SAFETY: the caller guarantees that `slice` is not dangling, so it
375 // cannot be longer than `isize::MAX`. They also guarantee that
376 // `self` is in bounds of `slice` so `self` cannot overflow an `isize`,
377 // so the call to `add` is safe.
380 assert_unsafe_precondition!(
381 "slice::get_unchecked requires that the range is within the slice",
382 [T](this: ops::Range<usize>, slice: *const [T]) =>
383 this.end >= this.start && this.end <= slice.len()
385 ptr::slice_from_raw_parts(slice.as_ptr().add(self.start), self.end - self.start)
390 unsafe fn get_unchecked_mut(self, slice: *mut [T]) -> *mut [T] {
391 let this = ops::Range { start: self.start, end: self.end };
392 // SAFETY: see comments for `get_unchecked` above.
394 assert_unsafe_precondition!(
395 "slice::get_unchecked_mut requires that the range is within the slice",
396 [T](this: ops::Range<usize>, slice: *mut [T]) =>
397 this.end >= this.start && this.end <= slice.len()
399 ptr::slice_from_raw_parts_mut(slice.as_mut_ptr().add(self.start), self.end - self.start)
404 fn index(self, slice: &[T]) -> &[T] {
405 if self.start > self.end {
406 slice_index_order_fail(self.start, self.end);
407 } else if self.end > slice.len() {
408 slice_end_index_len_fail(self.end, slice.len());
410 // SAFETY: `self` is checked to be valid and in bounds above.
411 unsafe { &*self.get_unchecked(slice) }
415 fn index_mut(self, slice: &mut [T]) -> &mut [T] {
416 if self.start > self.end {
417 slice_index_order_fail(self.start, self.end);
418 } else if self.end > slice.len() {
419 slice_end_index_len_fail(self.end, slice.len());
421 // SAFETY: `self` is checked to be valid and in bounds above.
422 unsafe { &mut *self.get_unchecked_mut(slice) }
426 #[stable(feature = "slice_get_slice_impls", since = "1.15.0")]
427 #[rustc_const_unstable(feature = "const_slice_index", issue = "none")]
428 unsafe impl<T> const SliceIndex<[T]> for ops::RangeTo<usize> {
432 fn get(self, slice: &[T]) -> Option<&[T]> {
433 (0..self.end).get(slice)
437 fn get_mut(self, slice: &mut [T]) -> Option<&mut [T]> {
438 (0..self.end).get_mut(slice)
442 unsafe fn get_unchecked(self, slice: *const [T]) -> *const [T] {
443 // SAFETY: the caller has to uphold the safety contract for `get_unchecked`.
444 unsafe { (0..self.end).get_unchecked(slice) }
448 unsafe fn get_unchecked_mut(self, slice: *mut [T]) -> *mut [T] {
449 // SAFETY: the caller has to uphold the safety contract for `get_unchecked_mut`.
450 unsafe { (0..self.end).get_unchecked_mut(slice) }
454 fn index(self, slice: &[T]) -> &[T] {
455 (0..self.end).index(slice)
459 fn index_mut(self, slice: &mut [T]) -> &mut [T] {
460 (0..self.end).index_mut(slice)
464 #[stable(feature = "slice_get_slice_impls", since = "1.15.0")]
465 #[rustc_const_unstable(feature = "const_slice_index", issue = "none")]
466 unsafe impl<T> const SliceIndex<[T]> for ops::RangeFrom<usize> {
470 fn get(self, slice: &[T]) -> Option<&[T]> {
471 (self.start..slice.len()).get(slice)
475 fn get_mut(self, slice: &mut [T]) -> Option<&mut [T]> {
476 (self.start..slice.len()).get_mut(slice)
480 unsafe fn get_unchecked(self, slice: *const [T]) -> *const [T] {
481 // SAFETY: the caller has to uphold the safety contract for `get_unchecked`.
482 unsafe { (self.start..slice.len()).get_unchecked(slice) }
486 unsafe fn get_unchecked_mut(self, slice: *mut [T]) -> *mut [T] {
487 // SAFETY: the caller has to uphold the safety contract for `get_unchecked_mut`.
488 unsafe { (self.start..slice.len()).get_unchecked_mut(slice) }
492 fn index(self, slice: &[T]) -> &[T] {
493 if self.start > slice.len() {
494 slice_start_index_len_fail(self.start, slice.len());
496 // SAFETY: `self` is checked to be valid and in bounds above.
497 unsafe { &*self.get_unchecked(slice) }
501 fn index_mut(self, slice: &mut [T]) -> &mut [T] {
502 if self.start > slice.len() {
503 slice_start_index_len_fail(self.start, slice.len());
505 // SAFETY: `self` is checked to be valid and in bounds above.
506 unsafe { &mut *self.get_unchecked_mut(slice) }
510 #[stable(feature = "slice_get_slice_impls", since = "1.15.0")]
511 #[rustc_const_unstable(feature = "const_slice_index", issue = "none")]
512 unsafe impl<T> const SliceIndex<[T]> for ops::RangeFull {
516 fn get(self, slice: &[T]) -> Option<&[T]> {
521 fn get_mut(self, slice: &mut [T]) -> Option<&mut [T]> {
526 unsafe fn get_unchecked(self, slice: *const [T]) -> *const [T] {
531 unsafe fn get_unchecked_mut(self, slice: *mut [T]) -> *mut [T] {
536 fn index(self, slice: &[T]) -> &[T] {
541 fn index_mut(self, slice: &mut [T]) -> &mut [T] {
546 #[stable(feature = "inclusive_range", since = "1.26.0")]
547 #[rustc_const_unstable(feature = "const_slice_index", issue = "none")]
548 unsafe impl<T> const SliceIndex<[T]> for ops::RangeInclusive<usize> {
552 fn get(self, slice: &[T]) -> Option<&[T]> {
553 if *self.end() == usize::MAX { None } else { self.into_slice_range().get(slice) }
557 fn get_mut(self, slice: &mut [T]) -> Option<&mut [T]> {
558 if *self.end() == usize::MAX { None } else { self.into_slice_range().get_mut(slice) }
562 unsafe fn get_unchecked(self, slice: *const [T]) -> *const [T] {
563 // SAFETY: the caller has to uphold the safety contract for `get_unchecked`.
564 unsafe { self.into_slice_range().get_unchecked(slice) }
568 unsafe fn get_unchecked_mut(self, slice: *mut [T]) -> *mut [T] {
569 // SAFETY: the caller has to uphold the safety contract for `get_unchecked_mut`.
570 unsafe { self.into_slice_range().get_unchecked_mut(slice) }
574 fn index(self, slice: &[T]) -> &[T] {
575 if *self.end() == usize::MAX {
576 slice_end_index_overflow_fail();
578 self.into_slice_range().index(slice)
582 fn index_mut(self, slice: &mut [T]) -> &mut [T] {
583 if *self.end() == usize::MAX {
584 slice_end_index_overflow_fail();
586 self.into_slice_range().index_mut(slice)
590 #[stable(feature = "inclusive_range", since = "1.26.0")]
591 #[rustc_const_unstable(feature = "const_slice_index", issue = "none")]
592 unsafe impl<T> const SliceIndex<[T]> for ops::RangeToInclusive<usize> {
596 fn get(self, slice: &[T]) -> Option<&[T]> {
597 (0..=self.end).get(slice)
601 fn get_mut(self, slice: &mut [T]) -> Option<&mut [T]> {
602 (0..=self.end).get_mut(slice)
606 unsafe fn get_unchecked(self, slice: *const [T]) -> *const [T] {
607 // SAFETY: the caller has to uphold the safety contract for `get_unchecked`.
608 unsafe { (0..=self.end).get_unchecked(slice) }
612 unsafe fn get_unchecked_mut(self, slice: *mut [T]) -> *mut [T] {
613 // SAFETY: the caller has to uphold the safety contract for `get_unchecked_mut`.
614 unsafe { (0..=self.end).get_unchecked_mut(slice) }
618 fn index(self, slice: &[T]) -> &[T] {
619 (0..=self.end).index(slice)
623 fn index_mut(self, slice: &mut [T]) -> &mut [T] {
624 (0..=self.end).index_mut(slice)
628 /// Performs bounds-checking of a range.
630 /// This method is similar to [`Index::index`] for slices, but it returns a
631 /// [`Range`] equivalent to `range`. You can use this method to turn any range
632 /// into `start` and `end` values.
634 /// `bounds` is the range of the slice to use for bounds-checking. It should
635 /// be a [`RangeTo`] range that ends at the length of the slice.
637 /// The returned [`Range`] is safe to pass to [`slice::get_unchecked`] and
638 /// [`slice::get_unchecked_mut`] for slices with the given range.
640 /// [`Range`]: ops::Range
641 /// [`RangeTo`]: ops::RangeTo
642 /// [`slice::get_unchecked`]: slice::get_unchecked
643 /// [`slice::get_unchecked_mut`]: slice::get_unchecked_mut
647 /// Panics if `range` would be out of bounds.
652 /// #![feature(slice_range)]
656 /// let v = [10, 40, 30];
657 /// assert_eq!(1..2, slice::range(1..2, ..v.len()));
658 /// assert_eq!(0..2, slice::range(..2, ..v.len()));
659 /// assert_eq!(1..3, slice::range(1.., ..v.len()));
662 /// Panics when [`Index::index`] would panic:
665 /// #![feature(slice_range)]
669 /// let _ = slice::range(2..1, ..3);
673 /// #![feature(slice_range)]
677 /// let _ = slice::range(1..4, ..3);
681 /// #![feature(slice_range)]
685 /// let _ = slice::range(1..=usize::MAX, ..3);
688 /// [`Index::index`]: ops::Index::index
690 #[unstable(feature = "slice_range", issue = "76393")]
692 pub fn range<R>(range: R, bounds: ops::RangeTo<usize>) -> ops::Range<usize>
694 R: ops::RangeBounds<usize>,
696 let len = bounds.end;
698 let start: ops::Bound<&usize> = range.start_bound();
699 let start = match start {
700 ops::Bound::Included(&start) => start,
701 ops::Bound::Excluded(start) => {
702 start.checked_add(1).unwrap_or_else(|| slice_start_index_overflow_fail())
704 ops::Bound::Unbounded => 0,
707 let end: ops::Bound<&usize> = range.end_bound();
708 let end = match end {
709 ops::Bound::Included(end) => {
710 end.checked_add(1).unwrap_or_else(|| slice_end_index_overflow_fail())
712 ops::Bound::Excluded(&end) => end,
713 ops::Bound::Unbounded => len,
717 slice_index_order_fail(start, end);
720 slice_end_index_len_fail(end, len);
723 ops::Range { start, end }
726 /// Convert pair of `ops::Bound`s into `ops::Range` without performing any bounds checking and (in debug) overflow checking
727 fn into_range_unchecked(
729 (start, end): (ops::Bound<usize>, ops::Bound<usize>),
730 ) -> ops::Range<usize> {
732 let start = match start {
733 Bound::Included(i) => i,
734 Bound::Excluded(i) => i + 1,
735 Bound::Unbounded => 0,
737 let end = match end {
738 Bound::Included(i) => i + 1,
739 Bound::Excluded(i) => i,
740 Bound::Unbounded => len,
745 /// Convert pair of `ops::Bound`s into `ops::Range`.
746 /// Returns `None` on overflowing indices.
749 (start, end): (ops::Bound<usize>, ops::Bound<usize>),
750 ) -> Option<ops::Range<usize>> {
752 let start = match start {
753 Bound::Included(start) => start,
754 Bound::Excluded(start) => start.checked_add(1)?,
755 Bound::Unbounded => 0,
758 let end = match end {
759 Bound::Included(end) => end.checked_add(1)?,
760 Bound::Excluded(end) => end,
761 Bound::Unbounded => len,
764 // Don't bother with checking `start < end` and `end <= len`
765 // since these checks are handled by `Range` impls
770 /// Convert pair of `ops::Bound`s into `ops::Range`.
771 /// Panics on overflowing indices.
774 (start, end): (ops::Bound<usize>, ops::Bound<usize>),
775 ) -> ops::Range<usize> {
777 let start = match start {
778 Bound::Included(start) => start,
779 Bound::Excluded(start) => {
780 start.checked_add(1).unwrap_or_else(|| slice_start_index_overflow_fail())
782 Bound::Unbounded => 0,
785 let end = match end {
786 Bound::Included(end) => {
787 end.checked_add(1).unwrap_or_else(|| slice_end_index_overflow_fail())
789 Bound::Excluded(end) => end,
790 Bound::Unbounded => len,
793 // Don't bother with checking `start < end` and `end <= len`
794 // since these checks are handled by `Range` impls
799 #[stable(feature = "slice_index_with_ops_bound_pair", since = "1.53.0")]
800 unsafe impl<T> SliceIndex<[T]> for (ops::Bound<usize>, ops::Bound<usize>) {
804 fn get(self, slice: &[T]) -> Option<&Self::Output> {
805 into_range(slice.len(), self)?.get(slice)
809 fn get_mut(self, slice: &mut [T]) -> Option<&mut Self::Output> {
810 into_range(slice.len(), self)?.get_mut(slice)
814 unsafe fn get_unchecked(self, slice: *const [T]) -> *const Self::Output {
815 // SAFETY: the caller has to uphold the safety contract for `get_unchecked`.
816 unsafe { into_range_unchecked(slice.len(), self).get_unchecked(slice) }
820 unsafe fn get_unchecked_mut(self, slice: *mut [T]) -> *mut Self::Output {
821 // SAFETY: the caller has to uphold the safety contract for `get_unchecked_mut`.
822 unsafe { into_range_unchecked(slice.len(), self).get_unchecked_mut(slice) }
826 fn index(self, slice: &[T]) -> &Self::Output {
827 into_slice_range(slice.len(), self).index(slice)
831 fn index_mut(self, slice: &mut [T]) -> &mut Self::Output {
832 into_slice_range(slice.len(), self).index_mut(slice)