2014-02-18 20:30:21 +00:00
|
|
|
// Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT
|
2013-10-16 18:34:01 -07:00
|
|
|
// file at the top-level directory of this distribution and at
|
|
|
|
// http://rust-lang.org/COPYRIGHT.
|
|
|
|
//
|
|
|
|
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
|
|
|
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
|
|
|
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
|
|
|
// option. This file may not be copied, modified, or distributed
|
|
|
|
// except according to those terms.
|
|
|
|
|
2014-02-09 00:23:04 -08:00
|
|
|
//! Basic functions for dealing with memory
|
|
|
|
//!
|
|
|
|
//! This module contains functions for querying the size and alignment of
|
|
|
|
//! types, initializing and manipulating memory.
|
2013-10-16 18:34:01 -07:00
|
|
|
|
2014-03-21 18:05:05 -07:00
|
|
|
#![allow(missing_doc)] // FIXME
|
2014-02-09 00:17:37 -08:00
|
|
|
|
2014-02-01 04:35:36 +08:00
|
|
|
use cast;
|
|
|
|
use ptr;
|
2014-02-15 23:49:08 -08:00
|
|
|
use intrinsics;
|
|
|
|
use intrinsics::{bswap16, bswap32, bswap64};
|
2013-10-16 18:34:01 -07:00
|
|
|
|
2014-02-18 20:30:21 +00:00
|
|
|
/// Returns the size of a type in bytes.
|
2013-10-16 18:34:01 -07:00
|
|
|
#[inline]
|
|
|
|
pub fn size_of<T>() -> uint {
|
|
|
|
unsafe { intrinsics::size_of::<T>() }
|
|
|
|
}
|
|
|
|
|
2014-02-18 20:30:21 +00:00
|
|
|
/// Returns the size of the type that `_val` points to in bytes.
|
2013-10-16 18:34:01 -07:00
|
|
|
#[inline]
|
|
|
|
pub fn size_of_val<T>(_val: &T) -> uint {
|
|
|
|
size_of::<T>()
|
|
|
|
}
|
|
|
|
|
2014-02-18 20:30:21 +00:00
|
|
|
/// Returns the size of a type in bytes, or 1 if the actual size is zero.
|
2013-10-21 21:41:32 +02:00
|
|
|
///
|
|
|
|
/// Useful for building structures containing variable-length arrays.
|
2013-10-16 18:34:01 -07:00
|
|
|
#[inline]
|
|
|
|
pub fn nonzero_size_of<T>() -> uint {
|
2014-04-16 10:53:09 +02:00
|
|
|
match size_of::<T>() {
|
|
|
|
0 => 1,
|
|
|
|
x => x
|
|
|
|
}
|
2013-10-16 18:34:01 -07:00
|
|
|
}
|
|
|
|
|
2014-02-18 20:30:21 +00:00
|
|
|
/// Returns the size in bytes of the type of the value that `_val` points to.
|
2013-10-16 18:34:01 -07:00
|
|
|
#[inline]
|
|
|
|
pub fn nonzero_size_of_val<T>(_val: &T) -> uint {
|
|
|
|
nonzero_size_of::<T>()
|
|
|
|
}
|
|
|
|
|
2013-10-21 21:41:32 +02:00
|
|
|
/// Returns the ABI-required minimum alignment of a type
|
|
|
|
///
|
|
|
|
/// This is the alignment used for struct fields. It may be smaller
|
|
|
|
/// than the preferred alignment.
|
2013-10-16 18:34:01 -07:00
|
|
|
#[inline]
|
|
|
|
pub fn min_align_of<T>() -> uint {
|
|
|
|
unsafe { intrinsics::min_align_of::<T>() }
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Returns the ABI-required minimum alignment of the type of the value that
|
|
|
|
/// `_val` points to
|
|
|
|
#[inline]
|
|
|
|
pub fn min_align_of_val<T>(_val: &T) -> uint {
|
|
|
|
min_align_of::<T>()
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Returns the preferred alignment of a type
|
|
|
|
#[inline]
|
|
|
|
pub fn pref_align_of<T>() -> uint {
|
|
|
|
unsafe { intrinsics::pref_align_of::<T>() }
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Returns the preferred alignment of the type of the value that
|
|
|
|
/// `_val` points to
|
|
|
|
#[inline]
|
|
|
|
pub fn pref_align_of_val<T>(_val: &T) -> uint {
|
|
|
|
pref_align_of::<T>()
|
|
|
|
}
|
|
|
|
|
2014-02-08 02:46:55 -08:00
|
|
|
/// Create a value initialized to zero.
|
|
|
|
///
|
|
|
|
/// `init` is unsafe because it returns a zeroed-out datum,
|
2014-03-27 00:01:11 +01:00
|
|
|
/// which is unsafe unless T is Copy.
|
2014-02-08 02:46:55 -08:00
|
|
|
#[inline]
|
|
|
|
pub unsafe fn init<T>() -> T {
|
|
|
|
intrinsics::init()
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Create an uninitialized value.
|
|
|
|
#[inline]
|
|
|
|
pub unsafe fn uninit<T>() -> T {
|
|
|
|
intrinsics::uninit()
|
|
|
|
}
|
|
|
|
|
2014-02-08 22:16:42 -08:00
|
|
|
/// Move a value to an uninitialized memory location.
|
|
|
|
///
|
|
|
|
/// Drop glue is not run on the destination.
|
|
|
|
#[inline]
|
|
|
|
pub unsafe fn move_val_init<T>(dst: &mut T, src: T) {
|
|
|
|
intrinsics::move_val_init(dst, src)
|
|
|
|
}
|
|
|
|
|
2014-04-14 20:04:14 +10:00
|
|
|
/// Convert an u16 to little endian from the target's endianness.
|
2014-03-16 15:31:47 -07:00
|
|
|
///
|
|
|
|
/// On little endian, this is a no-op. On big endian, the bytes are swapped.
|
2014-04-14 20:04:14 +10:00
|
|
|
#[cfg(target_endian = "little")] #[inline] pub fn to_le16(x: u16) -> u16 { x }
|
2014-03-16 15:31:47 -07:00
|
|
|
|
2014-04-14 20:04:14 +10:00
|
|
|
/// Convert an u16 to little endian from the target's endianness.
|
2014-03-16 15:31:47 -07:00
|
|
|
///
|
|
|
|
/// On little endian, this is a no-op. On big endian, the bytes are swapped.
|
2014-04-14 20:04:14 +10:00
|
|
|
#[cfg(target_endian = "big")] #[inline] pub fn to_le16(x: u16) -> u16 { unsafe { bswap16(x) } }
|
2014-03-16 15:31:47 -07:00
|
|
|
|
2014-04-14 20:04:14 +10:00
|
|
|
/// Convert an u32 to little endian from the target's endianness.
|
2014-03-16 15:31:47 -07:00
|
|
|
///
|
|
|
|
/// On little endian, this is a no-op. On big endian, the bytes are swapped.
|
2014-04-14 20:04:14 +10:00
|
|
|
#[cfg(target_endian = "little")] #[inline] pub fn to_le32(x: u32) -> u32 { x }
|
2014-03-16 15:31:47 -07:00
|
|
|
|
2014-04-14 20:04:14 +10:00
|
|
|
/// Convert an u32 to little endian from the target's endianness.
|
2014-03-16 15:31:47 -07:00
|
|
|
///
|
|
|
|
/// On little endian, this is a no-op. On big endian, the bytes are swapped.
|
2014-04-14 20:04:14 +10:00
|
|
|
#[cfg(target_endian = "big")] #[inline] pub fn to_le32(x: u32) -> u32 { unsafe { bswap32(x) } }
|
2014-03-16 15:31:47 -07:00
|
|
|
|
2014-04-14 20:04:14 +10:00
|
|
|
/// Convert an u64 to little endian from the target's endianness.
|
2014-03-16 15:31:47 -07:00
|
|
|
///
|
|
|
|
/// On little endian, this is a no-op. On big endian, the bytes are swapped.
|
2014-04-14 20:04:14 +10:00
|
|
|
#[cfg(target_endian = "little")] #[inline] pub fn to_le64(x: u64) -> u64 { x }
|
2014-03-16 15:31:47 -07:00
|
|
|
|
2014-04-14 20:04:14 +10:00
|
|
|
/// Convert an u64 to little endian from the target's endianness.
|
2014-03-16 15:31:47 -07:00
|
|
|
///
|
|
|
|
/// On little endian, this is a no-op. On big endian, the bytes are swapped.
|
2014-04-14 20:04:14 +10:00
|
|
|
#[cfg(target_endian = "big")] #[inline] pub fn to_le64(x: u64) -> u64 { unsafe { bswap64(x) } }
|
2014-02-09 00:17:37 -08:00
|
|
|
|
2014-03-16 15:31:47 -07:00
|
|
|
|
2014-04-14 20:04:14 +10:00
|
|
|
/// Convert an u16 to big endian from the target's endianness.
|
2014-03-16 15:31:47 -07:00
|
|
|
///
|
|
|
|
/// On big endian, this is a no-op. On little endian, the bytes are swapped.
|
2014-04-14 20:04:14 +10:00
|
|
|
#[cfg(target_endian = "little")] #[inline] pub fn to_be16(x: u16) -> u16 { unsafe { bswap16(x) } }
|
2014-03-16 15:31:47 -07:00
|
|
|
|
2014-04-14 20:04:14 +10:00
|
|
|
/// Convert an u16 to big endian from the target's endianness.
|
2014-03-16 15:31:47 -07:00
|
|
|
///
|
|
|
|
/// On big endian, this is a no-op. On little endian, the bytes are swapped.
|
2014-04-14 20:04:14 +10:00
|
|
|
#[cfg(target_endian = "big")] #[inline] pub fn to_be16(x: u16) -> u16 { x }
|
2014-03-16 15:31:47 -07:00
|
|
|
|
2014-04-14 20:04:14 +10:00
|
|
|
/// Convert an u32 to big endian from the target's endianness.
|
2014-03-16 15:31:47 -07:00
|
|
|
///
|
|
|
|
/// On big endian, this is a no-op. On little endian, the bytes are swapped.
|
2014-04-14 20:04:14 +10:00
|
|
|
#[cfg(target_endian = "little")] #[inline] pub fn to_be32(x: u32) -> u32 { unsafe { bswap32(x) } }
|
2014-03-16 15:31:47 -07:00
|
|
|
|
2014-04-14 20:04:14 +10:00
|
|
|
/// Convert an u32 to big endian from the target's endianness.
|
2014-03-16 15:31:47 -07:00
|
|
|
///
|
|
|
|
/// On big endian, this is a no-op. On little endian, the bytes are swapped.
|
2014-04-14 20:04:14 +10:00
|
|
|
#[cfg(target_endian = "big")] #[inline] pub fn to_be32(x: u32) -> u32 { x }
|
2014-03-16 15:31:47 -07:00
|
|
|
|
2014-04-14 20:04:14 +10:00
|
|
|
/// Convert an u64 to big endian from the target's endianness.
|
2014-03-16 15:31:47 -07:00
|
|
|
///
|
|
|
|
/// On big endian, this is a no-op. On little endian, the bytes are swapped.
|
2014-04-14 20:04:14 +10:00
|
|
|
#[cfg(target_endian = "little")] #[inline] pub fn to_be64(x: u64) -> u64 { unsafe { bswap64(x) } }
|
2014-03-16 15:31:47 -07:00
|
|
|
|
2014-04-14 20:04:14 +10:00
|
|
|
/// Convert an u64 to big endian from the target's endianness.
|
2014-03-16 15:31:47 -07:00
|
|
|
///
|
|
|
|
/// On big endian, this is a no-op. On little endian, the bytes are swapped.
|
2014-04-14 20:04:14 +10:00
|
|
|
#[cfg(target_endian = "big")] #[inline] pub fn to_be64(x: u64) -> u64 { x }
|
2014-02-09 00:17:37 -08:00
|
|
|
|
2014-03-16 15:31:47 -07:00
|
|
|
|
2014-04-14 20:04:14 +10:00
|
|
|
/// Convert an u16 from little endian to the target's endianness.
|
2014-03-16 15:31:47 -07:00
|
|
|
///
|
|
|
|
/// On little endian, this is a no-op. On big endian, the bytes are swapped.
|
2014-04-14 20:04:14 +10:00
|
|
|
#[cfg(target_endian = "little")] #[inline] pub fn from_le16(x: u16) -> u16 { x }
|
2014-03-16 15:31:47 -07:00
|
|
|
|
2014-04-14 20:04:14 +10:00
|
|
|
/// Convert an u16 from little endian to the target's endianness.
|
2014-03-16 15:31:47 -07:00
|
|
|
///
|
|
|
|
/// On little endian, this is a no-op. On big endian, the bytes are swapped.
|
2014-04-14 20:04:14 +10:00
|
|
|
#[cfg(target_endian = "big")] #[inline] pub fn from_le16(x: u16) -> u16 { unsafe { bswap16(x) } }
|
2014-03-16 15:31:47 -07:00
|
|
|
|
2014-04-14 20:04:14 +10:00
|
|
|
/// Convert an u32 from little endian to the target's endianness.
|
2014-03-16 15:31:47 -07:00
|
|
|
///
|
|
|
|
/// On little endian, this is a no-op. On big endian, the bytes are swapped.
|
2014-04-14 20:04:14 +10:00
|
|
|
#[cfg(target_endian = "little")] #[inline] pub fn from_le32(x: u32) -> u32 { x }
|
2014-03-16 15:31:47 -07:00
|
|
|
|
2014-04-14 20:04:14 +10:00
|
|
|
/// Convert an u32 from little endian to the target's endianness.
|
2014-03-16 15:31:47 -07:00
|
|
|
///
|
|
|
|
/// On little endian, this is a no-op. On big endian, the bytes are swapped.
|
2014-04-14 20:04:14 +10:00
|
|
|
#[cfg(target_endian = "big")] #[inline] pub fn from_le32(x: u32) -> u32 { unsafe { bswap32(x) } }
|
2014-03-16 15:31:47 -07:00
|
|
|
|
2014-04-14 20:04:14 +10:00
|
|
|
/// Convert an u64 from little endian to the target's endianness.
|
2014-03-16 15:31:47 -07:00
|
|
|
///
|
|
|
|
/// On little endian, this is a no-op. On big endian, the bytes are swapped.
|
2014-04-14 20:04:14 +10:00
|
|
|
#[cfg(target_endian = "little")] #[inline] pub fn from_le64(x: u64) -> u64 { x }
|
2014-03-16 15:31:47 -07:00
|
|
|
|
2014-04-14 20:04:14 +10:00
|
|
|
/// Convert an u64 from little endian to the target's endianness.
|
2014-03-16 15:31:47 -07:00
|
|
|
///
|
|
|
|
/// On little endian, this is a no-op. On big endian, the bytes are swapped.
|
2014-04-14 20:04:14 +10:00
|
|
|
#[cfg(target_endian = "big")] #[inline] pub fn from_le64(x: u64) -> u64 { unsafe { bswap64(x) } }
|
2014-02-09 00:17:37 -08:00
|
|
|
|
2014-03-16 15:31:47 -07:00
|
|
|
|
2014-04-14 20:04:14 +10:00
|
|
|
/// Convert an u16 from big endian to the target's endianness.
|
2014-03-16 15:31:47 -07:00
|
|
|
///
|
|
|
|
/// On big endian, this is a no-op. On little endian, the bytes are swapped.
|
2014-04-14 20:04:14 +10:00
|
|
|
#[cfg(target_endian = "little")] #[inline] pub fn from_be16(x: u16) -> u16 { unsafe { bswap16(x) } }
|
2014-03-16 15:31:47 -07:00
|
|
|
|
2014-04-14 20:04:14 +10:00
|
|
|
/// Convert an u16 from big endian to the target's endianness.
|
2014-03-16 15:31:47 -07:00
|
|
|
///
|
|
|
|
/// On big endian, this is a no-op. On little endian, the bytes are swapped.
|
2014-04-14 20:04:14 +10:00
|
|
|
#[cfg(target_endian = "big")] #[inline] pub fn from_be16(x: u16) -> u16 { x }
|
2014-03-16 15:31:47 -07:00
|
|
|
|
2014-04-14 20:04:14 +10:00
|
|
|
/// Convert an u32 from big endian to the target's endianness.
|
2014-03-16 15:31:47 -07:00
|
|
|
///
|
|
|
|
/// On big endian, this is a no-op. On little endian, the bytes are swapped.
|
2014-04-14 20:04:14 +10:00
|
|
|
#[cfg(target_endian = "little")] #[inline] pub fn from_be32(x: u32) -> u32 { unsafe { bswap32(x) } }
|
2014-03-16 15:31:47 -07:00
|
|
|
|
2014-04-14 20:04:14 +10:00
|
|
|
/// Convert an u32 from big endian to the target's endianness.
|
2014-03-16 15:31:47 -07:00
|
|
|
///
|
|
|
|
/// On big endian, this is a no-op. On little endian, the bytes are swapped.
|
2014-04-14 20:04:14 +10:00
|
|
|
#[cfg(target_endian = "big")] #[inline] pub fn from_be32(x: u32) -> u32 { x }
|
2014-03-16 15:31:47 -07:00
|
|
|
|
2014-04-14 20:04:14 +10:00
|
|
|
/// Convert an u64 from big endian to the target's endianness.
|
2014-03-16 15:31:47 -07:00
|
|
|
///
|
|
|
|
/// On big endian, this is a no-op. On little endian, the bytes are swapped.
|
2014-04-14 20:04:14 +10:00
|
|
|
#[cfg(target_endian = "little")] #[inline] pub fn from_be64(x: u64) -> u64 { unsafe { bswap64(x) } }
|
2014-03-16 15:31:47 -07:00
|
|
|
|
2014-04-14 20:04:14 +10:00
|
|
|
/// Convert an u64 from big endian to the target's endianness.
|
2014-03-16 15:31:47 -07:00
|
|
|
///
|
|
|
|
/// On big endian, this is a no-op. On little endian, the bytes are swapped.
|
2014-04-14 20:04:14 +10:00
|
|
|
#[cfg(target_endian = "big")] #[inline] pub fn from_be64(x: u64) -> u64 { x }
|
2014-02-09 00:17:37 -08:00
|
|
|
|
2014-02-01 04:35:36 +08:00
|
|
|
/**
|
|
|
|
* Swap the values at two mutable locations of the same type, without
|
|
|
|
* deinitialising or copying either one.
|
|
|
|
*/
|
|
|
|
#[inline]
|
|
|
|
pub fn swap<T>(x: &mut T, y: &mut T) {
|
|
|
|
unsafe {
|
|
|
|
// Give ourselves some scratch space to work with
|
|
|
|
let mut t: T = uninit();
|
|
|
|
|
|
|
|
// Perform the swap, `&mut` pointers never alias
|
|
|
|
ptr::copy_nonoverlapping_memory(&mut t, &*x, 1);
|
|
|
|
ptr::copy_nonoverlapping_memory(x, &*y, 1);
|
|
|
|
ptr::copy_nonoverlapping_memory(y, &t, 1);
|
|
|
|
|
2014-04-16 10:53:09 +02:00
|
|
|
// y and t now point to the same thing, but we need to completely forget `t`
|
2014-02-01 04:35:36 +08:00
|
|
|
// because it's no longer relevant.
|
|
|
|
cast::forget(t);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Replace the value at a mutable location with a new one, returning the old
|
|
|
|
* value, without deinitialising or copying either one.
|
|
|
|
*/
|
|
|
|
#[inline]
|
|
|
|
pub fn replace<T>(dest: &mut T, mut src: T) -> T {
|
|
|
|
swap(dest, &mut src);
|
|
|
|
src
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Disposes of a value.
|
|
|
|
#[inline]
|
|
|
|
pub fn drop<T>(_x: T) { }
|
|
|
|
|
2013-10-16 18:34:01 -07:00
|
|
|
#[cfg(test)]
|
|
|
|
mod tests {
|
|
|
|
use mem::*;
|
2014-02-01 04:35:36 +08:00
|
|
|
use option::{Some,None};
|
2014-04-15 18:17:48 -07:00
|
|
|
use str::StrSlice;
|
2013-10-16 18:34:01 -07:00
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn size_of_basic() {
|
|
|
|
assert_eq!(size_of::<u8>(), 1u);
|
|
|
|
assert_eq!(size_of::<u16>(), 2u);
|
|
|
|
assert_eq!(size_of::<u32>(), 4u);
|
|
|
|
assert_eq!(size_of::<u64>(), 8u);
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
#[cfg(target_arch = "x86")]
|
|
|
|
#[cfg(target_arch = "arm")]
|
|
|
|
#[cfg(target_arch = "mips")]
|
|
|
|
fn size_of_32() {
|
|
|
|
assert_eq!(size_of::<uint>(), 4u);
|
|
|
|
assert_eq!(size_of::<*uint>(), 4u);
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
#[cfg(target_arch = "x86_64")]
|
|
|
|
fn size_of_64() {
|
|
|
|
assert_eq!(size_of::<uint>(), 8u);
|
|
|
|
assert_eq!(size_of::<*uint>(), 8u);
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn size_of_val_basic() {
|
|
|
|
assert_eq!(size_of_val(&1u8), 1);
|
|
|
|
assert_eq!(size_of_val(&1u16), 2);
|
|
|
|
assert_eq!(size_of_val(&1u32), 4);
|
|
|
|
assert_eq!(size_of_val(&1u64), 8);
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn nonzero_size_of_basic() {
|
|
|
|
type Z = [i8, ..0];
|
|
|
|
assert_eq!(size_of::<Z>(), 0u);
|
|
|
|
assert_eq!(nonzero_size_of::<Z>(), 1u);
|
|
|
|
assert_eq!(nonzero_size_of::<uint>(), size_of::<uint>());
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn nonzero_size_of_val_basic() {
|
|
|
|
let z = [0u8, ..0];
|
|
|
|
assert_eq!(size_of_val(&z), 0u);
|
|
|
|
assert_eq!(nonzero_size_of_val(&z), 1u);
|
|
|
|
assert_eq!(nonzero_size_of_val(&1u), size_of_val(&1u));
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn align_of_basic() {
|
|
|
|
assert_eq!(pref_align_of::<u8>(), 1u);
|
|
|
|
assert_eq!(pref_align_of::<u16>(), 2u);
|
|
|
|
assert_eq!(pref_align_of::<u32>(), 4u);
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
#[cfg(target_arch = "x86")]
|
|
|
|
#[cfg(target_arch = "arm")]
|
|
|
|
#[cfg(target_arch = "mips")]
|
|
|
|
fn align_of_32() {
|
|
|
|
assert_eq!(pref_align_of::<uint>(), 4u);
|
|
|
|
assert_eq!(pref_align_of::<*uint>(), 4u);
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
#[cfg(target_arch = "x86_64")]
|
|
|
|
fn align_of_64() {
|
|
|
|
assert_eq!(pref_align_of::<uint>(), 8u);
|
|
|
|
assert_eq!(pref_align_of::<*uint>(), 8u);
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn align_of_val_basic() {
|
|
|
|
assert_eq!(pref_align_of_val(&1u8), 1u);
|
|
|
|
assert_eq!(pref_align_of_val(&1u16), 2u);
|
|
|
|
assert_eq!(pref_align_of_val(&1u32), 4u);
|
|
|
|
}
|
2014-02-01 04:35:36 +08:00
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_swap() {
|
|
|
|
let mut x = 31337;
|
|
|
|
let mut y = 42;
|
|
|
|
swap(&mut x, &mut y);
|
|
|
|
assert_eq!(x, 42);
|
|
|
|
assert_eq!(y, 31337);
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_replace() {
|
2014-04-15 18:17:48 -07:00
|
|
|
let mut x = Some("test".to_owned());
|
2014-02-01 04:35:36 +08:00
|
|
|
let y = replace(&mut x, None);
|
|
|
|
assert!(x.is_none());
|
|
|
|
assert!(y.is_some());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-04-16 10:53:09 +02:00
|
|
|
// FIXME #13642 (these benchmarks should be in another place)
|
2014-02-01 04:35:36 +08:00
|
|
|
/// Completely miscellaneous language-construct benchmarks.
|
|
|
|
#[cfg(test)]
|
|
|
|
mod bench {
|
2014-02-14 09:49:11 +08:00
|
|
|
extern crate test;
|
2014-04-01 09:16:35 +08:00
|
|
|
use self::test::Bencher;
|
2014-02-01 04:35:36 +08:00
|
|
|
use option::{Some,None};
|
|
|
|
|
|
|
|
// Static/dynamic method dispatch
|
|
|
|
|
|
|
|
struct Struct {
|
|
|
|
field: int
|
|
|
|
}
|
|
|
|
|
|
|
|
trait Trait {
|
|
|
|
fn method(&self) -> int;
|
|
|
|
}
|
|
|
|
|
|
|
|
impl Trait for Struct {
|
|
|
|
fn method(&self) -> int {
|
|
|
|
self.field
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[bench]
|
2014-04-01 09:16:35 +08:00
|
|
|
fn trait_vtable_method_call(b: &mut Bencher) {
|
2014-02-01 04:35:36 +08:00
|
|
|
let s = Struct { field: 10 };
|
|
|
|
let t = &s as &Trait;
|
2014-04-01 09:16:35 +08:00
|
|
|
b.iter(|| {
|
2014-02-12 23:39:21 +08:00
|
|
|
t.method()
|
2014-02-01 04:35:36 +08:00
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
#[bench]
|
2014-04-01 09:16:35 +08:00
|
|
|
fn trait_static_method_call(b: &mut Bencher) {
|
2014-02-01 04:35:36 +08:00
|
|
|
let s = Struct { field: 10 };
|
2014-04-01 09:16:35 +08:00
|
|
|
b.iter(|| {
|
2014-02-12 23:39:21 +08:00
|
|
|
s.method()
|
2014-02-01 04:35:36 +08:00
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
// Overhead of various match forms
|
|
|
|
|
|
|
|
#[bench]
|
2014-04-01 09:16:35 +08:00
|
|
|
fn match_option_some(b: &mut Bencher) {
|
2014-02-01 04:35:36 +08:00
|
|
|
let x = Some(10);
|
2014-04-01 09:16:35 +08:00
|
|
|
b.iter(|| {
|
2014-02-12 23:39:21 +08:00
|
|
|
match x {
|
2014-02-01 04:35:36 +08:00
|
|
|
Some(y) => y,
|
|
|
|
None => 11
|
2014-02-12 23:39:21 +08:00
|
|
|
}
|
2014-02-01 04:35:36 +08:00
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
#[bench]
|
2014-04-01 09:16:35 +08:00
|
|
|
fn match_vec_pattern(b: &mut Bencher) {
|
2014-02-01 04:35:36 +08:00
|
|
|
let x = [1,2,3,4,5,6];
|
2014-04-01 09:16:35 +08:00
|
|
|
b.iter(|| {
|
2014-02-12 23:39:21 +08:00
|
|
|
match x {
|
2014-02-01 04:35:36 +08:00
|
|
|
[1,2,3,..] => 10,
|
|
|
|
_ => 11
|
2014-02-12 23:39:21 +08:00
|
|
|
}
|
2014-02-01 04:35:36 +08:00
|
|
|
});
|
|
|
|
}
|
2013-10-16 18:34:01 -07:00
|
|
|
}
|