| 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 | |