]> git.proxmox.com Git - rustc.git/blob - src/liballoc/boxed.rs
Imported Upstream version 1.3.0+dfsg1
[rustc.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 pointer type for heap allocation.
12 //!
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.
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 //!
40 //! This will print `Cons(1, Cons(2, Nil))`.
41 //!
42 //! Recursive structures must be boxed, because if the definition of `Cons`
43 //! looked like this:
44 //!
45 //! ```rust,ignore
46 //! Cons(T, List<T>),
47 //! ```
48 //!
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.
53
54 #![stable(feature = "rust1", since = "1.0.0")]
55
56 use core::prelude::*;
57
58 use heap;
59 use raw_vec::RawVec;
60
61 use core::any::Any;
62 use core::cmp::Ordering;
63 use core::fmt;
64 use core::hash::{self, Hash};
65 use core::marker::{self, Unsize};
66 use core::mem;
67 use core::ops::{CoerceUnsized, Deref, DerefMut};
68 use core::ops::{Placer, Boxed, Place, InPlace, BoxPlace};
69 use core::ptr::{self, Unique};
70 use core::raw::{TraitObject};
71
72 /// A value that represents the heap. This is the default place that the `box`
73 /// keyword allocates into when no place is supplied.
74 ///
75 /// The following two examples are equivalent:
76 ///
77 /// ```
78 /// #![feature(box_heap)]
79 ///
80 /// #![feature(box_syntax, placement_in_syntax)]
81 /// use std::boxed::HEAP;
82 ///
83 /// fn main() {
84 /// let foo = box(HEAP) 5;
85 /// let foo = box 5;
86 /// }
87 /// ```
88 #[lang = "exchange_heap"]
89 #[unstable(feature = "box_heap",
90 reason = "may be renamed; uncertain about custom allocator design")]
91 #[allow(deprecated)]
92 pub const HEAP: ExchangeHeapSingleton =
93 ExchangeHeapSingleton { _force_singleton: () };
94
95 /// This the singleton type used solely for `boxed::HEAP`.
96 #[unstable(feature = "box_heap",
97 reason = "may be renamed; uncertain about custom allocator design")]
98 #[derive(Copy, Clone)]
99 pub struct ExchangeHeapSingleton { _force_singleton: () }
100
101 /// A pointer type for heap allocation.
102 ///
103 /// See the [module-level documentation](../../std/boxed/index.html) for more.
104 #[lang = "owned_box"]
105 #[stable(feature = "rust1", since = "1.0.0")]
106 #[fundamental]
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).
127 #[unstable(feature = "placement_in", reason = "placement box design is still being worked out.")]
128 pub struct IntermediateBox<T: ?Sized>{
129 ptr: *mut u8,
130 size: usize,
131 align: usize,
132 marker: marker::PhantomData<*mut T>,
133 }
134
135 impl<T> Place<T> for IntermediateBox<T> {
136 fn pointer(&mut self) -> *mut T {
137 unsafe { ::core::mem::transmute(self.ptr) }
138 }
139 }
140
141 unsafe fn finalize<T>(b: IntermediateBox<T>) -> Box<T> {
142 let p = b.ptr as *mut T;
143 mem::forget(b);
144 mem::transmute(p)
145 }
146
147 fn make_place<T>() -> IntermediateBox<T> {
148 let size = mem::size_of::<T>();
149 let align = mem::align_of::<T>();
150
151 let p = if size == 0 {
152 heap::EMPTY as *mut u8
153 } else {
154 let p = unsafe {
155 heap::allocate(size, align)
156 };
157 if p.is_null() {
158 panic!("Box make_place allocation failure.");
159 }
160 p
161 };
162
163 IntermediateBox { ptr: p, size: size, align: align, marker: marker::PhantomData }
164 }
165
166 impl<T> BoxPlace<T> for IntermediateBox<T> {
167 fn make_place() -> IntermediateBox<T> { make_place() }
168 }
169
170 impl<T> InPlace<T> for IntermediateBox<T> {
171 type Owner = Box<T>;
172 unsafe fn finalize(self) -> Box<T> { finalize(self) }
173 }
174
175 impl<T> Boxed for Box<T> {
176 type Data = T;
177 type Place = IntermediateBox<T>;
178 unsafe fn finalize(b: IntermediateBox<T>) -> Box<T> { finalize(b) }
179 }
180
181 impl<T> Placer<T> for ExchangeHeapSingleton {
182 type Place = IntermediateBox<T>;
183
184 fn make_place(self) -> IntermediateBox<T> {
185 make_place()
186 }
187 }
188
189 impl<T: ?Sized> Drop for IntermediateBox<T> {
190 fn drop(&mut self) {
191 if self.size > 0 {
192 unsafe {
193 heap::deallocate(self.ptr, self.size, self.align)
194 }
195 }
196 }
197 }
198
199 impl<T> Box<T> {
200 /// Allocates memory on the heap and then moves `x` into it.
201 ///
202 /// # Examples
203 ///
204 /// ```
205 /// let x = Box::new(5);
206 /// ```
207 #[stable(feature = "rust1", since = "1.0.0")]
208 #[inline(always)]
209 pub fn new(x: T) -> Box<T> {
210 box x
211 }
212 }
213
214 impl<T : ?Sized> Box<T> {
215 /// Constructs a box from the raw pointer.
216 ///
217 /// After this function call, pointer is owned by resulting box.
218 /// In particular, it means that `Box` destructor calls destructor
219 /// of `T` and releases memory. Since the way `Box` allocates and
220 /// releases memory is unspecified, the only valid pointer to pass
221 /// to this function is the one taken from another `Box` with
222 /// `Box::into_raw` function.
223 ///
224 /// Function is unsafe, because improper use of this function may
225 /// lead to memory problems like double-free, for example if the
226 /// function is called twice on the same raw pointer.
227 #[unstable(feature = "box_raw",
228 reason = "may be renamed or moved out of Box scope")]
229 #[inline]
230 // NB: may want to be called from_ptr, see comments on CStr::from_ptr
231 pub unsafe fn from_raw(raw: *mut T) -> Self {
232 mem::transmute(raw)
233 }
234
235 /// Consumes the `Box`, returning the wrapped raw pointer.
236 ///
237 /// After call to this function, caller is responsible for the memory
238 /// previously managed by `Box`, in particular caller should properly
239 /// destroy `T` and release memory. The proper way to do it is to
240 /// convert pointer back to `Box` with `Box::from_raw` function, because
241 /// `Box` does not specify, how memory is allocated.
242 ///
243 /// # Examples
244 /// ```
245 /// #![feature(box_raw)]
246 ///
247 /// let seventeen = Box::new(17u32);
248 /// let raw = Box::into_raw(seventeen);
249 /// let boxed_again = unsafe { Box::from_raw(raw) };
250 /// ```
251 #[unstable(feature = "box_raw", reason = "may be renamed")]
252 #[inline]
253 // NB: may want to be called into_ptr, see comments on CStr::from_ptr
254 pub fn into_raw(b: Box<T>) -> *mut T {
255 unsafe { mem::transmute(b) }
256 }
257 }
258
259 /// Consumes the `Box`, returning the wrapped raw pointer.
260 ///
261 /// After call to this function, caller is responsible for the memory
262 /// previously managed by `Box`, in particular caller should properly
263 /// destroy `T` and release memory. The proper way to do it is to
264 /// convert pointer back to `Box` with `Box::from_raw` function, because
265 /// `Box` does not specify, how memory is allocated.
266 ///
267 /// # Examples
268 /// ```
269 /// #![feature(box_raw)]
270 ///
271 /// use std::boxed;
272 ///
273 /// let seventeen = Box::new(17u32);
274 /// let raw = boxed::into_raw(seventeen);
275 /// let boxed_again = unsafe { Box::from_raw(raw) };
276 /// ```
277 #[unstable(feature = "box_raw", reason = "may be renamed")]
278 #[deprecated(since = "1.2.0", reason = "renamed to Box::into_raw")]
279 #[inline]
280 pub fn into_raw<T : ?Sized>(b: Box<T>) -> *mut T {
281 Box::into_raw(b)
282 }
283
284 #[stable(feature = "rust1", since = "1.0.0")]
285 impl<T: Default> Default for Box<T> {
286 #[stable(feature = "rust1", since = "1.0.0")]
287 fn default() -> Box<T> { box Default::default() }
288 }
289
290 #[stable(feature = "rust1", since = "1.0.0")]
291 impl<T> Default for Box<[T]> {
292 #[stable(feature = "rust1", since = "1.0.0")]
293 fn default() -> Box<[T]> { Box::<[T; 0]>::new([]) }
294 }
295
296 #[stable(feature = "rust1", since = "1.0.0")]
297 impl<T: Clone> Clone for Box<T> {
298 /// Returns a new box with a `clone()` of this box's contents.
299 ///
300 /// # Examples
301 ///
302 /// ```
303 /// let x = Box::new(5);
304 /// let y = x.clone();
305 /// ```
306 #[inline]
307 fn clone(&self) -> Box<T> { box {(**self).clone()} }
308 /// Copies `source`'s contents into `self` without creating a new allocation.
309 ///
310 /// # Examples
311 ///
312 /// ```
313 /// #![feature(box_raw)]
314 ///
315 /// let x = Box::new(5);
316 /// let mut y = Box::new(10);
317 ///
318 /// y.clone_from(&x);
319 ///
320 /// assert_eq!(*y, 5);
321 /// ```
322 #[inline]
323 fn clone_from(&mut self, source: &Box<T>) {
324 (**self).clone_from(&(**source));
325 }
326 }
327
328
329 #[stable(feature = "box_slice_clone", since = "1.3.0")]
330 impl Clone for Box<str> {
331 fn clone(&self) -> Self {
332 let len = self.len();
333 let buf = RawVec::with_capacity(len);
334 unsafe {
335 ptr::copy_nonoverlapping(self.as_ptr(), buf.ptr(), len);
336 mem::transmute(buf.into_box()) // bytes to str ~magic
337 }
338 }
339 }
340
341 #[stable(feature = "rust1", since = "1.0.0")]
342 impl<T: ?Sized + PartialEq> PartialEq for Box<T> {
343 #[inline]
344 fn eq(&self, other: &Box<T>) -> bool { PartialEq::eq(&**self, &**other) }
345 #[inline]
346 fn ne(&self, other: &Box<T>) -> bool { PartialEq::ne(&**self, &**other) }
347 }
348 #[stable(feature = "rust1", since = "1.0.0")]
349 impl<T: ?Sized + PartialOrd> PartialOrd for Box<T> {
350 #[inline]
351 fn partial_cmp(&self, other: &Box<T>) -> Option<Ordering> {
352 PartialOrd::partial_cmp(&**self, &**other)
353 }
354 #[inline]
355 fn lt(&self, other: &Box<T>) -> bool { PartialOrd::lt(&**self, &**other) }
356 #[inline]
357 fn le(&self, other: &Box<T>) -> bool { PartialOrd::le(&**self, &**other) }
358 #[inline]
359 fn ge(&self, other: &Box<T>) -> bool { PartialOrd::ge(&**self, &**other) }
360 #[inline]
361 fn gt(&self, other: &Box<T>) -> bool { PartialOrd::gt(&**self, &**other) }
362 }
363 #[stable(feature = "rust1", since = "1.0.0")]
364 impl<T: ?Sized + Ord> Ord for Box<T> {
365 #[inline]
366 fn cmp(&self, other: &Box<T>) -> Ordering {
367 Ord::cmp(&**self, &**other)
368 }
369 }
370 #[stable(feature = "rust1", since = "1.0.0")]
371 impl<T: ?Sized + Eq> Eq for Box<T> {}
372
373 #[stable(feature = "rust1", since = "1.0.0")]
374 impl<T: ?Sized + Hash> Hash for Box<T> {
375 fn hash<H: hash::Hasher>(&self, state: &mut H) {
376 (**self).hash(state);
377 }
378 }
379
380 impl Box<Any> {
381 #[inline]
382 #[stable(feature = "rust1", since = "1.0.0")]
383 /// Attempt to downcast the box to a concrete type.
384 pub fn downcast<T: Any>(self) -> Result<Box<T>, Box<Any>> {
385 if self.is::<T>() {
386 unsafe {
387 // Get the raw representation of the trait object
388 let raw = Box::into_raw(self);
389 let to: TraitObject =
390 mem::transmute::<*mut Any, TraitObject>(raw);
391
392 // Extract the data pointer
393 Ok(Box::from_raw(to.data as *mut T))
394 }
395 } else {
396 Err(self)
397 }
398 }
399 }
400
401 impl Box<Any + Send> {
402 #[inline]
403 #[stable(feature = "rust1", since = "1.0.0")]
404 /// Attempt to downcast the box to a concrete type.
405 pub fn downcast<T: Any>(self) -> Result<Box<T>, Box<Any + Send>> {
406 <Box<Any>>::downcast(self).map_err(|s| unsafe {
407 // reapply the Send marker
408 mem::transmute::<Box<Any>, Box<Any + Send>>(s)
409 })
410 }
411 }
412
413 #[stable(feature = "rust1", since = "1.0.0")]
414 impl<T: fmt::Display + ?Sized> fmt::Display for Box<T> {
415 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
416 fmt::Display::fmt(&**self, f)
417 }
418 }
419
420 #[stable(feature = "rust1", since = "1.0.0")]
421 impl<T: fmt::Debug + ?Sized> fmt::Debug for Box<T> {
422 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
423 fmt::Debug::fmt(&**self, f)
424 }
425 }
426
427 #[stable(feature = "rust1", since = "1.0.0")]
428 impl<T> fmt::Pointer for Box<T> {
429 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
430 // It's not possible to extract the inner Uniq directly from the Box,
431 // instead we cast it to a *const which aliases the Unique
432 let ptr: *const T = &**self;
433 fmt::Pointer::fmt(&ptr, f)
434 }
435 }
436
437 #[stable(feature = "rust1", since = "1.0.0")]
438 impl<T: ?Sized> Deref for Box<T> {
439 type Target = T;
440
441 fn deref(&self) -> &T { &**self }
442 }
443
444 #[stable(feature = "rust1", since = "1.0.0")]
445 impl<T: ?Sized> DerefMut for Box<T> {
446 fn deref_mut(&mut self) -> &mut T { &mut **self }
447 }
448
449 #[stable(feature = "rust1", since = "1.0.0")]
450 impl<I: Iterator + ?Sized> Iterator for Box<I> {
451 type Item = I::Item;
452 fn next(&mut self) -> Option<I::Item> { (**self).next() }
453 fn size_hint(&self) -> (usize, Option<usize>) { (**self).size_hint() }
454 }
455 #[stable(feature = "rust1", since = "1.0.0")]
456 impl<I: DoubleEndedIterator + ?Sized> DoubleEndedIterator for Box<I> {
457 fn next_back(&mut self) -> Option<I::Item> { (**self).next_back() }
458 }
459 #[stable(feature = "rust1", since = "1.0.0")]
460 impl<I: ExactSizeIterator + ?Sized> ExactSizeIterator for Box<I> {}
461
462
463 /// `FnBox` is a version of the `FnOnce` intended for use with boxed
464 /// closure objects. The idea is that where one would normally store a
465 /// `Box<FnOnce()>` in a data structure, you should use
466 /// `Box<FnBox()>`. The two traits behave essentially the same, except
467 /// that a `FnBox` closure can only be called if it is boxed. (Note
468 /// that `FnBox` may be deprecated in the future if `Box<FnOnce()>`
469 /// closures become directly usable.)
470 ///
471 /// ### Example
472 ///
473 /// Here is a snippet of code which creates a hashmap full of boxed
474 /// once closures and then removes them one by one, calling each
475 /// closure as it is removed. Note that the type of the closures
476 /// stored in the map is `Box<FnBox() -> i32>` and not `Box<FnOnce()
477 /// -> i32>`.
478 ///
479 /// ```
480 /// #![feature(fnbox)]
481 ///
482 /// use std::boxed::FnBox;
483 /// use std::collections::HashMap;
484 ///
485 /// fn make_map() -> HashMap<i32, Box<FnBox() -> i32>> {
486 /// let mut map: HashMap<i32, Box<FnBox() -> i32>> = HashMap::new();
487 /// map.insert(1, Box::new(|| 22));
488 /// map.insert(2, Box::new(|| 44));
489 /// map
490 /// }
491 ///
492 /// fn main() {
493 /// let mut map = make_map();
494 /// for i in &[1, 2] {
495 /// let f = map.remove(&i).unwrap();
496 /// assert_eq!(f(), i * 22);
497 /// }
498 /// }
499 /// ```
500 #[rustc_paren_sugar]
501 #[unstable(feature = "fnbox", reason = "Newly introduced")]
502 pub trait FnBox<A> {
503 type Output;
504
505 fn call_box(self: Box<Self>, args: A) -> Self::Output;
506 }
507
508 impl<A,F> FnBox<A> for F
509 where F: FnOnce<A>
510 {
511 type Output = F::Output;
512
513 fn call_box(self: Box<F>, args: A) -> F::Output {
514 self.call_once(args)
515 }
516 }
517
518 impl<'a,A,R> FnOnce<A> for Box<FnBox<A,Output=R>+'a> {
519 type Output = R;
520
521 extern "rust-call" fn call_once(self, args: A) -> R {
522 self.call_box(args)
523 }
524 }
525
526 impl<'a,A,R> FnOnce<A> for Box<FnBox<A,Output=R>+Send+'a> {
527 type Output = R;
528
529 extern "rust-call" fn call_once(self, args: A) -> R {
530 self.call_box(args)
531 }
532 }
533
534 impl<T: ?Sized+Unsize<U>, U: ?Sized> CoerceUnsized<Box<U>> for Box<T> {}
535
536 #[stable(feature = "box_slice_clone", since = "1.3.0")]
537 impl<T: Clone> Clone for Box<[T]> {
538 fn clone(&self) -> Self {
539 let mut new = BoxBuilder {
540 data: RawVec::with_capacity(self.len()),
541 len: 0
542 };
543
544 let mut target = new.data.ptr();
545
546 for item in self.iter() {
547 unsafe {
548 ptr::write(target, item.clone());
549 target = target.offset(1);
550 };
551
552 new.len += 1;
553 }
554
555 return unsafe { new.into_box() };
556
557 // Helper type for responding to panics correctly.
558 struct BoxBuilder<T> {
559 data: RawVec<T>,
560 len: usize,
561 }
562
563 impl<T> BoxBuilder<T> {
564 unsafe fn into_box(self) -> Box<[T]> {
565 let raw = ptr::read(&self.data);
566 mem::forget(self);
567 raw.into_box()
568 }
569 }
570
571 impl<T> Drop for BoxBuilder<T> {
572 fn drop(&mut self) {
573 let mut data = self.data.ptr();
574 let max = unsafe { data.offset(self.len as isize) };
575
576 while data != max {
577 unsafe {
578 ptr::read(data);
579 data = data.offset(1);
580 }
581 }
582 }
583 }
584 }
585 }
586