1 // Copyright 2012-2013 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 //! Miscellaneous helpers for common patterns.
16 use unstable::intrinsics;
18 /// The identity function.
20 pub fn id<T>(x: T) -> T { x }
24 pub fn ignore<T>(_x: T) { }
27 * Swap the values at two mutable locations of the same type, without
28 * deinitialising or copying either one.
31 pub fn swap<T>(x: &mut T, y: &mut T) {
33 // Give ourselves some scratch space to work with
34 let mut tmp: T = intrinsics::uninit();
35 let t: *mut T = &mut tmp;
37 // Perform the swap, `&mut` pointers never alias
38 let x_raw: *mut T = x;
39 let y_raw: *mut T = y;
40 ptr::copy_nonoverlapping_memory(t, x_raw, 1);
41 ptr::copy_nonoverlapping_memory(x, y_raw, 1);
42 ptr::copy_nonoverlapping_memory(y, t, 1);
44 // y and t now point to the same thing, but we need to completely forget `tmp`
45 // because it's no longer relevant.
51 * Replace the value at a mutable location with a new one, returning the old
52 * value, without deinitialising or copying either one.
55 pub fn replace<T>(dest: &mut T, mut src: T) -> T {
60 /// A non-copyable dummy type.
61 #[deriving(Eq, TotalEq, Ord, TotalOrd)]
62 #[unsafe_no_drop_flag]
63 pub struct NonCopyable;
66 // FIXME(#8233) should not be necessary
67 /// Create a new noncopyable token.
68 pub fn new() -> NonCopyable { NonCopyable }
71 impl Drop for NonCopyable {
72 fn drop(&mut self) { }
75 /// A type with no inhabitants
79 /// A utility function for ignoring this uninhabited type
80 pub fn uninhabited(self) -> ! {
82 // Nothing to match on
93 use option::{None, Some};
94 use either::{Either, Left, Right};
99 fn identity_crisis() {
100 // Writing a test for the identity function. How did it come to this?
101 let x = ~[(5, false)];
102 //FIXME #3387 assert!(x.eq(id(x.clone())));
104 assert!(x.eq(&id(y)));
111 swap(&mut x, &mut y);
113 assert_eq!(y, 31337);
118 let mut x = Some(NonCopyable);
119 let y = replace(&mut x, None);
120 assert!(x.is_none());
121 assert!(y.is_some());
125 fn test_uninhabited() {
126 let could_only_be_coin : Either <Void, ()> = Right (());
127 match could_only_be_coin {
128 Right (coin) => coin,
129 Left (is_void) => is_void.uninhabited ()
134 fn test_noncopyable() {
135 assert_eq!(size_of::<NonCopyable>(), 0);
137 // verify that `#[unsafe_no_drop_flag]` works as intended on a zero-size struct
139 static mut did_run: bool = false;
141 struct Foo { five: int }
145 assert_eq!(self.five, 5);
153 let _a = (NonCopyable, Foo { five: 5 }, NonCopyable);
156 unsafe { assert_eq!(did_run, true); }
160 /// Completely miscellaneous language-construct benchmarks.
164 use extra::test::BenchHarness;
165 use option::{Some,None};
167 // Static/dynamic method dispatch
174 fn method(&self) -> int;
177 impl Trait for Struct {
178 fn method(&self) -> int {
184 fn trait_vtable_method_call(bh: &mut BenchHarness) {
185 let s = Struct { field: 10 };
186 let t = &s as &Trait;
193 fn trait_static_method_call(bh: &mut BenchHarness) {
194 let s = Struct { field: 10 };
200 // Overhead of various match forms
203 fn match_option_some(bh: &mut BenchHarness) {
214 fn match_vec_pattern(bh: &mut BenchHarness) {
215 let x = [1,2,3,4,5,6];