]> git.lizzy.rs Git - rust.git/blob - src/libcore/mem.rs
1032b820b27514d5aa40f238571424eaf2ad6a37
[rust.git] / src / libcore / mem.rs
1 // Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT
2 // file at the top-level directory of this distribution and at
3 // http://rust-lang.org/COPYRIGHT.
4 //
5 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8 // option. This file may not be copied, modified, or distributed
9 // except according to those terms.
10
11 //! Basic functions for dealing with memory
12 //!
13 //! This module contains functions for querying the size and alignment of
14 //! types, initializing and manipulating memory.
15
16 use intrinsics;
17 use num::Int;
18 use ptr;
19
20 pub use intrinsics::transmute;
21
22 /// Returns the size of a type in bytes.
23 #[inline]
24 #[stable]
25 pub fn size_of<T>() -> uint {
26     unsafe { intrinsics::size_of::<T>() }
27 }
28
29 /// Returns the size of the type that `_val` points to in bytes.
30 #[inline]
31 #[stable]
32 pub fn size_of_val<T>(_val: &T) -> uint {
33     size_of::<T>()
34 }
35
36 /// Deprecated, this function will be removed soon
37 #[inline]
38 #[deprecated = "this function will be removed soon"]
39 pub fn nonzero_size_of<T>() -> uint {
40     match size_of::<T>() {
41         0 => 1,
42         n => n,
43     }
44 }
45
46 /// Deprecated, this function will be removed soon
47 #[inline]
48 #[deprecated = "this function will be removed soon"]
49 pub fn nonzero_size_of_val<T>(val: &T) -> uint {
50     match size_of_val::<T>(val) {
51         0 => 1,
52         n => n,
53     }
54 }
55
56 /// Returns the ABI-required minimum alignment of a type
57 ///
58 /// This is the alignment used for struct fields. It may be smaller
59 /// than the preferred alignment.
60 #[inline]
61 #[stable]
62 pub fn min_align_of<T>() -> uint {
63     unsafe { intrinsics::min_align_of::<T>() }
64 }
65
66 /// Returns the ABI-required minimum alignment of the type of the value that
67 /// `_val` points to
68 #[inline]
69 #[stable]
70 pub fn min_align_of_val<T>(_val: &T) -> uint {
71     min_align_of::<T>()
72 }
73
74 /// Returns the alignment in memory for a type.
75 ///
76 /// This function will return the alignment, in bytes, of a type in memory. If
77 /// the alignment returned is adhered to, then the type is guaranteed to
78 /// function properly.
79 #[inline]
80 #[stable]
81 pub fn align_of<T>() -> uint {
82     // We use the preferred alignment as the default alignment for a type. This
83     // appears to be what clang migrated towards as well:
84     //
85     // http://lists.cs.uiuc.edu/pipermail/cfe-commits/Week-of-Mon-20110725/044411.html
86     unsafe { intrinsics::pref_align_of::<T>() }
87 }
88
89 /// Returns the alignment of the type of the value that `_val` points to.
90 ///
91 /// This is similar to `align_of`, but function will properly handle types such
92 /// as trait objects (in the future), returning the alignment for an arbitrary
93 /// value at runtime.
94 #[inline]
95 #[stable]
96 pub fn align_of_val<T>(_val: &T) -> uint {
97     align_of::<T>()
98 }
99
100 /// Deprecated, this function has been renamed to align_of
101 #[inline]
102 #[deprecated = "use mem::align_of instead"]
103 pub fn pref_align_of<T>() -> uint { align_of::<T>() }
104
105 /// Deprecated, this function has been renamed to align_of_val
106 #[inline]
107 #[deprecated = "use mem::align_of_val instead"]
108 pub fn pref_align_of_val<T>(val: &T) -> uint { align_of_val(val) }
109
110 /// Create a value initialized to zero.
111 ///
112 /// This function is similar to allocating space for a a local variable and
113 /// zeroing it out (an unsafe operation).
114 ///
115 /// Care must be taken when using this function, if the type `T` has a
116 /// destructor and the value falls out of scope (due to unwinding or returning)
117 /// before being initialized, then the destructor will run on zeroed
118 /// data, likely leading to crashes.
119 ///
120 /// This is useful for FFI functions sometimes, but should generally be avoided.
121 #[inline]
122 #[stable]
123 pub unsafe fn zeroed<T>() -> T {
124     intrinsics::init()
125 }
126
127 /// Deprecated, use zeroed() instead
128 #[inline]
129 #[deprecated = "this function has been renamed to zeroed()"]
130 pub unsafe fn init<T>() -> T { zeroed() }
131
132 /// Create an uninitialized value.
133 ///
134 /// Care must be taken when using this function, if the type `T` has a
135 /// destructor and the value falls out of scope (due to unwinding or returning)
136 /// before being initialized, then the destructor will run on uninitialized
137 /// data, likely leading to crashes.
138 ///
139 /// This is useful for FFI functions sometimes, but should generally be avoided.
140 #[inline]
141 #[stable]
142 pub unsafe fn uninitialized<T>() -> T {
143     intrinsics::uninit()
144 }
145
146 /// Deprecated, use `uninitialized` instead.
147 #[inline]
148 #[deprecated = "this function has been renamed to `uninitialized`"]
149 pub unsafe fn uninit<T>() -> T {
150     intrinsics::uninit()
151 }
152
153 /// Unsafely overwrite a memory location with the given value without destroying
154 /// the old value.
155 ///
156 /// This operation is unsafe because it does not destroy the previous value
157 /// contained at the location `dst`. This could leak allocations or resources,
158 /// so care must be taken to previously deallocate the value at `dst`.
159 #[inline]
160 #[deprecated = "use ptr::write"]
161 pub unsafe fn overwrite<T>(dst: *mut T, src: T) {
162     intrinsics::move_val_init(&mut *dst, src)
163 }
164
165 /// Deprecated, use `overwrite` instead
166 #[inline]
167 #[deprecated = "use ptr::write"]
168 pub unsafe fn move_val_init<T>(dst: &mut T, src: T) {
169     ptr::write(dst, src)
170 }
171
172 /// Convert an u16 to little endian from the target's endianness.
173 ///
174 /// On little endian, this is a no-op.  On big endian, the bytes are swapped.
175 #[inline]
176 #[deprecated = "use `Int::to_little_endian` instead"]
177 pub fn to_le16(x: u16) -> u16 { x.to_little_endian() }
178
179 /// Convert an u32 to little endian from the target's endianness.
180 ///
181 /// On little endian, this is a no-op.  On big endian, the bytes are swapped.
182 #[inline]
183 #[deprecated = "use `Int::to_little_endian` instead"]
184 pub fn to_le32(x: u32) -> u32 { x.to_little_endian() }
185
186 /// Convert an u64 to little endian from the target's endianness.
187 ///
188 /// On little endian, this is a no-op.  On big endian, the bytes are swapped.
189 #[inline]
190 #[deprecated = "use `Int::to_little_endian` instead"]
191 pub fn to_le64(x: u64) -> u64 { x.to_little_endian() }
192
193 /// Convert an u16 to big endian from the target's endianness.
194 ///
195 /// On big endian, this is a no-op.  On little endian, the bytes are swapped.
196 #[inline]
197 #[deprecated = "use `Int::to_big_endian` instead"]
198 pub fn to_be16(x: u16) -> u16 { x.to_big_endian() }
199
200 /// Convert an u32 to big endian from the target's endianness.
201 ///
202 /// On big endian, this is a no-op.  On little endian, the bytes are swapped.
203 #[inline]
204 #[deprecated = "use `Int::to_big_endian` instead"]
205 pub fn to_be32(x: u32) -> u32 { x.to_big_endian() }
206
207 /// Convert an u64 to big endian from the target's endianness.
208 ///
209 /// On big endian, this is a no-op.  On little endian, the bytes are swapped.
210 #[inline]
211 #[deprecated = "use `Int::to_big_endian` instead"]
212 pub fn to_be64(x: u64) -> u64 { x.to_big_endian() }
213
214 /// Convert an u16 from little endian to the target's endianness.
215 ///
216 /// On little endian, this is a no-op.  On big endian, the bytes are swapped.
217 #[inline]
218 #[deprecated = "use `Int::from_little_endian` instead"]
219 pub fn from_le16(x: u16) -> u16 { Int::from_little_endian(x) }
220
221 /// Convert an u32 from little endian to the target's endianness.
222 ///
223 /// On little endian, this is a no-op.  On big endian, the bytes are swapped.
224 #[inline]
225 #[deprecated = "use `Int::from_little_endian` instead"]
226 pub fn from_le32(x: u32) -> u32 { Int::from_little_endian(x) }
227
228 /// Convert an u64 from little endian to the target's endianness.
229 ///
230 /// On little endian, this is a no-op.  On big endian, the bytes are swapped.
231 #[inline]
232 #[deprecated = "use `Int::from_little_endian` instead"]
233 pub fn from_le64(x: u64) -> u64 { Int::from_little_endian(x) }
234
235 /// Convert an u16 from big endian to the target's endianness.
236 ///
237 /// On big endian, this is a no-op.  On little endian, the bytes are swapped.
238 #[inline]
239 #[deprecated = "use `Int::from_big_endian` instead"]
240 pub fn from_be16(x: u16) -> u16 { Int::from_big_endian(x) }
241
242 /// Convert an u32 from big endian to the target's endianness.
243 ///
244 /// On big endian, this is a no-op.  On little endian, the bytes are swapped.
245 #[inline]
246 #[deprecated = "use `Int::from_big_endian` instead"]
247 pub fn from_be32(x: u32) -> u32 { Int::from_big_endian(x) }
248
249 /// Convert an u64 from big endian to the target's endianness.
250 ///
251 /// On big endian, this is a no-op.  On little endian, the bytes are swapped.
252 #[inline]
253 #[deprecated = "use `Int::from_big_endian` instead"]
254 pub fn from_be64(x: u64) -> u64 { Int::from_big_endian(x) }
255
256 /// Swap the values at two mutable locations of the same type, without
257 /// deinitialising or copying either one.
258 #[inline]
259 #[stable]
260 pub fn swap<T>(x: &mut T, y: &mut T) {
261     unsafe {
262         // Give ourselves some scratch space to work with
263         let mut t: T = uninitialized();
264
265         // Perform the swap, `&mut` pointers never alias
266         ptr::copy_nonoverlapping_memory(&mut t, &*x, 1);
267         ptr::copy_nonoverlapping_memory(x, &*y, 1);
268         ptr::copy_nonoverlapping_memory(y, &t, 1);
269
270         // y and t now point to the same thing, but we need to completely forget `t`
271         // because it's no longer relevant.
272         forget(t);
273     }
274 }
275
276 /// Replace the value at a mutable location with a new one, returning the old
277 /// value, without deinitialising or copying either one.
278 ///
279 /// This is primarily used for transferring and swapping ownership of a value
280 /// in a mutable location. For example, this function allows consumption of
281 /// one field of a struct by replacing it with another value. The normal approach
282 /// doesn't always work:
283 ///
284 /// ```rust,ignore
285 /// struct Buffer<T> { buf: Vec<T> }
286 ///
287 /// impl<T> Buffer<T> {
288 ///     fn get_and_reset(&mut self) -> Vec<T> {
289 ///         // error: cannot move out of dereference of `&mut`-pointer
290 ///         let buf = self.buf;
291 ///         self.buf = Vec::new();
292 ///         buf
293 ///     }
294 /// }
295 /// ```
296 ///
297 /// Note that `T` does not necessarily implement `Clone`, so it can't even
298 /// clone and reset `self.buf`. But `replace` can be used to disassociate
299 /// the original value of `self.buf` from `self`, allowing it to be returned:
300 ///
301 /// ```rust
302 /// # struct Buffer<T> { buf: Vec<T> }
303 /// impl<T> Buffer<T> {
304 ///     fn get_and_reset(&mut self) -> Vec<T> {
305 ///         use std::mem::replace;
306 ///         replace(&mut self.buf, Vec::new())
307 ///     }
308 /// }
309 /// ```
310 #[inline]
311 #[stable]
312 pub fn replace<T>(dest: &mut T, mut src: T) -> T {
313     swap(dest, &mut src);
314     src
315 }
316
317 /// Disposes of a value.
318 ///
319 /// This function can be used to destroy any value by allowing `drop` to take
320 /// ownership of its argument.
321 ///
322 /// # Example
323 ///
324 /// ```
325 /// use std::cell::RefCell;
326 ///
327 /// let x = RefCell::new(1);
328 ///
329 /// let mut mutable_borrow = x.borrow_mut();
330 /// *mutable_borrow = 1;
331 /// drop(mutable_borrow); // relinquish the mutable borrow on this slot
332 ///
333 /// let borrow = x.borrow();
334 /// println!("{}", *borrow);
335 /// ```
336 #[inline]
337 #[stable]
338 pub fn drop<T>(_x: T) { }
339
340 /// Moves a thing into the void.
341 ///
342 /// The forget function will take ownership of the provided value but neglect
343 /// to run any required cleanup or memory management operations on it.
344 ///
345 /// This function is the unsafe version of the `drop` function because it does
346 /// not run any destructors.
347 #[inline]
348 #[stable]
349 pub unsafe fn forget<T>(thing: T) { intrinsics::forget(thing) }
350
351 /// Interprets `src` as `&U`, and then reads `src` without moving the contained
352 /// value.
353 ///
354 /// This function will unsafely assume the pointer `src` is valid for
355 /// `sizeof(U)` bytes by transmuting `&T` to `&U` and then reading the `&U`. It
356 /// will also unsafely create a copy of the contained value instead of moving
357 /// out of `src`.
358 ///
359 /// It is not a compile-time error if `T` and `U` have different sizes, but it
360 /// is highly encouraged to only invoke this function where `T` and `U` have the
361 /// same size. This function triggers undefined behavior if `U` is larger than
362 /// `T`.
363 #[inline]
364 #[stable]
365 pub unsafe fn transmute_copy<T, U>(src: &T) -> U {
366     ptr::read(src as *T as *U)
367 }
368
369 /// Transforms lifetime of the second pointer to match the first.
370 #[inline]
371 #[unstable = "this function may be removed in the future due to its \
372               questionable utility"]
373 pub unsafe fn copy_lifetime<'a, S, T>(_ptr: &'a S, ptr: &T) -> &'a T {
374     transmute(ptr)
375 }
376
377 /// Transforms lifetime of the second mutable pointer to match the first.
378 #[inline]
379 #[unstable = "this function may be removed in the future due to its \
380               questionable utility"]
381 pub unsafe fn copy_mut_lifetime<'a, S, T>(_ptr: &'a mut S,
382                                           ptr: &mut T) -> &'a mut T {
383     transmute(ptr)
384 }
385
386 #[cfg(test)]
387 mod tests {
388     use mem::*;
389     use option::{Some,None};
390     use realstd::str::StrAllocating;
391     use realstd::owned::Box;
392     use realstd::vec::Vec;
393     use raw;
394
395     #[test]
396     fn size_of_basic() {
397         assert_eq!(size_of::<u8>(), 1u);
398         assert_eq!(size_of::<u16>(), 2u);
399         assert_eq!(size_of::<u32>(), 4u);
400         assert_eq!(size_of::<u64>(), 8u);
401     }
402
403     #[test]
404     #[cfg(target_arch = "x86")]
405     #[cfg(target_arch = "arm")]
406     #[cfg(target_arch = "mips")]
407     fn size_of_32() {
408         assert_eq!(size_of::<uint>(), 4u);
409         assert_eq!(size_of::<*uint>(), 4u);
410     }
411
412     #[test]
413     #[cfg(target_arch = "x86_64")]
414     fn size_of_64() {
415         assert_eq!(size_of::<uint>(), 8u);
416         assert_eq!(size_of::<*uint>(), 8u);
417     }
418
419     #[test]
420     fn size_of_val_basic() {
421         assert_eq!(size_of_val(&1u8), 1);
422         assert_eq!(size_of_val(&1u16), 2);
423         assert_eq!(size_of_val(&1u32), 4);
424         assert_eq!(size_of_val(&1u64), 8);
425     }
426
427     #[test]
428     fn align_of_basic() {
429         assert_eq!(align_of::<u8>(), 1u);
430         assert_eq!(align_of::<u16>(), 2u);
431         assert_eq!(align_of::<u32>(), 4u);
432     }
433
434     #[test]
435     #[cfg(target_arch = "x86")]
436     #[cfg(target_arch = "arm")]
437     #[cfg(target_arch = "mips")]
438     fn align_of_32() {
439         assert_eq!(align_of::<uint>(), 4u);
440         assert_eq!(align_of::<*uint>(), 4u);
441     }
442
443     #[test]
444     #[cfg(target_arch = "x86_64")]
445     fn align_of_64() {
446         assert_eq!(align_of::<uint>(), 8u);
447         assert_eq!(align_of::<*uint>(), 8u);
448     }
449
450     #[test]
451     fn align_of_val_basic() {
452         assert_eq!(align_of_val(&1u8), 1u);
453         assert_eq!(align_of_val(&1u16), 2u);
454         assert_eq!(align_of_val(&1u32), 4u);
455     }
456
457     #[test]
458     fn test_swap() {
459         let mut x = 31337;
460         let mut y = 42;
461         swap(&mut x, &mut y);
462         assert_eq!(x, 42);
463         assert_eq!(y, 31337);
464     }
465
466     #[test]
467     fn test_replace() {
468         let mut x = Some("test".to_string());
469         let y = replace(&mut x, None);
470         assert!(x.is_none());
471         assert!(y.is_some());
472     }
473
474     #[test]
475     fn test_transmute_copy() {
476         assert_eq!(1u, unsafe { ::mem::transmute_copy(&1) });
477     }
478
479     #[test]
480     fn test_transmute() {
481         trait Foo {}
482         impl Foo for int {}
483
484         let a = box 100 as Box<Foo>;
485         unsafe {
486             let x: raw::TraitObject = transmute(a);
487             assert!(*(x.data as *int) == 100);
488             let _x: Box<Foo> = transmute(x);
489         }
490
491         unsafe {
492             assert!(Vec::from_slice([76u8]) == transmute("L".to_string()));
493         }
494     }
495 }
496
497 // FIXME #13642 (these benchmarks should be in another place)
498 /// Completely miscellaneous language-construct benchmarks.
499 #[cfg(test)]
500 mod bench {
501     extern crate test;
502     use self::test::Bencher;
503     use option::{Some,None};
504
505     // Static/dynamic method dispatch
506
507     struct Struct {
508         field: int
509     }
510
511     trait Trait {
512         fn method(&self) -> int;
513     }
514
515     impl Trait for Struct {
516         fn method(&self) -> int {
517             self.field
518         }
519     }
520
521     #[bench]
522     fn trait_vtable_method_call(b: &mut Bencher) {
523         let s = Struct { field: 10 };
524         let t = &s as &Trait;
525         b.iter(|| {
526             t.method()
527         });
528     }
529
530     #[bench]
531     fn trait_static_method_call(b: &mut Bencher) {
532         let s = Struct { field: 10 };
533         b.iter(|| {
534             s.method()
535         });
536     }
537
538     // Overhead of various match forms
539
540     #[bench]
541     fn match_option_some(b: &mut Bencher) {
542         let x = Some(10);
543         b.iter(|| {
544             match x {
545                 Some(y) => y,
546                 None => 11
547             }
548         });
549     }
550
551     #[bench]
552     fn match_vec_pattern(b: &mut Bencher) {
553         let x = [1,2,3,4,5,6];
554         b.iter(|| {
555             match x {
556                 [1,2,3,..] => 10,
557                 _ => 11
558             }
559         });
560     }
561 }