mirror of https://github.com/python/cpython
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:
parent
63d867e95c
commit
c8bc5377ac
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue