diff options
author | Guido van Rossum <guido@python.org> | 2001-01-18 00:00:53 (GMT) |
---|---|---|
committer | Guido van Rossum <guido@python.org> | 2001-01-18 00:00:53 (GMT) |
commit | f77bc62e7351a052f2127221afa43bbf442d8c96 (patch) | |
tree | bc666c767e65559e3336c73a93c8dee8e13abe1d /Objects/tupleobject.c | |
parent | 24f67d568cf878f53c647356aa4e446f7ae9de61 (diff) | |
download | cpython-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/tupleobject.c')
-rw-r--r-- | Objects/tupleobject.c | 147 |
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: |