} \
}
-#define LY_ASSERT_SMOB(klass, var, number) LY_ASSERT_TYPE(klass::is_smob, var, number)
+void ly_wrong_smob_arg (bool pred (SCM), SCM var, int number, const char *fun);
+
+// Could be just implemented using LY_ASSERT_TYPE, but this variant
+// saves a slight amount of code
+
+#define LY_ASSERT_SMOB(klass, var, number) \
+ { \
+ if (!klass::is_smob (var)) \
+ ly_wrong_smob_arg (klass::is_smob, var, number, __FUNCTION__); \
+ }
+
+// This variant is for the case where klass::unsmob might actually be
+// situated in a base class of klass
+#define LY_ASSERT_DERIVED_SMOB(klass, var, number) \
+ { \
+ if (!derived_unsmob<klass> (var)) \
+ ly_wrong_smob_arg (klass::is_smob, var, number, __FUNCTION__); \
+ }
#endif /* LILY_GUILE_MACROS_HH */
return true;
}
+void
+ly_wrong_smob_arg (bool pred (SCM), SCM var, int number, const char *fun)
+{
+ string type = predicate_to_typename ((void *) pred);
+ if (pred (var))
+ {
+ // Uh oh. derived_unsmob <T> delivered 0, yet
+ // T::is_smob delivers true. This means that T::is_smob is a
+ // matching check from a base class of T, but var is of an
+ // incompatible derived type.
+ type = string (_ ("Wrong kind of ")).append (type);
+ }
+ scm_wrong_type_arg_msg (mangle_cxx_identifier (fun).c_str (),
+ number, var, type.c_str ());
+}
+
+
/* some SCM abbrevs
zijn deze nou handig?