| //@ build-pass | |
| //@ compile-flags: -Zmir-opt-level=3 | |
| use std::fmt::Debug; | |
| use std::mem::ManuallyDrop; | |
| use std::ptr; | |
| pub trait BitRegister {} | |
| macro_rules! register { | |
| ($($t:ty),+ $(,)?) => { $( | |
| impl BitRegister for $t { | |
| } | |
| )* }; | |
| } | |
| register!(u8, u16, u32); | |
| pub trait BitStore: Sized + Debug { | |
| /// The register type that the implementor describes. | |
| type Mem: BitRegister + Into<Self>; | |
| } | |
| macro_rules! store { | |
| ($($t:ty),+ $(,)?) => { $( | |
| impl BitStore for $t { | |
| type Mem = Self; | |
| } | |
| )+ }; | |
| } | |
| store!(u8, u16, u32,); | |
| #[repr(C)] | |
| pub struct BitVec<T> | |
| where | |
| T: BitStore, | |
| { | |
| /// Region pointer describing the live portion of the owned buffer. | |
| pointer: ptr::NonNull<T>, | |
| /// Allocated capacity, in elements `T`, of the owned buffer. | |
| capacity: usize, | |
| } | |
| impl<T> BitVec<T> | |
| where | |
| T: BitStore, | |
| { | |
| pub fn new() -> Self { | |
| let pointer = ptr::NonNull::<T>::new(ptr::null_mut()).unwrap(); | |
| BitVec { pointer, capacity: 10 } | |
| } | |
| pub fn clear(&mut self) { | |
| unsafe { | |
| self.set_len(0); | |
| } | |
| } | |
| #[inline] | |
| pub unsafe fn set_len(&mut self, new_len: usize) {} | |
| fn with_vec<F, R>(&mut self, func: F) -> R | |
| where | |
| F: FnOnce(&mut ManuallyDrop<Vec<T::Mem>>) -> R, | |
| { | |
| let cap = self.capacity; | |
| let elts = 10; | |
| let mut vec = ManuallyDrop::new(unsafe { Vec::from_raw_parts(ptr::null_mut(), elts, cap) }); | |
| let out = func(&mut vec); | |
| out | |
| } | |
| } | |
| impl<T> Drop for BitVec<T> | |
| where | |
| T: BitStore, | |
| { | |
| #[inline] | |
| fn drop(&mut self) { | |
| // The buffer elements do not have destructors. | |
| self.clear(); | |
| // Run the `Vec` destructor to deƤllocate the buffer. | |
| self.with_vec(|vec| unsafe { ManuallyDrop::drop(vec) }); | |
| } | |
| } | |
| fn main() { | |
| let bitvec = BitVec::<u32>::new(); | |
| } |