#[macro_export]
macro_rules! implement_decl {
(
impl < $($gp:ident),+ $(,)? >
$name:ident as $impl_vis:vis $impl_name:ident
: [
$( $ifty:ty ),+ $(,)?
]
where $($wc:tt)+
) => {
$crate::__implement_decl_g_zip! {
@zip
ctx: {
generics: [ $($gp),+ ],
wc: { $($wc)+ },
vis: $impl_vis,
name: $name,
impl_name: $impl_name,
},
names: [
__iface0 __iface1 __iface2 __iface3
__iface4 __iface5 __iface6 __iface7
__iface8 __iface9 __iface10 __iface11
__iface12 __iface13 __iface14 __iface15
],
tys: [ $($ifty),+ ],
acc: [ ]
}
};
(
impl $name:ident as $impl_vis:vis $impl_name:ident : [
$( $iface:ident ),+ $(,)?
] $(,)?
) => {
$crate::__implement_decl_first_iface! {
@find
args: [ vis: $impl_vis, name: $name, impl_name: $impl_name, ],
remaining: [ $( ($iface) )+ ]
}
$crate::__implement_decl_per_iface_impls!(
$name, $impl_name,
$( ($iface), )+
);
};
}
#[doc(hidden)]
#[macro_export]
macro_rules! __implement_decl_first_iface {
(@find
args: [ vis: $impl_vis:vis, name: $name:ident, impl_name: $impl_name:ident, ],
remaining: [ ($first_iface:ident) $($rest:tt)* ]
) => {
$crate::__implement_decl_struct! {
@walk
vis: $impl_vis,
name: $name,
impl_name: $impl_name,
first_iface: $first_iface,
fields: { },
inits: { },
qi_pairs: [ ],
offset: [ () () ], remaining: [ ($first_iface) $($rest)* ]
}
};
}
#[doc(hidden)]
#[macro_export]
macro_rules! __implement_decl_struct {
(@walk
vis: $impl_vis:vis,
name: $name:ident,
impl_name: $impl_name:ident,
first_iface: $first_iface:ident,
fields: { $($fields:tt)* },
inits: { $($inits:tt)* },
qi_pairs: [ $($qi_pairs:tt)* ],
offset: [ $($offset:tt)* ],
remaining: [ ($iface:ident) $($rest:tt)* ]
) => {
$crate::__implement_decl_struct! {
@walk
vis: $impl_vis,
name: $name,
impl_name: $impl_name,
first_iface: $first_iface,
fields: {
$($fields)*
#[allow(non_snake_case)]
pub $iface: &'static <$iface as $crate::Interface>::Vtable,
},
inits: {
$($inits)*
$iface: {
const C: <$iface as $crate::Interface>::Vtable =
<<$iface as $crate::Interface>::Vtable>::new::<
$impl_name,
{ $crate::__implement_decl_offset_negate!($($offset)*) },
>();
&C
},
},
qi_pairs: [ $($qi_pairs)* ($iface) ],
offset: [ $($offset)* () ],
remaining: [ $($rest)* ]
}
};
(@walk
vis: $impl_vis:vis,
name: $name:ident,
impl_name: $impl_name:ident,
first_iface: $first_iface:ident,
fields: { $($fields:tt)* },
inits: { $($inits:tt)* },
qi_pairs: [ $(($qi_iface:ident))* ],
offset: [ $($offset:tt)* ],
remaining: [ ]
) => {
#[repr(C)]
#[allow(non_camel_case_types, non_snake_case)]
$impl_vis struct $impl_name {
pub base: $crate::ComposeBase,
pub identity: &'static $crate::IInspectable_Vtbl,
$($fields)*
pub this: $name,
pub count: $crate::imp::WeakRefCount,
}
impl $name {
#[doc(hidden)]
#[inline(always)]
#[allow(non_snake_case)]
pub const fn into_outer(self) -> $impl_name {
$impl_name {
base: $crate::ComposeBase::new(),
identity: {
const C: $crate::IInspectable_Vtbl =
<$crate::IInspectable_Vtbl>::new::<$impl_name, $first_iface, -1>();
&C
},
$($inits)*
this: self,
count: $crate::imp::WeakRefCount::new(),
}
}
pub const fn into_static(self) -> $crate::StaticComObject<Self> {
$crate::StaticComObject::from_outer(self.into_outer())
}
}
impl ::core::ops::Deref for $impl_name {
type Target = $name;
#[inline(always)]
fn deref(&self) -> &Self::Target {
&self.this
}
}
impl $crate::IUnknownImpl for $impl_name {
type Impl = $name;
$crate::__implement_decl_iunknown_methods! {
qi: [ $( ($qi_iface : $qi_iface) )* ]
}
}
impl $crate::ComObjectInner for $name {
type Outer = $impl_name;
fn into_object(self) -> $crate::ComObject<Self> {
let boxed = $crate::imp::box_new(self.into_outer());
unsafe {
let ptr = $crate::imp::box_into_raw(boxed);
$crate::ComObject::from_raw(::core::ptr::NonNull::new_unchecked(ptr))
}
}
}
$crate::__implement_decl_shared_tail! {
gen: [ ],
wc: { },
name: $name,
impl_name: $impl_name,
}
};
}
#[doc(hidden)]
#[macro_export]
macro_rules! __implement_decl_iunknown_methods {
( qi: [ $( ($qi_iface:ident : $qi_ty:ty) )* ] ) => {
#[inline(always)]
fn get_impl(&self) -> &Self::Impl {
&self.this
}
#[inline(always)]
fn get_impl_mut(&mut self) -> &mut Self::Impl {
&mut self.this
}
#[inline(always)]
fn into_inner(self) -> Self::Impl {
self.this
}
#[inline(always)]
fn AddRef(&self) -> u32 {
self.count.add_ref()
}
#[inline(always)]
unsafe fn Release(self_: *mut Self) -> u32 {
unsafe {
let remaining = (*self_).count.release();
if remaining == 0 {
_ = $crate::imp::box_from_raw(self_);
}
remaining
}
}
#[inline(always)]
fn is_reference_count_one(&self) -> bool {
self.count.is_one()
}
unsafe fn GetTrustLevel(&self, value: *mut i32) -> $crate::HRESULT {
if value.is_null() {
return $crate::imp::E_POINTER;
}
unsafe { *value = 0; }
$crate::HRESULT(0)
}
fn to_object(&self) -> $crate::ComObject<Self::Impl> {
self.count.add_ref();
unsafe {
$crate::ComObject::from_raw(
::core::ptr::NonNull::new_unchecked(self as *const Self as *mut Self),
)
}
}
unsafe fn QueryInterface(
&self,
iid: *const $crate::GUID,
interface: *mut *mut ::core::ffi::c_void,
) -> $crate::HRESULT {
unsafe {
if iid.is_null() || interface.is_null() {
return $crate::imp::E_POINTER;
}
let iid = *iid;
let interface_ptr: *const ::core::ffi::c_void = 'found: {
if iid == <$crate::IUnknown as $crate::Interface>::IID
|| iid == <$crate::IInspectable as $crate::Interface>::IID
|| iid == <$crate::imp::IAgileObject as $crate::Interface>::IID
{
break 'found &self.identity as *const _ as *const ::core::ffi::c_void;
}
$(
if <<$qi_ty as $crate::Interface>::Vtable>::matches(&iid) {
break 'found &self.$qi_iface as *const _ as *const ::core::ffi::c_void;
}
)*
#[cfg(windows)]
if iid == <$crate::imp::IMarshal as $crate::Interface>::IID {
return $crate::imp::marshaler(
<Self as $crate::IUnknownImpl>::to_interface::<$crate::IUnknown>(self),
interface,
);
}
if iid == $crate::DYNAMIC_CAST_IID {
(interface as *mut *const dyn ::core::any::Any)
.write(self as &dyn ::core::any::Any as *const dyn ::core::any::Any);
return $crate::HRESULT(0);
}
let tear_off_ptr = self.count.query(
&iid,
&self.identity as *const _ as *mut _,
);
if !tear_off_ptr.is_null() {
*interface = tear_off_ptr;
return $crate::HRESULT(0);
}
if let ::core::option::Option::Some(base) = self.base.as_option() {
return $crate::Interface::query(
base,
&iid as *const $crate::GUID,
interface,
);
}
*interface = ::core::ptr::null_mut();
return $crate::imp::E_NOINTERFACE;
};
debug_assert!(!interface_ptr.is_null());
*interface = interface_ptr as *mut ::core::ffi::c_void;
self.count.add_ref();
$crate::HRESULT(0)
}
}
};
}
#[doc(hidden)]
#[macro_export]
macro_rules! __implement_decl_shared_tail {
(
gen: [ $($gp:ident),* ],
wc: { $($wc:tt)* },
name: $name:ident,
impl_name: $impl_name:ident,
) => {
impl< $($gp),* > $crate::Compose for $name < $($gp),* >
where $($wc)*
{
unsafe fn compose<'a>(
implementation: Self,
) -> ($crate::IInspectable, &'a mut ::core::option::Option<$crate::IInspectable>) {
unsafe {
let inspectable: $crate::IInspectable = implementation.into();
let identity_ptr: *mut ::core::ffi::c_void = $crate::Interface::as_raw(&inspectable);
let base_ptr = (identity_ptr as *mut *mut ::core::ffi::c_void).sub(1)
as *mut ::core::option::Option<$crate::IInspectable>;
(inspectable, &mut *base_ptr)
}
}
}
impl< $($gp),* > ::core::convert::From<$name < $($gp),* >> for $crate::IUnknown
where $($wc)*
{
#[inline(always)]
fn from(this: $name < $($gp),* >) -> Self {
let com_object = $crate::ComObject::new(this);
com_object.into_interface()
}
}
impl< $($gp),* > ::core::convert::From<$name < $($gp),* >> for $crate::IInspectable
where $($wc)*
{
#[inline(always)]
fn from(this: $name < $($gp),* >) -> Self {
let com_object = $crate::ComObject::new(this);
com_object.into_interface()
}
}
impl< $($gp),* > $crate::ComObjectInterface<$crate::IUnknown> for $impl_name < $($gp),* >
where $($wc)*
{
#[inline(always)]
fn as_interface_ref(&self) -> $crate::InterfaceRef<'_, $crate::IUnknown> {
unsafe { ::core::mem::transmute(&self.identity) }
}
}
impl< $($gp),* > $crate::ComObjectInterface<$crate::IInspectable> for $impl_name < $($gp),* >
where $($wc)*
{
#[inline(always)]
fn as_interface_ref(&self) -> $crate::InterfaceRef<'_, $crate::IInspectable> {
unsafe { ::core::mem::transmute(&self.identity) }
}
}
};
}
#[doc(hidden)]
#[macro_export]
macro_rules! __implement_decl_offset_negate {
( $($unit:tt)* ) => {
-( $crate::__implement_decl_count_units!($($unit)*) as isize )
};
}
#[doc(hidden)]
#[macro_export]
macro_rules! __implement_decl_count_units {
( $($unit:tt)* ) => {
( 0usize $( + $crate::__implement_decl_unit_to_one!($unit) )* )
};
}
#[doc(hidden)]
#[macro_export]
macro_rules! __implement_decl_unit_to_one {
( $unit:tt ) => {
1usize
};
}
#[doc(hidden)]
#[macro_export]
macro_rules! __implement_decl_per_iface_impls {
($name:ident, $impl_name:ident, $(($iface:ident),)+ ) => {
$crate::__implement_decl_per_iface_impls!(
@walk
name: $name,
impl_name: $impl_name,
index: [ ],
remaining: [ $( ($iface) )+ ]
);
};
(@walk
name: $name:ident,
impl_name: $impl_name:ident,
index: [ $($index:tt)* ],
remaining: [ ($iface:ident) $($rest:tt)* ]
) => {
impl ::core::convert::From<$name> for $iface {
#[inline(always)]
fn from(this: $name) -> Self {
let com_object = $crate::ComObject::new(this);
com_object.into_interface()
}
}
impl $crate::ComObjectInterface<$iface> for $impl_name {
#[inline(always)]
fn as_interface_ref(&self) -> $crate::InterfaceRef<'_, $iface> {
unsafe { ::core::mem::transmute(&self.$iface) }
}
}
impl $crate::AsImpl<$name> for $iface {
#[inline(always)]
unsafe fn as_impl_ptr(&self) -> ::core::ptr::NonNull<$name> {
unsafe {
let this = $crate::Interface::as_raw(self);
let this = (this as *mut *mut ::core::ffi::c_void)
.sub($crate::__implement_decl_index_plus_two!($($index)*))
as *mut $impl_name;
::core::ptr::NonNull::new_unchecked(
::core::ptr::addr_of!((*this).this) as *const $name as *mut $name,
)
}
}
}
$crate::__implement_decl_per_iface_impls!(
@walk
name: $name,
impl_name: $impl_name,
index: [ $($index)* () ],
remaining: [ $($rest)* ]
);
};
(@walk
name: $name:ident,
impl_name: $impl_name:ident,
index: [ $($index:tt)* ],
remaining: [ ]
) => {};
}
#[doc(hidden)]
#[macro_export]
macro_rules! __implement_decl_index_plus_two {
( $($unit:tt)* ) => {
( $crate::__implement_decl_count_units!($($unit)*) + 2usize )
};
}
#[doc(hidden)]
#[macro_export]
macro_rules! __implement_decl_g_zip {
(@zip
ctx: $ctx:tt,
names: [ $name_head:ident $($name_rest:ident)* ],
tys: [ $ty_head:ty $(, $ty_rest:ty)* $(,)? ],
acc: [ $($acc:tt)* ]
) => {
$crate::__implement_decl_g_zip! {
@zip
ctx: $ctx,
names: [ $($name_rest)* ],
tys: [ $($ty_rest),* ],
acc: [ $($acc)* ($name_head : $ty_head) ]
}
};
(@zip
ctx: {
generics: [ $($gp:ident),+ ],
wc: { $($wc:tt)* },
vis: $impl_vis:vis,
name: $name:ident,
impl_name: $impl_name:ident,
},
names: [ $($unused:ident)* ],
tys: [ ],
acc: [ $( ($iface:ident : $ifty:ty) )+ ]
) => {
$crate::__implement_decl_g_first_iface! {
@find
generics: [ $($gp),+ ],
wc: { $($wc)* },
vis: $impl_vis,
name: $name,
impl_name: $impl_name,
remaining: [ $( ($iface : $ifty) )+ ]
}
$crate::__implement_decl_g_per_iface_impls! {
generics: [ $($gp),+ ],
wc: { $($wc)* },
name: $name,
impl_name: $impl_name,
interfaces: [ $( ($iface : $ifty) )+ ]
}
};
}
#[doc(hidden)]
#[macro_export]
macro_rules! __implement_decl_g_first_iface {
(@find
generics: [ $($gp:ident),+ ],
wc: { $($wc:tt)* },
vis: $impl_vis:vis,
name: $name:ident,
impl_name: $impl_name:ident,
remaining: [ ($first_iface:ident : $first_ifty:ty) $($rest:tt)* ]
) => {
$crate::__implement_decl_g_struct! {
@walk
generics: [ $($gp),+ ],
wc: { $($wc)* },
vis: $impl_vis,
name: $name,
impl_name: $impl_name,
first_ifty: $first_ifty,
fields: { },
consts: { },
inits: { },
qi_pairs: [ ],
offset: [ () () ],
remaining: [ ($first_iface : $first_ifty) $($rest)* ]
}
};
}
#[doc(hidden)]
#[macro_export]
macro_rules! __implement_decl_g_struct {
(@walk
generics: [ $($gp:ident),+ ],
wc: { $($wc:tt)* },
vis: $impl_vis:vis,
name: $name:ident,
impl_name: $impl_name:ident,
first_ifty: $first_ifty:ty,
fields: { $($fields:tt)* },
consts: { $($consts:tt)* },
inits: { $($inits:tt)* },
qi_pairs: [ $($qi_pairs:tt)* ],
offset: [ $($offset:tt)* ],
remaining: [ ($iface:ident : $ifty:ty) $($rest:tt)* ]
) => {
$crate::__implement_decl_g_struct! {
@walk
generics: [ $($gp),+ ],
wc: { $($wc)* },
vis: $impl_vis,
name: $name,
impl_name: $impl_name,
first_ifty: $first_ifty,
fields: {
$($fields)*
#[allow(non_snake_case)]
pub $iface: &'static <$ifty as $crate::Interface>::Vtable,
},
consts: {
$($consts)*
#[allow(non_upper_case_globals)]
const $iface: <$ifty as $crate::Interface>::Vtable =
<<$ifty as $crate::Interface>::Vtable>::new::<
Self,
{ $crate::__implement_decl_offset_negate!($($offset)*) },
>();
},
inits: {
$($inits)*
$iface: &<$impl_name < $($gp),+ >>::$iface,
},
qi_pairs: [ $($qi_pairs)* ($iface : $ifty) ],
offset: [ $($offset)* () ],
remaining: [ $($rest)* ]
}
};
(@walk
generics: [ $($gp:ident),+ ],
wc: { $($wc:tt)* },
vis: $impl_vis:vis,
name: $name:ident,
impl_name: $impl_name:ident,
first_ifty: $first_ifty:ty,
fields: { $($fields:tt)* },
consts: { $($consts:tt)* },
inits: { $($inits:tt)* },
qi_pairs: [ $(($qi_iface:ident : $qi_ifty:ty))* ],
offset: [ $($offset:tt)* ],
remaining: [ ]
) => {
#[repr(C)]
#[allow(non_camel_case_types, non_snake_case)]
$impl_vis struct $impl_name < $($gp),+ >
where $($wc)*
{
pub base: $crate::ComposeBase,
pub identity: &'static $crate::IInspectable_Vtbl,
$($fields)*
pub this: $name < $($gp),+ >,
pub count: $crate::imp::WeakRefCount,
}
impl< $($gp),+ > $impl_name < $($gp),+ >
where $($wc)*
{
#[allow(non_upper_case_globals)]
const __VTABLE_IDENTITY: $crate::IInspectable_Vtbl =
<$crate::IInspectable_Vtbl>::new::<Self, $first_ifty, -1>();
$($consts)*
}
impl< $($gp),+ > $name < $($gp),+ >
where $($wc)*
{
#[doc(hidden)]
#[inline(always)]
#[allow(non_snake_case)]
pub fn into_outer(self) -> $impl_name < $($gp),+ > {
$impl_name {
base: $crate::ComposeBase::new(),
identity: &<$impl_name < $($gp),+ >>::__VTABLE_IDENTITY,
$($inits)*
this: self,
count: $crate::imp::WeakRefCount::new(),
}
}
}
impl< $($gp),+ > ::core::ops::Deref for $impl_name < $($gp),+ >
where $($wc)*
{
type Target = $name < $($gp),+ >;
#[inline(always)]
fn deref(&self) -> &Self::Target {
&self.this
}
}
impl< $($gp),+ > $crate::IUnknownImpl for $impl_name < $($gp),+ >
where $($wc)*
{
type Impl = $name < $($gp),+ >;
$crate::__implement_decl_iunknown_methods! {
qi: [ $( ($qi_iface : $qi_ifty) )* ]
}
}
impl< $($gp),+ > $crate::ComObjectInner for $name < $($gp),+ >
where $($wc)*
{
type Outer = $impl_name < $($gp),+ >;
fn into_object(self) -> $crate::ComObject<Self> {
let boxed = $crate::imp::box_new(self.into_outer());
unsafe {
let ptr = $crate::imp::box_into_raw(boxed);
$crate::ComObject::from_raw(::core::ptr::NonNull::new_unchecked(ptr))
}
}
}
$crate::__implement_decl_shared_tail! {
gen: [ $($gp),+ ],
wc: { $($wc)* },
name: $name,
impl_name: $impl_name,
}
};
}
#[doc(hidden)]
#[macro_export]
macro_rules! __implement_decl_g_per_iface_impls {
(
generics: [ $($gp:ident),+ ],
wc: { $($wc:tt)* },
name: $name:ident,
impl_name: $impl_name:ident,
interfaces: [ $( ($iface:ident : $ifty:ty) )+ ]
) => {
$crate::__implement_decl_g_per_iface_impls! {
@walk
generics: [ $($gp),+ ],
wc: { $($wc)* },
name: $name,
impl_name: $impl_name,
index: [ ],
remaining: [ $( ($iface : $ifty) )+ ]
}
};
(@walk
generics: [ $($gp:ident),+ ],
wc: { $($wc:tt)* },
name: $name:ident,
impl_name: $impl_name:ident,
index: [ $($index:tt)* ],
remaining: [ ($iface:ident : $ifty:ty) $($rest:tt)* ]
) => {
impl< $($gp),+ > ::core::convert::From<$name < $($gp),+ >> for $ifty
where $($wc)*
{
#[inline(always)]
fn from(this: $name < $($gp),+ >) -> Self {
let com_object = $crate::ComObject::new(this);
com_object.into_interface()
}
}
impl< $($gp),+ > $crate::ComObjectInterface<$ifty> for $impl_name < $($gp),+ >
where $($wc)*
{
#[inline(always)]
fn as_interface_ref(&self) -> $crate::InterfaceRef<'_, $ifty> {
unsafe { ::core::mem::transmute(&self.$iface) }
}
}
impl< $($gp),+ > $crate::AsImpl<$name < $($gp),+ >> for $ifty
where $($wc)*
{
#[inline(always)]
unsafe fn as_impl_ptr(&self) -> ::core::ptr::NonNull<$name < $($gp),+ >> {
unsafe {
let this = $crate::Interface::as_raw(self);
let this = (this as *mut *mut ::core::ffi::c_void)
.sub($crate::__implement_decl_index_plus_two!($($index)*))
as *mut $impl_name < $($gp),+ >;
::core::ptr::NonNull::new_unchecked(
::core::ptr::addr_of!((*this).this)
as *const $name < $($gp),+ >
as *mut $name < $($gp),+ >,
)
}
}
}
$crate::__implement_decl_g_per_iface_impls! {
@walk
generics: [ $($gp),+ ],
wc: { $($wc)* },
name: $name,
impl_name: $impl_name,
index: [ $($index)* () ],
remaining: [ $($rest)* ]
}
};
(@walk
generics: [ $($gp:ident),+ ],
wc: { $($wc:tt)* },
name: $name:ident,
impl_name: $impl_name:ident,
index: [ $($index:tt)* ],
remaining: [ ]
) => {};
}