@@ -553,6 +553,7 @@ use crate::pin::Pin;
553
553
use crate :: {
554
554
cmp, convert, hint, mem,
555
555
ops:: { self , ControlFlow , Deref , DerefMut } ,
556
+ slice,
556
557
} ;
557
558
558
559
/// The `Option` type. See [the module level documentation](self) for more.
@@ -734,6 +735,124 @@ impl<T> Option<T> {
734
735
}
735
736
}
736
737
738
+ const fn get_some_offset ( ) -> isize {
739
+ if mem:: size_of :: < Option < T > > ( ) == mem:: size_of :: < T > ( ) {
740
+ // niche optimization means the `T` is always stored at the same position as the Option.
741
+ 0
742
+ } else {
743
+ assert ! ( mem:: size_of:: <Option <T >>( ) == mem:: size_of:: <Option <mem:: MaybeUninit <T >>>( ) ) ;
744
+ let some_uninit = Some ( mem:: MaybeUninit :: < T > :: uninit ( ) ) ;
745
+ // SAFETY: This gets the byte offset of the `Some(_)` value following the fact that
746
+ // niche optimization is not active, and thus Option<T> and Option<MaybeUninit<t>> share
747
+ // the same layout.
748
+ unsafe {
749
+ ( some_uninit. as_ref ( ) . unwrap ( ) as * const mem:: MaybeUninit < T > )
750
+ . byte_offset_from ( & some_uninit as * const Option < mem:: MaybeUninit < T > > )
751
+ }
752
+ }
753
+ }
754
+
755
+ /// Returns a slice of the contained value, if any. If this is `None`, an
756
+ /// empty slice is returned. This can be useful to have a single type of
757
+ /// iterator over an `Option` or slice.
758
+ ///
759
+ /// Note: Should you have an `Option<&T>` and wish to get a slice of `T`,
760
+ /// you can unpack it via `opt.map_or(&[], std::slice::from_ref)`.
761
+ ///
762
+ /// # Examples
763
+ ///
764
+ /// ```rust
765
+ /// #![feature(option_as_slice)]
766
+ ///
767
+ /// assert_eq!(
768
+ /// [Some(1234).as_slice(), None.as_slice()],
769
+ /// [&[1234][..], &[][..]],
770
+ /// );
771
+ /// ```
772
+ ///
773
+ /// The inverse of this function is (discounting
774
+ /// borrowing) [`[_]::first`](slice::first):
775
+ ///
776
+ /// ```rust
777
+ /// #![feature(option_as_slice)]
778
+ ///
779
+ /// for i in [Some(1234_u16), None] {
780
+ /// assert_eq!(i.as_ref(), i.as_slice().first());
781
+ /// }
782
+ /// ```
783
+ #[ inline]
784
+ #[ must_use]
785
+ #[ unstable( feature = "option_as_slice" , issue = "108545" ) ]
786
+ pub fn as_slice ( & self ) -> & [ T ] {
787
+ // SAFETY: This is sound as long as `get_some_offset` returns the
788
+ // correct offset. Though in the `None` case, the slice may be located
789
+ // at a pointer pointing into padding, the fact that the slice is
790
+ // empty, and the padding is at a properly aligned position for a
791
+ // value of that type makes it sound.
792
+ unsafe {
793
+ slice:: from_raw_parts (
794
+ ( self as * const Option < T > ) . wrapping_byte_offset ( Self :: get_some_offset ( ) )
795
+ as * const T ,
796
+ self . is_some ( ) as usize ,
797
+ )
798
+ }
799
+ }
800
+
801
+ /// Returns a mutable slice of the contained value, if any. If this is
802
+ /// `None`, an empty slice is returned. This can be useful to have a
803
+ /// single type of iterator over an `Option` or slice.
804
+ ///
805
+ /// Note: Should you have an `Option<&mut T>` instead of a
806
+ /// `&mut Option<T>`, which this method takes, you can obtain a mutable
807
+ /// slice via `opt.map_or(&mut [], std::slice::from_mut)`.
808
+ ///
809
+ /// # Examples
810
+ ///
811
+ /// ```rust
812
+ /// #![feature(option_as_slice)]
813
+ ///
814
+ /// assert_eq!(
815
+ /// [Some(1234).as_mut_slice(), None.as_mut_slice()],
816
+ /// [&mut [1234][..], &mut [][..]],
817
+ /// );
818
+ /// ```
819
+ ///
820
+ /// The result is a mutable slice of zero or one items that points into
821
+ /// our original `Option`:
822
+ ///
823
+ /// ```rust
824
+ /// #![feature(option_as_slice)]
825
+ ///
826
+ /// let mut x = Some(1234);
827
+ /// x.as_mut_slice()[0] += 1;
828
+ /// assert_eq!(x, Some(1235));
829
+ /// ```
830
+ ///
831
+ /// The inverse of this method (discounting borrowing)
832
+ /// is [`[_]::first_mut`](slice::first_mut):
833
+ ///
834
+ /// ```rust
835
+ /// #![feature(option_as_slice)]
836
+ ///
837
+ /// assert_eq!(Some(123).as_mut_slice().first_mut(), Some(&mut 123))
838
+ /// ```
839
+ #[ inline]
840
+ #[ must_use]
841
+ #[ unstable( feature = "option_as_slice" , issue = "108545" ) ]
842
+ pub fn as_mut_slice ( & mut self ) -> & mut [ T ] {
843
+ // SAFETY: This is sound as long as `get_some_offset` returns the
844
+ // correct offset. Though in the `None` case, the slice may be located
845
+ // at a pointer pointing into padding, the fact that the slice is
846
+ // empty, and the padding is at a properly aligned position for a
847
+ // value of that type makes it sound.
848
+ unsafe {
849
+ slice:: from_raw_parts_mut (
850
+ ( self as * mut Option < T > ) . wrapping_byte_offset ( Self :: get_some_offset ( ) ) as * mut T ,
851
+ self . is_some ( ) as usize ,
852
+ )
853
+ }
854
+ }
855
+
737
856
/////////////////////////////////////////////////////////////////////////
738
857
// Getting to contained values
739
858
/////////////////////////////////////////////////////////////////////////
0 commit comments