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.
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.
11 //! Basic functions for dealing with memory
13 //! This module contains functions for querying the size and alignment of
14 //! types, initializing and manipulating memory.
20 pub use intrinsics::transmute;
22 /// Returns the size of a type in bytes.
25 pub fn size_of<T>() -> uint {
26 unsafe { intrinsics::size_of::<T>() }
29 /// Returns the size of the type that `_val` points to in bytes.
32 pub fn size_of_val<T>(_val: &T) -> uint {
36 /// Deprecated, this function will be removed soon
38 #[deprecated = "this function will be removed soon"]
39 pub fn nonzero_size_of<T>() -> uint {
40 match size_of::<T>() {
46 /// Deprecated, this function will be removed soon
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) {
56 /// Returns the ABI-required minimum alignment of a type
58 /// This is the alignment used for struct fields. It may be smaller
59 /// than the preferred alignment.
62 pub fn min_align_of<T>() -> uint {
63 unsafe { intrinsics::min_align_of::<T>() }
66 /// Returns the ABI-required minimum alignment of the type of the value that
70 pub fn min_align_of_val<T>(_val: &T) -> uint {
74 /// Returns the alignment in memory for a type.
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.
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:
85 // http://lists.cs.uiuc.edu/pipermail/cfe-commits/Week-of-Mon-20110725/044411.html
86 unsafe { intrinsics::pref_align_of::<T>() }
89 /// Returns the alignment of the type of the value that `_val` points to.
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
96 pub fn align_of_val<T>(_val: &T) -> uint {
100 /// Deprecated, this function has been renamed to align_of
102 #[deprecated = "use mem::align_of instead"]
103 pub fn pref_align_of<T>() -> uint { align_of::<T>() }
105 /// Deprecated, this function has been renamed to align_of_val
107 #[deprecated = "use mem::align_of_val instead"]
108 pub fn pref_align_of_val<T>(val: &T) -> uint { align_of_val(val) }
110 /// Create a value initialized to zero.
112 /// This function is similar to allocating space for a a local variable and
113 /// zeroing it out (an unsafe operation).
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.
120 /// This is useful for FFI functions sometimes, but should generally be avoided.
123 pub unsafe fn zeroed<T>() -> T {
127 /// Deprecated, use zeroed() instead
129 #[deprecated = "this function has been renamed to zeroed()"]
130 pub unsafe fn init<T>() -> T { zeroed() }
132 /// Create an uninitialized value.
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.
139 /// This is useful for FFI functions sometimes, but should generally be avoided.
142 pub unsafe fn uninitialized<T>() -> T {
146 /// Deprecated, use `uninitialized` instead.
148 #[deprecated = "this function has been renamed to `uninitialized`"]
149 pub unsafe fn uninit<T>() -> T {
153 /// Unsafely overwrite a memory location with the given value without destroying
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`.
160 #[deprecated = "use ptr::write"]
161 pub unsafe fn overwrite<T>(dst: *mut T, src: T) {
162 intrinsics::move_val_init(&mut *dst, src)
165 /// Deprecated, use `overwrite` instead
167 #[deprecated = "use ptr::write"]
168 pub unsafe fn move_val_init<T>(dst: &mut T, src: T) {
172 /// Convert an u16 to little endian from the target's endianness.
174 /// On little endian, this is a no-op. On big endian, the bytes are swapped.
176 #[deprecated = "use `Int::to_le` instead"]
177 pub fn to_le16(x: u16) -> u16 { x.to_le() }
179 /// Convert an u32 to little endian from the target's endianness.
181 /// On little endian, this is a no-op. On big endian, the bytes are swapped.
183 #[deprecated = "use `Int::to_le` instead"]
184 pub fn to_le32(x: u32) -> u32 { x.to_le() }
186 /// Convert an u64 to little endian from the target's endianness.
188 /// On little endian, this is a no-op. On big endian, the bytes are swapped.
190 #[deprecated = "use `Int::to_le` instead"]
191 pub fn to_le64(x: u64) -> u64 { x.to_le() }
193 /// Convert an u16 to big endian from the target's endianness.
195 /// On big endian, this is a no-op. On little endian, the bytes are swapped.
197 #[deprecated = "use `Int::to_be` instead"]
198 pub fn to_be16(x: u16) -> u16 { x.to_be() }
200 /// Convert an u32 to big endian from the target's endianness.
202 /// On big endian, this is a no-op. On little endian, the bytes are swapped.
204 #[deprecated = "use `Int::to_be` instead"]
205 pub fn to_be32(x: u32) -> u32 { x.to_be() }
207 /// Convert an u64 to big endian from the target's endianness.
209 /// On big endian, this is a no-op. On little endian, the bytes are swapped.
211 #[deprecated = "use `Int::to_be` instead"]
212 pub fn to_be64(x: u64) -> u64 { x.to_be() }
214 /// Convert an u16 from little endian to the target's endianness.
216 /// On little endian, this is a no-op. On big endian, the bytes are swapped.
218 #[deprecated = "use `Int::from_le` instead"]
219 pub fn from_le16(x: u16) -> u16 { Int::from_le(x) }
221 /// Convert an u32 from little endian to the target's endianness.
223 /// On little endian, this is a no-op. On big endian, the bytes are swapped.
225 #[deprecated = "use `Int::from_le` instead"]
226 pub fn from_le32(x: u32) -> u32 { Int::from_le(x) }
228 /// Convert an u64 from little endian to the target's endianness.
230 /// On little endian, this is a no-op. On big endian, the bytes are swapped.
232 #[deprecated = "use `Int::from_le` instead"]
233 pub fn from_le64(x: u64) -> u64 { Int::from_le(x) }
235 /// Convert an u16 from big endian to the target's endianness.
237 /// On big endian, this is a no-op. On little endian, the bytes are swapped.
239 #[deprecated = "use `Int::from_be` instead"]
240 pub fn from_be16(x: u16) -> u16 { Int::from_be(x) }
242 /// Convert an u32 from big endian to the target's endianness.
244 /// On big endian, this is a no-op. On little endian, the bytes are swapped.
246 #[deprecated = "use `Int::from_be` instead"]
247 pub fn from_be32(x: u32) -> u32 { Int::from_be(x) }
249 /// Convert an u64 from big endian to the target's endianness.
251 /// On big endian, this is a no-op. On little endian, the bytes are swapped.
253 #[deprecated = "use `Int::from_be` instead"]
254 pub fn from_be64(x: u64) -> u64 { Int::from_be(x) }
256 /// Swap the values at two mutable locations of the same type, without
257 /// deinitialising or copying either one.
260 pub fn swap<T>(x: &mut T, y: &mut T) {
262 // Give ourselves some scratch space to work with
263 let mut t: T = uninitialized();
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);
270 // y and t now point to the same thing, but we need to completely forget `t`
271 // because it's no longer relevant.
276 /// Replace the value at a mutable location with a new one, returning the old
277 /// value, without deinitialising or copying either one.
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:
285 /// struct Buffer<T> { buf: Vec<T> }
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();
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:
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())
312 pub fn replace<T>(dest: &mut T, mut src: T) -> T {
313 swap(dest, &mut src);
317 /// Disposes of a value.
319 /// This function can be used to destroy any value by allowing `drop` to take
320 /// ownership of its argument.
325 /// use std::cell::RefCell;
327 /// let x = RefCell::new(1);
329 /// let mut mutable_borrow = x.borrow_mut();
330 /// *mutable_borrow = 1;
331 /// drop(mutable_borrow); // relinquish the mutable borrow on this slot
333 /// let borrow = x.borrow();
334 /// println!("{}", *borrow);
338 pub fn drop<T>(_x: T) { }
340 /// Moves a thing into the void.
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.
345 /// This function is the unsafe version of the `drop` function because it does
346 /// not run any destructors.
349 pub unsafe fn forget<T>(thing: T) { intrinsics::forget(thing) }
351 /// Interprets `src` as `&U`, and then reads `src` without moving the contained
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
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
365 pub unsafe fn transmute_copy<T, U>(src: &T) -> U {
366 ptr::read(src as *T as *U)
369 /// Transforms lifetime of the second pointer to match the first.
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 {
377 /// Transforms lifetime of the second mutable pointer to match the first.
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 {
389 use option::{Some,None};
390 use realstd::str::StrAllocating;
391 use realstd::owned::Box;
392 use realstd::vec::Vec;
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);
404 #[cfg(target_arch = "x86")]
405 #[cfg(target_arch = "arm")]
406 #[cfg(target_arch = "mips")]
407 #[cfg(target_arch = "mipsel")]
409 assert_eq!(size_of::<uint>(), 4u);
410 assert_eq!(size_of::<*uint>(), 4u);
414 #[cfg(target_arch = "x86_64")]
416 assert_eq!(size_of::<uint>(), 8u);
417 assert_eq!(size_of::<*uint>(), 8u);
421 fn size_of_val_basic() {
422 assert_eq!(size_of_val(&1u8), 1);
423 assert_eq!(size_of_val(&1u16), 2);
424 assert_eq!(size_of_val(&1u32), 4);
425 assert_eq!(size_of_val(&1u64), 8);
429 fn align_of_basic() {
430 assert_eq!(align_of::<u8>(), 1u);
431 assert_eq!(align_of::<u16>(), 2u);
432 assert_eq!(align_of::<u32>(), 4u);
436 #[cfg(target_arch = "x86")]
437 #[cfg(target_arch = "arm")]
438 #[cfg(target_arch = "mips")]
439 #[cfg(target_arch = "mipsel")]
441 assert_eq!(align_of::<uint>(), 4u);
442 assert_eq!(align_of::<*uint>(), 4u);
446 #[cfg(target_arch = "x86_64")]
448 assert_eq!(align_of::<uint>(), 8u);
449 assert_eq!(align_of::<*uint>(), 8u);
453 fn align_of_val_basic() {
454 assert_eq!(align_of_val(&1u8), 1u);
455 assert_eq!(align_of_val(&1u16), 2u);
456 assert_eq!(align_of_val(&1u32), 4u);
463 swap(&mut x, &mut y);
465 assert_eq!(y, 31337);
470 let mut x = Some("test".to_string());
471 let y = replace(&mut x, None);
472 assert!(x.is_none());
473 assert!(y.is_some());
477 fn test_transmute_copy() {
478 assert_eq!(1u, unsafe { ::mem::transmute_copy(&1) });
482 fn test_transmute() {
486 let a = box 100 as Box<Foo>;
488 let x: raw::TraitObject = transmute(a);
489 assert!(*(x.data as *int) == 100);
490 let _x: Box<Foo> = transmute(x);
494 assert!(Vec::from_slice([76u8]) == transmute("L".to_string()));
499 // FIXME #13642 (these benchmarks should be in another place)
500 /// Completely miscellaneous language-construct benchmarks.
504 use self::test::Bencher;
505 use option::{Some,None};
507 // Static/dynamic method dispatch
514 fn method(&self) -> int;
517 impl Trait for Struct {
518 fn method(&self) -> int {
524 fn trait_vtable_method_call(b: &mut Bencher) {
525 let s = Struct { field: 10 };
526 let t = &s as &Trait;
533 fn trait_static_method_call(b: &mut Bencher) {
534 let s = Struct { field: 10 };
540 // Overhead of various match forms
543 fn match_option_some(b: &mut Bencher) {
554 fn match_vec_pattern(b: &mut Bencher) {
555 let x = [1,2,3,4,5,6];