Issue #16286: write a new subfunction bytes_compare_eq()

* cleanup bytes_richcompare()
* PyUnicode_RichCompare(): replace a test with a XOR
This commit is contained in:
Victor Stinner 2013-11-04 11:08:10 +01:00
parent 63d867e95c
commit c8bc5377ac
2 changed files with 50 additions and 42 deletions

View File

@ -802,6 +802,23 @@ bytes_item(PyBytesObject *a, Py_ssize_t i)
return PyLong_FromLong((unsigned char)a->ob_sval[i]);
}
Py_LOCAL(int)
bytes_compare_eq(PyBytesObject *a, PyBytesObject *b)
{
int cmp;
Py_ssize_t len;
len = Py_SIZE(a);
if (Py_SIZE(b) != len)
return 0;
if (a->ob_sval[0] != b->ob_sval[0])
return 0;
cmp = memcmp(a->ob_sval, b->ob_sval, len);
return (cmp == 0);
}
static PyObject*
bytes_richcompare(PyBytesObject *a, PyBytesObject *b, int op)
{
@ -822,53 +839,46 @@ bytes_richcompare(PyBytesObject *a, PyBytesObject *b, int op)
return NULL;
}
result = Py_NotImplemented;
goto out;
}
if (a == b) {
else if (a == b) {
switch (op) {
case Py_EQ:case Py_LE:case Py_GE:
result = Py_True;
goto out;
break;
case Py_NE:case Py_LT:case Py_GT:
result = Py_False;
goto out;
break;
}
}
if (op == Py_EQ) {
/* Supporting Py_NE here as well does not save
much time, since Py_NE is rarely used. */
if (Py_SIZE(a) == Py_SIZE(b)
&& (a->ob_sval[0] == b->ob_sval[0]
&& memcmp(a->ob_sval, b->ob_sval, Py_SIZE(a)) == 0)) {
result = Py_True;
} else {
result = Py_False;
else if (op == Py_EQ || op == Py_NE) {
int eq = bytes_compare_eq(a, b);
eq ^= (op == Py_NE);
result = eq ? Py_True : Py_False;
}
else {
len_a = Py_SIZE(a); len_b = Py_SIZE(b);
min_len = (len_a < len_b) ? len_a : len_b;
if (min_len > 0) {
c = Py_CHARMASK(*a->ob_sval) - Py_CHARMASK(*b->ob_sval);
if (c==0)
c = memcmp(a->ob_sval, b->ob_sval, min_len);
}
goto out;
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_GT: c = c > 0; break;
case Py_GE: c = c >= 0; break;
default:
assert(op != Py_EQ && op != Py_NE);
Py_RETURN_NOTIMPLEMENTED;
}
result = c ? Py_True : Py_False;
}
len_a = Py_SIZE(a); len_b = Py_SIZE(b);
min_len = (len_a < len_b) ? len_a : len_b;
if (min_len > 0) {
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;
}
result = c ? Py_True : Py_False;
out:
Py_INCREF(result);
return result;
}

View File

@ -10526,7 +10526,7 @@ unicode_compare(PyObject *str1, PyObject *str2)
#undef COMPARE
}
static int
Py_LOCAL(int)
unicode_compare_eq(PyObject *str1, PyObject *str2)
{
int kind;
@ -10630,10 +10630,8 @@ PyUnicode_RichCompare(PyObject *left, PyObject *right, int op)
if (op == Py_EQ || op == Py_NE) {
result = unicode_compare_eq(left, right);
if (op == Py_EQ)
v = TEST_COND(result);
else
v = TEST_COND(!result);
result ^= (op == Py_NE);
v = TEST_COND(result);
}
else {
result = unicode_compare(left, right);