Rollup merge of #126770 - wr7:master, r=Amanieu · model-checking/verify-rust-std@bc7345c

@@ -4522,6 +4522,121 @@ impl<T> [T] {

45224522

// are disjunct and in bounds.

45234523

unsafe { Ok(self.get_many_unchecked_mut(indices)) }

45244524

}

4525+4526+

/// Returns the index that an element reference points to.

4527+

///

4528+

/// Returns `None` if `element` does not point within the slice or if it points between elements.

4529+

///

4530+

/// This method is useful for extending slice iterators like [`slice::split`].

4531+

///

4532+

/// Note that this uses pointer arithmetic and **does not compare elements**.

4533+

/// To find the index of an element via comparison, use

4534+

/// [`.iter().position()`](crate::iter::Iterator::position) instead.

4535+

///

4536+

/// # Panics

4537+

/// Panics if `T` is zero-sized.

4538+

///

4539+

/// # Examples

4540+

/// Basic usage:

4541+

/// ```

4542+

/// #![feature(substr_range)]

4543+

///

4544+

/// let nums: &[u32] = &[1, 7, 1, 1];

4545+

/// let num = &nums[2];

4546+

///

4547+

/// assert_eq!(num, &1);

4548+

/// assert_eq!(nums.elem_offset(num), Some(2));

4549+

/// ```

4550+

/// Returning `None` with an in-between element:

4551+

/// ```

4552+

/// #![feature(substr_range)]

4553+

///

4554+

/// let arr: &[[u32; 2]] = &[[0, 1], [2, 3]];

4555+

/// let flat_arr: &[u32] = arr.as_flattened();

4556+

///

4557+

/// let ok_elm: &[u32; 2] = flat_arr[0..2].try_into().unwrap();

4558+

/// let weird_elm: &[u32; 2] = flat_arr[1..3].try_into().unwrap();

4559+

///

4560+

/// assert_eq!(ok_elm, &[0, 1]);

4561+

/// assert_eq!(weird_elm, &[1, 2]);

4562+

///

4563+

/// assert_eq!(arr.elem_offset(ok_elm), Some(0)); // Points to element 0

4564+

/// assert_eq!(arr.elem_offset(weird_elm), None); // Points between element 0 and 1

4565+

/// ```

4566+

#[must_use]

4567+

#[unstable(feature = "substr_range", issue = "126769")]

4568+

pub fn elem_offset(&self, element: &T) -> Option<usize> {

4569+

if T::IS_ZST {

4570+

panic!("elements are zero-sized");

4571+

}

4572+4573+

let self_start = self.as_ptr() as usize;

4574+

let elem_start = element as *const T as usize;

4575+4576+

let byte_offset = elem_start.wrapping_sub(self_start);

4577+4578+

if byte_offset % mem::size_of::<T>() != 0 {

4579+

return None;

4580+

}

4581+4582+

let offset = byte_offset / mem::size_of::<T>();

4583+4584+

if offset < self.len() { Some(offset) } else { None }

4585+

}

4586+4587+

/// Returns the range of indices that a subslice points to.

4588+

///

4589+

/// Returns `None` if `subslice` does not point within the slice or if it points between elements.

4590+

///

4591+

/// This method **does not compare elements**. Instead, this method finds the location in the slice that

4592+

/// `subslice` was obtained from. To find the index of a subslice via comparison, instead use

4593+

/// [`.windows()`](slice::windows)[`.position()`](crate::iter::Iterator::position).

4594+

///

4595+

/// This method is useful for extending slice iterators like [`slice::split`].

4596+

///

4597+

/// Note that this may return a false positive (either `Some(0..0)` or `Some(self.len()..self.len())`)

4598+

/// if `subslice` has a length of zero and points to the beginning or end of another, separate, slice.

4599+

///

4600+

/// # Panics

4601+

/// Panics if `T` is zero-sized.

4602+

///

4603+

/// # Examples

4604+

/// Basic usage:

4605+

/// ```

4606+

/// #![feature(substr_range)]

4607+

///

4608+

/// let nums = &[0, 5, 10, 0, 0, 5];

4609+

///

4610+

/// let mut iter = nums

4611+

/// .split(|t| *t == 0)

4612+

/// .map(|n| nums.subslice_range(n).unwrap());

4613+

///

4614+

/// assert_eq!(iter.next(), Some(0..0));

4615+

/// assert_eq!(iter.next(), Some(1..3));

4616+

/// assert_eq!(iter.next(), Some(4..4));

4617+

/// assert_eq!(iter.next(), Some(5..6));

4618+

/// ```

4619+

#[must_use]

4620+

#[unstable(feature = "substr_range", issue = "126769")]

4621+

pub fn subslice_range(&self, subslice: &[T]) -> Option<Range<usize>> {

4622+

if T::IS_ZST {

4623+

panic!("elements are zero-sized");

4624+

}

4625+4626+

let self_start = self.as_ptr() as usize;

4627+

let subslice_start = subslice.as_ptr() as usize;

4628+4629+

let byte_start = subslice_start.wrapping_sub(self_start);

4630+4631+

if byte_start % core::mem::size_of::<T>() != 0 {

4632+

return None;

4633+

}

4634+4635+

let start = byte_start / core::mem::size_of::<T>();

4636+

let end = start.wrapping_add(subslice.len());

4637+4638+

if start <= self.len() && end <= self.len() { Some(start..end) } else { None }

4639+

}

45254640

}

4526464145274642

impl<T, const N: usize> [[T; N]] {