]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
Patch #424335: Implement string_richcompare, remove string_compare.
authorMartin v. Löwis <martin@v.loewis.de>
Thu, 24 May 2001 16:56:35 +0000 (16:56 +0000)
committerMartin v. Löwis <martin@v.loewis.de>
Thu, 24 May 2001 16:56:35 +0000 (16:56 +0000)
               Use new _PyString_Eq in lookdict_string.

Include/stringobject.h
Objects/dictobject.c
Objects/stringobject.c

index 12df75a678958a9ec9d6b6425b68fd44b6bd34f7..fbcff314d1507bfd4e9d1856cf6656334f9726a8 100644 (file)
@@ -58,6 +58,7 @@ extern DL_IMPORT(char *) PyString_AsString(PyObject *);
 extern DL_IMPORT(void) PyString_Concat(PyObject **, PyObject *);
 extern DL_IMPORT(void) PyString_ConcatAndDel(PyObject **, PyObject *);
 extern DL_IMPORT(int) _PyString_Resize(PyObject **, int);
+extern DL_IMPORT(int) _PyString_Eq(PyObject *, PyObject*);
 extern DL_IMPORT(PyObject *) PyString_Format(PyObject *, PyObject *);
 extern DL_IMPORT(PyObject *) _PyString_FormatLong(PyObject*, int, int,
                                                  int, char**, int*);
index 2854efcdffeef31d9d466a9f9efdf58e3a13363a..d5700c9af66355f4956c8ab2eb9d22ee74b38703 100644 (file)
@@ -294,7 +294,7 @@ lookdict(dictobject *mp, PyObject *key, register long hash)
  * this assumption allows testing for errors during PyObject_Compare() to
  * be dropped; string-string comparisons never raise exceptions.  This also
  * means we don't need to go through PyObject_Compare(); we can always use
- * the tp_compare slot of the string type object directly.
+ * _PyString_Eq directly.
  *
  * This really only becomes meaningful if proper error handling in lookdict()
  * is too expensive.
@@ -308,7 +308,6 @@ lookdict_string(dictobject *mp, PyObject *key, register long hash)
        register unsigned int mask = mp->ma_size-1;
        dictentry *ep0 = mp->ma_table;
        register dictentry *ep;
-       cmpfunc compare = PyString_Type.tp_compare;
 
        /* make sure this function doesn't have to handle non-string keys */
        if (!PyString_Check(key)) {
@@ -328,7 +327,7 @@ lookdict_string(dictobject *mp, PyObject *key, register long hash)
                freeslot = ep;
        else {
                if (ep->me_hash == hash
-                   && compare(ep->me_key, key) == 0) {
+                   && _PyString_Eq(ep->me_key, key)) {
                        return ep;
                }
                freeslot = NULL;
@@ -347,7 +346,7 @@ lookdict_string(dictobject *mp, PyObject *key, register long hash)
                if (ep->me_key == key
                    || (ep->me_hash == hash
                        && ep->me_key != dummy
-                       && compare(ep->me_key, key) == 0))
+                       && _PyString_Eq(ep->me_key, key)))
                        return ep;
                if (ep->me_key == dummy && freeslot == NULL)
                        freeslot = ep;
index cf6421a024b0cabc43689684aa1f18faa28d9ca8..da49d814f756adf16abd7fa3724a6a4d6d0bdc4a 100644 (file)
@@ -630,20 +630,79 @@ string_item(PyStringObject *a, register int i)
        return v;
 }
 
