Listener (SCM callback, SCM target)
: callback_ (callback), target_ (target) { }
- void listen (SCM ev) const { scm_call_2 (callback_, target_, ev); }
-
- LY_DECLARE_SMOB_PROC (1, 0, 0, (SCM self, SCM ev))
+ LY_DECLARE_SMOB_PROC (&Listener::listen, 1, 0, 0)
+ SCM listen (SCM ev)
{
- Listener::unsmob (self)->listen (ev);
+ scm_call_2 (callback_, target_, ev);
return SCM_UNSPECIFIED;
}
Callback_wrapper (void (*trampoline) (SCM, SCM)) : trampoline_ (trampoline)
{ } // Private constructor, use only in make_smob
public:
- LY_DECLARE_SMOB_PROC (2, 0, 0, (SCM self, SCM target, SCM ev))
+ LY_DECLARE_SMOB_PROC (&Callback_wrapper::call, 2, 0, 0)
+ SCM call (SCM target, SCM ev)
{
- unsmob (self)->trampoline_ (target, ev);
+ trampoline_ (target, ev);
return SCM_UNSPECIFIED;
}
// Callback wrappers are for an unchanging entity, so we do the Lisp
static SCM equal_p (SCM, SCM);
int print_smob (SCM, scm_print_state *);
static int print_trampoline (SCM, SCM, scm_print_state *);
+ static void smob_proc_init (scm_t_bits) { };
// type_p_name_ can be overriden in the Super class with a static
// const char [] string. This requires both a declaration in the
static const int type_p_name_ = 0;
// LY_DECLARE_SMOB_PROC is used in the Super class definition for
- // making a smob callable like a function. Declaration has to be
- // public. It may be either be completed with a semicolon in which
- // case a definition of the member function smob_proc has to be done
- // outside of the class body, or the semicolon is left off and an
- // inline function body is added immediately below. It would be
- // nice if this were a non-static member function but it would seem
- // tricky to do the required trampolining for unsmobbing the first
- // argument of the callback and using it as a this pointer.
-#define LY_DECLARE_SMOB_PROC(REQ, OPT, VAR, ARGLIST) \
- static const int smob_proc_signature_ = ((REQ)<<8)|((OPT)<<4)|(VAR); \
- static SCM smob_proc ARGLIST
-
- // a separate LY_DEFINE_SMOB_PROC seems sort of pointless as it
- // would just result in SCM CLASS::smob_proc ARGLIST
- //
- // The default case without function functionality is recognized by
- // smob_proc_signature being -1.
- static const int smob_proc = 0;
- static const int smob_proc_signature_ = -1;
+ // making a smob callable like a function. Its first argument is a
+ // function member pointer constant, to a function taking the
+ // correct number of SCM arguments and returning SCM. The function
+ // itself has to be defined separately.
+
+#define LY_DECLARE_SMOB_PROC(PMF, REQ, OPT, VAR) \
+ static void smob_proc_init (scm_t_bits smob_tag) \
+ { \
+ scm_set_smob_apply (smob_tag, \
+ (scm_t_subr)smob_trampoline<PMF>, \
+ REQ, OPT, VAR); \
+ }
+
+ // Well, function template argument packs are a C++11 feature. So
+ // we just define a bunch of trampolines manually.
+ template <SCM (Super::*pmf)(void)>
+ static SCM smob_trampoline (SCM self)
+ {
+ return (Super::unchecked_unsmob (self)->*pmf)();
+ }
+ template <SCM (Super::*pmf)(SCM)>
+ static SCM smob_trampoline (SCM self, SCM arg1)
+ {
+ return (Super::unchecked_unsmob (self)->*pmf)(arg1);
+ }
+ template <SCM (Super::*pmf)(SCM, SCM)>
+ static SCM smob_trampoline (SCM self, SCM arg1, SCM arg2)
+ {
+ return (Super::unchecked_unsmob (self)->*pmf)(arg1, arg2);
+ }
+ template <SCM (Super::*pmf)(SCM, SCM, SCM)>
+ static SCM smob_trampoline (SCM self, SCM arg1, SCM arg2, SCM arg3)
+ {
+ return (Super::unchecked_unsmob (self)->*pmf)(arg1, arg2, arg3);
+ }
public:
static bool is_smob (SCM s)
class Unpure_pure_call : public Smob1<Unpure_pure_call>
{
public:
- LY_DECLARE_SMOB_PROC (2, 0, 1, (SCM self, SCM arg1, SCM arg2, SCM rest))
+ LY_DECLARE_SMOB_PROC (&Unpure_pure_call::call, 2, 0, 1)
+ SCM call (SCM arg1, SCM arg2, SCM rest)
{
- return scm_apply_0 (Unpure_pure_call::unsmob (self)->scm1 (),
+ return scm_apply_0 (scm1 (),
scm_call_2 (ly_lily_module_constant ("drop-right"),
scm_cons2 (arg1, arg2, rest),
scm_from_int (2)));