add SliceIndex wrapper types Last and Clamp<Idx>
This commit is contained in:
parent
f3fd3efe4f
commit
78d8ce7301
6 changed files with 577 additions and 0 deletions
472
library/core/src/index.rs
Normal file
472
library/core/src/index.rs
Normal file
|
|
@ -0,0 +1,472 @@
|
|||
#![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<range::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<range::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]
|
||||
}
|
||||
}
|
||||
|
|
@ -292,6 +292,7 @@ pub mod cmp;
|
|||
pub mod convert;
|
||||
pub mod default;
|
||||
pub mod error;
|
||||
pub mod index;
|
||||
pub mod marker;
|
||||
pub mod ops;
|
||||
|
||||
|
|
|
|||
|
|
@ -629,6 +629,18 @@ impl<Idx: PartialOrd<Idx>> RangeToInclusive<Idx> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<T> From<legacy::RangeToInclusive<T>> for RangeToInclusive<T> {
|
||||
fn from(value: legacy::RangeToInclusive<T>) -> Self {
|
||||
Self { last: value.end }
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> From<RangeToInclusive<T>> for legacy::RangeToInclusive<T> {
|
||||
fn from(value: RangeToInclusive<T>) -> Self {
|
||||
Self { end: value.last }
|
||||
}
|
||||
}
|
||||
|
||||
// RangeToInclusive<Idx> cannot impl From<RangeTo<Idx>>
|
||||
// because underflow would be possible with (..0).into()
|
||||
|
||||
|
|
|
|||
|
|
@ -134,6 +134,11 @@ mod private_slice_index {
|
|||
impl Sealed for range::RangeFrom<usize> {}
|
||||
|
||||
impl Sealed for ops::IndexRange {}
|
||||
|
||||
#[unstable(feature = "sliceindex_wrappers", issue = "146179")]
|
||||
impl Sealed for crate::index::Last {}
|
||||
#[unstable(feature = "sliceindex_wrappers", issue = "146179")]
|
||||
impl<T> Sealed for crate::index::Clamp<T> where T: Sealed {}
|
||||
}
|
||||
|
||||
/// A helper trait used for indexing operations.
|
||||
|
|
|
|||
83
library/coretests/tests/index.rs
Normal file
83
library/coretests/tests/index.rs
Normal file
|
|
@ -0,0 +1,83 @@
|
|||
use core::index::Clamp;
|
||||
use core::range;
|
||||
use core::slice::SliceIndex;
|
||||
|
||||
macro_rules! test_clamp {
|
||||
($range:expr, $(($slice:expr, $other:expr)),+) => {
|
||||
$(
|
||||
assert_eq!(Clamp($range.clone()).get(&$slice as &[_]), $other.get(&$slice as &[_]));
|
||||
assert_eq!(Clamp($range.clone()).get_mut(&mut $slice as &mut [_]), $other.get_mut(&mut $slice as &mut [_]));
|
||||
unsafe {
|
||||
assert_eq!(&*Clamp($range.clone()).get_unchecked(&$slice as &[_]), &*$other.get_unchecked(&$slice as &[_]));
|
||||
assert_eq!(&*Clamp($range.clone()).get_unchecked_mut(&mut $slice as &mut [_]), &*$other.get_unchecked_mut(&mut $slice as &mut [_]));
|
||||
}
|
||||
assert_eq!(Clamp($range.clone()).index(&$slice as &[_]), $other.index(&$slice as &[_]));
|
||||
assert_eq!(Clamp($range.clone()).index_mut(&mut $slice as &mut [_]), $other.index_mut(&mut $slice as &mut [_]));
|
||||
)+
|
||||
};
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_clamp_usize() {
|
||||
test_clamp!(2, ([0, 1], 1), ([0, 1, 2], 2));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_clamp_range_range() {
|
||||
test_clamp!(range::Range::from(1..4), ([0, 1], 1..2), ([0, 1, 2, 3, 4], 1..4), ([0], 1..1));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_clamp_ops_range() {
|
||||
test_clamp!(1..4, ([0, 1], 1..2), ([0, 1, 2, 3, 4], 1..4), ([0], 1..1));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_clamp_range_range_inclusive() {
|
||||
test_clamp!(
|
||||
range::RangeInclusive::from(1..=3),
|
||||
([0, 1], 1..=1),
|
||||
([0, 1, 2, 3, 4], 1..=3),
|
||||
([0], 0..=0)
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_clamp_ops_range_inclusive() {
|
||||
test_clamp!(1..=3, ([0, 1], 1..=1), ([0, 1, 2, 3, 4], 1..=3), ([0], 0..=0));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_clamp_range_range_from() {
|
||||
test_clamp!(range::RangeFrom::from(1..), ([0, 1], 1..), ([0, 1, 2, 3, 4], 1..), ([0], 1..));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_clamp_ops_range_from() {
|
||||
test_clamp!(1.., ([0, 1], 1..), ([0, 1, 2, 3, 4], 1..), ([0], 1..));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_clamp_range_to() {
|
||||
test_clamp!(..4, ([0, 1], ..2), ([0, 1, 2, 3, 4], ..4), ([0], ..1));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_clamp_range_range_to_inclusive() {
|
||||
test_clamp!(
|
||||
range::RangeToInclusive::from(..=4),
|
||||
([0, 1], ..=1),
|
||||
([0, 1, 2, 3, 4], ..=4),
|
||||
([0], ..=0)
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_clamp_ops_range_to_inclusive() {
|
||||
test_clamp!(..=4, ([0, 1], ..=1), ([0, 1, 2, 3, 4], ..=4), ([0], ..=0));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_clamp_range_full() {
|
||||
test_clamp!(.., ([0, 1], ..), ([0, 1, 2, 3, 4], ..), ([0], ..));
|
||||
}
|
||||
|
|
@ -81,6 +81,7 @@
|
|||
#![feature(maybe_uninit_write_slice)]
|
||||
#![feature(min_specialization)]
|
||||
#![feature(never_type)]
|
||||
#![feature(new_range_api)]
|
||||
#![feature(next_index)]
|
||||
#![feature(non_exhaustive_omitted_patterns_lint)]
|
||||
#![feature(numfmt)]
|
||||
|
|
@ -93,9 +94,11 @@
|
|||
#![feature(ptr_metadata)]
|
||||
#![feature(result_option_map_or_default)]
|
||||
#![feature(slice_from_ptr_range)]
|
||||
#![feature(slice_index_methods)]
|
||||
#![feature(slice_internals)]
|
||||
#![feature(slice_partition_dedup)]
|
||||
#![feature(slice_split_once)]
|
||||
#![feature(sliceindex_wrappers)]
|
||||
#![feature(split_array)]
|
||||
#![feature(split_as_slice)]
|
||||
#![feature(std_internals)]
|
||||
|
|
@ -173,6 +176,7 @@ mod fmt;
|
|||
mod future;
|
||||
mod hash;
|
||||
mod hint;
|
||||
mod index;
|
||||
mod intrinsics;
|
||||
mod io;
|
||||
mod iter;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue