@@ -1148,7 +1148,10 @@ impl<T> [T] {
1148
1148
#[ stable( feature = "rust1" , since = "1.0.0" ) ]
1149
1149
#[ inline]
1150
1150
pub fn split_at ( & self , mid : usize ) -> ( & [ T ] , & [ T ] ) {
1151
- ( & self [ ..mid] , & self [ mid..] )
1151
+ assert ! ( mid <= self . len( ) ) ;
1152
+ // SAFETY: `[ptr; mid]` and `[mid; len]` are inside `self`, which
1153
+ // fulfills the requirements of `from_raw_parts_mut`.
1154
+ unsafe { self . split_at_unchecked ( mid) }
1152
1155
}
1153
1156
1154
1157
/// Divides one mutable slice into two at an index.
@@ -1178,16 +1181,99 @@ impl<T> [T] {
1178
1181
#[ stable( feature = "rust1" , since = "1.0.0" ) ]
1179
1182
#[ inline]
1180
1183
pub fn split_at_mut ( & mut self , mid : usize ) -> ( & mut [ T ] , & mut [ T ] ) {
1181
- let len = self . len ( ) ;
1182
- let ptr = self . as_mut_ptr ( ) ;
1183
-
1184
+ assert ! ( mid <= self . len( ) ) ;
1184
1185
// SAFETY: `[ptr; mid]` and `[mid; len]` are inside `self`, which
1185
1186
// fulfills the requirements of `from_raw_parts_mut`.
1186
- unsafe {
1187
- assert ! ( mid <= len ) ;
1187
+ unsafe { self . split_at_mut_unchecked ( mid ) }
1188
+ }
1188
1189
1189
- ( from_raw_parts_mut ( ptr, mid) , from_raw_parts_mut ( ptr. add ( mid) , len - mid) )
1190
- }
1190
+ /// Divides one slice into two at an index, without doing bounds checking.
1191
+ ///
1192
+ /// The first will contain all indices from `[0, mid)` (excluding
1193
+ /// the index `mid` itself) and the second will contain all
1194
+ /// indices from `[mid, len)` (excluding the index `len` itself).
1195
+ ///
1196
+ /// This is generally not recommended, use with caution!
1197
+ /// Calling this method with an out-of-bounds index is *[undefined behavior]*
1198
+ /// even if the resulting reference is not used.
1199
+ /// For a safe alternative see [`split_at`].
1200
+ ///
1201
+ /// [`split_at`]: #method.split_at
1202
+ /// [undefined behavior]: https://doc.rust-lang.org/reference/behavior-considered-undefined.html
1203
+ ///
1204
+ /// # Examples
1205
+ ///
1206
+ /// ```compile_fail
1207
+ /// #![feature(slice_split_at_unchecked)]
1208
+ ///
1209
+ /// let v = [1, 2, 3, 4, 5, 6];
1210
+ ///
1211
+ /// unsafe {
1212
+ /// let (left, right) = v.split_at_unchecked(0);
1213
+ /// assert!(left == []);
1214
+ /// assert!(right == [1, 2, 3, 4, 5, 6]);
1215
+ /// }
1216
+ ///
1217
+ /// unsafe {
1218
+ /// let (left, right) = v.split_at_unchecked(2);
1219
+ /// assert!(left == [1, 2]);
1220
+ /// assert!(right == [3, 4, 5, 6]);
1221
+ /// }
1222
+ ///
1223
+ /// unsafe {
1224
+ /// let (left, right) = v.split_at_unchecked(6);
1225
+ /// assert!(left == [1, 2, 3, 4, 5, 6]);
1226
+ /// assert!(right == []);
1227
+ /// }
1228
+ /// ```
1229
+ #[ unstable( feature = "slice_split_at_unchecked" , reason = "new API" , issue = "76014" ) ]
1230
+ #[ inline]
1231
+ unsafe fn split_at_unchecked ( & self , mid : usize ) -> ( & [ T ] , & [ T ] ) {
1232
+ // SAFETY: Caller has to check that 0 <= mid < self.len()
1233
+ unsafe { ( self . get_unchecked ( ..mid) , self . get_unchecked ( mid..) ) }
1234
+ }
1235
+
1236
+ /// Divides one mutable slice into two at an index, without doing bounds checking.
1237
+ ///
1238
+ /// The first will contain all indices from `[0, mid)` (excluding
1239
+ /// the index `mid` itself) and the second will contain all
1240
+ /// indices from `[mid, len)` (excluding the index `len` itself).
1241
+ ///
1242
+ /// This is generally not recommended, use with caution!
1243
+ /// Calling this method with an out-of-bounds index is *[undefined behavior]*
1244
+ /// even if the resulting reference is not used.
1245
+ /// For a safe alternative see [`split_at_mut`].
1246
+ ///
1247
+ /// [`split_at_mut`]: #method.split_at_mut
1248
+ /// [undefined behavior]: https://doc.rust-lang.org/reference/behavior-considered-undefined.html
1249
+ ///
1250
+ /// # Examples
1251
+ ///
1252
+ /// ```compile_fail
1253
+ /// #![feature(slice_split_at_unchecked)]
1254
+ ///
1255
+ /// let mut v = [1, 0, 3, 0, 5, 6];
1256
+ /// // scoped to restrict the lifetime of the borrows
1257
+ /// unsafe {
1258
+ /// let (left, right) = v.split_at_mut_unchecked(2);
1259
+ /// assert!(left == [1, 0]);
1260
+ /// assert!(right == [3, 0, 5, 6]);
1261
+ /// left[1] = 2;
1262
+ /// right[1] = 4;
1263
+ /// }
1264
+ /// assert!(v == [1, 2, 3, 4, 5, 6]);
1265
+ /// ```
1266
+ #[ unstable( feature = "slice_split_at_unchecked" , reason = "new API" , issue = "76014" ) ]
1267
+ #[ inline]
1268
+ unsafe fn split_at_mut_unchecked ( & mut self , mid : usize ) -> ( & mut [ T ] , & mut [ T ] ) {
1269
+ let len = self . len ( ) ;
1270
+ let ptr = self . as_mut_ptr ( ) ;
1271
+
1272
+ // SAFETY: Caller has to check that 0 <= mid < self.len().
1273
+ //
1274
+ // [ptr; mid] and [mid; len] are not overlapping, so returning a mutable reference
1275
+ // is fine.
1276
+ unsafe { ( from_raw_parts_mut ( ptr, mid) , from_raw_parts_mut ( ptr. add ( mid) , len - mid) ) }
1191
1277
}
1192
1278
1193
1279
/// Returns an iterator over subslices separated by elements that match
0 commit comments