[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
equal? and smob flags
From: |
Andreas Vögele |
Subject: |
equal? and smob flags |
Date: |
Mon, 6 Sep 2004 09:52:55 +0200 |
When comparing smobs of the same type but with different smob flags the
procedure scm_equal_p in eq.c returns #f since the cell types, which
include the smob flags, are not equal.
I'm wondering if this behaviour is really intended. IMHO it would be
more useful to ignore the flags in scm_equal_p when comparing smobs.
Instead developers could decide on their own whether to ignore or
consider the smob flags in their custom comparison function.
The macros SCM_CELL_TYPE and SCM_SMOB_FLAGS are defined in gc.h and
smob.h respectively:
#define SCM_CELL_TYPE(x) SCM_CELL_WORD_0 (x)
#define SCM_SMOB_FLAGS(SCM_CELL_WORD_0 (x) >> 16)
The comparison of smobs with different flags fails because of the
following conditional in scm_equal_p:
if (SCM_CELL_TYPE (x) != SCM_CELL_TYPE (y))
{
...
return SCM_BOOL_F;
}
I don't know if there's existing third-party code that relies on the
fact that the smob flags aren't ignored by scm_equal_p. But if such
code existed it code could be updated easily by adding two lines of
code to the comparison function:
SCM_SMOB_EQUALP (my_tag, my_equalp, x ,y)
{
if (SCM_SMOB_FLAGS (x) != SCM_SMOB_FLAGS (y))
return SCM_BOOL_F;
/* Existing code follows here */
...
}
I've included a patch that changes scm_equal_p so that smobs that
provide their own comparison function are compared before the cell type
is compared:
Index: libguile/eq.c
===================================================================
RCS file: /cvsroot/guile/guile/guile-core/libguile/eq.c,v
retrieving revision 1.51
diff -u -r1.51 eq.c
--- libguile/eq.c 17 Aug 2004 23:19:04 -0000 1.51
+++ libguile/eq.c 6 Sep 2004 07:03:46 -0000
@@ -157,6 +157,15 @@
}
if (SCM_TYP7 (x) == scm_tc7_string && SCM_TYP7 (y) == scm_tc7_string)
return scm_string_equal_p (x, y);
+ if (SCM_TYP7 (x) == scm_tc7_smob && SCM_TYP7 (y) == scm_tc7_smob
+ && SCM_SMOBNUM (x) == SCM_SMOBNUM (y))
+ {
+ int i = SCM_SMOBNUM (x);
+ if (!(i < scm_numsmob))
+ return SCM_BOOL_F;
+ if (scm_smobs[i].equalp)
+ return (scm_smobs[i].equalp) (x, y);
+ }
/* This ensures that types and scm_length are the same. */
if (SCM_CELL_TYPE (x) != SCM_CELL_TYPE (y))
{
@@ -194,16 +203,6 @@
case scm_tc7_vector:
case scm_tc7_wvect:
return scm_vector_equal_p (x, y);
- case scm_tc7_smob:
- {
- int i = SCM_SMOBNUM (x);
- if (!(i < scm_numsmob))
- return SCM_BOOL_F;
- if (scm_smobs[i].equalp)
- return (scm_smobs[i].equalp) (x, y);
- else
- break;
- }
#if SCM_HAVE_ARRAYS
case scm_tc7_bvect: case scm_tc7_uvect: case scm_tc7_ivect:
case scm_tc7_fvect: case scm_tc7_cvect: case scm_tc7_dvect:
- equal? and smob flags,
Andreas Vögele <=