// 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<T>` 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<T>` 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<T> 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.
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.
/// # Examples
///
/// ```
- /// #![feature(partition_point)]
- ///
/// let v = [1, 2, 3, 3, 5, 6, 7];
/// let i = v.partition_point(|&x| x < 5);
///
/// 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<P>(&self, mut pred: P) -> usize
where
P: FnMut(&T) -> bool,
}
}
+trait CloneFromSpec<T> {
+ fn spec_clone_from(&mut self, src: &[T]);
+}
+
+impl<T> CloneFromSpec<T> 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<T> CloneFromSpec<T> 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<T> Default for &[T] {
/// Creates an empty slice.