summaryrefslogtreecommitdiffstats
path: root/Objects
diff options
context:
space:
mode:
authorVictor Stinner <victor.stinner@gmail.com>2013-11-04 10:08:10 (GMT)
committerVictor Stinner <victor.stinner@gmail.com>2013-11-04 10:08:10 (GMT)
commitc8bc5377ac59c6e6af5c0e925fa0af7d9df7ebc0 (patch)
treef1ebf7f7213b38f578e9bee21b168057944e7a7d /Objects
parent63d867e95c377ad91247051ab85a6294ed14cb35 (diff)
downloadcpython-c8bc5377ac59c6e6af5c0e925fa0af7d9df7ebc0.zip
cpython-c8bc5377ac59c6e6af5c0e925fa0af7d9df7ebc0.tar.gz
cpython-c8bc5377ac59c6e6af5c0e925fa0af7d9df7ebc0.tar.bz2
Issue #16286: write a new subfunction bytes_compare_eq()
* cleanup bytes_richcompare() * PyUnicode_RichCompare(): replace a test with a XOR
Diffstat (limited to 'Objects')
-rw-r--r--Objects/bytesobject.c84
-rw-r--r--Objects/unicodeobject.c8
2 files changed, 50 insertions, 42 deletions
diff --git a/Objects/bytesobject.c b/Objects/bytesobject.c
index 529c6347..9aa3ee2 100644
--- a/Objects/bytesobject.c
+++ b/Objects/bytesobject.c
@@ -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;
- }
- 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;
+ 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;
}
- result = c ? Py_True : Py_False;
- out:
+
Py_INCREF(result);
return result;
}
diff --git a/Objects/unicodeobject.c b/Objects/unicodeobject.c
index 01e5355..17ae481 100644
--- a/Objects/unicodeobject.c
+++ b/Objects/unicodeobject.c
@@ -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);