]> git.lizzy.rs Git - rust.git/blob - src/libcore/clone.rs
e6c462c62d2979fd98757d508783b70da07f3e60
[rust.git] / src / libcore / clone.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 /*! 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 /// A common trait for cloning an object.
25 pub trait Clone {
26     /// Returns a copy of the value. The contents of owned pointers
27     /// are copied to maintain uniqueness, while the contents of
28     /// managed pointers are not copied.
29     fn clone(&self) -> Self;
30
31     /// Perform copy-assignment from `source`.
32     ///
33     /// `a.clone_from(&b)` is equivalent to `a = b.clone()` in functionality,
34     /// but can be overridden to reuse the resources of `a` to avoid unnecessary
35     /// allocations.
36     #[inline(always)]
37     fn clone_from(&mut self, source: &Self) {
38         *self = source.clone()
39     }
40 }
41
42 impl<'a, T> Clone for &'a T {
43     /// Return a shallow copy of the reference.
44     #[inline]
45     fn clone(&self) -> &'a T { *self }
46 }
47
48 impl<'a, T> Clone for &'a [T] {
49     /// Return a shallow copy of the slice.
50     #[inline]
51     fn clone(&self) -> &'a [T] { *self }
52 }
53
54 impl<'a> Clone for &'a str {
55     /// Return a shallow copy of the slice.
56     #[inline]
57     fn clone(&self) -> &'a str { *self }
58 }
59
60 macro_rules! clone_impl(
61     ($t:ty) => {
62         impl Clone for $t {
63             /// Return a deep copy of the value.
64             #[inline]
65             fn clone(&self) -> $t { *self }
66         }
67     }
68 )
69
70 clone_impl!(int)
71 clone_impl!(i8)
72 clone_impl!(i16)
73 clone_impl!(i32)
74 clone_impl!(i64)
75
76 clone_impl!(uint)
77 clone_impl!(u8)
78 clone_impl!(u16)
79 clone_impl!(u32)
80 clone_impl!(u64)
81
82 clone_impl!(f32)
83 clone_impl!(f64)
84
85 clone_impl!(())
86 clone_impl!(bool)
87 clone_impl!(char)
88
89 macro_rules! extern_fn_clone(
90     ($($A:ident),*) => (
91         impl<$($A,)* ReturnType> Clone for extern "Rust" fn($($A),*) -> ReturnType {
92             /// Return a copy of a function pointer
93             #[inline]
94             fn clone(&self) -> extern "Rust" fn($($A),*) -> ReturnType { *self }
95         }
96     )
97 )
98
99 extern_fn_clone!()
100 extern_fn_clone!(A)
101 extern_fn_clone!(A, B)
102 extern_fn_clone!(A, B, C)
103 extern_fn_clone!(A, B, C, D)
104 extern_fn_clone!(A, B, C, D, E)
105 extern_fn_clone!(A, B, C, D, E, F)
106 extern_fn_clone!(A, B, C, D, E, F, G)
107 extern_fn_clone!(A, B, C, D, E, F, G, H)
108
109 #[cfg(test)]
110 mod test {
111     use prelude::*;
112     use realstd::owned::Box;
113     use realstd::gc::{Gc, GC};
114
115     fn realclone<T: ::realstd::clone::Clone>(t: &T) -> T {
116         use realstd::clone::Clone;
117         t.clone()
118     }
119
120     fn realclone_from<T: ::realstd::clone::Clone>(t1: &mut T, t2: &T) {
121         use realstd::clone::Clone;
122         t1.clone_from(t2)
123     }
124
125     #[test]
126     fn test_owned_clone() {
127         let a = box 5i;
128         let b: Box<int> = realclone(&a);
129         assert!(a == b);
130     }
131
132     #[test]
133     fn test_managed_clone() {
134         let a = box(GC) 5i;
135         let b: Gc<int> = realclone(&a);
136         assert!(a == b);
137     }
138
139     #[test]
140     fn test_borrowed_clone() {
141         let x = 5i;
142         let y: &int = &x;
143         let z: &int = (&y).clone();
144         assert_eq!(*z, 5);
145     }
146
147     #[test]
148     fn test_clone_from() {
149         let a = box 5;
150         let mut b = box 10;
151         realclone_from(&mut b, &a);
152         assert_eq!(*b, 5);
153     }
154
155     #[test]
156     fn test_extern_fn_clone() {
157         trait Empty {}
158         impl Empty for int {}
159
160         fn test_fn_a() -> f64 { 1.0 }
161         fn test_fn_b<T: Empty>(x: T) -> T { x }
162         fn test_fn_c(_: int, _: f64, _: int, _: int, _: int) {}
163
164         let _ = test_fn_a.clone();
165         let _ = test_fn_b::<int>.clone();
166         let _ = test_fn_c.clone();
167     }
168 }