1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176
/*! Reïmplementation of the `Box<[T]>` API. This module tracks the [`alloc::boxed::Box`] module in the version of Rust specified in the `rust-toolchain` file. It is required to provide an exact or equivalent API surface matching the `Box<[T]>` type, to the extent that it is possible in the language. Where differences occur, they must be documented in a section called `API Differences`. [`alloc::boxed::Box`]: https://doc.rust-lang.org/alloc/boxed/struct.Boxed.html !*/ use crate::{ boxed::BitBox, order::BitOrder, pointer::BitPtr, slice::BitSlice, store::BitStore, }; use core::{ marker::{ PhantomData, Unpin, }, mem, pin::Pin, }; impl<O, T> BitBox<O, T> where O: BitOrder, T: BitStore { /// Allocates memory on the heap and then places `bits` into it. /// /// # API Differences /// /// [`Box::new`] takes a `T` by direct value, and is not implemented as a /// means of cloning slices. As `BitSlice` cannot be held by value, this /// function clones the referent slice region into a new fixed-size heap /// buffer. /// /// # Examples /// /// ```rust /// # use bitvec::prelude::*; /// let boxed = BitBox::new(0u8.bits::<Lsb0>()); /// ``` pub fn new(bits: &BitSlice<O, T>) -> Self { Self::from_bitslice(bits) } /// Constructs a new `Pin<BitBox<O, T>>`. /// /// `BitSlice` is always `Unpin`, so this has no actual immobility effect. pub fn pin(bits: &BitSlice<O, T>) -> Pin<Self> where O: Unpin, T: Unpin { Pin::new(Self::new(bits)) } /// Constructs a bit box from a raw bit pointer. /// /// After calling this function, the raw pointer is owned by the resulting /// `BitBox`. Specifically, the `BitBox` destructor will free the allocated /// memory. For this to be safe, the memory must have been allocated by /// `BitBox` earlier in the program. /// /// # Safety /// /// This function is unsafe because improper use may lead to memory /// problems. For example, a double-free may occurr if the function is /// called twice on the same raw pointer. /// /// # Notes /// /// This function, and `into_raw`, exchange ordinary raw pointers /// `*mut BitSlice<O, T>`. Values of these types can be created from, and /// converted to, other region pointers such as `*mut [T]` through ordinary /// `as`-casting. /// /// This is valid in the Rust type system, but is incorrect at runtime. You /// must not, ever, use `as` to cast in either direction to or from a /// `BitSlice` pointer. /// /// # Examples /// /// Recreate a `BitBox` which was previously converted to a raw pointer /// using [`BitBox::into_raw`]: /// /// ```rust /// # use bitvec::prelude::*; /// let b = BitBox::new(0u8.bits::<Lsb0>()); /// let ptr = BitBox::into_raw(b); /// let b = unsafe { BitBox::<Lsb0, _>::from_raw(ptr) }; /// ``` /// /// [`BitBox::into_raw`]: #method.into_raw pub unsafe fn from_raw(raw: *mut BitSlice<O, T>) -> Self { Self { _order: PhantomData, pointer: BitPtr::from_mut_ptr(raw), } } /// Consumes the `BitBox`, returning a wrapped raw pointer. /// /// The pointer will be properly aligned and non-null. /// /// After calling this function, the caller is responsible for the memory /// previously managed by the `BitBox`. In particular, the caller should /// properly release the memory by converting the pointer back into a /// `BitBox` with the [`BitBox::from_raw`] function, allowing the `BitBox` /// destructor to perform the cleanup. /// /// Note: this is an associated function, which means that you have to call /// it as `BitBox::into_raw(b)` instead of `b.into_raw()`. This is to match /// layout with the standard library’s `Box` API; there will never be a name /// conflict with `BitSlice`. /// /// # Notes /// /// As with `::from_raw`, the pointer returned by this function must not /// ever have its type or value changed or inspected in any way. It may only /// be held and then passed into `::from_raw` in the future. /// /// # Examples /// /// Converting the raw pointer back into a `BitBox` with /// [`BitBox::from_raw`] for automatic cleanup: /// /// ```rust /// # use bitvec::prelude::*; /// let b = BitBox::new(0u64.bits::<Msb0>()); /// let ptr = BitBox::into_raw(b); /// let b = unsafe { BitBox::<Msb0, _>::from_raw(ptr) }; /// ``` /// /// [`BitBox::from_raw`]: #method.from_raw pub fn into_raw(b: Self) -> *mut BitSlice<O, T> { let out = b.pointer.as_mut_ptr(); mem::forget(b); out } /// Consumes and leaks the `BitBox`, returning a mutable reference, /// `&'a mut BitSlice<O, T>`. Note that the memory region `[T]` must outlive /// the chosen lifetime `'a`. /// /// This function is mainly useful for bit regions that live for the /// remainder of the program’s life. Dropping the returned reference will /// cause a memory leak. If this is not acceptable, the reference should /// first be wrapped with the [`BitBox::from_raw`] function, producing a /// `BitBox`. This `BitBox` can then be dropped which will properly /// deallocate the memory. /// /// Note: this is an associated function, which means that you have to call /// it as `BitBox::leak(b)` instead of `b.leak()`. This is to match layout /// with the standard library’s `Box` API; there will never be a name /// conflict with `BitSlice`. /// /// # Examples /// /// Simple usage: /// /// ```rust /// # use bitvec::prelude::*; /// let b = BitBox::new(0u64.bits::<Local>()); /// let static_ref: &'static mut BitSlice<Local, u64> = BitBox::leak(b); /// static_ref.set(0, true); /// assert_eq!(static_ref.count_ones(), 1); /// ``` /// /// [`BitBox::from_raw`]: #method.from_raw pub fn leak<'a>(self) -> &'a mut BitSlice<O, T> { let out = self.bitptr(); mem::forget(self); out.into_bitslice_mut() } }