1 | //! The `Box<T>` type for heap allocation. |
2 | //! |
3 | //! [`Box<T>`], casually referred to as a 'box', provides the simplest form of |
4 | //! heap allocation in Rust. Boxes provide ownership for this allocation, and |
5 | //! drop their contents when they go out of scope. Boxes also ensure that they |
6 | //! never allocate more than `isize::MAX` bytes. |
7 | //! |
8 | //! # Examples |
9 | //! |
10 | //! Move a value from the stack to the heap by creating a [`Box`]: |
11 | //! |
12 | //! ``` |
13 | //! let val: u8 = 5; |
14 | //! let boxed: Box<u8> = Box::new(val); |
15 | //! ``` |
16 | //! |
17 | //! Move a value from a [`Box`] back to the stack by [dereferencing]: |
18 | //! |
19 | //! ``` |
20 | //! let boxed: Box<u8> = Box::new(5); |
21 | //! let val: u8 = *boxed; |
22 | //! ``` |
23 | //! |
24 | //! Creating a recursive data structure: |
25 | //! |
26 | //! ``` |
27 | //! #[derive(Debug)] |
28 | //! enum List<T> { |
29 | //! Cons(T, Box<List<T>>), |
30 | //! Nil, |
31 | //! } |
32 | //! |
33 | //! let list: List<i32> = List::Cons(1, Box::new(List::Cons(2, Box::new(List::Nil)))); |
34 | //! println!("{list:?}" ); |
35 | //! ``` |
36 | //! |
37 | //! This will print `Cons(1, Cons(2, Nil))`. |
38 | //! |
39 | //! Recursive structures must be boxed, because if the definition of `Cons` |
40 | //! looked like this: |
41 | //! |
42 | //! ```compile_fail,E0072 |
43 | //! # enum List<T> { |
44 | //! Cons(T, List<T>), |
45 | //! # } |
46 | //! ``` |
47 | //! |
48 | //! It wouldn't work. This is because the size of a `List` depends on how many |
49 | //! elements are in the list, and so we don't know how much memory to allocate |
50 | //! for a `Cons`. By introducing a [`Box<T>`], which has a defined size, we know how |
51 | //! big `Cons` needs to be. |
52 | //! |
53 | //! # Memory layout |
54 | //! |
55 | //! For non-zero-sized values, a [`Box`] will use the [`Global`] allocator for |
56 | //! its allocation. It is valid to convert both ways between a [`Box`] and a |
57 | //! raw pointer allocated with the [`Global`] allocator, given that the |
58 | //! [`Layout`] used with the allocator is correct for the type. More precisely, |
59 | //! a `value: *mut T` that has been allocated with the [`Global`] allocator |
60 | //! with `Layout::for_value(&*value)` may be converted into a box using |
61 | //! [`Box::<T>::from_raw(value)`]. Conversely, the memory backing a `value: *mut |
62 | //! T` obtained from [`Box::<T>::into_raw`] may be deallocated using the |
63 | //! [`Global`] allocator with [`Layout::for_value(&*value)`]. |
64 | //! |
65 | //! For zero-sized values, the `Box` pointer still has to be [valid] for reads |
66 | //! and writes and sufficiently aligned. In particular, casting any aligned |
67 | //! non-zero integer literal to a raw pointer produces a valid pointer, but a |
68 | //! pointer pointing into previously allocated memory that since got freed is |
69 | //! not valid. The recommended way to build a Box to a ZST if `Box::new` cannot |
70 | //! be used is to use [`ptr::NonNull::dangling`]. |
71 | //! |
72 | //! So long as `T: Sized`, a `Box<T>` is guaranteed to be represented |
73 | //! as a single pointer and is also ABI-compatible with C pointers |
74 | //! (i.e. the C type `T*`). This means that if you have extern "C" |
75 | //! Rust functions that will be called from C, you can define those |
76 | //! Rust functions using `Box<T>` types, and use `T*` as corresponding |
77 | //! type on the C side. As an example, consider this C header which |
78 | //! declares functions that create and destroy some kind of `Foo` |
79 | //! value: |
80 | //! |
81 | //! ```c |
82 | //! /* C header */ |
83 | //! |
84 | //! /* Returns ownership to the caller */ |
85 | //! struct Foo* foo_new(void); |
86 | //! |
87 | //! /* Takes ownership from the caller; no-op when invoked with null */ |
88 | //! void foo_delete(struct Foo*); |
89 | //! ``` |
90 | //! |
91 | //! These two functions might be implemented in Rust as follows. Here, the |
92 | //! `struct Foo*` type from C is translated to `Box<Foo>`, which captures |
93 | //! the ownership constraints. Note also that the nullable argument to |
94 | //! `foo_delete` is represented in Rust as `Option<Box<Foo>>`, since `Box<Foo>` |
95 | //! cannot be null. |
96 | //! |
97 | //! ``` |
98 | //! #[repr(C)] |
99 | //! pub struct Foo; |
100 | //! |
101 | //! #[no_mangle] |
102 | //! pub extern "C" fn foo_new() -> Box<Foo> { |
103 | //! Box::new(Foo) |
104 | //! } |
105 | //! |
106 | //! #[no_mangle] |
107 | //! pub extern "C" fn foo_delete(_: Option<Box<Foo>>) {} |
108 | //! ``` |
109 | //! |
110 | //! Even though `Box<T>` has the same representation and C ABI as a C pointer, |
111 | //! this does not mean that you can convert an arbitrary `T*` into a `Box<T>` |
112 | //! and expect things to work. `Box<T>` values will always be fully aligned, |
113 | //! non-null pointers. Moreover, the destructor for `Box<T>` will attempt to |
114 | //! free the value with the global allocator. In general, the best practice |
115 | //! is to only use `Box<T>` for pointers that originated from the global |
116 | //! allocator. |
117 | //! |
118 | //! **Important.** At least at present, you should avoid using |
119 | //! `Box<T>` types for functions that are defined in C but invoked |
120 | //! from Rust. In those cases, you should directly mirror the C types |
121 | //! as closely as possible. Using types like `Box<T>` where the C |
122 | //! definition is just using `T*` can lead to undefined behavior, as |
123 | //! described in [rust-lang/unsafe-code-guidelines#198][ucg#198]. |
124 | //! |
125 | //! # Considerations for unsafe code |
126 | //! |
127 | //! **Warning: This section is not normative and is subject to change, possibly |
128 | //! being relaxed in the future! It is a simplified summary of the rules |
129 | //! currently implemented in the compiler.** |
130 | //! |
131 | //! The aliasing rules for `Box<T>` are the same as for `&mut T`. `Box<T>` |
132 | //! asserts uniqueness over its content. Using raw pointers derived from a box |
133 | //! after that box has been mutated through, moved or borrowed as `&mut T` |
134 | //! is not allowed. For more guidance on working with box from unsafe code, see |
135 | //! [rust-lang/unsafe-code-guidelines#326][ucg#326]. |
136 | //! |
137 | //! |
138 | //! [ucg#198]: https://github.com/rust-lang/unsafe-code-guidelines/issues/198 |
139 | //! [ucg#326]: https://github.com/rust-lang/unsafe-code-guidelines/issues/326 |
140 | //! [dereferencing]: core::ops::Deref |
141 | //! [`Box::<T>::from_raw(value)`]: Box::from_raw |
142 | //! [`Global`]: crate::alloc::Global |
143 | //! [`Layout`]: crate::alloc::Layout |
144 | //! [`Layout::for_value(&*value)`]: crate::alloc::Layout::for_value |
145 | //! [valid]: ptr#safety |
146 | |
147 | use core::any::Any; |
148 | use core::borrow; |
149 | use core::cmp::Ordering; |
150 | use core::convert::{From, TryFrom}; |
151 | |
152 | // use core::error::Error; |
153 | use core::fmt; |
154 | use core::future::Future; |
155 | use core::hash::{Hash, Hasher}; |
156 | #[cfg (not(no_global_oom_handling))] |
157 | use core::iter::FromIterator; |
158 | use core::iter::{FusedIterator, Iterator}; |
159 | use core::marker::Unpin; |
160 | use core::mem; |
161 | use core::ops::{Deref, DerefMut}; |
162 | use core::pin::Pin; |
163 | use core::ptr::{self, NonNull}; |
164 | use core::task::{Context, Poll}; |
165 | |
166 | use super::alloc::{AllocError, Allocator, Global, Layout}; |
167 | use super::raw_vec::RawVec; |
168 | #[cfg (not(no_global_oom_handling))] |
169 | use super::vec::Vec; |
170 | #[cfg (not(no_global_oom_handling))] |
171 | use alloc_crate::alloc::handle_alloc_error; |
172 | |
173 | /// A pointer type for heap allocation. |
174 | /// |
175 | /// See the [module-level documentation](../../std/boxed/index.html) for more. |
176 | pub struct Box<T: ?Sized, A: Allocator = Global>(NonNull<T>, A); |
177 | |
178 | // Safety: Box owns both T and A, so sending is safe if |
179 | // sending is safe for T and A. |
180 | unsafe impl<T: ?Sized, A: Allocator> Send for Box<T, A> |
181 | where |
182 | T: Send, |
183 | A: Send, |
184 | { |
185 | } |
186 | |
187 | // Safety: Box owns both T and A, so sharing is safe if |
188 | // sharing is safe for T and A. |
189 | unsafe impl<T: ?Sized, A: Allocator> Sync for Box<T, A> |
190 | where |
191 | T: Sync, |
192 | A: Sync, |
193 | { |
194 | } |
195 | |
196 | impl<T> Box<T> { |
197 | /// Allocates memory on the heap and then places `x` into it. |
198 | /// |
199 | /// This doesn't actually allocate if `T` is zero-sized. |
200 | /// |
201 | /// # Examples |
202 | /// |
203 | /// ``` |
204 | /// let five = Box::new(5); |
205 | /// ``` |
206 | #[cfg (all(not(no_global_oom_handling)))] |
207 | #[inline (always)] |
208 | #[must_use ] |
209 | pub fn new(x: T) -> Self { |
210 | Self::new_in(x, Global) |
211 | } |
212 | |
213 | /// Constructs a new box with uninitialized contents. |
214 | /// |
215 | /// # Examples |
216 | /// |
217 | /// ``` |
218 | /// #![feature(new_uninit)] |
219 | /// |
220 | /// let mut five = Box::<u32>::new_uninit(); |
221 | /// |
222 | /// let five = unsafe { |
223 | /// // Deferred initialization: |
224 | /// five.as_mut_ptr().write(5); |
225 | /// |
226 | /// five.assume_init() |
227 | /// }; |
228 | /// |
229 | /// assert_eq!(*five, 5) |
230 | /// ``` |
231 | #[cfg (not(no_global_oom_handling))] |
232 | #[must_use ] |
233 | #[inline (always)] |
234 | pub fn new_uninit() -> Box<mem::MaybeUninit<T>> { |
235 | Self::new_uninit_in(Global) |
236 | } |
237 | |
238 | /// Constructs a new `Box` with uninitialized contents, with the memory |
239 | /// being filled with `0` bytes. |
240 | /// |
241 | /// See [`MaybeUninit::zeroed`][zeroed] for examples of correct and incorrect usage |
242 | /// of this method. |
243 | /// |
244 | /// # Examples |
245 | /// |
246 | /// ``` |
247 | /// #![feature(new_uninit)] |
248 | /// |
249 | /// let zero = Box::<u32>::new_zeroed(); |
250 | /// let zero = unsafe { zero.assume_init() }; |
251 | /// |
252 | /// assert_eq!(*zero, 0) |
253 | /// ``` |
254 | /// |
255 | /// [zeroed]: mem::MaybeUninit::zeroed |
256 | #[cfg (not(no_global_oom_handling))] |
257 | #[must_use ] |
258 | #[inline (always)] |
259 | pub fn new_zeroed() -> Box<mem::MaybeUninit<T>> { |
260 | Self::new_zeroed_in(Global) |
261 | } |
262 | |
263 | /// Constructs a new `Pin<Box<T>>`. If `T` does not implement [`Unpin`], then |
264 | /// `x` will be pinned in memory and unable to be moved. |
265 | /// |
266 | /// Constructing and pinning of the `Box` can also be done in two steps: `Box::pin(x)` |
267 | /// does the same as <code>[Box::into_pin]\([Box::new]\(x))</code>. Consider using |
268 | /// [`into_pin`](Box::into_pin) if you already have a `Box<T>`, or if you want to |
269 | /// construct a (pinned) `Box` in a different way than with [`Box::new`]. |
270 | #[cfg (not(no_global_oom_handling))] |
271 | #[must_use ] |
272 | #[inline (always)] |
273 | pub fn pin(x: T) -> Pin<Box<T>> { |
274 | Box::new(x).into() |
275 | } |
276 | |
277 | /// Allocates memory on the heap then places `x` into it, |
278 | /// returning an error if the allocation fails |
279 | /// |
280 | /// This doesn't actually allocate if `T` is zero-sized. |
281 | /// |
282 | /// # Examples |
283 | /// |
284 | /// ``` |
285 | /// #![feature(allocator_api)] |
286 | /// |
287 | /// let five = Box::try_new(5)?; |
288 | /// # Ok::<(), std::alloc::AllocError>(()) |
289 | /// ``` |
290 | #[inline (always)] |
291 | pub fn try_new(x: T) -> Result<Self, AllocError> { |
292 | Self::try_new_in(x, Global) |
293 | } |
294 | |
295 | /// Constructs a new box with uninitialized contents on the heap, |
296 | /// returning an error if the allocation fails |
297 | /// |
298 | /// # Examples |
299 | /// |
300 | /// ``` |
301 | /// #![feature(allocator_api, new_uninit)] |
302 | /// |
303 | /// let mut five = Box::<u32>::try_new_uninit()?; |
304 | /// |
305 | /// let five = unsafe { |
306 | /// // Deferred initialization: |
307 | /// five.as_mut_ptr().write(5); |
308 | /// |
309 | /// five.assume_init() |
310 | /// }; |
311 | /// |
312 | /// assert_eq!(*five, 5); |
313 | /// # Ok::<(), std::alloc::AllocError>(()) |
314 | /// ``` |
315 | #[inline (always)] |
316 | pub fn try_new_uninit() -> Result<Box<mem::MaybeUninit<T>>, AllocError> { |
317 | Box::try_new_uninit_in(Global) |
318 | } |
319 | |
320 | /// Constructs a new `Box` with uninitialized contents, with the memory |
321 | /// being filled with `0` bytes on the heap |
322 | /// |
323 | /// See [`MaybeUninit::zeroed`][zeroed] for examples of correct and incorrect usage |
324 | /// of this method. |
325 | /// |
326 | /// # Examples |
327 | /// |
328 | /// ``` |
329 | /// #![feature(allocator_api, new_uninit)] |
330 | /// |
331 | /// let zero = Box::<u32>::try_new_zeroed()?; |
332 | /// let zero = unsafe { zero.assume_init() }; |
333 | /// |
334 | /// assert_eq!(*zero, 0); |
335 | /// # Ok::<(), std::alloc::AllocError>(()) |
336 | /// ``` |
337 | /// |
338 | /// [zeroed]: mem::MaybeUninit::zeroed |
339 | #[inline (always)] |
340 | pub fn try_new_zeroed() -> Result<Box<mem::MaybeUninit<T>>, AllocError> { |
341 | Box::try_new_zeroed_in(Global) |
342 | } |
343 | } |
344 | |
345 | impl<T, A: Allocator> Box<T, A> { |
346 | /// Allocates memory in the given allocator then places `x` into it. |
347 | /// |
348 | /// This doesn't actually allocate if `T` is zero-sized. |
349 | /// |
350 | /// # Examples |
351 | /// |
352 | /// ``` |
353 | /// #![feature(allocator_api)] |
354 | /// |
355 | /// use std::alloc::System; |
356 | /// |
357 | /// let five = Box::new_in(5, System); |
358 | /// ``` |
359 | #[cfg (not(no_global_oom_handling))] |
360 | #[must_use ] |
361 | #[inline (always)] |
362 | pub fn new_in(x: T, alloc: A) -> Self |
363 | where |
364 | A: Allocator, |
365 | { |
366 | let mut boxed = Self::new_uninit_in(alloc); |
367 | unsafe { |
368 | boxed.as_mut_ptr().write(x); |
369 | boxed.assume_init() |
370 | } |
371 | } |
372 | |
373 | /// Allocates memory in the given allocator then places `x` into it, |
374 | /// returning an error if the allocation fails |
375 | /// |
376 | /// This doesn't actually allocate if `T` is zero-sized. |
377 | /// |
378 | /// # Examples |
379 | /// |
380 | /// ``` |
381 | /// #![feature(allocator_api)] |
382 | /// |
383 | /// use std::alloc::System; |
384 | /// |
385 | /// let five = Box::try_new_in(5, System)?; |
386 | /// # Ok::<(), std::alloc::AllocError>(()) |
387 | /// ``` |
388 | #[inline (always)] |
389 | pub fn try_new_in(x: T, alloc: A) -> Result<Self, AllocError> |
390 | where |
391 | A: Allocator, |
392 | { |
393 | let mut boxed = Self::try_new_uninit_in(alloc)?; |
394 | unsafe { |
395 | boxed.as_mut_ptr().write(x); |
396 | Ok(boxed.assume_init()) |
397 | } |
398 | } |
399 | |
400 | /// Constructs a new box with uninitialized contents in the provided allocator. |
401 | /// |
402 | /// # Examples |
403 | /// |
404 | /// ``` |
405 | /// #![feature(allocator_api, new_uninit)] |
406 | /// |
407 | /// use std::alloc::System; |
408 | /// |
409 | /// let mut five = Box::<u32, _>::new_uninit_in(System); |
410 | /// |
411 | /// let five = unsafe { |
412 | /// // Deferred initialization: |
413 | /// five.as_mut_ptr().write(5); |
414 | /// |
415 | /// five.assume_init() |
416 | /// }; |
417 | /// |
418 | /// assert_eq!(*five, 5) |
419 | /// ``` |
420 | #[cfg (not(no_global_oom_handling))] |
421 | #[must_use ] |
422 | // #[unstable(feature = "new_uninit", issue = "63291")] |
423 | #[inline (always)] |
424 | pub fn new_uninit_in(alloc: A) -> Box<mem::MaybeUninit<T>, A> |
425 | where |
426 | A: Allocator, |
427 | { |
428 | let layout = Layout::new::<mem::MaybeUninit<T>>(); |
429 | // NOTE: Prefer match over unwrap_or_else since closure sometimes not inlineable. |
430 | // That would make code size bigger. |
431 | match Box::try_new_uninit_in(alloc) { |
432 | Ok(m) => m, |
433 | Err(_) => handle_alloc_error(layout), |
434 | } |
435 | } |
436 | |
437 | /// Constructs a new box with uninitialized contents in the provided allocator, |
438 | /// returning an error if the allocation fails |
439 | /// |
440 | /// # Examples |
441 | /// |
442 | /// ``` |
443 | /// #![feature(allocator_api, new_uninit)] |
444 | /// |
445 | /// use std::alloc::System; |
446 | /// |
447 | /// let mut five = Box::<u32, _>::try_new_uninit_in(System)?; |
448 | /// |
449 | /// let five = unsafe { |
450 | /// // Deferred initialization: |
451 | /// five.as_mut_ptr().write(5); |
452 | /// |
453 | /// five.assume_init() |
454 | /// }; |
455 | /// |
456 | /// assert_eq!(*five, 5); |
457 | /// # Ok::<(), std::alloc::AllocError>(()) |
458 | /// ``` |
459 | #[inline (always)] |
460 | pub fn try_new_uninit_in(alloc: A) -> Result<Box<mem::MaybeUninit<T>, A>, AllocError> |
461 | where |
462 | A: Allocator, |
463 | { |
464 | let layout = Layout::new::<mem::MaybeUninit<T>>(); |
465 | let ptr = alloc.allocate(layout)?.cast(); |
466 | unsafe { Ok(Box::from_raw_in(ptr.as_ptr(), alloc)) } |
467 | } |
468 | |
469 | /// Constructs a new `Box` with uninitialized contents, with the memory |
470 | /// being filled with `0` bytes in the provided allocator. |
471 | /// |
472 | /// See [`MaybeUninit::zeroed`][zeroed] for examples of correct and incorrect usage |
473 | /// of this method. |
474 | /// |
475 | /// # Examples |
476 | /// |
477 | /// ``` |
478 | /// #![feature(allocator_api, new_uninit)] |
479 | /// |
480 | /// use std::alloc::System; |
481 | /// |
482 | /// let zero = Box::<u32, _>::new_zeroed_in(System); |
483 | /// let zero = unsafe { zero.assume_init() }; |
484 | /// |
485 | /// assert_eq!(*zero, 0) |
486 | /// ``` |
487 | /// |
488 | /// [zeroed]: mem::MaybeUninit::zeroed |
489 | #[cfg (not(no_global_oom_handling))] |
490 | // #[unstable(feature = "new_uninit", issue = "63291")] |
491 | #[must_use ] |
492 | #[inline (always)] |
493 | pub fn new_zeroed_in(alloc: A) -> Box<mem::MaybeUninit<T>, A> |
494 | where |
495 | A: Allocator, |
496 | { |
497 | let layout = Layout::new::<mem::MaybeUninit<T>>(); |
498 | // NOTE: Prefer match over unwrap_or_else since closure sometimes not inlineable. |
499 | // That would make code size bigger. |
500 | match Box::try_new_zeroed_in(alloc) { |
501 | Ok(m) => m, |
502 | Err(_) => handle_alloc_error(layout), |
503 | } |
504 | } |
505 | |
506 | /// Constructs a new `Box` with uninitialized contents, with the memory |
507 | /// being filled with `0` bytes in the provided allocator, |
508 | /// returning an error if the allocation fails, |
509 | /// |
510 | /// See [`MaybeUninit::zeroed`][zeroed] for examples of correct and incorrect usage |
511 | /// of this method. |
512 | /// |
513 | /// # Examples |
514 | /// |
515 | /// ``` |
516 | /// #![feature(allocator_api, new_uninit)] |
517 | /// |
518 | /// use std::alloc::System; |
519 | /// |
520 | /// let zero = Box::<u32, _>::try_new_zeroed_in(System)?; |
521 | /// let zero = unsafe { zero.assume_init() }; |
522 | /// |
523 | /// assert_eq!(*zero, 0); |
524 | /// # Ok::<(), std::alloc::AllocError>(()) |
525 | /// ``` |
526 | /// |
527 | /// [zeroed]: mem::MaybeUninit::zeroed |
528 | #[inline (always)] |
529 | pub fn try_new_zeroed_in(alloc: A) -> Result<Box<mem::MaybeUninit<T>, A>, AllocError> |
530 | where |
531 | A: Allocator, |
532 | { |
533 | let layout = Layout::new::<mem::MaybeUninit<T>>(); |
534 | let ptr = alloc.allocate_zeroed(layout)?.cast(); |
535 | unsafe { Ok(Box::from_raw_in(ptr.as_ptr(), alloc)) } |
536 | } |
537 | |
538 | /// Constructs a new `Pin<Box<T, A>>`. If `T` does not implement [`Unpin`], then |
539 | /// `x` will be pinned in memory and unable to be moved. |
540 | /// |
541 | /// Constructing and pinning of the `Box` can also be done in two steps: `Box::pin_in(x, alloc)` |
542 | /// does the same as <code>[Box::into_pin]\([Box::new_in]\(x, alloc))</code>. Consider using |
543 | /// [`into_pin`](Box::into_pin) if you already have a `Box<T, A>`, or if you want to |
544 | /// construct a (pinned) `Box` in a different way than with [`Box::new_in`]. |
545 | #[cfg (not(no_global_oom_handling))] |
546 | #[must_use ] |
547 | #[inline (always)] |
548 | pub fn pin_in(x: T, alloc: A) -> Pin<Self> |
549 | where |
550 | A: 'static + Allocator, |
551 | { |
552 | Self::into_pin(Self::new_in(x, alloc)) |
553 | } |
554 | |
555 | /// Converts a `Box<T>` into a `Box<[T]>` |
556 | /// |
557 | /// This conversion does not allocate on the heap and happens in place. |
558 | #[inline (always)] |
559 | pub fn into_boxed_slice(boxed: Self) -> Box<[T], A> { |
560 | let (raw, alloc) = Box::into_raw_with_allocator(boxed); |
561 | unsafe { Box::from_raw_in(raw as *mut [T; 1], alloc) } |
562 | } |
563 | |
564 | /// Consumes the `Box`, returning the wrapped value. |
565 | /// |
566 | /// # Examples |
567 | /// |
568 | /// ``` |
569 | /// #![feature(box_into_inner)] |
570 | /// |
571 | /// let c = Box::new(5); |
572 | /// |
573 | /// assert_eq!(Box::into_inner(c), 5); |
574 | /// ``` |
575 | #[inline (always)] |
576 | pub fn into_inner(boxed: Self) -> T { |
577 | let ptr = boxed.0; |
578 | let unboxed = unsafe { ptr.as_ptr().read() }; |
579 | unsafe { boxed.1.deallocate(ptr.cast(), Layout::new::<T>()) }; |
580 | unboxed |
581 | } |
582 | } |
583 | |
584 | impl<T> Box<[T]> { |
585 | /// Constructs a new boxed slice with uninitialized contents. |
586 | /// |
587 | /// # Examples |
588 | /// |
589 | /// ``` |
590 | /// #![feature(new_uninit)] |
591 | /// |
592 | /// let mut values = Box::<[u32]>::new_uninit_slice(3); |
593 | /// |
594 | /// let values = unsafe { |
595 | /// // Deferred initialization: |
596 | /// values[0].as_mut_ptr().write(1); |
597 | /// values[1].as_mut_ptr().write(2); |
598 | /// values[2].as_mut_ptr().write(3); |
599 | /// |
600 | /// values.assume_init() |
601 | /// }; |
602 | /// |
603 | /// assert_eq!(*values, [1, 2, 3]) |
604 | /// ``` |
605 | #[cfg (not(no_global_oom_handling))] |
606 | #[must_use ] |
607 | #[inline (always)] |
608 | pub fn new_uninit_slice(len: usize) -> Box<[mem::MaybeUninit<T>]> { |
609 | unsafe { RawVec::with_capacity(len).into_box(len) } |
610 | } |
611 | |
612 | /// Constructs a new boxed slice with uninitialized contents, with the memory |
613 | /// being filled with `0` bytes. |
614 | /// |
615 | /// See [`MaybeUninit::zeroed`][zeroed] for examples of correct and incorrect usage |
616 | /// of this method. |
617 | /// |
618 | /// # Examples |
619 | /// |
620 | /// ``` |
621 | /// #![feature(new_uninit)] |
622 | /// |
623 | /// let values = Box::<[u32]>::new_zeroed_slice(3); |
624 | /// let values = unsafe { values.assume_init() }; |
625 | /// |
626 | /// assert_eq!(*values, [0, 0, 0]) |
627 | /// ``` |
628 | /// |
629 | /// [zeroed]: mem::MaybeUninit::zeroed |
630 | #[cfg (not(no_global_oom_handling))] |
631 | #[must_use ] |
632 | #[inline (always)] |
633 | pub fn new_zeroed_slice(len: usize) -> Box<[mem::MaybeUninit<T>]> { |
634 | unsafe { RawVec::with_capacity_zeroed(len).into_box(len) } |
635 | } |
636 | |
637 | /// Constructs a new boxed slice with uninitialized contents. Returns an error if |
638 | /// the allocation fails |
639 | /// |
640 | /// # Examples |
641 | /// |
642 | /// ``` |
643 | /// #![feature(allocator_api, new_uninit)] |
644 | /// |
645 | /// let mut values = Box::<[u32]>::try_new_uninit_slice(3)?; |
646 | /// let values = unsafe { |
647 | /// // Deferred initialization: |
648 | /// values[0].as_mut_ptr().write(1); |
649 | /// values[1].as_mut_ptr().write(2); |
650 | /// values[2].as_mut_ptr().write(3); |
651 | /// values.assume_init() |
652 | /// }; |
653 | /// |
654 | /// assert_eq!(*values, [1, 2, 3]); |
655 | /// # Ok::<(), std::alloc::AllocError>(()) |
656 | /// ``` |
657 | #[inline (always)] |
658 | pub fn try_new_uninit_slice(len: usize) -> Result<Box<[mem::MaybeUninit<T>]>, AllocError> { |
659 | unsafe { |
660 | let layout = match Layout::array::<mem::MaybeUninit<T>>(len) { |
661 | Ok(l) => l, |
662 | Err(_) => return Err(AllocError), |
663 | }; |
664 | let ptr = Global.allocate(layout)?; |
665 | Ok(RawVec::from_raw_parts_in(ptr.as_ptr() as *mut _, len, Global).into_box(len)) |
666 | } |
667 | } |
668 | |
669 | /// Constructs a new boxed slice with uninitialized contents, with the memory |
670 | /// being filled with `0` bytes. Returns an error if the allocation fails |
671 | /// |
672 | /// See [`MaybeUninit::zeroed`][zeroed] for examples of correct and incorrect usage |
673 | /// of this method. |
674 | /// |
675 | /// # Examples |
676 | /// |
677 | /// ``` |
678 | /// #![feature(allocator_api, new_uninit)] |
679 | /// |
680 | /// let values = Box::<[u32]>::try_new_zeroed_slice(3)?; |
681 | /// let values = unsafe { values.assume_init() }; |
682 | /// |
683 | /// assert_eq!(*values, [0, 0, 0]); |
684 | /// # Ok::<(), std::alloc::AllocError>(()) |
685 | /// ``` |
686 | /// |
687 | /// [zeroed]: mem::MaybeUninit::zeroed |
688 | #[inline (always)] |
689 | pub fn try_new_zeroed_slice(len: usize) -> Result<Box<[mem::MaybeUninit<T>]>, AllocError> { |
690 | unsafe { |
691 | let layout = match Layout::array::<mem::MaybeUninit<T>>(len) { |
692 | Ok(l) => l, |
693 | Err(_) => return Err(AllocError), |
694 | }; |
695 | let ptr = Global.allocate_zeroed(layout)?; |
696 | Ok(RawVec::from_raw_parts_in(ptr.as_ptr() as *mut _, len, Global).into_box(len)) |
697 | } |
698 | } |
699 | } |
700 | |
701 | impl<T, A: Allocator> Box<[T], A> { |
702 | /// Constructs a new boxed slice with uninitialized contents in the provided allocator. |
703 | /// |
704 | /// # Examples |
705 | /// |
706 | /// ``` |
707 | /// #![feature(allocator_api, new_uninit)] |
708 | /// |
709 | /// use std::alloc::System; |
710 | /// |
711 | /// let mut values = Box::<[u32], _>::new_uninit_slice_in(3, System); |
712 | /// |
713 | /// let values = unsafe { |
714 | /// // Deferred initialization: |
715 | /// values[0].as_mut_ptr().write(1); |
716 | /// values[1].as_mut_ptr().write(2); |
717 | /// values[2].as_mut_ptr().write(3); |
718 | /// |
719 | /// values.assume_init() |
720 | /// }; |
721 | /// |
722 | /// assert_eq!(*values, [1, 2, 3]) |
723 | /// ``` |
724 | #[cfg (not(no_global_oom_handling))] |
725 | #[must_use ] |
726 | #[inline (always)] |
727 | pub fn new_uninit_slice_in(len: usize, alloc: A) -> Box<[mem::MaybeUninit<T>], A> { |
728 | unsafe { RawVec::with_capacity_in(len, alloc).into_box(len) } |
729 | } |
730 | |
731 | /// Constructs a new boxed slice with uninitialized contents in the provided allocator, |
732 | /// with the memory being filled with `0` bytes. |
733 | /// |
734 | /// See [`MaybeUninit::zeroed`][zeroed] for examples of correct and incorrect usage |
735 | /// of this method. |
736 | /// |
737 | /// # Examples |
738 | /// |
739 | /// ``` |
740 | /// #![feature(allocator_api, new_uninit)] |
741 | /// |
742 | /// use std::alloc::System; |
743 | /// |
744 | /// let values = Box::<[u32], _>::new_zeroed_slice_in(3, System); |
745 | /// let values = unsafe { values.assume_init() }; |
746 | /// |
747 | /// assert_eq!(*values, [0, 0, 0]) |
748 | /// ``` |
749 | /// |
750 | /// [zeroed]: mem::MaybeUninit::zeroed |
751 | #[cfg (not(no_global_oom_handling))] |
752 | #[must_use ] |
753 | #[inline (always)] |
754 | pub fn new_zeroed_slice_in(len: usize, alloc: A) -> Box<[mem::MaybeUninit<T>], A> { |
755 | unsafe { RawVec::with_capacity_zeroed_in(len, alloc).into_box(len) } |
756 | } |
757 | |
758 | pub fn into_vec(self) -> Vec<T, A> |
759 | where |
760 | A: Allocator, |
761 | { |
762 | unsafe { |
763 | let len = self.len(); |
764 | let (b, alloc) = Box::into_raw_with_allocator(self); |
765 | Vec::from_raw_parts_in(b as *mut T, len, len, alloc) |
766 | } |
767 | } |
768 | } |
769 | |
770 | impl<T, A: Allocator> Box<mem::MaybeUninit<T>, A> { |
771 | /// Converts to `Box<T, A>`. |
772 | /// |
773 | /// # Safety |
774 | /// |
775 | /// As with [`MaybeUninit::assume_init`], |
776 | /// it is up to the caller to guarantee that the value |
777 | /// really is in an initialized state. |
778 | /// Calling this when the content is not yet fully initialized |
779 | /// causes immediate undefined behavior. |
780 | /// |
781 | /// [`MaybeUninit::assume_init`]: mem::MaybeUninit::assume_init |
782 | /// |
783 | /// # Examples |
784 | /// |
785 | /// ``` |
786 | /// #![feature(new_uninit)] |
787 | /// |
788 | /// let mut five = Box::<u32>::new_uninit(); |
789 | /// |
790 | /// let five: Box<u32> = unsafe { |
791 | /// // Deferred initialization: |
792 | /// five.as_mut_ptr().write(5); |
793 | /// |
794 | /// five.assume_init() |
795 | /// }; |
796 | /// |
797 | /// assert_eq!(*five, 5) |
798 | /// ``` |
799 | #[inline (always)] |
800 | pub unsafe fn assume_init(self) -> Box<T, A> { |
801 | let (raw, alloc) = Box::into_raw_with_allocator(self); |
802 | unsafe { Box::from_raw_in(raw as *mut T, alloc) } |
803 | } |
804 | |
805 | /// Writes the value and converts to `Box<T, A>`. |
806 | /// |
807 | /// This method converts the box similarly to [`Box::assume_init`] but |
808 | /// writes `value` into it before conversion thus guaranteeing safety. |
809 | /// In some scenarios use of this method may improve performance because |
810 | /// the compiler may be able to optimize copying from stack. |
811 | /// |
812 | /// # Examples |
813 | /// |
814 | /// ``` |
815 | /// #![feature(new_uninit)] |
816 | /// |
817 | /// let big_box = Box::<[usize; 1024]>::new_uninit(); |
818 | /// |
819 | /// let mut array = [0; 1024]; |
820 | /// for (i, place) in array.iter_mut().enumerate() { |
821 | /// *place = i; |
822 | /// } |
823 | /// |
824 | /// // The optimizer may be able to elide this copy, so previous code writes |
825 | /// // to heap directly. |
826 | /// let big_box = Box::write(big_box, array); |
827 | /// |
828 | /// for (i, x) in big_box.iter().enumerate() { |
829 | /// assert_eq!(*x, i); |
830 | /// } |
831 | /// ``` |
832 | #[inline (always)] |
833 | pub fn write(mut boxed: Self, value: T) -> Box<T, A> { |
834 | unsafe { |
835 | (*boxed).write(value); |
836 | boxed.assume_init() |
837 | } |
838 | } |
839 | } |
840 | |
841 | impl<T, A: Allocator> Box<[mem::MaybeUninit<T>], A> { |
842 | /// Converts to `Box<[T], A>`. |
843 | /// |
844 | /// # Safety |
845 | /// |
846 | /// As with [`MaybeUninit::assume_init`], |
847 | /// it is up to the caller to guarantee that the values |
848 | /// really are in an initialized state. |
849 | /// Calling this when the content is not yet fully initialized |
850 | /// causes immediate undefined behavior. |
851 | /// |
852 | /// [`MaybeUninit::assume_init`]: mem::MaybeUninit::assume_init |
853 | /// |
854 | /// # Examples |
855 | /// |
856 | /// ``` |
857 | /// #![feature(new_uninit)] |
858 | /// |
859 | /// let mut values = Box::<[u32]>::new_uninit_slice(3); |
860 | /// |
861 | /// let values = unsafe { |
862 | /// // Deferred initialization: |
863 | /// values[0].as_mut_ptr().write(1); |
864 | /// values[1].as_mut_ptr().write(2); |
865 | /// values[2].as_mut_ptr().write(3); |
866 | /// |
867 | /// values.assume_init() |
868 | /// }; |
869 | /// |
870 | /// assert_eq!(*values, [1, 2, 3]) |
871 | /// ``` |
872 | #[inline (always)] |
873 | pub unsafe fn assume_init(self) -> Box<[T], A> { |
874 | let (raw, alloc) = Box::into_raw_with_allocator(self); |
875 | unsafe { Box::from_raw_in(raw as *mut [T], alloc) } |
876 | } |
877 | } |
878 | |
879 | impl<T: ?Sized> Box<T> { |
880 | /// Constructs a box from a raw pointer. |
881 | /// |
882 | /// After calling this function, the raw pointer is owned by the |
883 | /// resulting `Box`. Specifically, the `Box` destructor will call |
884 | /// the destructor of `T` and free the allocated memory. For this |
885 | /// to be safe, the memory must have been allocated in accordance |
886 | /// with the [memory layout] used by `Box` . |
887 | /// |
888 | /// # Safety |
889 | /// |
890 | /// This function is unsafe because improper use may lead to |
891 | /// memory problems. For example, a double-free may occur if the |
892 | /// function is called twice on the same raw pointer. |
893 | /// |
894 | /// The safety conditions are described in the [memory layout] section. |
895 | /// |
896 | /// # Examples |
897 | /// |
898 | /// Recreate a `Box` which was previously converted to a raw pointer |
899 | /// using [`Box::into_raw`]: |
900 | /// ``` |
901 | /// let x = Box::new(5); |
902 | /// let ptr = Box::into_raw(x); |
903 | /// let x = unsafe { Box::from_raw(ptr) }; |
904 | /// ``` |
905 | /// Manually create a `Box` from scratch by using the global allocator: |
906 | /// ``` |
907 | /// use std::alloc::{alloc, Layout}; |
908 | /// |
909 | /// unsafe { |
910 | /// let ptr = alloc(Layout::new::<i32>()) as *mut i32; |
911 | /// // In general .write is required to avoid attempting to destruct |
912 | /// // the (uninitialized) previous contents of `ptr`, though for this |
913 | /// // simple example `*ptr = 5` would have worked as well. |
914 | /// ptr.write(5); |
915 | /// let x = Box::from_raw(ptr); |
916 | /// } |
917 | /// ``` |
918 | /// |
919 | /// [memory layout]: self#memory-layout |
920 | /// [`Layout`]: crate::Layout |
921 | #[must_use = "call `drop(from_raw(ptr))` if you intend to drop the `Box`" ] |
922 | #[inline (always)] |
923 | pub unsafe fn from_raw(raw: *mut T) -> Self { |
924 | unsafe { Self::from_raw_in(raw, Global) } |
925 | } |
926 | } |
927 | |
928 | impl<T: ?Sized, A: Allocator> Box<T, A> { |
929 | /// Constructs a box from a raw pointer in the given allocator. |
930 | /// |
931 | /// After calling this function, the raw pointer is owned by the |
932 | /// resulting `Box`. Specifically, the `Box` destructor will call |
933 | /// the destructor of `T` and free the allocated memory. For this |
934 | /// to be safe, the memory must have been allocated in accordance |
935 | /// with the [memory layout] used by `Box` . |
936 | /// |
937 | /// # Safety |
938 | /// |
939 | /// This function is unsafe because improper use may lead to |
940 | /// memory problems. For example, a double-free may occur if the |
941 | /// function is called twice on the same raw pointer. |
942 | /// |
943 | /// |
944 | /// # Examples |
945 | /// |
946 | /// Recreate a `Box` which was previously converted to a raw pointer |
947 | /// using [`Box::into_raw_with_allocator`]: |
948 | /// ``` |
949 | /// use std::alloc::System; |
950 | /// # use allocator_api2::boxed::Box; |
951 | /// |
952 | /// let x = Box::new_in(5, System); |
953 | /// let (ptr, alloc) = Box::into_raw_with_allocator(x); |
954 | /// let x = unsafe { Box::from_raw_in(ptr, alloc) }; |
955 | /// ``` |
956 | /// Manually create a `Box` from scratch by using the system allocator: |
957 | /// ``` |
958 | /// use allocator_api2::alloc::{Allocator, Layout, System}; |
959 | /// # use allocator_api2::boxed::Box; |
960 | /// |
961 | /// unsafe { |
962 | /// let ptr = System.allocate(Layout::new::<i32>())?.as_ptr().cast::<i32>(); |
963 | /// // In general .write is required to avoid attempting to destruct |
964 | /// // the (uninitialized) previous contents of `ptr`, though for this |
965 | /// // simple example `*ptr = 5` would have worked as well. |
966 | /// ptr.write(5); |
967 | /// let x = Box::from_raw_in(ptr, System); |
968 | /// } |
969 | /// # Ok::<(), allocator_api2::alloc::AllocError>(()) |
970 | /// ``` |
971 | /// |
972 | /// [memory layout]: self#memory-layout |
973 | /// [`Layout`]: crate::Layout |
974 | #[inline (always)] |
975 | pub const unsafe fn from_raw_in(raw: *mut T, alloc: A) -> Self { |
976 | Box(unsafe { NonNull::new_unchecked(raw) }, alloc) |
977 | } |
978 | |
979 | /// Consumes the `Box`, returning a wrapped raw pointer. |
980 | /// |
981 | /// The pointer will be properly aligned and non-null. |
982 | /// |
983 | /// After calling this function, the caller is responsible for the |
984 | /// memory previously managed by the `Box`. In particular, the |
985 | /// caller should properly destroy `T` and release the memory, taking |
986 | /// into account the [memory layout] used by `Box`. The easiest way to |
987 | /// do this is to convert the raw pointer back into a `Box` with the |
988 | /// [`Box::from_raw`] function, allowing the `Box` destructor to perform |
989 | /// the cleanup. |
990 | /// |
991 | /// Note: this is an associated function, which means that you have |
992 | /// to call it as `Box::into_raw(b)` instead of `b.into_raw()`. This |
993 | /// is so that there is no conflict with a method on the inner type. |
994 | /// |
995 | /// # Examples |
996 | /// Converting the raw pointer back into a `Box` with [`Box::from_raw`] |
997 | /// for automatic cleanup: |
998 | /// ``` |
999 | /// let x = Box::new(String::from("Hello" )); |
1000 | /// let ptr = Box::into_raw(x); |
1001 | /// let x = unsafe { Box::from_raw(ptr) }; |
1002 | /// ``` |
1003 | /// Manual cleanup by explicitly running the destructor and deallocating |
1004 | /// the memory: |
1005 | /// ``` |
1006 | /// use std::alloc::{dealloc, Layout}; |
1007 | /// use std::ptr; |
1008 | /// |
1009 | /// let x = Box::new(String::from("Hello" )); |
1010 | /// let p = Box::into_raw(x); |
1011 | /// unsafe { |
1012 | /// ptr::drop_in_place(p); |
1013 | /// dealloc(p as *mut u8, Layout::new::<String>()); |
1014 | /// } |
1015 | /// ``` |
1016 | /// |
1017 | /// [memory layout]: self#memory-layout |
1018 | #[inline (always)] |
1019 | pub fn into_raw(b: Self) -> *mut T { |
1020 | Self::into_raw_with_allocator(b).0 |
1021 | } |
1022 | |
1023 | /// Consumes the `Box`, returning a wrapped raw pointer and the allocator. |
1024 | /// |
1025 | /// The pointer will be properly aligned and non-null. |
1026 | /// |
1027 | /// After calling this function, the caller is responsible for the |
1028 | /// memory previously managed by the `Box`. In particular, the |
1029 | /// caller should properly destroy `T` and release the memory, taking |
1030 | /// into account the [memory layout] used by `Box`. The easiest way to |
1031 | /// do this is to convert the raw pointer back into a `Box` with the |
1032 | /// [`Box::from_raw_in`] function, allowing the `Box` destructor to perform |
1033 | /// the cleanup. |
1034 | /// |
1035 | /// Note: this is an associated function, which means that you have |
1036 | /// to call it as `Box::into_raw_with_allocator(b)` instead of `b.into_raw_with_allocator()`. This |
1037 | /// is so that there is no conflict with a method on the inner type. |
1038 | /// |
1039 | /// # Examples |
1040 | /// Converting the raw pointer back into a `Box` with [`Box::from_raw_in`] |
1041 | /// for automatic cleanup: |
1042 | /// ``` |
1043 | /// #![feature(allocator_api)] |
1044 | /// |
1045 | /// use std::alloc::System; |
1046 | /// |
1047 | /// let x = Box::new_in(String::from("Hello" ), System); |
1048 | /// let (ptr, alloc) = Box::into_raw_with_allocator(x); |
1049 | /// let x = unsafe { Box::from_raw_in(ptr, alloc) }; |
1050 | /// ``` |
1051 | /// Manual cleanup by explicitly running the destructor and deallocating |
1052 | /// the memory: |
1053 | /// ``` |
1054 | /// #![feature(allocator_api)] |
1055 | /// |
1056 | /// use std::alloc::{Allocator, Layout, System}; |
1057 | /// use std::ptr::{self, NonNull}; |
1058 | /// |
1059 | /// let x = Box::new_in(String::from("Hello" ), System); |
1060 | /// let (ptr, alloc) = Box::into_raw_with_allocator(x); |
1061 | /// unsafe { |
1062 | /// ptr::drop_in_place(ptr); |
1063 | /// let non_null = NonNull::new_unchecked(ptr); |
1064 | /// alloc.deallocate(non_null.cast(), Layout::new::<String>()); |
1065 | /// } |
1066 | /// ``` |
1067 | /// |
1068 | /// [memory layout]: self#memory-layout |
1069 | #[inline (always)] |
1070 | pub fn into_raw_with_allocator(b: Self) -> (*mut T, A) { |
1071 | let (leaked, alloc) = Box::into_non_null(b); |
1072 | (leaked.as_ptr(), alloc) |
1073 | } |
1074 | |
1075 | #[inline (always)] |
1076 | pub fn into_non_null(b: Self) -> (NonNull<T>, A) { |
1077 | // Box is recognized as a "unique pointer" by Stacked Borrows, but internally it is a |
1078 | // raw pointer for the type system. Turning it directly into a raw pointer would not be |
1079 | // recognized as "releasing" the unique pointer to permit aliased raw accesses, |
1080 | // so all raw pointer methods have to go through `Box::leak`. Turning *that* to a raw pointer |
1081 | // behaves correctly. |
1082 | let alloc = unsafe { ptr::read(&b.1) }; |
1083 | (NonNull::from(Box::leak(b)), alloc) |
1084 | } |
1085 | |
1086 | /// Returns a reference to the underlying allocator. |
1087 | /// |
1088 | /// Note: this is an associated function, which means that you have |
1089 | /// to call it as `Box::allocator(&b)` instead of `b.allocator()`. This |
1090 | /// is so that there is no conflict with a method on the inner type. |
1091 | #[inline (always)] |
1092 | pub const fn allocator(b: &Self) -> &A { |
1093 | &b.1 |
1094 | } |
1095 | |
1096 | /// Consumes and leaks the `Box`, returning a mutable reference, |
1097 | /// `&'a mut T`. Note that the type `T` must outlive the chosen lifetime |
1098 | /// `'a`. If the type has only static references, or none at all, then this |
1099 | /// may be chosen to be `'static`. |
1100 | /// |
1101 | /// This function is mainly useful for data that lives for the remainder of |
1102 | /// the program's life. Dropping the returned reference will cause a memory |
1103 | /// leak. If this is not acceptable, the reference should first be wrapped |
1104 | /// with the [`Box::from_raw`] function producing a `Box`. This `Box` can |
1105 | /// then be dropped which will properly destroy `T` and release the |
1106 | /// allocated memory. |
1107 | /// |
1108 | /// Note: this is an associated function, which means that you have |
1109 | /// to call it as `Box::leak(b)` instead of `b.leak()`. This |
1110 | /// is so that there is no conflict with a method on the inner type. |
1111 | /// |
1112 | /// # Examples |
1113 | /// |
1114 | /// Simple usage: |
1115 | /// |
1116 | /// ``` |
1117 | /// let x = Box::new(41); |
1118 | /// let static_ref: &'static mut usize = Box::leak(x); |
1119 | /// *static_ref += 1; |
1120 | /// assert_eq!(*static_ref, 42); |
1121 | /// ``` |
1122 | /// |
1123 | /// Unsized data: |
1124 | /// |
1125 | /// ``` |
1126 | /// let x = vec![1, 2, 3].into_boxed_slice(); |
1127 | /// let static_ref = Box::leak(x); |
1128 | /// static_ref[0] = 4; |
1129 | /// assert_eq!(*static_ref, [4, 2, 3]); |
1130 | /// ``` |
1131 | #[inline (always)] |
1132 | fn leak<'a>(b: Self) -> &'a mut T |
1133 | where |
1134 | A: 'a, |
1135 | { |
1136 | unsafe { &mut *mem::ManuallyDrop::new(b).0.as_ptr() } |
1137 | } |
1138 | |
1139 | /// Converts a `Box<T>` into a `Pin<Box<T>>`. If `T` does not implement [`Unpin`], then |
1140 | /// `*boxed` will be pinned in memory and unable to be moved. |
1141 | /// |
1142 | /// This conversion does not allocate on the heap and happens in place. |
1143 | /// |
1144 | /// This is also available via [`From`]. |
1145 | /// |
1146 | /// Constructing and pinning a `Box` with <code>Box::into_pin([Box::new]\(x))</code> |
1147 | /// can also be written more concisely using <code>[Box::pin]\(x)</code>. |
1148 | /// This `into_pin` method is useful if you already have a `Box<T>`, or you are |
1149 | /// constructing a (pinned) `Box` in a different way than with [`Box::new`]. |
1150 | /// |
1151 | /// # Notes |
1152 | /// |
1153 | /// It's not recommended that crates add an impl like `From<Box<T>> for Pin<T>`, |
1154 | /// as it'll introduce an ambiguity when calling `Pin::from`. |
1155 | /// A demonstration of such a poor impl is shown below. |
1156 | /// |
1157 | /// ```compile_fail |
1158 | /// # use std::pin::Pin; |
1159 | /// struct Foo; // A type defined in this crate. |
1160 | /// impl From<Box<()>> for Pin<Foo> { |
1161 | /// fn from(_: Box<()>) -> Pin<Foo> { |
1162 | /// Pin::new(Foo) |
1163 | /// } |
1164 | /// } |
1165 | /// |
1166 | /// let foo = Box::new(()); |
1167 | /// let bar = Pin::from(foo); |
1168 | /// ``` |
1169 | #[inline (always)] |
1170 | pub fn into_pin(boxed: Self) -> Pin<Self> |
1171 | where |
1172 | A: 'static, |
1173 | { |
1174 | // It's not possible to move or replace the insides of a `Pin<Box<T>>` |
1175 | // when `T: !Unpin`, so it's safe to pin it directly without any |
1176 | // additional requirements. |
1177 | unsafe { Pin::new_unchecked(boxed) } |
1178 | } |
1179 | } |
1180 | |
1181 | impl<T: ?Sized, A: Allocator> Drop for Box<T, A> { |
1182 | #[inline (always)] |
1183 | fn drop(&mut self) { |
1184 | let layout: Layout = Layout::for_value::<T>(&**self); |
1185 | unsafe { |
1186 | ptr::drop_in_place(self.0.as_mut()); |
1187 | self.1.deallocate(self.0.cast(), layout); |
1188 | } |
1189 | } |
1190 | } |
1191 | |
1192 | #[cfg (not(no_global_oom_handling))] |
1193 | impl<T: Default> Default for Box<T> { |
1194 | /// Creates a `Box<T>`, with the `Default` value for T. |
1195 | #[inline (always)] |
1196 | fn default() -> Self { |
1197 | Box::new(T::default()) |
1198 | } |
1199 | } |
1200 | |
1201 | impl<T, A: Allocator + Default> Default for Box<[T], A> { |
1202 | #[inline (always)] |
1203 | fn default() -> Self { |
1204 | let ptr: NonNull<[T]> = NonNull::<[T; 0]>::dangling(); |
1205 | Box(ptr, A::default()) |
1206 | } |
1207 | } |
1208 | |
1209 | impl<A: Allocator + Default> Default for Box<str, A> { |
1210 | #[inline (always)] |
1211 | fn default() -> Self { |
1212 | // SAFETY: This is the same as `Unique::cast<U>` but with an unsized `U = str`. |
1213 | let ptr: NonNull<str> = unsafe { |
1214 | let bytes: NonNull<[u8]> = NonNull::<[u8; 0]>::dangling(); |
1215 | NonNull::new_unchecked(bytes.as_ptr() as *mut str) |
1216 | }; |
1217 | Box(ptr, A::default()) |
1218 | } |
1219 | } |
1220 | |
1221 | #[cfg (not(no_global_oom_handling))] |
1222 | impl<T: Clone, A: Allocator + Clone> Clone for Box<T, A> { |
1223 | /// Returns a new box with a `clone()` of this box's contents. |
1224 | /// |
1225 | /// # Examples |
1226 | /// |
1227 | /// ``` |
1228 | /// let x = Box::new(5); |
1229 | /// let y = x.clone(); |
1230 | /// |
1231 | /// // The value is the same |
1232 | /// assert_eq!(x, y); |
1233 | /// |
1234 | /// // But they are unique objects |
1235 | /// assert_ne!(&*x as *const i32, &*y as *const i32); |
1236 | /// ``` |
1237 | #[inline (always)] |
1238 | fn clone(&self) -> Self { |
1239 | // Pre-allocate memory to allow writing the cloned value directly. |
1240 | let mut boxed = Self::new_uninit_in(self.1.clone()); |
1241 | unsafe { |
1242 | boxed.write((**self).clone()); |
1243 | boxed.assume_init() |
1244 | } |
1245 | } |
1246 | |
1247 | /// Copies `source`'s contents into `self` without creating a new allocation. |
1248 | /// |
1249 | /// # Examples |
1250 | /// |
1251 | /// ``` |
1252 | /// let x = Box::new(5); |
1253 | /// let mut y = Box::new(10); |
1254 | /// let yp: *const i32 = &*y; |
1255 | /// |
1256 | /// y.clone_from(&x); |
1257 | /// |
1258 | /// // The value is the same |
1259 | /// assert_eq!(x, y); |
1260 | /// |
1261 | /// // And no allocation occurred |
1262 | /// assert_eq!(yp, &*y); |
1263 | /// ``` |
1264 | #[inline (always)] |
1265 | fn clone_from(&mut self, source: &Self) { |
1266 | (**self).clone_from(&(**source)); |
1267 | } |
1268 | } |
1269 | |
1270 | #[cfg (not(no_global_oom_handling))] |
1271 | impl Clone for Box<str> { |
1272 | #[inline (always)] |
1273 | fn clone(&self) -> Self { |
1274 | // this makes a copy of the data |
1275 | let buf: Box<[u8]> = self.as_bytes().into(); |
1276 | unsafe { Box::from_raw(Box::into_raw(buf) as *mut str) } |
1277 | } |
1278 | } |
1279 | |
1280 | impl<T: ?Sized + PartialEq, A: Allocator> PartialEq for Box<T, A> { |
1281 | #[inline (always)] |
1282 | fn eq(&self, other: &Self) -> bool { |
1283 | PartialEq::eq(&**self, &**other) |
1284 | } |
1285 | #[inline (always)] |
1286 | fn ne(&self, other: &Self) -> bool { |
1287 | PartialEq::ne(&**self, &**other) |
1288 | } |
1289 | } |
1290 | |
1291 | impl<T: ?Sized + PartialOrd, A: Allocator> PartialOrd for Box<T, A> { |
1292 | #[inline (always)] |
1293 | fn partial_cmp(&self, other: &Self) -> Option<Ordering> { |
1294 | PartialOrd::partial_cmp(&**self, &**other) |
1295 | } |
1296 | #[inline (always)] |
1297 | fn lt(&self, other: &Self) -> bool { |
1298 | PartialOrd::lt(&**self, &**other) |
1299 | } |
1300 | #[inline (always)] |
1301 | fn le(&self, other: &Self) -> bool { |
1302 | PartialOrd::le(&**self, &**other) |
1303 | } |
1304 | #[inline (always)] |
1305 | fn ge(&self, other: &Self) -> bool { |
1306 | PartialOrd::ge(&**self, &**other) |
1307 | } |
1308 | #[inline (always)] |
1309 | fn gt(&self, other: &Self) -> bool { |
1310 | PartialOrd::gt(&**self, &**other) |
1311 | } |
1312 | } |
1313 | |
1314 | impl<T: ?Sized + Ord, A: Allocator> Ord for Box<T, A> { |
1315 | #[inline (always)] |
1316 | fn cmp(&self, other: &Self) -> Ordering { |
1317 | Ord::cmp(&**self, &**other) |
1318 | } |
1319 | } |
1320 | |
1321 | impl<T: ?Sized + Eq, A: Allocator> Eq for Box<T, A> {} |
1322 | |
1323 | impl<T: ?Sized + Hash, A: Allocator> Hash for Box<T, A> { |
1324 | #[inline (always)] |
1325 | fn hash<H: Hasher>(&self, state: &mut H) { |
1326 | (**self).hash(state); |
1327 | } |
1328 | } |
1329 | |
1330 | impl<T: ?Sized + Hasher, A: Allocator> Hasher for Box<T, A> { |
1331 | #[inline (always)] |
1332 | fn finish(&self) -> u64 { |
1333 | (**self).finish() |
1334 | } |
1335 | #[inline (always)] |
1336 | fn write(&mut self, bytes: &[u8]) { |
1337 | (**self).write(bytes) |
1338 | } |
1339 | #[inline (always)] |
1340 | fn write_u8(&mut self, i: u8) { |
1341 | (**self).write_u8(i) |
1342 | } |
1343 | #[inline (always)] |
1344 | fn write_u16(&mut self, i: u16) { |
1345 | (**self).write_u16(i) |
1346 | } |
1347 | #[inline (always)] |
1348 | fn write_u32(&mut self, i: u32) { |
1349 | (**self).write_u32(i) |
1350 | } |
1351 | #[inline (always)] |
1352 | fn write_u64(&mut self, i: u64) { |
1353 | (**self).write_u64(i) |
1354 | } |
1355 | #[inline (always)] |
1356 | fn write_u128(&mut self, i: u128) { |
1357 | (**self).write_u128(i) |
1358 | } |
1359 | #[inline (always)] |
1360 | fn write_usize(&mut self, i: usize) { |
1361 | (**self).write_usize(i) |
1362 | } |
1363 | #[inline (always)] |
1364 | fn write_i8(&mut self, i: i8) { |
1365 | (**self).write_i8(i) |
1366 | } |
1367 | #[inline (always)] |
1368 | fn write_i16(&mut self, i: i16) { |
1369 | (**self).write_i16(i) |
1370 | } |
1371 | #[inline (always)] |
1372 | fn write_i32(&mut self, i: i32) { |
1373 | (**self).write_i32(i) |
1374 | } |
1375 | #[inline (always)] |
1376 | fn write_i64(&mut self, i: i64) { |
1377 | (**self).write_i64(i) |
1378 | } |
1379 | #[inline (always)] |
1380 | fn write_i128(&mut self, i: i128) { |
1381 | (**self).write_i128(i) |
1382 | } |
1383 | #[inline (always)] |
1384 | fn write_isize(&mut self, i: isize) { |
1385 | (**self).write_isize(i) |
1386 | } |
1387 | } |
1388 | |
1389 | #[cfg (not(no_global_oom_handling))] |
1390 | impl<T> From<T> for Box<T> { |
1391 | /// Converts a `T` into a `Box<T>` |
1392 | /// |
1393 | /// The conversion allocates on the heap and moves `t` |
1394 | /// from the stack into it. |
1395 | /// |
1396 | /// # Examples |
1397 | /// |
1398 | /// ```rust |
1399 | /// let x = 5; |
1400 | /// let boxed = Box::new(5); |
1401 | /// |
1402 | /// assert_eq!(Box::from(x), boxed); |
1403 | /// ``` |
1404 | #[inline (always)] |
1405 | fn from(t: T) -> Self { |
1406 | Box::new(t) |
1407 | } |
1408 | } |
1409 | |
1410 | impl<T: ?Sized, A: Allocator> From<Box<T, A>> for Pin<Box<T, A>> |
1411 | where |
1412 | A: 'static, |
1413 | { |
1414 | /// Converts a `Box<T>` into a `Pin<Box<T>>`. If `T` does not implement [`Unpin`], then |
1415 | /// `*boxed` will be pinned in memory and unable to be moved. |
1416 | /// |
1417 | /// This conversion does not allocate on the heap and happens in place. |
1418 | /// |
1419 | /// This is also available via [`Box::into_pin`]. |
1420 | /// |
1421 | /// Constructing and pinning a `Box` with <code><Pin<Box\<T>>>::from([Box::new]\(x))</code> |
1422 | /// can also be written more concisely using <code>[Box::pin]\(x)</code>. |
1423 | /// This `From` implementation is useful if you already have a `Box<T>`, or you are |
1424 | /// constructing a (pinned) `Box` in a different way than with [`Box::new`]. |
1425 | #[inline (always)] |
1426 | fn from(boxed: Box<T, A>) -> Self { |
1427 | Box::into_pin(boxed) |
1428 | } |
1429 | } |
1430 | |
1431 | #[cfg (not(no_global_oom_handling))] |
1432 | impl<T: Copy, A: Allocator + Default> From<&[T]> for Box<[T], A> { |
1433 | /// Converts a `&[T]` into a `Box<[T]>` |
1434 | /// |
1435 | /// This conversion allocates on the heap |
1436 | /// and performs a copy of `slice` and its contents. |
1437 | /// |
1438 | /// # Examples |
1439 | /// ```rust |
1440 | /// // create a &[u8] which will be used to create a Box<[u8]> |
1441 | /// let slice: &[u8] = &[104, 101, 108, 108, 111]; |
1442 | /// let boxed_slice: Box<[u8]> = Box::from(slice); |
1443 | /// |
1444 | /// println!("{boxed_slice:?}" ); |
1445 | /// ``` |
1446 | #[inline (always)] |
1447 | fn from(slice: &[T]) -> Box<[T], A> { |
1448 | let len: usize = slice.len(); |
1449 | let buf: RawVec = RawVec::with_capacity_in(capacity:len, A::default()); |
1450 | unsafe { |
1451 | ptr::copy_nonoverlapping(src:slice.as_ptr(), dst:buf.ptr(), count:len); |
1452 | buf.into_box(slice.len()).assume_init() |
1453 | } |
1454 | } |
1455 | } |
1456 | |
1457 | #[cfg (not(no_global_oom_handling))] |
1458 | impl<A: Allocator + Default> From<&str> for Box<str, A> { |
1459 | /// Converts a `&str` into a `Box<str>` |
1460 | /// |
1461 | /// This conversion allocates on the heap |
1462 | /// and performs a copy of `s`. |
1463 | /// |
1464 | /// # Examples |
1465 | /// |
1466 | /// ```rust |
1467 | /// let boxed: Box<str> = Box::from("hello" ); |
1468 | /// println!("{boxed}" ); |
1469 | /// ``` |
1470 | #[inline (always)] |
1471 | fn from(s: &str) -> Box<str, A> { |
1472 | let (raw: *mut [u8], alloc: A) = Box::into_raw_with_allocator(Box::<[u8], A>::from(s.as_bytes())); |
1473 | unsafe { Box::from_raw_in(raw as *mut str, alloc) } |
1474 | } |
1475 | } |
1476 | |
1477 | impl<A: Allocator> From<Box<str, A>> for Box<[u8], A> { |
1478 | /// Converts a `Box<str>` into a `Box<[u8]>` |
1479 | /// |
1480 | /// This conversion does not allocate on the heap and happens in place. |
1481 | /// |
1482 | /// # Examples |
1483 | /// ```rust |
1484 | /// // create a Box<str> which will be used to create a Box<[u8]> |
1485 | /// let boxed: Box<str> = Box::from("hello" ); |
1486 | /// let boxed_str: Box<[u8]> = Box::from(boxed); |
1487 | /// |
1488 | /// // create a &[u8] which will be used to create a Box<[u8]> |
1489 | /// let slice: &[u8] = &[104, 101, 108, 108, 111]; |
1490 | /// let boxed_slice = Box::from(slice); |
1491 | /// |
1492 | /// assert_eq!(boxed_slice, boxed_str); |
1493 | /// ``` |
1494 | #[inline (always)] |
1495 | fn from(s: Box<str, A>) -> Self { |
1496 | let (raw: *mut str, alloc: A) = Box::into_raw_with_allocator(s); |
1497 | unsafe { Box::from_raw_in(raw as *mut [u8], alloc) } |
1498 | } |
1499 | } |
1500 | |
1501 | impl<T, A: Allocator, const N: usize> Box<[T; N], A> { |
1502 | #[inline (always)] |
1503 | pub fn slice(b: Self) -> Box<[T], A> { |
1504 | let (ptr: *mut [T; N], alloc: A) = Box::into_raw_with_allocator(b); |
1505 | unsafe { Box::from_raw_in(raw:ptr, alloc) } |
1506 | } |
1507 | |
1508 | pub fn into_vec(self) -> Vec<T, A> |
1509 | where |
1510 | A: Allocator, |
1511 | { |
1512 | unsafe { |
1513 | let (b: *mut [T; N], alloc: A) = Box::into_raw_with_allocator(self); |
1514 | Vec::from_raw_parts_in(ptr:b as *mut T, N, N, alloc) |
1515 | } |
1516 | } |
1517 | } |
1518 | |
1519 | #[cfg (not(no_global_oom_handling))] |
1520 | impl<T, const N: usize> From<[T; N]> for Box<[T]> { |
1521 | /// Converts a `[T; N]` into a `Box<[T]>` |
1522 | /// |
1523 | /// This conversion moves the array to newly heap-allocated memory. |
1524 | /// |
1525 | /// # Examples |
1526 | /// |
1527 | /// ```rust |
1528 | /// let boxed: Box<[u8]> = Box::from([4, 2]); |
1529 | /// println!("{boxed:?}" ); |
1530 | /// ``` |
1531 | #[inline (always)] |
1532 | fn from(array: [T; N]) -> Box<[T]> { |
1533 | Box::slice(Box::new(array)) |
1534 | } |
1535 | } |
1536 | |
1537 | impl<T, A: Allocator, const N: usize> TryFrom<Box<[T], A>> for Box<[T; N], A> { |
1538 | type Error = Box<[T], A>; |
1539 | |
1540 | /// Attempts to convert a `Box<[T]>` into a `Box<[T; N]>`. |
1541 | /// |
1542 | /// The conversion occurs in-place and does not require a |
1543 | /// new memory allocation. |
1544 | /// |
1545 | /// # Errors |
1546 | /// |
1547 | /// Returns the old `Box<[T]>` in the `Err` variant if |
1548 | /// `boxed_slice.len()` does not equal `N`. |
1549 | #[inline (always)] |
1550 | fn try_from(boxed_slice: Box<[T], A>) -> Result<Self, Self::Error> { |
1551 | if boxed_slice.len() == N { |
1552 | let (ptr: *mut [T], alloc: A) = Box::into_raw_with_allocator(boxed_slice); |
1553 | Ok(unsafe { Box::from_raw_in(raw:ptr as *mut [T; N], alloc) }) |
1554 | } else { |
1555 | Err(boxed_slice) |
1556 | } |
1557 | } |
1558 | } |
1559 | |
1560 | impl<A: Allocator> Box<dyn Any, A> { |
1561 | /// Attempt to downcast the box to a concrete type. |
1562 | /// |
1563 | /// # Examples |
1564 | /// |
1565 | /// ``` |
1566 | /// use std::any::Any; |
1567 | /// |
1568 | /// fn print_if_string(value: Box<dyn Any>) { |
1569 | /// if let Ok(string) = value.downcast::<String>() { |
1570 | /// println!("String ({}): {}" , string.len(), string); |
1571 | /// } |
1572 | /// } |
1573 | /// |
1574 | /// let my_string = "Hello World" .to_string(); |
1575 | /// print_if_string(Box::new(my_string)); |
1576 | /// print_if_string(Box::new(0i8)); |
1577 | /// ``` |
1578 | #[inline (always)] |
1579 | pub fn downcast<T: Any>(self) -> Result<Box<T, A>, Self> { |
1580 | if self.is::<T>() { |
1581 | unsafe { Ok(self.downcast_unchecked::<T>()) } |
1582 | } else { |
1583 | Err(self) |
1584 | } |
1585 | } |
1586 | |
1587 | /// Downcasts the box to a concrete type. |
1588 | /// |
1589 | /// For a safe alternative see [`downcast`]. |
1590 | /// |
1591 | /// # Examples |
1592 | /// |
1593 | /// ``` |
1594 | /// #![feature(downcast_unchecked)] |
1595 | /// |
1596 | /// use std::any::Any; |
1597 | /// |
1598 | /// let x: Box<dyn Any> = Box::new(1_usize); |
1599 | /// |
1600 | /// unsafe { |
1601 | /// assert_eq!(*x.downcast_unchecked::<usize>(), 1); |
1602 | /// } |
1603 | /// ``` |
1604 | /// |
1605 | /// # Safety |
1606 | /// |
1607 | /// The contained value must be of type `T`. Calling this method |
1608 | /// with the incorrect type is *undefined behavior*. |
1609 | /// |
1610 | /// [`downcast`]: Self::downcast |
1611 | #[inline (always)] |
1612 | pub unsafe fn downcast_unchecked<T: Any>(self) -> Box<T, A> { |
1613 | debug_assert!(self.is::<T>()); |
1614 | unsafe { |
1615 | let (raw, alloc): (*mut dyn Any, _) = Box::into_raw_with_allocator(self); |
1616 | Box::from_raw_in(raw as *mut T, alloc) |
1617 | } |
1618 | } |
1619 | } |
1620 | |
1621 | impl<A: Allocator> Box<dyn Any + Send, A> { |
1622 | /// Attempt to downcast the box to a concrete type. |
1623 | /// |
1624 | /// # Examples |
1625 | /// |
1626 | /// ``` |
1627 | /// use std::any::Any; |
1628 | /// |
1629 | /// fn print_if_string(value: Box<dyn Any + Send>) { |
1630 | /// if let Ok(string) = value.downcast::<String>() { |
1631 | /// println!("String ({}): {}" , string.len(), string); |
1632 | /// } |
1633 | /// } |
1634 | /// |
1635 | /// let my_string = "Hello World" .to_string(); |
1636 | /// print_if_string(Box::new(my_string)); |
1637 | /// print_if_string(Box::new(0i8)); |
1638 | /// ``` |
1639 | #[inline (always)] |
1640 | pub fn downcast<T: Any>(self) -> Result<Box<T, A>, Self> { |
1641 | if self.is::<T>() { |
1642 | unsafe { Ok(self.downcast_unchecked::<T>()) } |
1643 | } else { |
1644 | Err(self) |
1645 | } |
1646 | } |
1647 | |
1648 | /// Downcasts the box to a concrete type. |
1649 | /// |
1650 | /// For a safe alternative see [`downcast`]. |
1651 | /// |
1652 | /// # Examples |
1653 | /// |
1654 | /// ``` |
1655 | /// #![feature(downcast_unchecked)] |
1656 | /// |
1657 | /// use std::any::Any; |
1658 | /// |
1659 | /// let x: Box<dyn Any + Send> = Box::new(1_usize); |
1660 | /// |
1661 | /// unsafe { |
1662 | /// assert_eq!(*x.downcast_unchecked::<usize>(), 1); |
1663 | /// } |
1664 | /// ``` |
1665 | /// |
1666 | /// # Safety |
1667 | /// |
1668 | /// The contained value must be of type `T`. Calling this method |
1669 | /// with the incorrect type is *undefined behavior*. |
1670 | /// |
1671 | /// [`downcast`]: Self::downcast |
1672 | #[inline (always)] |
1673 | pub unsafe fn downcast_unchecked<T: Any>(self) -> Box<T, A> { |
1674 | debug_assert!(self.is::<T>()); |
1675 | unsafe { |
1676 | let (raw, alloc): (*mut (dyn Any + Send), _) = Box::into_raw_with_allocator(self); |
1677 | Box::from_raw_in(raw as *mut T, alloc) |
1678 | } |
1679 | } |
1680 | } |
1681 | |
1682 | impl<A: Allocator> Box<dyn Any + Send + Sync, A> { |
1683 | /// Attempt to downcast the box to a concrete type. |
1684 | /// |
1685 | /// # Examples |
1686 | /// |
1687 | /// ``` |
1688 | /// use std::any::Any; |
1689 | /// |
1690 | /// fn print_if_string(value: Box<dyn Any + Send + Sync>) { |
1691 | /// if let Ok(string) = value.downcast::<String>() { |
1692 | /// println!("String ({}): {}" , string.len(), string); |
1693 | /// } |
1694 | /// } |
1695 | /// |
1696 | /// let my_string = "Hello World" .to_string(); |
1697 | /// print_if_string(Box::new(my_string)); |
1698 | /// print_if_string(Box::new(0i8)); |
1699 | /// ``` |
1700 | #[inline (always)] |
1701 | pub fn downcast<T: Any>(self) -> Result<Box<T, A>, Self> { |
1702 | if self.is::<T>() { |
1703 | unsafe { Ok(self.downcast_unchecked::<T>()) } |
1704 | } else { |
1705 | Err(self) |
1706 | } |
1707 | } |
1708 | |
1709 | /// Downcasts the box to a concrete type. |
1710 | /// |
1711 | /// For a safe alternative see [`downcast`]. |
1712 | /// |
1713 | /// # Examples |
1714 | /// |
1715 | /// ``` |
1716 | /// #![feature(downcast_unchecked)] |
1717 | /// |
1718 | /// use std::any::Any; |
1719 | /// |
1720 | /// let x: Box<dyn Any + Send + Sync> = Box::new(1_usize); |
1721 | /// |
1722 | /// unsafe { |
1723 | /// assert_eq!(*x.downcast_unchecked::<usize>(), 1); |
1724 | /// } |
1725 | /// ``` |
1726 | /// |
1727 | /// # Safety |
1728 | /// |
1729 | /// The contained value must be of type `T`. Calling this method |
1730 | /// with the incorrect type is *undefined behavior*. |
1731 | /// |
1732 | /// [`downcast`]: Self::downcast |
1733 | #[inline (always)] |
1734 | pub unsafe fn downcast_unchecked<T: Any>(self) -> Box<T, A> { |
1735 | debug_assert!(self.is::<T>()); |
1736 | unsafe { |
1737 | let (raw, alloc): (*mut (dyn Any + Send + Sync), _) = |
1738 | Box::into_raw_with_allocator(self); |
1739 | Box::from_raw_in(raw as *mut T, alloc) |
1740 | } |
1741 | } |
1742 | } |
1743 | |
1744 | impl<T: fmt::Display + ?Sized, A: Allocator> fmt::Display for Box<T, A> { |
1745 | #[inline (always)] |
1746 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { |
1747 | fmt::Display::fmt(&**self, f) |
1748 | } |
1749 | } |
1750 | |
1751 | impl<T: fmt::Debug + ?Sized, A: Allocator> fmt::Debug for Box<T, A> { |
1752 | #[inline (always)] |
1753 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { |
1754 | fmt::Debug::fmt(&**self, f) |
1755 | } |
1756 | } |
1757 | |
1758 | impl<T: ?Sized, A: Allocator> fmt::Pointer for Box<T, A> { |
1759 | #[inline (always)] |
1760 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { |
1761 | // It's not possible to extract the inner Uniq directly from the Box, |
1762 | // instead we cast it to a *const which aliases the Unique |
1763 | let ptr: *const T = &**self; |
1764 | fmt::Pointer::fmt(&ptr, f) |
1765 | } |
1766 | } |
1767 | |
1768 | impl<T: ?Sized, A: Allocator> Deref for Box<T, A> { |
1769 | type Target = T; |
1770 | |
1771 | #[inline (always)] |
1772 | fn deref(&self) -> &T { |
1773 | unsafe { self.0.as_ref() } |
1774 | } |
1775 | } |
1776 | |
1777 | impl<T: ?Sized, A: Allocator> DerefMut for Box<T, A> { |
1778 | #[inline (always)] |
1779 | fn deref_mut(&mut self) -> &mut T { |
1780 | unsafe { self.0.as_mut() } |
1781 | } |
1782 | } |
1783 | |
1784 | impl<I: Iterator + ?Sized, A: Allocator> Iterator for Box<I, A> { |
1785 | type Item = I::Item; |
1786 | |
1787 | #[inline (always)] |
1788 | fn next(&mut self) -> Option<I::Item> { |
1789 | (**self).next() |
1790 | } |
1791 | |
1792 | #[inline (always)] |
1793 | fn size_hint(&self) -> (usize, Option<usize>) { |
1794 | (**self).size_hint() |
1795 | } |
1796 | |
1797 | #[inline (always)] |
1798 | fn nth(&mut self, n: usize) -> Option<I::Item> { |
1799 | (**self).nth(n) |
1800 | } |
1801 | |
1802 | #[inline (always)] |
1803 | fn last(self) -> Option<I::Item> { |
1804 | BoxIter::last(self) |
1805 | } |
1806 | } |
1807 | |
1808 | trait BoxIter { |
1809 | type Item; |
1810 | fn last(self) -> Option<Self::Item>; |
1811 | } |
1812 | |
1813 | impl<I: Iterator + ?Sized, A: Allocator> BoxIter for Box<I, A> { |
1814 | type Item = I::Item; |
1815 | |
1816 | #[inline (always)] |
1817 | fn last(self) -> Option<I::Item> { |
1818 | #[inline (always)] |
1819 | fn some<T>(_: Option<T>, x: T) -> Option<T> { |
1820 | Some(x) |
1821 | } |
1822 | |
1823 | self.fold(init:None, f:some) |
1824 | } |
1825 | } |
1826 | |
1827 | impl<I: DoubleEndedIterator + ?Sized, A: Allocator> DoubleEndedIterator for Box<I, A> { |
1828 | #[inline (always)] |
1829 | fn next_back(&mut self) -> Option<I::Item> { |
1830 | (**self).next_back() |
1831 | } |
1832 | #[inline (always)] |
1833 | fn nth_back(&mut self, n: usize) -> Option<I::Item> { |
1834 | (**self).nth_back(n) |
1835 | } |
1836 | } |
1837 | |
1838 | impl<I: ExactSizeIterator + ?Sized, A: Allocator> ExactSizeIterator for Box<I, A> { |
1839 | #[inline (always)] |
1840 | fn len(&self) -> usize { |
1841 | (**self).len() |
1842 | } |
1843 | } |
1844 | |
1845 | impl<I: FusedIterator + ?Sized, A: Allocator> FusedIterator for Box<I, A> {} |
1846 | |
1847 | #[cfg (not(no_global_oom_handling))] |
1848 | impl<I> FromIterator<I> for Box<[I]> { |
1849 | #[inline (always)] |
1850 | fn from_iter<T: IntoIterator<Item = I>>(iter: T) -> Self { |
1851 | iter.into_iter().collect::<Vec<_>>().into_boxed_slice() |
1852 | } |
1853 | } |
1854 | |
1855 | #[cfg (not(no_global_oom_handling))] |
1856 | impl<T: Clone, A: Allocator + Clone> Clone for Box<[T], A> { |
1857 | #[inline (always)] |
1858 | fn clone(&self) -> Self { |
1859 | let alloc: A = Box::allocator(self).clone(); |
1860 | let mut vec: Vec = Vec::with_capacity_in(self.len(), alloc); |
1861 | vec.extend_from_slice(self); |
1862 | vec.into_boxed_slice() |
1863 | } |
1864 | |
1865 | #[inline (always)] |
1866 | fn clone_from(&mut self, other: &Self) { |
1867 | if self.len() == other.len() { |
1868 | self.clone_from_slice(src:other); |
1869 | } else { |
1870 | *self = other.clone(); |
1871 | } |
1872 | } |
1873 | } |
1874 | |
1875 | impl<T: ?Sized, A: Allocator> borrow::Borrow<T> for Box<T, A> { |
1876 | #[inline (always)] |
1877 | fn borrow(&self) -> &T { |
1878 | self |
1879 | } |
1880 | } |
1881 | |
1882 | impl<T: ?Sized, A: Allocator> borrow::BorrowMut<T> for Box<T, A> { |
1883 | #[inline (always)] |
1884 | fn borrow_mut(&mut self) -> &mut T { |
1885 | self |
1886 | } |
1887 | } |
1888 | |
1889 | impl<T: ?Sized, A: Allocator> AsRef<T> for Box<T, A> { |
1890 | #[inline (always)] |
1891 | fn as_ref(&self) -> &T { |
1892 | self |
1893 | } |
1894 | } |
1895 | |
1896 | impl<T: ?Sized, A: Allocator> AsMut<T> for Box<T, A> { |
1897 | #[inline (always)] |
1898 | fn as_mut(&mut self) -> &mut T { |
1899 | self |
1900 | } |
1901 | } |
1902 | |
1903 | /* Nota bene |
1904 | * |
1905 | * We could have chosen not to add this impl, and instead have written a |
1906 | * function of Pin<Box<T>> to Pin<T>. Such a function would not be sound, |
1907 | * because Box<T> implements Unpin even when T does not, as a result of |
1908 | * this impl. |
1909 | * |
1910 | * We chose this API instead of the alternative for a few reasons: |
1911 | * - Logically, it is helpful to understand pinning in regard to the |
1912 | * memory region being pointed to. For this reason none of the |
1913 | * standard library pointer types support projecting through a pin |
1914 | * (Box<T> is the only pointer type in std for which this would be |
1915 | * safe.) |
1916 | * - It is in practice very useful to have Box<T> be unconditionally |
1917 | * Unpin because of trait objects, for which the structural auto |
1918 | * trait functionality does not apply (e.g., Box<dyn Foo> would |
1919 | * otherwise not be Unpin). |
1920 | * |
1921 | * Another type with the same semantics as Box but only a conditional |
1922 | * implementation of `Unpin` (where `T: Unpin`) would be valid/safe, and |
1923 | * could have a method to project a Pin<T> from it. |
1924 | */ |
1925 | impl<T: ?Sized, A: Allocator> Unpin for Box<T, A> where A: 'static {} |
1926 | |
1927 | impl<F: ?Sized + Future + Unpin, A: Allocator> Future for Box<F, A> |
1928 | where |
1929 | A: 'static, |
1930 | { |
1931 | type Output = F::Output; |
1932 | |
1933 | #[inline (always)] |
1934 | fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> { |
1935 | F::poll(self:Pin::new(&mut *self), cx) |
1936 | } |
1937 | } |
1938 | |
1939 | #[cfg (feature = "std" )] |
1940 | mod error { |
1941 | use std::error::Error; |
1942 | |
1943 | use super::Box; |
1944 | |
1945 | #[cfg (not(no_global_oom_handling))] |
1946 | impl<'a, E: Error + 'a> From<E> for Box<dyn Error + 'a> { |
1947 | /// Converts a type of [`Error`] into a box of dyn [`Error`]. |
1948 | /// |
1949 | /// # Examples |
1950 | /// |
1951 | /// ``` |
1952 | /// use std::error::Error; |
1953 | /// use std::fmt; |
1954 | /// use std::mem; |
1955 | /// |
1956 | /// #[derive(Debug)] |
1957 | /// struct AnError; |
1958 | /// |
1959 | /// impl fmt::Display for AnError { |
1960 | /// fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { |
1961 | /// write!(f, "An error") |
1962 | /// } |
1963 | /// } |
1964 | /// |
1965 | /// impl Error for AnError {} |
1966 | /// |
1967 | /// let an_error = AnError; |
1968 | /// assert!(0 == mem::size_of_val(&an_error)); |
1969 | /// let a_boxed_error = Box::<dyn Error>::from(an_error); |
1970 | /// assert!(mem::size_of::<Box<dyn Error>>() == mem::size_of_val(&a_boxed_error)) |
1971 | /// ``` |
1972 | #[inline (always)] |
1973 | fn from(err: E) -> Box<dyn Error + 'a> { |
1974 | unsafe { Box::from_raw(Box::leak(Box::new(err))) } |
1975 | } |
1976 | } |
1977 | |
1978 | #[cfg (not(no_global_oom_handling))] |
1979 | impl<'a, E: Error + Send + Sync + 'a> From<E> for Box<dyn Error + Send + Sync + 'a> { |
1980 | /// Converts a type of [`Error`] + [`Send`] + [`Sync`] into a box of |
1981 | /// dyn [`Error`] + [`Send`] + [`Sync`]. |
1982 | /// |
1983 | /// # Examples |
1984 | /// |
1985 | /// ``` |
1986 | /// use std::error::Error; |
1987 | /// use std::fmt; |
1988 | /// use std::mem; |
1989 | /// |
1990 | /// #[derive(Debug)] |
1991 | /// struct AnError; |
1992 | /// |
1993 | /// impl fmt::Display for AnError { |
1994 | /// fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { |
1995 | /// write!(f, "An error") |
1996 | /// } |
1997 | /// } |
1998 | /// |
1999 | /// impl Error for AnError {} |
2000 | /// |
2001 | /// unsafe impl Send for AnError {} |
2002 | /// |
2003 | /// unsafe impl Sync for AnError {} |
2004 | /// |
2005 | /// let an_error = AnError; |
2006 | /// assert!(0 == mem::size_of_val(&an_error)); |
2007 | /// let a_boxed_error = Box::<dyn Error + Send + Sync>::from(an_error); |
2008 | /// assert!( |
2009 | /// mem::size_of::<Box<dyn Error + Send + Sync>>() == mem::size_of_val(&a_boxed_error)) |
2010 | /// ``` |
2011 | #[inline (always)] |
2012 | fn from(err: E) -> Box<dyn Error + Send + Sync + 'a> { |
2013 | unsafe { Box::from_raw(Box::leak(Box::new(err))) } |
2014 | } |
2015 | } |
2016 | |
2017 | impl<T: Error> Error for Box<T> { |
2018 | #[inline (always)] |
2019 | fn source(&self) -> Option<&(dyn Error + 'static)> { |
2020 | Error::source(&**self) |
2021 | } |
2022 | } |
2023 | } |
2024 | |
2025 | #[cfg (feature = "std" )] |
2026 | impl<R: std::io::Read + ?Sized, A: Allocator> std::io::Read for Box<R, A> { |
2027 | #[inline ] |
2028 | fn read(&mut self, buf: &mut [u8]) -> std::io::Result<usize> { |
2029 | (**self).read(buf) |
2030 | } |
2031 | |
2032 | #[inline ] |
2033 | fn read_to_end(&mut self, buf: &mut std::vec::Vec<u8>) -> std::io::Result<usize> { |
2034 | (**self).read_to_end(buf) |
2035 | } |
2036 | |
2037 | #[inline ] |
2038 | fn read_to_string(&mut self, buf: &mut String) -> std::io::Result<usize> { |
2039 | (**self).read_to_string(buf) |
2040 | } |
2041 | |
2042 | #[inline ] |
2043 | fn read_exact(&mut self, buf: &mut [u8]) -> std::io::Result<()> { |
2044 | (**self).read_exact(buf) |
2045 | } |
2046 | } |
2047 | |
2048 | #[cfg (feature = "std" )] |
2049 | impl<W: std::io::Write + ?Sized, A: Allocator> std::io::Write for Box<W, A> { |
2050 | #[inline ] |
2051 | fn write(&mut self, buf: &[u8]) -> std::io::Result<usize> { |
2052 | (**self).write(buf) |
2053 | } |
2054 | |
2055 | #[inline ] |
2056 | fn flush(&mut self) -> std::io::Result<()> { |
2057 | (**self).flush() |
2058 | } |
2059 | |
2060 | #[inline ] |
2061 | fn write_all(&mut self, buf: &[u8]) -> std::io::Result<()> { |
2062 | (**self).write_all(buf) |
2063 | } |
2064 | |
2065 | #[inline ] |
2066 | fn write_fmt(&mut self, fmt: fmt::Arguments<'_>) -> std::io::Result<()> { |
2067 | (**self).write_fmt(fmt) |
2068 | } |
2069 | } |
2070 | |
2071 | #[cfg (feature = "std" )] |
2072 | impl<S: std::io::Seek + ?Sized, A: Allocator> std::io::Seek for Box<S, A> { |
2073 | #[inline ] |
2074 | fn seek(&mut self, pos: std::io::SeekFrom) -> std::io::Result<u64> { |
2075 | (**self).seek(pos) |
2076 | } |
2077 | |
2078 | #[inline ] |
2079 | fn stream_position(&mut self) -> std::io::Result<u64> { |
2080 | (**self).stream_position() |
2081 | } |
2082 | } |
2083 | |
2084 | #[cfg (feature = "std" )] |
2085 | impl<B: std::io::BufRead + ?Sized, A: Allocator> std::io::BufRead for Box<B, A> { |
2086 | #[inline ] |
2087 | fn fill_buf(&mut self) -> std::io::Result<&[u8]> { |
2088 | (**self).fill_buf() |
2089 | } |
2090 | |
2091 | #[inline ] |
2092 | fn consume(&mut self, amt: usize) { |
2093 | (**self).consume(amt) |
2094 | } |
2095 | |
2096 | #[inline ] |
2097 | fn read_until(&mut self, byte: u8, buf: &mut std::vec::Vec<u8>) -> std::io::Result<usize> { |
2098 | (**self).read_until(byte, buf) |
2099 | } |
2100 | |
2101 | #[inline ] |
2102 | fn read_line(&mut self, buf: &mut std::string::String) -> std::io::Result<usize> { |
2103 | (**self).read_line(buf) |
2104 | } |
2105 | } |
2106 | |
2107 | #[cfg (feature = "alloc" )] |
2108 | impl<A: Allocator> Extend<Box<str, A>> for alloc_crate::string::String { |
2109 | fn extend<I: IntoIterator<Item = Box<str, A>>>(&mut self, iter: I) { |
2110 | iter.into_iter().for_each(move |s: Box| self.push_str(&s)); |
2111 | } |
2112 | } |
2113 | |
2114 | #[cfg (not(no_global_oom_handling))] |
2115 | impl Clone for Box<core::ffi::CStr> { |
2116 | #[inline ] |
2117 | fn clone(&self) -> Self { |
2118 | (**self).into() |
2119 | } |
2120 | } |
2121 | |
2122 | #[cfg (not(no_global_oom_handling))] |
2123 | impl From<&core::ffi::CStr> for Box<core::ffi::CStr> { |
2124 | /// Converts a `&CStr` into a `Box<CStr>`, |
2125 | /// by copying the contents into a newly allocated [`Box`]. |
2126 | fn from(s: &core::ffi::CStr) -> Box<core::ffi::CStr> { |
2127 | let boxed: Box<[u8]> = Box::from(s.to_bytes_with_nul()); |
2128 | unsafe { Box::from_raw(Box::into_raw(boxed) as *mut core::ffi::CStr) } |
2129 | } |
2130 | } |
2131 | |
2132 | #[cfg (feature = "serde" )] |
2133 | impl<T, A> serde::Serialize for Box<T, A> |
2134 | where |
2135 | T: serde::Serialize, |
2136 | A: Allocator, |
2137 | { |
2138 | #[inline (always)] |
2139 | fn serialize<S: serde::ser::Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> { |
2140 | (**self).serialize(serializer) |
2141 | } |
2142 | } |
2143 | |
2144 | #[cfg (feature = "serde" )] |
2145 | impl<'de, T, A> serde::Deserialize<'de> for Box<T, A> |
2146 | where |
2147 | T: serde::Deserialize<'de>, |
2148 | A: Allocator + Default, |
2149 | { |
2150 | #[inline (always)] |
2151 | fn deserialize<D: serde::de::Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> { |
2152 | let value = T::deserialize(deserializer)?; |
2153 | Ok(Box::new_in(value, A::default())) |
2154 | } |
2155 | } |
2156 | |