summaryrefslogtreecommitdiffstats
path: root/Objects
diff options
context:
space:
mode:
authorGuido van Rossum <guido@python.org>2001-01-18 00:00:53 (GMT)
committerGuido van Rossum <guido@python.org>2001-01-18 00:00:53 (GMT)
commitf77bc62e7351a052f2127221afa43bbf442d8c96 (patch)
treebc666c767e65559e3336c73a93c8dee8e13abe1d /Objects
parent24f67d568cf878f53c647356aa4e446f7ae9de61 (diff)
downloadcpython-f77bc62e7351a052f2127221afa43bbf442d8c96.zip
cpython-f77bc62e7351a052f2127221afa43bbf442d8c96.tar.gz
cpython-f77bc62e7351a052f2127221afa43bbf442d8c96.tar.bz2
Same treatment as listobject.c:
- tuplecontains(): call RichCompare(Py_EQ). - Get rid of tuplecompare(), in favor of new tuplerichcompare() (a clone of list_compare()). - Aligned the comments for large struct initializers.
Diffstat (limited to 'Objects')
-rw-r--r--Objects/tupleobject.c147
1 files changed, 104 insertions, 43 deletions
diff --git a/Objects/tupleobject.c b/Objects/tupleobject.c
index be62d0f..d40f947 100644
--- a/Objects/tupleobject.c
+++ b/Objects/tupleobject.c
@@ -200,20 +200,6 @@ tuplerepr(PyTupleObject *v)
return s;
}
-static int
-tuplecompare(register PyTupleObject *v, register PyTupleObject *w)
-{
- register int len =
- (v->ob_size < w->ob_size) ? v->ob_size : w->ob_size;
- register int i;
- for (i = 0; i < len; i++) {
- int cmp = PyObject_Compare(v->ob_item[i], w->ob_item[i]);
- if (cmp != 0)
- return cmp;
- }
- return v->ob_size - w->ob_size;
-}
-
static long
tuplehash(PyTupleObject *v)
{
@@ -246,10 +232,11 @@ tuplecontains(PyTupleObject *a, PyObject *el)
int i, cmp;
for (i = 0; i < a->ob_size; ++i) {
- cmp = PyObject_Compare(el, PyTuple_GET_ITEM(a, i));
- if (cmp == 0)
+ cmp = PyObject_RichCompareBool(el, PyTuple_GET_ITEM(a, i),
+ Py_EQ);
+ if (cmp > 0)
return 1;
- if (PyErr_Occurred())
+ else if (cmp < 0)
return -1;
}
return 0;
@@ -384,15 +371,87 @@ tupletraverse(PyTupleObject *o, visitproc visit, void *arg)
return 0;
}
+static PyObject *
+tuplerichcompare(PyObject *v, PyObject *w, int op)
+{
+ PyTupleObject *vt, *wt;
+ int i;
+
+ if (!PyTuple_Check(v) || !PyTuple_Check(w)) {
+ Py_INCREF(Py_NotImplemented);
+ return Py_NotImplemented;
+ }
+
+ vt = (PyTupleObject *)v;
+ wt = (PyTupleObject *)w;
+
+ if (vt->ob_size != wt->ob_size && (op == Py_EQ || op == Py_NE)) {
+ /* Shortcut: if the lengths differ, the tuples differ */
+ PyObject *res;
+ if (op == Py_EQ)
+ res = Py_False;
+ else
+ res = Py_True;
+ Py_INCREF(res);
+ return res;
+ }
+
+ /* Search for the first index where items are different */
+ for (i = 0; i < vt->ob_size && i < wt->ob_size; i++) {
+ int k = PyObject_RichCompareBool(vt->ob_item[i],
+ wt->ob_item[i], Py_EQ);
+ if (k < 0)
+ return NULL;
+ if (!k)
+ break;
+ }
+
+ if (i >= vt->ob_size || i >= wt->ob_size) {
+ /* No more items to compare -- compare sizes */
+ int vs = vt->ob_size;
+ int ws = wt->ob_size;
+ int cmp;
+ PyObject *res;
+ switch (op) {
+ case Py_LT: cmp = vs < ws; break;
+ case Py_LE: cmp = ws <= ws; break;
+ case Py_EQ: cmp = vs == ws; break;
+ case Py_NE: cmp = vs != ws; break;
+ case Py_GT: cmp = vs > ws; break;
+ case Py_GE: cmp = vs >= ws; break;
+ default: return NULL; /* cannot happen */
+ }
+ if (cmp)
+ res = Py_True;
+ else
+ res = Py_False;
+ Py_INCREF(res);
+ return res;
+ }
+
+ /* We have an item that differs -- shortcuts for EQ/NE */
+ if (op == Py_EQ) {
+ Py_INCREF(Py_False);
+ return Py_False;
+ }
+ if (op == Py_NE) {
+ Py_INCREF(Py_True);
+ return Py_True;
+ }
+
+ /* Compare the final item again using the proper operator */
+ return PyObject_RichCompare(vt->ob_item[i], wt->ob_item[i], op);
+}
+
static PySequenceMethods tuple_as_sequence = {
- (inquiry)tuplelength, /*sq_length*/
- (binaryfunc)tupleconcat, /*sq_concat*/
- (intargfunc)tuplerepeat, /*sq_repeat*/
- (intargfunc)tupleitem, /*sq_item*/
- (intintargfunc)tupleslice, /*sq_slice*/
- 0, /*sq_ass_item*/
- 0, /*sq_ass_slice*/
- (objobjproc)tuplecontains, /*sq_contains*/
+ (inquiry)tuplelength, /* sq_length */
+ (binaryfunc)tupleconcat, /* sq_concat */
+ (intargfunc)tuplerepeat, /* sq_repeat */
+ (intargfunc)tupleitem, /* sq_item */
+ (intintargfunc)tupleslice, /* sq_slice */
+ 0, /* sq_ass_item */
+ 0, /* sq_ass_slice */
+ (objobjproc)tuplecontains, /* sq_contains */
};
PyTypeObject PyTuple_Type = {
@@ -401,24 +460,26 @@ PyTypeObject PyTuple_Type = {
"tuple",
sizeof(PyTupleObject) - sizeof(PyObject *) + PyGC_HEAD_SIZE,
sizeof(PyObject *),
- (destructor)tupledealloc, /*tp_dealloc*/
- (printfunc)tupleprint, /*tp_print*/
- 0, /*tp_getattr*/
- 0, /*tp_setattr*/
- (cmpfunc)tuplecompare, /*tp_compare*/
- (reprfunc)tuplerepr, /*tp_repr*/
- 0, /*tp_as_number*/
- &tuple_as_sequence, /*tp_as_sequence*/
- 0, /*tp_as_mapping*/
- (hashfunc)tuplehash, /*tp_hash*/
- 0, /*tp_call*/
- 0, /*tp_str*/
- 0, /*tp_getattro*/
- 0, /*tp_setattro*/
- 0, /*tp_as_buffer*/
- Py_TPFLAGS_DEFAULT | Py_TPFLAGS_GC, /*tp_flags*/
- 0, /*tp_doc*/
- (traverseproc)tupletraverse, /* tp_traverse */
+ (destructor)tupledealloc, /* tp_dealloc */
+ (printfunc)tupleprint, /* tp_print */
+ 0, /* tp_getattr */
+ 0, /* tp_setattr */
+ 0, /* tp_compare */
+ (reprfunc)tuplerepr, /* tp_repr */
+ 0, /* tp_as_number */
+ &tuple_as_sequence, /* tp_as_sequence */
+ 0, /* tp_as_mapping */
+ (hashfunc)tuplehash, /* tp_hash */
+ 0, /* tp_call */
+ 0, /* tp_str */
+ 0, /* tp_getattro */
+ 0, /* tp_setattro */
+ 0, /* tp_as_buffer */
+ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_GC, /* tp_flags */
+ 0, /* tp_doc */
+ (traverseproc)tupletraverse, /* tp_traverse */
+ 0, /* tp_clear */
+ tuplerichcompare, /* tp_richcompare */
};
/* The following function breaks the notion that tuples are immutable: