@@ -1842,7 +1842,8 @@ impl<T> [T] {
18421842 ///
18431843 /// # Panics
18441844 ///
1845- /// Panics if `mid > len`.
1845+ /// Panics if `mid > len`. For a non-panicking alternative see
1846+ /// [`split_at_checked`](slice::split_at_checked).
18461847 ///
18471848 /// # Examples
18481849 ///
@@ -1869,14 +1870,15 @@ impl<T> [T] {
18691870 /// ```
18701871 #[ stable( feature = "rust1" , since = "1.0.0" ) ]
18711872 #[ rustc_const_stable( feature = "const_slice_split_at_not_mut" , since = "1.71.0" ) ]
1873+ #[ rustc_allow_const_fn_unstable( split_at_checked) ]
18721874 #[ inline]
18731875 #[ track_caller]
18741876 #[ must_use]
18751877 pub const fn split_at ( & self , mid : usize ) -> ( & [ T ] , & [ T ] ) {
1876- assert ! ( mid <= self . len ( ) ) ;
1877- // SAFETY: `[ptr; mid]` and `[mid; len]` are inside `self`, which
1878- // fulfills the requirements of `split_at_unchecked`.
1879- unsafe { self . split_at_unchecked ( mid ) }
1878+ match self . split_at_checked ( mid ) {
1879+ Some ( pair ) => pair ,
1880+ None => panic ! ( "mid > len" ) ,
1881+ }
18801882 }
18811883
18821884 /// Divides one mutable slice into two at an index.
@@ -1887,7 +1889,8 @@ impl<T> [T] {
18871889 ///
18881890 /// # Panics
18891891 ///
1890- /// Panics if `mid > len`.
1892+ /// Panics if `mid > len`. For a non-panicking alternative see
1893+ /// [`split_at_mut_checked`](slice::split_at_mut_checked).
18911894 ///
18921895 /// # Examples
18931896 ///
@@ -1906,10 +1909,10 @@ impl<T> [T] {
19061909 #[ must_use]
19071910 #[ rustc_const_unstable( feature = "const_slice_split_at_mut" , issue = "101804" ) ]
19081911 pub const fn split_at_mut ( & mut self , mid : usize ) -> ( & mut [ T ] , & mut [ T ] ) {
1909- assert ! ( mid <= self . len ( ) ) ;
1910- // SAFETY: `[ptr; mid]` and `[mid; len]` are inside `self`, which
1911- // fulfills the requirements of `from_raw_parts_mut`.
1912- unsafe { self . split_at_mut_unchecked ( mid ) }
1912+ match self . split_at_mut_checked ( mid ) {
1913+ Some ( pair ) => pair ,
1914+ None => panic ! ( "mid > len" ) ,
1915+ }
19131916 }
19141917
19151918 /// Divides one slice into two at an index, without doing bounds checking.
@@ -2031,6 +2034,256 @@ impl<T> [T] {
20312034 unsafe { ( from_raw_parts_mut ( ptr, mid) , from_raw_parts_mut ( ptr. add ( mid) , len - mid) ) }
20322035 }
20332036
2037+ /// Divides one slice into two at an index returning, `None` if slice is too
2038+ /// short.
2039+ ///
2040+ /// The first will contain all indices from `[0, mid)` (excluding
2041+ /// the index `mid` itself) and the second will contain all
2042+ /// indices from `[mid, len)` (excluding the index `len` itself).
2043+ ///
2044+ /// Returns `None` if `mid > len`.
2045+ ///
2046+ /// # Examples
2047+ ///
2048+ /// ```
2049+ /// #![feature(split_at_checked)]
2050+ ///
2051+ /// let v = [1, 2, 3, 4, 5, 6];
2052+ ///
2053+ /// {
2054+ /// let (left, right) = v.split_at_checked(0).unwrap();
2055+ /// assert_eq!(left, []);
2056+ /// assert_eq!(right, [1, 2, 3, 4, 5, 6]);
2057+ /// }
2058+ ///
2059+ /// {
2060+ /// let (left, right) = v.split_at_checked(2).unwrap();
2061+ /// assert_eq!(left, [1, 2]);
2062+ /// assert_eq!(right, [3, 4, 5, 6]);
2063+ /// }
2064+ ///
2065+ /// {
2066+ /// let (left, right) = v.split_at_checked(6).unwrap();
2067+ /// assert_eq!(left, [1, 2, 3, 4, 5, 6]);
2068+ /// assert_eq!(right, []);
2069+ /// }
2070+ ///
2071+ /// assert_eq!(None, v.split_at_checked(7));
2072+ /// ```
2073+ #[ unstable( feature = "split_at_checked" , reason = "new API" , issue = "119128" ) ]
2074+ #[ rustc_const_unstable( feature = "split_at_checked" , issue = "119128" ) ]
2075+ #[ inline]
2076+ #[ track_caller]
2077+ #[ must_use]
2078+ pub const fn split_at_checked ( & self , mid : usize ) -> Option < ( & [ T ] , & [ T ] ) > {
2079+ if mid <= self . len ( ) {
2080+ // SAFETY: `[ptr; mid]` and `[mid; len]` are inside `self`, which
2081+ // fulfills the requirements of `split_at_unchecked`.
2082+ Some ( unsafe { self . split_at_unchecked ( mid) } )
2083+ } else {
2084+ None
2085+ }
2086+ }
2087+
2088+ /// Divides one mutable slice into two at an index, returning `None` if
2089+ /// slice is too short.
2090+ ///
2091+ /// The first will contain all indices from `[0, mid)` (excluding
2092+ /// the index `mid` itself) and the second will contain all
2093+ /// indices from `[mid, len)` (excluding the index `len` itself).
2094+ ///
2095+ /// Returns `None` if `mid > len`.
2096+ ///
2097+ /// # Examples
2098+ ///
2099+ /// ```
2100+ /// #![feature(split_at_checked)]
2101+ ///
2102+ /// let mut v = [1, 0, 3, 0, 5, 6];
2103+ ///
2104+ /// if let Some((left, right)) = v.split_at_mut_checked(2) {
2105+ /// assert_eq!(left, [1, 0]);
2106+ /// assert_eq!(right, [3, 0, 5, 6]);
2107+ /// left[1] = 2;
2108+ /// right[1] = 4;
2109+ /// }
2110+ /// assert_eq!(v, [1, 2, 3, 4, 5, 6]);
2111+ ///
2112+ /// assert_eq!(None, v.split_at_mut_checked(7));
2113+ /// ```
2114+ #[ unstable( feature = "split_at_checked" , reason = "new API" , issue = "119128" ) ]
2115+ #[ rustc_const_unstable( feature = "split_at_checked" , issue = "119128" ) ]
2116+ #[ inline]
2117+ #[ track_caller]
2118+ #[ must_use]
2119+ pub const fn split_at_mut_checked ( & mut self , mid : usize ) -> Option < ( & mut [ T ] , & mut [ T ] ) > {
2120+ if mid <= self . len ( ) {
2121+ // SAFETY: `[ptr; mid]` and `[mid; len]` are inside `self`, which
2122+ // fulfills the requirements of `split_at_unchecked`.
2123+ Some ( unsafe { self . split_at_mut_unchecked ( mid) } )
2124+ } else {
2125+ None
2126+ }
2127+ }
2128+
2129+ /// Divides one slice into an array and a remainder slice at an index.
2130+ ///
2131+ /// The array will contain all indices from `[0, N)` (excluding
2132+ /// the index `N` itself) and the slice will contain all
2133+ /// indices from `[N, len)` (excluding the index `len` itself).
2134+ ///
2135+ /// # Panics
2136+ ///
2137+ /// Panics if `N > len`.
2138+ ///
2139+ /// # Examples
2140+ ///
2141+ /// ```
2142+ /// #![feature(split_array)]
2143+ ///
2144+ /// let v = &[1, 2, 3, 4, 5, 6][..];
2145+ ///
2146+ /// {
2147+ /// let (left, right) = v.split_array_ref::<0>();
2148+ /// assert_eq!(left, &[]);
2149+ /// assert_eq!(right, [1, 2, 3, 4, 5, 6]);
2150+ /// }
2151+ ///
2152+ /// {
2153+ /// let (left, right) = v.split_array_ref::<2>();
2154+ /// assert_eq!(left, &[1, 2]);
2155+ /// assert_eq!(right, [3, 4, 5, 6]);
2156+ /// }
2157+ ///
2158+ /// {
2159+ /// let (left, right) = v.split_array_ref::<6>();
2160+ /// assert_eq!(left, &[1, 2, 3, 4, 5, 6]);
2161+ /// assert_eq!(right, []);
2162+ /// }
2163+ /// ```
2164+ #[ unstable( feature = "split_array" , reason = "new API" , issue = "90091" ) ]
2165+ #[ inline]
2166+ #[ track_caller]
2167+ #[ must_use]
2168+ pub fn split_array_ref < const N : usize > ( & self ) -> ( & [ T ; N ] , & [ T ] ) {
2169+ let ( a, b) = self . split_at ( N ) ;
2170+ // SAFETY: a points to [T; N]? Yes it's [T] of length N (checked by split_at)
2171+ unsafe { ( & * ( a. as_ptr ( ) as * const [ T ; N ] ) , b) }
2172+ }
2173+
2174+ /// Divides one mutable slice into an array and a remainder slice at an index.
2175+ ///
2176+ /// The array will contain all indices from `[0, N)` (excluding
2177+ /// the index `N` itself) and the slice will contain all
2178+ /// indices from `[N, len)` (excluding the index `len` itself).
2179+ ///
2180+ /// # Panics
2181+ ///
2182+ /// Panics if `N > len`.
2183+ ///
2184+ /// # Examples
2185+ ///
2186+ /// ```
2187+ /// #![feature(split_array)]
2188+ ///
2189+ /// let mut v = &mut [1, 0, 3, 0, 5, 6][..];
2190+ /// let (left, right) = v.split_array_mut::<2>();
2191+ /// assert_eq!(left, &mut [1, 0]);
2192+ /// assert_eq!(right, [3, 0, 5, 6]);
2193+ /// left[1] = 2;
2194+ /// right[1] = 4;
2195+ /// assert_eq!(v, [1, 2, 3, 4, 5, 6]);
2196+ /// ```
2197+ #[ unstable( feature = "split_array" , reason = "new API" , issue = "90091" ) ]
2198+ #[ inline]
2199+ #[ track_caller]
2200+ #[ must_use]
2201+ pub fn split_array_mut < const N : usize > ( & mut self ) -> ( & mut [ T ; N ] , & mut [ T ] ) {
2202+ let ( a, b) = self . split_at_mut ( N ) ;
2203+ // SAFETY: a points to [T; N]? Yes it's [T] of length N (checked by split_at_mut)
2204+ unsafe { ( & mut * ( a. as_mut_ptr ( ) as * mut [ T ; N ] ) , b) }
2205+ }
2206+
2207+ /// Divides one slice into an array and a remainder slice at an index from
2208+ /// the end.
2209+ ///
2210+ /// The slice will contain all indices from `[0, len - N)` (excluding
2211+ /// the index `len - N` itself) and the array will contain all
2212+ /// indices from `[len - N, len)` (excluding the index `len` itself).
2213+ ///
2214+ /// # Panics
2215+ ///
2216+ /// Panics if `N > len`.
2217+ ///
2218+ /// # Examples
2219+ ///
2220+ /// ```
2221+ /// #![feature(split_array)]
2222+ ///
2223+ /// let v = &[1, 2, 3, 4, 5, 6][..];
2224+ ///
2225+ /// {
2226+ /// let (left, right) = v.rsplit_array_ref::<0>();
2227+ /// assert_eq!(left, [1, 2, 3, 4, 5, 6]);
2228+ /// assert_eq!(right, &[]);
2229+ /// }
2230+ ///
2231+ /// {
2232+ /// let (left, right) = v.rsplit_array_ref::<2>();
2233+ /// assert_eq!(left, [1, 2, 3, 4]);
2234+ /// assert_eq!(right, &[5, 6]);
2235+ /// }
2236+ ///
2237+ /// {
2238+ /// let (left, right) = v.rsplit_array_ref::<6>();
2239+ /// assert_eq!(left, []);
2240+ /// assert_eq!(right, &[1, 2, 3, 4, 5, 6]);
2241+ /// }
2242+ /// ```
2243+ #[ unstable( feature = "split_array" , reason = "new API" , issue = "90091" ) ]
2244+ #[ inline]
2245+ #[ must_use]
2246+ pub fn rsplit_array_ref < const N : usize > ( & self ) -> ( & [ T ] , & [ T ; N ] ) {
2247+ assert ! ( N <= self . len( ) ) ;
2248+ let ( a, b) = self . split_at ( self . len ( ) - N ) ;
2249+ // SAFETY: b points to [T; N]? Yes it's [T] of length N (checked by split_at)
2250+ unsafe { ( a, & * ( b. as_ptr ( ) as * const [ T ; N ] ) ) }
2251+ }
2252+
2253+ /// Divides one mutable slice into an array and a remainder slice at an
2254+ /// index from the end.
2255+ ///
2256+ /// The slice will contain all indices from `[0, len - N)` (excluding
2257+ /// the index `N` itself) and the array will contain all
2258+ /// indices from `[len - N, len)` (excluding the index `len` itself).
2259+ ///
2260+ /// # Panics
2261+ ///
2262+ /// Panics if `N > len`.
2263+ ///
2264+ /// # Examples
2265+ ///
2266+ /// ```
2267+ /// #![feature(split_array)]
2268+ ///
2269+ /// let mut v = &mut [1, 0, 3, 0, 5, 6][..];
2270+ /// let (left, right) = v.rsplit_array_mut::<4>();
2271+ /// assert_eq!(left, [1, 0]);
2272+ /// assert_eq!(right, &mut [3, 0, 5, 6]);
2273+ /// left[1] = 2;
2274+ /// right[1] = 4;
2275+ /// assert_eq!(v, [1, 2, 3, 4, 5, 6]);
2276+ /// ```
2277+ #[ unstable( feature = "split_array" , reason = "new API" , issue = "90091" ) ]
2278+ #[ inline]
2279+ #[ must_use]
2280+ pub fn rsplit_array_mut < const N : usize > ( & mut self ) -> ( & mut [ T ] , & mut [ T ; N ] ) {
2281+ assert ! ( N <= self . len( ) ) ;
2282+ let ( a, b) = self . split_at_mut ( self . len ( ) - N ) ;
2283+ // SAFETY: b points to [T; N]? Yes it's [T] of length N (checked by split_at_mut)
2284+ unsafe { ( a, & mut * ( b. as_mut_ptr ( ) as * mut [ T ; N ] ) ) }
2285+ }
2286+
20342287 /// Returns an iterator over subslices separated by elements that match
20352288 /// `pred`. The matched element is not contained in the subslices.
20362289 ///
0 commit comments