Move unsafe code of slice new function of their Iterator structs

Init false state in Split* constructors
This commit is contained in:
Lzu Tao 2020-09-17 09:14:28 +00:00
parent 9fe9c6da3e
commit 53d5261c69
2 changed files with 126 additions and 145 deletions

View File

@ -82,8 +82,20 @@ unsafe impl<T: Sync> Sync for Iter<'_, T> {}
unsafe impl<T: Sync> Send for Iter<'_, T> {}
impl<'a, T> Iter<'a, T> {
pub(super) fn new(ptr: NonNull<T>, end: *const T) -> Self {
Self { ptr, end, _marker: PhantomData }
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.
@ -188,8 +200,35 @@ unsafe impl<T: Sync> Sync for IterMut<'_, T> {}
unsafe impl<T: Send> Send for IterMut<'_, T> {}
impl<'a, T> IterMut<'a, T> {
pub(super) fn new(ptr: NonNull<T>, end: *mut T) -> Self {
Self { ptr, end, _marker: PhantomData }
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.
@ -291,8 +330,8 @@ where
}
impl<'a, T: 'a, P: FnMut(&T) -> bool> Split<'a, T, P> {
pub(super) fn new(slice: &'a [T], pred: P, finished: bool) -> Self {
Self { v: slice, pred, finished }
pub(super) fn new(slice: &'a [T], pred: P) -> Self {
Self { v: slice, pred, finished: false }
}
}
@ -405,8 +444,9 @@ where
}
impl<'a, T: 'a, P: FnMut(&T) -> bool> SplitInclusive<'a, T, P> {
pub(super) fn new(slice: &'a [T], pred: P, finished: bool) -> Self {
Self { v: slice, pred, finished }
#[inline]
pub(super) fn new(slice: &'a [T], pred: P) -> Self {
Self { v: slice, pred, finished: false }
}
}
@ -509,8 +549,9 @@ where
}
impl<'a, T: 'a, P: FnMut(&T) -> bool> SplitMut<'a, T, P> {
pub(super) fn new(slice: &'a mut [T], pred: P, finished: bool) -> Self {
Self { v: slice, pred, finished }
#[inline]
pub(super) fn new(slice: &'a mut [T], pred: P) -> Self {
Self { v: slice, pred, finished: false }
}
}
@ -630,8 +671,9 @@ where
}
impl<'a, T: 'a, P: FnMut(&T) -> bool> SplitInclusiveMut<'a, T, P> {
pub(super) fn new(slice: &'a mut [T], pred: P, finished: bool) -> Self {
Self { v: slice, pred, finished }
#[inline]
pub(super) fn new(slice: &'a mut [T], pred: P) -> Self {
Self { v: slice, pred, finished: false }
}
}
@ -742,8 +784,9 @@ where
}
impl<'a, T: 'a, P: FnMut(&T) -> bool> RSplit<'a, T, P> {
pub(super) fn new(slice: &'a [T], pred: P, finished: bool) -> Self {
Self { inner: Split::new(slice, pred, finished) }
#[inline]
pub(super) fn new(slice: &'a [T], pred: P) -> Self {
Self { inner: Split::new(slice, pred) }
}
}
@ -819,8 +862,9 @@ where
}
impl<'a, T: 'a, P: FnMut(&T) -> bool> RSplitMut<'a, T, P> {
pub(super) fn new(slice: &'a mut [T], pred: P, finished: bool) -> Self {
Self { inner: SplitMut::new(slice, pred, finished) }
#[inline]
pub(super) fn new(slice: &'a mut [T], pred: P) -> Self {
Self { inner: SplitMut::new(slice, pred) }
}
}
@ -1516,13 +1560,15 @@ pub struct ChunksExact<'a, T: 'a> {
chunk_size: usize,
}
impl<'a, T: 'a> ChunksExact<'a, T> {
pub(super) fn new(slice: &'a [T], rem: &'a [T], size: usize) -> Self {
Self { v: slice, rem, chunk_size: size }
}
}
impl<'a, T> ChunksExact<'a, T> {
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.
@ -1662,13 +1708,15 @@ pub struct ChunksExactMut<'a, T: 'a> {
chunk_size: usize,
}
impl<'a, T: 'a> ChunksExactMut<'a, T> {
pub(super) fn new(slice: &'a mut [T], rem: &'a mut [T], size: usize) -> Self {
Self { v: slice, rem, chunk_size: size }
}
}
impl<'a, T> ChunksExactMut<'a, T> {
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.
@ -1801,8 +1849,9 @@ pub struct ArrayWindows<'a, T: 'a, const N: usize> {
}
impl<'a, T: 'a, const N: usize> ArrayWindows<'a, T, N> {
pub(super) fn new(head: *const T, num: usize) -> Self {
Self { slice_head: head, num, marker: PhantomData }
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 }
}
}
@ -1910,13 +1959,17 @@ pub struct ArrayChunks<'a, T: 'a, const N: usize> {
rem: &'a [T],
}
impl<'a, T: 'a, const N: usize> ArrayChunks<'a, T, N> {
pub(super) fn new(iter: Iter<'a, [T; N]>, rem: &'a [T]) -> Self {
Self { iter, rem }
}
}
impl<'a, T, const N: usize> ArrayChunks<'a, T, N> {
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.
@ -2023,13 +2076,18 @@ pub struct ArrayChunksMut<'a, T: 'a, const N: usize> {
rem: &'a mut [T],
}
impl<'a, T: 'a, const N: usize> ArrayChunksMut<'a, T, N> {
pub(super) fn new(iter: IterMut<'a, [T; N]>, rem: &'a mut [T]) -> Self {
Self { iter, rem }
}
}
impl<'a, T, const N: usize> ArrayChunksMut<'a, T, N> {
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.
@ -2440,8 +2498,11 @@ pub struct RChunksExact<'a, T: 'a> {
}
impl<'a, T> RChunksExact<'a, T> {
pub(super) fn new(slice: &'a [T], rem: &'a [T], size: usize) -> Self {
Self { v: slice, rem, chunk_size: size }
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
@ -2589,8 +2650,11 @@ pub struct RChunksExactMut<'a, T: 'a> {
}
impl<'a, T> RChunksExactMut<'a, T> {
pub(super) fn new(slice: &'a mut [T], rem: &'a mut [T], size: usize) -> Self {
Self { v: slice, rem, chunk_size: size }
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

View File

@ -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::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};
@ -679,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::new(NonNull::new_unchecked(ptr as *mut T), end)
}
Iter::new(self)
}
/// Returns an iterator that allows modifying each value.
@ -723,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::new(NonNull::new_unchecked(ptr), end)
}
IterMut::new(self)
}
/// Returns an iterator over all contiguous windows of length
@ -892,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::new(fst, snd, chunk_size)
ChunksExact::new(self, chunk_size)
}
/// Returns an iterator over `chunk_size` elements of the slice at a time, starting at the
@ -938,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::new(fst, snd, chunk_size)
ChunksExactMut::new(self, chunk_size)
}
/// Returns an iterator over `N` elements of the slice at a time, starting at the
@ -976,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::new(array_slice.iter(), snd)
ArrayChunks::new(self)
}
/// Returns an iterator over `N` elements of the slice at a time, starting at the
@ -1017,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::new(array_slice.iter_mut(), snd)
}
ArrayChunksMut::new(self)
}
/// Returns an iterator over overlapping windows of `N` elements of a slice,
@ -1056,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::new(self.as_ptr(), num_windows)
ArrayWindows::new(self)
}
/// Returns an iterator over `chunk_size` elements of the slice at a time, starting at the end
@ -1169,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::new(snd, 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
@ -1215,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::new(snd, fst, chunk_size)
RChunksExactMut::new(self, chunk_size)
}
/// Divides one slice into two at an index.
@ -1437,7 +1354,7 @@ impl<T> [T] {
where
F: FnMut(&T) -> bool,
{
Split::new(self, pred, false)
Split::new(self, pred)
}
/// Returns an iterator over mutable subslices separated by elements that
@ -1459,7 +1376,7 @@ impl<T> [T] {
where
F: FnMut(&T) -> bool,
{
SplitMut::new(self, pred, false)
SplitMut::new(self, pred)
}
/// Returns an iterator over subslices separated by elements that match
@ -1497,7 +1414,7 @@ impl<T> [T] {
where
F: FnMut(&T) -> bool,
{
SplitInclusive::new(self, pred, false)
SplitInclusive::new(self, pred)
}
/// Returns an iterator over mutable subslices separated by elements that
@ -1522,7 +1439,7 @@ impl<T> [T] {
where
F: FnMut(&T) -> bool,
{
SplitInclusiveMut::new(self, pred, false)
SplitInclusiveMut::new(self, pred)
}
/// Returns an iterator over subslices separated by elements that match
@ -1558,7 +1475,7 @@ impl<T> [T] {
where
F: FnMut(&T) -> bool,
{
RSplit::new(self, pred, false)
RSplit::new(self, pred)
}
/// Returns an iterator over mutable subslices separated by elements that
@ -1584,7 +1501,7 @@ impl<T> [T] {
where
F: FnMut(&T) -> bool,
{
RSplitMut::new(self, pred, false)
RSplitMut::new(self, pred)
}
/// Returns an iterator over subslices separated by elements that match