@@ -1125,22 +1125,6 @@ impl<T> MaybeUninit<T> {
11251125 // unlike copy_from_slice this does not call clone_from_slice on the slice
11261126 // this is because `MaybeUninit<T: Clone>` does not implement Clone.
11271127
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-
11441128 assert_eq ! ( this. len( ) , src. len( ) , "destination and source slices have different lengths" ) ;
11451129 // NOTE: We need to explicitly slice them to the same length
11461130 // for bounds checking to be elided, and the optimizer will
@@ -1162,6 +1146,152 @@ impl<T> MaybeUninit<T> {
11621146 unsafe { MaybeUninit :: slice_assume_init_mut ( this) }
11631147 }
11641148
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+
11651295 /// Returns the contents of this `MaybeUninit` as a slice of potentially uninitialized bytes.
11661296 ///
11671297 /// 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] {
13151445 unsafe { intrinsics:: transmute_unchecked ( self ) }
13161446 }
13171447}
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