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
`` +
``
``
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]] {
`