@@ -10,7 +10,7 @@ use crate::cmp::Ordering::{self, Greater, Less};
1010use crate :: marker:: Copy ;
1111use crate :: mem;
1212use crate :: num:: NonZeroUsize ;
13- use crate :: ops:: { FnMut , Range , RangeBounds } ;
13+ use crate :: ops:: { Bound , FnMut , OneSidedRange , Range , RangeBounds } ;
1414use crate :: option:: Option ;
1515use crate :: option:: Option :: { None , Some } ;
1616use crate :: ptr;
@@ -82,6 +82,29 @@ pub use index::range;
8282#[ unstable( feature = "inherent_ascii_escape" , issue = "77174" ) ]
8383pub use ascii:: EscapeAscii ;
8484
85+ /// Calculates the direction and split point of a one-sided range.
86+ ///
87+ /// This is a helper function for `take` and `take_mut` that returns
88+ /// the direction of the split (front or back) as well as the index at
89+ /// which to split. Returns `None` if the split index would overflow.
90+ #[ inline]
91+ fn split_point_of ( range : impl OneSidedRange < usize > ) -> Option < ( Direction , usize ) > {
92+ use Bound :: * ;
93+
94+ Some ( match ( range. start_bound ( ) , range. end_bound ( ) ) {
95+ ( Unbounded , Excluded ( i) ) => ( Direction :: Front , * i) ,
96+ ( Unbounded , Included ( i) ) => ( Direction :: Front , i. checked_add ( 1 ) ?) ,
97+ ( Excluded ( i) , Unbounded ) => ( Direction :: Back , i. checked_add ( 1 ) ?) ,
98+ ( Included ( i) , Unbounded ) => ( Direction :: Back , * i) ,
99+ _ => unreachable ! ( ) ,
100+ } )
101+ }
102+
103+ enum Direction {
104+ Front ,
105+ Back ,
106+ }
107+
85108#[ lang = "slice" ]
86109#[ cfg( not( test) ) ]
87110impl < T > [ T ] {
@@ -3576,6 +3599,245 @@ impl<T> [T] {
35763599 {
35773600 self . binary_search_by ( |x| if pred ( x) { Less } else { Greater } ) . unwrap_or_else ( |i| i)
35783601 }
3602+
3603+ /// Removes the subslice corresponding to the given range
3604+ /// and returns a reference to it.
3605+ ///
3606+ /// Returns `None` and does not modify the slice if the given
3607+ /// range is out of bounds.
3608+ ///
3609+ /// Note that this method only accepts one-sided ranges such as
3610+ /// `2..` or `..6`, but not `2..6`.
3611+ ///
3612+ /// # Examples
3613+ ///
3614+ /// Taking the first three elements of a slice:
3615+ ///
3616+ /// ```
3617+ /// #![feature(slice_take)]
3618+ ///
3619+ /// let mut slice: &[_] = &['a', 'b', 'c', 'd'];
3620+ /// let mut first_three = slice.take(..3).unwrap();
3621+ ///
3622+ /// assert_eq!(slice, &['d']);
3623+ /// assert_eq!(first_three, &['a', 'b', 'c']);
3624+ /// ```
3625+ ///
3626+ /// Taking the last two elements of a slice:
3627+ ///
3628+ /// ```
3629+ /// #![feature(slice_take)]
3630+ ///
3631+ /// let mut slice: &[_] = &['a', 'b', 'c', 'd'];
3632+ /// let mut tail = slice.take(2..).unwrap();
3633+ ///
3634+ /// assert_eq!(slice, &['a', 'b']);
3635+ /// assert_eq!(tail, &['c', 'd']);
3636+ /// ```
3637+ ///
3638+ /// Getting `None` when `range` is out of bounds:
3639+ ///
3640+ /// ```
3641+ /// #![feature(slice_take)]
3642+ ///
3643+ /// let mut slice: &[_] = &['a', 'b', 'c', 'd'];
3644+ ///
3645+ /// assert_eq!(None, slice.take(5..));
3646+ /// assert_eq!(None, slice.take(..5));
3647+ /// assert_eq!(None, slice.take(..=4));
3648+ /// let expected: &[char] = &['a', 'b', 'c', 'd'];
3649+ /// assert_eq!(Some(expected), slice.take(..4));
3650+ /// ```
3651+ #[ inline]
3652+ #[ must_use = "method does not modify the slice if the range is out of bounds" ]
3653+ #[ unstable( feature = "slice_take" , issue = "62280" ) ]
3654+ pub fn take < ' a , R : OneSidedRange < usize > > ( self : & mut & ' a Self , range : R ) -> Option < & ' a Self > {
3655+ let ( direction, split_index) = split_point_of ( range) ?;
3656+ if split_index > self . len ( ) {
3657+ return None ;
3658+ }
3659+ let ( front, back) = self . split_at ( split_index) ;
3660+ match direction {
3661+ Direction :: Front => {
3662+ * self = back;
3663+ Some ( front)
3664+ }
3665+ Direction :: Back => {
3666+ * self = front;
3667+ Some ( back)
3668+ }
3669+ }
3670+ }
3671+
3672+ /// Removes the subslice corresponding to the given range
3673+ /// and returns a mutable reference to it.
3674+ ///
3675+ /// Returns `None` and does not modify the slice if the given
3676+ /// range is out of bounds.
3677+ ///
3678+ /// Note that this method only accepts one-sided ranges such as
3679+ /// `2..` or `..6`, but not `2..6`.
3680+ ///
3681+ /// # Examples
3682+ ///
3683+ /// Taking the first three elements of a slice:
3684+ ///
3685+ /// ```
3686+ /// #![feature(slice_take)]
3687+ ///
3688+ /// let mut slice: &mut [_] = &mut ['a', 'b', 'c', 'd'];
3689+ /// let mut first_three = slice.take_mut(..3).unwrap();
3690+ ///
3691+ /// assert_eq!(slice, &mut ['d']);
3692+ /// assert_eq!(first_three, &mut ['a', 'b', 'c']);
3693+ /// ```
3694+ ///
3695+ /// Taking the last two elements of a slice:
3696+ ///
3697+ /// ```
3698+ /// #![feature(slice_take)]
3699+ ///
3700+ /// let mut slice: &mut [_] = &mut ['a', 'b', 'c', 'd'];
3701+ /// let mut tail = slice.take_mut(2..).unwrap();
3702+ ///
3703+ /// assert_eq!(slice, &mut ['a', 'b']);
3704+ /// assert_eq!(tail, &mut ['c', 'd']);
3705+ /// ```
3706+ ///
3707+ /// Getting `None` when `range` is out of bounds:
3708+ ///
3709+ /// ```
3710+ /// #![feature(slice_take)]
3711+ ///
3712+ /// let mut slice: &mut [_] = &mut ['a', 'b', 'c', 'd'];
3713+ ///
3714+ /// assert_eq!(None, slice.take_mut(5..));
3715+ /// assert_eq!(None, slice.take_mut(..5));
3716+ /// assert_eq!(None, slice.take_mut(..=4));
3717+ /// let expected: &mut [_] = &mut ['a', 'b', 'c', 'd'];
3718+ /// assert_eq!(Some(expected), slice.take_mut(..4));
3719+ /// ```
3720+ #[ inline]
3721+ #[ must_use = "method does not modify the slice if the range is out of bounds" ]
3722+ #[ unstable( feature = "slice_take" , issue = "62280" ) ]
3723+ pub fn take_mut < ' a , R : OneSidedRange < usize > > (
3724+ self : & mut & ' a mut Self ,
3725+ range : R ,
3726+ ) -> Option < & ' a mut Self > {
3727+ let ( direction, split_index) = split_point_of ( range) ?;
3728+ if split_index > self . len ( ) {
3729+ return None ;
3730+ }
3731+ let ( front, back) = mem:: take ( self ) . split_at_mut ( split_index) ;
3732+ match direction {
3733+ Direction :: Front => {
3734+ * self = back;
3735+ Some ( front)
3736+ }
3737+ Direction :: Back => {
3738+ * self = front;
3739+ Some ( back)
3740+ }
3741+ }
3742+ }
3743+
3744+ /// Removes the first element of the slice and returns a reference
3745+ /// to it.
3746+ ///
3747+ /// Returns `None` if the slice is empty.
3748+ ///
3749+ /// # Examples
3750+ ///
3751+ /// ```
3752+ /// #![feature(slice_take)]
3753+ ///
3754+ /// let mut slice: &[_] = &['a', 'b', 'c'];
3755+ /// let first = slice.take_first().unwrap();
3756+ ///
3757+ /// assert_eq!(slice, &['b', 'c']);
3758+ /// assert_eq!(first, &'a');
3759+ /// ```
3760+ #[ inline]
3761+ #[ unstable( feature = "slice_take" , issue = "62280" ) ]
3762+ pub fn take_first < ' a > ( self : & mut & ' a Self ) -> Option < & ' a T > {
3763+ let ( first, rem) = self . split_first ( ) ?;
3764+ * self = rem;
3765+ Some ( first)
3766+ }
3767+
3768+ /// Removes the first element of the slice and returns a mutable
3769+ /// reference to it.
3770+ ///
3771+ /// Returns `None` if the slice is empty.
3772+ ///
3773+ /// # Examples
3774+ ///
3775+ /// ```
3776+ /// #![feature(slice_take)]
3777+ ///
3778+ /// let mut slice: &mut [_] = &mut ['a', 'b', 'c'];
3779+ /// let first = slice.take_first_mut().unwrap();
3780+ /// *first = 'd';
3781+ ///
3782+ /// assert_eq!(slice, &['b', 'c']);
3783+ /// assert_eq!(first, &'d');
3784+ /// ```
3785+ #[ inline]
3786+ #[ unstable( feature = "slice_take" , issue = "62280" ) ]
3787+ pub fn take_first_mut < ' a > ( self : & mut & ' a mut Self ) -> Option < & ' a mut T > {
3788+ let ( first, rem) = mem:: take ( self ) . split_first_mut ( ) ?;
3789+ * self = rem;
3790+ Some ( first)
3791+ }
3792+
3793+ /// Removes the last element of the slice and returns a reference
3794+ /// to it.
3795+ ///
3796+ /// Returns `None` if the slice is empty.
3797+ ///
3798+ /// # Examples
3799+ ///
3800+ /// ```
3801+ /// #![feature(slice_take)]
3802+ ///
3803+ /// let mut slice: &[_] = &['a', 'b', 'c'];
3804+ /// let last = slice.take_last().unwrap();
3805+ ///
3806+ /// assert_eq!(slice, &['a', 'b']);
3807+ /// assert_eq!(last, &'c');
3808+ /// ```
3809+ #[ inline]
3810+ #[ unstable( feature = "slice_take" , issue = "62280" ) ]
3811+ pub fn take_last < ' a > ( self : & mut & ' a Self ) -> Option < & ' a T > {
3812+ let ( last, rem) = self . split_last ( ) ?;
3813+ * self = rem;
3814+ Some ( last)
3815+ }
3816+
3817+ /// Removes the last element of the slice and returns a mutable
3818+ /// reference to it.
3819+ ///
3820+ /// Returns `None` if the slice is empty.
3821+ ///
3822+ /// # Examples
3823+ ///
3824+ /// ```
3825+ /// #![feature(slice_take)]
3826+ ///
3827+ /// let mut slice: &mut [_] = &mut ['a', 'b', 'c'];
3828+ /// let last = slice.take_last_mut().unwrap();
3829+ /// *last = 'd';
3830+ ///
3831+ /// assert_eq!(slice, &['a', 'b']);
3832+ /// assert_eq!(last, &'d');
3833+ /// ```
3834+ #[ inline]
3835+ #[ unstable( feature = "slice_take" , issue = "62280" ) ]
3836+ pub fn take_last_mut < ' a > ( self : & mut & ' a mut Self ) -> Option < & ' a mut T > {
3837+ let ( last, rem) = mem:: take ( self ) . split_last_mut ( ) ?;
3838+ * self = rem;
3839+ Some ( last)
3840+ }
35793841}
35803842
35813843trait CloneFromSpec < T > {
0 commit comments