1 | #![deny (unsafe_op_in_unsafe_fn)]
|
2 | #![allow (clippy::needless_doctest_main, clippy::partialeq_ne_impl)]
|
3 |
|
4 | #[cfg (feature = "alloc" )]
|
5 | pub use self::slice::SliceExt;
|
6 |
|
7 | pub mod alloc;
|
8 |
|
9 | #[cfg (feature = "alloc" )]
|
10 | pub mod boxed;
|
11 |
|
12 | #[cfg (feature = "alloc" )]
|
13 | mod raw_vec;
|
14 |
|
15 | #[cfg (feature = "alloc" )]
|
16 | pub mod vec;
|
17 |
|
18 | #[cfg (feature = "alloc" )]
|
19 | mod macros;
|
20 |
|
21 | #[cfg (feature = "alloc" )]
|
22 | mod slice;
|
23 |
|
24 | #[cfg (feature = "alloc" )]
|
25 | mod unique;
|
26 |
|
27 | /// Allows turning a [`Box<T: Sized, A>`][boxed::Box] into a [`Box<U: ?Sized, A>`][boxed::Box] where `T` can be unsizing-coerced into a `U`.
|
28 | ///
|
29 | /// This is the only way to create an `allocator_api2::boxed::Box` of an unsized type on stable.
|
30 | ///
|
31 | /// With the standard library's `alloc::boxed::Box`, this is done automatically using the unstable unsize traits, but this crate's Box
|
32 | /// can't take advantage of that machinery on stable. So, we need to use type inference and the fact that you *can*
|
33 | /// still coerce the inner pointer of a box to get the compiler to help us unsize it using this macro.
|
34 | ///
|
35 | /// # Example
|
36 | ///
|
37 | /// ```
|
38 | /// use allocator_api2::unsize_box;
|
39 | /// use allocator_api2::boxed::Box;
|
40 | /// use core::any::Any;
|
41 | ///
|
42 | /// let sized_box: Box<u64> = Box::new(0);
|
43 | /// let unsized_box: Box<dyn Any> = unsize_box!(sized_box);
|
44 | /// ```
|
45 | #[macro_export ]
|
46 | #[cfg (feature = "alloc" )]
|
47 | macro_rules! unsize_box {( $boxed:expr $(,)? ) => ({
|
48 | let (ptr, allocator) = ::allocator_api2::boxed::Box::into_raw_with_allocator($boxed);
|
49 | // we don't want to allow casting to arbitrary type U, but we do want to allow unsize coercion to happen.
|
50 | // that's exactly what's happening here -- this is *not* a pointer cast ptr as *mut _, but the compiler
|
51 | // *will* allow an unsizing coercion to happen into the `ptr` place, if one is available. And we use _ so that the user can
|
52 | // fill in what they want the unsized type to be by annotating the type of the variable this macro will
|
53 | // assign its result to.
|
54 | let ptr: *mut _ = ptr;
|
55 | // SAFETY: see above for why ptr's type can only be something that can be safely coerced.
|
56 | // also, ptr just came from a properly allocated box in the same allocator.
|
57 | unsafe {
|
58 | ::allocator_api2::boxed::Box::from_raw_in(ptr, allocator)
|
59 | }
|
60 | })}
|
61 |
|
62 | #[cfg (feature = "alloc" )]
|
63 | pub mod collections {
|
64 | pub use super::raw_vec::{TryReserveError, TryReserveErrorKind};
|
65 | }
|
66 |
|
67 | #[cfg (feature = "alloc" )]
|
68 | #[track_caller ]
|
69 | #[inline (always)]
|
70 | #[cfg (debug_assertions)]
|
71 | unsafe fn assume(v: bool) {
|
72 | if !v {
|
73 | core::unreachable!()
|
74 | }
|
75 | }
|
76 |
|
77 | #[cfg (feature = "alloc" )]
|
78 | #[track_caller ]
|
79 | #[inline (always)]
|
80 | #[cfg (not(debug_assertions))]
|
81 | unsafe fn assume(v: bool) {
|
82 | if !v {
|
83 | unsafe {
|
84 | core::hint::unreachable_unchecked();
|
85 | }
|
86 | }
|
87 | }
|
88 |
|
89 | #[cfg (feature = "alloc" )]
|
90 | #[inline (always)]
|
91 | fn addr<T>(x: *const T) -> usize {
|
92 | #[allow (clippy::useless_transmute, clippy::transmutes_expressible_as_ptr_casts)]
|
93 | unsafe {
|
94 | core::mem::transmute(src:x)
|
95 | }
|
96 | }
|
97 |
|
98 | #[cfg (feature = "alloc" )]
|
99 | #[inline (always)]
|
100 | fn invalid_mut<T>(addr: usize) -> *mut T {
|
101 | #[allow (clippy::useless_transmute, clippy::transmutes_expressible_as_ptr_casts)]
|
102 | unsafe {
|
103 | core::mem::transmute(src:addr)
|
104 | }
|
105 | }
|
106 | |