stdx/
slice.rs

1// SPDX-FileCopyrightText: (c) The Rust Project Contributors
2// SPDX-License-Identifier: Apache-2.0 OR MIT
3// - https://github.com/rust-lang/rust/blob/master/LICENSE-MIT
4//! Unstable Rust code
5use core::ops;
6
7#[track_caller]
8fn slice_end_index_len_fail(index: usize, len: usize) -> ! {
9    panic!(
10        "slice end index is out of range for slice\nrange end index {index} out of range for slice of length {len}",
11    )
12}
13#[track_caller]
14fn slice_index_order_fail(index: usize, end: usize) -> ! {
15    panic!("slice index start is larger than end\nslice index starts at {index} but ends at {end}",)
16}
17#[track_caller]
18const fn slice_start_index_overflow_fail() -> ! {
19    panic!("attempted to index slice from after maximum usize");
20}
21#[track_caller]
22const fn slice_end_index_overflow_fail() -> ! {
23    panic!("attempted to index slice up to maximum usize");
24}
25
26#[track_caller]
27pub fn range<R>(range: R, bounds: ops::RangeTo<usize>) -> ops::Range<usize>
28where
29    R: ops::RangeBounds<usize>,
30{
31    let len = bounds.end;
32
33    let start = match range.start_bound() {
34        ops::Bound::Included(&start) => start,
35        ops::Bound::Excluded(start) => {
36            start.checked_add(1).unwrap_or_else(|| slice_start_index_overflow_fail())
37        }
38        ops::Bound::Unbounded => 0,
39    };
40
41    let end = match range.end_bound() {
42        ops::Bound::Included(end) => {
43            end.checked_add(1).unwrap_or_else(|| slice_end_index_overflow_fail())
44        }
45        ops::Bound::Excluded(&end) => end,
46        ops::Bound::Unbounded => len,
47    };
48
49    if start > end {
50        slice_index_order_fail(start, end);
51    }
52    if end > len {
53        slice_end_index_len_fail(end, len);
54    }
55
56    ops::Range { start, end }
57}