| 
									
										
										
										
											2002-04-26 19:40:56 +00:00
										 |  |  | /* enumerate object */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include "Python.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | typedef struct { | 
					
						
							|  |  |  | 	PyObject_HEAD | 
					
						
							| 
									
										
										
										
											2008-07-24 07:04:55 +00:00
										 |  |  | 	Py_ssize_t en_index;	   /* current index of enumeration */ | 
					
						
							| 
									
										
										
										
											2002-04-26 19:40:56 +00:00
										 |  |  | 	PyObject* en_sit;          /* secondary iterator of enumeration */ | 
					
						
							| 
									
										
										
										
											2003-05-28 14:05:34 +00:00
										 |  |  | 	PyObject* en_result;	   /* result tuple  */ | 
					
						
							| 
									
										
										
										
											2008-07-24 07:04:55 +00:00
										 |  |  | 	PyObject* en_longindex;	   /* index for sequences >= PY_SSIZE_T_MAX */ | 
					
						
							| 
									
										
										
										
											2002-04-26 19:40:56 +00:00
										 |  |  | } enumobject; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static PyObject * | 
					
						
							|  |  |  | enum_new(PyTypeObject *type, PyObject *args, PyObject *kwds) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	enumobject *en; | 
					
						
							|  |  |  | 	PyObject *seq = NULL; | 
					
						
							| 
									
										
										
										
											2008-05-13 19:04:54 +00:00
										 |  |  | 	PyObject *start = NULL; | 
					
						
							|  |  |  | 	static char *kwlist[] = {"sequence", "start", 0}; | 
					
						
							| 
									
										
										
										
											2002-04-26 19:40:56 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-05-13 19:04:54 +00:00
										 |  |  | 	if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|O:enumerate", kwlist, | 
					
						
							|  |  |  | 					 &seq, &start)) | 
					
						
							| 
									
										
										
										
											2002-04-26 19:40:56 +00:00
										 |  |  | 		return NULL; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	en = (enumobject *)type->tp_alloc(type, 0); | 
					
						
							|  |  |  | 	if (en == NULL) | 
					
						
							|  |  |  | 		return NULL; | 
					
						
							| 
									
										
										
										
											2008-07-24 07:04:55 +00:00
										 |  |  | 	if (start != NULL) { | 
					
						
							| 
									
										
										
										
											2008-05-13 19:04:54 +00:00
										 |  |  | 		start = PyNumber_Index(start); | 
					
						
							|  |  |  | 		if (start == NULL) { | 
					
						
							|  |  |  | 			Py_DECREF(en); | 
					
						
							|  |  |  | 			return NULL; | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2008-07-24 07:04:55 +00:00
										 |  |  | 		assert(PyInt_Check(start) || PyLong_Check(start)); | 
					
						
							|  |  |  | 		en->en_index = PyInt_AsSsize_t(start); | 
					
						
							|  |  |  | 		if (en->en_index == -1 && PyErr_Occurred()) { | 
					
						
							|  |  |  | 			PyErr_Clear(); | 
					
						
							|  |  |  | 			en->en_index = PY_SSIZE_T_MAX; | 
					
						
							| 
									
										
										
										
											2008-05-13 19:04:54 +00:00
										 |  |  | 			en->en_longindex = start; | 
					
						
							|  |  |  | 		} else { | 
					
						
							|  |  |  | 			en->en_longindex = NULL; | 
					
						
							|  |  |  | 			Py_DECREF(start); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} else { | 
					
						
							|  |  |  | 		en->en_index = 0; | 
					
						
							|  |  |  | 		en->en_longindex = NULL; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2002-04-26 19:40:56 +00:00
										 |  |  | 	en->en_sit = PyObject_GetIter(seq); | 
					
						
							|  |  |  | 	if (en->en_sit == NULL) { | 
					
						
							|  |  |  | 		Py_DECREF(en); | 
					
						
							|  |  |  | 		return NULL; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2003-11-02 05:37:44 +00:00
										 |  |  | 	en->en_result = PyTuple_Pack(2, Py_None, Py_None); | 
					
						
							| 
									
										
										
										
											2003-05-28 14:05:34 +00:00
										 |  |  | 	if (en->en_result == NULL) { | 
					
						
							|  |  |  | 		Py_DECREF(en); | 
					
						
							|  |  |  | 		return NULL; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2002-04-26 19:40:56 +00:00
										 |  |  | 	return (PyObject *)en; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void | 
					
						
							|  |  |  | enum_dealloc(enumobject *en) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	PyObject_GC_UnTrack(en); | 
					
						
							|  |  |  | 	Py_XDECREF(en->en_sit); | 
					
						
							| 
									
										
										
										
											2003-05-28 14:05:34 +00:00
										 |  |  | 	Py_XDECREF(en->en_result); | 
					
						
							| 
									
										
										
										
											2007-10-03 21:18:11 +00:00
										 |  |  | 	Py_XDECREF(en->en_longindex); | 
					
						
							| 
									
										
										
										
											2007-12-19 02:37:44 +00:00
										 |  |  | 	Py_TYPE(en)->tp_free(en); | 
					
						
							| 
									
										
										
										
											2002-04-26 19:40:56 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static int | 
					
						
							|  |  |  | enum_traverse(enumobject *en, visitproc visit, void *arg) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2006-04-15 21:47:09 +00:00
										 |  |  | 	Py_VISIT(en->en_sit); | 
					
						
							|  |  |  | 	Py_VISIT(en->en_result); | 
					
						
							| 
									
										
										
										
											2007-10-03 21:18:11 +00:00
										 |  |  | 	Py_VISIT(en->en_longindex); | 
					
						
							| 
									
										
										
										
											2002-04-26 19:40:56 +00:00
										 |  |  | 	return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-10-03 21:18:11 +00:00
										 |  |  | static PyObject * | 
					
						
							|  |  |  | enum_next_long(enumobject *en, PyObject* next_item) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	static PyObject *one = NULL; | 
					
						
							|  |  |  | 	PyObject *result = en->en_result; | 
					
						
							|  |  |  | 	PyObject *next_index; | 
					
						
							|  |  |  | 	PyObject *stepped_up; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (en->en_longindex == NULL) { | 
					
						
							| 
									
										
										
										
											2008-07-24 07:04:55 +00:00
										 |  |  | 		en->en_longindex = PyInt_FromSsize_t(PY_SSIZE_T_MAX); | 
					
						
							| 
									
										
										
										
											2007-10-03 21:18:11 +00:00
										 |  |  | 		if (en->en_longindex == NULL) | 
					
						
							|  |  |  | 			return NULL; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	if (one == NULL) { | 
					
						
							|  |  |  | 		one = PyInt_FromLong(1); | 
					
						
							|  |  |  | 		if (one == NULL) | 
					
						
							|  |  |  | 			return NULL; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	next_index = en->en_longindex; | 
					
						
							|  |  |  | 	assert(next_index != NULL); | 
					
						
							|  |  |  | 	stepped_up = PyNumber_Add(next_index, one); | 
					
						
							|  |  |  | 	if (stepped_up == NULL) | 
					
						
							|  |  |  | 		return NULL; | 
					
						
							|  |  |  | 	en->en_longindex = stepped_up; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (result->ob_refcnt == 1) { | 
					
						
							|  |  |  | 		Py_INCREF(result); | 
					
						
							|  |  |  | 		Py_DECREF(PyTuple_GET_ITEM(result, 0)); | 
					
						
							|  |  |  | 		Py_DECREF(PyTuple_GET_ITEM(result, 1)); | 
					
						
							|  |  |  | 	} else { | 
					
						
							|  |  |  | 		result = PyTuple_New(2); | 
					
						
							|  |  |  | 		if (result == NULL) { | 
					
						
							|  |  |  | 			Py_DECREF(next_index); | 
					
						
							|  |  |  | 			Py_DECREF(next_item); | 
					
						
							|  |  |  | 			return NULL; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	PyTuple_SET_ITEM(result, 0, next_index); | 
					
						
							|  |  |  | 	PyTuple_SET_ITEM(result, 1, next_item); | 
					
						
							|  |  |  | 	return result; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2002-04-26 19:40:56 +00:00
										 |  |  | static PyObject * | 
					
						
							|  |  |  | enum_next(enumobject *en) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	PyObject *next_index; | 
					
						
							| 
									
										
										
										
											2002-07-16 21:02:42 +00:00
										 |  |  | 	PyObject *next_item; | 
					
						
							| 
									
										
										
										
											2003-05-28 14:05:34 +00:00
										 |  |  | 	PyObject *result = en->en_result; | 
					
						
							|  |  |  | 	PyObject *it = en->en_sit; | 
					
						
							| 
									
										
										
										
											2002-04-26 19:40:56 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-12-19 02:37:44 +00:00
										 |  |  | 	next_item = (*Py_TYPE(it)->tp_iternext)(it); | 
					
						
							| 
									
										
										
										
											2003-05-28 14:05:34 +00:00
										 |  |  | 	if (next_item == NULL) | 
					
						
							| 
									
										
										
										
											2002-04-26 19:40:56 +00:00
										 |  |  | 		return NULL; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-07-24 07:04:55 +00:00
										 |  |  | 	if (en->en_index == PY_SSIZE_T_MAX) | 
					
						
							| 
									
										
										
										
											2007-10-03 21:18:11 +00:00
										 |  |  | 		return enum_next_long(en, next_item); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-07-24 07:04:55 +00:00
										 |  |  | 	next_index = PyInt_FromSsize_t(en->en_index); | 
					
						
							| 
									
										
										
										
											2002-07-16 21:02:42 +00:00
										 |  |  | 	if (next_index == NULL) { | 
					
						
							| 
									
										
										
										
											2003-05-28 14:05:34 +00:00
										 |  |  | 		Py_DECREF(next_item); | 
					
						
							| 
									
										
										
										
											2002-04-26 19:40:56 +00:00
										 |  |  | 		return NULL; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2003-05-28 14:05:34 +00:00
										 |  |  | 	en->en_index++; | 
					
						
							| 
									
										
										
										
											2002-04-26 19:40:56 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-05-28 14:05:34 +00:00
										 |  |  | 	if (result->ob_refcnt == 1) { | 
					
						
							|  |  |  | 		Py_INCREF(result); | 
					
						
							|  |  |  | 		Py_DECREF(PyTuple_GET_ITEM(result, 0)); | 
					
						
							|  |  |  | 		Py_DECREF(PyTuple_GET_ITEM(result, 1)); | 
					
						
							|  |  |  | 	} else { | 
					
						
							|  |  |  | 		result = PyTuple_New(2); | 
					
						
							|  |  |  | 		if (result == NULL) { | 
					
						
							|  |  |  | 			Py_DECREF(next_index); | 
					
						
							|  |  |  | 			Py_DECREF(next_item); | 
					
						
							|  |  |  | 			return NULL; | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2002-04-26 19:40:56 +00:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2003-05-28 14:05:34 +00:00
										 |  |  | 	PyTuple_SET_ITEM(result, 0, next_index); | 
					
						
							| 
									
										
										
										
											2002-04-26 19:40:56 +00:00
										 |  |  | 	PyTuple_SET_ITEM(result, 1, next_item); | 
					
						
							|  |  |  | 	return result; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2002-06-13 20:33:02 +00:00
										 |  |  | PyDoc_STRVAR(enum_doc, | 
					
						
							| 
									
										
										
										
											2003-04-21 20:26:25 +00:00
										 |  |  | "enumerate(iterable) -> iterator for index, value of iterable\n" | 
					
						
							|  |  |  | "\n" | 
					
						
							| 
									
										
										
										
											2009-09-25 16:07:55 +00:00
										 |  |  | "Return an enumerate object.  iterable must be another object that supports\n" | 
					
						
							| 
									
										
										
										
											2003-04-21 20:26:25 +00:00
										 |  |  | "iteration.  The enumerate object yields pairs containing a count (from\n" | 
					
						
							|  |  |  | "zero) and a value yielded by the iterable argument.  enumerate is useful\n" | 
					
						
							|  |  |  | "for obtaining an indexed list: (0, seq[0]), (1, seq[1]), (2, seq[2]), ..."); | 
					
						
							| 
									
										
										
										
											2002-04-26 19:40:56 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | PyTypeObject PyEnum_Type = { | 
					
						
							| 
									
										
										
										
											2007-07-21 06:55:02 +00:00
										 |  |  | 	PyVarObject_HEAD_INIT(&PyType_Type, 0) | 
					
						
							| 
									
										
										
										
											2002-04-26 19:40:56 +00:00
										 |  |  | 	"enumerate",                    /* tp_name */ | 
					
						
							|  |  |  | 	sizeof(enumobject),             /* tp_basicsize */ | 
					
						
							|  |  |  | 	0,                              /* tp_itemsize */ | 
					
						
							|  |  |  | 	/* methods */ | 
					
						
							|  |  |  | 	(destructor)enum_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 */ | 
					
						
							|  |  |  | 	enum_doc,                       /* tp_doc */ | 
					
						
							|  |  |  | 	(traverseproc)enum_traverse,    /* tp_traverse */ | 
					
						
							|  |  |  | 	0,                              /* tp_clear */ | 
					
						
							|  |  |  | 	0,                              /* tp_richcompare */ | 
					
						
							|  |  |  | 	0,                              /* tp_weaklistoffset */ | 
					
						
							| 
									
										
										
										
											2003-03-17 19:46:11 +00:00
										 |  |  | 	PyObject_SelfIter,		/* tp_iter */ | 
					
						
							| 
									
										
										
										
											2002-04-26 19:40:56 +00:00
										 |  |  | 	(iternextfunc)enum_next,        /* tp_iternext */ | 
					
						
							| 
									
										
										
										
											2002-07-16 21:02:42 +00:00
										 |  |  | 	0,                              /* tp_methods */ | 
					
						
							| 
									
										
										
										
											2002-04-26 19:40:56 +00:00
										 |  |  | 	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 */ | 
					
						
							|  |  |  | 	enum_new,                       /* tp_new */ | 
					
						
							|  |  |  | 	PyObject_GC_Del,                /* tp_free */ | 
					
						
							|  |  |  | }; | 
					
						
							| 
									
										
										
										
											2003-11-06 14:06:48 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | /* Reversed Object ***************************************************************/ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | typedef struct { | 
					
						
							|  |  |  | 	PyObject_HEAD | 
					
						
							| 
									
										
										
										
											2006-02-16 14:32:27 +00:00
										 |  |  | 	Py_ssize_t      index; | 
					
						
							| 
									
										
										
										
											2003-11-06 14:06:48 +00:00
										 |  |  | 	PyObject* seq; | 
					
						
							|  |  |  | } reversedobject; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static PyObject * | 
					
						
							|  |  |  | reversed_new(PyTypeObject *type, PyObject *args, PyObject *kwds) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2006-02-16 14:32:27 +00:00
										 |  |  | 	Py_ssize_t n; | 
					
						
							| 
									
										
										
										
											2009-05-09 02:07:04 +00:00
										 |  |  | 	PyObject *seq, *reversed_meth; | 
					
						
							|  |  |  | 	static PyObject *reversed_cache = NULL; | 
					
						
							| 
									
										
										
										
											2003-11-06 14:06:48 +00:00
										 |  |  | 	reversedobject *ro; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-05-16 13:24:29 +00:00
										 |  |  | 	if (type == &PyReversed_Type && !_PyArg_NoKeywords("reversed()", kwds)) | 
					
						
							|  |  |  | 		return NULL; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (!PyArg_UnpackTuple(args, "reversed", 1, 1, &seq) ) | 
					
						
							| 
									
										
										
										
											2003-11-06 14:06:48 +00:00
										 |  |  | 		return NULL; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-05-09 17:23:03 +00:00
										 |  |  | 	if (PyInstance_Check(seq)) { | 
					
						
							|  |  |  | 		reversed_meth = PyObject_GetAttrString(seq, "__reversed__"); | 
					
						
							|  |  |  | 		if (reversed_meth == NULL) { | 
					
						
							|  |  |  | 			if (PyErr_ExceptionMatches(PyExc_AttributeError)) | 
					
						
							|  |  |  | 				PyErr_Clear(); | 
					
						
							|  |  |  | 			else | 
					
						
							|  |  |  | 				return NULL; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2009-05-25 02:40:21 +00:00
										 |  |  | 	else { | 
					
						
							| 
									
										
										
										
											2009-05-09 17:23:03 +00:00
										 |  |  | 		reversed_meth = _PyObject_LookupSpecial(seq, "__reversed__", | 
					
						
							|  |  |  | 							&reversed_cache); | 
					
						
							| 
									
										
										
										
											2009-05-25 02:40:21 +00:00
										 |  |  | 		if (reversed_meth == NULL && PyErr_Occurred()) | 
					
						
							|  |  |  | 			return NULL; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2009-05-09 02:07:04 +00:00
										 |  |  | 	if (reversed_meth != NULL) { | 
					
						
							|  |  |  | 		PyObject *res = PyObject_CallFunctionObjArgs(reversed_meth, NULL); | 
					
						
							|  |  |  | 		Py_DECREF(reversed_meth); | 
					
						
							|  |  |  | 		return res; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2003-11-06 14:06:48 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	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); | 
					
						
							| 
									
										
										
										
											2007-12-19 02:37:44 +00:00
										 |  |  | 	Py_TYPE(ro)->tp_free(ro); | 
					
						
							| 
									
										
										
										
											2003-11-06 14:06:48 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static int | 
					
						
							|  |  |  | reversed_traverse(reversedobject *ro, visitproc visit, void *arg) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2006-04-15 21:47:09 +00:00
										 |  |  | 	Py_VISIT(ro->seq); | 
					
						
							| 
									
										
										
										
											2003-11-06 14:06:48 +00:00
										 |  |  | 	return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static PyObject * | 
					
						
							|  |  |  | reversed_next(reversedobject *ro) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	PyObject *item; | 
					
						
							| 
									
										
										
										
											2006-03-07 12:08:51 +00:00
										 |  |  | 	Py_ssize_t index = ro->index; | 
					
						
							| 
									
										
										
										
											2003-11-06 14:06:48 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2004-03-10 10:10:42 +00:00
										 |  |  | 	if (index >= 0) { | 
					
						
							|  |  |  | 		item = PySequence_GetItem(ro->seq, index); | 
					
						
							|  |  |  | 		if (item != NULL) { | 
					
						
							|  |  |  | 			ro->index--; | 
					
						
							|  |  |  | 			return item; | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2004-04-12 18:10:01 +00:00
										 |  |  | 		if (PyErr_ExceptionMatches(PyExc_IndexError) || | 
					
						
							|  |  |  | 		    PyErr_ExceptionMatches(PyExc_StopIteration)) | 
					
						
							|  |  |  | 			PyErr_Clear(); | 
					
						
							| 
									
										
										
										
											2004-03-10 10:10:42 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 	ro->index = -1; | 
					
						
							| 
									
										
										
										
											2004-09-01 07:02:44 +00:00
										 |  |  | 	Py_CLEAR(ro->seq); | 
					
						
							| 
									
										
										
										
											2004-03-10 10:10:42 +00:00
										 |  |  | 	return NULL; | 
					
						
							| 
									
										
										
										
											2004-02-10 09:33:39 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-11-06 14:06:48 +00:00
										 |  |  | PyDoc_STRVAR(reversed_doc, | 
					
						
							| 
									
										
										
										
											2004-08-25 19:42:12 +00:00
										 |  |  | "reversed(sequence) -> reverse iterator over values of the sequence\n" | 
					
						
							| 
									
										
										
										
											2003-11-06 14:06:48 +00:00
										 |  |  | "\n" | 
					
						
							|  |  |  | "Return a reverse iterator"); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-09-24 21:23:05 +00:00
										 |  |  | static PyObject * | 
					
						
							| 
									
										
										
										
											2004-03-10 10:10:42 +00:00
										 |  |  | reversed_len(reversedobject *ro) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2006-02-15 17:27:45 +00:00
										 |  |  | 	Py_ssize_t position, seqsize; | 
					
						
							| 
									
										
										
										
											2004-04-12 18:10:01 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	if (ro->seq == NULL) | 
					
						
							| 
									
										
										
										
											2005-09-24 21:23:05 +00:00
										 |  |  | 		return PyInt_FromLong(0); | 
					
						
							| 
									
										
										
										
											2004-04-12 18:10:01 +00:00
										 |  |  | 	seqsize = PySequence_Size(ro->seq); | 
					
						
							|  |  |  | 	if (seqsize == -1) | 
					
						
							| 
									
										
										
										
											2005-09-24 21:23:05 +00:00
										 |  |  | 		return NULL; | 
					
						
							| 
									
										
										
										
											2004-04-12 18:10:01 +00:00
										 |  |  | 	position = ro->index + 1; | 
					
						
							| 
									
										
										
										
											2006-02-16 14:32:27 +00:00
										 |  |  | 	return PyInt_FromSsize_t((seqsize < position)  ?  0  :  position); | 
					
						
							| 
									
										
										
										
											2004-03-10 10:10:42 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-02-11 21:32:43 +00:00
										 |  |  | PyDoc_STRVAR(length_hint_doc, "Private method returning an estimate of len(list(it))."); | 
					
						
							| 
									
										
										
										
											2005-09-24 21:23:05 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | static PyMethodDef reversediter_methods[] = { | 
					
						
							| 
									
										
										
										
											2006-02-11 21:32:43 +00:00
										 |  |  | 	{"__length_hint__", (PyCFunction)reversed_len, METH_NOARGS, length_hint_doc}, | 
					
						
							| 
									
										
										
										
											2005-09-24 21:23:05 +00:00
										 |  |  |  	{NULL,		NULL}		/* sentinel */ | 
					
						
							| 
									
										
										
										
											2004-02-08 10:49:42 +00:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-11-06 14:06:48 +00:00
										 |  |  | PyTypeObject PyReversed_Type = { | 
					
						
							| 
									
										
										
										
											2007-07-21 06:55:02 +00:00
										 |  |  | 	PyVarObject_HEAD_INIT(&PyType_Type, 0) | 
					
						
							| 
									
										
										
										
											2003-11-06 14:06:48 +00:00
										 |  |  | 	"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 */ | 
					
						
							| 
									
										
										
										
											2005-09-24 21:23:05 +00:00
										 |  |  | 	0,				/* tp_as_sequence */ | 
					
						
							| 
									
										
										
										
											2003-11-06 14:06:48 +00:00
										 |  |  | 	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 */ | 
					
						
							| 
									
										
										
										
											2005-09-24 21:23:05 +00:00
										 |  |  | 	reversediter_methods,		/* tp_methods */ | 
					
						
							| 
									
										
										
										
											2003-11-06 14:06:48 +00:00
										 |  |  | 	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 */ | 
					
						
							|  |  |  | }; |