]> git.lizzy.rs Git - rust.git/blob - src/liballoc/boxed.rs
Merge pull request #20682 from sfackler/fix-impls
[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 #![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 /// use std::boxed::HEAP;
37 ///
38 /// # struct Bar;
39 /// # impl Bar { fn new(_a: int) { } }
40 /// let foo = box(HEAP) Bar::new(2);
41 /// let foo = box Bar::new(2);
42 /// ```
43 #[lang = "exchange_heap"]
44 #[experimental = "may be renamed; uncertain about custom allocator design"]
45 pub static HEAP: () = ();
46
47 /// A type that represents a uniquely-owned value.
48 #[lang = "owned_box"]
49 #[stable]
50 pub struct Box<T>(Unique<T>);
51
52 #[stable]
53 impl<T: Default> Default for Box<T> {
54     #[stable]
55     fn default() -> Box<T> { box Default::default() }
56 }
57
58 #[stable]
59 impl<T> Default for Box<[T]> {
60     #[stable]
61     fn default() -> Box<[T]> { box [] }
62 }
63
64 #[stable]
65 impl<T: Clone> Clone for Box<T> {
66     /// Returns a copy of the owned box.
67     #[inline]
68     fn clone(&self) -> Box<T> { box {(**self).clone()} }
69
70     /// Performs copy-assignment from `source` by reusing the existing allocation.
71     #[inline]
72     fn clone_from(&mut self, source: &Box<T>) {
73         (**self).clone_from(&(**source));
74     }
75 }
76
77 #[stable]
78 impl<T: ?Sized + PartialEq> PartialEq for Box<T> {
79     #[inline]
80     fn eq(&self, other: &Box<T>) -> bool { PartialEq::eq(&**self, &**other) }
81     #[inline]
82     fn ne(&self, other: &Box<T>) -> bool { PartialEq::ne(&**self, &**other) }
83 }
84 #[stable]
85 impl<T: ?Sized + PartialOrd> PartialOrd for Box<T> {
86     #[inline]
87     fn partial_cmp(&self, other: &Box<T>) -> Option<Ordering> {
88         PartialOrd::partial_cmp(&**self, &**other)
89     }
90     #[inline]
91     fn lt(&self, other: &Box<T>) -> bool { PartialOrd::lt(&**self, &**other) }
92     #[inline]
93     fn le(&self, other: &Box<T>) -> bool { PartialOrd::le(&**self, &**other) }
94     #[inline]
95     fn ge(&self, other: &Box<T>) -> bool { PartialOrd::ge(&**self, &**other) }
96     #[inline]
97     fn gt(&self, other: &Box<T>) -> bool { PartialOrd::gt(&**self, &**other) }
98 }
99 #[stable]
100 impl<T: ?Sized + Ord> Ord for Box<T> {
101     #[inline]
102     fn cmp(&self, other: &Box<T>) -> Ordering {
103         Ord::cmp(&**self, &**other)
104     }
105
106 #[stable]}
107 impl<T: ?Sized + Eq> Eq for Box<T> {}
108
109 impl<S: hash::Writer, T: ?Sized + Hash<S>> Hash<S> for Box<T> {
110     #[inline]
111     fn hash(&self, state: &mut S) {
112         (**self).hash(state);
113     }
114 }
115
116 /// Extension methods for an owning `Any` trait object.
117 #[unstable = "post-DST and coherence changes, this will not be a trait but \
118               rather a direct `impl` on `Box<Any>`"]
119 pub trait BoxAny {
120     /// Returns the boxed value if it is of type `T`, or
121     /// `Err(Self)` if it isn't.
122     #[stable]
123     fn downcast<T: 'static>(self) -> Result<Box<T>, Self>;
124 }
125
126 impl BoxAny for Box<Any> {
127     #[inline]
128     #[unstable = "method may be renamed with respect to other downcasting \
129                   methods"]
130     fn downcast<T: 'static>(self) -> Result<Box<T>, Box<Any>> {
131         if self.is::<T>() {
132             unsafe {
133                 // Get the raw representation of the trait object
134                 let to: TraitObject =
135                     mem::transmute::<Box<Any>, TraitObject>(self);
136
137                 // Extract the data pointer
138                 Ok(mem::transmute(to.data))
139             }
140         } else {
141             Err(self)
142         }
143     }
144 }
145
146 impl<T: ?Sized + fmt::Show> fmt::Show for Box<T> {
147     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
148         write!(f, "Box({:?})", &**self)
149     }
150 }
151
152 impl<T: ?Sized + fmt::String> fmt::String for Box<T> {
153     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
154         fmt::String::fmt(&**self, f)
155     }
156 }
157
158 impl fmt::Show for Box<Any> {
159     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
160         f.pad("Box<Any>")
161     }
162 }
163
164 #[stable]
165 impl<T: ?Sized> Deref for Box<T> {
166     type Target = T;
167
168     fn deref(&self) -> &T { &**self }
169 }
170
171 #[stable]
172 impl<T: ?Sized> DerefMut for Box<T> {
173     fn deref_mut(&mut self) -> &mut T { &mut **self }
174 }
175
176 #[cfg(test)]
177 mod test {
178     #[test]
179     fn test_owned_clone() {
180         let a = box 5i;
181         let b: Box<int> = a.clone();
182         assert!(a == b);
183     }
184
185     #[test]
186     fn any_move() {
187         let a = box 8u as Box<Any>;
188         let b = box Test as Box<Any>;
189
190         match a.downcast::<uint>() {
191             Ok(a) => { assert!(a == box 8u); }
192             Err(..) => panic!()
193         }
194         match b.downcast::<Test>() {
195             Ok(a) => { assert!(a == box Test); }
196             Err(..) => panic!()
197         }
198
199         let a = box 8u as Box<Any>;
200         let b = box Test as Box<Any>;
201
202         assert!(a.downcast::<Box<Test>>().is_err());
203         assert!(b.downcast::<Box<uint>>().is_err());
204     }
205
206     #[test]
207     fn test_show() {
208         let a = box 8u as Box<Any>;
209         let b = box Test as Box<Any>;
210         let a_str = a.to_str();
211         let b_str = b.to_str();
212         assert_eq!(a_str, "Box<Any>");
213         assert_eq!(b_str, "Box<Any>");
214
215         let a = &8u as &Any;
216         let b = &Test as &Any;
217         let s = format!("{}", a);
218         assert_eq!(s, "&Any");
219         let s = format!("{}", b);
220         assert_eq!(s, "&Any");
221     }
222
223     #[test]
224     fn deref() {
225         fn homura<T: Deref<Target=i32>>(_: T) { }
226         homura(box 765i32);
227     }
228 }