From: David Kastrup <dak@gnu.org>
Date: Thu, 28 Apr 2016 23:34:28 +0000 (+0200)
Subject: Issue 4842/2: Add Method_instance class
X-Git-Tag: release/2.19.42-1~14
X-Git-Url: https://git.donarmstrong.com/?a=commitdiff_plain;h=d061586179ac3febbb53f33734bd53d47498f273;p=lilypond.git

Issue 4842/2: Add Method_instance class

This is a lightweight container class combining an SCM method call
with a particular instance into a C++ callable.
---

diff --git a/lily/callback.cc b/lily/callback.cc
index fac40a02de..baab7b0614 100644
--- a/lily/callback.cc
+++ b/lily/callback.cc
@@ -22,3 +22,4 @@
 const char * const Callback_wrapper::type_p_name_ = 0;
 const char * const Callback2_wrapper::type_p_name_ = 0;
 const char * const Callback0_wrapper::type_p_name_ = 0;
+const char * const Method_instance::type_p_name_ = 0;
diff --git a/lily/include/callback.hh b/lily/include/callback.hh
index 7151d04478..963f4eb59c 100644
--- a/lily/include/callback.hh
+++ b/lily/include/callback.hh
@@ -146,4 +146,45 @@ public:
   }
 };
 
+// The following will usually be used unsmobbified, relying on its
+// constituents being protected independently.
+
+class Method_instance : public Simple_smob<Method_instance>
+{
+  SCM method_, instance_;
+public:
+  static const char * const type_p_name_; // = 0
+  LY_DECLARE_SMOB_PROC (&Method_instance::call, 0, 0, 1)
+  SCM call (SCM rest)
+  {
+    return scm_apply_1 (method_, instance_, rest);
+  }
+
+  Method_instance (SCM method, SCM instance)
+    : method_ (method), instance_ (instance)
+  { }
+  Method_instance (SCM method, Smob_core *instance)
+    : method_ (method), instance_ (instance->self_scm ())
+  { }
+  SCM method () const { return method_; }
+  SCM instance () const { return instance_; }
+  SCM operator () () const
+  {
+    return scm_call_1 (method_, instance_);
+  }
+  SCM operator () (SCM arg) const
+  {
+    return scm_call_2 (method_, instance_, arg);
+  }
+  SCM operator () (SCM arg1, SCM arg2) const
+  {
+    return scm_call_3 (method_, instance_, arg1, arg2);
+  }
+  SCM mark_smob () const
+  {
+    scm_gc_mark (method_);
+    return instance_;
+  }
+};
+
 #endif