@@ -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 ] {
@@ -3517,6 +3540,245 @@ impl<T> [T] {
35173540 {
35183541 self . binary_search_by ( |x| if pred ( x) { Less } else { Greater } ) . unwrap_or_else ( |i| i)
35193542 }
3543+
3544+ /// Removes the subslice corresponding to the given range
3545+ /// and returns a reference to it.
3546+ ///
3547+ /// Returns `None` and does not modify the slice if the given
3548+ /// range is out of bounds.
3549+ ///
3550+ /// Note that this method only accepts one-sided ranges such as
3551+ /// `2..` or `..6`, but not `2..6`.
3552+ ///
3553+ /// # Examples
3554+ ///
3555+ /// Taking the first three elements of a slice:
3556+ ///
3557+ /// ```
3558+ /// #![feature(slice_take)]
3559+ ///
3560+ /// let mut slice: &[_] = &['a', 'b', 'c', 'd'];
3561+ /// let mut first_three = slice.take(..3).unwrap();
3562+ ///
3563+ /// assert_eq!(slice, &['d']);
3564+ /// assert_eq!(first_three, &['a', 'b', 'c']);
3565+ /// ```
3566+ ///
3567+ /// Taking the last two elements of a slice:
3568+ ///
3569+ /// ```
3570+ /// #![feature(slice_take)]
3571+ ///
3572+ /// let mut slice: &[_] = &['a', 'b', 'c', 'd'];
3573+ /// let mut tail = slice.take(2..).unwrap();
3574+ ///
3575+ /// assert_eq!(slice, &['a', 'b']);
3576+ /// assert_eq!(tail, &['c', 'd']);
3577+ /// ```
3578+ ///
3579+ /// Getting `None` when `range` is out of bounds:
3580+ ///
3581+ /// ```
3582+ /// #![feature(slice_take)]
3583+ ///
3584+ /// let mut slice: &[_] = &['a', 'b', 'c', 'd'];
3585+ ///
3586+ /// assert_eq!(None, slice.take(5..));
3587+ /// assert_eq!(None, slice.take(..5));
3588+ /// assert_eq!(None, slice.take(..=4));
3589+ /// let expected: &[char] = &['a', 'b', 'c', 'd'];
3590+ /// assert_eq!(Some(expected), slice.take(..4));
3591+ /// ```
3592+ #[ inline]
3593+ #[ must_use = "method does not modify the slice if the range is out of bounds" ]
3594+ #[ unstable( feature = "slice_take" , issue = "62280" ) ]
3595+ pub fn take < ' a , R : OneSidedRange < usize > > ( self : & mut & ' a Self , range : R ) -> Option < & ' a Self > {
3596+ let ( direction, split_index) = split_point_of ( range) ?;
3597+ if split_index > self . len ( ) {
3598+ return None ;
3599+ }
3600+ let ( front, back) = self . split_at ( split_index) ;
3601+ match direction {
3602+ Direction :: Front => {
3603+ * self = back;
3604+ Some ( front)
3605+ }
3606+ Direction :: Back => {
3607+ * self = front;
3608+ Some ( back)
3609+ }
3610+ }
3611+ }
3612+
3613+ /// Removes the subslice corresponding to the given range
3614+ /// and returns a mutable reference to it.
3615+ ///
3616+ /// Returns `None` and does not modify the slice if the given
3617+ /// range is out of bounds.
3618+ ///
3619+ /// Note that this method only accepts one-sided ranges such as
3620+ /// `2..` or `..6`, but not `2..6`.
3621+ ///
3622+ /// # Examples
3623+ ///
3624+ /// Taking the first three elements of a slice:
3625+ ///
3626+ /// ```
3627+ /// #![feature(slice_take)]
3628+ ///
3629+ /// let mut slice: &mut [_] = &mut ['a', 'b', 'c', 'd'];
3630+ /// let mut first_three = slice.take_mut(..3).unwrap();
3631+ ///
3632+ /// assert_eq!(slice, &mut ['d']);
3633+ /// assert_eq!(first_three, &mut ['a', 'b', 'c']);
3634+ /// ```
3635+ ///
3636+ /// Taking the last two elements of a slice:
3637+ ///
3638+ /// ```
3639+ /// #![feature(slice_take)]
3640+ ///
3641+ /// let mut slice: &mut [_] = &mut ['a', 'b', 'c', 'd'];
3642+ /// let mut tail = slice.take_mut(2..).unwrap();
3643+ ///
3644+ /// assert_eq!(slice, &mut ['a', 'b']);
3645+ /// assert_eq!(tail, &mut ['c', 'd']);
3646+ /// ```
3647+ ///
3648+ /// Getting `None` when `range` is out of bounds:
3649+ ///
3650+ /// ```
3651+ /// #![feature(slice_take)]
3652+ ///
3653+ /// let mut slice: &mut [_] = &mut ['a', 'b', 'c', 'd'];
3654+ ///
3655+ /// assert_eq!(None, slice.take_mut(5..));
3656+ /// assert_eq!(None, slice.take_mut(..5));
3657+ /// assert_eq!(None, slice.take_mut(..=4));
3658+ /// let expected: &mut [_] = &mut ['a', 'b', 'c', 'd'];
3659+ /// assert_eq!(Some(expected), slice.take_mut(..4));
3660+ /// ```
3661+ #[ inline]
3662+ #[ must_use = "method does not modify the slice if the range is out of bounds" ]
3663+ #[ unstable( feature = "slice_take" , issue = "62280" ) ]
3664+ pub fn take_mut < ' a , R : OneSidedRange < usize > > (
3665+ self : & mut & ' a mut Self ,
3666+ range : R ,
3667+ ) -> Option < & ' a mut Self > {
3668+ let ( direction, split_index) = split_point_of ( range) ?;
3669+ if split_index > self . len ( ) {
3670+ return None ;
3671+ }
3672+ let ( front, back) = mem:: take ( self ) . split_at_mut ( split_index) ;
3673+ match direction {
3674+ Direction :: Front => {
3675+ * self = back;
3676+ Some ( front)
3677+ }
3678+ Direction :: Back => {
3679+ * self = front;
3680+ Some ( back)
3681+ }
3682+ }
3683+ }
3684+
3685+ /// Removes the first element of the slice and returns a reference
3686+ /// to it.
3687+ ///
3688+ /// Returns `None` if the slice is empty.
3689+ ///
3690+ /// # Examples
3691+ ///
3692+ /// ```
3693+ /// #![feature(slice_take)]
3694+ ///
3695+ /// let mut slice: &[_] = &['a', 'b', 'c'];
3696+ /// let first = slice.take_first().unwrap();
3697+ ///
3698+ /// assert_eq!(slice, &['b', 'c']);
3699+ /// assert_eq!(first, &'a');
3700+ /// ```
3701+ #[ inline]
3702+ #[ unstable( feature = "slice_take" , issue = "62280" ) ]
3703+ pub fn take_first < ' a > ( self : & mut & ' a Self ) -> Option < & ' a T > {
3704+ let ( first, rem) = self . split_first ( ) ?;
3705+ * self = rem;
3706+ Some ( first)
3707+ }
3708+
3709+ /// Removes the first element of the slice and returns a mutable
3710+ /// reference to it.
3711+ ///
3712+ /// Returns `None` if the slice is empty.
3713+ ///
3714+ /// # Examples
3715+ ///
3716+ /// ```
3717+ /// #![feature(slice_take)]
3718+ ///
3719+ /// let mut slice: &mut [_] = &mut ['a', 'b', 'c'];
3720+ /// let first = slice.take_first_mut().unwrap();
3721+ /// *first = 'd';
3722+ ///
3723+ /// assert_eq!(slice, &['b', 'c']);
3724+ /// assert_eq!(first, &'d');
3725+ /// ```
3726+ #[ inline]
3727+ #[ unstable( feature = "slice_take" , issue = "62280" ) ]
3728+ pub fn take_first_mut < ' a > ( self : & mut & ' a mut Self ) -> Option < & ' a mut T > {
3729+ let ( first, rem) = mem:: take ( self ) . split_first_mut ( ) ?;
3730+ * self = rem;
3731+ Some ( first)
3732+ }
3733+
3734+ /// Removes the last element of the slice and returns a reference
3735+ /// to it.
3736+ ///
3737+ /// Returns `None` if the slice is empty.
3738+ ///
3739+ /// # Examples
3740+ ///
3741+ /// ```
3742+ /// #![feature(slice_take)]
3743+ ///
3744+ /// let mut slice: &[_] = &['a', 'b', 'c'];
3745+ /// let last = slice.take_last().unwrap();
3746+ ///
3747+ /// assert_eq!(slice, &['a', 'b']);
3748+ /// assert_eq!(last, &'c');
3749+ /// ```
3750+ #[ inline]
3751+ #[ unstable( feature = "slice_take" , issue = "62280" ) ]
3752+ pub fn take_last < ' a > ( self : & mut & ' a Self ) -> Option < & ' a T > {
3753+ let ( last, rem) = self . split_last ( ) ?;
3754+ * self = rem;
3755+ Some ( last)
3756+ }
3757+
3758+ /// Removes the last element of the slice and returns a mutable
3759+ /// reference to it.
3760+ ///
3761+ /// Returns `None` if the slice is empty.
3762+ ///
3763+ /// # Examples
3764+ ///
3765+ /// ```
3766+ /// #![feature(slice_take)]
3767+ ///
3768+ /// let mut slice: &mut [_] = &mut ['a', 'b', 'c'];
3769+ /// let last = slice.take_last_mut().unwrap();
3770+ /// *last = 'd';
3771+ ///
3772+ /// assert_eq!(slice, &['a', 'b']);
3773+ /// assert_eq!(last, &'d');
3774+ /// ```
3775+ #[ inline]
3776+ #[ unstable( feature = "slice_take" , issue = "62280" ) ]
3777+ pub fn take_last_mut < ' a > ( self : & mut & ' a mut Self ) -> Option < & ' a mut T > {
3778+ let ( last, rem) = mem:: take ( self ) . split_last_mut ( ) ?;
3779+ * self = rem;
3780+ Some ( last)
3781+ }
35203782}
35213783
35223784trait CloneFromSpec < T > {
0 commit comments