X-Git-Url: https://git.lizzy.rs/?a=blobdiff_plain;f=library%2Fcore%2Fsrc%2Fslice%2Fmod.rs;h=5510bb0257e3424af7f4e60f4ea536606da64733;hb=caca2121ffe4cb47d8ea2d9469c493995f57e0b5;hp=d314d38c30abffa8c3c51da0085782fad6c46c5f;hpb=3eb5bee242fae12c4cf547bfe0665653c20ca0c2;p=rust.git diff --git a/library/core/src/slice/mod.rs b/library/core/src/slice/mod.rs index d314d38c30a..5510bb0257e 100644 --- a/library/core/src/slice/mod.rs +++ b/library/core/src/slice/mod.rs @@ -18,6 +18,7 @@ use crate::ptr; use crate::result::Result; use crate::result::Result::{Err, Ok}; +use crate::slice; #[unstable( feature = "slice_internals", @@ -29,11 +30,12 @@ mod ascii; mod cmp; -pub(crate) mod index; +mod index; mod iter; mod raw; mod rotate; mod sort; +mod specialize; #[stable(feature = "rust1", since = "1.0.0")] pub use iter::{Chunks, ChunksMut, Windows}; @@ -76,6 +78,9 @@ #[stable(feature = "slice_get_slice", since = "1.28.0")] pub use index::SliceIndex; +#[unstable(feature = "slice_range", issue = "76393")] +pub use index::range; + #[lang = "slice"] #[cfg(not(test))] impl [T] { @@ -94,9 +99,23 @@ impl [T] { // SAFETY: const sound because we transmute out the length field as a usize (which it must be) #[rustc_allow_const_fn_unstable(const_fn_union)] pub const fn len(&self) -> usize { - // SAFETY: this is safe because `&[T]` and `FatPtr` have the same layout. - // Only `std` can make this guarantee. - unsafe { crate::ptr::Repr { rust: self }.raw.len } + #[cfg(bootstrap)] + { + // SAFETY: this is safe because `&[T]` and `FatPtr` have the same layout. + // Only `std` can make this guarantee. + unsafe { crate::ptr::Repr { rust: self }.raw.len } + } + #[cfg(not(bootstrap))] + { + // FIXME: Replace with `crate::ptr::metadata(self)` when that is const-stable. + // As of this writing this causes a "Const-stable functions can only call other + // const-stable functions" error. + + // SAFETY: Accessing the value from the `PtrRepr` union is safe since *const T + // and PtrComponents have the same memory layouts. Only std can make this + // guarantee. + unsafe { crate::ptr::PtrRepr { const_ptr: self }.components.metadata } + } } /// Returns `true` if the slice has a length of 0. @@ -543,8 +562,8 @@ pub const fn as_mut_ptr_range(&mut self) -> Range<*mut T> { #[inline] pub fn swap(&mut self, a: usize, b: usize) { // Can't take two mutable loans from one vector, so instead use raw pointers. - let pa = ptr::raw_mut!(self[a]); - let pb = ptr::raw_mut!(self[b]); + let pa = ptr::addr_of_mut!(self[a]); + let pb = ptr::addr_of_mut!(self[b]); // SAFETY: `pa` and `pb` have been created from safe mutable references and refer // to elements in the slice and therefore are guaranteed to be valid and aligned. // Note that accessing the elements behind `a` and `b` is checked and will @@ -2082,6 +2101,12 @@ pub fn strip_suffix + ?Sized>(&self, suffix: &P) -> Op /// [`Result::Err`] is returned, containing the index where a matching /// element could be inserted while maintaining sorted order. /// + /// See also [`binary_search_by`], [`binary_search_by_key`], and [`partition_point`]. + /// + /// [`binary_search_by`]: #method.binary_search_by + /// [`binary_search_by_key`]: #method.binary_search_by_key + /// [`partition_point`]: #method.partition_point + /// /// # Examples /// /// Looks up a series of four elements. The first is found, with a @@ -2129,6 +2154,12 @@ pub fn binary_search(&self, x: &T) -> Result /// [`Result::Err`] is returned, containing the index where a matching /// element could be inserted while maintaining sorted order. /// + /// See also [`binary_search`], [`binary_search_by_key`], and [`partition_point`]. + /// + /// [`binary_search`]: #method.binary_search + /// [`binary_search_by_key`]: #method.binary_search_by_key + /// [`partition_point`]: #method.partition_point + /// /// # Examples /// /// Looks up a series of four elements. The first is found, with a @@ -2192,7 +2223,12 @@ pub fn binary_search_by<'a, F>(&'a self, mut f: F) -> Result /// [`Result::Err`] is returned, containing the index where a matching /// element could be inserted while maintaining sorted order. /// + /// See also [`binary_search`], [`binary_search_by`], and [`partition_point`]. + /// /// [`sort_by_key`]: #method.sort_by_key + /// [`binary_search`]: #method.binary_search + /// [`binary_search_by`]: #method.binary_search_by + /// [`partition_point`]: #method.partition_point /// /// # Examples /// @@ -2837,13 +2873,7 @@ pub fn fill(&mut self, value: T) where T: Clone, { - if let Some((last, elems)) = self.split_last_mut() { - for el in elems { - el.clone_from(&value); - } - - *last = value - } + specialize::SpecFill::spec_fill(self, value); } /// Fills `self` with elements returned by calling a closure repeatedly. @@ -2858,13 +2888,12 @@ pub fn fill(&mut self, value: T) /// # Examples /// /// ``` - /// #![feature(slice_fill_with)] - /// /// let mut buf = vec![1; 10]; /// buf.fill_with(Default::default); /// assert_eq!(buf, vec![0; 10]); /// ``` - #[unstable(feature = "slice_fill_with", issue = "79221")] + #[doc(alias = "memset")] + #[stable(feature = "slice_fill_with", since = "1.51.0")] pub fn fill_with(&mut self, mut f: F) where F: FnMut() -> T, @@ -2934,15 +2963,7 @@ pub fn clone_from_slice(&mut self, src: &[T]) where T: Clone, { - assert!(self.len() == src.len(), "destination and source slices have different lengths"); - // NOTE: We need to explicitly slice them to the same length - // for bounds checking to be elided, and the optimizer will - // generate memcpy for simple cases (for example T = u8). - let len = self.len(); - let src = &src[..len]; - for i in 0..len { - self[i].clone_from(&src[i]); - } + self.spec_clone_from(src); } /// Copies all elements from `src` into `self`, using a memcpy. @@ -3059,7 +3080,7 @@ pub fn copy_within>(&mut self, src: R, dest: usize) where T: Copy, { - let Range { start: src_start, end: src_end } = src.assert_len(self.len()); + let Range { start: src_start, end: src_end } = slice::range(src, ..self.len()); let count = src_end - src_start; assert!(dest <= self.len() - count, "dest is out of bounds"); // SAFETY: the conditions for `ptr::copy` have all been checked above, @@ -3406,11 +3427,15 @@ pub fn is_sorted_by_key(&self, f: F) -> bool /// If this slice is not partitioned, the returned result is unspecified and meaningless, /// as this method performs a kind of binary search. /// + /// See also [`binary_search`], [`binary_search_by`], and [`binary_search_by_key`]. + /// + /// [`binary_search`]: #method.binary_search + /// [`binary_search_by`]: #method.binary_search_by + /// [`binary_search_by_key`]: #method.binary_search_by_key + /// /// # Examples /// /// ``` - /// #![feature(partition_point)] - /// /// let v = [1, 2, 3, 3, 5, 6, 7]; /// let i = v.partition_point(|&x| x < 5); /// @@ -3418,7 +3443,7 @@ pub fn is_sorted_by_key(&self, f: F) -> bool /// assert!(v[..i].iter().all(|&x| x < 5)); /// assert!(v[i..].iter().all(|&x| !(x < 5))); /// ``` - #[unstable(feature = "partition_point", reason = "new API", issue = "73831")] + #[stable(feature = "partition_point", since = "1.52.0")] pub fn partition_point

(&self, mut pred: P) -> usize where P: FnMut(&T) -> bool, @@ -3447,6 +3472,36 @@ pub fn partition_point

(&self, mut pred: P) -> usize } } +trait CloneFromSpec { + fn spec_clone_from(&mut self, src: &[T]); +} + +impl CloneFromSpec for [T] +where + T: Clone, +{ + default fn spec_clone_from(&mut self, src: &[T]) { + assert!(self.len() == src.len(), "destination and source slices have different lengths"); + // NOTE: We need to explicitly slice them to the same length + // to make it easier for the optimizer to elide bounds checking. + // But since it can't be relied on we also have an explicit specialization for T: Copy. + let len = self.len(); + let src = &src[..len]; + for i in 0..len { + self[i].clone_from(&src[i]); + } + } +} + +impl CloneFromSpec for [T] +where + T: Copy, +{ + fn spec_clone_from(&mut self, src: &[T]) { + self.copy_from_slice(src); + } +} + #[stable(feature = "rust1", since = "1.0.0")] impl Default for &[T] { /// Creates an empty slice.