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<T> (SCM x) - unpack X and return a pointer to the C++ object,
+ or 0 if it has the wrong type.
IMPLEMENTATION
static Scm_init scm_init_;
static void init (void);
static string smob_name_;
+protected:
static Super *unchecked_unsmob (SCM s)
{
return reinterpret_cast<Super *> (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.
// 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) { };
}
// 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 <SCM (Super::*pmf)(void)>
static SCM smob_trampoline (SCM self)
{
return (Super::unchecked_unsmob (self)->*pmf)(arg1, arg2, arg3);
}
-public:
static bool is_smob (SCM s)
{
return SCM_SMOB_PREDICATE (smob_tag (), s);
{
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 <class T>
+ friend T *unsmob (SCM s);
+
+ template <class T>
+ friend T *ly_assert_smob (SCM s, int number, const char *fun);
+};
template <class T>
-inline T *derived_unsmob (SCM arg)
+inline T *unsmob (SCM s)
{
- return dynamic_cast<T *> (T::unsmob (arg));
+ return T::is_smob (s) ? dynamic_cast<T *> (T::unchecked_unsmob (s)) : 0;
}
// Simple smobs