mirror of
https://github.com/rust-lang/rust.git
synced 2025-06-06 12:18:33 +00:00
Overload get{,_mut}{,_unchecked}
This commit is contained in:
parent
a31ad75bde
commit
5377b5e9c4
@ -54,6 +54,7 @@
|
|||||||
#![feature(trusted_len)]
|
#![feature(trusted_len)]
|
||||||
#![feature(unicode)]
|
#![feature(unicode)]
|
||||||
#![feature(unique)]
|
#![feature(unique)]
|
||||||
|
#![feature(slice_get_slice)]
|
||||||
#![cfg_attr(test, feature(rand, test))]
|
#![cfg_attr(test, feature(rand, test))]
|
||||||
|
|
||||||
#![no_std]
|
#![no_std]
|
||||||
|
@ -118,6 +118,8 @@ pub use core::slice::{SplitMut, ChunksMut, Split};
|
|||||||
pub use core::slice::{SplitN, RSplitN, SplitNMut, RSplitNMut};
|
pub use core::slice::{SplitN, RSplitN, SplitNMut, RSplitNMut};
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
pub use core::slice::{from_raw_parts, from_raw_parts_mut};
|
pub use core::slice::{from_raw_parts, from_raw_parts_mut};
|
||||||
|
#[unstable(feature = "slice_get_slice", issue = "35729")]
|
||||||
|
pub use core::slice::SliceIndex;
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
// Basic slice extension methods
|
// Basic slice extension methods
|
||||||
@ -353,7 +355,9 @@ impl<T> [T] {
|
|||||||
/// ```
|
/// ```
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn get(&self, index: usize) -> Option<&T> {
|
pub fn get<I>(&self, index: I) -> Option<&I::Output>
|
||||||
|
where I: SliceIndex<T>
|
||||||
|
{
|
||||||
core_slice::SliceExt::get(self, index)
|
core_slice::SliceExt::get(self, index)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -372,7 +376,9 @@ impl<T> [T] {
|
|||||||
/// or `None` if the index is out of bounds
|
/// or `None` if the index is out of bounds
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn get_mut(&mut self, index: usize) -> Option<&mut T> {
|
pub fn get_mut<I>(&mut self, index: I) -> Option<&mut I::Output>
|
||||||
|
where I: SliceIndex<T>
|
||||||
|
{
|
||||||
core_slice::SliceExt::get_mut(self, index)
|
core_slice::SliceExt::get_mut(self, index)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -390,7 +396,9 @@ impl<T> [T] {
|
|||||||
/// ```
|
/// ```
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
#[inline]
|
#[inline]
|
||||||
pub unsafe fn get_unchecked(&self, index: usize) -> &T {
|
pub unsafe fn get_unchecked<I>(&self, index: I) -> &I::Output
|
||||||
|
where I: SliceIndex<T>
|
||||||
|
{
|
||||||
core_slice::SliceExt::get_unchecked(self, index)
|
core_slice::SliceExt::get_unchecked(self, index)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -410,7 +418,9 @@ impl<T> [T] {
|
|||||||
/// ```
|
/// ```
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
#[inline]
|
#[inline]
|
||||||
pub unsafe fn get_unchecked_mut(&mut self, index: usize) -> &mut T {
|
pub unsafe fn get_unchecked_mut<I>(&mut self, index: I) -> &mut I::Output
|
||||||
|
where I: SliceIndex<T>
|
||||||
|
{
|
||||||
core_slice::SliceExt::get_unchecked_mut(self, index)
|
core_slice::SliceExt::get_unchecked_mut(self, index)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -38,10 +38,14 @@ use cmp;
|
|||||||
use fmt;
|
use fmt;
|
||||||
use intrinsics::assume;
|
use intrinsics::assume;
|
||||||
use iter::*;
|
use iter::*;
|
||||||
use ops::{self, RangeFull};
|
use ops::{FnMut, self};
|
||||||
|
use option::Option;
|
||||||
|
use option::Option::{None, Some};
|
||||||
|
use result::Result;
|
||||||
|
use result::Result::{Ok, Err};
|
||||||
use ptr;
|
use ptr;
|
||||||
use mem;
|
use mem;
|
||||||
use marker;
|
use marker::{Copy, Send, Sync, Sized, self};
|
||||||
use iter_private::TrustedRandomAccess;
|
use iter_private::TrustedRandomAccess;
|
||||||
|
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
@ -80,7 +84,8 @@ pub trait SliceExt {
|
|||||||
#[stable(feature = "core", since = "1.6.0")]
|
#[stable(feature = "core", since = "1.6.0")]
|
||||||
fn chunks(&self, size: usize) -> Chunks<Self::Item>;
|
fn chunks(&self, size: usize) -> Chunks<Self::Item>;
|
||||||
#[stable(feature = "core", since = "1.6.0")]
|
#[stable(feature = "core", since = "1.6.0")]
|
||||||
fn get(&self, index: usize) -> Option<&Self::Item>;
|
fn get<I>(&self, index: I) -> Option<&I::Output>
|
||||||
|
where I: SliceIndex<Self::Item>;
|
||||||
#[stable(feature = "core", since = "1.6.0")]
|
#[stable(feature = "core", since = "1.6.0")]
|
||||||
fn first(&self) -> Option<&Self::Item>;
|
fn first(&self) -> Option<&Self::Item>;
|
||||||
#[stable(feature = "core", since = "1.6.0")]
|
#[stable(feature = "core", since = "1.6.0")]
|
||||||
@ -90,7 +95,8 @@ pub trait SliceExt {
|
|||||||
#[stable(feature = "core", since = "1.6.0")]
|
#[stable(feature = "core", since = "1.6.0")]
|
||||||
fn last(&self) -> Option<&Self::Item>;
|
fn last(&self) -> Option<&Self::Item>;
|
||||||
#[stable(feature = "core", since = "1.6.0")]
|
#[stable(feature = "core", since = "1.6.0")]
|
||||||
unsafe fn get_unchecked(&self, index: usize) -> &Self::Item;
|
unsafe fn get_unchecked<I>(&self, index: I) -> &I::Output
|
||||||
|
where I: SliceIndex<Self::Item>;
|
||||||
#[stable(feature = "core", since = "1.6.0")]
|
#[stable(feature = "core", since = "1.6.0")]
|
||||||
fn as_ptr(&self) -> *const Self::Item;
|
fn as_ptr(&self) -> *const Self::Item;
|
||||||
#[stable(feature = "core", since = "1.6.0")]
|
#[stable(feature = "core", since = "1.6.0")]
|
||||||
@ -108,7 +114,8 @@ pub trait SliceExt {
|
|||||||
#[stable(feature = "core", since = "1.6.0")]
|
#[stable(feature = "core", since = "1.6.0")]
|
||||||
fn is_empty(&self) -> bool { self.len() == 0 }
|
fn is_empty(&self) -> bool { self.len() == 0 }
|
||||||
#[stable(feature = "core", since = "1.6.0")]
|
#[stable(feature = "core", since = "1.6.0")]
|
||||||
fn get_mut(&mut self, index: usize) -> Option<&mut Self::Item>;
|
fn get_mut<I>(&mut self, index: I) -> Option<&mut I::Output>
|
||||||
|
where I: SliceIndex<Self::Item>;
|
||||||
#[stable(feature = "core", since = "1.6.0")]
|
#[stable(feature = "core", since = "1.6.0")]
|
||||||
fn iter_mut(&mut self) -> IterMut<Self::Item>;
|
fn iter_mut(&mut self) -> IterMut<Self::Item>;
|
||||||
#[stable(feature = "core", since = "1.6.0")]
|
#[stable(feature = "core", since = "1.6.0")]
|
||||||
@ -137,7 +144,8 @@ pub trait SliceExt {
|
|||||||
#[stable(feature = "core", since = "1.6.0")]
|
#[stable(feature = "core", since = "1.6.0")]
|
||||||
fn reverse(&mut self);
|
fn reverse(&mut self);
|
||||||
#[stable(feature = "core", since = "1.6.0")]
|
#[stable(feature = "core", since = "1.6.0")]
|
||||||
unsafe fn get_unchecked_mut(&mut self, index: usize) -> &mut Self::Item;
|
unsafe fn get_unchecked_mut<I>(&mut self, index: I) -> &mut I::Output
|
||||||
|
where I: SliceIndex<Self::Item>;
|
||||||
#[stable(feature = "core", since = "1.6.0")]
|
#[stable(feature = "core", since = "1.6.0")]
|
||||||
fn as_mut_ptr(&mut self) -> *mut Self::Item;
|
fn as_mut_ptr(&mut self) -> *mut Self::Item;
|
||||||
|
|
||||||
@ -258,8 +266,10 @@ impl<T> SliceExt for [T] {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn get(&self, index: usize) -> Option<&T> {
|
fn get<I>(&self, index: I) -> Option<&I::Output>
|
||||||
if index < self.len() { Some(&self[index]) } else { None }
|
where I: SliceIndex<T>
|
||||||
|
{
|
||||||
|
index.get(self)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
@ -284,8 +294,10 @@ impl<T> SliceExt for [T] {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
unsafe fn get_unchecked(&self, index: usize) -> &T {
|
unsafe fn get_unchecked<I>(&self, index: I) -> &I::Output
|
||||||
&*(self.as_ptr().offset(index as isize))
|
where I: SliceIndex<T>
|
||||||
|
{
|
||||||
|
index.get_unchecked(self)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
@ -323,8 +335,10 @@ impl<T> SliceExt for [T] {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn get_mut(&mut self, index: usize) -> Option<&mut T> {
|
fn get_mut<I>(&mut self, index: I) -> Option<&mut I::Output>
|
||||||
if index < self.len() { Some(&mut self[index]) } else { None }
|
where I: SliceIndex<T>
|
||||||
|
{
|
||||||
|
index.get_mut(self)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
@ -451,8 +465,10 @@ impl<T> SliceExt for [T] {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
unsafe fn get_unchecked_mut(&mut self, index: usize) -> &mut T {
|
unsafe fn get_unchecked_mut<I>(&mut self, index: I) -> &mut I::Output
|
||||||
&mut *self.as_mut_ptr().offset(index as isize)
|
where I: SliceIndex<T>
|
||||||
|
{
|
||||||
|
index.get_unchecked_mut(self)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
@ -515,23 +531,26 @@ impl<T> SliceExt for [T] {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
#[rustc_on_unimplemented = "slice indices are of type `usize`"]
|
#[rustc_on_unimplemented = "slice indices are of type `usize` or ranges of `usize`"]
|
||||||
impl<T> ops::Index<usize> for [T] {
|
impl<T, I> ops::Index<I> for [T]
|
||||||
type Output = T;
|
where I: SliceIndex<T>
|
||||||
|
{
|
||||||
|
type Output = I::Output;
|
||||||
|
|
||||||
fn index(&self, index: usize) -> &T {
|
#[inline]
|
||||||
// NB built-in indexing
|
fn index(&self, index: I) -> &I::Output {
|
||||||
&(*self)[index]
|
index.index(self)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
#[rustc_on_unimplemented = "slice indices are of type `usize`"]
|
#[rustc_on_unimplemented = "slice indices are of type `usize` or ranges of `usize`"]
|
||||||
impl<T> ops::IndexMut<usize> for [T] {
|
impl<T, I> ops::IndexMut<I> for [T]
|
||||||
|
where I: SliceIndex<T>
|
||||||
|
{
|
||||||
#[inline]
|
#[inline]
|
||||||
fn index_mut(&mut self, index: usize) -> &mut T {
|
fn index_mut(&mut self, index: I) -> &mut I::Output {
|
||||||
// NB built-in indexing
|
index.index_mut(self)
|
||||||
&mut (*self)[index]
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -547,205 +566,349 @@ fn slice_index_order_fail(index: usize, end: usize) -> ! {
|
|||||||
panic!("slice index starts at {} but ends at {}", index, end);
|
panic!("slice index starts at {} but ends at {}", index, end);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// A helper trait used for indexing operations.
|
||||||
|
#[unstable(feature = "slice_get_slice", issue = "35729")]
|
||||||
|
#[rustc_on_unimplemented = "slice indices are of type `usize` or ranges of `usize`"]
|
||||||
|
pub trait SliceIndex<T> {
|
||||||
|
/// The output type returned by methods.
|
||||||
|
type Output: ?Sized;
|
||||||
|
|
||||||
/// Implements slicing with syntax `&self[begin .. end]`.
|
/// Returns a shared reference to the output at this location, if in
|
||||||
///
|
/// bounds.
|
||||||
/// Returns a slice of self for the index range [`begin`..`end`).
|
fn get(self, slice: &[T]) -> Option<&Self::Output>;
|
||||||
///
|
|
||||||
/// This operation is `O(1)`.
|
/// Returns a mutable reference to the output at this location, if in
|
||||||
///
|
/// bounds.
|
||||||
/// # Panics
|
fn get_mut(self, slice: &mut [T]) -> Option<&mut Self::Output>;
|
||||||
///
|
|
||||||
/// Requires that `begin <= end` and `end <= self.len()`,
|
/// Returns a shared reference to the output at this location, without
|
||||||
/// otherwise slicing will panic.
|
/// performing any bounds checking.
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
unsafe fn get_unchecked(self, slice: &[T]) -> &Self::Output;
|
||||||
#[rustc_on_unimplemented = "slice indices are of type `usize`"]
|
|
||||||
impl<T> ops::Index<ops::Range<usize>> for [T] {
|
/// Returns a mutable reference to the output at this location, without
|
||||||
|
/// performing any bounds checking.
|
||||||
|
unsafe fn get_unchecked_mut(self, slice: &mut [T]) -> &mut Self::Output;
|
||||||
|
|
||||||
|
/// Returns a shared reference to the output at this location, panicking
|
||||||
|
/// if out of bounds.
|
||||||
|
fn index(self, slice: &[T]) -> &Self::Output;
|
||||||
|
|
||||||
|
/// Returns a mutable reference to the output at this location, panicking
|
||||||
|
/// if out of bounds.
|
||||||
|
fn index_mut(self, slice: &mut [T]) -> &mut Self::Output;
|
||||||
|
}
|
||||||
|
|
||||||
|
#[stable(feature = "slice-get-slice-impls", since = "1.13.0")]
|
||||||
|
impl<T> SliceIndex<T> for usize {
|
||||||
|
type Output = T;
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn get(self, slice: &[T]) -> Option<&T> {
|
||||||
|
if self < slice.len() {
|
||||||
|
unsafe {
|
||||||
|
Some(self.get_unchecked(slice))
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn get_mut(self, slice: &mut [T]) -> Option<&mut T> {
|
||||||
|
if self < slice.len() {
|
||||||
|
unsafe {
|
||||||
|
Some(self.get_unchecked_mut(slice))
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
unsafe fn get_unchecked(self, slice: &[T]) -> &T {
|
||||||
|
&*slice.as_ptr().offset(self as isize)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
unsafe fn get_unchecked_mut(self, slice: &mut [T]) -> &mut T {
|
||||||
|
&mut *slice.as_mut_ptr().offset(self as isize)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn index(self, slice: &[T]) -> &T {
|
||||||
|
// NB: use intrinsic indexing
|
||||||
|
&(*slice)[self]
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn index_mut(self, slice: &mut [T]) -> &mut T {
|
||||||
|
// NB: use intrinsic indexing
|
||||||
|
&mut (*slice)[self]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[stable(feature = "slice-get-slice-impls", since = "1.13.0")]
|
||||||
|
impl<T> SliceIndex<T> for ops::Range<usize> {
|
||||||
type Output = [T];
|
type Output = [T];
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn index(&self, index: ops::Range<usize>) -> &[T] {
|
fn get(self, slice: &[T]) -> Option<&[T]> {
|
||||||
if index.start > index.end {
|
if self.start > self.end || self.end > slice.len() {
|
||||||
slice_index_order_fail(index.start, index.end);
|
None
|
||||||
} else if index.end > self.len() {
|
} else {
|
||||||
slice_index_len_fail(index.end, self.len());
|
unsafe {
|
||||||
|
Some(self.get_unchecked(slice))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn get_mut(self, slice: &mut [T]) -> Option<&mut [T]> {
|
||||||
|
if self.start > self.end || self.end > slice.len() {
|
||||||
|
None
|
||||||
|
} else {
|
||||||
|
unsafe {
|
||||||
|
Some(self.get_unchecked_mut(slice))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
unsafe fn get_unchecked(self, slice: &[T]) -> &[T] {
|
||||||
|
from_raw_parts(slice.as_ptr().offset(self.start as isize), self.end - self.start)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
unsafe fn get_unchecked_mut(self, slice: &mut [T]) -> &mut [T] {
|
||||||
|
from_raw_parts_mut(slice.as_mut_ptr().offset(self.start as isize), self.end - self.start)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn index(self, slice: &[T]) -> &[T] {
|
||||||
|
if self.start > self.end {
|
||||||
|
slice_index_order_fail(self.start, self.end);
|
||||||
|
} else if self.end > slice.len() {
|
||||||
|
slice_index_len_fail(self.end, slice.len());
|
||||||
}
|
}
|
||||||
unsafe {
|
unsafe {
|
||||||
from_raw_parts (
|
self.get_unchecked(slice)
|
||||||
self.as_ptr().offset(index.start as isize),
|
}
|
||||||
index.end - index.start
|
}
|
||||||
)
|
|
||||||
|
#[inline]
|
||||||
|
fn index_mut(self, slice: &mut [T]) -> &mut [T] {
|
||||||
|
if self.start > self.end {
|
||||||
|
slice_index_order_fail(self.start, self.end);
|
||||||
|
} else if self.end > slice.len() {
|
||||||
|
slice_index_len_fail(self.end, slice.len());
|
||||||
|
}
|
||||||
|
unsafe {
|
||||||
|
self.get_unchecked_mut(slice)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Implements slicing with syntax `&self[.. end]`.
|
#[stable(feature = "slice-get-slice-impls", since = "1.13.0")]
|
||||||
///
|
impl<T> SliceIndex<T> for ops::RangeTo<usize> {
|
||||||
/// Returns a slice of self from the beginning until but not including
|
|
||||||
/// the index `end`.
|
|
||||||
///
|
|
||||||
/// Equivalent to `&self[0 .. end]`
|
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
|
||||||
#[rustc_on_unimplemented = "slice indices are of type `usize`"]
|
|
||||||
impl<T> ops::Index<ops::RangeTo<usize>> for [T] {
|
|
||||||
type Output = [T];
|
type Output = [T];
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn index(&self, index: ops::RangeTo<usize>) -> &[T] {
|
fn get(self, slice: &[T]) -> Option<&[T]> {
|
||||||
self.index(0 .. index.end)
|
(0..self.end).get(slice)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn get_mut(self, slice: &mut [T]) -> Option<&mut [T]> {
|
||||||
|
(0..self.end).get_mut(slice)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
unsafe fn get_unchecked(self, slice: &[T]) -> &[T] {
|
||||||
|
(0..self.end).get_unchecked(slice)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
unsafe fn get_unchecked_mut(self, slice: &mut [T]) -> &mut [T] {
|
||||||
|
(0..self.end).get_unchecked_mut(slice)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn index(self, slice: &[T]) -> &[T] {
|
||||||
|
(0..self.end).index(slice)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn index_mut(self, slice: &mut [T]) -> &mut [T] {
|
||||||
|
(0..self.end).index_mut(slice)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Implements slicing with syntax `&self[begin ..]`.
|
#[stable(feature = "slice-get-slice-impls", since = "1.13.0")]
|
||||||
///
|
impl<T> SliceIndex<T> for ops::RangeFrom<usize> {
|
||||||
/// Returns a slice of self from and including the index `begin` until the end.
|
|
||||||
///
|
|
||||||
/// Equivalent to `&self[begin .. self.len()]`
|
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
|
||||||
#[rustc_on_unimplemented = "slice indices are of type `usize`"]
|
|
||||||
impl<T> ops::Index<ops::RangeFrom<usize>> for [T] {
|
|
||||||
type Output = [T];
|
type Output = [T];
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn index(&self, index: ops::RangeFrom<usize>) -> &[T] {
|
fn get(self, slice: &[T]) -> Option<&[T]> {
|
||||||
self.index(index.start .. self.len())
|
(self.start..slice.len()).get(slice)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn get_mut(self, slice: &mut [T]) -> Option<&mut [T]> {
|
||||||
|
(self.start..slice.len()).get_mut(slice)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
unsafe fn get_unchecked(self, slice: &[T]) -> &[T] {
|
||||||
|
(self.start..slice.len()).get_unchecked(slice)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
unsafe fn get_unchecked_mut(self, slice: &mut [T]) -> &mut [T] {
|
||||||
|
(self.start..slice.len()).get_unchecked_mut(slice)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn index(self, slice: &[T]) -> &[T] {
|
||||||
|
(self.start..slice.len()).index(slice)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn index_mut(self, slice: &mut [T]) -> &mut [T] {
|
||||||
|
(self.start..slice.len()).index_mut(slice)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Implements slicing with syntax `&self[..]`.
|
#[stable(feature = "slice-get-slice-impls", since = "1.13.0")]
|
||||||
///
|
impl<T> SliceIndex<T> for ops::RangeFull {
|
||||||
/// Returns a slice of the whole slice. This operation cannot panic.
|
|
||||||
///
|
|
||||||
/// Equivalent to `&self[0 .. self.len()]`
|
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
|
||||||
impl<T> ops::Index<RangeFull> for [T] {
|
|
||||||
type Output = [T];
|
type Output = [T];
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn index(&self, _index: RangeFull) -> &[T] {
|
fn get(self, slice: &[T]) -> Option<&[T]> {
|
||||||
self
|
Some(slice)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn get_mut(self, slice: &mut [T]) -> Option<&mut [T]> {
|
||||||
|
Some(slice)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
unsafe fn get_unchecked(self, slice: &[T]) -> &[T] {
|
||||||
|
slice
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
unsafe fn get_unchecked_mut(self, slice: &mut [T]) -> &mut [T] {
|
||||||
|
slice
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn index(self, slice: &[T]) -> &[T] {
|
||||||
|
slice
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn index_mut(self, slice: &mut [T]) -> &mut [T] {
|
||||||
|
slice
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[unstable(feature = "inclusive_range", reason = "recently added, follows RFC", issue = "28237")]
|
|
||||||
#[rustc_on_unimplemented = "slice indices are of type `usize`"]
|
#[stable(feature = "slice-get-slice-impls", since = "1.13.0")]
|
||||||
impl<T> ops::Index<ops::RangeInclusive<usize>> for [T] {
|
impl<T> SliceIndex<T> for ops::RangeInclusive<usize> {
|
||||||
type Output = [T];
|
type Output = [T];
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn index(&self, index: ops::RangeInclusive<usize>) -> &[T] {
|
fn get(self, slice: &[T]) -> Option<&[T]> {
|
||||||
match index {
|
match self {
|
||||||
|
ops::RangeInclusive::Empty { .. } => Some(&[]),
|
||||||
|
ops::RangeInclusive::NonEmpty { end, .. } if end == usize::max_value() => None,
|
||||||
|
ops::RangeInclusive::NonEmpty { start, end } => (start..end + 1).get(slice),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn get_mut(self, slice: &mut [T]) -> Option<&mut [T]> {
|
||||||
|
match self {
|
||||||
|
ops::RangeInclusive::Empty { .. } => Some(&mut []),
|
||||||
|
ops::RangeInclusive::NonEmpty { end, .. } if end == usize::max_value() => None,
|
||||||
|
ops::RangeInclusive::NonEmpty { start, end } => (start..end + 1).get_mut(slice),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
unsafe fn get_unchecked(self, slice: &[T]) -> &[T] {
|
||||||
|
match self {
|
||||||
ops::RangeInclusive::Empty { .. } => &[],
|
ops::RangeInclusive::Empty { .. } => &[],
|
||||||
ops::RangeInclusive::NonEmpty { end, .. } if end == usize::max_value() =>
|
ops::RangeInclusive::NonEmpty { start, end } => (start..end + 1).get_unchecked(slice),
|
||||||
panic!("attempted to index slice up to maximum usize"),
|
}
|
||||||
ops::RangeInclusive::NonEmpty { start, end } =>
|
}
|
||||||
self.index(start .. end+1)
|
|
||||||
|
#[inline]
|
||||||
|
unsafe fn get_unchecked_mut(self, slice: &mut [T]) -> &mut [T] {
|
||||||
|
match self {
|
||||||
|
ops::RangeInclusive::Empty { .. } => &mut [],
|
||||||
|
ops::RangeInclusive::NonEmpty { start, end } => {
|
||||||
|
(start..end + 1).get_unchecked_mut(slice)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn index(self, slice: &[T]) -> &[T] {
|
||||||
|
match self {
|
||||||
|
ops::RangeInclusive::Empty { .. } => &[],
|
||||||
|
ops::RangeInclusive::NonEmpty { end, .. } if end == usize::max_value() => {
|
||||||
|
panic!("attempted to index slice up to maximum usize");
|
||||||
|
},
|
||||||
|
ops::RangeInclusive::NonEmpty { start, end } => (start..end + 1).index(slice),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn index_mut(self, slice: &mut [T]) -> &mut [T] {
|
||||||
|
match self {
|
||||||
|
ops::RangeInclusive::Empty { .. } => &mut [],
|
||||||
|
ops::RangeInclusive::NonEmpty { end, .. } if end == usize::max_value() => {
|
||||||
|
panic!("attempted to index slice up to maximum usize");
|
||||||
|
},
|
||||||
|
ops::RangeInclusive::NonEmpty { start, end } => (start..end + 1).index_mut(slice),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#[unstable(feature = "inclusive_range", reason = "recently added, follows RFC", issue = "28237")]
|
|
||||||
#[rustc_on_unimplemented = "slice indices are of type `usize`"]
|
#[stable(feature = "slice-get-slice-impls", since = "1.13.0")]
|
||||||
impl<T> ops::Index<ops::RangeToInclusive<usize>> for [T] {
|
impl<T> SliceIndex<T> for ops::RangeToInclusive<usize> {
|
||||||
type Output = [T];
|
type Output = [T];
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn index(&self, index: ops::RangeToInclusive<usize>) -> &[T] {
|
fn get(self, slice: &[T]) -> Option<&[T]> {
|
||||||
self.index(0...index.end)
|
(0...self.end).get(slice)
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/// Implements mutable slicing with syntax `&mut self[begin .. end]`.
|
|
||||||
///
|
|
||||||
/// Returns a slice of self for the index range [`begin`..`end`).
|
|
||||||
///
|
|
||||||
/// This operation is `O(1)`.
|
|
||||||
///
|
|
||||||
/// # Panics
|
|
||||||
///
|
|
||||||
/// Requires that `begin <= end` and `end <= self.len()`,
|
|
||||||
/// otherwise slicing will panic.
|
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
|
||||||
#[rustc_on_unimplemented = "slice indices are of type `usize`"]
|
|
||||||
impl<T> ops::IndexMut<ops::Range<usize>> for [T] {
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn index_mut(&mut self, index: ops::Range<usize>) -> &mut [T] {
|
fn get_mut(self, slice: &mut [T]) -> Option<&mut [T]> {
|
||||||
if index.start > index.end {
|
(0...self.end).get_mut(slice)
|
||||||
slice_index_order_fail(index.start, index.end);
|
|
||||||
} else if index.end > self.len() {
|
|
||||||
slice_index_len_fail(index.end, self.len());
|
|
||||||
}
|
}
|
||||||
unsafe {
|
|
||||||
from_raw_parts_mut(
|
|
||||||
self.as_mut_ptr().offset(index.start as isize),
|
|
||||||
index.end - index.start
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Implements mutable slicing with syntax `&mut self[.. end]`.
|
|
||||||
///
|
|
||||||
/// Returns a slice of self from the beginning until but not including
|
|
||||||
/// the index `end`.
|
|
||||||
///
|
|
||||||
/// Equivalent to `&mut self[0 .. end]`
|
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
|
||||||
#[rustc_on_unimplemented = "slice indices are of type `usize`"]
|
|
||||||
impl<T> ops::IndexMut<ops::RangeTo<usize>> for [T] {
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn index_mut(&mut self, index: ops::RangeTo<usize>) -> &mut [T] {
|
unsafe fn get_unchecked(self, slice: &[T]) -> &[T] {
|
||||||
self.index_mut(0 .. index.end)
|
(0...self.end).get_unchecked(slice)
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/// Implements mutable slicing with syntax `&mut self[begin ..]`.
|
|
||||||
///
|
|
||||||
/// Returns a slice of self from and including the index `begin` until the end.
|
|
||||||
///
|
|
||||||
/// Equivalent to `&mut self[begin .. self.len()]`
|
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
|
||||||
#[rustc_on_unimplemented = "slice indices are of type `usize`"]
|
|
||||||
impl<T> ops::IndexMut<ops::RangeFrom<usize>> for [T] {
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn index_mut(&mut self, index: ops::RangeFrom<usize>) -> &mut [T] {
|
unsafe fn get_unchecked_mut(self, slice: &mut [T]) -> &mut [T] {
|
||||||
let len = self.len();
|
(0...self.end).get_unchecked_mut(slice)
|
||||||
self.index_mut(index.start .. len)
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/// Implements mutable slicing with syntax `&mut self[..]`.
|
|
||||||
///
|
|
||||||
/// Returns a slice of the whole slice. This operation can not panic.
|
|
||||||
///
|
|
||||||
/// Equivalent to `&mut self[0 .. self.len()]`
|
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
|
||||||
impl<T> ops::IndexMut<RangeFull> for [T] {
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn index_mut(&mut self, _index: RangeFull) -> &mut [T] {
|
fn index(self, slice: &[T]) -> &[T] {
|
||||||
self
|
(0...self.end).index(slice)
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
#[unstable(feature = "inclusive_range", reason = "recently added, follows RFC", issue = "28237")]
|
|
||||||
#[rustc_on_unimplemented = "slice indices are of type `usize`"]
|
|
||||||
impl<T> ops::IndexMut<ops::RangeInclusive<usize>> for [T] {
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn index_mut(&mut self, index: ops::RangeInclusive<usize>) -> &mut [T] {
|
fn index_mut(self, slice: &mut [T]) -> &mut [T] {
|
||||||
match index {
|
(0...self.end).index_mut(slice)
|
||||||
ops::RangeInclusive::Empty { .. } => &mut [],
|
|
||||||
ops::RangeInclusive::NonEmpty { end, .. } if end == usize::max_value() =>
|
|
||||||
panic!("attempted to index slice up to maximum usize"),
|
|
||||||
ops::RangeInclusive::NonEmpty { start, end } =>
|
|
||||||
self.index_mut(start .. end+1)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#[unstable(feature = "inclusive_range", reason = "recently added, follows RFC", issue = "28237")]
|
|
||||||
#[rustc_on_unimplemented = "slice indices are of type `usize`"]
|
|
||||||
impl<T> ops::IndexMut<ops::RangeToInclusive<usize>> for [T] {
|
|
||||||
#[inline]
|
|
||||||
fn index_mut(&mut self, index: ops::RangeToInclusive<usize>) -> &mut [T] {
|
|
||||||
self.index_mut(0...index.end)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -180,3 +180,47 @@ fn test_windows_last() {
|
|||||||
let c2 = v2.windows(2);
|
let c2 = v2.windows(2);
|
||||||
assert_eq!(c2.last().unwrap()[0], 3);
|
assert_eq!(c2.last().unwrap()[0], 3);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn get_range() {
|
||||||
|
let v: &[i32] = &[0, 1, 2, 3, 4, 5];
|
||||||
|
assert_eq!(v.get(..), Some(&[0, 1, 2, 3, 4, 5][..]));
|
||||||
|
assert_eq!(v.get(..2), Some(&[0, 1][..]));
|
||||||
|
assert_eq!(v.get(2..), Some(&[2, 3, 4, 5][..]));
|
||||||
|
assert_eq!(v.get(1..4), Some(&[1, 2, 3][..]));
|
||||||
|
assert_eq!(v.get(7..), None);
|
||||||
|
assert_eq!(v.get(7..10), None);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn get_mut_range() {
|
||||||
|
let mut v: &mut [i32] = &mut [0, 1, 2, 3, 4, 5];
|
||||||
|
assert_eq!(v.get_mut(..), Some(&mut [0, 1, 2, 3, 4, 5][..]));
|
||||||
|
assert_eq!(v.get_mut(..2), Some(&mut [0, 1][..]));
|
||||||
|
assert_eq!(v.get_mut(2..), Some(&mut [2, 3, 4, 5][..]));
|
||||||
|
assert_eq!(v.get_mut(1..4), Some(&mut [1, 2, 3][..]));
|
||||||
|
assert_eq!(v.get_mut(7..), None);
|
||||||
|
assert_eq!(v.get_mut(7..10), None);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn get_unchecked_range() {
|
||||||
|
unsafe {
|
||||||
|
let v: &[i32] = &[0, 1, 2, 3, 4, 5];
|
||||||
|
assert_eq!(v.get_unchecked(..), &[0, 1, 2, 3, 4, 5][..]);
|
||||||
|
assert_eq!(v.get_unchecked(..2), &[0, 1][..]);
|
||||||
|
assert_eq!(v.get_unchecked(2..), &[2, 3, 4, 5][..]);
|
||||||
|
assert_eq!(v.get_unchecked(1..4), &[1, 2, 3][..]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn get_unchecked_mut_range() {
|
||||||
|
unsafe {
|
||||||
|
let v: &mut [i32] = &mut [0, 1, 2, 3, 4, 5];
|
||||||
|
assert_eq!(v.get_unchecked_mut(..), &mut [0, 1, 2, 3, 4, 5][..]);
|
||||||
|
assert_eq!(v.get_unchecked_mut(..2), &mut [0, 1][..]);
|
||||||
|
assert_eq!(v.get_unchecked_mut(2..), &mut[2, 3, 4, 5][..]);
|
||||||
|
assert_eq!(v.get_unchecked_mut(1..4), &mut [1, 2, 3][..]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -13,7 +13,7 @@
|
|||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
fn bar<T>(_: T) {}
|
fn bar<T>(_: T) {}
|
||||||
[0][0u8]; //~ ERROR: `[{integer}]: std::ops::Index<u8>` is not satisfied
|
[0][0u8]; //~ ERROR: the trait bound `u8: std::slice::SliceIndex<{integer}>` is not satisfied
|
||||||
|
|
||||||
[0][0]; // should infer to be a usize
|
[0][0]; // should infer to be a usize
|
||||||
|
|
||||||
|
@ -19,8 +19,8 @@ pub fn main() {
|
|||||||
v[3i32]; //~ERROR : std::ops::Index<i32>` is not satisfied
|
v[3i32]; //~ERROR : std::ops::Index<i32>` is not satisfied
|
||||||
s.as_bytes()[3_usize];
|
s.as_bytes()[3_usize];
|
||||||
s.as_bytes()[3];
|
s.as_bytes()[3];
|
||||||
s.as_bytes()[3u8]; //~ERROR : std::ops::Index<u8>` is not satisfied
|
s.as_bytes()[3u8]; //~ERROR : std::slice::SliceIndex<u8>` is not satisfied
|
||||||
s.as_bytes()[3i8]; //~ERROR : std::ops::Index<i8>` is not satisfied
|
s.as_bytes()[3i8]; //~ERROR : std::slice::SliceIndex<u8>` is not satisfied
|
||||||
s.as_bytes()[3u32]; //~ERROR : std::ops::Index<u32>` is not satisfied
|
s.as_bytes()[3u32]; //~ERROR : std::slice::SliceIndex<u8>` is not satisfied
|
||||||
s.as_bytes()[3i32]; //~ERROR : std::ops::Index<i32>` is not satisfied
|
s.as_bytes()[3i32]; //~ERROR : std::slice::SliceIndex<u8>` is not satisfied
|
||||||
}
|
}
|
||||||
|
@ -9,6 +9,7 @@
|
|||||||
// except according to those terms.
|
// except according to those terms.
|
||||||
|
|
||||||
// Test new Index error message for slices
|
// Test new Index error message for slices
|
||||||
|
// ignore-tidy-linelength
|
||||||
|
|
||||||
#![feature(rustc_attrs)]
|
#![feature(rustc_attrs)]
|
||||||
|
|
||||||
@ -17,12 +18,12 @@ use std::ops::Index;
|
|||||||
#[rustc_error]
|
#[rustc_error]
|
||||||
fn main() {
|
fn main() {
|
||||||
let x = &[1, 2, 3] as &[i32];
|
let x = &[1, 2, 3] as &[i32];
|
||||||
x[1i32];
|
x[1i32]; //~ ERROR E0277
|
||||||
//~^ ERROR E0277
|
//~| NOTE slice indices are of type `usize` or ranges of `usize`
|
||||||
//~| NOTE the trait `std::ops::Index<i32>` is not implemented for `[i32]`
|
//~| NOTE trait `std::slice::SliceIndex<i32>` is not implemented for `i32`
|
||||||
//~| NOTE slice indices are of type `usize`
|
//~| NOTE required because of the requirements on the impl of `std::ops::Index<i32>`
|
||||||
x[..1i32];
|
x[..1i32]; //~ ERROR E0277
|
||||||
//~^ ERROR E0277
|
//~| NOTE slice indices are of type `usize` or ranges of `usize`
|
||||||
//~| NOTE the trait `std::ops::Index<std::ops::RangeTo<i32>>` is not implemented for `[i32]`
|
//~| NOTE trait `std::slice::SliceIndex<i32>` is not implemented for `std::ops::RangeTo<i32>`
|
||||||
//~| NOTE slice indices are of type `usize`
|
//~| NOTE requirements on the impl of `std::ops::Index<std::ops::RangeTo<i32>>`
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user