|
1 | 1 | use crate::any::type_name;
|
2 | 2 | use crate::fmt;
|
3 | 3 | use crate::intrinsics;
|
4 |
| -use crate::mem::ManuallyDrop; |
| 4 | +use crate::mem::{self, ManuallyDrop}; |
5 | 5 | use crate::ptr;
|
| 6 | +use crate::slice; |
6 | 7 |
|
7 | 8 | /// A wrapper type to construct uninitialized instances of `T`.
|
8 | 9 | ///
|
@@ -1160,4 +1161,126 @@ impl<T> MaybeUninit<T> {
|
1160 | 1161 | // SAFETY: Valid elements have just been written into `this` so it is initialized
|
1161 | 1162 | unsafe { MaybeUninit::slice_assume_init_mut(this) }
|
1162 | 1163 | }
|
| 1164 | + |
| 1165 | + /// Returns the contents of this `MaybeUninit` as a slice of potentially uninitialized bytes. |
| 1166 | + /// |
| 1167 | + /// Note that even if the contents of a `MaybeUninit` have been initialized, the value may still |
| 1168 | + /// contain padding bytes which are left uninitialized. |
| 1169 | + /// |
| 1170 | + /// # Examples |
| 1171 | + /// |
| 1172 | + /// ``` |
| 1173 | + /// #![feature(maybe_uninit_as_bytes, maybe_uninit_slice)] |
| 1174 | + /// use std::mem::MaybeUninit; |
| 1175 | + /// |
| 1176 | + /// let val = 0x12345678i32; |
| 1177 | + /// let uninit = MaybeUninit::new(val); |
| 1178 | + /// let uninit_bytes = uninit.as_bytes(); |
| 1179 | + /// let bytes = unsafe { MaybeUninit::slice_assume_init_ref(uninit_bytes) }; |
| 1180 | + /// assert_eq!(bytes, val.to_ne_bytes()); |
| 1181 | + /// ``` |
| 1182 | + #[unstable(feature = "maybe_uninit_as_bytes", issue = "93092")] |
| 1183 | + pub fn as_bytes(&self) -> &[MaybeUninit<u8>] { |
| 1184 | + // SAFETY: MaybeUninit<u8> is always valid, even for padding bytes |
| 1185 | + unsafe { |
| 1186 | + slice::from_raw_parts(self.as_ptr() as *const MaybeUninit<u8>, mem::size_of::<T>()) |
| 1187 | + } |
| 1188 | + } |
| 1189 | + |
| 1190 | + /// Returns the contents of this `MaybeUninit` as a mutable slice of potentially uninitialized |
| 1191 | + /// bytes. |
| 1192 | + /// |
| 1193 | + /// Note that even if the contents of a `MaybeUninit` have been initialized, the value may still |
| 1194 | + /// contain padding bytes which are left uninitialized. |
| 1195 | + /// |
| 1196 | + /// # Examples |
| 1197 | + /// |
| 1198 | + /// ``` |
| 1199 | + /// #![feature(maybe_uninit_as_bytes)] |
| 1200 | + /// use std::mem::MaybeUninit; |
| 1201 | + /// |
| 1202 | + /// let val = 0x12345678i32; |
| 1203 | + /// let mut uninit = MaybeUninit::new(val); |
| 1204 | + /// let uninit_bytes = uninit.as_bytes_mut(); |
| 1205 | + /// if cfg!(target_endian = "little") { |
| 1206 | + /// uninit_bytes[0].write(0xcd); |
| 1207 | + /// } else { |
| 1208 | + /// uninit_bytes[3].write(0xcd); |
| 1209 | + /// } |
| 1210 | + /// let val2 = unsafe { uninit.assume_init() }; |
| 1211 | + /// assert_eq!(val2, 0x123456cd); |
| 1212 | + /// ``` |
| 1213 | + #[unstable(feature = "maybe_uninit_as_bytes", issue = "93092")] |
| 1214 | + pub fn as_bytes_mut(&mut self) -> &mut [MaybeUninit<u8>] { |
| 1215 | + // SAFETY: MaybeUninit<u8> is always valid, even for padding bytes |
| 1216 | + unsafe { |
| 1217 | + slice::from_raw_parts_mut( |
| 1218 | + self.as_mut_ptr() as *mut MaybeUninit<u8>, |
| 1219 | + mem::size_of::<T>(), |
| 1220 | + ) |
| 1221 | + } |
| 1222 | + } |
| 1223 | + |
| 1224 | + /// Returns the contents of this slice of `MaybeUninit` as a slice of potentially uninitialized |
| 1225 | + /// bytes. |
| 1226 | + /// |
| 1227 | + /// Note that even if the contents of a `MaybeUninit` have been initialized, the value may still |
| 1228 | + /// contain padding bytes which are left uninitialized. |
| 1229 | + /// |
| 1230 | + /// # Examples |
| 1231 | + /// |
| 1232 | + /// ``` |
| 1233 | + /// #![feature(maybe_uninit_as_bytes, maybe_uninit_write_slice, maybe_uninit_slice)] |
| 1234 | + /// use std::mem::MaybeUninit; |
| 1235 | + /// |
| 1236 | + /// let uninit = [MaybeUninit::new(0x1234u16), MaybeUninit::new(0x5678u16)]; |
| 1237 | + /// let uninit_bytes = MaybeUninit::slice_as_bytes(&uninit); |
| 1238 | + /// let bytes = unsafe { MaybeUninit::slice_assume_init_ref(&uninit_bytes) }; |
| 1239 | + /// let val1 = u16::from_ne_bytes(bytes[0..2].try_into().unwrap()); |
| 1240 | + /// let val2 = u16::from_ne_bytes(bytes[2..4].try_into().unwrap()); |
| 1241 | + /// assert_eq!(&[val1, val2], &[0x1234u16, 0x5678u16]); |
| 1242 | + /// ``` |
| 1243 | + #[unstable(feature = "maybe_uninit_as_bytes", issue = "93092")] |
| 1244 | + pub fn slice_as_bytes(this: &[MaybeUninit<T>]) -> &[MaybeUninit<u8>] { |
| 1245 | + // SAFETY: MaybeUninit<u8> is always valid, even for padding bytes |
| 1246 | + unsafe { |
| 1247 | + slice::from_raw_parts( |
| 1248 | + this.as_ptr() as *const MaybeUninit<u8>, |
| 1249 | + this.len() * mem::size_of::<T>(), |
| 1250 | + ) |
| 1251 | + } |
| 1252 | + } |
| 1253 | + |
| 1254 | + /// Returns the contents of this mutable slice of `MaybeUninit` as a mutable slice of |
| 1255 | + /// potentially uninitialized bytes. |
| 1256 | + /// |
| 1257 | + /// Note that even if the contents of a `MaybeUninit` have been initialized, the value may still |
| 1258 | + /// contain padding bytes which are left uninitialized. |
| 1259 | + /// |
| 1260 | + /// # Examples |
| 1261 | + /// |
| 1262 | + /// ``` |
| 1263 | + /// #![feature(maybe_uninit_as_bytes, maybe_uninit_write_slice, maybe_uninit_slice)] |
| 1264 | + /// use std::mem::MaybeUninit; |
| 1265 | + /// |
| 1266 | + /// let mut uninit = [MaybeUninit::<u16>::uninit(), MaybeUninit::<u16>::uninit()]; |
| 1267 | + /// let uninit_bytes = MaybeUninit::slice_as_bytes_mut(&mut uninit); |
| 1268 | + /// MaybeUninit::write_slice(uninit_bytes, &[0x12, 0x34, 0x56, 0x78]); |
| 1269 | + /// let vals = unsafe { MaybeUninit::slice_assume_init_ref(&uninit) }; |
| 1270 | + /// if cfg!(target_endian = "little") { |
| 1271 | + /// assert_eq!(vals, &[0x3412u16, 0x7856u16]); |
| 1272 | + /// } else { |
| 1273 | + /// assert_eq!(vals, &[0x1234u16, 0x5678u16]); |
| 1274 | + /// } |
| 1275 | + /// ``` |
| 1276 | + #[unstable(feature = "maybe_uninit_as_bytes", issue = "93092")] |
| 1277 | + pub fn slice_as_bytes_mut(this: &mut [MaybeUninit<T>]) -> &mut [MaybeUninit<u8>] { |
| 1278 | + // SAFETY: MaybeUninit<u8> is always valid, even for padding bytes |
| 1279 | + unsafe { |
| 1280 | + slice::from_raw_parts_mut( |
| 1281 | + this.as_mut_ptr() as *mut MaybeUninit<u8>, |
| 1282 | + this.len() * mem::size_of::<T>(), |
| 1283 | + ) |
| 1284 | + } |
| 1285 | + } |
1163 | 1286 | }
|
0 commit comments