@@ -1123,22 +1123,6 @@ impl<T> MaybeUninit<T> {
1123
1123
// unlike copy_from_slice this does not call clone_from_slice on the slice
1124
1124
// this is because `MaybeUninit<T: Clone>` does not implement Clone.
1125
1125
1126
- struct Guard < ' a , T > {
1127
- slice : & ' a mut [ MaybeUninit < T > ] ,
1128
- initialized : usize ,
1129
- }
1130
-
1131
- impl < ' a , T > Drop for Guard < ' a , T > {
1132
- fn drop ( & mut self ) {
1133
- let initialized_part = & mut self . slice [ ..self . initialized ] ;
1134
- // SAFETY: this raw slice will contain only initialized objects
1135
- // that's why, it is allowed to drop it.
1136
- unsafe {
1137
- crate :: ptr:: drop_in_place ( MaybeUninit :: slice_assume_init_mut ( initialized_part) ) ;
1138
- }
1139
- }
1140
- }
1141
-
1142
1126
assert_eq ! ( this. len( ) , src. len( ) , "destination and source slices have different lengths" ) ;
1143
1127
// NOTE: We need to explicitly slice them to the same length
1144
1128
// for bounds checking to be elided, and the optimizer will
@@ -1147,7 +1131,7 @@ impl<T> MaybeUninit<T> {
1147
1131
let src = & src[ ..len] ;
1148
1132
1149
1133
// guard is needed b/c panic might happen during a clone
1150
- let mut guard = Guard { slice : this, initialized : 0 } ;
1134
+ let mut guard = CloneGuard { slice : this, initialized : 0 } ;
1151
1135
1152
1136
for i in 0 ..len {
1153
1137
guard. slice [ i] . write ( src[ i] . clone ( ) ) ;
@@ -1160,6 +1144,202 @@ impl<T> MaybeUninit<T> {
1160
1144
unsafe { MaybeUninit :: slice_assume_init_mut ( this) }
1161
1145
}
1162
1146
1147
+ /// Fills `this` with elements by copying `value`, returning a reference to
1148
+ /// the now initialized contents of `this`.
1149
+ ///
1150
+ /// This is similar to [`slice::fill`] but is restricted to `Copy` values.
1151
+ /// Use [`MaybeUninit::fill_cloned`] to initialize from a `Clone` value.
1152
+ ///
1153
+ /// # Examples
1154
+ ///
1155
+ /// ```
1156
+ /// #![feature(maybe_uninit_fill)]
1157
+ /// use std::mem::MaybeUninit;
1158
+ ///
1159
+ /// let mut dst = [MaybeUninit::uninit(); 5];
1160
+ /// let init = MaybeUninit::fill(&mut dst, 0u8);
1161
+ ///
1162
+ /// assert_eq!(init, &[0, 0, 0, 0, 0]);
1163
+ /// ```
1164
+ #[ doc( alias = "memset" ) ]
1165
+ #[ unstable( feature = "maybe_uninit_fill" , issue = "none" ) ]
1166
+ pub fn fill < ' a > ( this : & ' a mut [ MaybeUninit < T > ] , value : T ) -> & ' a [ T ]
1167
+ where
1168
+ T : Copy ,
1169
+ {
1170
+ this. fill ( MaybeUninit :: new ( value) ) ;
1171
+ // SAFETY: Valid elements have just been copied into `this` so it is initialized
1172
+ unsafe { MaybeUninit :: slice_assume_init_ref ( this) }
1173
+ }
1174
+
1175
+ /// Fills `this` with elements by copying `value`, returning a mutable
1176
+ /// reference to the now initialized contents of `this`.
1177
+ ///
1178
+ /// This is similar to [`slice::fill`] but is restricted to `Copy` values.
1179
+ /// Use [`MaybeUninit::fill_cloned`] to initialize from a `Clone` value.
1180
+ ///
1181
+ /// # Examples
1182
+ ///
1183
+ /// ```
1184
+ /// #![feature(maybe_uninit_fill)]
1185
+ /// use std::mem::MaybeUninit;
1186
+ ///
1187
+ /// let mut dst = [MaybeUninit::uninit(); 5];
1188
+ /// let init = MaybeUninit::fill_mut(&mut dst, 0u8);
1189
+ /// init[4] = 123;
1190
+ ///
1191
+ /// assert_eq!(init, &[0, 0, 0, 0, 123]);
1192
+ /// ```
1193
+ #[ unstable( feature = "maybe_uninit_fill" , issue = "none" ) ]
1194
+ pub fn fill_mut < ' a > ( this : & ' a mut [ MaybeUninit < T > ] , value : T ) -> & ' a mut [ T ]
1195
+ where
1196
+ T : Copy ,
1197
+ {
1198
+ this. fill ( MaybeUninit :: new ( value) ) ;
1199
+ // SAFETY: Valid elements have just been copied into `this` so it is initialized
1200
+ unsafe { MaybeUninit :: slice_assume_init_mut ( this) }
1201
+ }
1202
+
1203
+ /// Fills `this` with elements by cloning `value`, returning a reference to
1204
+ /// the now initialized contents of `this`. Any already initialized elements
1205
+ /// will not be dropped.
1206
+ ///
1207
+ /// This is similar to [`slice::fill`] but does not drop existing elements.
1208
+ ///
1209
+ /// # Panics
1210
+ ///
1211
+ /// This function will panic if the implementation of `Clone` panics.
1212
+ ///
1213
+ /// If there is a panic, the already initialized elements will be dropped.
1214
+ ///
1215
+ /// # Examples
1216
+ ///
1217
+ /// ```
1218
+ /// #![feature(maybe_uninit_fill)]
1219
+ /// use std::mem::MaybeUninit;
1220
+ ///
1221
+ /// let mut dst = [
1222
+ /// MaybeUninit::uninit(),
1223
+ /// MaybeUninit::uninit(),
1224
+ /// MaybeUninit::uninit(),
1225
+ /// ];
1226
+ /// let msg = String::from("hello");
1227
+ /// let init = MaybeUninit::fill_cloned(&mut dst, &msg);
1228
+ ///
1229
+ /// assert_eq!(init, &["hello", "hello", "hello"]);
1230
+ /// ```
1231
+ #[ unstable( feature = "maybe_uninit_fill" , issue = "none" ) ]
1232
+ pub fn fill_cloned < ' a > ( this : & ' a mut [ MaybeUninit < T > ] , value : & T ) -> & ' a [ T ]
1233
+ where
1234
+ T : Clone ,
1235
+ {
1236
+ let len = this. len ( ) ;
1237
+
1238
+ // guard is needed b/c panic might happen during a clone
1239
+ let mut guard = CloneGuard { slice : this, initialized : 0 } ;
1240
+
1241
+ for i in 0 ..len {
1242
+ guard. slice [ i] . write ( value. clone ( ) ) ;
1243
+ guard. initialized += 1 ;
1244
+ }
1245
+
1246
+ super :: forget ( guard) ;
1247
+
1248
+ // SAFETY: Valid elements have just been written into `this` so it is initialized
1249
+ unsafe { MaybeUninit :: slice_assume_init_ref ( this) }
1250
+ }
1251
+
1252
+ /// Fills `this` with elements returned by calling a closure repeatedly,
1253
+ /// returning a reference to the now initialized contents of `this`. Any
1254
+ /// already initialized elements will not be dropped.
1255
+ ///
1256
+ /// This is similar to [`slice::fill_with`] but does not drop existing
1257
+ /// elements.
1258
+ ///
1259
+ /// # Panics
1260
+ ///
1261
+ /// This function will panic if the closure panics.
1262
+ ///
1263
+ /// If there is a panic, the already initialized elements will be dropped.
1264
+ ///
1265
+ /// # Examples
1266
+ ///
1267
+ /// ```
1268
+ /// #![feature(maybe_uninit_fill)]
1269
+ /// use std::mem::MaybeUninit;
1270
+ ///
1271
+ /// let mut dst = [MaybeUninit::uninit(); 5];
1272
+ /// let mut next = 0;
1273
+ /// let init = MaybeUninit::fill_with(&mut dst, || { next += 1; next });
1274
+ ///
1275
+ /// assert_eq!(init, &[1, 2, 3, 4, 5]);
1276
+ /// ```
1277
+ #[ unstable( feature = "maybe_uninit_fill" , issue = "none" ) ]
1278
+ pub fn fill_with < ' a , F > ( this : & ' a mut [ MaybeUninit < T > ] , mut f : F ) -> & ' a [ T ]
1279
+ where
1280
+ F : FnMut ( ) -> T ,
1281
+ {
1282
+ let len = this. len ( ) ;
1283
+ let mut guard = CloneGuard { slice : this, initialized : 0 } ;
1284
+
1285
+ for i in 0 ..len {
1286
+ guard. slice [ i] . write ( f ( ) ) ;
1287
+ guard. initialized += 1 ;
1288
+ }
1289
+
1290
+ super :: forget ( guard) ;
1291
+
1292
+ // SAFETY: Valid elements have just been written into `this` so it is initialized
1293
+ unsafe { MaybeUninit :: slice_assume_init_ref ( this) }
1294
+ }
1295
+
1296
+ /// Fills `this` with the contents of an iterator, returning a reference to
1297
+ /// the now initialized contents of `this`. Any already initialized elements
1298
+ /// will not be dropped.
1299
+ ///
1300
+ /// # Panics
1301
+ ///
1302
+ /// This function will panic if the iterator panics.
1303
+ ///
1304
+ /// If there is a panic, the already initialized elements will be dropped.
1305
+ ///
1306
+ /// # Examples
1307
+ ///
1308
+ /// ```
1309
+ /// #![feature(maybe_uninit_fill)]
1310
+ /// use std::mem::MaybeUninit;
1311
+ ///
1312
+ /// let mut dst = [MaybeUninit::uninit(); 5];
1313
+ /// let mut iter = [1, 2, 3].into_iter().cycle();
1314
+ /// let init = MaybeUninit::fill_from(&mut dst, iter);
1315
+ ///
1316
+ /// assert_eq!(init, &[1, 2, 3, 1, 2]);
1317
+ /// ```
1318
+ #[ unstable( feature = "maybe_uninit_fill" , issue = "none" ) ]
1319
+ pub fn fill_from < ' a , I > ( this : & ' a mut [ MaybeUninit < T > ] , mut iter : I ) -> & ' a [ T ]
1320
+ where
1321
+ I : Iterator < Item = T > ,
1322
+ {
1323
+ let len = this. len ( ) ;
1324
+ let mut guard = CloneGuard { slice : this, initialized : 0 } ;
1325
+
1326
+ for i in 0 ..len {
1327
+ match iter. next ( ) {
1328
+ Some ( value) => {
1329
+ guard. slice [ i] . write ( value) ;
1330
+ guard. initialized += 1 ;
1331
+ }
1332
+ None => break ,
1333
+ }
1334
+ }
1335
+
1336
+ let init_len = guard. initialized ;
1337
+ super :: forget ( guard) ;
1338
+
1339
+ // SAFETY: Valid elements have just been written into `this` so it is initialized
1340
+ unsafe { MaybeUninit :: slice_assume_init_ref ( & mut this[ ..init_len] ) }
1341
+ }
1342
+
1163
1343
/// Returns the contents of this `MaybeUninit` as a slice of potentially uninitialized bytes.
1164
1344
///
1165
1345
/// Note that even if the contents of a `MaybeUninit` have been initialized, the value may still
@@ -1313,3 +1493,19 @@ impl<T, const N: usize> [MaybeUninit<T>; N] {
1313
1493
unsafe { intrinsics:: transmute_unchecked ( self ) }
1314
1494
}
1315
1495
}
1496
+
1497
+ struct CloneGuard < ' a , T > {
1498
+ slice : & ' a mut [ MaybeUninit < T > ] ,
1499
+ initialized : usize ,
1500
+ }
1501
+
1502
+ impl < ' a , T > Drop for CloneGuard < ' a , T > {
1503
+ fn drop ( & mut self ) {
1504
+ let initialized_part = & mut self . slice [ ..self . initialized ] ;
1505
+ // SAFETY: this raw slice will contain only initialized objects
1506
+ // that's why, it is allowed to drop it.
1507
+ unsafe {
1508
+ crate :: ptr:: drop_in_place ( MaybeUninit :: slice_assume_init_mut ( initialized_part) ) ;
1509
+ }
1510
+ }
1511
+ }
0 commit comments