[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