mirror of
https://github.com/rust-lang/rust.git
synced 2026-04-30 06:43:20 +03:00
d2020fbf7c
stabilizes `core::range::RangeInclusive` and `core::range::RangeInclusiveIter` and the `core::range` module
473 lines
16 KiB
Rust
473 lines
16 KiB
Rust
#![unstable(feature = "sliceindex_wrappers", issue = "146179")]
|
|
|
|
//! Helper types for indexing slices.
|
|
|
|
use crate::intrinsics::slice_get_unchecked;
|
|
use crate::slice::SliceIndex;
|
|
use crate::{cmp, ops, range};
|
|
|
|
/// Clamps an index, guaranteeing that it will only access valid elements of the slice.
|
|
///
|
|
/// # Examples
|
|
///
|
|
/// ```
|
|
/// #![feature(sliceindex_wrappers)]
|
|
///
|
|
/// use core::index::Clamp;
|
|
///
|
|
/// let s: &[usize] = &[0, 1, 2, 3];
|
|
///
|
|
/// assert_eq!(&3, &s[Clamp(6)]);
|
|
/// assert_eq!(&[1, 2, 3], &s[Clamp(1..6)]);
|
|
/// assert_eq!(&[] as &[usize], &s[Clamp(5..6)]);
|
|
/// assert_eq!(&[0, 1, 2, 3], &s[Clamp(..6)]);
|
|
/// assert_eq!(&[0, 1, 2, 3], &s[Clamp(..=6)]);
|
|
/// assert_eq!(&[] as &[usize], &s[Clamp(6..)]);
|
|
/// ```
|
|
#[unstable(feature = "sliceindex_wrappers", issue = "146179")]
|
|
#[derive(Debug)]
|
|
pub struct Clamp<Idx>(pub Idx);
|
|
|
|
/// Always accesses the last element of the slice.
|
|
///
|
|
/// # Examples
|
|
///
|
|
/// ```
|
|
/// #![feature(sliceindex_wrappers)]
|
|
/// #![feature(slice_index_methods)]
|
|
///
|
|
/// use core::index::Last;
|
|
/// use core::slice::SliceIndex;
|
|
///
|
|
/// let s = &[0, 1, 2, 3];
|
|
///
|
|
/// assert_eq!(&3, &s[Last]);
|
|
/// assert_eq!(None, Last.get(&[] as &[usize]));
|
|
///
|
|
/// ```
|
|
#[unstable(feature = "sliceindex_wrappers", issue = "146179")]
|
|
#[derive(Debug)]
|
|
pub struct Last;
|
|
|
|
#[unstable(feature = "sliceindex_wrappers", issue = "146179")]
|
|
unsafe impl<T> SliceIndex<[T]> for Clamp<usize> {
|
|
type Output = T;
|
|
|
|
fn get(self, slice: &[T]) -> Option<&Self::Output> {
|
|
slice.get(cmp::min(self.0, slice.len() - 1))
|
|
}
|
|
|
|
fn get_mut(self, slice: &mut [T]) -> Option<&mut Self::Output> {
|
|
slice.get_mut(cmp::min(self.0, slice.len() - 1))
|
|
}
|
|
|
|
unsafe fn get_unchecked(self, slice: *const [T]) -> *const Self::Output {
|
|
// SAFETY: the caller ensures that the slice isn't empty
|
|
unsafe { slice_get_unchecked(slice, cmp::min(self.0, slice.len() - 1)) }
|
|
}
|
|
|
|
unsafe fn get_unchecked_mut(self, slice: *mut [T]) -> *mut Self::Output {
|
|
// SAFETY: the caller ensures that the slice isn't empty
|
|
unsafe { slice_get_unchecked(slice, cmp::min(self.0, slice.len() - 1)) }
|
|
}
|
|
|
|
fn index(self, slice: &[T]) -> &Self::Output {
|
|
&(*slice)[cmp::min(self.0, slice.len() - 1)]
|
|
}
|
|
|
|
fn index_mut(self, slice: &mut [T]) -> &mut Self::Output {
|
|
&mut (*slice)[cmp::min(self.0, slice.len() - 1)]
|
|
}
|
|
}
|
|
|
|
#[unstable(feature = "sliceindex_wrappers", issue = "146179")]
|
|
unsafe impl<T> SliceIndex<[T]> for Clamp<range::Range<usize>> {
|
|
type Output = [T];
|
|
|
|
fn get(self, slice: &[T]) -> Option<&Self::Output> {
|
|
let start = cmp::min(self.0.start, slice.len());
|
|
let end = cmp::min(self.0.end, slice.len());
|
|
(start..end).get(slice)
|
|
}
|
|
|
|
fn get_mut(self, slice: &mut [T]) -> Option<&mut Self::Output> {
|
|
let start = cmp::min(self.0.start, slice.len());
|
|
let end = cmp::min(self.0.end, slice.len());
|
|
(start..end).get_mut(slice)
|
|
}
|
|
|
|
unsafe fn get_unchecked(self, slice: *const [T]) -> *const Self::Output {
|
|
let start = cmp::min(self.0.start, slice.len());
|
|
let end = cmp::min(self.0.end, slice.len());
|
|
// SAFETY: a range ending before len is always valid
|
|
unsafe { (start..end).get_unchecked(slice) }
|
|
}
|
|
|
|
unsafe fn get_unchecked_mut(self, slice: *mut [T]) -> *mut Self::Output {
|
|
let start = cmp::min(self.0.start, slice.len());
|
|
let end = cmp::min(self.0.end, slice.len());
|
|
// SAFETY: a range ending before len is always valid
|
|
unsafe { (start..end).get_unchecked_mut(slice) }
|
|
}
|
|
|
|
fn index(self, slice: &[T]) -> &Self::Output {
|
|
let start = cmp::min(self.0.start, slice.len());
|
|
let end = cmp::min(self.0.end, slice.len());
|
|
(start..end).index(slice)
|
|
}
|
|
|
|
fn index_mut(self, slice: &mut [T]) -> &mut Self::Output {
|
|
let start = cmp::min(self.0.start, slice.len());
|
|
let end = cmp::min(self.0.end, slice.len());
|
|
(start..end).index_mut(slice)
|
|
}
|
|
}
|
|
|
|
#[unstable(feature = "sliceindex_wrappers", issue = "146179")]
|
|
unsafe impl<T> SliceIndex<[T]> for Clamp<ops::Range<usize>> {
|
|
type Output = [T];
|
|
|
|
fn get(self, slice: &[T]) -> Option<&Self::Output> {
|
|
let start = cmp::min(self.0.start, slice.len());
|
|
let end = cmp::min(self.0.end, slice.len());
|
|
(start..end).get(slice)
|
|
}
|
|
|
|
fn get_mut(self, slice: &mut [T]) -> Option<&mut Self::Output> {
|
|
let start = cmp::min(self.0.start, slice.len());
|
|
let end = cmp::min(self.0.end, slice.len());
|
|
(start..end).get_mut(slice)
|
|
}
|
|
|
|
unsafe fn get_unchecked(self, slice: *const [T]) -> *const Self::Output {
|
|
let start = cmp::min(self.0.start, slice.len());
|
|
let end = cmp::min(self.0.end, slice.len());
|
|
// SAFETY: a range ending before len is always valid
|
|
unsafe { (start..end).get_unchecked(slice) }
|
|
}
|
|
|
|
unsafe fn get_unchecked_mut(self, slice: *mut [T]) -> *mut Self::Output {
|
|
let start = cmp::min(self.0.start, slice.len());
|
|
let end = cmp::min(self.0.end, slice.len());
|
|
// SAFETY: a range ending before len is always valid
|
|
unsafe { (start..end).get_unchecked_mut(slice) }
|
|
}
|
|
|
|
fn index(self, slice: &[T]) -> &Self::Output {
|
|
let start = cmp::min(self.0.start, slice.len());
|
|
let end = cmp::min(self.0.end, slice.len());
|
|
(start..end).index(slice)
|
|
}
|
|
|
|
fn index_mut(self, slice: &mut [T]) -> &mut Self::Output {
|
|
let start = cmp::min(self.0.start, slice.len());
|
|
let end = cmp::min(self.0.end, slice.len());
|
|
(start..end).index_mut(slice)
|
|
}
|
|
}
|
|
|
|
#[unstable(feature = "sliceindex_wrappers", issue = "146179")]
|
|
unsafe impl<T> SliceIndex<[T]> for Clamp<range::RangeInclusive<usize>> {
|
|
type Output = [T];
|
|
|
|
fn get(self, slice: &[T]) -> Option<&Self::Output> {
|
|
let start = cmp::min(self.0.start, slice.len() - 1);
|
|
let end = cmp::min(self.0.last, slice.len() - 1);
|
|
(start..=end).get(slice)
|
|
}
|
|
|
|
fn get_mut(self, slice: &mut [T]) -> Option<&mut Self::Output> {
|
|
let start = cmp::min(self.0.start, slice.len() - 1);
|
|
let end = cmp::min(self.0.last, slice.len() - 1);
|
|
(start..=end).get_mut(slice)
|
|
}
|
|
|
|
unsafe fn get_unchecked(self, slice: *const [T]) -> *const Self::Output {
|
|
let start = cmp::min(self.0.start, slice.len() - 1);
|
|
let end = cmp::min(self.0.last, slice.len() - 1);
|
|
// SAFETY: the caller ensures that the slice isn't empty
|
|
unsafe { (start..=end).get_unchecked(slice) }
|
|
}
|
|
|
|
unsafe fn get_unchecked_mut(self, slice: *mut [T]) -> *mut Self::Output {
|
|
let start = cmp::min(self.0.start, slice.len() - 1);
|
|
let end = cmp::min(self.0.last, slice.len() - 1);
|
|
// SAFETY: the caller ensures that the slice isn't empty
|
|
unsafe { (start..=end).get_unchecked_mut(slice) }
|
|
}
|
|
|
|
fn index(self, slice: &[T]) -> &Self::Output {
|
|
let start = cmp::min(self.0.start, slice.len() - 1);
|
|
let end = cmp::min(self.0.last, slice.len() - 1);
|
|
(start..=end).index(slice)
|
|
}
|
|
|
|
fn index_mut(self, slice: &mut [T]) -> &mut Self::Output {
|
|
let start = cmp::min(self.0.start, slice.len() - 1);
|
|
let end = cmp::min(self.0.last, slice.len() - 1);
|
|
(start..=end).index_mut(slice)
|
|
}
|
|
}
|
|
|
|
#[unstable(feature = "sliceindex_wrappers", issue = "146179")]
|
|
unsafe impl<T> SliceIndex<[T]> for Clamp<ops::RangeInclusive<usize>> {
|
|
type Output = [T];
|
|
|
|
fn get(self, slice: &[T]) -> Option<&Self::Output> {
|
|
let start = cmp::min(self.0.start, slice.len() - 1);
|
|
let end = cmp::min(self.0.end, slice.len() - 1);
|
|
(start..=end).get(slice)
|
|
}
|
|
|
|
fn get_mut(self, slice: &mut [T]) -> Option<&mut Self::Output> {
|
|
let start = cmp::min(self.0.start, slice.len() - 1);
|
|
let end = cmp::min(self.0.end, slice.len() - 1);
|
|
(start..=end).get_mut(slice)
|
|
}
|
|
|
|
unsafe fn get_unchecked(self, slice: *const [T]) -> *const Self::Output {
|
|
let start = cmp::min(self.0.start, slice.len() - 1);
|
|
let end = cmp::min(self.0.end, slice.len() - 1);
|
|
// SAFETY: the caller ensures that the slice isn't empty
|
|
unsafe { (start..=end).get_unchecked(slice) }
|
|
}
|
|
|
|
unsafe fn get_unchecked_mut(self, slice: *mut [T]) -> *mut Self::Output {
|
|
let start = cmp::min(self.0.start, slice.len() - 1);
|
|
let end = cmp::min(self.0.end, slice.len() - 1);
|
|
// SAFETY: the caller ensures that the slice isn't empty
|
|
unsafe { (start..=end).get_unchecked_mut(slice) }
|
|
}
|
|
|
|
fn index(self, slice: &[T]) -> &Self::Output {
|
|
let start = cmp::min(self.0.start, slice.len() - 1);
|
|
let end = cmp::min(self.0.end, slice.len() - 1);
|
|
(start..=end).index(slice)
|
|
}
|
|
|
|
fn index_mut(self, slice: &mut [T]) -> &mut Self::Output {
|
|
let start = cmp::min(self.0.start, slice.len() - 1);
|
|
let end = cmp::min(self.0.end, slice.len() - 1);
|
|
(start..=end).index_mut(slice)
|
|
}
|
|
}
|
|
|
|
#[unstable(feature = "sliceindex_wrappers", issue = "146179")]
|
|
unsafe impl<T> SliceIndex<[T]> for Clamp<range::RangeFrom<usize>> {
|
|
type Output = [T];
|
|
|
|
fn get(self, slice: &[T]) -> Option<&Self::Output> {
|
|
(cmp::min(self.0.start, slice.len())..).get(slice)
|
|
}
|
|
|
|
fn get_mut(self, slice: &mut [T]) -> Option<&mut Self::Output> {
|
|
(cmp::min(self.0.start, slice.len())..).get_mut(slice)
|
|
}
|
|
|
|
unsafe fn get_unchecked(self, slice: *const [T]) -> *const Self::Output {
|
|
// SAFETY: a range starting at len is valid
|
|
unsafe { (cmp::min(self.0.start, slice.len())..).get_unchecked(slice) }
|
|
}
|
|
|
|
unsafe fn get_unchecked_mut(self, slice: *mut [T]) -> *mut Self::Output {
|
|
// SAFETY: a range starting at len is valid
|
|
unsafe { (cmp::min(self.0.start, slice.len())..).get_unchecked_mut(slice) }
|
|
}
|
|
|
|
fn index(self, slice: &[T]) -> &Self::Output {
|
|
(cmp::min(self.0.start, slice.len())..).index(slice)
|
|
}
|
|
|
|
fn index_mut(self, slice: &mut [T]) -> &mut Self::Output {
|
|
(cmp::min(self.0.start, slice.len())..).index_mut(slice)
|
|
}
|
|
}
|
|
|
|
#[unstable(feature = "sliceindex_wrappers", issue = "146179")]
|
|
unsafe impl<T> SliceIndex<[T]> for Clamp<ops::RangeFrom<usize>> {
|
|
type Output = [T];
|
|
|
|
fn get(self, slice: &[T]) -> Option<&Self::Output> {
|
|
(cmp::min(self.0.start, slice.len())..).get(slice)
|
|
}
|
|
|
|
fn get_mut(self, slice: &mut [T]) -> Option<&mut Self::Output> {
|
|
(cmp::min(self.0.start, slice.len())..).get_mut(slice)
|
|
}
|
|
|
|
unsafe fn get_unchecked(self, slice: *const [T]) -> *const Self::Output {
|
|
// SAFETY: a range starting at len is valid
|
|
unsafe { (cmp::min(self.0.start, slice.len())..).get_unchecked(slice) }
|
|
}
|
|
|
|
unsafe fn get_unchecked_mut(self, slice: *mut [T]) -> *mut Self::Output {
|
|
// SAFETY: a range starting at len is valid
|
|
unsafe { (cmp::min(self.0.start, slice.len())..).get_unchecked_mut(slice) }
|
|
}
|
|
|
|
fn index(self, slice: &[T]) -> &Self::Output {
|
|
(cmp::min(self.0.start, slice.len())..).index(slice)
|
|
}
|
|
|
|
fn index_mut(self, slice: &mut [T]) -> &mut Self::Output {
|
|
(cmp::min(self.0.start, slice.len())..).index_mut(slice)
|
|
}
|
|
}
|
|
|
|
#[unstable(feature = "sliceindex_wrappers", issue = "146179")]
|
|
unsafe impl<T> SliceIndex<[T]> for Clamp<ops::RangeTo<usize>> {
|
|
type Output = [T];
|
|
|
|
fn get(self, slice: &[T]) -> Option<&Self::Output> {
|
|
(..cmp::min(self.0.end, slice.len())).get(slice)
|
|
}
|
|
|
|
fn get_mut(self, slice: &mut [T]) -> Option<&mut Self::Output> {
|
|
(..cmp::min(self.0.end, slice.len())).get_mut(slice)
|
|
}
|
|
|
|
unsafe fn get_unchecked(self, slice: *const [T]) -> *const Self::Output {
|
|
// SAFETY: a range ending before len is always valid
|
|
unsafe { (..cmp::min(self.0.end, slice.len())).get_unchecked(slice) }
|
|
}
|
|
|
|
unsafe fn get_unchecked_mut(self, slice: *mut [T]) -> *mut Self::Output {
|
|
// SAFETY: a range ending before len is always valid
|
|
unsafe { (..cmp::min(self.0.end, slice.len())).get_unchecked_mut(slice) }
|
|
}
|
|
|
|
fn index(self, slice: &[T]) -> &Self::Output {
|
|
(..cmp::min(self.0.end, slice.len())).index(slice)
|
|
}
|
|
|
|
fn index_mut(self, slice: &mut [T]) -> &mut Self::Output {
|
|
(..cmp::min(self.0.end, slice.len())).index_mut(slice)
|
|
}
|
|
}
|
|
|
|
#[unstable(feature = "sliceindex_wrappers", issue = "146179")]
|
|
unsafe impl<T> SliceIndex<[T]> for Clamp<range::RangeToInclusive<usize>> {
|
|
type Output = [T];
|
|
|
|
fn get(self, slice: &[T]) -> Option<&Self::Output> {
|
|
(..=cmp::min(self.0.last, slice.len() - 1)).get(slice)
|
|
}
|
|
|
|
fn get_mut(self, slice: &mut [T]) -> Option<&mut Self::Output> {
|
|
(..=cmp::min(self.0.last, slice.len() - 1)).get_mut(slice)
|
|
}
|
|
|
|
unsafe fn get_unchecked(self, slice: *const [T]) -> *const Self::Output {
|
|
// SAFETY: the caller ensures that the slice isn't empty
|
|
unsafe { (..=cmp::min(self.0.last, slice.len() - 1)).get_unchecked(slice) }
|
|
}
|
|
|
|
unsafe fn get_unchecked_mut(self, slice: *mut [T]) -> *mut Self::Output {
|
|
// SAFETY: the caller ensures that the slice isn't empty
|
|
unsafe { (..=cmp::min(self.0.last, slice.len() - 1)).get_unchecked_mut(slice) }
|
|
}
|
|
|
|
fn index(self, slice: &[T]) -> &Self::Output {
|
|
(..=cmp::min(self.0.last, slice.len() - 1)).index(slice)
|
|
}
|
|
|
|
fn index_mut(self, slice: &mut [T]) -> &mut Self::Output {
|
|
(..=cmp::min(self.0.last, slice.len() - 1)).index_mut(slice)
|
|
}
|
|
}
|
|
|
|
#[unstable(feature = "sliceindex_wrappers", issue = "146179")]
|
|
unsafe impl<T> SliceIndex<[T]> for Clamp<ops::RangeToInclusive<usize>> {
|
|
type Output = [T];
|
|
|
|
fn get(self, slice: &[T]) -> Option<&Self::Output> {
|
|
(..=cmp::min(self.0.end, slice.len() - 1)).get(slice)
|
|
}
|
|
|
|
fn get_mut(self, slice: &mut [T]) -> Option<&mut Self::Output> {
|
|
(..=cmp::min(self.0.end, slice.len() - 1)).get_mut(slice)
|
|
}
|
|
|
|
unsafe fn get_unchecked(self, slice: *const [T]) -> *const Self::Output {
|
|
// SAFETY: the caller ensures that the slice isn't empty
|
|
unsafe { (..=cmp::min(self.0.end, slice.len() - 1)).get_unchecked(slice) }
|
|
}
|
|
|
|
unsafe fn get_unchecked_mut(self, slice: *mut [T]) -> *mut Self::Output {
|
|
// SAFETY: the caller ensures that the slice isn't empty
|
|
unsafe { (..=cmp::min(self.0.end, slice.len() - 1)).get_unchecked_mut(slice) }
|
|
}
|
|
|
|
fn index(self, slice: &[T]) -> &Self::Output {
|
|
(..=cmp::min(self.0.end, slice.len() - 1)).index(slice)
|
|
}
|
|
|
|
fn index_mut(self, slice: &mut [T]) -> &mut Self::Output {
|
|
(..=cmp::min(self.0.end, slice.len() - 1)).index_mut(slice)
|
|
}
|
|
}
|
|
|
|
#[unstable(feature = "sliceindex_wrappers", issue = "146179")]
|
|
unsafe impl<T> SliceIndex<[T]> for Clamp<ops::RangeFull> {
|
|
type Output = [T];
|
|
|
|
fn get(self, slice: &[T]) -> Option<&Self::Output> {
|
|
(..).get(slice)
|
|
}
|
|
|
|
fn get_mut(self, slice: &mut [T]) -> Option<&mut Self::Output> {
|
|
(..).get_mut(slice)
|
|
}
|
|
|
|
unsafe fn get_unchecked(self, slice: *const [T]) -> *const Self::Output {
|
|
// SAFETY: RangeFull just returns `slice` here
|
|
unsafe { (..).get_unchecked(slice) }
|
|
}
|
|
|
|
unsafe fn get_unchecked_mut(self, slice: *mut [T]) -> *mut Self::Output {
|
|
// SAFETY: RangeFull just returns `slice` here
|
|
unsafe { (..).get_unchecked_mut(slice) }
|
|
}
|
|
|
|
fn index(self, slice: &[T]) -> &Self::Output {
|
|
(..).index(slice)
|
|
}
|
|
|
|
fn index_mut(self, slice: &mut [T]) -> &mut Self::Output {
|
|
(..).index_mut(slice)
|
|
}
|
|
}
|
|
|
|
#[unstable(feature = "sliceindex_wrappers", issue = "146179")]
|
|
unsafe impl<T> SliceIndex<[T]> for Last {
|
|
type Output = T;
|
|
|
|
fn get(self, slice: &[T]) -> Option<&Self::Output> {
|
|
slice.last()
|
|
}
|
|
|
|
fn get_mut(self, slice: &mut [T]) -> Option<&mut Self::Output> {
|
|
slice.last_mut()
|
|
}
|
|
|
|
unsafe fn get_unchecked(self, slice: *const [T]) -> *const Self::Output {
|
|
// SAFETY: the caller ensures that the slice isn't empty
|
|
unsafe { slice_get_unchecked(slice, slice.len() - 1) }
|
|
}
|
|
|
|
unsafe fn get_unchecked_mut(self, slice: *mut [T]) -> *mut Self::Output {
|
|
// SAFETY: the caller ensures that the slice isn't empty
|
|
unsafe { slice_get_unchecked(slice, slice.len() - 1) }
|
|
}
|
|
|
|
fn index(self, slice: &[T]) -> &Self::Output {
|
|
// N.B., use intrinsic indexing
|
|
&(*slice)[slice.len() - 1]
|
|
}
|
|
|
|
fn index_mut(self, slice: &mut [T]) -> &mut Self::Output {
|
|
// N.B., use intrinsic indexing
|
|
&mut (*slice)[slice.len() - 1]
|
|
}
|
|
}
|