@@ -117,6 +117,8 @@ pub unsafe fn replace<T>(dest: *mut T, mut src: T) -> T {
117
117
/// `zero_memory`, or `copy_memory`). Note that `*src = foo` counts as a use
118
118
/// because it will attempt to drop the value previously at `*src`.
119
119
///
120
+ /// The pointer must be aligned; use `read_unaligned` if that is not the case.
121
+ ///
120
122
/// # Examples
121
123
///
122
124
/// Basic usage:
@@ -137,6 +139,44 @@ pub unsafe fn read<T>(src: *const T) -> T {
137
139
tmp
138
140
}
139
141
142
+ /// Reads the value from `src` without moving it. This leaves the
143
+ /// memory in `src` unchanged.
144
+ ///
145
+ /// Unlike `read`, the pointer may be unaligned.
146
+ ///
147
+ /// # Safety
148
+ ///
149
+ /// Beyond accepting a raw pointer, this is unsafe because it semantically
150
+ /// moves the value out of `src` without preventing further usage of `src`.
151
+ /// If `T` is not `Copy`, then care must be taken to ensure that the value at
152
+ /// `src` is not used before the data is overwritten again (e.g. with `write`,
153
+ /// `zero_memory`, or `copy_memory`). Note that `*src = foo` counts as a use
154
+ /// because it will attempt to drop the value previously at `*src`.
155
+ ///
156
+ /// # Examples
157
+ ///
158
+ /// Basic usage:
159
+ ///
160
+ /// ```
161
+ /// #![feature(ptr_unaligned)]
162
+ ///
163
+ /// let x = 12;
164
+ /// let y = &x as *const i32;
165
+ ///
166
+ /// unsafe {
167
+ /// assert_eq!(std::ptr::read_unaligned(y), 12);
168
+ /// }
169
+ /// ```
170
+ #[ inline( always) ]
171
+ #[ unstable( feature = "ptr_unaligned" , issue = "37955" ) ]
172
+ pub unsafe fn read_unaligned < T > ( src : * const T ) -> T {
173
+ let mut tmp: T = mem:: uninitialized ( ) ;
174
+ copy_nonoverlapping ( src as * const u8 ,
175
+ & mut tmp as * mut T as * mut u8 ,
176
+ mem:: size_of :: < T > ( ) ) ;
177
+ tmp
178
+ }
179
+
140
180
/// Overwrites a memory location with the given value without reading or
141
181
/// dropping the old value.
142
182
///
@@ -151,6 +191,8 @@ pub unsafe fn read<T>(src: *const T) -> T {
151
191
/// This is appropriate for initializing uninitialized memory, or overwriting
152
192
/// memory that has previously been `read` from.
153
193
///
194
+ /// The pointer must be aligned; use `write_unaligned` if that is not the case.
195
+ ///
154
196
/// # Examples
155
197
///
156
198
/// Basic usage:
@@ -171,6 +213,47 @@ pub unsafe fn write<T>(dst: *mut T, src: T) {
171
213
intrinsics:: move_val_init ( & mut * dst, src)
172
214
}
173
215
216
+ /// Overwrites a memory location with the given value without reading or
217
+ /// dropping the old value.
218
+ ///
219
+ /// Unlike `write`, the pointer may be unaligned.
220
+ ///
221
+ /// # Safety
222
+ ///
223
+ /// This operation is marked unsafe because it accepts a raw pointer.
224
+ ///
225
+ /// It does not drop the contents of `dst`. This is safe, but it could leak
226
+ /// allocations or resources, so care must be taken not to overwrite an object
227
+ /// that should be dropped.
228
+ ///
229
+ /// This is appropriate for initializing uninitialized memory, or overwriting
230
+ /// memory that has previously been `read` from.
231
+ ///
232
+ /// # Examples
233
+ ///
234
+ /// Basic usage:
235
+ ///
236
+ /// ```
237
+ /// #![feature(ptr_unaligned)]
238
+ ///
239
+ /// let mut x = 0;
240
+ /// let y = &mut x as *mut i32;
241
+ /// let z = 12;
242
+ ///
243
+ /// unsafe {
244
+ /// std::ptr::write_unaligned(y, z);
245
+ /// assert_eq!(std::ptr::read_unaligned(y), 12);
246
+ /// }
247
+ /// ```
248
+ #[ inline]
249
+ #[ unstable( feature = "ptr_unaligned" , issue = "37955" ) ]
250
+ pub unsafe fn write_unaligned < T > ( dst : * mut T , src : T ) {
251
+ copy_nonoverlapping ( & src as * const T as * const u8 ,
252
+ dst as * mut u8 ,
253
+ mem:: size_of :: < T > ( ) ) ;
254
+ mem:: forget ( src) ;
255
+ }
256
+
174
257
/// Performs a volatile read of the value from `src` without moving it. This
175
258
/// leaves the memory in `src` unchanged.
176
259
///
0 commit comments