-static int
-string_compare(PyStringObject *a, PyStringObject *b)
+static PyObject*
+string_richcompare(PyStringObject *a, PyStringObject *b, int op)
 {
-       int len_a = a->ob_size, len_b = b->ob_size;
-       int min_len = (len_a < len_b) ? len_a : len_b;
-       int cmp;
+       int c;
+       int len_a, len_b;
+       int min_len;
+       PyObject *result;
+
+       /* One of the objects is a string object. Make sure the
+          other one is one, too.  */
+       if (a->ob_type != b->ob_type) {
+               result = Py_NotImplemented;
+               goto out;
+       }
+       if (a == b) {
+               switch (op) {
+               case Py_EQ:case Py_LE:case Py_GE:
+                       result = Py_True;
+                       goto out;
+               case Py_NE:case Py_LT:case Py_GT:
+                       result = Py_False;
+                       goto out;
+               }
+       }
+       if (op == Py_EQ) {
+               /* Supporting Py_NE here as well does not save
+                  much time, since Py_NE is rarely used.  */
+               if (a->ob_size == b->ob_size
+                   && (a->ob_sval[0] == b->ob_sval[0]
+                       && memcmp(a->ob_sval, b->ob_sval, 
+                                 a->ob_size) == 0)) {
+                       result = Py_True;
+               } else {
+                       result = Py_False;
+               }
+               goto out;
+       }
+       len_a = a->ob_size; len_b = b->ob_size;
+       min_len = (len_a < len_b) ? len_a : len_b;
        if (min_len > 0) {
-               cmp = Py_CHARMASK(*a->ob_sval) - Py_CHARMASK(*b->ob_sval);
-               if (cmp == 0)
-                       cmp = memcmp(a->ob_sval, b->ob_sval, min_len);
-               if (cmp != 0)
-                       return cmp;
+               c = Py_CHARMASK(*a->ob_sval) - Py_CHARMASK(*b->ob_sval);
+               if (c==0)
+                       c = memcmp(a->ob_sval, b->ob_sval, min_len);
+       }else
+               c = 0;
+       if (c == 0)
+               c = (len_a < len_b) ? -1 : (len_a > len_b) ? 1 : 0;
+       switch (op) {
+       case Py_LT: c = c <  0; break;
+       case Py_LE: c = c <= 0; break;
+       case Py_EQ: assert(0);  break; /* unreachable */
+       case Py_NE: c = c != 0; break;
+       case Py_GT: c = c >  0; break;
+       case Py_GE: c = c >= 0; break;
+       default:
+               result = Py_NotImplemented;
+               goto out;
        }
-       return (len_a < len_b) ? -1 : (len_a > len_b) ? 1 : 0;
+       result = c ? Py_True : Py_False;
+  out:
+       Py_INCREF(result);
+       return result;
+}
+
+int
+_PyString_Eq(PyObject *o1, PyObject *o2)
+{
+       PyStringObject *a, *b;
+       a = (PyStringObject*)o1;
+       b = (PyStringObject*)o2;
+        return a->ob_size == b->ob_size
+          && *a->ob_sval == *b->ob_sval
+          && memcmp(a->ob_sval, b->ob_sval, a->ob_size) == 0;
 }
 
 static long
@@ -2466,7 +2525,7 @@ PyTypeObject PyString_Type = {
        (printfunc)string_print, /*tp_print*/
        (getattrfunc)string_getattr,            /*tp_getattr*/
        0,              /*tp_setattr*/
-       (cmpfunc)string_compare, /*tp_compare*/
+       0,              /*tp_compare*/
        (reprfunc)string_repr, /*tp_repr*/
        0,              /*tp_as_number*/
        &string_as_sequence,    /*tp_as_sequence*/
@@ -2479,6 +2538,12 @@ PyTypeObject PyString_Type = {
        &string_as_buffer,      /*tp_as_buffer*/
        Py_TPFLAGS_DEFAULT,     /*tp_flags*/
        0,              /*tp_doc*/
+       0,              /*tp_traverse*/
+       0,              /*tp_clear*/
+       (richcmpfunc)string_richcompare,        /*tp_richcompare*/
+       0,              /*tp_weaklistoffset*/
+       0,              /*tp_iter*/
+       0,              /*tp_iternext*/
 };
 
 void