X-Git-Url: https://git.donarmstrong.com/?a=blobdiff_plain;f=lily%2Finclude%2Fsmobs.hh;h=9ccaa61345565a02a4a50d5ac6d402389993b934;hb=8c59e9496cf80f99423dca2f6875db2a8c21f16c;hp=ee6af16162be9da50d33da46753708a99d22718d;hpb=1a3796c7166c453fc1ef5d30858e6bbb88fdb59f;p=lilypond.git diff --git a/lily/include/smobs.hh b/lily/include/smobs.hh index ee6af16162..9ccaa61345 100644 --- a/lily/include/smobs.hh +++ b/lily/include/smobs.hh @@ -97,12 +97,10 @@ CALLING INTERFACE - Common public methods to C++ smob objects: + Common global functions for accessing C++ smob objects: - - unsmob (SCM x) - unpacks X and returns pointer to the C++ object, - or 0 if it has the wrong type. This can be used as a boolean - condition at C++ level. - - smob_p (SCM x) returns #t or #f at Scheme level. + - unsmob (SCM x) - unpack X and return a pointer to the C++ object, + or 0 if it has the wrong type. IMPLEMENTATION @@ -153,11 +151,11 @@ class Smob_base static Scm_init scm_init_; static void init (void); static string smob_name_; +protected: static Super *unchecked_unsmob (SCM s) { return reinterpret_cast (SCM_SMOB_DATA (s)); } -protected: // reference scm_init_ in smob_tag which is sure to be called. The // constructor, in contrast, may not be called at all in classes // like Smob1. @@ -179,11 +177,11 @@ private: // Most default functions are do-nothings. void init() will // recognize their address when not overriden and will then refrain // altogether from passing the the respective callbacks to GUILE. - SCM mark_smob (void); + SCM mark_smob (void) const; static SCM mark_trampoline (SCM); // Used for calling mark_smob static size_t free_smob (SCM obj); static SCM equal_p (SCM, SCM); - int print_smob (SCM, scm_print_state *); + int print_smob (SCM, scm_print_state *) const; static int print_trampoline (SCM, SCM, scm_print_state *); static void smob_proc_init (scm_t_bits) { }; @@ -215,7 +213,12 @@ private: } // Well, function template argument packs are a C++11 feature. So - // we just define a bunch of trampolines manually. + // we just define a bunch of trampolines manually. It turns out + // that GUILE 1.8.8 cannot actually make callable structures with + // more than 3 arguments anyway. That's surprising, to say the + // least, but in emergency situations one can always use a "rest" + // argument and take it apart manually. + template static SCM smob_trampoline (SCM self) { @@ -237,7 +240,6 @@ private: return (Super::unchecked_unsmob (self)->*pmf)(arg1, arg2, arg3); } -public: static bool is_smob (SCM s) { return SCM_SMOB_PREDICATE (smob_tag (), s); @@ -246,18 +248,18 @@ public: { return is_smob (s) ? SCM_BOOL_T : SCM_BOOL_F; } - static Super *unsmob (SCM s) - { - return is_smob (s) ? Super::unchecked_unsmob (s) : 0; - } -}; -// derived_unsmob includes a dynamic_cast: + template + friend T *unsmob (SCM s); + + template + friend T *ly_assert_smob (SCM s, int number, const char *fun); +}; template -inline T *derived_unsmob (SCM arg) +inline T *unsmob (SCM s) { - return dynamic_cast (T::unsmob (arg)); + return T::is_smob (s) ? dynamic_cast (T::unchecked_unsmob (s)) : 0; } // Simple smobs