@@ -1014,154 +1014,6 @@ impl<T> MaybeUninit<T> {
1014
1014
this. as_mut_ptr ( ) as * mut T
1015
1015
}
1016
1016
1017
- /// Copies the elements from `src` to `this`, returning a mutable reference to the now initialized contents of `this`.
1018
- ///
1019
- /// If `T` does not implement `Copy`, use [`write_slice_cloned`]
1020
- ///
1021
- /// This is similar to [`slice::copy_from_slice`].
1022
- ///
1023
- /// # Panics
1024
- ///
1025
- /// This function will panic if the two slices have different lengths.
1026
- ///
1027
- /// # Examples
1028
- ///
1029
- /// ```
1030
- /// #![feature(maybe_uninit_write_slice)]
1031
- /// use std::mem::MaybeUninit;
1032
- ///
1033
- /// let mut dst = [MaybeUninit::uninit(); 32];
1034
- /// let src = [0; 32];
1035
- ///
1036
- /// let init = MaybeUninit::write_slice(&mut dst, &src);
1037
- ///
1038
- /// assert_eq!(init, src);
1039
- /// ```
1040
- ///
1041
- /// ```
1042
- /// #![feature(maybe_uninit_write_slice)]
1043
- /// use std::mem::MaybeUninit;
1044
- ///
1045
- /// let mut vec = Vec::with_capacity(32);
1046
- /// let src = [0; 16];
1047
- ///
1048
- /// MaybeUninit::write_slice(&mut vec.spare_capacity_mut()[..src.len()], &src);
1049
- ///
1050
- /// // SAFETY: we have just copied all the elements of len into the spare capacity
1051
- /// // the first src.len() elements of the vec are valid now.
1052
- /// unsafe {
1053
- /// vec.set_len(src.len());
1054
- /// }
1055
- ///
1056
- /// assert_eq!(vec, src);
1057
- /// ```
1058
- ///
1059
- /// [`write_slice_cloned`]: MaybeUninit::write_slice_cloned
1060
- #[ unstable( feature = "maybe_uninit_write_slice" , issue = "79995" ) ]
1061
- pub fn write_slice < ' a > ( this : & ' a mut [ MaybeUninit < T > ] , src : & [ T ] ) -> & ' a mut [ T ]
1062
- where
1063
- T : Copy ,
1064
- {
1065
- // SAFETY: &[T] and &[MaybeUninit<T>] have the same layout
1066
- let uninit_src: & [ MaybeUninit < T > ] = unsafe { super :: transmute ( src) } ;
1067
-
1068
- this. copy_from_slice ( uninit_src) ;
1069
-
1070
- // SAFETY: Valid elements have just been copied into `this` so it is initialized
1071
- unsafe { MaybeUninit :: slice_assume_init_mut ( this) }
1072
- }
1073
-
1074
- /// Clones the elements from `src` to `this`, returning a mutable reference to the now initialized contents of `this`.
1075
- /// Any already initialized elements will not be dropped.
1076
- ///
1077
- /// If `T` implements `Copy`, use [`write_slice`]
1078
- ///
1079
- /// This is similar to [`slice::clone_from_slice`] but does not drop existing elements.
1080
- ///
1081
- /// # Panics
1082
- ///
1083
- /// This function will panic if the two slices have different lengths, or if the implementation of `Clone` panics.
1084
- ///
1085
- /// If there is a panic, the already cloned elements will be dropped.
1086
- ///
1087
- /// # Examples
1088
- ///
1089
- /// ```
1090
- /// #![feature(maybe_uninit_write_slice)]
1091
- /// use std::mem::MaybeUninit;
1092
- ///
1093
- /// let mut dst = [MaybeUninit::uninit(), MaybeUninit::uninit(), MaybeUninit::uninit(), MaybeUninit::uninit(), MaybeUninit::uninit()];
1094
- /// let src = ["wibbly".to_string(), "wobbly".to_string(), "timey".to_string(), "wimey".to_string(), "stuff".to_string()];
1095
- ///
1096
- /// let init = MaybeUninit::write_slice_cloned(&mut dst, &src);
1097
- ///
1098
- /// assert_eq!(init, src);
1099
- /// ```
1100
- ///
1101
- /// ```
1102
- /// #![feature(maybe_uninit_write_slice)]
1103
- /// use std::mem::MaybeUninit;
1104
- ///
1105
- /// let mut vec = Vec::with_capacity(32);
1106
- /// let src = ["rust", "is", "a", "pretty", "cool", "language"];
1107
- ///
1108
- /// MaybeUninit::write_slice_cloned(&mut vec.spare_capacity_mut()[..src.len()], &src);
1109
- ///
1110
- /// // SAFETY: we have just cloned all the elements of len into the spare capacity
1111
- /// // the first src.len() elements of the vec are valid now.
1112
- /// unsafe {
1113
- /// vec.set_len(src.len());
1114
- /// }
1115
- ///
1116
- /// assert_eq!(vec, src);
1117
- /// ```
1118
- ///
1119
- /// [`write_slice`]: MaybeUninit::write_slice
1120
- #[ unstable( feature = "maybe_uninit_write_slice" , issue = "79995" ) ]
1121
- pub fn write_slice_cloned < ' a > ( this : & ' a mut [ MaybeUninit < T > ] , src : & [ T ] ) -> & ' a mut [ T ]
1122
- where
1123
- T : Clone ,
1124
- {
1125
- // unlike copy_from_slice this does not call clone_from_slice on the slice
1126
- // this is because `MaybeUninit<T: Clone>` does not implement Clone.
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
- assert_eq ! ( this. len( ) , src. len( ) , "destination and source slices have different lengths" ) ;
1145
- // NOTE: We need to explicitly slice them to the same length
1146
- // for bounds checking to be elided, and the optimizer will
1147
- // generate memcpy for simple cases (for example T = u8).
1148
- let len = this. len ( ) ;
1149
- let src = & src[ ..len] ;
1150
-
1151
- // guard is needed b/c panic might happen during a clone
1152
- let mut guard = Guard { slice : this, initialized : 0 } ;
1153
-
1154
- for i in 0 ..len {
1155
- guard. slice [ i] . write ( src[ i] . clone ( ) ) ;
1156
- guard. initialized += 1 ;
1157
- }
1158
-
1159
- super :: forget ( guard) ;
1160
-
1161
- // SAFETY: Valid elements have just been written into `this` so it is initialized
1162
- unsafe { MaybeUninit :: slice_assume_init_mut ( this) }
1163
- }
1164
-
1165
1017
/// Returns the contents of this `MaybeUninit` as a slice of potentially uninitialized bytes.
1166
1018
///
1167
1019
/// Note that even if the contents of a `MaybeUninit` have been initialized, the value may still
@@ -1265,7 +1117,7 @@ impl<T> MaybeUninit<T> {
1265
1117
///
1266
1118
/// let mut uninit = [MaybeUninit::<u16>::uninit(), MaybeUninit::<u16>::uninit()];
1267
1119
/// let uninit_bytes = MaybeUninit::slice_as_bytes_mut(&mut uninit);
1268
- /// MaybeUninit:: write_slice(uninit_bytes, &[0x12, 0x34, 0x56, 0x78]);
1120
+ /// uninit_bytes. write_slice(&[0x12, 0x34, 0x56, 0x78]);
1269
1121
/// let vals = unsafe { MaybeUninit::slice_assume_init_ref(&uninit) };
1270
1122
/// if cfg!(target_endian = "little") {
1271
1123
/// assert_eq!(vals, &[0x3412u16, 0x7856u16]);
@@ -1321,3 +1173,145 @@ impl<T, const N: usize> [MaybeUninit<T>; N] {
1321
1173
unsafe { super :: transmute_copy ( & ManuallyDrop :: new ( self ) ) }
1322
1174
}
1323
1175
}
1176
+
1177
+ impl < T > [ MaybeUninit < T > ] {
1178
+ /// Copies the elements from `src` to `this`, returning a mutable reference to the now initialized contents of `this`.
1179
+ ///
1180
+ /// If `T` does not implement `Copy`, use [`write_slice_cloned`](slice::write_slice_cloned)
1181
+ ///
1182
+ /// This is similar to [`slice::copy_from_slice`].
1183
+ ///
1184
+ /// # Panics
1185
+ ///
1186
+ /// This function will panic if the two slices have different lengths.
1187
+ ///
1188
+ /// # Examples
1189
+ ///
1190
+ /// ```
1191
+ /// #![feature(maybe_uninit_write_slice)]
1192
+ /// use std::mem::MaybeUninit;
1193
+ ///
1194
+ /// let mut dst = [MaybeUninit::uninit(); 32];
1195
+ /// let src = [0; 32];
1196
+ ///
1197
+ /// let init = dst.write_slice(&src);
1198
+ ///
1199
+ /// assert_eq!(init, src);
1200
+ /// ```
1201
+ ///
1202
+ /// ```
1203
+ /// #![feature(maybe_uninit_write_slice)]
1204
+ /// let mut vec = Vec::with_capacity(32);
1205
+ /// let src = [0; 16];
1206
+ ///
1207
+ /// vec.spare_capacity_mut()[..src.len()].write_slice(&src);
1208
+ ///
1209
+ /// // SAFETY: we have just copied all the elements of len into the spare capacity
1210
+ /// // the first src.len() elements of the vec are valid now.
1211
+ /// unsafe {
1212
+ /// vec.set_len(src.len());
1213
+ /// }
1214
+ ///
1215
+ /// assert_eq!(vec, src);
1216
+ /// ```
1217
+ #[ unstable( feature = "maybe_uninit_write_slice" , issue = "79995" ) ]
1218
+ pub fn write_slice ( & mut self , src : & [ T ] ) -> & mut [ T ]
1219
+ where
1220
+ T : Copy ,
1221
+ {
1222
+ // SAFETY: &[T] and &[MaybeUninit<T>] have the same layout
1223
+ let uninit_src: & [ MaybeUninit < T > ] = unsafe { super :: transmute ( src) } ;
1224
+
1225
+ self . copy_from_slice ( uninit_src) ;
1226
+
1227
+ // SAFETY: Valid elements have just been copied into `this` so it is initialized
1228
+ unsafe { MaybeUninit :: slice_assume_init_mut ( self ) }
1229
+ }
1230
+
1231
+ /// Clones the elements from `src` to `this`, returning a mutable reference to the now initialized contents of `this`.
1232
+ /// Any already initialized elements will not be dropped.
1233
+ ///
1234
+ /// If `T` implements `Copy`, use [`write_slice`](slice::write_slice)
1235
+ ///
1236
+ /// This is similar to [`slice::clone_from_slice`] but does not drop existing elements.
1237
+ ///
1238
+ /// # Panics
1239
+ ///
1240
+ /// This function will panic if the two slices have different lengths, or if the implementation of `Clone` panics.
1241
+ ///
1242
+ /// If there is a panic, the already cloned elements will be dropped.
1243
+ ///
1244
+ /// # Examples
1245
+ ///
1246
+ /// ```
1247
+ /// #![feature(maybe_uninit_write_slice)]
1248
+ /// use std::mem::MaybeUninit;
1249
+ ///
1250
+ /// let mut dst = [MaybeUninit::uninit(), MaybeUninit::uninit(), MaybeUninit::uninit(), MaybeUninit::uninit(), MaybeUninit::uninit()];
1251
+ /// let src = ["wibbly".to_string(), "wobbly".to_string(), "timey".to_string(), "wimey".to_string(), "stuff".to_string()];
1252
+ ///
1253
+ /// let init = dst.write_slice_cloned(&src);
1254
+ ///
1255
+ /// assert_eq!(init, src);
1256
+ /// ```
1257
+ ///
1258
+ /// ```
1259
+ /// #![feature(maybe_uninit_write_slice)]
1260
+ /// let mut vec = Vec::with_capacity(32);
1261
+ /// let src = ["rust", "is", "a", "pretty", "cool", "language"];
1262
+ ///
1263
+ /// vec.spare_capacity_mut()[..src.len()].write_slice_cloned(&src);
1264
+ ///
1265
+ /// // SAFETY: we have just cloned all the elements of len into the spare capacity
1266
+ /// // the first src.len() elements of the vec are valid now.
1267
+ /// unsafe {
1268
+ /// vec.set_len(src.len());
1269
+ /// }
1270
+ ///
1271
+ /// assert_eq!(vec, src);
1272
+ /// ```
1273
+ #[ unstable( feature = "maybe_uninit_write_slice" , issue = "79995" ) ]
1274
+ pub fn write_slice_cloned ( & mut self , src : & [ T ] ) -> & mut [ T ]
1275
+ where
1276
+ T : Clone ,
1277
+ {
1278
+ // unlike copy_from_slice this does not call clone_from_slice on the slice
1279
+ // this is because `MaybeUninit<T: Clone>` does not implement Clone.
1280
+
1281
+ struct Guard < ' a , T > {
1282
+ slice : & ' a mut [ MaybeUninit < T > ] ,
1283
+ initialized : usize ,
1284
+ }
1285
+
1286
+ impl < ' a , T > Drop for Guard < ' a , T > {
1287
+ fn drop ( & mut self ) {
1288
+ let initialized_part = & mut self . slice [ ..self . initialized ] ;
1289
+ // SAFETY: this raw slice will contain only initialized objects
1290
+ // that's why, it is allowed to drop it.
1291
+ unsafe {
1292
+ ptr:: drop_in_place ( MaybeUninit :: slice_assume_init_mut ( initialized_part) ) ;
1293
+ }
1294
+ }
1295
+ }
1296
+
1297
+ assert_eq ! ( self . len( ) , src. len( ) , "destination and source slices have different lengths" ) ;
1298
+ // NOTE: We need to explicitly slice them to the same length
1299
+ // for bounds checking to be elided, and the optimizer will
1300
+ // generate memcpy for simple cases (for example T = u8).
1301
+ let len = self . len ( ) ;
1302
+ let src = & src[ ..len] ;
1303
+
1304
+ // guard is needed b/c panic might happen during a clone
1305
+ let mut guard = Guard { slice : self , initialized : 0 } ;
1306
+
1307
+ for i in 0 ..len {
1308
+ guard. slice [ i] . write ( src[ i] . clone ( ) ) ;
1309
+ guard. initialized += 1 ;
1310
+ }
1311
+
1312
+ super :: forget ( guard) ;
1313
+
1314
+ // SAFETY: Valid elements have just been written into `self` so it is initialized
1315
+ unsafe { MaybeUninit :: slice_assume_init_mut ( self ) }
1316
+ }
1317
+ }
0 commit comments