(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 }