@@ -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