(index<- )        ./libstd/util.rs

   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.
   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  //! Miscellaneous helpers for common patterns.
  12  
  13  use cast;
  14  use ptr;
  15  use prelude::*;
  16  use unstable::intrinsics;
  17  
  18  /// The identity function.
  19  #[inline]
  20  pub fn id<T>(xT) -> T { x }
  21  
  22  /// Ignores a value.
  23  #[inline]
  24  pub fn ignore<T>(_xT) { }
  25  
  26  /**
  27   * Swap the values at two mutable locations of the same type, without
  28   * deinitialising or copying either one.
  29   */
  30  #[inline]
  31  pub fn swap<T>(x&mut T, y&mut T) {
  32      unsafe {
  33          // Give ourselves some scratch space to work with
  34          let mut tmpT = intrinsics::uninit();
  35          let t*mut T = &mut tmp;
  36  
  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);
  43  
  44          // y and t now point to the same thing, but we need to completely forget `tmp`
  45          // because it's no longer relevant.
  46          cast::forget(tmp);
  47      }
  48  }
  49  
  50  /**
  51   * Replace the value at a mutable location with a new one, returning the old
  52   * value, without deinitialising or copying either one.
  53   */
  54  #[inline]
  55  pub fn replace<T>(dest&mut T, mut srcT) -> T {
  56      swap(dest, &mut src);
  57      src
  58  }
  59  
  60  /// A non-copyable dummy type.
  61  #[deriving(Eq, TotalEq, Ord, TotalOrd)]
  62  #[unsafe_no_drop_flag]
  63  pub struct NonCopyable;
  64  
  65  impl NonCopyable {
  66      // FIXME(#8233) should not be necessary
  67      /// Create a new noncopyable token.
  68      pub fn new() -> NonCopyable { NonCopyable }
  69  }
  70  
  71  impl Drop for NonCopyable {
  72      fn drop(&mut self) { }
  73  }
  74  
  75  /// A type with no inhabitants
  76  pub enum Void { }
  77  
  78  impl Void {
  79      /// A utility function for ignoring this uninhabited type
  80      pub fn uninhabited(self) -> ! {
  81          match self {
  82              // Nothing to match on
  83          }
  84      }
  85  }
  86  
  87  
  88  #[cfg(test)]
  89  mod tests {
  90      use super::*;
  91  
  92      use clone::Clone;
  93      use ops::Drop;
  94      use option::{None, Some};
  95      use either::{Either, Left, Right};
  96      use sys::size_of;
  97  
  98      #[test]
  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())));
 103          let y = x.clone();
 104          assert!(x.eq(&id(y)));
 105      }
 106  
 107      #[test]
 108      fn test_swap() {
 109          let mut x = 31337;
 110          let mut y = 42;
 111          swap(&mut x, &mut y);
 112          assert_eq!(x, 42);
 113          assert_eq!(y, 31337);
 114      }
 115  
 116      #[test]
 117      fn test_replace() {
 118          let mut x = Some(NonCopyable);
 119          let y = replace(&mut x, None);
 120          assert!(x.is_none());
 121          assert!(y.is_some());
 122      }
 123  
 124      #[test]
 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 ()
 130          }
 131      }
 132  
 133      #[test]
 134      fn test_noncopyable() {
 135          assert_eq!(size_of::<NonCopyable>(), 0);
 136  
 137          // verify that `#[unsafe_no_drop_flag]` works as intended on a zero-size struct
 138  
 139          static mut did_run: bool = false;
 140  
 141          struct Foo { five: int }
 142  
 143          impl Drop for Foo {
 144              fn drop(&mut self) {
 145                  assert_eq!(self.five, 5);
 146                  unsafe {
 147                      did_run = true;
 148                  }
 149              }
 150          }
 151  
 152          {
 153              let _a = (NonCopyable, Foo { five: 5 }, NonCopyable);
 154          }
 155  
 156          unsafe { assert_eq!(did_run, true); }
 157      }
 158  }
 159  
 160  /// Completely miscellaneous language-construct benchmarks.
 161  #[cfg(test)]
 162  mod bench {
 163  
 164      use extra::test::BenchHarness;
 165      use option::{Some,None};
 166  
 167      // Static/dynamic method dispatch
 168  
 169      struct Struct {
 170          field: int
 171      }
 172  
 173      trait Trait {
 174          fn method(&self) -> int;
 175      }
 176  
 177      impl Trait for Struct {
 178          fn method(&self) -> int {
 179              self.field
 180          }
 181      }
 182  
 183      #[bench]
 184      fn trait_vtable_method_call(bh: &mut BenchHarness) {
 185          let s = Struct { field: 10 };
 186          let t = &s as &Trait;
 187          do bh.iter {
 188              t.method();
 189          }
 190      }
 191  
 192      #[bench]
 193      fn trait_static_method_call(bh: &mut BenchHarness) {
 194          let s = Struct { field: 10 };
 195          do bh.iter {
 196              s.method();
 197          }
 198      }
 199  
 200      // Overhead of various match forms
 201  
 202      #[bench]
 203      fn match_option_some(bh: &mut BenchHarness) {
 204          let x = Some(10);
 205          do bh.iter {
 206              let _q = match x {
 207                  Some(y) => y,
 208                  None => 11
 209              };
 210          }
 211      }
 212  
 213      #[bench]
 214      fn match_vec_pattern(bh: &mut BenchHarness) {
 215          let x = [1,2,3,4,5,6];
 216          do bh.iter {
 217              let _q = match x {
 218                  [1,2,3,.._] => 10,
 219                  _ => 11
 220              };
 221          }
 222      }
 223  }

