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