]> git.donarmstrong.com Git - lilypond.git/commitdiff
Issue 4873/1: operator SCM & () for Protected_scm
authorDavid Kastrup <dak@gnu.org>
Wed, 1 Jun 2016 17:38:35 +0000 (19:38 +0200)
committerDavid Kastrup <dak@gnu.org>
Mon, 6 Jun 2016 08:03:55 +0000 (10:03 +0200)
This allows passing SCM reference parameters that are
actually based on Protected_scm.

lily/include/protected-scm.hh
lily/protected-scm.cc

index 82b1fed11f95b2beb1f474b72e016fd2c6166d8d..0115cb9f9ff6e2d388dd2fc714ec5639cdcc180c 100644 (file)
@@ -46,12 +46,14 @@ class Protected_scm
   static SCM list_;
   static SCM last_;
   Protected_scm (Protected_scm const &);
+  void protectify (SCM);
 public:
   Protected_scm ();
   Protected_scm (SCM);
   Protected_scm &operator = (SCM);
   Protected_scm &operator = (Protected_scm const &);
-  operator SCM () const;
+  operator const SCM & () const;
+  operator SCM & ();
 };
 
 #endif /* PROTECTED_SCM_HH */
index 6f6ce7c7442152fbd6def56d62e1fd49b24a4b5d..75091e19015ce3d78e87dd208be3fae1cf2b9f73 100644 (file)
@@ -40,6 +40,17 @@ Protected_scm::Protected_scm (SCM s)
 SCM Protected_scm::list_ = SCM_EOL;
 SCM Protected_scm::last_ = SCM_EOL;
 
+void
+Protected_scm::protectify (SCM s)
+{
+  s = scm_list_1 (s);
+  if (SCM_CONSP (last_))
+    SCM_SETCDR (last_, s);
+  else
+    list_ = scm_permanent_object (s);
+  last_ = object_ = s;
+}
+
 Protected_scm &
 Protected_scm::operator = (SCM s)
 {
@@ -48,14 +59,7 @@ Protected_scm::operator = (SCM s)
   else if (SCM_IMP (s))
     object_ = s;
   else
-    {
-      s = scm_list_1 (s);
-      if (SCM_CONSP (last_))
-        SCM_SETCDR (last_, s);
-      else
-        list_ = scm_permanent_object (s);
-      last_ = object_ = s;
-    }
+    protectify (s);
 
   return *this;
 }
@@ -66,7 +70,17 @@ Protected_scm::operator = (Protected_scm const &s)
   return *this = (SCM) s;
 }
 
-Protected_scm::operator SCM () const
+Protected_scm::operator SCM const & () const
 {
-  return SCM_CONSP (object_) ? SCM_CAR (object_) : object_;
+  return SCM_CONSP (object_) ? *SCM_CARLOC (object_) : object_;
+}
+
+Protected_scm::operator SCM & ()
+{
+  // The reference may be used to overwrite an immediate value with a
+  // non-immediate one, so we _have_ to create full protection.
+  if (!SCM_CONSP (object_))
+    protectify (object_);
+
+  return *SCM_CARLOC (object_);
 }