import objc.runtime.*; public import objc.runtime.(Id, SEL, Method, Protocol, BOOL, nil); private selector(name) = sel_registerName(cstring(name)); Class(name) = objc_getClass(cstring(name)); // TODO: choose objc_msgSend form based on storage class of return value msgSend(ReturnTypes, self: Id, _cmd: SEL, ...args) = CCodePointer[ (Id, SEL, ...Type(...args)), ReturnTypes ](objc_msgSend)(self, _cmd, ...args); record Selector[ReturnType, ...ArgTypes] { sel: SEL; } alias Void = static (); overload Selector(name, ReturnType, ...ArgTypes) = Selector[ReturnType, ...ArgTypes](selector(name)); [ReturnType, ...ArgTypes] overload call( sel: Selector[ReturnType, ...ArgTypes], self, ...args: ArgTypes ) = msgSend(ReturnType, self, sel.sel, ...args);