// (where it will mask the private template member) rather than
// specializing a different template function/pointer.
//
- // Since we consider those internal-only, two of them are actually
- // implemented as literal zero constant. That allows us to fall
- // back to GUILE's default implementation. Arguably the same could
- // be done for print_smob, but the resulting default output of, say,
- // #<Context_mod 0x7352414> would depend on memory layout, thus
- // being unsuitable for regtest comparisons unless filtered.
-
- SCM mark_smob (void); // Should not be inline since we do an address
- // comparison
+ // 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);
static SCM mark_trampoline (SCM); // Used for calling mark_smob
- static const int equal_p = 0;
- static const int smob_proc = 0;
- static const int smob_proc_signature_ = 0;
+ static size_t free_smob (SCM obj);
+ static SCM equal_p (SCM, SCM);
+
+ // print_smob is the exception. It is unconditionally passed to
+ // GUILE since the default output of, say, #<Context_mod 0x7352414>
+ // would depend on memory layout, thus being unsuitable for regtest
+ // comparisons unless filtered.
static int print_smob (SCM, SCM, scm_print_state *);
- static size_t free_smob (SCM obj)
- {
- delete Smob_base<Super>::unregister_ptr (obj);
- return 0;
- }
+
// type_p_name_ can be overriden in the Super class with a static
// const char [] string. This requires both a declaration in the
// class as well as a single instantiation outside. Using a
// in a single compilation unit. That requires just as much source
// code maintenance while being harder to understand and quite
// trickier in its failure symptoms when things go wrong. So we
- // just do things like with the other specializations.
+ // just use a static zero as "not here" indication.
static const int type_p_name_ = 0;
- // This macro is used in the Super class definition for making a
- // smob callable like a function. Declaration has to be public. It
- // may be either be completed with a semicolon in which case a
- // definition of the member function smob_proc has to be done
+
+ // LY_DECLARE_SMOB_PROC is used in the Super class definition for
+ // making a smob callable like a function. Declaration has to be
+ // public. It may be either be completed with a semicolon in which
+ // case a definition of the member function smob_proc has to be done
// outside of the class body, or the semicolon is left off and an
// inline function body is added immediately below. It would be
// nice if this were a non-static member function but it would seem
#define LY_DECLARE_SMOB_PROC(REQ, OPT, VAR, ARGLIST) \
static const int smob_proc_signature_ = ((REQ)<<8)|((OPT)<<4)|(VAR); \
static SCM smob_proc ARGLIST
+
// a separate LY_DEFINE_SMOB_PROC seems sort of pointless as it
// would just result in SCM CLASS::smob_proc ARGLIST
+ //
+ // The default case without function functionality is recognized by
+ // smob_proc_signature being -1.
+ static const int smob_proc = 0;
+ static const int smob_proc_signature_ = -1;
+
public:
static bool is_smob (SCM s)
{
}
};
-
+// Simple smobs
template <class Super>
class Simple_smob : public Smob_base<Super> {
public:
+ static size_t free_smob (SCM obj)
+ {
+ delete Smob_base<Super>::unregister_ptr (obj);
+ return 0;
+ }
SCM smobbed_copy () const
{
Super *p = new Super(*static_cast<const Super *> (this));
SCM self_scm_;
SCM protection_cons_;
public:
+ static size_t free_smob (SCM obj)
+ {
+ delete Smob_base<Super>::unregister_ptr (obj);
+ return 0;
+ }
SCM unprotected_smobify_self ()
{
self_scm_ = SCM_UNDEFINED;
return s;
}
-// Default, should not actually get called
+// Defaults, should not actually get called
template <class Super>
SCM
Smob_base<Super>::mark_smob ()
return SCM_UNSPECIFIED;
}
+template <class Super>
+size_t
+Smob_base<Super>::free_smob (SCM)
+{
+ return 0;
+}
+
+template <class Super>
+SCM
+Smob_base<Super>::equal_p (SCM, SCM)
+{
+ return SCM_BOOL_F;
+}
+
+// Default, will often get called
+
template <class Super>
int
Smob_base<Super>::print_smob (SCM, SCM p, scm_print_state *)
// While that's not a consideration for type_p_name_, it's easier
// doing it like the rest.
- if (Super::free_smob != 0)
+ if (&Super::free_smob != &Smob_base<Super>::free_smob)
scm_set_smob_free (smob_tag_, Super::free_smob);
if (&Super::mark_smob != &Smob_base<Super>::mark_smob)
scm_set_smob_mark (smob_tag_, Super::mark_trampoline);
- if (Super::print_smob != 0)
- scm_set_smob_print (smob_tag_, Super::print_smob);
- if (Super::equal_p != 0)
+ scm_set_smob_print (smob_tag_, Super::print_smob);
+ if (&Super::equal_p != &Smob_base<Super>::equal_p)
scm_set_smob_equalp (smob_tag_, Super::equal_p);
if (Super::type_p_name_ != 0)
{
scm_c_export (Super::type_p_name_, NULL);
}
ly_add_type_predicate ((void *) is_smob, smob_name_.c_str ());
- if (Super::smob_proc != 0)
+ if (Super::smob_proc_signature_ >= 0)
scm_set_smob_apply (smob_tag_,
(scm_t_subr)Super::smob_proc,
Super::smob_proc_signature_ >> 8,