]> git.lizzy.rs Git - rust.git/blob - src/liballoc/boxed.rs
rollup merge of #20070: aturon/stab-2-clone
[rust.git] / src / liballoc / boxed.rs
1 // Copyright 2012-2014 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 //! A unique pointer type.
12
13 use core::any::{Any, AnyRefExt};
14 use core::clone::Clone;
15 use core::cmp::{PartialEq, PartialOrd, Eq, Ord, Ordering};
16 use core::default::Default;
17 use core::fmt;
18 use core::hash::{mod, Hash};
19 use core::kinds::Sized;
20 use core::mem;
21 use core::option::Option;
22 use core::raw::TraitObject;
23 use core::result::Result;
24 use core::result::Result::{Ok, Err};
25 use core::ops::{Deref, DerefMut};
26
27 /// A value that represents the global exchange heap. This is the default
28 /// place that the `box` keyword allocates into when no place is supplied.
29 ///
30 /// The following two examples are equivalent:
31 ///
32 /// ```rust
33 /// use std::boxed::HEAP;
34 ///
35 /// # struct Bar;
36 /// # impl Bar { fn new(_a: int) { } }
37 /// let foo = box(HEAP) Bar::new(2);
38 /// let foo = box Bar::new(2);
39 /// ```
40 #[lang = "exchange_heap"]
41 #[experimental = "may be renamed; uncertain about custom allocator design"]
42 pub static HEAP: () = ();
43
44 /// A type that represents a uniquely-owned value.
45 #[lang = "owned_box"]
46 #[unstable = "custom allocators will add an additional type parameter (with default)"]
47 pub struct Box<T>(*mut T);
48
49 #[stable]
50 impl<T: Default> Default for Box<T> {
51     #[stable]
52     fn default() -> Box<T> { box Default::default() }
53 }
54
55 #[stable]
56 impl<T> Default for Box<[T]> {
57     #[stable]
58     fn default() -> Box<[T]> { box [] }
59 }
60
61 #[stable]
62 impl<T: Clone> Clone for Box<T> {
63     /// Returns a copy of the owned box.
64     #[inline]
65     fn clone(&self) -> Box<T> { box {(**self).clone()} }
66
67     /// Performs copy-assignment from `source` by reusing the existing allocation.
68     #[inline]
69     fn clone_from(&mut self, source: &Box<T>) {
70         (**self).clone_from(&(**source));
71     }
72 }
73
74 impl<Sized? T: PartialEq> PartialEq for Box<T> {
75     #[inline]
76     fn eq(&self, other: &Box<T>) -> bool { PartialEq::eq(&**self, &**other) }
77     #[inline]
78     fn ne(&self, other: &Box<T>) -> bool { PartialEq::ne(&**self, &**other) }
79 }
80 impl<Sized? T: PartialOrd> PartialOrd for Box<T> {
81     #[inline]
82     fn partial_cmp(&self, other: &Box<T>) -> Option<Ordering> {
83         PartialOrd::partial_cmp(&**self, &**other)
84     }
85     #[inline]
86     fn lt(&self, other: &Box<T>) -> bool { PartialOrd::lt(&**self, &**other) }
87     #[inline]
88     fn le(&self, other: &Box<T>) -> bool { PartialOrd::le(&**self, &**other) }
89     #[inline]
90     fn ge(&self, other: &Box<T>) -> bool { PartialOrd::ge(&**self, &**other) }
91     #[inline]
92     fn gt(&self, other: &Box<T>) -> bool { PartialOrd::gt(&**self, &**other) }
93 }
94 impl<Sized? T: Ord> Ord for Box<T> {
95     #[inline]
96     fn cmp(&self, other: &Box<T>) -> Ordering {
97         Ord::cmp(&**self, &**other)
98     }
99 }
100 impl<Sized? T: Eq> Eq for Box<T> {}
101
102 impl<S: hash::Writer, Sized? T: Hash<S>> Hash<S> for Box<T> {
103     #[inline]
104     fn hash(&self, state: &mut S) {
105         (**self).hash(state);
106     }
107 }
108
109
110 /// Extension methods for an owning `Any` trait object.
111 #[unstable = "post-DST and coherence changes, this will not be a trait but \
112               rather a direct `impl` on `Box<Any>`"]
113 pub trait BoxAny {
114     /// Returns the boxed value if it is of type `T`, or
115     /// `Err(Self)` if it isn't.
116     #[unstable = "naming conventions around accessing innards may change"]
117     fn downcast<T: 'static>(self) -> Result<Box<T>, Self>;
118 }
119
120 #[stable]
121 impl BoxAny for Box<Any> {
122     #[inline]
123     fn downcast<T: 'static>(self) -> Result<Box<T>, Box<Any>> {
124         if self.is::<T>() {
125             unsafe {
126                 // Get the raw representation of the trait object
127                 let to: TraitObject =
128                     mem::transmute::<Box<Any>, TraitObject>(self);
129
130                 // Extract the data pointer
131                 Ok(mem::transmute(to.data))
132             }
133         } else {
134             Err(self)
135         }
136     }
137 }
138
139 impl<Sized? T: fmt::Show> fmt::Show for Box<T> {
140     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
141         (**self).fmt(f)
142     }
143 }
144
145 impl fmt::Show for Box<Any+'static> {
146     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
147         f.pad("Box<Any>")
148     }
149 }
150
151 impl<Sized? T> Deref<T> for Box<T> {
152     fn deref(&self) -> &T { &**self }
153 }
154
155 impl<Sized? T> DerefMut<T> for Box<T> {
156     fn deref_mut(&mut self) -> &mut T { &mut **self }
157 }
158
159 #[cfg(test)]
160 mod test {
161     #[test]
162     fn test_owned_clone() {
163         let a = box 5i;
164         let b: Box<int> = a.clone();
165         assert!(a == b);
166     }
167
168     #[test]
169     fn any_move() {
170         let a = box 8u as Box<Any>;
171         let b = box Test as Box<Any>;
172
173         match a.downcast::<uint>() {
174             Ok(a) => { assert!(a == box 8u); }
175             Err(..) => panic!()
176         }
177         match b.downcast::<Test>() {
178             Ok(a) => { assert!(a == box Test); }
179             Err(..) => panic!()
180         }
181
182         let a = box 8u as Box<Any>;
183         let b = box Test as Box<Any>;
184
185         assert!(a.downcast::<Box<Test>>().is_err());
186         assert!(b.downcast::<Box<uint>>().is_err());
187     }
188
189     #[test]
190     fn test_show() {
191         let a = box 8u as Box<Any>;
192         let b = box Test as Box<Any>;
193         let a_str = a.to_str();
194         let b_str = b.to_str();
195         assert_eq!(a_str, "Box<Any>");
196         assert_eq!(b_str, "Box<Any>");
197
198         let a = &8u as &Any;
199         let b = &Test as &Any;
200         let s = format!("{}", a);
201         assert_eq!(s, "&Any");
202         let s = format!("{}", b);
203         assert_eq!(s, "&Any");
204     }
205
206     #[test]
207     fn deref() {
208         fn homura<T: Deref<i32>>(_: T) { }
209         homura(box 765i32);
210     }
211 }