]>
Commit | Line | Data |
---|---|---|
1a4d82fc JJ |
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 | ||
85aaf69f SL |
11 | //! A pointer type for heap allocation. |
12 | //! | |
62682a34 SL |
13 | //! `Box<T>`, casually referred to as a 'box', provides the simplest form of |
14 | //! heap allocation in Rust. Boxes provide ownership for this allocation, and | |
15 | //! drop their contents when they go out of scope. | |
85aaf69f SL |
16 | //! |
17 | //! # Examples | |
18 | //! | |
19 | //! Creating a box: | |
20 | //! | |
21 | //! ``` | |
22 | //! let x = Box::new(5); | |
23 | //! ``` | |
24 | //! | |
25 | //! Creating a recursive data structure: | |
26 | //! | |
27 | //! ``` | |
28 | //! #[derive(Debug)] | |
29 | //! enum List<T> { | |
30 | //! Cons(T, Box<List<T>>), | |
31 | //! Nil, | |
32 | //! } | |
33 | //! | |
34 | //! fn main() { | |
35 | //! let list: List<i32> = List::Cons(1, Box::new(List::Cons(2, Box::new(List::Nil)))); | |
36 | //! println!("{:?}", list); | |
37 | //! } | |
38 | //! ``` | |
39 | //! | |
d9579d0f | 40 | //! This will print `Cons(1, Cons(2, Nil))`. |
9346a6ac | 41 | //! |
62682a34 SL |
42 | //! Recursive structures must be boxed, because if the definition of `Cons` |
43 | //! looked like this: | |
9346a6ac AL |
44 | //! |
45 | //! ```rust,ignore | |
46 | //! Cons(T, List<T>), | |
47 | //! ``` | |
48 | //! | |
62682a34 SL |
49 | //! It wouldn't work. This is because the size of a `List` depends on how many |
50 | //! elements are in the list, and so we don't know how much memory to allocate | |
51 | //! for a `Cons`. By introducing a `Box`, which has a defined size, we know how | |
52 | //! big `Cons` needs to be. | |
1a4d82fc | 53 | |
85aaf69f SL |
54 | #![stable(feature = "rust1", since = "1.0.0")] |
55 | ||
c1a9b12d SL |
56 | use heap; |
57 | use raw_vec::RawVec; | |
58 | ||
1a4d82fc | 59 | use core::any::Any; |
e9174d1e | 60 | use core::borrow; |
85aaf69f | 61 | use core::cmp::Ordering; |
1a4d82fc JJ |
62 | use core::fmt; |
63 | use core::hash::{self, Hash}; | |
9e0c209e | 64 | use core::iter::FusedIterator; |
c1a9b12d | 65 | use core::marker::{self, Unsize}; |
1a4d82fc | 66 | use core::mem; |
62682a34 | 67 | use core::ops::{CoerceUnsized, Deref, DerefMut}; |
3157f602 | 68 | use core::ops::{BoxPlace, Boxed, InPlace, Place, Placer}; |
c1a9b12d | 69 | use core::ptr::{self, Unique}; |
92a42be0 | 70 | use core::convert::From; |
1a4d82fc | 71 | |
85aaf69f SL |
72 | /// A value that represents the heap. This is the default place that the `box` |
73 | /// keyword allocates into when no place is supplied. | |
1a4d82fc JJ |
74 | /// |
75 | /// The following two examples are equivalent: | |
76 | /// | |
c34b1796 | 77 | /// ``` |
c1a9b12d SL |
78 | /// #![feature(box_heap)] |
79 | /// | |
80 | /// #![feature(box_syntax, placement_in_syntax)] | |
1a4d82fc JJ |
81 | /// use std::boxed::HEAP; |
82 | /// | |
83 | /// fn main() { | |
b039eaaf | 84 | /// let foo: Box<i32> = in HEAP { 5 }; |
85aaf69f | 85 | /// let foo = box 5; |
1a4d82fc JJ |
86 | /// } |
87 | /// ``` | |
62682a34 | 88 | #[unstable(feature = "box_heap", |
e9174d1e SL |
89 | reason = "may be renamed; uncertain about custom allocator design", |
90 | issue = "27779")] | |
92a42be0 | 91 | pub const HEAP: ExchangeHeapSingleton = ExchangeHeapSingleton { _force_singleton: () }; |
c1a9b12d SL |
92 | |
93 | /// This the singleton type used solely for `boxed::HEAP`. | |
94 | #[unstable(feature = "box_heap", | |
e9174d1e SL |
95 | reason = "may be renamed; uncertain about custom allocator design", |
96 | issue = "27779")] | |
c1a9b12d | 97 | #[derive(Copy, Clone)] |
b039eaaf SL |
98 | pub struct ExchangeHeapSingleton { |
99 | _force_singleton: (), | |
100 | } | |
1a4d82fc | 101 | |
85aaf69f SL |
102 | /// A pointer type for heap allocation. |
103 | /// | |
104 | /// See the [module-level documentation](../../std/boxed/index.html) for more. | |
1a4d82fc | 105 | #[lang = "owned_box"] |
85aaf69f | 106 | #[stable(feature = "rust1", since = "1.0.0")] |
c1a9b12d SL |
107 | pub struct Box<T: ?Sized>(Unique<T>); |
108 | ||
109 | /// `IntermediateBox` represents uninitialized backing storage for `Box`. | |
110 | /// | |
111 | /// FIXME (pnkfelix): Ideally we would just reuse `Box<T>` instead of | |
112 | /// introducing a separate `IntermediateBox<T>`; but then you hit | |
113 | /// issues when you e.g. attempt to destructure an instance of `Box`, | |
114 | /// since it is a lang item and so it gets special handling by the | |
115 | /// compiler. Easier just to make this parallel type for now. | |
116 | /// | |
117 | /// FIXME (pnkfelix): Currently the `box` protocol only supports | |
118 | /// creating instances of sized types. This IntermediateBox is | |
119 | /// designed to be forward-compatible with a future protocol that | |
120 | /// supports creating instances of unsized types; that is why the type | |
121 | /// parameter has the `?Sized` generalization marker, and is also why | |
122 | /// this carries an explicit size. However, it probably does not need | |
123 | /// to carry the explicit alignment; that is just a work-around for | |
124 | /// the fact that the `align_of` intrinsic currently requires the | |
125 | /// input type to be Sized (which I do not think is strictly | |
126 | /// necessary). | |
e9174d1e SL |
127 | #[unstable(feature = "placement_in", |
128 | reason = "placement box design is still being worked out.", | |
129 | issue = "27779")] | |
b039eaaf | 130 | pub struct IntermediateBox<T: ?Sized> { |
c1a9b12d SL |
131 | ptr: *mut u8, |
132 | size: usize, | |
133 | align: usize, | |
134 | marker: marker::PhantomData<*mut T>, | |
135 | } | |
136 | ||
92a42be0 SL |
137 | #[unstable(feature = "placement_in", |
138 | reason = "placement box design is still being worked out.", | |
139 | issue = "27779")] | |
c1a9b12d SL |
140 | impl<T> Place<T> for IntermediateBox<T> { |
141 | fn pointer(&mut self) -> *mut T { | |
b039eaaf | 142 | self.ptr as *mut T |
c1a9b12d SL |
143 | } |
144 | } | |
145 | ||
146 | unsafe fn finalize<T>(b: IntermediateBox<T>) -> Box<T> { | |
147 | let p = b.ptr as *mut T; | |
148 | mem::forget(b); | |
149 | mem::transmute(p) | |
150 | } | |
151 | ||
152 | fn make_place<T>() -> IntermediateBox<T> { | |
153 | let size = mem::size_of::<T>(); | |
154 | let align = mem::align_of::<T>(); | |
155 | ||
156 | let p = if size == 0 { | |
157 | heap::EMPTY as *mut u8 | |
158 | } else { | |
b039eaaf | 159 | let p = unsafe { heap::allocate(size, align) }; |
c1a9b12d SL |
160 | if p.is_null() { |
161 | panic!("Box make_place allocation failure."); | |
162 | } | |
163 | p | |
164 | }; | |
165 | ||
b039eaaf SL |
166 | IntermediateBox { |
167 | ptr: p, | |
168 | size: size, | |
169 | align: align, | |
170 | marker: marker::PhantomData, | |
171 | } | |
c1a9b12d SL |
172 | } |
173 | ||
92a42be0 SL |
174 | #[unstable(feature = "placement_in", |
175 | reason = "placement box design is still being worked out.", | |
176 | issue = "27779")] | |
c1a9b12d | 177 | impl<T> BoxPlace<T> for IntermediateBox<T> { |
b039eaaf SL |
178 | fn make_place() -> IntermediateBox<T> { |
179 | make_place() | |
180 | } | |
c1a9b12d SL |
181 | } |
182 | ||
92a42be0 SL |
183 | #[unstable(feature = "placement_in", |
184 | reason = "placement box design is still being worked out.", | |
185 | issue = "27779")] | |
c1a9b12d SL |
186 | impl<T> InPlace<T> for IntermediateBox<T> { |
187 | type Owner = Box<T>; | |
b039eaaf SL |
188 | unsafe fn finalize(self) -> Box<T> { |
189 | finalize(self) | |
190 | } | |
c1a9b12d SL |
191 | } |
192 | ||
92a42be0 | 193 | #[unstable(feature = "placement_new_protocol", issue = "27779")] |
c1a9b12d SL |
194 | impl<T> Boxed for Box<T> { |
195 | type Data = T; | |
196 | type Place = IntermediateBox<T>; | |
b039eaaf SL |
197 | unsafe fn finalize(b: IntermediateBox<T>) -> Box<T> { |
198 | finalize(b) | |
199 | } | |
c1a9b12d SL |
200 | } |
201 | ||
92a42be0 SL |
202 | #[unstable(feature = "placement_in", |
203 | reason = "placement box design is still being worked out.", | |
204 | issue = "27779")] | |
c1a9b12d SL |
205 | impl<T> Placer<T> for ExchangeHeapSingleton { |
206 | type Place = IntermediateBox<T>; | |
207 | ||
208 | fn make_place(self) -> IntermediateBox<T> { | |
209 | make_place() | |
210 | } | |
211 | } | |
212 | ||
92a42be0 SL |
213 | #[unstable(feature = "placement_in", |
214 | reason = "placement box design is still being worked out.", | |
215 | issue = "27779")] | |
c1a9b12d SL |
216 | impl<T: ?Sized> Drop for IntermediateBox<T> { |
217 | fn drop(&mut self) { | |
218 | if self.size > 0 { | |
b039eaaf | 219 | unsafe { heap::deallocate(self.ptr, self.size, self.align) } |
c1a9b12d SL |
220 | } |
221 | } | |
222 | } | |
1a4d82fc JJ |
223 | |
224 | impl<T> Box<T> { | |
9cc50fc6 | 225 | /// Allocates memory on the heap and then places `x` into it. |
85aaf69f SL |
226 | /// |
227 | /// # Examples | |
228 | /// | |
229 | /// ``` | |
9cc50fc6 | 230 | /// let five = Box::new(5); |
85aaf69f SL |
231 | /// ``` |
232 | #[stable(feature = "rust1", since = "1.0.0")] | |
c34b1796 | 233 | #[inline(always)] |
1a4d82fc JJ |
234 | pub fn new(x: T) -> Box<T> { |
235 | box x | |
236 | } | |
237 | } | |
238 | ||
92a42be0 | 239 | impl<T: ?Sized> Box<T> { |
9cc50fc6 | 240 | /// Constructs a box from a raw pointer. |
85aaf69f | 241 | /// |
9cc50fc6 SL |
242 | /// After calling this function, the raw pointer is owned by the |
243 | /// resulting `Box`. Specifically, the `Box` destructor will call | |
244 | /// the destructor of `T` and free the allocated memory. Since the | |
245 | /// way `Box` allocates and releases memory is unspecified, the | |
246 | /// only valid pointer to pass to this function is the one taken | |
247 | /// from another `Box` via the `Box::into_raw` function. | |
85aaf69f | 248 | /// |
9cc50fc6 SL |
249 | /// This function is unsafe because improper use may lead to |
250 | /// memory problems. For example, a double-free may occur if the | |
85aaf69f | 251 | /// function is called twice on the same raw pointer. |
5bcae85e SL |
252 | /// |
253 | /// # Examples | |
254 | /// | |
255 | /// ``` | |
256 | /// let x = Box::new(5); | |
257 | /// let ptr = Box::into_raw(x); | |
258 | /// let x = unsafe { Box::from_raw(ptr) }; | |
259 | /// ``` | |
e9174d1e | 260 | #[stable(feature = "box_raw", since = "1.4.0")] |
c34b1796 | 261 | #[inline] |
85aaf69f SL |
262 | pub unsafe fn from_raw(raw: *mut T) -> Self { |
263 | mem::transmute(raw) | |
264 | } | |
62682a34 SL |
265 | |
266 | /// Consumes the `Box`, returning the wrapped raw pointer. | |
267 | /// | |
9cc50fc6 SL |
268 | /// After calling this function, the caller is responsible for the |
269 | /// memory previously managed by the `Box`. In particular, the | |
270 | /// caller should properly destroy `T` and release the memory. The | |
271 | /// proper way to do so is to convert the raw pointer back into a | |
272 | /// `Box` with the `Box::from_raw` function. | |
62682a34 | 273 | /// |
9e0c209e SL |
274 | /// Note: this is an associated function, which means that you have |
275 | /// to call it as `Box::into_raw(b)` instead of `b.into_raw()`. This | |
276 | /// is so that there is no conflict with a method on the inner type. | |
277 | /// | |
62682a34 | 278 | /// # Examples |
62682a34 | 279 | /// |
e9174d1e | 280 | /// ``` |
5bcae85e SL |
281 | /// let x = Box::new(5); |
282 | /// let ptr = Box::into_raw(x); | |
62682a34 | 283 | /// ``` |
e9174d1e | 284 | #[stable(feature = "box_raw", since = "1.4.0")] |
62682a34 | 285 | #[inline] |
62682a34 SL |
286 | pub fn into_raw(b: Box<T>) -> *mut T { |
287 | unsafe { mem::transmute(b) } | |
288 | } | |
85aaf69f SL |
289 | } |
290 | ||
85aaf69f | 291 | #[stable(feature = "rust1", since = "1.0.0")] |
1a4d82fc | 292 | impl<T: Default> Default for Box<T> { |
9e0c209e | 293 | /// Creates a `Box<T>`, with the `Default` value for T. |
b039eaaf SL |
294 | fn default() -> Box<T> { |
295 | box Default::default() | |
296 | } | |
1a4d82fc JJ |
297 | } |
298 | ||
85aaf69f | 299 | #[stable(feature = "rust1", since = "1.0.0")] |
1a4d82fc | 300 | impl<T> Default for Box<[T]> { |
b039eaaf SL |
301 | fn default() -> Box<[T]> { |
302 | Box::<[T; 0]>::new([]) | |
303 | } | |
1a4d82fc JJ |
304 | } |
305 | ||
85aaf69f | 306 | #[stable(feature = "rust1", since = "1.0.0")] |
1a4d82fc | 307 | impl<T: Clone> Clone for Box<T> { |
85aaf69f SL |
308 | /// Returns a new box with a `clone()` of this box's contents. |
309 | /// | |
310 | /// # Examples | |
311 | /// | |
312 | /// ``` | |
313 | /// let x = Box::new(5); | |
314 | /// let y = x.clone(); | |
315 | /// ``` | |
b039eaaf | 316 | #[rustfmt_skip] |
1a4d82fc | 317 | #[inline] |
b039eaaf SL |
318 | fn clone(&self) -> Box<T> { |
319 | box { (**self).clone() } | |
320 | } | |
85aaf69f SL |
321 | /// Copies `source`'s contents into `self` without creating a new allocation. |
322 | /// | |
323 | /// # Examples | |
324 | /// | |
325 | /// ``` | |
326 | /// let x = Box::new(5); | |
327 | /// let mut y = Box::new(10); | |
328 | /// | |
329 | /// y.clone_from(&x); | |
330 | /// | |
331 | /// assert_eq!(*y, 5); | |
332 | /// ``` | |
1a4d82fc JJ |
333 | #[inline] |
334 | fn clone_from(&mut self, source: &Box<T>) { | |
335 | (**self).clone_from(&(**source)); | |
336 | } | |
337 | } | |
338 | ||
c1a9b12d SL |
339 | |
340 | #[stable(feature = "box_slice_clone", since = "1.3.0")] | |
341 | impl Clone for Box<str> { | |
342 | fn clone(&self) -> Self { | |
343 | let len = self.len(); | |
344 | let buf = RawVec::with_capacity(len); | |
345 | unsafe { | |
346 | ptr::copy_nonoverlapping(self.as_ptr(), buf.ptr(), len); | |
347 | mem::transmute(buf.into_box()) // bytes to str ~magic | |
348 | } | |
349 | } | |
350 | } | |
351 | ||
85aaf69f | 352 | #[stable(feature = "rust1", since = "1.0.0")] |
1a4d82fc JJ |
353 | impl<T: ?Sized + PartialEq> PartialEq for Box<T> { |
354 | #[inline] | |
b039eaaf SL |
355 | fn eq(&self, other: &Box<T>) -> bool { |
356 | PartialEq::eq(&**self, &**other) | |
357 | } | |
1a4d82fc | 358 | #[inline] |
b039eaaf SL |
359 | fn ne(&self, other: &Box<T>) -> bool { |
360 | PartialEq::ne(&**self, &**other) | |
361 | } | |
1a4d82fc | 362 | } |
85aaf69f | 363 | #[stable(feature = "rust1", since = "1.0.0")] |
1a4d82fc JJ |
364 | impl<T: ?Sized + PartialOrd> PartialOrd for Box<T> { |
365 | #[inline] | |
366 | fn partial_cmp(&self, other: &Box<T>) -> Option<Ordering> { | |
367 | PartialOrd::partial_cmp(&**self, &**other) | |
368 | } | |
369 | #[inline] | |
b039eaaf SL |
370 | fn lt(&self, other: &Box<T>) -> bool { |
371 | PartialOrd::lt(&**self, &**other) | |
372 | } | |
1a4d82fc | 373 | #[inline] |
b039eaaf SL |
374 | fn le(&self, other: &Box<T>) -> bool { |
375 | PartialOrd::le(&**self, &**other) | |
376 | } | |
1a4d82fc | 377 | #[inline] |
b039eaaf SL |
378 | fn ge(&self, other: &Box<T>) -> bool { |
379 | PartialOrd::ge(&**self, &**other) | |
380 | } | |
1a4d82fc | 381 | #[inline] |
b039eaaf SL |
382 | fn gt(&self, other: &Box<T>) -> bool { |
383 | PartialOrd::gt(&**self, &**other) | |
384 | } | |
1a4d82fc | 385 | } |
85aaf69f | 386 | #[stable(feature = "rust1", since = "1.0.0")] |
1a4d82fc JJ |
387 | impl<T: ?Sized + Ord> Ord for Box<T> { |
388 | #[inline] | |
389 | fn cmp(&self, other: &Box<T>) -> Ordering { | |
390 | Ord::cmp(&**self, &**other) | |
391 | } | |
392 | } | |
85aaf69f | 393 | #[stable(feature = "rust1", since = "1.0.0")] |
1a4d82fc JJ |
394 | impl<T: ?Sized + Eq> Eq for Box<T> {} |
395 | ||
85aaf69f SL |
396 | #[stable(feature = "rust1", since = "1.0.0")] |
397 | impl<T: ?Sized + Hash> Hash for Box<T> { | |
398 | fn hash<H: hash::Hasher>(&self, state: &mut H) { | |
1a4d82fc JJ |
399 | (**self).hash(state); |
400 | } | |
401 | } | |
402 | ||
92a42be0 SL |
403 | #[stable(feature = "from_for_ptrs", since = "1.6.0")] |
404 | impl<T> From<T> for Box<T> { | |
405 | fn from(t: T) -> Self { | |
406 | Box::new(t) | |
407 | } | |
408 | } | |
409 | ||
c34b1796 | 410 | impl Box<Any> { |
1a4d82fc | 411 | #[inline] |
c34b1796 | 412 | #[stable(feature = "rust1", since = "1.0.0")] |
bd371182 | 413 | /// Attempt to downcast the box to a concrete type. |
5bcae85e SL |
414 | /// |
415 | /// # Examples | |
416 | /// | |
417 | /// ``` | |
418 | /// use std::any::Any; | |
419 | /// | |
420 | /// fn print_if_string(value: Box<Any>) { | |
421 | /// if let Ok(string) = value.downcast::<String>() { | |
422 | /// println!("String ({}): {}", string.len(), string); | |
423 | /// } | |
424 | /// } | |
425 | /// | |
426 | /// fn main() { | |
427 | /// let my_string = "Hello World".to_string(); | |
428 | /// print_if_string(Box::new(my_string)); | |
429 | /// print_if_string(Box::new(0i8)); | |
430 | /// } | |
431 | /// ``` | |
c34b1796 | 432 | pub fn downcast<T: Any>(self) -> Result<Box<T>, Box<Any>> { |
1a4d82fc JJ |
433 | if self.is::<T>() { |
434 | unsafe { | |
9e0c209e SL |
435 | let raw: *mut Any = Box::into_raw(self); |
436 | Ok(Box::from_raw(raw as *mut T)) | |
1a4d82fc JJ |
437 | } |
438 | } else { | |
439 | Err(self) | |
440 | } | |
441 | } | |
442 | } | |
443 | ||
bd371182 | 444 | impl Box<Any + Send> { |
c34b1796 AL |
445 | #[inline] |
446 | #[stable(feature = "rust1", since = "1.0.0")] | |
bd371182 | 447 | /// Attempt to downcast the box to a concrete type. |
5bcae85e SL |
448 | /// |
449 | /// # Examples | |
450 | /// | |
451 | /// ``` | |
452 | /// use std::any::Any; | |
453 | /// | |
454 | /// fn print_if_string(value: Box<Any + Send>) { | |
455 | /// if let Ok(string) = value.downcast::<String>() { | |
456 | /// println!("String ({}): {}", string.len(), string); | |
457 | /// } | |
458 | /// } | |
459 | /// | |
460 | /// fn main() { | |
461 | /// let my_string = "Hello World".to_string(); | |
462 | /// print_if_string(Box::new(my_string)); | |
463 | /// print_if_string(Box::new(0i8)); | |
464 | /// } | |
465 | /// ``` | |
bd371182 AL |
466 | pub fn downcast<T: Any>(self) -> Result<Box<T>, Box<Any + Send>> { |
467 | <Box<Any>>::downcast(self).map_err(|s| unsafe { | |
468 | // reapply the Send marker | |
469 | mem::transmute::<Box<Any>, Box<Any + Send>>(s) | |
470 | }) | |
c34b1796 AL |
471 | } |
472 | } | |
473 | ||
85aaf69f SL |
474 | #[stable(feature = "rust1", since = "1.0.0")] |
475 | impl<T: fmt::Display + ?Sized> fmt::Display for Box<T> { | |
1a4d82fc | 476 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { |
85aaf69f | 477 | fmt::Display::fmt(&**self, f) |
1a4d82fc JJ |
478 | } |
479 | } | |
480 | ||
85aaf69f SL |
481 | #[stable(feature = "rust1", since = "1.0.0")] |
482 | impl<T: fmt::Debug + ?Sized> fmt::Debug for Box<T> { | |
1a4d82fc | 483 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { |
85aaf69f | 484 | fmt::Debug::fmt(&**self, f) |
1a4d82fc JJ |
485 | } |
486 | } | |
487 | ||
9346a6ac | 488 | #[stable(feature = "rust1", since = "1.0.0")] |
7453a54e | 489 | impl<T: ?Sized> fmt::Pointer for Box<T> { |
9346a6ac AL |
490 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { |
491 | // It's not possible to extract the inner Uniq directly from the Box, | |
492 | // instead we cast it to a *const which aliases the Unique | |
493 | let ptr: *const T = &**self; | |
494 | fmt::Pointer::fmt(&ptr, f) | |
495 | } | |
496 | } | |
497 | ||
85aaf69f | 498 | #[stable(feature = "rust1", since = "1.0.0")] |
1a4d82fc JJ |
499 | impl<T: ?Sized> Deref for Box<T> { |
500 | type Target = T; | |
501 | ||
b039eaaf SL |
502 | fn deref(&self) -> &T { |
503 | &**self | |
504 | } | |
1a4d82fc JJ |
505 | } |
506 | ||
85aaf69f | 507 | #[stable(feature = "rust1", since = "1.0.0")] |
1a4d82fc | 508 | impl<T: ?Sized> DerefMut for Box<T> { |
b039eaaf SL |
509 | fn deref_mut(&mut self) -> &mut T { |
510 | &mut **self | |
511 | } | |
1a4d82fc JJ |
512 | } |
513 | ||
85aaf69f SL |
514 | #[stable(feature = "rust1", since = "1.0.0")] |
515 | impl<I: Iterator + ?Sized> Iterator for Box<I> { | |
516 | type Item = I::Item; | |
b039eaaf SL |
517 | fn next(&mut self) -> Option<I::Item> { |
518 | (**self).next() | |
519 | } | |
520 | fn size_hint(&self) -> (usize, Option<usize>) { | |
521 | (**self).size_hint() | |
522 | } | |
85aaf69f SL |
523 | } |
524 | #[stable(feature = "rust1", since = "1.0.0")] | |
525 | impl<I: DoubleEndedIterator + ?Sized> DoubleEndedIterator for Box<I> { | |
b039eaaf SL |
526 | fn next_back(&mut self) -> Option<I::Item> { |
527 | (**self).next_back() | |
528 | } | |
85aaf69f SL |
529 | } |
530 | #[stable(feature = "rust1", since = "1.0.0")] | |
531 | impl<I: ExactSizeIterator + ?Sized> ExactSizeIterator for Box<I> {} | |
1a4d82fc | 532 | |
9e0c209e SL |
533 | #[unstable(feature = "fused", issue = "35602")] |
534 | impl<I: FusedIterator + ?Sized> FusedIterator for Box<I> {} | |
535 | ||
c34b1796 AL |
536 | |
537 | /// `FnBox` is a version of the `FnOnce` intended for use with boxed | |
538 | /// closure objects. The idea is that where one would normally store a | |
539 | /// `Box<FnOnce()>` in a data structure, you should use | |
540 | /// `Box<FnBox()>`. The two traits behave essentially the same, except | |
541 | /// that a `FnBox` closure can only be called if it is boxed. (Note | |
542 | /// that `FnBox` may be deprecated in the future if `Box<FnOnce()>` | |
543 | /// closures become directly usable.) | |
544 | /// | |
545 | /// ### Example | |
546 | /// | |
547 | /// Here is a snippet of code which creates a hashmap full of boxed | |
548 | /// once closures and then removes them one by one, calling each | |
549 | /// closure as it is removed. Note that the type of the closures | |
550 | /// stored in the map is `Box<FnBox() -> i32>` and not `Box<FnOnce() | |
551 | /// -> i32>`. | |
552 | /// | |
553 | /// ``` | |
62682a34 | 554 | /// #![feature(fnbox)] |
c34b1796 AL |
555 | /// |
556 | /// use std::boxed::FnBox; | |
557 | /// use std::collections::HashMap; | |
558 | /// | |
559 | /// fn make_map() -> HashMap<i32, Box<FnBox() -> i32>> { | |
560 | /// let mut map: HashMap<i32, Box<FnBox() -> i32>> = HashMap::new(); | |
561 | /// map.insert(1, Box::new(|| 22)); | |
562 | /// map.insert(2, Box::new(|| 44)); | |
563 | /// map | |
564 | /// } | |
565 | /// | |
566 | /// fn main() { | |
567 | /// let mut map = make_map(); | |
568 | /// for i in &[1, 2] { | |
569 | /// let f = map.remove(&i).unwrap(); | |
570 | /// assert_eq!(f(), i * 22); | |
571 | /// } | |
572 | /// } | |
573 | /// ``` | |
574 | #[rustc_paren_sugar] | |
a7813a04 XL |
575 | #[unstable(feature = "fnbox", |
576 | reason = "will be deprecated if and when Box<FnOnce> becomes usable", issue = "28796")] | |
c34b1796 AL |
577 | pub trait FnBox<A> { |
578 | type Output; | |
579 | ||
580 | fn call_box(self: Box<Self>, args: A) -> Self::Output; | |
581 | } | |
582 | ||
a7813a04 XL |
583 | #[unstable(feature = "fnbox", |
584 | reason = "will be deprecated if and when Box<FnOnce> becomes usable", issue = "28796")] | |
3157f602 XL |
585 | impl<A, F> FnBox<A> for F |
586 | where F: FnOnce<A> | |
c34b1796 AL |
587 | { |
588 | type Output = F::Output; | |
589 | ||
590 | fn call_box(self: Box<F>, args: A) -> F::Output { | |
591 | self.call_once(args) | |
592 | } | |
593 | } | |
594 | ||
a7813a04 XL |
595 | #[unstable(feature = "fnbox", |
596 | reason = "will be deprecated if and when Box<FnOnce> becomes usable", issue = "28796")] | |
92a42be0 | 597 | impl<'a, A, R> FnOnce<A> for Box<FnBox<A, Output = R> + 'a> { |
c34b1796 AL |
598 | type Output = R; |
599 | ||
600 | extern "rust-call" fn call_once(self, args: A) -> R { | |
601 | self.call_box(args) | |
602 | } | |
603 | } | |
604 | ||
a7813a04 XL |
605 | #[unstable(feature = "fnbox", |
606 | reason = "will be deprecated if and when Box<FnOnce> becomes usable", issue = "28796")] | |
92a42be0 | 607 | impl<'a, A, R> FnOnce<A> for Box<FnBox<A, Output = R> + Send + 'a> { |
c34b1796 AL |
608 | type Output = R; |
609 | ||
610 | extern "rust-call" fn call_once(self, args: A) -> R { | |
611 | self.call_box(args) | |
1a4d82fc JJ |
612 | } |
613 | } | |
d9579d0f | 614 | |
92a42be0 SL |
615 | #[unstable(feature = "coerce_unsized", issue = "27732")] |
616 | impl<T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<Box<U>> for Box<T> {} | |
c1a9b12d SL |
617 | |
618 | #[stable(feature = "box_slice_clone", since = "1.3.0")] | |
619 | impl<T: Clone> Clone for Box<[T]> { | |
620 | fn clone(&self) -> Self { | |
621 | let mut new = BoxBuilder { | |
622 | data: RawVec::with_capacity(self.len()), | |
b039eaaf | 623 | len: 0, |
c1a9b12d SL |
624 | }; |
625 | ||
626 | let mut target = new.data.ptr(); | |
627 | ||
628 | for item in self.iter() { | |
629 | unsafe { | |
630 | ptr::write(target, item.clone()); | |
631 | target = target.offset(1); | |
632 | }; | |
633 | ||
634 | new.len += 1; | |
635 | } | |
636 | ||
637 | return unsafe { new.into_box() }; | |
638 | ||
639 | // Helper type for responding to panics correctly. | |
640 | struct BoxBuilder<T> { | |
641 | data: RawVec<T>, | |
642 | len: usize, | |
643 | } | |
644 | ||
645 | impl<T> BoxBuilder<T> { | |
646 | unsafe fn into_box(self) -> Box<[T]> { | |
647 | let raw = ptr::read(&self.data); | |
648 | mem::forget(self); | |
649 | raw.into_box() | |
650 | } | |
651 | } | |
652 | ||
653 | impl<T> Drop for BoxBuilder<T> { | |
654 | fn drop(&mut self) { | |
655 | let mut data = self.data.ptr(); | |
656 | let max = unsafe { data.offset(self.len as isize) }; | |
657 | ||
658 | while data != max { | |
659 | unsafe { | |
660 | ptr::read(data); | |
661 | data = data.offset(1); | |
662 | } | |
663 | } | |
664 | } | |
665 | } | |
666 | } | |
667 | } | |
668 | ||
92a42be0 | 669 | #[stable(feature = "rust1", since = "1.0.0")] |
e9174d1e | 670 | impl<T: ?Sized> borrow::Borrow<T> for Box<T> { |
b039eaaf SL |
671 | fn borrow(&self) -> &T { |
672 | &**self | |
673 | } | |
e9174d1e SL |
674 | } |
675 | ||
92a42be0 | 676 | #[stable(feature = "rust1", since = "1.0.0")] |
e9174d1e | 677 | impl<T: ?Sized> borrow::BorrowMut<T> for Box<T> { |
b039eaaf SL |
678 | fn borrow_mut(&mut self) -> &mut T { |
679 | &mut **self | |
680 | } | |
681 | } | |
682 | ||
683 | #[stable(since = "1.5.0", feature = "smart_ptr_as_ref")] | |
684 | impl<T: ?Sized> AsRef<T> for Box<T> { | |
685 | fn as_ref(&self) -> &T { | |
686 | &**self | |
687 | } | |
688 | } | |
689 | ||
690 | #[stable(since = "1.5.0", feature = "smart_ptr_as_ref")] | |
691 | impl<T: ?Sized> AsMut<T> for Box<T> { | |
692 | fn as_mut(&mut self) -> &mut T { | |
693 | &mut **self | |
694 | } | |
e9174d1e | 695 | } |