Rename Range::ensure_subset_of
to slice::range
This commit is contained in:
parent
f6111a256e
commit
5d519eaa6e
@ -1063,7 +1063,7 @@ fn range_tail_head<R>(&self, range: R) -> (usize, usize)
|
|||||||
where
|
where
|
||||||
R: RangeBounds<usize>,
|
R: RangeBounds<usize>,
|
||||||
{
|
{
|
||||||
let Range { start, end } = Range::ensure_subset_of(range, ..self.len());
|
let Range { start, end } = slice::range(range, ..self.len());
|
||||||
let tail = self.wrap_add(self.tail, start);
|
let tail = self.wrap_add(self.tail, start);
|
||||||
let head = self.wrap_add(self.tail, end);
|
let head = self.wrap_add(self.tail, end);
|
||||||
(tail, head)
|
(tail, head)
|
||||||
|
@ -115,7 +115,6 @@
|
|||||||
#![feature(or_patterns)]
|
#![feature(or_patterns)]
|
||||||
#![feature(pattern)]
|
#![feature(pattern)]
|
||||||
#![feature(ptr_internals)]
|
#![feature(ptr_internals)]
|
||||||
#![feature(range_ensure_subset_of)]
|
|
||||||
#![feature(rustc_attrs)]
|
#![feature(rustc_attrs)]
|
||||||
#![feature(receiver_trait)]
|
#![feature(receiver_trait)]
|
||||||
#![cfg_attr(bootstrap, feature(min_const_generics))]
|
#![cfg_attr(bootstrap, feature(min_const_generics))]
|
||||||
@ -123,6 +122,7 @@
|
|||||||
#![feature(set_ptr_value)]
|
#![feature(set_ptr_value)]
|
||||||
#![feature(slice_ptr_get)]
|
#![feature(slice_ptr_get)]
|
||||||
#![feature(slice_ptr_len)]
|
#![feature(slice_ptr_len)]
|
||||||
|
#![feature(slice_range)]
|
||||||
#![feature(staged_api)]
|
#![feature(staged_api)]
|
||||||
#![feature(str_internals)]
|
#![feature(str_internals)]
|
||||||
#![feature(trusted_len)]
|
#![feature(trusted_len)]
|
||||||
|
@ -92,6 +92,8 @@
|
|||||||
use crate::boxed::Box;
|
use crate::boxed::Box;
|
||||||
use crate::vec::Vec;
|
use crate::vec::Vec;
|
||||||
|
|
||||||
|
#[unstable(feature = "slice_range", issue = "76393")]
|
||||||
|
pub use core::slice::range;
|
||||||
#[unstable(feature = "array_chunks", issue = "74985")]
|
#[unstable(feature = "array_chunks", issue = "74985")]
|
||||||
pub use core::slice::ArrayChunks;
|
pub use core::slice::ArrayChunks;
|
||||||
#[unstable(feature = "array_chunks", issue = "74985")]
|
#[unstable(feature = "array_chunks", issue = "74985")]
|
||||||
|
@ -49,6 +49,7 @@
|
|||||||
use core::ops::Bound::{Excluded, Included, Unbounded};
|
use core::ops::Bound::{Excluded, Included, Unbounded};
|
||||||
use core::ops::{self, Add, AddAssign, Index, IndexMut, Range, RangeBounds};
|
use core::ops::{self, Add, AddAssign, Index, IndexMut, Range, RangeBounds};
|
||||||
use core::ptr;
|
use core::ptr;
|
||||||
|
use core::slice;
|
||||||
use core::str::{lossy, pattern::Pattern};
|
use core::str::{lossy, pattern::Pattern};
|
||||||
|
|
||||||
use crate::borrow::{Cow, ToOwned};
|
use crate::borrow::{Cow, ToOwned};
|
||||||
@ -1510,14 +1511,14 @@ pub fn drain<R>(&mut self, range: R) -> Drain<'_>
|
|||||||
// of the vector version. The data is just plain bytes.
|
// of the vector version. The data is just plain bytes.
|
||||||
// Because the range removal happens in Drop, if the Drain iterator is leaked,
|
// Because the range removal happens in Drop, if the Drain iterator is leaked,
|
||||||
// the removal will not happen.
|
// the removal will not happen.
|
||||||
let Range { start, end } = Range::ensure_subset_of(range, ..self.len());
|
let Range { start, end } = slice::range(range, ..self.len());
|
||||||
assert!(self.is_char_boundary(start));
|
assert!(self.is_char_boundary(start));
|
||||||
assert!(self.is_char_boundary(end));
|
assert!(self.is_char_boundary(end));
|
||||||
|
|
||||||
// Take out two simultaneous borrows. The &mut String won't be accessed
|
// Take out two simultaneous borrows. The &mut String won't be accessed
|
||||||
// until iteration is over, in Drop.
|
// until iteration is over, in Drop.
|
||||||
let self_ptr = self as *mut _;
|
let self_ptr = self as *mut _;
|
||||||
// SAFETY: `ensure_subset_of` and `is_char_boundary` do the appropriate bounds checks.
|
// SAFETY: `slice::range` and `is_char_boundary` do the appropriate bounds checks.
|
||||||
let chars_iter = unsafe { self.get_unchecked(start..end) }.chars();
|
let chars_iter = unsafe { self.get_unchecked(start..end) }.chars();
|
||||||
|
|
||||||
Drain { start, end, iter: chars_iter, string: self_ptr }
|
Drain { start, end, iter: chars_iter, string: self_ptr }
|
||||||
|
@ -1650,7 +1650,7 @@ pub fn drain<R>(&mut self, range: R) -> Drain<'_, T, A>
|
|||||||
// the hole, and the vector length is restored to the new length.
|
// the hole, and the vector length is restored to the new length.
|
||||||
//
|
//
|
||||||
let len = self.len();
|
let len = self.len();
|
||||||
let Range { start, end } = Range::ensure_subset_of(range, ..len);
|
let Range { start, end } = slice::range(range, ..len);
|
||||||
|
|
||||||
unsafe {
|
unsafe {
|
||||||
// set self.vec length's to start, to be safe in case Drain is leaked
|
// set self.vec length's to start, to be safe in case Drain is leaked
|
||||||
|
@ -1,9 +1,5 @@
|
|||||||
use crate::fmt;
|
use crate::fmt;
|
||||||
use crate::hash::Hash;
|
use crate::hash::Hash;
|
||||||
use crate::slice::index::{
|
|
||||||
slice_end_index_len_fail, slice_end_index_overflow_fail, slice_index_order_fail,
|
|
||||||
slice_start_index_overflow_fail,
|
|
||||||
};
|
|
||||||
|
|
||||||
/// An unbounded range (`..`).
|
/// An unbounded range (`..`).
|
||||||
///
|
///
|
||||||
@ -151,103 +147,6 @@ pub fn is_empty(&self) -> bool {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Range<usize> {
|
|
||||||
/// Performs bounds-checking of a range.
|
|
||||||
///
|
|
||||||
/// This method is similar to [`Index::index`] for slices, but it returns a
|
|
||||||
/// `Range` equivalent to `range`. You can use this method to turn any range
|
|
||||||
/// into `start` and `end` values.
|
|
||||||
///
|
|
||||||
/// `bounds` is the range of the slice to use for bounds-checking. It should
|
|
||||||
/// be a [`RangeTo`] range that ends at the length of the slice.
|
|
||||||
///
|
|
||||||
/// The returned `Range` is safe to pass to [`slice::get_unchecked`] and
|
|
||||||
/// [`slice::get_unchecked_mut`] for slices with the given range.
|
|
||||||
///
|
|
||||||
/// [`slice::get_unchecked`]: ../../std/primitive.slice.html#method.get_unchecked
|
|
||||||
/// [`slice::get_unchecked_mut`]: ../../std/primitive.slice.html#method.get_unchecked_mut
|
|
||||||
///
|
|
||||||
/// # Panics
|
|
||||||
///
|
|
||||||
/// Panics if `range` would be out of bounds.
|
|
||||||
///
|
|
||||||
/// # Examples
|
|
||||||
///
|
|
||||||
/// ```
|
|
||||||
/// #![feature(range_ensure_subset_of)]
|
|
||||||
///
|
|
||||||
/// use std::ops::Range;
|
|
||||||
///
|
|
||||||
/// let v = [10, 40, 30];
|
|
||||||
/// assert_eq!(1..2, Range::ensure_subset_of(1..2, ..v.len()));
|
|
||||||
/// assert_eq!(0..2, Range::ensure_subset_of(..2, ..v.len()));
|
|
||||||
/// assert_eq!(1..3, Range::ensure_subset_of(1.., ..v.len()));
|
|
||||||
/// ```
|
|
||||||
///
|
|
||||||
/// Panics when [`Index::index`] would panic:
|
|
||||||
///
|
|
||||||
/// ```should_panic
|
|
||||||
/// #![feature(range_ensure_subset_of)]
|
|
||||||
///
|
|
||||||
/// use std::ops::Range;
|
|
||||||
///
|
|
||||||
/// Range::ensure_subset_of(2..1, ..3);
|
|
||||||
/// ```
|
|
||||||
///
|
|
||||||
/// ```should_panic
|
|
||||||
/// #![feature(range_ensure_subset_of)]
|
|
||||||
///
|
|
||||||
/// use std::ops::Range;
|
|
||||||
///
|
|
||||||
/// Range::ensure_subset_of(1..4, ..3);
|
|
||||||
/// ```
|
|
||||||
///
|
|
||||||
/// ```should_panic
|
|
||||||
/// #![feature(range_ensure_subset_of)]
|
|
||||||
///
|
|
||||||
/// use std::ops::Range;
|
|
||||||
///
|
|
||||||
/// Range::ensure_subset_of(1..=usize::MAX, ..3);
|
|
||||||
/// ```
|
|
||||||
///
|
|
||||||
/// [`Index::index`]: crate::ops::Index::index
|
|
||||||
#[track_caller]
|
|
||||||
#[unstable(feature = "range_ensure_subset_of", issue = "76393")]
|
|
||||||
pub fn ensure_subset_of<R>(range: R, bounds: RangeTo<usize>) -> Self
|
|
||||||
where
|
|
||||||
R: RangeBounds<usize>,
|
|
||||||
{
|
|
||||||
let len = bounds.end;
|
|
||||||
|
|
||||||
let start: Bound<&usize> = range.start_bound();
|
|
||||||
let start = match start {
|
|
||||||
Bound::Included(&start) => start,
|
|
||||||
Bound::Excluded(start) => {
|
|
||||||
start.checked_add(1).unwrap_or_else(|| slice_start_index_overflow_fail())
|
|
||||||
}
|
|
||||||
Bound::Unbounded => 0,
|
|
||||||
};
|
|
||||||
|
|
||||||
let end: Bound<&usize> = range.end_bound();
|
|
||||||
let end = match end {
|
|
||||||
Bound::Included(end) => {
|
|
||||||
end.checked_add(1).unwrap_or_else(|| slice_end_index_overflow_fail())
|
|
||||||
}
|
|
||||||
Bound::Excluded(&end) => end,
|
|
||||||
Bound::Unbounded => len,
|
|
||||||
};
|
|
||||||
|
|
||||||
if start > end {
|
|
||||||
slice_index_order_fail(start, end);
|
|
||||||
}
|
|
||||||
if end > len {
|
|
||||||
slice_end_index_len_fail(end, len);
|
|
||||||
}
|
|
||||||
|
|
||||||
Self { start, end }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// A range only bounded inclusively below (`start..`).
|
/// A range only bounded inclusively below (`start..`).
|
||||||
///
|
///
|
||||||
/// The `RangeFrom` `start..` contains all values with `x >= start`.
|
/// The `RangeFrom` `start..` contains all values with `x >= start`.
|
||||||
|
@ -37,28 +37,28 @@ fn slice_start_index_len_fail(index: usize, len: usize) -> ! {
|
|||||||
#[inline(never)]
|
#[inline(never)]
|
||||||
#[cold]
|
#[cold]
|
||||||
#[track_caller]
|
#[track_caller]
|
||||||
pub(crate) fn slice_end_index_len_fail(index: usize, len: usize) -> ! {
|
fn slice_end_index_len_fail(index: usize, len: usize) -> ! {
|
||||||
panic!("range end index {} out of range for slice of length {}", index, len);
|
panic!("range end index {} out of range for slice of length {}", index, len);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline(never)]
|
#[inline(never)]
|
||||||
#[cold]
|
#[cold]
|
||||||
#[track_caller]
|
#[track_caller]
|
||||||
pub(crate) fn slice_index_order_fail(index: usize, end: usize) -> ! {
|
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);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline(never)]
|
#[inline(never)]
|
||||||
#[cold]
|
#[cold]
|
||||||
#[track_caller]
|
#[track_caller]
|
||||||
pub(crate) fn slice_start_index_overflow_fail() -> ! {
|
fn slice_start_index_overflow_fail() -> ! {
|
||||||
panic!("attempted to index slice from after maximum usize");
|
panic!("attempted to index slice from after maximum usize");
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline(never)]
|
#[inline(never)]
|
||||||
#[cold]
|
#[cold]
|
||||||
#[track_caller]
|
#[track_caller]
|
||||||
pub(crate) fn slice_end_index_overflow_fail() -> ! {
|
fn slice_end_index_overflow_fail() -> ! {
|
||||||
panic!("attempted to index slice up to maximum usize");
|
panic!("attempted to index slice up to maximum usize");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -449,3 +449,100 @@ fn index_mut(self, slice: &mut [T]) -> &mut [T] {
|
|||||||
(0..=self.end).index_mut(slice)
|
(0..=self.end).index_mut(slice)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Performs bounds-checking of a range.
|
||||||
|
///
|
||||||
|
/// This method is similar to [`Index::index`] for slices, but it returns a
|
||||||
|
/// [`Range`] equivalent to `range`. You can use this method to turn any range
|
||||||
|
/// into `start` and `end` values.
|
||||||
|
///
|
||||||
|
/// `bounds` is the range of the slice to use for bounds-checking. It should
|
||||||
|
/// be a [`RangeTo`] range that ends at the length of the slice.
|
||||||
|
///
|
||||||
|
/// The returned [`Range`] is safe to pass to [`slice::get_unchecked`] and
|
||||||
|
/// [`slice::get_unchecked_mut`] for slices with the given range.
|
||||||
|
///
|
||||||
|
/// [`Range`]: ops::Range
|
||||||
|
/// [`RangeTo`]: ops::RangeTo
|
||||||
|
/// [`slice::get_unchecked`]: ../../std/primitive.slice.html#method.get_unchecked
|
||||||
|
/// [`slice::get_unchecked_mut`]: ../../std/primitive.slice.html#method.get_unchecked_mut
|
||||||
|
///
|
||||||
|
/// # Panics
|
||||||
|
///
|
||||||
|
/// Panics if `range` would be out of bounds.
|
||||||
|
///
|
||||||
|
/// # Examples
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// #![feature(slice_range)]
|
||||||
|
///
|
||||||
|
/// use std::slice;
|
||||||
|
///
|
||||||
|
/// let v = [10, 40, 30];
|
||||||
|
/// assert_eq!(1..2, slice::range(1..2, ..v.len()));
|
||||||
|
/// assert_eq!(0..2, slice::range(..2, ..v.len()));
|
||||||
|
/// assert_eq!(1..3, slice::range(1.., ..v.len()));
|
||||||
|
/// ```
|
||||||
|
///
|
||||||
|
/// Panics when [`Index::index`] would panic:
|
||||||
|
///
|
||||||
|
/// ```should_panic
|
||||||
|
/// #![feature(slice_range)]
|
||||||
|
///
|
||||||
|
/// use std::slice;
|
||||||
|
///
|
||||||
|
/// slice::range(2..1, ..3);
|
||||||
|
/// ```
|
||||||
|
///
|
||||||
|
/// ```should_panic
|
||||||
|
/// #![feature(slice_range)]
|
||||||
|
///
|
||||||
|
/// use std::slice;
|
||||||
|
///
|
||||||
|
/// slice::range(1..4, ..3);
|
||||||
|
/// ```
|
||||||
|
///
|
||||||
|
/// ```should_panic
|
||||||
|
/// #![feature(slice_range)]
|
||||||
|
///
|
||||||
|
/// use std::slice;
|
||||||
|
///
|
||||||
|
/// slice::range(1..=usize::MAX, ..3);
|
||||||
|
/// ```
|
||||||
|
///
|
||||||
|
/// [`Index::index`]: ops::Index::index
|
||||||
|
#[track_caller]
|
||||||
|
#[unstable(feature = "slice_range", issue = "76393")]
|
||||||
|
pub fn range<R>(range: R, bounds: ops::RangeTo<usize>) -> ops::Range<usize>
|
||||||
|
where
|
||||||
|
R: ops::RangeBounds<usize>,
|
||||||
|
{
|
||||||
|
let len = bounds.end;
|
||||||
|
|
||||||
|
let start: ops::Bound<&usize> = range.start_bound();
|
||||||
|
let start = match start {
|
||||||
|
ops::Bound::Included(&start) => start,
|
||||||
|
ops::Bound::Excluded(start) => {
|
||||||
|
start.checked_add(1).unwrap_or_else(|| slice_start_index_overflow_fail())
|
||||||
|
}
|
||||||
|
ops::Bound::Unbounded => 0,
|
||||||
|
};
|
||||||
|
|
||||||
|
let end: ops::Bound<&usize> = range.end_bound();
|
||||||
|
let end = match end {
|
||||||
|
ops::Bound::Included(end) => {
|
||||||
|
end.checked_add(1).unwrap_or_else(|| slice_end_index_overflow_fail())
|
||||||
|
}
|
||||||
|
ops::Bound::Excluded(&end) => end,
|
||||||
|
ops::Bound::Unbounded => len,
|
||||||
|
};
|
||||||
|
|
||||||
|
if start > end {
|
||||||
|
slice_index_order_fail(start, end);
|
||||||
|
}
|
||||||
|
if end > len {
|
||||||
|
slice_end_index_len_fail(end, len);
|
||||||
|
}
|
||||||
|
|
||||||
|
ops::Range { start, end }
|
||||||
|
}
|
||||||
|
@ -18,6 +18,7 @@
|
|||||||
use crate::ptr;
|
use crate::ptr;
|
||||||
use crate::result::Result;
|
use crate::result::Result;
|
||||||
use crate::result::Result::{Err, Ok};
|
use crate::result::Result::{Err, Ok};
|
||||||
|
use crate::slice;
|
||||||
|
|
||||||
#[unstable(
|
#[unstable(
|
||||||
feature = "slice_internals",
|
feature = "slice_internals",
|
||||||
@ -29,7 +30,7 @@
|
|||||||
|
|
||||||
mod ascii;
|
mod ascii;
|
||||||
mod cmp;
|
mod cmp;
|
||||||
pub(crate) mod index;
|
mod index;
|
||||||
mod iter;
|
mod iter;
|
||||||
mod raw;
|
mod raw;
|
||||||
mod rotate;
|
mod rotate;
|
||||||
@ -76,6 +77,9 @@
|
|||||||
#[stable(feature = "slice_get_slice", since = "1.28.0")]
|
#[stable(feature = "slice_get_slice", since = "1.28.0")]
|
||||||
pub use index::SliceIndex;
|
pub use index::SliceIndex;
|
||||||
|
|
||||||
|
#[unstable(feature = "slice_range", issue = "76393")]
|
||||||
|
pub use index::range;
|
||||||
|
|
||||||
#[lang = "slice"]
|
#[lang = "slice"]
|
||||||
#[cfg(not(test))]
|
#[cfg(not(test))]
|
||||||
impl<T> [T] {
|
impl<T> [T] {
|
||||||
@ -3052,7 +3056,7 @@ pub fn copy_within<R: RangeBounds<usize>>(&mut self, src: R, dest: usize)
|
|||||||
where
|
where
|
||||||
T: Copy,
|
T: Copy,
|
||||||
{
|
{
|
||||||
let Range { start: src_start, end: src_end } = Range::ensure_subset_of(src, ..self.len());
|
let Range { start: src_start, end: src_end } = slice::range(src, ..self.len());
|
||||||
let count = src_end - src_start;
|
let count = src_end - src_start;
|
||||||
assert!(dest <= self.len() - count, "dest is out of bounds");
|
assert!(dest <= self.len() - count, "dest is out of bounds");
|
||||||
// SAFETY: the conditions for `ptr::copy` have all been checked above,
|
// SAFETY: the conditions for `ptr::copy` have all been checked above,
|
||||||
|
Loading…
Reference in New Issue
Block a user