#[macro_export]
macro_rules! sel {
($name:ident) => ({
#[inline(always)]
fn register_sel(name_with_nul: &str) -> $crate::runtime::Sel {
let ptr = name_with_nul.as_ptr() as *const i8;
unsafe { $crate::runtime::sel_registerName(ptr) }
}
register_sel(concat!(stringify!($name), '\0'))
});
($($name:ident :)+) => ({
#[inline(always)]
fn register_sel(name_with_nul: &str) -> $crate::runtime::Sel {
let ptr = name_with_nul.as_ptr() as *const i8;
unsafe { $crate::runtime::sel_registerName(ptr) }
}
register_sel(concat!($(stringify!($name), ':'),+, '\0'))
});
}
#[macro_export]
macro_rules! msg_send {
($obj:expr, $name:ident) => ({
let sel = sel!($name);
let ptr = $crate::to_obj_ptr(&$obj);
$crate::runtime::objc_msgSend(ptr, sel)
});
($obj:expr, $($name:ident : $arg:expr)+) => ({
let sel = sel!($($name:)+);
let ptr = $crate::to_obj_ptr(&$obj);
$crate::runtime::objc_msgSend(ptr, sel $(,$arg)+)
});
}
#[macro_export]
macro_rules! encode_message_impl {
($code:expr, $name:ident) => (
encode_message_impl!($code, $name,);
);
($code:expr, $name:ident, $($t:ident),*) => (
impl<'a $(, $t)*> $crate::Encode for &'a $name<$($t),*> {
fn code() -> $crate::Encoding<&'a $name<$($t),*>> {
$crate::Encoding($code)
}
}
impl<'a $(, $t)*> $crate::Encode for &'a mut $name<$($t),*> {
fn code() -> $crate::Encoding<&'a mut $name<$($t),*>> {
$crate::Encoding($code)
}
}
impl<'a $(, $t)*> $crate::Encode for Option<&'a $name<$($t),*>> {
fn code() -> $crate::Encoding<Option<&'a $name<$($t),*>>> {
$crate::Encoding($code)
}
}
impl<'a $(, $t)*> $crate::Encode for Option<&'a mut $name<$($t),*>> {
fn code() -> $crate::Encoding<Option<&'a mut $name<$($t),*>>> {
$crate::Encoding($code)
}
}
impl<$($t),*> $crate::Encode for *const $name<$($t),*> {
fn code() -> $crate::Encoding<*const $name<$($t),*>> {
$crate::Encoding($code)
}
}
impl<$($t),*> $crate::Encode for *mut $name<$($t),*> {
fn code() -> $crate::Encoding<*mut $name<$($t),*>> {
$crate::Encoding($code)
}
}
);
}
#[macro_export]
macro_rules! method {
(
($self_ty:ty)$self_name:ident,
$name:ident
; $body:block
) => ({
method!(-$name,; sel!($name), $body, (), $self_name: $self_ty,)
});
(
($self_ty:ty)$self_name:ident,
$name:ident
-> $ret_ty:ty, $body:block
) => ({
method!(-$name,; sel!($name), $body, $ret_ty, $self_name: $self_ty,)
});
(
($self_ty:ty)$self_name:ident,
$($name:ident : ($arg_ty:ty) $arg_name:ident),+
; $body:block
) => ({
method!($(-$name,)+; sel!($($name:)+), $body, (), $self_name: $self_ty, $($arg_name: $arg_ty),+)
});
(
($self_ty:ty)$self_name:ident,
$($name:ident : ($arg_ty:ty) $arg_name:ident),+
-> $ret_ty:ty, $body:block
) => ({
method!($(-$name,)+; sel!($($name:)+), $body, $ret_ty, $self_name: $self_ty, $($arg_name: $arg_ty),+)
});
(
-$first_name:ident, $(-$next_name:ident,)*;
$sel:expr, $body:block, $ret_ty:ty,
$self_name:ident : $self_ty:ty, $($arg_name:ident : $arg_ty:ty),*
) => ({
#[allow(non_snake_case)]
extern fn $first_name($self_name: $self_ty, _cmd: $crate::runtime::Sel $(, $arg_name: $arg_ty)*) -> $ret_ty $body
let imp: $crate::runtime::Imp = unsafe { ::std::mem::transmute($first_name) };
let mut types = $crate::encode::<$ret_ty>().to_string();
types.push_str($crate::encode::<$self_ty>());
types.push_str($crate::encode::<$crate::runtime::Sel>());
$(types.push_str($crate::encode::<$arg_ty>());)*
$crate::MethodDecl { sel: $sel, imp: imp, types: types }
});
}