[Python-checkins] python/dist/src/Objects iterobject.c,1.11,1.12 tupleobject.c,2.70,2.71

rhettinger@users.sourceforge.net rhettinger@users.sourceforge.net
Thu, 08 Aug 2002 18:30:21 -0700


Update of /cvsroot/python/python/dist/src/Objects
In directory usw-pr-cvs1:/tmp/cvs-serv30405

Modified Files:
	iterobject.c tupleobject.c 
Log Message:
Moved special case for tuples from iterobject.c to 
tupleobject.c. Makes the code in iterobject.c cleaner 
and speeds-up the general case by not checking for 
tuples everytime.   SF Patch #592065.


Index: iterobject.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Objects/iterobject.c,v
retrieving revision 1.11
retrieving revision 1.12
diff -C2 -d -r1.11 -r1.12
*** iterobject.c	16 Jul 2002 20:24:46 -0000	1.11
--- iterobject.c	9 Aug 2002 01:30:17 -0000	1.12
***************
*** 56,59 ****
--- 56,60 ----
  	seqiterobject *it;
  	PyObject *seq;
+ 	PyObject *result;
  
  	assert(PySeqIter_Check(iterator));
***************
*** 63,93 ****
  		return NULL;
  
! 	if (PyTuple_CheckExact(seq)) {
! 		if (it->it_index < PyTuple_GET_SIZE(seq)) {
! 			PyObject *item;
! 			item = PyTuple_GET_ITEM(seq, it->it_index);
! 			it->it_index++;
! 			Py_INCREF(item);
! 			return item;
! 		}
  		Py_DECREF(seq);
  		it->it_seq = NULL;
- 		return NULL;
- 	}
- 	else {
- 		PyObject *result = PySequence_GetItem(seq, it->it_index);
- 		if (result != NULL) {
- 			it->it_index++;
- 			return result;
- 		}
- 		if (PyErr_ExceptionMatches(PyExc_IndexError) ||
- 		    PyErr_ExceptionMatches(PyExc_StopIteration))
- 		{
- 			PyErr_Clear();
- 			Py_DECREF(seq);
- 			it->it_seq = NULL;
- 		}
- 		return NULL;
  	}
  }
  
--- 64,80 ----
  		return NULL;
  
! 	result = PySequence_GetItem(seq, it->it_index);
! 	if (result != NULL) {
! 		it->it_index++;
! 		return result;
! 	}
! 	if (PyErr_ExceptionMatches(PyExc_IndexError) ||
! 	    PyErr_ExceptionMatches(PyExc_StopIteration))
! 	{
! 		PyErr_Clear();
  		Py_DECREF(seq);
  		it->it_seq = NULL;
  	}
+ 	return NULL;
  }
  

Index: tupleobject.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Objects/tupleobject.c,v
retrieving revision 2.70
retrieving revision 2.71
diff -C2 -d -r2.70 -r2.71
*** tupleobject.c	17 Jul 2002 16:30:38 -0000	2.70
--- tupleobject.c	9 Aug 2002 01:30:17 -0000	2.71
***************
*** 597,600 ****
--- 597,602 ----
  };
  
+ static PyObject *tuple_iter(PyObject *seq);
+ 
  PyTypeObject PyTuple_Type = {
  	PyObject_HEAD_INIT(&PyType_Type)
***************
*** 625,629 ****
  	tuplerichcompare,			/* tp_richcompare */
  	0,					/* tp_weaklistoffset */
! 	0,					/* tp_iter */
  	0,					/* tp_iternext */
  	0,					/* tp_methods */
--- 627,631 ----
  	tuplerichcompare,			/* tp_richcompare */
  	0,					/* tp_weaklistoffset */
! 	tuple_iter,	    			/* tp_iter */
  	0,					/* tp_iternext */
  	0,					/* tp_methods */
***************
*** 723,724 ****
--- 725,835 ----
  #endif
  }
+ 
+ /*********************** Tuple Iterator **************************/
+ 
+ typedef struct {
+ 	PyObject_HEAD
+ 	long it_index;
+ 	PyTupleObject *it_seq; /* Set to NULL when iterator is exhausted */
+ } tupleiterobject;
+ 
+ PyTypeObject PyTupleIter_Type;
+ 
+ static PyObject *
+ tuple_iter(PyObject *seq)
+ {
+ 	tupleiterobject *it;
+ 
+ 	if (!PyTuple_Check(seq)) {
+ 		PyErr_BadInternalCall();
+ 		return NULL;
+ 	}
+ 	it = PyObject_GC_New(tupleiterobject, &PyTupleIter_Type);
+ 	if (it == NULL)
+ 		return NULL;
+ 	it->it_index = 0;
+ 	Py_INCREF(seq);
+ 	it->it_seq = (PyTupleObject *)seq;
+ 	_PyObject_GC_TRACK(it);
+ 	return (PyObject *)it;
+ }
+ 
+ static void
+ tupleiter_dealloc(tupleiterobject *it)
+ {
+ 	_PyObject_GC_UNTRACK(it);
+ 	Py_XDECREF(it->it_seq);
+ 	PyObject_GC_Del(it);
+ }
+ 
+ static int
+ tupleiter_traverse(tupleiterobject *it, visitproc visit, void *arg)
+ {
+ 	if (it->it_seq == NULL)
+ 		return 0;
+ 	return visit((PyObject *)it->it_seq, arg);
+ }
+ 
+ 
+ static PyObject *
+ tupleiter_getiter(PyObject *it)
+ {
+ 	Py_INCREF(it);
+ 	return it;
+ }
+ 
+ static PyObject *
+ tupleiter_next(tupleiterobject *it)
+ {
+ 	PyTupleObject *seq;
+ 	PyObject *item;
+ 
+ 	assert(it != NULL);
+ 	seq = it->it_seq;
+ 	if (seq == NULL)
+ 		return NULL;
+ 	assert(PyTuple_Check(seq));
+ 
+ 	if (it->it_index < PyTuple_GET_SIZE(seq)) {
+ 		item = PyTuple_GET_ITEM(seq, it->it_index);
+ 		++it->it_index;
+ 		Py_INCREF(item);
+ 		return item;
+ 	}
+ 
+ 	Py_DECREF(seq);
+ 	it->it_seq = NULL;
+ 	return NULL;
+ }
+ 
+ PyTypeObject PyTupleIter_Type = {
+ 	PyObject_HEAD_INIT(&PyType_Type)
+ 	0,					/* ob_size */
+ 	"tupleiterator",			/* tp_name */
+ 	sizeof(tupleiterobject),		/* tp_basicsize */
+ 	0,					/* tp_itemsize */
+ 	/* methods */
+ 	(destructor)tupleiter_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,/* tp_flags */
+ 	0,					/* tp_doc */
+ 	(traverseproc)tupleiter_traverse,	/* tp_traverse */
+ 	0,					/* tp_clear */
+ 	0,					/* tp_richcompare */
+ 	0,					/* tp_weaklistoffset */
+ 	(getiterfunc)tupleiter_getiter,		/* tp_iter */
+ 	(iternextfunc)tupleiter_next,		/* tp_iternext */
+ };