@@ -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,151 @@ 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`]. If you want to use the `Default` trait to generate values, you can
1188
+ /// pass [`Default::default`] as the argument.
1189
+ ///
1190
+ /// # Panics
1191
+ ///
1192
+ /// This function will panic if any call to the provided closure panics.
1193
+ ///
1194
+ /// If such a panic occurs, any elements previously initialized during this operation will be
1195
+ /// dropped.
1196
+ ///
1197
+ /// # Examples
1198
+ ///
1199
+ /// Fill an uninit vec with the default value.
1200
+ /// ```
1201
+ /// #![feature(maybe_uninit_fill)]
1202
+ /// use std::mem::MaybeUninit;
1203
+ ///
1204
+ /// let mut buf = vec![MaybeUninit::<i32>::uninit(); 10];
1205
+ /// let initialized = MaybeUninit::fill_with(buf.as_mut_slice(), Default::default);
1206
+ /// assert_eq!(initialized, &mut [0; 10]);
1207
+ /// ```
1208
+ #[ unstable( feature = "maybe_uninit_fill" , issue = "117428" ) ]
1209
+ pub fn fill_with < ' a , F > ( this : & ' a mut [ MaybeUninit < T > ] , mut f : F ) -> & ' a mut [ T ]
1210
+ where
1211
+ F : FnMut ( ) -> T ,
1212
+ {
1213
+ let mut guard = Guard { slice : this, initialized : 0 } ;
1214
+
1215
+ for element in guard. slice . iter_mut ( ) {
1216
+ element. write ( f ( ) ) ;
1217
+ guard. initialized += 1 ;
1218
+ }
1219
+
1220
+ super :: forget ( guard) ;
1221
+
1222
+ // SAFETY: Valid elements have just been written into `this` so it is initialized
1223
+ unsafe { MaybeUninit :: slice_assume_init_mut ( this) }
1224
+ }
1225
+
1226
+ /// Fills `this` with elements yielded by an iterator until either all elements have been
1227
+ /// initialized or the iterator is empty.
1228
+ ///
1229
+ /// Returns two slices. The first slice contains the initialized portion of the original slice.
1230
+ /// The second slice is the still-uninitialized remainder of the original slice.
1231
+ ///
1232
+ /// # Panics
1233
+ ///
1234
+ /// This function panics if the iterator's `next` function panics.
1235
+ ///
1236
+ /// If such a panic occurs, any elements previously initialized during this operation will be
1237
+ /// dropped.
1238
+ ///
1239
+ /// # Examples
1240
+ ///
1241
+ /// Fill an uninit vec with a cycling iterator.
1242
+ /// ```
1243
+ /// #![feature(maybe_uninit_fill)]
1244
+ /// use std::mem::MaybeUninit;
1245
+ ///
1246
+ /// let mut buf = vec![MaybeUninit::uninit(); 5];
1247
+ ///
1248
+ /// let iter = [1, 2, 3].into_iter().cycle();
1249
+ /// let (initialized, remainder) = MaybeUninit::fill_from(&mut buf, iter);
1250
+ ///
1251
+ /// assert_eq!(initialized, &mut [1, 2, 3, 1, 2]);
1252
+ /// assert_eq!(0, remainder.len());
1253
+ /// ```
1254
+ ///
1255
+ /// Fill an uninit vec, but not completely.
1256
+ /// ```
1257
+ /// #![feature(maybe_uninit_fill)]
1258
+ /// use std::mem::MaybeUninit;
1259
+ ///
1260
+ /// let mut buf = vec![MaybeUninit::uninit(); 5];
1261
+ /// let iter = [1, 2];
1262
+ /// let (initialized, remainder) = MaybeUninit::fill_from(&mut buf, iter);
1263
+ ///
1264
+ /// assert_eq!(initialized, &mut [1, 2]);
1265
+ /// assert_eq!(remainder.len(), 3);
1266
+ /// ```
1267
+ #[ unstable( feature = "maybe_uninit_fill" , issue = "117428" ) ]
1268
+ pub fn fill_from < ' a , I > (
1269
+ this : & ' a mut [ MaybeUninit < T > ] ,
1270
+ it : I ,
1271
+ ) -> ( & ' a mut [ T ] , & ' a mut [ MaybeUninit < T > ] )
1272
+ where
1273
+ I : IntoIterator < Item = T > ,
1274
+ {
1275
+ let iter = it. into_iter ( ) ;
1276
+ let mut guard = Guard { slice : this, initialized : 0 } ;
1277
+
1278
+ for ( element, val) in guard. slice . iter_mut ( ) . zip ( iter) {
1279
+ element. write ( val) ;
1280
+ guard. initialized += 1 ;
1281
+ }
1282
+
1283
+ let initialized_len = guard. initialized ;
1284
+ super :: forget ( guard) ;
1285
+
1286
+ // SAFETY: guard.initialized <= this.len()
1287
+ let ( initted, remainder) = unsafe { this. split_at_mut_unchecked ( initialized_len) } ;
1288
+
1289
+ // SAFETY: Valid elements have just been written into `init`, so that portion
1290
+ // of `this` is initialized.
1291
+ ( unsafe { MaybeUninit :: slice_assume_init_mut ( initted) } , remainder)
1292
+ }
1293
+
1165
1294
/// Returns the contents of this `MaybeUninit` as a slice of potentially uninitialized bytes.
1166
1295
///
1167
1296
/// Note that even if the contents of a `MaybeUninit` have been initialized, the value may still
@@ -1315,3 +1444,44 @@ impl<T, const N: usize> [MaybeUninit<T>; N] {
1315
1444
unsafe { intrinsics:: transmute_unchecked ( self ) }
1316
1445
}
1317
1446
}
1447
+
1448
+ struct Guard < ' a , T > {
1449
+ slice : & ' a mut [ MaybeUninit < T > ] ,
1450
+ initialized : usize ,
1451
+ }
1452
+
1453
+ impl < ' a , T > Drop for Guard < ' a , T > {
1454
+ fn drop ( & mut self ) {
1455
+ let initialized_part = & mut self . slice [ ..self . initialized ] ;
1456
+ // SAFETY: this raw sub-slice will contain only initialized objects.
1457
+ unsafe {
1458
+ crate :: ptr:: drop_in_place ( MaybeUninit :: slice_assume_init_mut ( initialized_part) ) ;
1459
+ }
1460
+ }
1461
+ }
1462
+
1463
+ trait SpecFill < T > {
1464
+ fn spec_fill ( & mut self , value : T ) ;
1465
+ }
1466
+
1467
+ impl < T : Clone > SpecFill < T > for [ MaybeUninit < T > ] {
1468
+ default fn spec_fill ( & mut self , value : T ) {
1469
+ let mut guard = Guard { slice : self , initialized : 0 } ;
1470
+
1471
+ if let Some ( ( last, elems) ) = guard. slice . split_last_mut ( ) {
1472
+ for el in elems {
1473
+ el. write ( value. clone ( ) ) ;
1474
+ guard. initialized += 1 ;
1475
+ }
1476
+
1477
+ last. write ( value) ;
1478
+ }
1479
+ super :: forget ( guard) ;
1480
+ }
1481
+ }
1482
+
1483
+ impl < T : Copy > SpecFill < T > for [ MaybeUninit < T > ] {
1484
+ fn spec_fill ( & mut self , value : T ) {
1485
+ self . fill ( MaybeUninit :: new ( value) ) ;
1486
+ }
1487
+ }
0 commit comments