-#define IMPLEMENT_SMOBS(CL)\
-long CL::smob_tag_;\
-static scm_smobfuns CL ## _funs = { \
- CL::mark_smob, CL::free_smob, \
- CL::print_smob, 0, \
-}; \
-void \
-CL::init_smobs () \
-{ \
- smob_tag_ = scm_newsmob (&CL ## _funs); \
-} \
+#include "smobs.hh"
+
+#define IMPLEMENT_TYPE_P(CL, FUNCNAME) \
+ SCM CL ## _type_p_proc; \
+ void init_type_ ## CL () \
+ { \
+ SCM subr = scm_c_define_gsubr (FUNCNAME, 1, 0, 0, \
+ (Scheme_function_unknown) CL::smob_p); \
+ CL ## _type_p_proc = subr; \
+ ly_add_function_documentation (subr, FUNCNAME, "(SCM x)", \
+ "Is @var{x} a @code{" #CL "} object?"); \
+ scm_c_export (FUNCNAME, NULL); \
+ } \
+ ADD_SCM_INIT_FUNC (init_type_ ## CL, init_type_ ## CL)
+
+#define IMPLEMENT_BASE_SMOBS(CL) \
+ void \
+ CL ## _type_adder () \
+ {\
+ ly_add_type_predicate ((void*) &CL::unsmob, #CL); \
+ }\
+ ADD_SCM_INIT_FUNC(CL ## _type_adder_ctor, \
+ CL ## _type_adder);\
+ const char *CL::smob_name_ = #CL; \
+ scm_t_bits CL::smob_tag_; \
+ SCM \
+ CL::smob_p (SCM s) \
+ { \
+ if (SCM_NIMP (s) && SCM_CELL_TYPE (s) == smob_tag_) \
+ return SCM_BOOL_T; \
+ else \
+ return SCM_BOOL_F; \