use super::*;
#[repr(transparent)]
pub struct IUnknown(std::ptr::NonNull<std::ffi::c_void>);
#[doc(hidden)]
#[repr(C)]
pub struct IUnknown_Vtbl {
pub QueryInterface: unsafe extern "system" fn(this: *mut std::ffi::c_void, iid: &GUID, interface: *mut *const std::ffi::c_void) -> HRESULT,
pub AddRef: unsafe extern "system" fn(this: *mut std::ffi::c_void) -> u32,
pub Release: unsafe extern "system" fn(this: *mut std::ffi::c_void) -> u32,
}
unsafe impl Vtable for IUnknown {
type Vtable = IUnknown_Vtbl;
}
unsafe impl Interface for IUnknown {
const IID: GUID = GUID::from_u128(0x00000000_0000_0000_c000_000000000046);
}
impl Clone for IUnknown {
fn clone(&self) -> Self {
unsafe {
(self.vtable().AddRef)(std::mem::transmute_copy(self));
}
Self(self.0)
}
}
impl Drop for IUnknown {
fn drop(&mut self) {
unsafe {
(self.vtable().Release)(std::mem::transmute_copy(self));
}
}
}
impl PartialEq for IUnknown {
fn eq(&self, other: &Self) -> bool {
self.cast::<IUnknown>().unwrap().0 == other.cast::<IUnknown>().unwrap().0
}
}
impl Eq for IUnknown {}
impl std::fmt::Debug for IUnknown {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_tuple("IUnknown").field(&self.0).finish()
}
}
#[doc(hidden)]
pub trait IUnknownImpl {
type Impl;
fn get_impl(&self) -> &Self::Impl;
unsafe fn QueryInterface(&self, iid: &GUID, interface: *mut *const std::ffi::c_void) -> HRESULT;
fn AddRef(&self) -> u32;
unsafe fn Release(&self) -> u32;
}
#[cfg(feature = "implement")]
impl IUnknown_Vtbl {
pub const fn new<T: IUnknownImpl, const OFFSET: isize>() -> Self {
unsafe extern "system" fn QueryInterface<T: IUnknownImpl, const OFFSET: isize>(this: *mut std::ffi::c_void, iid: &GUID, interface: *mut *const std::ffi::c_void) -> HRESULT {
let this = (this as *mut *mut std::ffi::c_void).offset(OFFSET) as *mut T;
(*this).QueryInterface(iid, interface)
}
unsafe extern "system" fn AddRef<T: IUnknownImpl, const OFFSET: isize>(this: *mut std::ffi::c_void) -> u32 {
let this = (this as *mut *mut std::ffi::c_void).offset(OFFSET) as *mut T;
(*this).AddRef()
}
unsafe extern "system" fn Release<T: IUnknownImpl, const OFFSET: isize>(this: *mut std::ffi::c_void) -> u32 {
let this = (this as *mut *mut std::ffi::c_void).offset(OFFSET) as *mut T;
(*this).Release()
}
Self { QueryInterface: QueryInterface::<T, OFFSET>, AddRef: AddRef::<T, OFFSET>, Release: Release::<T, OFFSET> }
}
}