covk 0.1.2-1.4.346

Unsafe vulkan bindings for Rust
Documentation
use crate::*;
use alloc::boxed::Box;
use core::any::TypeId;
use core::fmt::{Debug, Display, Pointer};
use core::hash::{Hash, Hasher};
use core::ops::Deref;
use core::ptr::NonNull;
use core::sync::atomic::{AtomicUsize, Ordering};

#[repr(C)]
#[derive(Debug)]
pub struct HndDataBase<T, S> {
    pub p_drop: unsafe fn(NonNull<HndDataBase<T, S>>),
    pub count: AtomicUsize,
    pub raw: T,
    pub scope: S,
}

#[repr(C)]
#[derive(Debug)]
pub struct HndData<T, S, Dep> {
    pub base: HndDataBase<T, S>,
    pub dep: Dep,
}

impl<T, S, Dep> Deref for HndData<T, S, Dep> {
    type Target = HndDataBase<T, S>;
    fn deref(&self) -> &Self::Target {
        &self.base
    }
}

pub trait HndInst<T, S, Dep> {
    fn drop(this: &mut HndData<T, S, Dep>);
}

#[repr(transparent)]
pub struct Hnd<T, S>(NonNull<HndDataBase<T, S>>);

impl<T, S> Hnd<T, S> {
    pub fn new<Dep: Send + Sync + 'static, Inst: HndInst<T, S, Dep>>(
        scope: S,
        raw: T,
        dep: Dep,
        inst: Inst,
    ) -> Self {
        unsafe {
            Self(
                NonNull::new_unchecked(Box::leak(Box::new(HndData::<T, S, Dep> {
                    base: HndDataBase {
                        p_drop: Self::drop::<Dep, Inst>,
                        count: AtomicUsize::new(1),
                        scope,
                        raw,
                    },
                    dep,
                })))
                .cast::<HndDataBase<T, S>>(),
            )
        }
    }

    unsafe fn drop<Dep, Inst: HndInst<T, S, Dep>>(this: NonNull<HndDataBase<T, S>>) {
        unsafe {
            let mut this = Box::from_raw(this.cast::<HndData<T, S, Dep>>().as_ptr());
            Inst::drop(&mut this);
            drop(this);
        }
    }
}

impl<T, S> Deref for Hnd<T, S> {
    type Target = HndDataBase<T, S>;
    fn deref(&self) -> &Self::Target {
        unsafe { self.0.as_ref() }
    }
}

impl<T, S> Hnd<T, S> {
    fn add_ref(&self) {
        unsafe {
            self.count.fetch_add(1, Ordering::Relaxed);
        }
    }
    fn release(&self) {
        unsafe {
            if 1 == self.count.fetch_sub(1, Ordering::Release) {
                core::sync::atomic::fence(Ordering::Acquire);
                unsafe {
                    (self.p_drop)(self.0);
                }
            }
        }
    }
}

impl<T, S> Clone for Hnd<T, S> {
    fn clone(&self) -> Self {
        self.add_ref();
        Self(self.0)
    }
}

unsafe impl<T: Send, S: Send> Send for Hnd<T, S> {}
unsafe impl<T: Sync, S: Sync> Sync for Hnd<T, S> {}

impl<T: Debug, S> Debug for Hnd<T, S> {
    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
        self.raw.fmt(f)
    }
}

impl<T: Pointer, S> Pointer for Hnd<T, S> {
    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
        self.raw.fmt(f)
    }
}

impl<T: Display, S> Display for Hnd<T, S> {
    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
        self.raw.fmt(f)
    }
}

impl<T: PartialEq, S1, S2> PartialEq<Hnd<T, S2>> for Hnd<T, S1> {
    fn eq(&self, other: &Hnd<T, S2>) -> bool {
        self.raw.eq(&other.raw)
    }
    fn ne(&self, other: &Hnd<T, S2>) -> bool {
        self.raw.ne(&other.raw)
    }
}

impl<T: Eq, S> Eq for Hnd<T, S> {}

impl<T: Hash, S> Hash for Hnd<T, S> {
    fn hash<H: Hasher>(&self, state: &mut H) {
        self.raw.hash(state)
    }
}

impl<T: PartialOrd, S1, S2> PartialOrd<Hnd<T, S2>> for Hnd<T, S1> {
    fn partial_cmp(&self, other: &Hnd<T, S2>) -> Option<core::cmp::Ordering> {
        self.raw.partial_cmp(&other.raw)
    }

    fn lt(&self, other: &Hnd<T, S2>) -> bool {
        self.raw.lt(&other.raw)
    }

    fn le(&self, other: &Hnd<T, S2>) -> bool {
        self.raw.le(&other.raw)
    }

    fn gt(&self, other: &Hnd<T, S2>) -> bool {
        self.raw.gt(&other.raw)
    }

    fn ge(&self, other: &Hnd<T, S2>) -> bool {
        self.raw.ge(&other.raw)
    }
}

impl<T: Ord, S> Ord for Hnd<T, S> {
    fn cmp(&self, other: &Self) -> core::cmp::Ordering {
        self.raw.cmp(&other.raw)
    }
}

impl<T, S> Drop for Hnd<T, S> {
    fn drop(&mut self) {
        self.release();
    }
}