@@ -1125,22 +1125,6 @@ impl<T> MaybeUninit<T> {
1125
1125
// unlike copy_from_slice this does not call clone_from_slice on the slice
1126
1126
// this is because `MaybeUninit<T: Clone>` does not implement Clone.
1127
1127
1128
- struct Guard < ' a , T > {
1129
- slice : & ' a mut [ MaybeUninit < T > ] ,
1130
- initialized : usize ,
1131
- }
1132
-
1133
- impl < ' a , T > Drop for Guard < ' a , T > {
1134
- fn drop ( & mut self ) {
1135
- let initialized_part = & mut self . slice [ ..self . initialized ] ;
1136
- // SAFETY: this raw slice will contain only initialized objects
1137
- // that's why, it is allowed to drop it.
1138
- unsafe {
1139
- crate :: ptr:: drop_in_place ( MaybeUninit :: slice_assume_init_mut ( initialized_part) ) ;
1140
- }
1141
- }
1142
- }
1143
-
1144
1128
assert_eq ! ( this. len( ) , src. len( ) , "destination and source slices have different lengths" ) ;
1145
1129
// NOTE: We need to explicitly slice them to the same length
1146
1130
// for bounds checking to be elided, and the optimizer will
@@ -1162,6 +1146,152 @@ impl<T> MaybeUninit<T> {
1162
1146
unsafe { MaybeUninit :: slice_assume_init_mut ( this) }
1163
1147
}
1164
1148
1149
+ /// Fills `this` with elements by cloning `value`, returning a mutable reference to the now
1150
+ /// initialized contents of `this`.
1151
+ /// Any previously initialized elements will not be dropped.
1152
+ ///
1153
+ /// This is similar to [`slice::fill`].
1154
+ ///
1155
+ /// # Panics
1156
+ ///
1157
+ /// This function will panic if any call to `Clone` panics.
1158
+ ///
1159
+ /// If such a panic occurs, any elements previously initialized during this operation will be
1160
+ /// dropped.
1161
+ ///
1162
+ /// # Examples
1163
+ ///
1164
+ /// Fill an uninit vec with 1.
1165
+ /// ```
1166
+ /// #[feature(maybe_uninit_fill)]
1167
+ /// use std::mem::MaybeUninit;
1168
+ ///
1169
+ /// let mut buf = vec![MaybeUninit::uninit(); 10];
1170
+ /// let initialized = MaybeUninit::fill(buf.as_mut_slice(), 1);
1171
+ /// assert_eq!(initialized, &mut [1; 10]);
1172
+ /// ```
1173
+ #[ doc( alias = "memset" ) ]
1174
+ #[ unstable( feature = "maybe_uninit_fill" , issue = "117428" ) ]
1175
+ pub fn fill < ' a > ( this : & ' a mut [ MaybeUninit < T > ] , value : T ) -> & ' a mut [ T ]
1176
+ where
1177
+ T : Clone ,
1178
+ {
1179
+ SpecFill :: spec_fill ( this, value) ;
1180
+ // SAFETY: Valid elements have just been filled into `this` so it is initialized
1181
+ unsafe { MaybeUninit :: slice_assume_init_mut ( this) }
1182
+ }
1183
+
1184
+ /// Fills `this` with elements returned by calling a closure repeatedly.
1185
+ ///
1186
+ /// This method uses a closure to create new values. If you'd rather `Clone` a given value, use
1187
+ /// [`MaybeUninit::fill_cloned`], or [`MaybeUninit::fill`] if the value is `Copy`. If you want
1188
+ /// to use the `Default` trait to generate values, you can pass [`Default::default`] as the
1189
+ /// argument.
1190
+ ///
1191
+ /// # Panics
1192
+ ///
1193
+ /// This function will panic if any call to the provided closure panics.
1194
+ ///
1195
+ /// If such a panic occurs, any elements previously initialized during this operation will be
1196
+ /// dropped.
1197
+ ///
1198
+ /// # Examples
1199
+ ///
1200
+ /// Fill an uninit vec with the default value.
1201
+ /// ```
1202
+ /// #[feature(maybe_uninit_fill)]
1203
+ /// use std::mem::MaybeUninit;
1204
+ ///
1205
+ /// let mut buf = vec![MaybeUninit::<i32>::uninit(); 10];
1206
+ /// let initialized = MaybeUninit::fill_with(buf.as_mut_slice(), Default::default);
1207
+ /// assert_eq!(initialized, &mut [1; 10]);
1208
+ /// ```
1209
+ #[ unstable( feature = "maybe_uninit_fill" , issue = "117428" ) ]
1210
+ pub fn fill_with < ' a , F > ( this : & ' a mut [ MaybeUninit < T > ] , mut f : F ) -> & ' a mut [ T ]
1211
+ where
1212
+ F : FnMut ( ) -> T ,
1213
+ {
1214
+ let mut guard = Guard { slice : this, initialized : 0 } ;
1215
+
1216
+ for element in guard. slice . iter_mut ( ) {
1217
+ element. write ( f ( ) ) ;
1218
+ guard. initialized += 1 ;
1219
+ }
1220
+
1221
+ super :: forget ( guard) ;
1222
+
1223
+ // SAFETY: Valid elements have just been written into `this` so it is initialized
1224
+ unsafe { MaybeUninit :: slice_assume_init_mut ( this) }
1225
+ }
1226
+
1227
+ /// Fills `this` with elements yielded by an iterator until either all elements have been
1228
+ /// initialized or the iterator is empty.
1229
+ ///
1230
+ /// Returns two slices. The first slice contains the initialized portion of the original slice.
1231
+ /// The second slice is the still-uninitialized remainder of the original slice.
1232
+ ///
1233
+ /// # Panics
1234
+ ///
1235
+ /// This function panics if the iterator's `next` function panics.
1236
+ ///
1237
+ /// If such a panic occurs, any elements previously initialized during this operation will be
1238
+ /// dropped.
1239
+ ///
1240
+ /// # Examples
1241
+ ///
1242
+ /// Fill an uninit vec with a cycling iterator.
1243
+ /// ```
1244
+ /// #[feature(maybe_uninit_fill)]
1245
+ /// use std::mem::MaybeUninit;
1246
+ ///
1247
+ /// let mut buf = vec![MaybeUninit::uninit(); 5];
1248
+ ///
1249
+ /// let iter = [1, 2, 3].into_iter().cycle();
1250
+ /// let (initialized, remainder) = MaybeUninit::fill_from(&mut buf, iter);
1251
+ ///
1252
+ /// assert_eq!(initialized, &mut [1, 2, 3, 1, 2]);
1253
+ /// assert_eq!(0, remainder.len());
1254
+ /// ```
1255
+ ///
1256
+ /// Fill an uninit vec, but not completely.
1257
+ /// ```
1258
+ /// #[feature(maybe_uninit_fill)]
1259
+ /// use std::mem::MaybeUninit;
1260
+ ///
1261
+ /// let mut buf = vec![MaybeUninit::uninit(); 5];
1262
+ /// let iter = [1, 2];
1263
+ /// let (initialized, remainder) = MaybeUninit::fill_from(&mut buf, iter);
1264
+ ///
1265
+ /// assert_eq!(initialized, &mut [1, 2]);
1266
+ /// assert_eq!(remainder.len(), 3);
1267
+ /// ```
1268
+ #[ unstable( feature = "maybe_uninit_fill" , issue = "117428" ) ]
1269
+ pub fn fill_from < ' a , I > (
1270
+ this : & ' a mut [ MaybeUninit < T > ] ,
1271
+ it : I ,
1272
+ ) -> ( & ' a mut [ T ] , & ' a mut [ MaybeUninit < T > ] )
1273
+ where
1274
+ I : IntoIterator < Item = T > ,
1275
+ {
1276
+ let iter = it. into_iter ( ) ;
1277
+ let mut guard = Guard { slice : this, initialized : 0 } ;
1278
+
1279
+ for ( element, val) in guard. slice . iter_mut ( ) . zip ( iter) {
1280
+ element. write ( val) ;
1281
+ guard. initialized += 1 ;
1282
+ }
1283
+
1284
+ let initialized_len = guard. initialized ;
1285
+ super :: forget ( guard) ;
1286
+
1287
+ // SAFETY: guard.initialized <= this.len()
1288
+ let ( initted, remainder) = unsafe { this. split_at_mut_unchecked ( initialized_len) } ;
1289
+
1290
+ // SAFETY: Valid elements have just been written into `init`, so that portion
1291
+ // of `this` is initialized.
1292
+ ( unsafe { MaybeUninit :: slice_assume_init_mut ( initted) } , remainder)
1293
+ }
1294
+
1165
1295
/// Returns the contents of this `MaybeUninit` as a slice of potentially uninitialized bytes.
1166
1296
///
1167
1297
/// Note that even if the contents of a `MaybeUninit` have been initialized, the value may still
@@ -1315,3 +1445,44 @@ impl<T, const N: usize> [MaybeUninit<T>; N] {
1315
1445
unsafe { intrinsics:: transmute_unchecked ( self ) }
1316
1446
}
1317
1447
}
1448
+
1449
+ struct Guard < ' a , T > {
1450
+ slice : & ' a mut [ MaybeUninit < T > ] ,
1451
+ initialized : usize ,
1452
+ }
1453
+
1454
+ impl < ' a , T > Drop for Guard < ' a , T > {
1455
+ fn drop ( & mut self ) {
1456
+ let initialized_part = & mut self . slice [ ..self . initialized ] ;
1457
+ // SAFETY: this raw sub-slice will contain only initialized objects.
1458
+ unsafe {
1459
+ crate :: ptr:: drop_in_place ( MaybeUninit :: slice_assume_init_mut ( initialized_part) ) ;
1460
+ }
1461
+ }
1462
+ }
1463
+
1464
+ trait SpecFill < T > {
1465
+ fn spec_fill ( & mut self , value : T ) ;
1466
+ }
1467
+
1468
+ impl < T : Clone > SpecFill < T > for [ MaybeUninit < T > ] {
1469
+ default fn spec_fill ( & mut self , value : T ) {
1470
+ let mut guard = Guard { slice : self , initialized : 0 } ;
1471
+
1472
+ if let Some ( ( last, elems) ) = guard. slice . split_last_mut ( ) {
1473
+ for el in elems {
1474
+ el. write ( value. clone ( ) ) ;
1475
+ guard. initialized += 1 ;
1476
+ }
1477
+
1478
+ last. write ( value) ;
1479
+ }
1480
+ super :: forget ( guard) ;
1481
+ }
1482
+ }
1483
+
1484
+ impl < T : Copy > SpecFill < T > for [ MaybeUninit < T > ] {
1485
+ fn spec_fill ( & mut self , value : T ) {
1486
+ self . fill ( MaybeUninit :: new ( value) ) ;
1487
+ }
1488
+ }
0 commit comments