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

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

`

4522

4522

`// are disjunct and in bounds.

`

4523

4523

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

`

4524

4524

`}

`

``

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() 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 {

`

``

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::() != 0 {

`

``

4579

`+

return None;

`

``

4580

`+

}

`

``

4581

+

``

4582

`+

let offset = byte_offset / mem::size_of::();

`

``

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().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> {

`

``

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::() != 0 {

`

``

4632

`+

return None;

`

``

4633

`+

}

`

``

4634

+

``

4635

`+

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

`

``

4636

`+

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

`

``

4637

+

``

4638

`+

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

`

``

4639

`+

}

`

4525

4640

`}

`

4526

4641

``

4527

4642

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

`