@@ -1842,7 +1842,8 @@ impl<T> [T] {
1842
1842
///
1843
1843
/// # Panics
1844
1844
///
1845
- /// Panics if `mid > len`.
1845
+ /// Panics if `mid > len`. For a non-panicking alternative see
1846
+ /// [`split_at_checked`](slice::split_at_checked).
1846
1847
///
1847
1848
/// # Examples
1848
1849
///
@@ -1869,14 +1870,15 @@ impl<T> [T] {
1869
1870
/// ```
1870
1871
#[ stable( feature = "rust1" , since = "1.0.0" ) ]
1871
1872
#[ rustc_const_stable( feature = "const_slice_split_at_not_mut" , since = "1.71.0" ) ]
1873
+ #[ rustc_allow_const_fn_unstable( split_at_checked) ]
1872
1874
#[ inline]
1873
1875
#[ track_caller]
1874
1876
#[ must_use]
1875
1877
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
+ }
1880
1882
}
1881
1883
1882
1884
/// Divides one mutable slice into two at an index.
@@ -1887,7 +1889,8 @@ impl<T> [T] {
1887
1889
///
1888
1890
/// # Panics
1889
1891
///
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).
1891
1894
///
1892
1895
/// # Examples
1893
1896
///
@@ -1906,10 +1909,10 @@ impl<T> [T] {
1906
1909
#[ must_use]
1907
1910
#[ rustc_const_unstable( feature = "const_slice_split_at_mut" , issue = "101804" ) ]
1908
1911
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
+ }
1913
1916
}
1914
1917
1915
1918
/// Divides one slice into two at an index, without doing bounds checking.
@@ -2031,6 +2034,256 @@ impl<T> [T] {
2031
2034
unsafe { ( from_raw_parts_mut ( ptr, mid) , from_raw_parts_mut ( ptr. add ( mid) , len - mid) ) }
2032
2035
}
2033
2036
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
+
2034
2287
/// Returns an iterator over subslices separated by elements that match
2035
2288
/// `pred`. The matched element is not contained in the subslices.
2036
2289
///
0 commit comments