mirror of
https://github.com/rust-lang/rust.git
synced 2025-05-14 02:49:40 +00:00
Auto merge of #76787 - lzutao:slice_iters_new, r=lcnr
Using <Iter>::new instead of exposing internal fields As requested in https://github.com/rust-lang/rust/pull/76311#discussion_r487685126
This commit is contained in:
commit
c6ab8e5fe0
@ -8,7 +8,7 @@ use crate::cmp::Ordering;
|
||||
use crate::fmt;
|
||||
use crate::intrinsics::{assume, exact_div, unchecked_sub};
|
||||
use crate::iter::{FusedIterator, TrustedLen, TrustedRandomAccess};
|
||||
use crate::marker::{self, Send, Sized, Sync};
|
||||
use crate::marker::{PhantomData, Send, Sized, Sync};
|
||||
use crate::mem;
|
||||
use crate::ptr::NonNull;
|
||||
|
||||
@ -62,11 +62,11 @@ fn size_from_ptr<T>(_: *const T) -> usize {
|
||||
/// [slices]: ../../std/primitive.slice.html
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub struct Iter<'a, T: 'a> {
|
||||
pub(super) ptr: NonNull<T>,
|
||||
pub(super) end: *const T, // If T is a ZST, this is actually ptr+len. This encoding is picked so that
|
||||
ptr: NonNull<T>,
|
||||
end: *const T, // If T is a ZST, this is actually ptr+len. This encoding is picked so that
|
||||
// ptr == end is a quick test for the Iterator being empty, that works
|
||||
// for both ZST and non-ZST.
|
||||
pub(super) _marker: marker::PhantomData<&'a T>,
|
||||
_marker: PhantomData<&'a T>,
|
||||
}
|
||||
|
||||
#[stable(feature = "core_impl_debug", since = "1.9.0")]
|
||||
@ -82,6 +82,23 @@ unsafe impl<T: Sync> Sync for Iter<'_, T> {}
|
||||
unsafe impl<T: Sync> Send for Iter<'_, T> {}
|
||||
|
||||
impl<'a, T> Iter<'a, T> {
|
||||
#[inline]
|
||||
pub(super) fn new(slice: &'a [T]) -> Self {
|
||||
let ptr = slice.as_ptr();
|
||||
// SAFETY: Similar to `IterMut::new`.
|
||||
unsafe {
|
||||
assume(!ptr.is_null());
|
||||
|
||||
let end = if mem::size_of::<T>() == 0 {
|
||||
(ptr as *const u8).wrapping_add(slice.len()) as *const T
|
||||
} else {
|
||||
ptr.add(slice.len())
|
||||
};
|
||||
|
||||
Self { ptr: NonNull::new_unchecked(ptr as *mut T), end, _marker: PhantomData }
|
||||
}
|
||||
}
|
||||
|
||||
/// Views the underlying data as a subslice of the original data.
|
||||
///
|
||||
/// This has the same lifetime as the original slice, and so the
|
||||
@ -164,11 +181,11 @@ impl<T> AsRef<[T]> for Iter<'_, T> {
|
||||
/// [slices]: ../../std/primitive.slice.html
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub struct IterMut<'a, T: 'a> {
|
||||
pub(super) ptr: NonNull<T>,
|
||||
pub(super) end: *mut T, // If T is a ZST, this is actually ptr+len. This encoding is picked so that
|
||||
ptr: NonNull<T>,
|
||||
end: *mut T, // If T is a ZST, this is actually ptr+len. This encoding is picked so that
|
||||
// ptr == end is a quick test for the Iterator being empty, that works
|
||||
// for both ZST and non-ZST.
|
||||
pub(super) _marker: marker::PhantomData<&'a mut T>,
|
||||
_marker: PhantomData<&'a mut T>,
|
||||
}
|
||||
|
||||
#[stable(feature = "core_impl_debug", since = "1.9.0")]
|
||||
@ -184,6 +201,38 @@ unsafe impl<T: Sync> Sync for IterMut<'_, T> {}
|
||||
unsafe impl<T: Send> Send for IterMut<'_, T> {}
|
||||
|
||||
impl<'a, T> IterMut<'a, T> {
|
||||
#[inline]
|
||||
pub(super) fn new(slice: &'a mut [T]) -> Self {
|
||||
let ptr = slice.as_mut_ptr();
|
||||
// SAFETY: There are several things here:
|
||||
//
|
||||
// `ptr` has been obtained by `slice.as_ptr()` where `slice` is a valid
|
||||
// reference thus it is non-NUL and safe to use and pass to
|
||||
// `NonNull::new_unchecked` .
|
||||
//
|
||||
// Adding `slice.len()` to the starting pointer gives a pointer
|
||||
// at the end of `slice`. `end` will never be dereferenced, only checked
|
||||
// for direct pointer equality with `ptr` to check if the iterator is
|
||||
// done.
|
||||
//
|
||||
// In the case of a ZST, the end pointer is just the start pointer plus
|
||||
// the length, to also allows for the fast `ptr == end` check.
|
||||
//
|
||||
// See the `next_unchecked!` and `is_empty!` macros as well as the
|
||||
// `post_inc_start` method for more informations.
|
||||
unsafe {
|
||||
assume(!ptr.is_null());
|
||||
|
||||
let end = if mem::size_of::<T>() == 0 {
|
||||
(ptr as *mut u8).wrapping_add(slice.len()) as *mut T
|
||||
} else {
|
||||
ptr.add(slice.len())
|
||||
};
|
||||
|
||||
Self { ptr: NonNull::new_unchecked(ptr), end, _marker: PhantomData }
|
||||
}
|
||||
}
|
||||
|
||||
/// Views the underlying data as a subslice of the original data.
|
||||
///
|
||||
/// To avoid creating `&mut` references that alias, this is forced
|
||||
@ -277,9 +326,16 @@ pub struct Split<'a, T: 'a, P>
|
||||
where
|
||||
P: FnMut(&T) -> bool,
|
||||
{
|
||||
pub(super) v: &'a [T],
|
||||
pub(super) pred: P,
|
||||
pub(super) finished: bool,
|
||||
v: &'a [T],
|
||||
pred: P,
|
||||
finished: bool,
|
||||
}
|
||||
|
||||
impl<'a, T: 'a, P: FnMut(&T) -> bool> Split<'a, T, P> {
|
||||
#[inline]
|
||||
pub(super) fn new(slice: &'a [T], pred: P) -> Self {
|
||||
Self { v: slice, pred, finished: false }
|
||||
}
|
||||
}
|
||||
|
||||
#[stable(feature = "core_impl_debug", since = "1.9.0")]
|
||||
@ -385,9 +441,16 @@ pub struct SplitInclusive<'a, T: 'a, P>
|
||||
where
|
||||
P: FnMut(&T) -> bool,
|
||||
{
|
||||
pub(super) v: &'a [T],
|
||||
pub(super) pred: P,
|
||||
pub(super) finished: bool,
|
||||
v: &'a [T],
|
||||
pred: P,
|
||||
finished: bool,
|
||||
}
|
||||
|
||||
impl<'a, T: 'a, P: FnMut(&T) -> bool> SplitInclusive<'a, T, P> {
|
||||
#[inline]
|
||||
pub(super) fn new(slice: &'a [T], pred: P) -> Self {
|
||||
Self { v: slice, pred, finished: false }
|
||||
}
|
||||
}
|
||||
|
||||
#[unstable(feature = "split_inclusive", issue = "72360")]
|
||||
@ -483,9 +546,16 @@ pub struct SplitMut<'a, T: 'a, P>
|
||||
where
|
||||
P: FnMut(&T) -> bool,
|
||||
{
|
||||
pub(super) v: &'a mut [T],
|
||||
pub(super) pred: P,
|
||||
pub(super) finished: bool,
|
||||
v: &'a mut [T],
|
||||
pred: P,
|
||||
finished: bool,
|
||||
}
|
||||
|
||||
impl<'a, T: 'a, P: FnMut(&T) -> bool> SplitMut<'a, T, P> {
|
||||
#[inline]
|
||||
pub(super) fn new(slice: &'a mut [T], pred: P) -> Self {
|
||||
Self { v: slice, pred, finished: false }
|
||||
}
|
||||
}
|
||||
|
||||
#[stable(feature = "core_impl_debug", since = "1.9.0")]
|
||||
@ -598,9 +668,16 @@ pub struct SplitInclusiveMut<'a, T: 'a, P>
|
||||
where
|
||||
P: FnMut(&T) -> bool,
|
||||
{
|
||||
pub(super) v: &'a mut [T],
|
||||
pub(super) pred: P,
|
||||
pub(super) finished: bool,
|
||||
v: &'a mut [T],
|
||||
pred: P,
|
||||
finished: bool,
|
||||
}
|
||||
|
||||
impl<'a, T: 'a, P: FnMut(&T) -> bool> SplitInclusiveMut<'a, T, P> {
|
||||
#[inline]
|
||||
pub(super) fn new(slice: &'a mut [T], pred: P) -> Self {
|
||||
Self { v: slice, pred, finished: false }
|
||||
}
|
||||
}
|
||||
|
||||
#[unstable(feature = "split_inclusive", issue = "72360")]
|
||||
@ -706,7 +783,14 @@ pub struct RSplit<'a, T: 'a, P>
|
||||
where
|
||||
P: FnMut(&T) -> bool,
|
||||
{
|
||||
pub(super) inner: Split<'a, T, P>,
|
||||
inner: Split<'a, T, P>,
|
||||
}
|
||||
|
||||
impl<'a, T: 'a, P: FnMut(&T) -> bool> RSplit<'a, T, P> {
|
||||
#[inline]
|
||||
pub(super) fn new(slice: &'a [T], pred: P) -> Self {
|
||||
Self { inner: Split::new(slice, pred) }
|
||||
}
|
||||
}
|
||||
|
||||
#[stable(feature = "slice_rsplit", since = "1.27.0")]
|
||||
@ -777,7 +861,14 @@ pub struct RSplitMut<'a, T: 'a, P>
|
||||
where
|
||||
P: FnMut(&T) -> bool,
|
||||
{
|
||||
pub(super) inner: SplitMut<'a, T, P>,
|
||||
inner: SplitMut<'a, T, P>,
|
||||
}
|
||||
|
||||
impl<'a, T: 'a, P: FnMut(&T) -> bool> RSplitMut<'a, T, P> {
|
||||
#[inline]
|
||||
pub(super) fn new(slice: &'a mut [T], pred: P) -> Self {
|
||||
Self { inner: SplitMut::new(slice, pred) }
|
||||
}
|
||||
}
|
||||
|
||||
#[stable(feature = "slice_rsplit", since = "1.27.0")]
|
||||
@ -840,9 +931,9 @@ impl<T, P> FusedIterator for RSplitMut<'_, T, P> where P: FnMut(&T) -> bool {}
|
||||
/// match a predicate function, splitting at most a fixed number of
|
||||
/// times.
|
||||
#[derive(Debug)]
|
||||
pub(super) struct GenericSplitN<I> {
|
||||
pub(super) iter: I,
|
||||
pub(super) count: usize,
|
||||
struct GenericSplitN<I> {
|
||||
iter: I,
|
||||
count: usize,
|
||||
}
|
||||
|
||||
impl<T, I: SplitIter<Item = T>> Iterator for GenericSplitN<I> {
|
||||
@ -882,7 +973,14 @@ pub struct SplitN<'a, T: 'a, P>
|
||||
where
|
||||
P: FnMut(&T) -> bool,
|
||||
{
|
||||
pub(super) inner: GenericSplitN<Split<'a, T, P>>,
|
||||
inner: GenericSplitN<Split<'a, T, P>>,
|
||||
}
|
||||
|
||||
impl<'a, T: 'a, P: FnMut(&T) -> bool> SplitN<'a, T, P> {
|
||||
#[inline]
|
||||
pub(super) fn new(s: Split<'a, T, P>, n: usize) -> Self {
|
||||
Self { inner: GenericSplitN { iter: s, count: n } }
|
||||
}
|
||||
}
|
||||
|
||||
#[stable(feature = "core_impl_debug", since = "1.9.0")]
|
||||
@ -908,7 +1006,14 @@ pub struct RSplitN<'a, T: 'a, P>
|
||||
where
|
||||
P: FnMut(&T) -> bool,
|
||||
{
|
||||
pub(super) inner: GenericSplitN<RSplit<'a, T, P>>,
|
||||
inner: GenericSplitN<RSplit<'a, T, P>>,
|
||||
}
|
||||
|
||||
impl<'a, T: 'a, P: FnMut(&T) -> bool> RSplitN<'a, T, P> {
|
||||
#[inline]
|
||||
pub(super) fn new(s: RSplit<'a, T, P>, n: usize) -> Self {
|
||||
Self { inner: GenericSplitN { iter: s, count: n } }
|
||||
}
|
||||
}
|
||||
|
||||
#[stable(feature = "core_impl_debug", since = "1.9.0")]
|
||||
@ -933,7 +1038,14 @@ pub struct SplitNMut<'a, T: 'a, P>
|
||||
where
|
||||
P: FnMut(&T) -> bool,
|
||||
{
|
||||
pub(super) inner: GenericSplitN<SplitMut<'a, T, P>>,
|
||||
inner: GenericSplitN<SplitMut<'a, T, P>>,
|
||||
}
|
||||
|
||||
impl<'a, T: 'a, P: FnMut(&T) -> bool> SplitNMut<'a, T, P> {
|
||||
#[inline]
|
||||
pub(super) fn new(s: SplitMut<'a, T, P>, n: usize) -> Self {
|
||||
Self { inner: GenericSplitN { iter: s, count: n } }
|
||||
}
|
||||
}
|
||||
|
||||
#[stable(feature = "core_impl_debug", since = "1.9.0")]
|
||||
@ -959,7 +1071,14 @@ pub struct RSplitNMut<'a, T: 'a, P>
|
||||
where
|
||||
P: FnMut(&T) -> bool,
|
||||
{
|
||||
pub(super) inner: GenericSplitN<RSplitMut<'a, T, P>>,
|
||||
inner: GenericSplitN<RSplitMut<'a, T, P>>,
|
||||
}
|
||||
|
||||
impl<'a, T: 'a, P: FnMut(&T) -> bool> RSplitNMut<'a, T, P> {
|
||||
#[inline]
|
||||
pub(super) fn new(s: RSplitMut<'a, T, P>, n: usize) -> Self {
|
||||
Self { inner: GenericSplitN { iter: s, count: n } }
|
||||
}
|
||||
}
|
||||
|
||||
#[stable(feature = "core_impl_debug", since = "1.9.0")]
|
||||
@ -986,8 +1105,15 @@ forward_iterator! { RSplitNMut: T, &'a mut [T] }
|
||||
#[derive(Debug)]
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub struct Windows<'a, T: 'a> {
|
||||
pub(super) v: &'a [T],
|
||||
pub(super) size: usize,
|
||||
v: &'a [T],
|
||||
size: usize,
|
||||
}
|
||||
|
||||
impl<'a, T: 'a> Windows<'a, T> {
|
||||
#[inline]
|
||||
pub(super) fn new(slice: &'a [T], size: usize) -> Self {
|
||||
Self { v: slice, size }
|
||||
}
|
||||
}
|
||||
|
||||
// FIXME(#26925) Remove in favor of `#[derive(Clone)]`
|
||||
@ -1118,8 +1244,15 @@ unsafe impl<'a, T> TrustedRandomAccess for Windows<'a, T> {
|
||||
#[derive(Debug)]
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub struct Chunks<'a, T: 'a> {
|
||||
pub(super) v: &'a [T],
|
||||
pub(super) chunk_size: usize,
|
||||
v: &'a [T],
|
||||
chunk_size: usize,
|
||||
}
|
||||
|
||||
impl<'a, T: 'a> Chunks<'a, T> {
|
||||
#[inline]
|
||||
pub(super) fn new(slice: &'a [T], size: usize) -> Self {
|
||||
Self { v: slice, chunk_size: size }
|
||||
}
|
||||
}
|
||||
|
||||
// FIXME(#26925) Remove in favor of `#[derive(Clone)]`
|
||||
@ -1272,8 +1405,15 @@ unsafe impl<'a, T> TrustedRandomAccess for Chunks<'a, T> {
|
||||
#[derive(Debug)]
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub struct ChunksMut<'a, T: 'a> {
|
||||
pub(super) v: &'a mut [T],
|
||||
pub(super) chunk_size: usize,
|
||||
v: &'a mut [T],
|
||||
chunk_size: usize,
|
||||
}
|
||||
|
||||
impl<'a, T: 'a> ChunksMut<'a, T> {
|
||||
#[inline]
|
||||
pub(super) fn new(slice: &'a mut [T], size: usize) -> Self {
|
||||
Self { v: slice, chunk_size: size }
|
||||
}
|
||||
}
|
||||
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
@ -1425,12 +1565,21 @@ unsafe impl<'a, T> TrustedRandomAccess for ChunksMut<'a, T> {
|
||||
#[derive(Debug)]
|
||||
#[stable(feature = "chunks_exact", since = "1.31.0")]
|
||||
pub struct ChunksExact<'a, T: 'a> {
|
||||
pub(super) v: &'a [T],
|
||||
pub(super) rem: &'a [T],
|
||||
pub(super) chunk_size: usize,
|
||||
v: &'a [T],
|
||||
rem: &'a [T],
|
||||
chunk_size: usize,
|
||||
}
|
||||
|
||||
impl<'a, T> ChunksExact<'a, T> {
|
||||
#[inline]
|
||||
pub(super) fn new(slice: &'a [T], chunk_size: usize) -> Self {
|
||||
let rem = slice.len() % chunk_size;
|
||||
let fst_len = slice.len() - rem;
|
||||
// SAFETY: 0 <= fst_len <= slice.len() by construction above
|
||||
let (fst, snd) = unsafe { slice.split_at_unchecked(fst_len) };
|
||||
Self { v: fst, rem: snd, chunk_size }
|
||||
}
|
||||
|
||||
/// Returns the remainder of the original slice that is not going to be
|
||||
/// returned by the iterator. The returned slice has at most `chunk_size-1`
|
||||
/// elements.
|
||||
@ -1565,12 +1714,21 @@ unsafe impl<'a, T> TrustedRandomAccess for ChunksExact<'a, T> {
|
||||
#[derive(Debug)]
|
||||
#[stable(feature = "chunks_exact", since = "1.31.0")]
|
||||
pub struct ChunksExactMut<'a, T: 'a> {
|
||||
pub(super) v: &'a mut [T],
|
||||
pub(super) rem: &'a mut [T],
|
||||
pub(super) chunk_size: usize,
|
||||
v: &'a mut [T],
|
||||
rem: &'a mut [T],
|
||||
chunk_size: usize,
|
||||
}
|
||||
|
||||
impl<'a, T> ChunksExactMut<'a, T> {
|
||||
#[inline]
|
||||
pub(super) fn new(slice: &'a mut [T], chunk_size: usize) -> Self {
|
||||
let rem = slice.len() % chunk_size;
|
||||
let fst_len = slice.len() - rem;
|
||||
// SAFETY: 0 <= fst_len <= slice.len() by construction above
|
||||
let (fst, snd) = unsafe { slice.split_at_mut_unchecked(fst_len) };
|
||||
Self { v: fst, rem: snd, chunk_size }
|
||||
}
|
||||
|
||||
/// Returns the remainder of the original slice that is not going to be
|
||||
/// returned by the iterator. The returned slice has at most `chunk_size-1`
|
||||
/// elements.
|
||||
@ -1697,9 +1855,17 @@ unsafe impl<'a, T> TrustedRandomAccess for ChunksExactMut<'a, T> {
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
#[unstable(feature = "array_windows", issue = "75027")]
|
||||
pub struct ArrayWindows<'a, T: 'a, const N: usize> {
|
||||
pub(crate) slice_head: *const T,
|
||||
pub(crate) num: usize,
|
||||
pub(crate) marker: marker::PhantomData<&'a [T; N]>,
|
||||
slice_head: *const T,
|
||||
num: usize,
|
||||
marker: PhantomData<&'a [T; N]>,
|
||||
}
|
||||
|
||||
impl<'a, T: 'a, const N: usize> ArrayWindows<'a, T, N> {
|
||||
#[inline]
|
||||
pub(super) fn new(slice: &'a [T]) -> Self {
|
||||
let num_windows = slice.len().saturating_sub(N - 1);
|
||||
Self { slice_head: slice.as_ptr(), num: num_windows, marker: PhantomData }
|
||||
}
|
||||
}
|
||||
|
||||
#[unstable(feature = "array_windows", issue = "75027")]
|
||||
@ -1802,11 +1968,22 @@ impl<T, const N: usize> ExactSizeIterator for ArrayWindows<'_, T, N> {
|
||||
#[derive(Debug)]
|
||||
#[unstable(feature = "array_chunks", issue = "74985")]
|
||||
pub struct ArrayChunks<'a, T: 'a, const N: usize> {
|
||||
pub(super) iter: Iter<'a, [T; N]>,
|
||||
pub(super) rem: &'a [T],
|
||||
iter: Iter<'a, [T; N]>,
|
||||
rem: &'a [T],
|
||||
}
|
||||
|
||||
impl<'a, T, const N: usize> ArrayChunks<'a, T, N> {
|
||||
#[inline]
|
||||
pub(super) fn new(slice: &'a [T]) -> Self {
|
||||
let len = slice.len() / N;
|
||||
let (fst, snd) = slice.split_at(len * N);
|
||||
// SAFETY: We cast a slice of `len * N` elements into
|
||||
// a slice of `len` many `N` elements chunks.
|
||||
let array_slice: &[[T; N]] = unsafe { from_raw_parts(fst.as_ptr().cast(), len) };
|
||||
|
||||
Self { iter: array_slice.iter(), rem: snd }
|
||||
}
|
||||
|
||||
/// Returns the remainder of the original slice that is not going to be
|
||||
/// returned by the iterator. The returned slice has at most `N-1`
|
||||
/// elements.
|
||||
@ -1909,11 +2086,23 @@ unsafe impl<'a, T, const N: usize> TrustedRandomAccess for ArrayChunks<'a, T, N>
|
||||
#[derive(Debug)]
|
||||
#[unstable(feature = "array_chunks", issue = "74985")]
|
||||
pub struct ArrayChunksMut<'a, T: 'a, const N: usize> {
|
||||
pub(super) iter: IterMut<'a, [T; N]>,
|
||||
pub(super) rem: &'a mut [T],
|
||||
iter: IterMut<'a, [T; N]>,
|
||||
rem: &'a mut [T],
|
||||
}
|
||||
|
||||
impl<'a, T, const N: usize> ArrayChunksMut<'a, T, N> {
|
||||
#[inline]
|
||||
pub(super) fn new(slice: &'a mut [T]) -> Self {
|
||||
let len = slice.len() / N;
|
||||
let (fst, snd) = slice.split_at_mut(len * N);
|
||||
// SAFETY: We cast a slice of `len * N` elements into
|
||||
// a slice of `len` many `N` elements chunks.
|
||||
unsafe {
|
||||
let array_slice: &mut [[T; N]] = from_raw_parts_mut(fst.as_mut_ptr().cast(), len);
|
||||
Self { iter: array_slice.iter_mut(), rem: snd }
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns the remainder of the original slice that is not going to be
|
||||
/// returned by the iterator. The returned slice has at most `N-1`
|
||||
/// elements.
|
||||
@ -2006,8 +2195,15 @@ unsafe impl<'a, T, const N: usize> TrustedRandomAccess for ArrayChunksMut<'a, T,
|
||||
#[derive(Debug)]
|
||||
#[stable(feature = "rchunks", since = "1.31.0")]
|
||||
pub struct RChunks<'a, T: 'a> {
|
||||
pub(super) v: &'a [T],
|
||||
pub(super) chunk_size: usize,
|
||||
v: &'a [T],
|
||||
chunk_size: usize,
|
||||
}
|
||||
|
||||
impl<'a, T: 'a> RChunks<'a, T> {
|
||||
#[inline]
|
||||
pub(super) fn new(slice: &'a [T], size: usize) -> Self {
|
||||
Self { v: slice, chunk_size: size }
|
||||
}
|
||||
}
|
||||
|
||||
// FIXME(#26925) Remove in favor of `#[derive(Clone)]`
|
||||
@ -2156,8 +2352,15 @@ unsafe impl<'a, T> TrustedRandomAccess for RChunks<'a, T> {
|
||||
#[derive(Debug)]
|
||||
#[stable(feature = "rchunks", since = "1.31.0")]
|
||||
pub struct RChunksMut<'a, T: 'a> {
|
||||
pub(super) v: &'a mut [T],
|
||||
pub(super) chunk_size: usize,
|
||||
v: &'a mut [T],
|
||||
chunk_size: usize,
|
||||
}
|
||||
|
||||
impl<'a, T: 'a> RChunksMut<'a, T> {
|
||||
#[inline]
|
||||
pub(super) fn new(slice: &'a mut [T], size: usize) -> Self {
|
||||
Self { v: slice, chunk_size: size }
|
||||
}
|
||||
}
|
||||
|
||||
#[stable(feature = "rchunks", since = "1.31.0")]
|
||||
@ -2306,12 +2509,20 @@ unsafe impl<'a, T> TrustedRandomAccess for RChunksMut<'a, T> {
|
||||
#[derive(Debug)]
|
||||
#[stable(feature = "rchunks", since = "1.31.0")]
|
||||
pub struct RChunksExact<'a, T: 'a> {
|
||||
pub(super) v: &'a [T],
|
||||
pub(super) rem: &'a [T],
|
||||
pub(super) chunk_size: usize,
|
||||
v: &'a [T],
|
||||
rem: &'a [T],
|
||||
chunk_size: usize,
|
||||
}
|
||||
|
||||
impl<'a, T> RChunksExact<'a, T> {
|
||||
#[inline]
|
||||
pub(super) fn new(slice: &'a [T], chunk_size: usize) -> Self {
|
||||
let rem = slice.len() % chunk_size;
|
||||
// SAFETY: 0 <= rem <= slice.len() by construction above
|
||||
let (fst, snd) = unsafe { slice.split_at_unchecked(rem) };
|
||||
Self { v: snd, rem: fst, chunk_size }
|
||||
}
|
||||
|
||||
/// Returns the remainder of the original slice that is not going to be
|
||||
/// returned by the iterator. The returned slice has at most `chunk_size-1`
|
||||
/// elements.
|
||||
@ -2451,12 +2662,20 @@ unsafe impl<'a, T> TrustedRandomAccess for RChunksExact<'a, T> {
|
||||
#[derive(Debug)]
|
||||
#[stable(feature = "rchunks", since = "1.31.0")]
|
||||
pub struct RChunksExactMut<'a, T: 'a> {
|
||||
pub(super) v: &'a mut [T],
|
||||
pub(super) rem: &'a mut [T],
|
||||
pub(super) chunk_size: usize,
|
||||
v: &'a mut [T],
|
||||
rem: &'a mut [T],
|
||||
chunk_size: usize,
|
||||
}
|
||||
|
||||
impl<'a, T> RChunksExactMut<'a, T> {
|
||||
#[inline]
|
||||
pub(super) fn new(slice: &'a mut [T], chunk_size: usize) -> Self {
|
||||
let rem = slice.len() % chunk_size;
|
||||
// SAFETY: 0 <= rem <= slice.len() by construction above
|
||||
let (fst, snd) = unsafe { slice.split_at_mut_unchecked(rem) };
|
||||
Self { v: snd, rem: fst, chunk_size }
|
||||
}
|
||||
|
||||
/// Returns the remainder of the original slice that is not going to be
|
||||
/// returned by the iterator. The returned slice has at most `chunk_size-1`
|
||||
/// elements.
|
||||
|
@ -9,13 +9,12 @@
|
||||
#![stable(feature = "rust1", since = "1.0.0")]
|
||||
|
||||
use crate::cmp::Ordering::{self, Equal, Greater, Less};
|
||||
use crate::intrinsics::assume;
|
||||
use crate::marker::{self, Copy};
|
||||
use crate::marker::Copy;
|
||||
use crate::mem;
|
||||
use crate::ops::{FnMut, Range, RangeBounds};
|
||||
use crate::option::Option;
|
||||
use crate::option::Option::{None, Some};
|
||||
use crate::ptr::{self, NonNull};
|
||||
use crate::ptr;
|
||||
use crate::result::Result;
|
||||
use crate::result::Result::{Err, Ok};
|
||||
|
||||
@ -35,8 +34,6 @@ mod raw;
|
||||
mod rotate;
|
||||
mod sort;
|
||||
|
||||
use iter::GenericSplitN;
|
||||
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub use iter::{Chunks, ChunksMut, Windows};
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
@ -681,34 +678,7 @@ impl<T> [T] {
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[inline]
|
||||
pub fn iter(&self) -> Iter<'_, T> {
|
||||
let ptr = self.as_ptr();
|
||||
// SAFETY: There are several things here:
|
||||
//
|
||||
// `ptr` has been obtained by `self.as_ptr()` where `self` is a valid
|
||||
// reference thus it is non-NUL and safe to use and pass to
|
||||
// `NonNull::new_unchecked` .
|
||||
//
|
||||
// Adding `self.len()` to the starting pointer gives a pointer
|
||||
// at the end of `self`. `end` will never be dereferenced, only checked
|
||||
// for direct pointer equality with `ptr` to check if the iterator is
|
||||
// done.
|
||||
//
|
||||
// In the case of a ZST, the end pointer is just the start pointer plus
|
||||
// the length, to also allows for the fast `ptr == end` check.
|
||||
//
|
||||
// See the `next_unchecked!` and `is_empty!` macros as well as the
|
||||
// `post_inc_start` method for more informations.
|
||||
unsafe {
|
||||
assume(!ptr.is_null());
|
||||
|
||||
let end = if mem::size_of::<T>() == 0 {
|
||||
(ptr as *const u8).wrapping_add(self.len()) as *const T
|
||||
} else {
|
||||
ptr.add(self.len())
|
||||
};
|
||||
|
||||
Iter { ptr: NonNull::new_unchecked(ptr as *mut T), end, _marker: marker::PhantomData }
|
||||
}
|
||||
Iter::new(self)
|
||||
}
|
||||
|
||||
/// Returns an iterator that allows modifying each value.
|
||||
@ -725,34 +695,7 @@ impl<T> [T] {
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[inline]
|
||||
pub fn iter_mut(&mut self) -> IterMut<'_, T> {
|
||||
let ptr = self.as_mut_ptr();
|
||||
// SAFETY: There are several things here:
|
||||
//
|
||||
// `ptr` has been obtained by `self.as_ptr()` where `self` is a valid
|
||||
// reference thus it is non-NUL and safe to use and pass to
|
||||
// `NonNull::new_unchecked` .
|
||||
//
|
||||
// Adding `self.len()` to the starting pointer gives a pointer
|
||||
// at the end of `self`. `end` will never be dereferenced, only checked
|
||||
// for direct pointer equality with `ptr` to check if the iterator is
|
||||
// done.
|
||||
//
|
||||
// In the case of a ZST, the end pointer is just the start pointer plus
|
||||
// the length, to also allows for the fast `ptr == end` check.
|
||||
//
|
||||
// See the `next_unchecked!` and `is_empty!` macros as well as the
|
||||
// `post_inc_start` method for more informations.
|
||||
unsafe {
|
||||
assume(!ptr.is_null());
|
||||
|
||||
let end = if mem::size_of::<T>() == 0 {
|
||||
(ptr as *mut u8).wrapping_add(self.len()) as *mut T
|
||||
} else {
|
||||
ptr.add(self.len())
|
||||
};
|
||||
|
||||
IterMut { ptr: NonNull::new_unchecked(ptr), end, _marker: marker::PhantomData }
|
||||
}
|
||||
IterMut::new(self)
|
||||
}
|
||||
|
||||
/// Returns an iterator over all contiguous windows of length
|
||||
@ -785,7 +728,7 @@ impl<T> [T] {
|
||||
#[inline]
|
||||
pub fn windows(&self, size: usize) -> Windows<'_, T> {
|
||||
assert_ne!(size, 0);
|
||||
Windows { v: self, size }
|
||||
Windows::new(self, size)
|
||||
}
|
||||
|
||||
/// Returns an iterator over `chunk_size` elements of the slice at a time, starting at the
|
||||
@ -819,7 +762,7 @@ impl<T> [T] {
|
||||
#[inline]
|
||||
pub fn chunks(&self, chunk_size: usize) -> Chunks<'_, T> {
|
||||
assert_ne!(chunk_size, 0);
|
||||
Chunks { v: self, chunk_size }
|
||||
Chunks::new(self, chunk_size)
|
||||
}
|
||||
|
||||
/// Returns an iterator over `chunk_size` elements of the slice at a time, starting at the
|
||||
@ -857,7 +800,7 @@ impl<T> [T] {
|
||||
#[inline]
|
||||
pub fn chunks_mut(&mut self, chunk_size: usize) -> ChunksMut<'_, T> {
|
||||
assert_ne!(chunk_size, 0);
|
||||
ChunksMut { v: self, chunk_size }
|
||||
ChunksMut::new(self, chunk_size)
|
||||
}
|
||||
|
||||
/// Returns an iterator over `chunk_size` elements of the slice at a time, starting at the
|
||||
@ -894,11 +837,7 @@ impl<T> [T] {
|
||||
#[inline]
|
||||
pub fn chunks_exact(&self, chunk_size: usize) -> ChunksExact<'_, T> {
|
||||
assert_ne!(chunk_size, 0);
|
||||
let rem = self.len() % chunk_size;
|
||||
let fst_len = self.len() - rem;
|
||||
// SAFETY: 0 <= fst_len <= self.len() by construction above
|
||||
let (fst, snd) = unsafe { self.split_at_unchecked(fst_len) };
|
||||
ChunksExact { v: fst, rem: snd, chunk_size }
|
||||
ChunksExact::new(self, chunk_size)
|
||||
}
|
||||
|
||||
/// Returns an iterator over `chunk_size` elements of the slice at a time, starting at the
|
||||
@ -940,11 +879,7 @@ impl<T> [T] {
|
||||
#[inline]
|
||||
pub fn chunks_exact_mut(&mut self, chunk_size: usize) -> ChunksExactMut<'_, T> {
|
||||
assert_ne!(chunk_size, 0);
|
||||
let rem = self.len() % chunk_size;
|
||||
let fst_len = self.len() - rem;
|
||||
// SAFETY: 0 <= fst_len <= self.len() by construction above
|
||||
let (fst, snd) = unsafe { self.split_at_mut_unchecked(fst_len) };
|
||||
ChunksExactMut { v: fst, rem: snd, chunk_size }
|
||||
ChunksExactMut::new(self, chunk_size)
|
||||
}
|
||||
|
||||
/// Returns an iterator over `N` elements of the slice at a time, starting at the
|
||||
@ -978,12 +913,7 @@ impl<T> [T] {
|
||||
#[inline]
|
||||
pub fn array_chunks<const N: usize>(&self) -> ArrayChunks<'_, T, N> {
|
||||
assert_ne!(N, 0);
|
||||
let len = self.len() / N;
|
||||
let (fst, snd) = self.split_at(len * N);
|
||||
// SAFETY: We cast a slice of `len * N` elements into
|
||||
// a slice of `len` many `N` elements chunks.
|
||||
let array_slice: &[[T; N]] = unsafe { from_raw_parts(fst.as_ptr().cast(), len) };
|
||||
ArrayChunks { iter: array_slice.iter(), rem: snd }
|
||||
ArrayChunks::new(self)
|
||||
}
|
||||
|
||||
/// Returns an iterator over `N` elements of the slice at a time, starting at the
|
||||
@ -1019,14 +949,7 @@ impl<T> [T] {
|
||||
#[inline]
|
||||
pub fn array_chunks_mut<const N: usize>(&mut self) -> ArrayChunksMut<'_, T, N> {
|
||||
assert_ne!(N, 0);
|
||||
let len = self.len() / N;
|
||||
let (fst, snd) = self.split_at_mut(len * N);
|
||||
// SAFETY: We cast a slice of `len * N` elements into
|
||||
// a slice of `len` many `N` elements chunks.
|
||||
unsafe {
|
||||
let array_slice: &mut [[T; N]] = from_raw_parts_mut(fst.as_mut_ptr().cast(), len);
|
||||
ArrayChunksMut { iter: array_slice.iter_mut(), rem: snd }
|
||||
}
|
||||
ArrayChunksMut::new(self)
|
||||
}
|
||||
|
||||
/// Returns an iterator over overlapping windows of `N` elements of a slice,
|
||||
@ -1058,9 +981,7 @@ impl<T> [T] {
|
||||
#[inline]
|
||||
pub fn array_windows<const N: usize>(&self) -> ArrayWindows<'_, T, N> {
|
||||
assert_ne!(N, 0);
|
||||
|
||||
let num_windows = self.len().saturating_sub(N - 1);
|
||||
ArrayWindows { slice_head: self.as_ptr(), num: num_windows, marker: marker::PhantomData }
|
||||
ArrayWindows::new(self)
|
||||
}
|
||||
|
||||
/// Returns an iterator over `chunk_size` elements of the slice at a time, starting at the end
|
||||
@ -1094,7 +1015,7 @@ impl<T> [T] {
|
||||
#[inline]
|
||||
pub fn rchunks(&self, chunk_size: usize) -> RChunks<'_, T> {
|
||||
assert!(chunk_size != 0);
|
||||
RChunks { v: self, chunk_size }
|
||||
RChunks::new(self, chunk_size)
|
||||
}
|
||||
|
||||
/// Returns an iterator over `chunk_size` elements of the slice at a time, starting at the end
|
||||
@ -1132,7 +1053,7 @@ impl<T> [T] {
|
||||
#[inline]
|
||||
pub fn rchunks_mut(&mut self, chunk_size: usize) -> RChunksMut<'_, T> {
|
||||
assert!(chunk_size != 0);
|
||||
RChunksMut { v: self, chunk_size }
|
||||
RChunksMut::new(self, chunk_size)
|
||||
}
|
||||
|
||||
/// Returns an iterator over `chunk_size` elements of the slice at a time, starting at the
|
||||
@ -1171,10 +1092,7 @@ impl<T> [T] {
|
||||
#[inline]
|
||||
pub fn rchunks_exact(&self, chunk_size: usize) -> RChunksExact<'_, T> {
|
||||
assert!(chunk_size != 0);
|
||||
let rem = self.len() % chunk_size;
|
||||
// SAFETY: 0 <= rem <= self.len() by construction above
|
||||
let (fst, snd) = unsafe { self.split_at_unchecked(rem) };
|
||||
RChunksExact { v: snd, rem: fst, chunk_size }
|
||||
RChunksExact::new(self, chunk_size)
|
||||
}
|
||||
|
||||
/// Returns an iterator over `chunk_size` elements of the slice at a time, starting at the end
|
||||
@ -1217,10 +1135,7 @@ impl<T> [T] {
|
||||
#[inline]
|
||||
pub fn rchunks_exact_mut(&mut self, chunk_size: usize) -> RChunksExactMut<'_, T> {
|
||||
assert!(chunk_size != 0);
|
||||
let rem = self.len() % chunk_size;
|
||||
// SAFETY: 0 <= rem <= self.len() by construction above
|
||||
let (fst, snd) = unsafe { self.split_at_mut_unchecked(rem) };
|
||||
RChunksExactMut { v: snd, rem: fst, chunk_size }
|
||||
RChunksExactMut::new(self, chunk_size)
|
||||
}
|
||||
|
||||
/// Divides one slice into two at an index.
|
||||
@ -1439,7 +1354,7 @@ impl<T> [T] {
|
||||
where
|
||||
F: FnMut(&T) -> bool,
|
||||
{
|
||||
Split { v: self, pred, finished: false }
|
||||
Split::new(self, pred)
|
||||
}
|
||||
|
||||
/// Returns an iterator over mutable subslices separated by elements that
|
||||
@ -1461,7 +1376,7 @@ impl<T> [T] {
|
||||
where
|
||||
F: FnMut(&T) -> bool,
|
||||
{
|
||||
SplitMut { v: self, pred, finished: false }
|
||||
SplitMut::new(self, pred)
|
||||
}
|
||||
|
||||
/// Returns an iterator over subslices separated by elements that match
|
||||
@ -1499,7 +1414,7 @@ impl<T> [T] {
|
||||
where
|
||||
F: FnMut(&T) -> bool,
|
||||
{
|
||||
SplitInclusive { v: self, pred, finished: false }
|
||||
SplitInclusive::new(self, pred)
|
||||
}
|
||||
|
||||
/// Returns an iterator over mutable subslices separated by elements that
|
||||
@ -1524,7 +1439,7 @@ impl<T> [T] {
|
||||
where
|
||||
F: FnMut(&T) -> bool,
|
||||
{
|
||||
SplitInclusiveMut { v: self, pred, finished: false }
|
||||
SplitInclusiveMut::new(self, pred)
|
||||
}
|
||||
|
||||
/// Returns an iterator over subslices separated by elements that match
|
||||
@ -1560,7 +1475,7 @@ impl<T> [T] {
|
||||
where
|
||||
F: FnMut(&T) -> bool,
|
||||
{
|
||||
RSplit { inner: self.split(pred) }
|
||||
RSplit::new(self, pred)
|
||||
}
|
||||
|
||||
/// Returns an iterator over mutable subslices separated by elements that
|
||||
@ -1586,7 +1501,7 @@ impl<T> [T] {
|
||||
where
|
||||
F: FnMut(&T) -> bool,
|
||||
{
|
||||
RSplitMut { inner: self.split_mut(pred) }
|
||||
RSplitMut::new(self, pred)
|
||||
}
|
||||
|
||||
/// Returns an iterator over subslices separated by elements that match
|
||||
@ -1614,7 +1529,7 @@ impl<T> [T] {
|
||||
where
|
||||
F: FnMut(&T) -> bool,
|
||||
{
|
||||
SplitN { inner: GenericSplitN { iter: self.split(pred), count: n } }
|
||||
SplitN::new(self.split(pred), n)
|
||||
}
|
||||
|
||||
/// Returns an iterator over subslices separated by elements that match
|
||||
@ -1640,7 +1555,7 @@ impl<T> [T] {
|
||||
where
|
||||
F: FnMut(&T) -> bool,
|
||||
{
|
||||
SplitNMut { inner: GenericSplitN { iter: self.split_mut(pred), count: n } }
|
||||
SplitNMut::new(self.split_mut(pred), n)
|
||||
}
|
||||
|
||||
/// Returns an iterator over subslices separated by elements that match
|
||||
@ -1669,7 +1584,7 @@ impl<T> [T] {
|
||||
where
|
||||
F: FnMut(&T) -> bool,
|
||||
{
|
||||
RSplitN { inner: GenericSplitN { iter: self.rsplit(pred), count: n } }
|
||||
RSplitN::new(self.rsplit(pred), n)
|
||||
}
|
||||
|
||||
/// Returns an iterator over subslices separated by elements that match
|
||||
@ -1696,7 +1611,7 @@ impl<T> [T] {
|
||||
where
|
||||
F: FnMut(&T) -> bool,
|
||||
{
|
||||
RSplitNMut { inner: GenericSplitN { iter: self.rsplit_mut(pred), count: n } }
|
||||
RSplitNMut::new(self.rsplit_mut(pred), n)
|
||||
}
|
||||
|
||||
/// Returns `true` if the slice contains an element with the given value.
|
||||
|
Loading…
Reference in New Issue
Block a user