summaryrefslogtreecommitdiffstats
path: root/library/core/src/slice
diff options
context:
space:
mode:
Diffstat (limited to 'library/core/src/slice')
-rw-r--r--library/core/src/slice/index.rs14
-rw-r--r--library/core/src/slice/iter.rs4
-rw-r--r--library/core/src/slice/iter/macros.rs22
-rw-r--r--library/core/src/slice/mod.rs30
-rw-r--r--library/core/src/slice/sort.rs2
5 files changed, 46 insertions, 26 deletions
diff --git a/library/core/src/slice/index.rs b/library/core/src/slice/index.rs
index c295a0e06..353935324 100644
--- a/library/core/src/slice/index.rs
+++ b/library/core/src/slice/index.rs
@@ -2,6 +2,7 @@
use crate::intrinsics::assert_unsafe_precondition;
use crate::intrinsics::const_eval_select;
+use crate::intrinsics::unchecked_sub;
use crate::ops;
use crate::ptr;
@@ -371,25 +372,25 @@ unsafe impl<T> const SliceIndex<[T]> for ops::Range<usize> {
#[inline]
unsafe fn get_unchecked(self, slice: *const [T]) -> *const [T] {
- let this = ops::Range { start: self.start, end: self.end };
+ let this = ops::Range { ..self };
// SAFETY: the caller guarantees that `slice` is not dangling, so it
// cannot be longer than `isize::MAX`. They also guarantee that
// `self` is in bounds of `slice` so `self` cannot overflow an `isize`,
- // so the call to `add` is safe.
-
+ // so the call to `add` is safe and the length calculation cannot overflow.
unsafe {
assert_unsafe_precondition!(
"slice::get_unchecked requires that the range is within the slice",
[T](this: ops::Range<usize>, slice: *const [T]) =>
this.end >= this.start && this.end <= slice.len()
);
- ptr::slice_from_raw_parts(slice.as_ptr().add(self.start), self.end - self.start)
+ let new_len = unchecked_sub(self.end, self.start);
+ ptr::slice_from_raw_parts(slice.as_ptr().add(self.start), new_len)
}
}
#[inline]
unsafe fn get_unchecked_mut(self, slice: *mut [T]) -> *mut [T] {
- let this = ops::Range { start: self.start, end: self.end };
+ let this = ops::Range { ..self };
// SAFETY: see comments for `get_unchecked` above.
unsafe {
assert_unsafe_precondition!(
@@ -397,7 +398,8 @@ unsafe impl<T> const SliceIndex<[T]> for ops::Range<usize> {
[T](this: ops::Range<usize>, slice: *mut [T]) =>
this.end >= this.start && this.end <= slice.len()
);
- ptr::slice_from_raw_parts_mut(slice.as_mut_ptr().add(self.start), self.end - self.start)
+ let new_len = unchecked_sub(self.end, self.start);
+ ptr::slice_from_raw_parts_mut(slice.as_mut_ptr().add(self.start), new_len)
}
}
diff --git a/library/core/src/slice/iter.rs b/library/core/src/slice/iter.rs
index c4317799b..88b84bd13 100644
--- a/library/core/src/slice/iter.rs
+++ b/library/core/src/slice/iter.rs
@@ -132,9 +132,7 @@ iterator! {struct Iter -> *const T, &'a T, const, {/* no mut */}, {
Self: Sized,
F: FnMut(&Self::Item, &Self::Item) -> Option<Ordering>,
{
- self.as_slice().windows(2).all(|w| {
- compare(&&w[0], &&w[1]).map(|o| o != Ordering::Greater).unwrap_or(false)
- })
+ self.as_slice().is_sorted_by(|a, b| compare(&a, &b))
}
}}
diff --git a/library/core/src/slice/iter/macros.rs b/library/core/src/slice/iter/macros.rs
index 89b92a7d5..392752f2a 100644
--- a/library/core/src/slice/iter/macros.rs
+++ b/library/core/src/slice/iter/macros.rs
@@ -176,11 +176,11 @@ macro_rules! iterator {
}
#[inline]
- fn advance_by(&mut self, n: usize) -> Result<(), usize> {
+ fn advance_by(&mut self, n: usize) -> Result<(), NonZeroUsize> {
let advance = cmp::min(len!(self), n);
// SAFETY: By construction, `advance` does not exceed `self.len()`.
unsafe { self.post_inc_start(advance) };
- if advance == n { Ok(()) } else { Err(advance) }
+ NonZeroUsize::new(n - advance).map_or(Ok(()), Err)
}
#[inline]
@@ -371,11 +371,11 @@ macro_rules! iterator {
}
#[inline]
- fn advance_back_by(&mut self, n: usize) -> Result<(), usize> {
+ fn advance_back_by(&mut self, n: usize) -> Result<(), NonZeroUsize> {
let advance = cmp::min(len!(self), n);
// SAFETY: By construction, `advance` does not exceed `self.len()`.
unsafe { self.pre_dec_end(advance) };
- if advance == n { Ok(()) } else { Err(advance) }
+ NonZeroUsize::new(n - advance).map_or(Ok(()), Err)
}
}
@@ -393,6 +393,20 @@ macro_rules! iterator {
}
}
}
+
+ #[stable(feature = "default_iters", since = "1.70.0")]
+ impl<T> Default for $name<'_, T> {
+ /// Creates an empty slice iterator.
+ ///
+ /// ```
+ #[doc = concat!("# use core::slice::", stringify!($name), ";")]
+ #[doc = concat!("let iter: ", stringify!($name<'_, u8>), " = Default::default();")]
+ /// assert_eq!(iter.len(), 0);
+ /// ```
+ fn default() -> Self {
+ (& $( $mut_ )? []).into_iter()
+ }
+ }
}
}
diff --git a/library/core/src/slice/mod.rs b/library/core/src/slice/mod.rs
index 1cd86b445..f541808a6 100644
--- a/library/core/src/slice/mod.rs
+++ b/library/core/src/slice/mod.rs
@@ -1695,7 +1695,13 @@ impl<T> [T] {
let ptr = self.as_ptr();
// SAFETY: Caller has to check that `0 <= mid <= self.len()`
- unsafe { (from_raw_parts(ptr, mid), from_raw_parts(ptr.add(mid), len - mid)) }
+ unsafe {
+ assert_unsafe_precondition!(
+ "slice::split_at_unchecked requires the index to be within the slice",
+ (mid: usize, len: usize) => mid <= len
+ );
+ (from_raw_parts(ptr, mid), from_raw_parts(ptr.add(mid), len - mid))
+ }
}
/// Divides one mutable slice into two at an index, without doing bounds checking.
@@ -2381,7 +2387,8 @@ impl<T> [T] {
}
/// Binary searches this slice for a given element.
- /// This behaves similarly to [`contains`] if this slice is sorted.
+ /// If the slice is not sorted, the returned result is unspecified and
+ /// meaningless.
///
/// If the value is found then [`Result::Ok`] is returned, containing the
/// index of the matching element. If there are multiple matches, then any
@@ -2393,7 +2400,6 @@ impl<T> [T] {
///
/// See also [`binary_search_by`], [`binary_search_by_key`], and [`partition_point`].
///
- /// [`contains`]: slice::contains
/// [`binary_search_by`]: slice::binary_search_by
/// [`binary_search_by_key`]: slice::binary_search_by_key
/// [`partition_point`]: slice::partition_point
@@ -2456,12 +2462,13 @@ impl<T> [T] {
}
/// Binary searches this slice with a comparator function.
- /// This behaves similarly to [`contains`] if this slice is sorted.
///
- /// The comparator function should implement an order consistent
- /// with the sort order of the underlying slice, returning an
- /// order code that indicates whether its argument is `Less`,
- /// `Equal` or `Greater` the desired target.
+ /// The comparator function should return an order code that indicates
+ /// whether its argument is `Less`, `Equal` or `Greater` the desired
+ /// target.
+ /// If the slice is not sorted or if the comparator function does not
+ /// implement an order consistent with the sort order of the underlying
+ /// slice, the returned result is unspecified and meaningless.
///
/// If the value is found then [`Result::Ok`] is returned, containing the
/// index of the matching element. If there are multiple matches, then any
@@ -2473,7 +2480,6 @@ impl<T> [T] {
///
/// See also [`binary_search`], [`binary_search_by_key`], and [`partition_point`].
///
- /// [`contains`]: slice::contains
/// [`binary_search`]: slice::binary_search
/// [`binary_search_by_key`]: slice::binary_search_by_key
/// [`partition_point`]: slice::partition_point
@@ -2542,10 +2548,11 @@ impl<T> [T] {
}
/// Binary searches this slice with a key extraction function.
- /// This behaves similarly to [`contains`] if this slice is sorted.
///
/// Assumes that the slice is sorted by the key, for instance with
/// [`sort_by_key`] using the same key extraction function.
+ /// If the slice is not sorted by the key, the returned result is
+ /// unspecified and meaningless.
///
/// If the value is found then [`Result::Ok`] is returned, containing the
/// index of the matching element. If there are multiple matches, then any
@@ -2557,7 +2564,6 @@ impl<T> [T] {
///
/// See also [`binary_search`], [`binary_search_by`], and [`partition_point`].
///
- /// [`contains`]: slice::contains
/// [`sort_by_key`]: slice::sort_by_key
/// [`binary_search`]: slice::binary_search
/// [`binary_search_by`]: slice::binary_search_by
@@ -3816,7 +3822,7 @@ impl<T> [T] {
where
F: FnMut(&'a T, &'a T) -> Option<Ordering>,
{
- self.iter().is_sorted_by(|a, b| compare(*a, *b))
+ self.array_windows().all(|[a, b]| compare(a, b).map_or(false, Ordering::is_le))
}
/// Checks if the elements of this slice are sorted using the given key extraction function.
diff --git a/library/core/src/slice/sort.rs b/library/core/src/slice/sort.rs
index 2333f60a8..07fd96f92 100644
--- a/library/core/src/slice/sort.rs
+++ b/library/core/src/slice/sort.rs
@@ -1486,7 +1486,7 @@ where
}
/// Finds a streak of presorted elements starting at the beginning of the slice. Returns the first
-/// value that is not part of said streak, and a bool denoting wether the streak was reversed.
+/// value that is not part of said streak, and a bool denoting whether the streak was reversed.
/// Streaks can be increasing or decreasing.
fn find_streak<T, F>(v: &[T], is_less: &mut F) -> (usize, bool)
where