@@ -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,151 @@ 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`]. 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+
11651294 /// Returns the contents of this `MaybeUninit` as a slice of potentially uninitialized bytes.
11661295 ///
11671296 /// 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] {
13151444 unsafe { intrinsics:: transmute_unchecked ( self ) }
13161445 }
13171446}
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