use core::alloc::Layout;
use core::ptr::{self, NonNull};
use crate::allocator::AllocatorProvider;
use crate::sync::atomic::{self, Ordering::*};
use crate::vec::types::EcoVec;
impl<T, A> Drop for EcoVec<T, A>
where
A: AllocatorProvider,
{
fn drop(&mut self) {
match self.header() {
None => return,
Some(header) => {
if header.refs.load(Acquire) == 1 {
} else if header.refs.fetch_sub(1, Release) != 1 {
return;
} else {
atomic::fence(Acquire);
}
}
}
let layout = Self::layout(self.capacity());
let alloc_ptr = unsafe { NonNull::new_unchecked(self.allocation_mut()) };
let data_ptr = unsafe { self.data_mut() };
struct DeallocGuard<'a, A: AllocatorProvider> {
alloc: &'a A,
ptr: NonNull<u8>,
layout: Layout,
}
impl<A: AllocatorProvider> Drop for DeallocGuard<'_, A> {
fn drop(&mut self) {
unsafe { self.alloc.deallocate(self.ptr, self.layout) };
}
}
let _dealloc = DeallocGuard { alloc: &self.alloc, ptr: alloc_ptr, layout };
unsafe {
ptr::drop_in_place(ptr::slice_from_raw_parts_mut(data_ptr, self.len));
}
}
}