[Python-checkins] python/dist/src/Objects enumobject.c, 1.8,
1.9 rangeobject.c, 2.48, 2.49
rhettinger at users.sourceforge.net
rhettinger at users.sourceforge.net
Thu Nov 6 09:06:50 EST 2003
Update of /cvsroot/python/python/dist/src/Objects
In directory sc8-pr-cvs1:/tmp/cvs-serv17028/Objects
Modified Files:
enumobject.c rangeobject.c
Log Message:
Implement and apply PEP 322, reverse iteration
Index: enumobject.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Objects/enumobject.c,v
retrieving revision 1.8
retrieving revision 1.9
diff -C2 -d -r1.8 -r1.9
*** enumobject.c 2 Nov 2003 05:37:44 -0000 1.8
--- enumobject.c 6 Nov 2003 14:06:47 -0000 1.9
***************
*** 156,157 ****
--- 156,282 ----
PyObject_GC_Del, /* tp_free */
};
+
+ /* Reversed Object ***************************************************************/
+
+ typedef struct {
+ PyObject_HEAD
+ long index;
+ PyObject* seq;
+ } reversedobject;
+
+ static PyObject *
+ reversed_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+ {
+ long n;
+ PyObject *seq;
+ reversedobject *ro;
+
+ if (!PyArg_UnpackTuple(args, "reversed", 1, 1, &seq))
+ return NULL;
+
+ /* Special case optimization for xrange */
+ if (PyRange_Check(seq))
+ return PyObject_CallMethod(seq, "__reversed__", NULL);
+
+ if (!PySequence_Check(seq)) {
+ PyErr_SetString(PyExc_TypeError,
+ "argument to reversed() must be a sequence");
+ return NULL;
+ }
+
+ n = PySequence_Size(seq);
+ if (n == -1)
+ return NULL;
+
+ ro = (reversedobject *)type->tp_alloc(type, 0);
+ if (ro == NULL)
+ return NULL;
+
+ ro->index = n-1;
+ Py_INCREF(seq);
+ ro->seq = seq;
+ return (PyObject *)ro;
+ }
+
+ static void
+ reversed_dealloc(reversedobject *ro)
+ {
+ PyObject_GC_UnTrack(ro);
+ Py_XDECREF(ro->seq);
+ ro->ob_type->tp_free(ro);
+ }
+
+ static int
+ reversed_traverse(reversedobject *ro, visitproc visit, void *arg)
+ {
+ if (ro->seq)
+ return visit((PyObject *)(ro->seq), arg);
+ return 0;
+ }
+
+ static PyObject *
+ reversed_next(reversedobject *ro)
+ {
+ PyObject *item;
+
+ if (ro->index < 0)
+ return NULL;
+
+ assert(PySequence_Check(ro->seq));
+ item = PySequence_GetItem(ro->seq, ro->index);
+ if (item == NULL)
+ return NULL;
+
+ ro->index--;
+ return item;
+ }
+
+ PyDoc_STRVAR(reversed_doc,
+ "reverse(sequence) -> reverse iterator over values of the sequence\n"
+ "\n"
+ "Return a reverse iterator");
+
+ PyTypeObject PyReversed_Type = {
+ PyObject_HEAD_INIT(&PyType_Type)
+ 0, /* ob_size */
+ "reversed", /* tp_name */
+ sizeof(reversedobject), /* tp_basicsize */
+ 0, /* tp_itemsize */
+ /* methods */
+ (destructor)reversed_dealloc, /* tp_dealloc */
+ 0, /* tp_print */
+ 0, /* tp_getattr */
+ 0, /* tp_setattr */
+ 0, /* tp_compare */
+ 0, /* tp_repr */
+ 0, /* tp_as_number */
+ 0, /* tp_as_sequence */
+ 0, /* tp_as_mapping */
+ 0, /* tp_hash */
+ 0, /* tp_call */
+ 0, /* tp_str */
+ PyObject_GenericGetAttr, /* tp_getattro */
+ 0, /* tp_setattro */
+ 0, /* tp_as_buffer */
+ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
+ Py_TPFLAGS_BASETYPE, /* tp_flags */
+ reversed_doc, /* tp_doc */
+ (traverseproc)reversed_traverse,/* tp_traverse */
+ 0, /* tp_clear */
+ 0, /* tp_richcompare */
+ 0, /* tp_weaklistoffset */
+ PyObject_SelfIter, /* tp_iter */
+ (iternextfunc)reversed_next, /* tp_iternext */
+ 0, /* tp_methods */
+ 0, /* tp_members */
+ 0, /* tp_getset */
+ 0, /* tp_base */
+ 0, /* tp_dict */
+ 0, /* tp_descr_get */
+ 0, /* tp_descr_set */
+ 0, /* tp_dictoffset */
+ 0, /* tp_init */
+ PyType_GenericAlloc, /* tp_alloc */
+ reversed_new, /* tp_new */
+ PyObject_GC_Del, /* tp_free */
+ };
Index: rangeobject.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Objects/rangeobject.c,v
retrieving revision 2.48
retrieving revision 2.49
diff -C2 -d -r2.48 -r2.49
*** rangeobject.c 17 Mar 2003 19:46:11 -0000 2.48
--- rangeobject.c 6 Nov 2003 14:06:47 -0000 2.49
***************
*** 172,175 ****
--- 172,184 ----
static PyObject * range_iter(PyObject *seq);
+ static PyObject * range_reverse(PyObject *seq);
+
+ PyDoc_STRVAR(reverse_doc,
+ "Returns a reverse iterator.");
+
+ static PyMethodDef range_methods[] = {
+ {"__reversed__", (PyCFunction)range_reverse, METH_NOARGS, reverse_doc},
+ {NULL, NULL} /* sentinel */
+ };
PyTypeObject PyRange_Type = {
***************
*** 202,206 ****
(getiterfunc)range_iter, /* tp_iter */
0, /* tp_iternext */
! 0, /* tp_methods */
0, /* tp_members */
0, /* tp_getset */
--- 211,215 ----
(getiterfunc)range_iter, /* tp_iter */
0, /* tp_iternext */
! range_methods, /* tp_methods */
0, /* tp_members */
0, /* tp_getset */
***************
*** 243,246 ****
--- 252,281 ----
it->step = ((rangeobject *)seq)->step;
it->len = ((rangeobject *)seq)->len;
+ return (PyObject *)it;
+ }
+
+ static PyObject *
+ range_reverse(PyObject *seq)
+ {
+ rangeiterobject *it;
+ long start, step, len;
+
+ if (!PyRange_Check(seq)) {
+ PyErr_BadInternalCall();
+ return NULL;
+ }
+ it = PyObject_New(rangeiterobject, &Pyrangeiter_Type);
+ if (it == NULL)
+ return NULL;
+
+ start = ((rangeobject *)seq)->start;
+ step = ((rangeobject *)seq)->step;
+ len = ((rangeobject *)seq)->len;
+
+ it->index = 0;
+ it->start = start + (len-1) * step;
+ it->step = -step;
+ it->len = len;
+
return (PyObject *)it;
}
More information about the Python-checkins
mailing list