@@ -4540,6 +4540,121 @@ impl<T> [T] {
45404540        // are disjunct and in bounds. 
45414541        unsafe  {  Ok ( self . get_many_unchecked_mut ( indices) )  } 
45424542    } 
4543+ 
4544+     /// Returns the index that an element reference points to. 
4545+      /// 
4546+      /// Returns `None` if `element` does not point within the slice or if it points between elements. 
4547+      /// 
4548+      /// This method is useful for extending slice iterators like [`slice::split`]. 
4549+      /// 
4550+      /// Note that this uses pointer arithmetic and **does not compare elements**. 
4551+      /// To find the index of an element via comparison, use 
4552+      /// [`.iter().position()`](crate::iter::Iterator::position) instead. 
4553+      /// 
4554+      /// # Panics 
4555+      /// Panics if `T` is zero-sized. 
4556+      /// 
4557+      /// # Examples 
4558+      /// Basic usage: 
4559+      /// ``` 
4560+      /// #![feature(substr_range)] 
4561+      /// 
4562+      /// let nums: &[u32] = &[1, 7, 1, 1]; 
4563+      /// let num = &nums[2]; 
4564+      /// 
4565+      /// assert_eq!(num, &1); 
4566+      /// assert_eq!(nums.elem_offset(num), Some(2)); 
4567+      /// ``` 
4568+      /// Returning `None` with an in-between element: 
4569+      /// ``` 
4570+      /// #![feature(substr_range)] 
4571+      /// 
4572+      /// let arr: &[[u32; 2]] = &[[0, 1], [2, 3]]; 
4573+      /// let flat_arr: &[u32] = arr.as_flattened(); 
4574+      /// 
4575+      /// let ok_elm: &[u32; 2] = flat_arr[0..2].try_into().unwrap(); 
4576+      /// let weird_elm: &[u32; 2] = flat_arr[1..3].try_into().unwrap(); 
4577+      /// 
4578+      /// assert_eq!(ok_elm, &[0, 1]); 
4579+      /// assert_eq!(weird_elm, &[1, 2]); 
4580+      /// 
4581+      /// assert_eq!(arr.elem_offset(ok_elm), Some(0)); // Points to element 0 
4582+      /// assert_eq!(arr.elem_offset(weird_elm), None); // Points between element 0 and 1 
4583+      /// ``` 
4584+      #[ must_use]  
4585+     #[ unstable( feature = "substr_range" ,  issue = "126769" ) ]  
4586+     pub  fn  elem_offset ( & self ,  element :  & T )  -> Option < usize >  { 
4587+         if  T :: IS_ZST  { 
4588+             panic ! ( "elements are zero-sized" ) ; 
4589+         } 
4590+ 
4591+         let  self_start = self . as_ptr ( )  as  usize ; 
4592+         let  elem_start = element as  * const  T  as  usize ; 
4593+ 
4594+         let  byte_offset = elem_start. wrapping_sub ( self_start) ; 
4595+ 
4596+         if  byte_offset % mem:: size_of :: < T > ( )  != 0  { 
4597+             return  None ; 
4598+         } 
4599+ 
4600+         let  offset = byte_offset / mem:: size_of :: < T > ( ) ; 
4601+ 
4602+         if  offset < self . len ( )  {  Some ( offset)  }  else  {  None  } 
4603+     } 
4604+ 
4605+     /// Returns the range of indices that a subslice points to. 
4606+      /// 
4607+      /// Returns `None` if `subslice` does not point within the slice or if it points between elements. 
4608+      /// 
4609+      /// This method **does not compare elements**. Instead, this method finds the location in the slice that 
4610+      /// `subslice` was obtained from. To find the index of a subslice via comparison, instead use 
4611+      /// [`.windows()`](slice::windows)[`.position()`](crate::iter::Iterator::position). 
4612+      /// 
4613+      /// This method is useful for extending slice iterators like [`slice::split`]. 
4614+      /// 
4615+      /// Note that this may return a false positive (either `Some(0..0)` or `Some(self.len()..self.len())`) 
4616+      /// if `subslice` has a length of zero and points to the beginning or end of another, separate, slice. 
4617+      /// 
4618+      /// # Panics 
4619+      /// Panics if `T` is zero-sized. 
4620+      /// 
4621+      /// # Examples 
4622+      /// Basic usage: 
4623+      /// ``` 
4624+      /// #![feature(substr_range)] 
4625+      /// 
4626+      /// let nums = &[0, 5, 10, 0, 0, 5]; 
4627+      /// 
4628+      /// let mut iter = nums 
4629+      ///     .split(|t| *t == 0) 
4630+      ///     .map(|n| nums.subslice_range(n).unwrap()); 
4631+      /// 
4632+      /// assert_eq!(iter.next(), Some(0..0)); 
4633+      /// assert_eq!(iter.next(), Some(1..3)); 
4634+      /// assert_eq!(iter.next(), Some(4..4)); 
4635+      /// assert_eq!(iter.next(), Some(5..6)); 
4636+      /// ``` 
4637+      #[ must_use]  
4638+     #[ unstable( feature = "substr_range" ,  issue = "126769" ) ]  
4639+     pub  fn  subslice_range ( & self ,  subslice :  & [ T ] )  -> Option < Range < usize > >  { 
4640+         if  T :: IS_ZST  { 
4641+             panic ! ( "elements are zero-sized" ) ; 
4642+         } 
4643+ 
4644+         let  self_start = self . as_ptr ( )  as  usize ; 
4645+         let  subslice_start = subslice. as_ptr ( )  as  usize ; 
4646+ 
4647+         let  byte_start = subslice_start. wrapping_sub ( self_start) ; 
4648+ 
4649+         if  byte_start % core:: mem:: size_of :: < T > ( )  != 0  { 
4650+             return  None ; 
4651+         } 
4652+ 
4653+         let  start = byte_start / core:: mem:: size_of :: < T > ( ) ; 
4654+         let  end = start. wrapping_add ( subslice. len ( ) ) ; 
4655+ 
4656+         if  start <= self . len ( )  && end <= self . len ( )  {  Some ( start..end)  }  else  {  None  } 
4657+     } 
45434658} 
45444659
45454660impl < T ,  const  N :  usize >  [ [ T ;  N ] ]  { 
0 commit comments