libstd/util.rs:62:23-62:23 -struct- definition:
#[unsafe_no_drop_flag]
pub struct NonCopyable;
references:-
61: #[deriving(Eq, TotalEq, Ord, TotalOrd)]
61: #[deriving(Eq, TotalEq, Ord, TotalOrd)]
61: #[deriving(Eq, TotalEq, Ord, TotalOrd)]
61: #[deriving(Eq, TotalEq, Ord, TotalOrd)]
71: impl Drop for NonCopyable {
61: #[deriving(Eq, TotalEq, Ord, TotalOrd)]
61: #[deriving(Eq, TotalEq, Ord, TotalOrd)]
68:     pub fn new() -> NonCopyable { NonCopyable }
61: #[deriving(Eq, TotalEq, Ord, TotalOrd)]
65: impl NonCopyable {
61: #[deriving(Eq, TotalEq, Ord, TotalOrd)]
61: #[deriving(Eq, TotalEq, Ord, TotalOrd)]
61: #[deriving(Eq, TotalEq, Ord, TotalOrd)]
61: #[deriving(Eq, TotalEq, Ord, TotalOrd)]
61: #[deriving(Eq, TotalEq, Ord, TotalOrd)]
libstd/task/mod.rs:
174:     can_not_copy: Option<util::NonCopyable>,


libstd/util.rs:54:10-54:10 -fn- definition:
#[inline]
pub fn replace<T>(dest: &mut T, mut src: T) -> T {
references:-
libstd/rt/kill.rs:
531:                         Some(blk(util::replace(&mut inner.child_tombstones, None)));
libstd/rt/uv/process.rs:
65:         let io = util::replace(&mut config.io, ~[]);
libstd/rt/args.rs:
76:             let val = util::replace(&mut *ptr, None);
libstd/vec.rs:
1597:         let v = util::replace(self, ~[x]);
libstd/option.rs:
207:         util::replace(self, None)
libstd/hashmap.rs:
212:                         Some(replace(&mut b.value, v))
159:         let old_buckets = replace(&mut self.buckets,
libstd/trie.rs:
423:         match replace(child, Nothing) {
libstd/task/spawn.rs:
297:                     let rest = util::replace(&mut nobe.ancestors,
libstd/local_data.rs:
153:                 let data = match util::replace(entry, None) {


libstd/util.rs:19:10-19:10 -fn- definition:
#[inline]
pub fn id<T>(x: T) -> T { x }
references:-
libstd/rt/uv/net.rs:
96:     uv_socket_addr_as_socket_addr(addr, util::id)


libstd/util.rs:75:31-75:31 -enum- definition:
/// A type with no inhabitants
pub enum Void { }
references:-
78: impl Void {
libstd/rt/comm.rs:
68:         let packet: *mut Void = cast::transmute(packet);
51:     void_packet: *mut Void,
57:     void_packet: *mut Void,
libstd/fmt/mod.rs:
459:     priv value: &'self util::Void,
458:     priv formatter: extern "Rust" fn(&util::Void, &mut Formatter),
686:                 unsafe { Some(*(v as *util::Void as *uint)) }
682:                 unsafe { Some(*(v as *util::Void as *uint)) }


libstd/util.rs:23:10-23:10 -fn- definition:
#[inline]
pub fn ignore<T>(_x: T) { }
references:-
libstd/rt/kill.rs:
577:         { use util; util::ignore(group); }


libstd/util.rs:30:10-30:10 -fn- definition:
#[inline]
pub fn swap<T>(x: &mut T, y: &mut T) {
references:-
56:     swap(dest, &mut src);
libstd/vec.rs:
1841:                         util::swap(&mut *p_r, &mut *p_w);
1999:             util::swap(a, b);
libstd/ptr.rs:
190:     swap(cast::transmute(dest), &mut src); // cannot overlap
libstd/iter.rs:
703:                 (Some(x), Some(y)) => util::swap(x, y),
libstd/trie.rs:
386:     swap(&mut tmp, child);