From: David Kastrup Date: Wed, 1 Jun 2016 17:38:35 +0000 (+0200) Subject: Issue 4873/1: operator SCM & () for Protected_scm X-Git-Tag: release/2.19.43-1~17 X-Git-Url: https://git.donarmstrong.com/?a=commitdiff_plain;h=91723da7360b372904979b2d572f3f941ebbc924;p=lilypond.git Issue 4873/1: operator SCM & () for Protected_scm This allows passing SCM reference parameters that are actually based on Protected_scm. --- diff --git a/lily/include/protected-scm.hh b/lily/include/protected-scm.hh index 82b1fed11f..0115cb9f9f 100644 --- a/lily/include/protected-scm.hh +++ b/lily/include/protected-scm.hh @@ -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 */ diff --git a/lily/protected-scm.cc b/lily/protected-scm.cc index 6f6ce7c744..75091e1901 100644 --- a/lily/protected-scm.cc +++ b/lily/protected-scm.cc @@ -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_); }