]> git.lizzy.rs Git - rust.git/blob - src/liballoc/boxed.rs
Rollup merge of #21312 - michaelsproul:remove-error-send-bound, r=aturon
[rust.git] / src / liballoc / boxed.rs
1 // Copyright 2012-2015 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 #![stable]
14
15 use core::any::Any;
16 use core::clone::Clone;
17 use core::cmp::{PartialEq, PartialOrd, Eq, Ord, Ordering};
18 use core::default::Default;
19 use core::fmt;
20 use core::hash::{self, Hash};
21 use core::marker::Sized;
22 use core::mem;
23 use core::option::Option;
24 use core::ptr::Unique;
25 use core::raw::TraitObject;
26 use core::result::Result;
27 use core::result::Result::{Ok, Err};
28 use core::ops::{Deref, DerefMut};
29
30 /// A value that represents the global exchange heap. This is the default
31 /// place that the `box` keyword allocates into when no place is supplied.
32 ///
33 /// The following two examples are equivalent:
34 ///
35 /// ```rust
36 /// #![feature(box_syntax)]
37 /// use std::boxed::HEAP;
38 ///
39 /// fn main() {
40 /// # struct Bar;
41 /// # impl Bar { fn new(_a: int) { } }
42 ///     let foo = box(HEAP) Bar::new(2);
43 ///     let foo = box Bar::new(2);
44 /// }
45 /// ```
46 #[lang = "exchange_heap"]
47 #[unstable = "may be renamed; uncertain about custom allocator design"]
48 pub static HEAP: () = ();
49
50 /// A type that represents a uniquely-owned value.
51 #[lang = "owned_box"]
52 #[stable]
53 pub struct Box<T>(Unique<T>);
54
55 impl<T> Box<T> {
56     /// Moves `x` into a freshly allocated box on the global exchange heap.
57     #[stable]
58     pub fn new(x: T) -> Box<T> {
59         box x
60     }
61 }
62
63 #[stable]
64 impl<T: Default> Default for Box<T> {
65     #[stable]
66     fn default() -> Box<T> { box Default::default() }
67 }
68
69 #[stable]
70 impl<T> Default for Box<[T]> {
71     #[stable]
72     fn default() -> Box<[T]> { box [] }
73 }
74
75 #[stable]
76 impl<T: Clone> Clone for Box<T> {
77     /// Returns a copy of the owned box.
78     #[inline]
79     fn clone(&self) -> Box<T> { box {(**self).clone()} }
80
81     /// Performs copy-assignment from `source` by reusing the existing allocation.
82     #[inline]
83     fn clone_from(&mut self, source: &Box<T>) {
84         (**self).clone_from(&(**source));
85     }
86 }
87
88 #[stable]
89 impl<T: ?Sized + PartialEq> PartialEq for Box<T> {
90     #[inline]
91     fn eq(&self, other: &Box<T>) -> bool { PartialEq::eq(&**self, &**other) }
92     #[inline]
93     fn ne(&self, other: &Box<T>) -> bool { PartialEq::ne(&**self, &**other) }
94 }
95 #[stable]
96 impl<T: ?Sized + PartialOrd> PartialOrd for Box<T> {
97     #[inline]
98     fn partial_cmp(&self, other: &Box<T>) -> Option<Ordering> {
99         PartialOrd::partial_cmp(&**self, &**other)
100     }
101     #[inline]
102     fn lt(&self, other: &Box<T>) -> bool { PartialOrd::lt(&**self, &**other) }
103     #[inline]
104     fn le(&self, other: &Box<T>) -> bool { PartialOrd::le(&**self, &**other) }
105     #[inline]
106     fn ge(&self, other: &Box<T>) -> bool { PartialOrd::ge(&**self, &**other) }
107     #[inline]
108     fn gt(&self, other: &Box<T>) -> bool { PartialOrd::gt(&**self, &**other) }
109 }
110 #[stable]
111 impl<T: ?Sized + Ord> Ord for Box<T> {
112     #[inline]
113     fn cmp(&self, other: &Box<T>) -> Ordering {
114         Ord::cmp(&**self, &**other)
115     }
116 }
117 #[stable]
118 impl<T: ?Sized + Eq> Eq for Box<T> {}
119
120 impl<S: hash::Hasher, T: ?Sized + Hash<S>> Hash<S> for Box<T> {
121     #[inline]
122     fn hash(&self, state: &mut S) {
123         (**self).hash(state);
124     }
125 }
126
127 /// Extension methods for an owning `Any` trait object.
128 #[unstable = "this trait will likely disappear once compiler bugs blocking \
129               a direct impl on `Box<Any>` have been fixed "]
130 // FIXME(#18737): this should be a direct impl on `Box<Any>`. If you're
131 //                removing this please make sure that you can downcase on
132 //                `Box<Any + Send>` as well as `Box<Any>`
133 pub trait BoxAny {
134     /// Returns the boxed value if it is of type `T`, or
135     /// `Err(Self)` if it isn't.
136     #[stable]
137     fn downcast<T: 'static>(self) -> Result<Box<T>, Self>;
138 }
139
140 #[stable]
141 impl BoxAny for Box<Any> {
142     #[inline]
143     fn downcast<T: 'static>(self) -> Result<Box<T>, Box<Any>> {
144         if self.is::<T>() {
145             unsafe {
146                 // Get the raw representation of the trait object
147                 let to: TraitObject =
148                     mem::transmute::<Box<Any>, TraitObject>(self);
149
150                 // Extract the data pointer
151                 Ok(mem::transmute(to.data))
152             }
153         } else {
154             Err(self)
155         }
156     }
157 }
158
159 impl<T: ?Sized + fmt::Show> fmt::Show for Box<T> {
160     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
161         write!(f, "Box({:?})", &**self)
162     }
163 }
164
165 #[stable]
166 impl<T: ?Sized + fmt::String> fmt::String for Box<T> {
167     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
168         fmt::String::fmt(&**self, f)
169     }
170 }
171
172 impl fmt::Show for Box<Any> {
173     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
174         f.pad("Box<Any>")
175     }
176 }
177
178 #[stable]
179 impl<T: ?Sized> Deref for Box<T> {
180     type Target = T;
181
182     fn deref(&self) -> &T { &**self }
183 }
184
185 #[stable]
186 impl<T: ?Sized> DerefMut for Box<T> {
187     fn deref_mut(&mut self) -> &mut T { &mut **self }
188 }
189
190 #[cfg(test)]
191 mod test {
192     #[test]
193     fn test_owned_clone() {
194         let a = Box::new(5i);
195         let b: Box<int> = a.clone();
196         assert!(a == b);
197     }
198
199     #[test]
200     fn any_move() {
201         let a = Box::new(8u) as Box<Any>;
202         let b = Box::new(Test) as Box<Any>;
203
204         match a.downcast::<uint>() {
205             Ok(a) => { assert!(a == Box::new(8u)); }
206             Err(..) => panic!()
207         }
208         match b.downcast::<Test>() {
209             Ok(a) => { assert!(a == Box::new(Test)); }
210             Err(..) => panic!()
211         }
212
213         let a = Box::new(8u) as Box<Any>;
214         let b = Box::new(Test) as Box<Any>;
215
216         assert!(a.downcast::<Box<Test>>().is_err());
217         assert!(b.downcast::<Box<uint>>().is_err());
218     }
219
220     #[test]
221     fn test_show() {
222         let a = Box::new(8u) as Box<Any>;
223         let b = Box::new(Test) as Box<Any>;
224         let a_str = a.to_str();
225         let b_str = b.to_str();
226         assert_eq!(a_str, "Box<Any>");
227         assert_eq!(b_str, "Box<Any>");
228
229         let a = &8u as &Any;
230         let b = &Test as &Any;
231         let s = format!("{}", a);
232         assert_eq!(s, "&Any");
233         let s = format!("{}", b);
234         assert_eq!(s, "&Any");
235     }
236
237     #[test]
238     fn deref() {
239         fn homura<T: Deref<Target=i32>>(_: T) { }
240         homura(Box::new(765i32));
241     }
242 }