(index<- )        ./libcore/clone.rs

    git branch:    * master           5200215 auto merge of #14035 : alexcrichton/rust/experimental, r=huonw
    modified:    Fri May  9 13:02:28 2014
   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  /*! The `Clone` trait for types that cannot be 'implicitly copied'
  12  
  13  In Rust, some simple types are "implicitly copyable" and when you
  14  assign them or pass them as arguments, the receiver will get a copy,
  15  leaving the original value in place. These types do not require
  16  allocation to copy and do not have finalizers (i.e. they do not
  17  contain owned boxes or implement `Drop`), so the compiler considers
  18  them cheap and safe to copy. For other types copies must be made
  19  explicitly, by convention implementing the `Clone` trait and calling
  20  the `clone` method.
  21  
  22  */
  23  
  24  use owned::Box;
  25  
  26  /// A common trait for cloning an object.
  27  pub trait Clone {
  28      /// Returns a copy of the value. The contents of owned pointers
  29      /// are copied to maintain uniqueness, while the contents of
  30      /// managed pointers are not copied.
  31      fn clone(&self) -> Self;
  32  
  33      /// Perform copy-assignment from `source`.
  34      ///
  35      /// `a.clone_from(&b)` is equivalent to `a = b.clone()` in functionality,
  36      /// but can be overridden to reuse the resources of `a` to avoid unnecessary
  37      /// allocations.
  38      #[inline(always)]
  39      fn clone_from(&mut self, source&Self) {
  40          *self = source.clone()
  41      }
  42  }
  43  
  44  impl<T: Clone> Clone for Box<T> {
  45      /// Return a copy of the owned box.
  46      #[inline]
  47      fn clone(&self) -> Box<T> { box {(**self).clone()} }
  48  
  49      /// Perform copy-assignment from `source` by reusing the existing allocation.
  50      #[inline]
  51      fn clone_from(&mut self, source&Box<T>) {
  52          (**self).clone_from(&(**source));
  53      }
  54  }
  55  
  56  impl<T> Clone for @T {
  57      /// Return a shallow copy of the managed box.
  58      #[inline]
  59      fn clone(&self) -> @T { *self }
  60  }
  61  
  62  impl<'a, T> Clone for &'a T {
  63      /// Return a shallow copy of the reference.
  64      #[inline]
  65      fn clone(&self) -> &'a T { *self }
  66  }
  67  
  68  impl<'a, T> Clone for &'a [T{
  69      /// Return a shallow copy of the slice.
  70      #[inline]
  71      fn clone(&self) -> &'a [T] { *self }
  72  }
  73  
  74  impl<'a> Clone for &'a str {
  75      /// Return a shallow copy of the slice.
  76      #[inline]
  77      fn clone(&self) -> &'a str { *self }
  78  }
  79  
  80  macro_rules! clone_impl(
  81      ($t:ty) => {
  82          impl Clone for $t {
  83              /// Return a deep copy of the value.
  84              #[inline]
  85              fn clone(&self) -> $t { *self }
  86          }
  87      }
  88  )
  89  
  90  clone_impl!(int)
  91  clone_impl!(i8)
  92  clone_impl!(i16)
  93  clone_impl!(i32)
  94  clone_impl!(i64)
  95  
  96  clone_impl!(uint)
  97  clone_impl!(u8)
  98  clone_impl!(u16)
  99  clone_impl!(u32)
 100  clone_impl!(u64)
 101  
 102  clone_impl!(f32)
 103  clone_impl!(f64)
 104  
 105  clone_impl!(())
 106  clone_impl!(bool)
 107  clone_impl!(char)
 108  
 109  macro_rules! extern_fn_clone(
 110      ($($A:ident),*) => (
 111          impl<$($A,)* ReturnType> Clone for extern "Rust" fn($($A),*) -> ReturnType {
 112              /// Return a copy of a function pointer
 113              #[inline]
 114              fn clone(&self) -> extern "Rust" fn($($A),*) -> ReturnType { *self }
 115          }
 116      )
 117  )
 118  
 119  extern_fn_clone!()
 120  extern_fn_clone!(A)
 121  extern_fn_clone!(A, B)
 122  extern_fn_clone!(A, B, C)
 123  extern_fn_clone!(A, B, C, D)
 124  extern_fn_clone!(A, B, C, D, E)
 125  extern_fn_clone!(A, B, C, D, E, F)
 126  extern_fn_clone!(A, B, C, D, E, F, G)
 127  extern_fn_clone!(A, B, C, D, E, F, G, H)
 128  
 129  #[cfg(test)]
 130  mod test {
 131      use prelude::*;
 132      use owned::Box;
 133  
 134      #[test]
 135      fn test_owned_clone() {
 136          let a = box 5i;
 137          let b: Box<int> = a.clone();
 138          assert_eq!(a, b);
 139      }
 140  
 141      #[test]
 142      fn test_managed_clone() {
 143          let a = @5i;
 144          let b: @int = a.clone();
 145          assert_eq!(a, b);
 146      }
 147  
 148      #[test]
 149      fn test_borrowed_clone() {
 150          let x = 5i;
 151          let y: &int = &x;
 152          let z: &int = (&y).clone();
 153          assert_eq!(*z, 5);
 154      }
 155  
 156      #[test]
 157      fn test_clone_from() {
 158          let a = box 5;
 159          let mut b = box 10;
 160          b.clone_from(&a);
 161          assert_eq!(*b, 5);
 162      }
 163  
 164      #[test]
 165      fn test_extern_fn_clone() {
 166          trait Empty {}
 167          impl Empty for int {}
 168  
 169          fn test_fn_a() -> f64 { 1.0 }
 170          fn test_fn_b<T: Empty>(x: T) -> T { x }
 171          fn test_fn_c(_: int, _: f64, _: ~[int], _: int, _: int, _: int) {}
 172  
 173          let _ = test_fn_a.clone();
 174          let _ = test_fn_b::<int>.clone();
 175          let _ = test_fn_c.clone();
 176      }
 177  }