index.rs - source
Description: Source of the Rust file `library/core/src/index.rs`.

#
core/
index.rs

    1#![unstable(feature = "sliceindex_wrappers", issue = "146179")]
    2
    3//! Helper types for indexing slices.
    4
    5use crate::intrinsics::slice_get_unchecked;
    6use crate::slice::SliceIndex;
    7use crate::{cmp, ops, range};
    8
    9/// Clamps an index, guaranteeing that it will only access valid elements of the slice.
    10///
    11/// # Examples
    12///
    13/// ```
    14/// #![feature(sliceindex_wrappers)]
    15///
    16/// use core::index::Clamp;
    17///
    18/// let s: &[usize] = &[0, 1, 2, 3];
    19///
    20/// assert_eq!(&3, &s[Clamp(6)]);
    21/// assert_eq!(&[1, 2, 3], &s[Clamp(1..6)]);
    22/// assert_eq!(&[] as &[usize], &s[Clamp(5..6)]);
    23/// assert_eq!(&[0, 1, 2, 3], &s[Clamp(..6)]);
    24/// assert_eq!(&[0, 1, 2, 3], &s[Clamp(..=6)]);
    25/// assert_eq!(&[] as &[usize], &s[Clamp(6..)]);
    26/// ```
    27#[unstable(feature = "sliceindex_wrappers", issue = "146179")]
    28#[derive(Debug)]
    29pub struct Clamp<Idx>(pub Idx);
    30
    31/// Always accesses the last element of the slice.
    32///
    33/// # Examples
    34///
    35/// ```
    36/// #![feature(sliceindex_wrappers)]
    37/// #![feature(slice_index_methods)]
    38///
    39/// use core::index::Last;
    40/// use core::slice::SliceIndex;
    41///
    42/// let s = &[0, 1, 2, 3];
    43///
    44/// assert_eq!(&3, &s[Last]);
    45/// assert_eq!(None, Last.get(&[] as &[usize]));
    46///
    47/// ```
    48#[unstable(feature = "sliceindex_wrappers", issue = "146179")]
    49#[derive(Debug)]
    50pub struct Last;
    51
    52#[unstable(feature = "sliceindex_wrappers", issue = "146179")]
    53unsafe impl<T> SliceIndex<[T]> for Clamp<usize> {
    54    type Output = T;
    55
    56    fn get(self, slice: &[T]) -> Option<&Self::Output> {
    57        slice.get(cmp::min(self.0, slice.len() - 1))
    58    }
    59
    60    fn get_mut(self, slice: &mut [T]) -> Option<&mut Self::Output> {
    61        slice.get_mut(cmp::min(self.0, slice.len() - 1))
    62    }
    63
    64    unsafe fn get_unchecked(self, slice: *const [T]) -> *const Self::Output {
    65        // SAFETY: the caller ensures that the slice isn't empty
    66        unsafe { slice_get_unchecked(slice, cmp::min(self.0, slice.len() - 1)) }
    67    }
    68
    69    unsafe fn get_unchecked_mut(self, slice: *mut [T]) -> *mut Self::Output {
    70        // SAFETY: the caller ensures that the slice isn't empty
    71        unsafe { slice_get_unchecked(slice, cmp::min(self.0, slice.len() - 1)) }
    72    }
    73
    74    fn index(self, slice: &[T]) -> &Self::Output {
    75        &(*slice)[cmp::min(self.0, slice.len() - 1)]
    76    }
    77
    78    fn index_mut(self, slice: &mut [T]) -> &mut Self::Output {
    79        &mut (*slice)[cmp::min(self.0, slice.len() - 1)]
    80    }
    81}
    82
    83#[unstable(feature = "sliceindex_wrappers", issue = "146179")]
    84unsafe impl<T> SliceIndex<[T]> for Clamp<range::Range<usize>> {
    85    type Output = [T];
    86
    87    fn get(self, slice: &[T]) -> Option<&Self::Output> {
    88        let start = cmp::min(self.0.start, slice.len());
    89        let end = cmp::min(self.0.end, slice.len());
    90        (start..end).get(slice)
    91    }
    92
    93    fn get_mut(self, slice: &mut [T]) -> Option<&mut Self::Output> {
    94        let start = cmp::min(self.0.start, slice.len());
    95        let end = cmp::min(self.0.end, slice.len());
    96        (start..end).get_mut(slice)
    97    }
    98
    99    unsafe fn get_unchecked(self, slice: *const [T]) -> *const Self::Output {
    100        let start = cmp::min(self.0.start, slice.len());
    101        let end = cmp::min(self.0.end, slice.len());
    102        // SAFETY: a range ending before len is always valid
    103        unsafe { (start..end).get_unchecked(slice) }
    104    }
    105
    106    unsafe fn get_unchecked_mut(self, slice: *mut [T]) -> *mut Self::Output {
    107        let start = cmp::min(self.0.start, slice.len());
    108        let end = cmp::min(self.0.end, slice.len());
    109        // SAFETY: a range ending before len is always valid
    110        unsafe { (start..end).get_unchecked_mut(slice) }
    111    }
    112
    113    fn index(self, slice: &[T]) -> &Self::Output {
    114        let start = cmp::min(self.0.start, slice.len());
    115        let end = cmp::min(self.0.end, slice.len());
    116        (start..end).index(slice)
    117    }
    118
    119    fn index_mut(self, slice: &mut [T]) -> &mut Self::Output {
    120        let start = cmp::min(self.0.start, slice.len());
    121        let end = cmp::min(self.0.end, slice.len());
    122        (start..end).index_mut(slice)
    123    }
    124}
    125
    126#[unstable(feature = "sliceindex_wrappers", issue = "146179")]
    127unsafe impl<T> SliceIndex<[T]> for Clamp<ops::Range<usize>> {
    128    type Output = [T];
    129
    130    fn get(self, slice: &[T]) -> Option<&Self::Output> {
    131        let start = cmp::min(self.0.start, slice.len());
    132        let end = cmp::min(self.0.end, slice.len());
    133        (start..end).get(slice)
    134    }
    135
    136    fn get_mut(self, slice: &mut [T]) -> Option<&mut Self::Output> {
    137        let start = cmp::min(self.0.start, slice.len());
    138        let end = cmp::min(self.0.end, slice.len());
    139        (start..end).get_mut(slice)
    140    }
    141
    142    unsafe fn get_unchecked(self, slice: *const [T]) -> *const Self::Output {
    143        let start = cmp::min(self.0.start, slice.len());
    144        let end = cmp::min(self.0.end, slice.len());
    145        // SAFETY: a range ending before len is always valid
    146        unsafe { (start..end).get_unchecked(slice) }
    147    }
    148
    149    unsafe fn get_unchecked_mut(self, slice: *mut [T]) -> *mut Self::Output {
    150        let start = cmp::min(self.0.start, slice.len());
    151        let end = cmp::min(self.0.end, slice.len());
    152        // SAFETY: a range ending before len is always valid
    153        unsafe { (start..end).get_unchecked_mut(slice) }
    154    }
    155
    156    fn index(self, slice: &[T]) -> &Self::Output {
    157        let start = cmp::min(self.0.start, slice.len());
    158        let end = cmp::min(self.0.end, slice.len());
    159        (start..end).index(slice)
    160    }
    161
    162    fn index_mut(self, slice: &mut [T]) -> &mut Self::Output {
    163        let start = cmp::min(self.0.start, slice.len());
    164        let end = cmp::min(self.0.end, slice.len());
    165        (start..end).index_mut(slice)
    166    }
    167}
    168
    169#[unstable(feature = "sliceindex_wrappers", issue = "146179")]
    170unsafe impl<T> SliceIndex<[T]> for Clamp<range::RangeInclusive<usize>> {
    171    type Output = [T];
    172
    173    fn get(self, slice: &[T]) -> Option<&Self::Output> {
    174        let start = cmp::min(self.0.start, slice.len() - 1);
    175        let end = cmp::min(self.0.last, slice.len() - 1);
    176        (start..=end).get(slice)
    177    }
    178
    179    fn get_mut(self, slice: &mut [T]) -> Option<&mut Self::Output> {
    180        let start = cmp::min(self.0.start, slice.len() - 1);
    181        let end = cmp::min(self.0.last, slice.len() - 1);
    182        (start..=end).get_mut(slice)
    183    }
    184
    185    unsafe fn get_unchecked(self, slice: *const [T]) -> *const Self::Output {
    186        let start = cmp::min(self.0.start, slice.len() - 1);
    187        let end = cmp::min(self.0.last, slice.len() - 1);
    188        // SAFETY: the caller ensures that the slice isn't empty
    189        unsafe { (start..=end).get_unchecked(slice) }
    190    }
    191
    192    unsafe fn get_unchecked_mut(self, slice: *mut [T]) -> *mut Self::Output {
    193        let start = cmp::min(self.0.start, slice.len() - 1);
    194        let end = cmp::min(self.0.last, slice.len() - 1);
    195        // SAFETY: the caller ensures that the slice isn't empty
    196        unsafe { (start..=end).get_unchecked_mut(slice) }
    197    }
    198
    199    fn index(self, slice: &[T]) -> &Self::Output {
    200        let start = cmp::min(self.0.start, slice.len() - 1);
    201        let end = cmp::min(self.0.last, slice.len() - 1);
    202        (start..=end).index(slice)
    203    }
    204
    205    fn index_mut(self, slice: &mut [T]) -> &mut Self::Output {
    206        let start = cmp::min(self.0.start, slice.len() - 1);
    207        let end = cmp::min(self.0.last, slice.len() - 1);
    208        (start..=end).index_mut(slice)
    209    }
    210}
    211
    212#[unstable(feature = "sliceindex_wrappers", issue = "146179")]
    213unsafe impl<T> SliceIndex<[T]> for Clamp<ops::RangeInclusive<usize>> {
    214    type Output = [T];
    215
    216    fn get(self, slice: &[T]) -> Option<&Self::Output> {
    217        let start = cmp::min(self.0.start, slice.len() - 1);
    218        let end = cmp::min(self.0.end, slice.len() - 1);
    219        (start..=end).get(slice)
    220    }
    221
    222    fn get_mut(self, slice: &mut [T]) -> Option<&mut Self::Output> {
    223        let start = cmp::min(self.0.start, slice.len() - 1);
    224        let end = cmp::min(self.0.end, slice.len() - 1);
    225        (start..=end).get_mut(slice)
    226    }
    227
    228    unsafe fn get_unchecked(self, slice: *const [T]) -> *const Self::Output {
    229        let start = cmp::min(self.0.start, slice.len() - 1);
    230        let end = cmp::min(self.0.end, slice.len() - 1);
    231        // SAFETY: the caller ensures that the slice isn't empty
    232        unsafe { (start..=end).get_unchecked(slice) }
    233    }
    234
    235    unsafe fn get_unchecked_mut(self, slice: *mut [T]) -> *mut Self::Output {
    236        let start = cmp::min(self.0.start, slice.len() - 1);
    237        let end = cmp::min(self.0.end, slice.len() - 1);
    238        // SAFETY: the caller ensures that the slice isn't empty
    239        unsafe { (start..=end).get_unchecked_mut(slice) }
    240    }
    241
    242    fn index(self, slice: &[T]) -> &Self::Output {
    243        let start = cmp::min(self.0.start, slice.len() - 1);
    244        let end = cmp::min(self.0.end, slice.len() - 1);
    245        (start..=end).index(slice)
    246    }
    247
    248    fn index_mut(self, slice: &mut [T]) -> &mut Self::Output {
    249        let start = cmp::min(self.0.start, slice.len() - 1);
    250        let end = cmp::min(self.0.end, slice.len() - 1);
    251        (start..=end).index_mut(slice)
    252    }
    253}
    254
    255#[unstable(feature = "sliceindex_wrappers", issue = "146179")]
    256unsafe impl<T> SliceIndex<[T]> for Clamp<range::RangeFrom<usize>> {
    257    type Output = [T];
    258
    259    fn get(self, slice: &[T]) -> Option<&Self::Output> {
    260        (cmp::min(self.0.start, slice.len())..).get(slice)
    261    }
    262
    263    fn get_mut(self, slice: &mut [T]) -> Option<&mut Self::Output> {
    264        (cmp::min(self.0.start, slice.len())..).get_mut(slice)
    265    }
    266
    267    unsafe fn get_unchecked(self, slice: *const [T]) -> *const Self::Output {
    268        // SAFETY: a range starting at len is valid
    269        unsafe { (cmp::min(self.0.start, slice.len())..).get_unchecked(slice) }
    270    }
    271
    272    unsafe fn get_unchecked_mut(self, slice: *mut [T]) -> *mut Self::Output {
    273        // SAFETY: a range starting at len is valid
    274        unsafe { (cmp::min(self.0.start, slice.len())..).get_unchecked_mut(slice) }
    275    }
    276
    277    fn index(self, slice: &[T]) -> &Self::Output {
    278        (cmp::min(self.0.start, slice.len())..).index(slice)
    279    }
    280
    281    fn index_mut(self, slice: &mut [T]) -> &mut Self::Output {
    282        (cmp::min(self.0.start, slice.len())..).index_mut(slice)
    283    }
    284}
    285
    286#[unstable(feature = "sliceindex_wrappers", issue = "146179")]
    287unsafe impl<T> SliceIndex<[T]> for Clamp<ops::RangeFrom<usize>> {
    288    type Output = [T];
    289
    290    fn get(self, slice: &[T]) -> Option<&Self::Output> {
    291        (cmp::min(self.0.start, slice.len())..).get(slice)
    292    }
    293
    294    fn get_mut(self, slice: &mut [T]) -> Option<&mut Self::Output> {
    295        (cmp::min(self.0.start, slice.len())..).get_mut(slice)
    296    }
    297
    298    unsafe fn get_unchecked(self, slice: *const [T]) -> *const Self::Output {
    299        // SAFETY: a range starting at len is valid
    300        unsafe { (cmp::min(self.0.start, slice.len())..).get_unchecked(slice) }
    301    }
    302
    303    unsafe fn get_unchecked_mut(self, slice: *mut [T]) -> *mut Self::Output {
    304        // SAFETY: a range starting at len is valid
    305        unsafe { (cmp::min(self.0.start, slice.len())..).get_unchecked_mut(slice) }
    306    }
    307
    308    fn index(self, slice: &[T]) -> &Self::Output {
    309        (cmp::min(self.0.start, slice.len())..).index(slice)
    310    }
    311
    312    fn index_mut(self, slice: &mut [T]) -> &mut Self::Output {
    313        (cmp::min(self.0.start, slice.len())..).index_mut(slice)
    314    }
    315}
    316
    317#[unstable(feature = "sliceindex_wrappers", issue = "146179")]
    318unsafe impl<T> SliceIndex<[T]> for Clamp<range::RangeTo<usize>> {
    319    type Output = [T];
    320
    321    fn get(self, slice: &[T]) -> Option<&Self::Output> {
    322        (..cmp::min(self.0.end, slice.len())).get(slice)
    323    }
    324
    325    fn get_mut(self, slice: &mut [T]) -> Option<&mut Self::Output> {
    326        (..cmp::min(self.0.end, slice.len())).get_mut(slice)
    327    }
    328
    329    unsafe fn get_unchecked(self, slice: *const [T]) -> *const Self::Output {
    330        // SAFETY: a range ending before len is always valid
    331        unsafe { (..cmp::min(self.0.end, slice.len())).get_unchecked(slice) }
    332    }
    333
    334    unsafe fn get_unchecked_mut(self, slice: *mut [T]) -> *mut Self::Output {
    335        // SAFETY: a range ending before len is always valid
    336        unsafe { (..cmp::min(self.0.end, slice.len())).get_unchecked_mut(slice) }
    337    }
    338
    339    fn index(self, slice: &[T]) -> &Self::Output {
    340        (..cmp::min(self.0.end, slice.len())).index(slice)
    341    }
    342
    343    fn index_mut(self, slice: &mut [T]) -> &mut Self::Output {
    344        (..cmp::min(self.0.end, slice.len())).index_mut(slice)
    345    }
    346}
    347
    348#[unstable(feature = "sliceindex_wrappers", issue = "146179")]
    349unsafe impl<T> SliceIndex<[T]> for Clamp<range::RangeToInclusive<usize>> {
    350    type Output = [T];
    351
    352    fn get(self, slice: &[T]) -> Option<&Self::Output> {
    353        (..=cmp::min(self.0.last, slice.len() - 1)).get(slice)
    354    }
    355
    356    fn get_mut(self, slice: &mut [T]) -> Option<&mut Self::Output> {
    357        (..=cmp::min(self.0.last, slice.len() - 1)).get_mut(slice)
    358    }
    359
    360    unsafe fn get_unchecked(self, slice: *const [T]) -> *const Self::Output {
    361        // SAFETY: the caller ensures that the slice isn't empty
    362        unsafe { (..=cmp::min(self.0.last, slice.len() - 1)).get_unchecked(slice) }
    363    }
    364
    365    unsafe fn get_unchecked_mut(self, slice: *mut [T]) -> *mut Self::Output {
    366        // SAFETY: the caller ensures that the slice isn't empty
    367        unsafe { (..=cmp::min(self.0.last, slice.len() - 1)).get_unchecked_mut(slice) }
    368    }
    369
    370    fn index(self, slice: &[T]) -> &Self::Output {
    371        (..=cmp::min(self.0.last, slice.len() - 1)).index(slice)
    372    }
    373
    374    fn index_mut(self, slice: &mut [T]) -> &mut Self::Output {
    375        (..=cmp::min(self.0.last, slice.len() - 1)).index_mut(slice)
    376    }
    377}
    378
    379#[unstable(feature = "sliceindex_wrappers", issue = "146179")]
    380unsafe impl<T> SliceIndex<[T]> for Clamp<ops::RangeToInclusive<usize>> {
    381    type Output = [T];
    382
    383    fn get(self, slice: &[T]) -> Option<&Self::Output> {
    384        (..=cmp::min(self.0.end, slice.len() - 1)).get(slice)
    385    }
    386
    387    fn get_mut(self, slice: &mut [T]) -> Option<&mut Self::Output> {
    388        (..=cmp::min(self.0.end, slice.len() - 1)).get_mut(slice)
    389    }
    390
    391    unsafe fn get_unchecked(self, slice: *const [T]) -> *const Self::Output {
    392        // SAFETY: the caller ensures that the slice isn't empty
    393        unsafe { (..=cmp::min(self.0.end, slice.len() - 1)).get_unchecked(slice) }
    394    }
    395
    396    unsafe fn get_unchecked_mut(self, slice: *mut [T]) -> *mut Self::Output {
    397        // SAFETY: the caller ensures that the slice isn't empty
    398        unsafe { (..=cmp::min(self.0.end, slice.len() - 1)).get_unchecked_mut(slice) }
    399    }
    400
    401    fn index(self, slice: &[T]) -> &Self::Output {
    402        (..=cmp::min(self.0.end, slice.len() - 1)).index(slice)
    403    }
    404
    405    fn index_mut(self, slice: &mut [T]) -> &mut Self::Output {
    406        (..=cmp::min(self.0.end, slice.len() - 1)).index_mut(slice)
    407    }
    408}
    409
    410#[unstable(feature = "sliceindex_wrappers", issue = "146179")]
    411unsafe impl<T> SliceIndex<[T]> for Clamp<range::RangeFull> {
    412    type Output = [T];
    413
    414    fn get(self, slice: &[T]) -> Option<&Self::Output> {
    415        (..).get(slice)
    416    }
    417
    418    fn get_mut(self, slice: &mut [T]) -> Option<&mut Self::Output> {
    419        (..).get_mut(slice)
    420    }
    421
    422    unsafe fn get_unchecked(self, slice: *const [T]) -> *const Self::Output {
    423        // SAFETY: RangeFull just returns `slice` here
    424        unsafe { (..).get_unchecked(slice) }
    425    }
    426
    427    unsafe fn get_unchecked_mut(self, slice: *mut [T]) -> *mut Self::Output {
    428        // SAFETY: RangeFull just returns `slice` here
    429        unsafe { (..).get_unchecked_mut(slice) }
    430    }
    431
    432    fn index(self, slice: &[T]) -> &Self::Output {
    433        (..).index(slice)
    434    }
    435
    436    fn index_mut(self, slice: &mut [T]) -> &mut Self::Output {
    437        (..).index_mut(slice)
    438    }
    439}
    440
    441#[unstable(feature = "sliceindex_wrappers", issue = "146179")]
    442unsafe impl<T> SliceIndex<[T]> for Last {
    443    type Output = T;
    444
    445    fn get(self, slice: &[T]) -> Option<&Self::Output> {
    446        slice.last()
    447    }
    448
    449    fn get_mut(self, slice: &mut [T]) -> Option<&mut Self::Output> {
    450        slice.last_mut()
    451    }
    452
    453    unsafe fn get_unchecked(self, slice: *const [T]) -> *const Self::Output {
    454        // SAFETY: the caller ensures that the slice isn't empty
    455        unsafe { slice_get_unchecked(slice, slice.len() - 1) }
    456    }
    457
    458    unsafe fn get_unchecked_mut(self, slice: *mut [T]) -> *mut Self::Output {
    459        // SAFETY: the caller ensures that the slice isn't empty
    460        unsafe { slice_get_unchecked(slice, slice.len() - 1) }
    461    }
    462
    463    fn index(self, slice: &[T]) -> &Self::Output {
    464        // N.B., use intrinsic indexing
    465        &(*slice)[slice.len() - 1]
    466    }
    467
    468    fn index_mut(self, slice: &mut [T]) -> &mut Self::Output {
    469        // N.B., use intrinsic indexing
    470        &mut (*slice)[slice.len() - 1]
    471    }
    472}