@@ -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} 
45264641
45274642impl < T ,  const  N :  usize >  [ [ T ;  N ] ]  { 
0 commit comments