| 
									
										
										
										
											2003-02-01 00:10:11 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | #include "Python.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* Itertools module written and maintained 
 | 
					
						
							|  |  |  |    by Raymond D. Hettinger <python@rcn.com> | 
					
						
							|  |  |  |    Copyright (c) 2003 Python Software Foundation. | 
					
						
							|  |  |  |    All rights reserved. | 
					
						
							|  |  |  | */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-02-23 04:40:07 +00:00
										 |  |  | /* cycle object **********************************************************/ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | typedef struct { | 
					
						
							|  |  |  | 	PyObject_HEAD | 
					
						
							|  |  |  | 	PyObject *it; | 
					
						
							|  |  |  | 	PyObject *saved; | 
					
						
							|  |  |  | 	int firstpass; | 
					
						
							|  |  |  | } cycleobject; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-07-14 07:07:12 +00:00
										 |  |  | static PyTypeObject cycle_type; | 
					
						
							| 
									
										
										
										
											2003-02-23 04:40:07 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | static PyObject * | 
					
						
							|  |  |  | cycle_new(PyTypeObject *type, PyObject *args, PyObject *kwds) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	PyObject *it; | 
					
						
							|  |  |  | 	PyObject *iterable; | 
					
						
							|  |  |  | 	PyObject *saved; | 
					
						
							|  |  |  | 	cycleobject *lz; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (!PyArg_UnpackTuple(args, "cycle", 1, 1, &iterable)) | 
					
						
							|  |  |  | 		return NULL; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* Get iterator. */ | 
					
						
							|  |  |  | 	it = PyObject_GetIter(iterable); | 
					
						
							|  |  |  | 	if (it == NULL) | 
					
						
							|  |  |  | 		return NULL; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	saved = PyList_New(0); | 
					
						
							|  |  |  | 	if (saved == NULL) { | 
					
						
							|  |  |  | 		Py_DECREF(it); | 
					
						
							|  |  |  | 		return NULL; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* create cycleobject structure */ | 
					
						
							|  |  |  | 	lz = (cycleobject *)type->tp_alloc(type, 0); | 
					
						
							|  |  |  | 	if (lz == NULL) { | 
					
						
							|  |  |  | 		Py_DECREF(it); | 
					
						
							|  |  |  | 		Py_DECREF(saved); | 
					
						
							|  |  |  | 		return NULL; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	lz->it = it; | 
					
						
							|  |  |  | 	lz->saved = saved; | 
					
						
							|  |  |  | 	lz->firstpass = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return (PyObject *)lz; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void | 
					
						
							|  |  |  | cycle_dealloc(cycleobject *lz) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	PyObject_GC_UnTrack(lz); | 
					
						
							|  |  |  | 	Py_XDECREF(lz->saved); | 
					
						
							|  |  |  | 	Py_XDECREF(lz->it); | 
					
						
							|  |  |  | 	lz->ob_type->tp_free(lz); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static int | 
					
						
							|  |  |  | cycle_traverse(cycleobject *lz, visitproc visit, void *arg) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	int err; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (lz->it) { | 
					
						
							|  |  |  | 		err = visit(lz->it, arg); | 
					
						
							|  |  |  | 		if (err) | 
					
						
							|  |  |  | 			return err; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	if (lz->saved) { | 
					
						
							|  |  |  | 		err = visit(lz->saved, arg); | 
					
						
							|  |  |  | 		if (err) | 
					
						
							|  |  |  | 			return err; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static PyObject * | 
					
						
							|  |  |  | cycle_next(cycleobject *lz) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	PyObject *item; | 
					
						
							|  |  |  | 	PyObject *it; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	while (1) { | 
					
						
							|  |  |  | 		item = PyIter_Next(lz->it); | 
					
						
							|  |  |  | 		if (item != NULL) { | 
					
						
							|  |  |  | 			if (!lz->firstpass) | 
					
						
							|  |  |  | 				PyList_Append(lz->saved, item); | 
					
						
							|  |  |  | 			return item; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		if (PyList_Size(lz->saved) == 0)  | 
					
						
							|  |  |  | 			return NULL; | 
					
						
							|  |  |  | 		it = PyObject_GetIter(lz->saved); | 
					
						
							|  |  |  | 		if (it == NULL) | 
					
						
							|  |  |  | 			return NULL; | 
					
						
							|  |  |  | 		Py_DECREF(lz->it); | 
					
						
							|  |  |  | 		lz->it = it; | 
					
						
							|  |  |  | 		lz->firstpass = 1; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | PyDoc_STRVAR(cycle_doc, | 
					
						
							|  |  |  | "cycle(iterable) --> cycle object\n\
 | 
					
						
							|  |  |  | \n\ | 
					
						
							|  |  |  | Return elements from the iterable until it is exhausted.\n\ | 
					
						
							|  |  |  | Then repeat the sequence indefinitely."); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-07-14 07:07:12 +00:00
										 |  |  | static PyTypeObject cycle_type = { | 
					
						
							| 
									
										
										
										
											2003-02-23 04:40:07 +00:00
										 |  |  | 	PyObject_HEAD_INIT(NULL) | 
					
						
							|  |  |  | 	0,				/* ob_size */ | 
					
						
							|  |  |  | 	"itertools.cycle",		/* tp_name */ | 
					
						
							|  |  |  | 	sizeof(cycleobject),		/* tp_basicsize */ | 
					
						
							|  |  |  | 	0,				/* tp_itemsize */ | 
					
						
							|  |  |  | 	/* methods */ | 
					
						
							|  |  |  | 	(destructor)cycle_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 */ | 
					
						
							|  |  |  | 	cycle_doc,			/* tp_doc */ | 
					
						
							|  |  |  | 	(traverseproc)cycle_traverse,	/* tp_traverse */ | 
					
						
							|  |  |  | 	0,				/* tp_clear */ | 
					
						
							|  |  |  | 	0,				/* tp_richcompare */ | 
					
						
							|  |  |  | 	0,				/* tp_weaklistoffset */ | 
					
						
							| 
									
										
										
										
											2003-03-17 19:46:11 +00:00
										 |  |  | 	PyObject_SelfIter,		/* tp_iter */ | 
					
						
							| 
									
										
										
										
											2003-02-23 04:40:07 +00:00
										 |  |  | 	(iternextfunc)cycle_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 */ | 
					
						
							| 
									
										
										
										
											2003-05-23 03:55:42 +00:00
										 |  |  | 	0,				/* tp_alloc */ | 
					
						
							| 
									
										
										
										
											2003-02-23 04:40:07 +00:00
										 |  |  | 	cycle_new,			/* tp_new */ | 
					
						
							|  |  |  | 	PyObject_GC_Del,		/* tp_free */ | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-02-01 00:10:11 +00:00
										 |  |  | /* dropwhile object **********************************************************/ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | typedef struct { | 
					
						
							|  |  |  | 	PyObject_HEAD | 
					
						
							|  |  |  | 	PyObject *func; | 
					
						
							|  |  |  | 	PyObject *it; | 
					
						
							|  |  |  | 	long	 start; | 
					
						
							|  |  |  | } dropwhileobject; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-07-14 07:07:12 +00:00
										 |  |  | static PyTypeObject dropwhile_type; | 
					
						
							| 
									
										
										
										
											2003-02-01 00:10:11 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | static PyObject * | 
					
						
							|  |  |  | dropwhile_new(PyTypeObject *type, PyObject *args, PyObject *kwds) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	PyObject *func, *seq; | 
					
						
							|  |  |  | 	PyObject *it; | 
					
						
							|  |  |  | 	dropwhileobject *lz; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (!PyArg_UnpackTuple(args, "dropwhile", 2, 2, &func, &seq)) | 
					
						
							|  |  |  | 		return NULL; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* Get iterator. */ | 
					
						
							|  |  |  | 	it = PyObject_GetIter(seq); | 
					
						
							|  |  |  | 	if (it == NULL) | 
					
						
							|  |  |  | 		return NULL; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* create dropwhileobject structure */ | 
					
						
							|  |  |  | 	lz = (dropwhileobject *)type->tp_alloc(type, 0); | 
					
						
							|  |  |  | 	if (lz == NULL) { | 
					
						
							|  |  |  | 		Py_DECREF(it); | 
					
						
							|  |  |  | 		return NULL; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	Py_INCREF(func); | 
					
						
							|  |  |  | 	lz->func = func; | 
					
						
							|  |  |  | 	lz->it = it; | 
					
						
							|  |  |  | 	lz->start = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return (PyObject *)lz; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void | 
					
						
							|  |  |  | dropwhile_dealloc(dropwhileobject *lz) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	PyObject_GC_UnTrack(lz); | 
					
						
							|  |  |  | 	Py_XDECREF(lz->func); | 
					
						
							|  |  |  | 	Py_XDECREF(lz->it); | 
					
						
							|  |  |  | 	lz->ob_type->tp_free(lz); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static int | 
					
						
							|  |  |  | dropwhile_traverse(dropwhileobject *lz, visitproc visit, void *arg) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	int err; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (lz->it) { | 
					
						
							|  |  |  | 		err = visit(lz->it, arg); | 
					
						
							|  |  |  | 		if (err) | 
					
						
							|  |  |  | 			return err; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	if (lz->func) { | 
					
						
							|  |  |  | 		err = visit(lz->func, arg); | 
					
						
							|  |  |  | 		if (err) | 
					
						
							|  |  |  | 			return err; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static PyObject * | 
					
						
							|  |  |  | dropwhile_next(dropwhileobject *lz) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	PyObject *item, *good; | 
					
						
							| 
									
										
										
										
											2003-03-01 01:48:24 +00:00
										 |  |  | 	PyObject *it = lz->it; | 
					
						
							| 
									
										
										
										
											2003-02-01 00:10:11 +00:00
										 |  |  | 	long ok; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	for (;;) { | 
					
						
							| 
									
										
										
										
											2003-03-01 01:48:24 +00:00
										 |  |  | 		assert(PyIter_Check(it)); | 
					
						
							|  |  |  | 		item = (*it->ob_type->tp_iternext)(it); | 
					
						
							| 
									
										
										
										
											2003-02-01 00:10:11 +00:00
										 |  |  | 		if (item == NULL) | 
					
						
							|  |  |  | 			return NULL; | 
					
						
							|  |  |  | 		if (lz->start == 1) | 
					
						
							|  |  |  | 			return item; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		good = PyObject_CallFunctionObjArgs(lz->func, item, NULL); | 
					
						
							|  |  |  | 		if (good == NULL) { | 
					
						
							|  |  |  | 			Py_DECREF(item); | 
					
						
							|  |  |  | 			return NULL; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		ok = PyObject_IsTrue(good); | 
					
						
							|  |  |  | 		Py_DECREF(good); | 
					
						
							|  |  |  | 		if (!ok) { | 
					
						
							|  |  |  | 			lz->start = 1; | 
					
						
							|  |  |  | 			return item; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		Py_DECREF(item); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | PyDoc_STRVAR(dropwhile_doc, | 
					
						
							|  |  |  | "dropwhile(predicate, iterable) --> dropwhile object\n\
 | 
					
						
							|  |  |  | \n\ | 
					
						
							|  |  |  | Drop items from the iterable while predicate(item) is true.\n\ | 
					
						
							|  |  |  | Afterwards, return every element until the iterable is exhausted."); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-07-14 07:07:12 +00:00
										 |  |  | static PyTypeObject dropwhile_type = { | 
					
						
							| 
									
										
										
										
											2003-02-01 00:10:11 +00:00
										 |  |  | 	PyObject_HEAD_INIT(NULL) | 
					
						
							|  |  |  | 	0,				/* ob_size */ | 
					
						
							| 
									
										
										
										
											2003-02-09 06:40:58 +00:00
										 |  |  | 	"itertools.dropwhile",		/* tp_name */ | 
					
						
							|  |  |  | 	sizeof(dropwhileobject),	/* tp_basicsize */ | 
					
						
							| 
									
										
										
										
											2003-02-01 00:10:11 +00:00
										 |  |  | 	0,				/* tp_itemsize */ | 
					
						
							|  |  |  | 	/* methods */ | 
					
						
							| 
									
										
										
										
											2003-02-09 06:40:58 +00:00
										 |  |  | 	(destructor)dropwhile_dealloc,	/* tp_dealloc */ | 
					
						
							| 
									
										
										
										
											2003-02-01 00:10:11 +00:00
										 |  |  | 	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 */ | 
					
						
							| 
									
										
										
										
											2003-02-09 06:40:58 +00:00
										 |  |  | 	dropwhile_doc,			/* tp_doc */ | 
					
						
							| 
									
										
										
										
											2003-02-01 00:10:11 +00:00
										 |  |  | 	(traverseproc)dropwhile_traverse,    /* tp_traverse */ | 
					
						
							|  |  |  | 	0,				/* tp_clear */ | 
					
						
							|  |  |  | 	0,				/* tp_richcompare */ | 
					
						
							|  |  |  | 	0,				/* tp_weaklistoffset */ | 
					
						
							| 
									
										
										
										
											2003-03-17 19:46:11 +00:00
										 |  |  | 	PyObject_SelfIter,		/* tp_iter */ | 
					
						
							| 
									
										
										
										
											2003-02-09 06:40:58 +00:00
										 |  |  | 	(iternextfunc)dropwhile_next,	/* tp_iternext */ | 
					
						
							| 
									
										
										
										
											2003-02-01 00:10:11 +00:00
										 |  |  | 	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 */ | 
					
						
							| 
									
										
										
										
											2003-05-23 03:55:42 +00:00
										 |  |  | 	0,				/* tp_alloc */ | 
					
						
							| 
									
										
										
										
											2003-02-09 06:40:58 +00:00
										 |  |  | 	dropwhile_new,			/* tp_new */ | 
					
						
							| 
									
										
										
										
											2003-02-01 00:10:11 +00:00
										 |  |  | 	PyObject_GC_Del,		/* tp_free */ | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* takewhile object **********************************************************/ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | typedef struct { | 
					
						
							|  |  |  | 	PyObject_HEAD | 
					
						
							|  |  |  | 	PyObject *func; | 
					
						
							|  |  |  | 	PyObject *it; | 
					
						
							|  |  |  | 	long	 stop; | 
					
						
							|  |  |  | } takewhileobject; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-07-14 07:07:12 +00:00
										 |  |  | static PyTypeObject takewhile_type; | 
					
						
							| 
									
										
										
										
											2003-02-01 00:10:11 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | static PyObject * | 
					
						
							|  |  |  | takewhile_new(PyTypeObject *type, PyObject *args, PyObject *kwds) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	PyObject *func, *seq; | 
					
						
							|  |  |  | 	PyObject *it; | 
					
						
							|  |  |  | 	takewhileobject *lz; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (!PyArg_UnpackTuple(args, "takewhile", 2, 2, &func, &seq)) | 
					
						
							|  |  |  | 		return NULL; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* Get iterator. */ | 
					
						
							|  |  |  | 	it = PyObject_GetIter(seq); | 
					
						
							|  |  |  | 	if (it == NULL) | 
					
						
							|  |  |  | 		return NULL; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* create takewhileobject structure */ | 
					
						
							|  |  |  | 	lz = (takewhileobject *)type->tp_alloc(type, 0); | 
					
						
							|  |  |  | 	if (lz == NULL) { | 
					
						
							|  |  |  | 		Py_DECREF(it); | 
					
						
							|  |  |  | 		return NULL; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	Py_INCREF(func); | 
					
						
							|  |  |  | 	lz->func = func; | 
					
						
							|  |  |  | 	lz->it = it; | 
					
						
							|  |  |  | 	lz->stop = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return (PyObject *)lz; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void | 
					
						
							|  |  |  | takewhile_dealloc(takewhileobject *lz) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	PyObject_GC_UnTrack(lz); | 
					
						
							|  |  |  | 	Py_XDECREF(lz->func); | 
					
						
							|  |  |  | 	Py_XDECREF(lz->it); | 
					
						
							|  |  |  | 	lz->ob_type->tp_free(lz); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static int | 
					
						
							|  |  |  | takewhile_traverse(takewhileobject *lz, visitproc visit, void *arg) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	int err; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (lz->it) { | 
					
						
							|  |  |  | 		err = visit(lz->it, arg); | 
					
						
							|  |  |  | 		if (err) | 
					
						
							|  |  |  | 			return err; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	if (lz->func) { | 
					
						
							|  |  |  | 		err = visit(lz->func, arg); | 
					
						
							|  |  |  | 		if (err) | 
					
						
							|  |  |  | 			return err; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static PyObject * | 
					
						
							|  |  |  | takewhile_next(takewhileobject *lz) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	PyObject *item, *good; | 
					
						
							| 
									
										
										
										
											2003-03-01 01:48:24 +00:00
										 |  |  | 	PyObject *it = lz->it; | 
					
						
							| 
									
										
										
										
											2003-02-01 00:10:11 +00:00
										 |  |  | 	long ok; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (lz->stop == 1) | 
					
						
							|  |  |  | 		return NULL; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-03-01 01:48:24 +00:00
										 |  |  | 	assert(PyIter_Check(it)); | 
					
						
							|  |  |  | 	item = (*it->ob_type->tp_iternext)(it); | 
					
						
							| 
									
										
										
										
											2003-02-01 00:10:11 +00:00
										 |  |  | 	if (item == NULL) | 
					
						
							|  |  |  | 		return NULL; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	good = PyObject_CallFunctionObjArgs(lz->func, item, NULL); | 
					
						
							|  |  |  | 	if (good == NULL) { | 
					
						
							|  |  |  | 		Py_DECREF(item); | 
					
						
							|  |  |  | 		return NULL; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	ok = PyObject_IsTrue(good); | 
					
						
							|  |  |  | 	Py_DECREF(good); | 
					
						
							|  |  |  | 	if (ok) | 
					
						
							|  |  |  | 		return item; | 
					
						
							|  |  |  | 	Py_DECREF(item); | 
					
						
							|  |  |  | 	lz->stop = 1; | 
					
						
							|  |  |  | 	return NULL; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | PyDoc_STRVAR(takewhile_doc, | 
					
						
							|  |  |  | "takewhile(predicate, iterable) --> takewhile object\n\
 | 
					
						
							|  |  |  | \n\ | 
					
						
							|  |  |  | Return successive entries from an iterable as long as the \n\ | 
					
						
							|  |  |  | predicate evaluates to true for each entry."); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-07-14 07:07:12 +00:00
										 |  |  | static PyTypeObject takewhile_type = { | 
					
						
							| 
									
										
										
										
											2003-02-01 00:10:11 +00:00
										 |  |  | 	PyObject_HEAD_INIT(NULL) | 
					
						
							|  |  |  | 	0,				/* ob_size */ | 
					
						
							| 
									
										
										
										
											2003-02-09 06:40:58 +00:00
										 |  |  | 	"itertools.takewhile",		/* tp_name */ | 
					
						
							|  |  |  | 	sizeof(takewhileobject),	/* tp_basicsize */ | 
					
						
							| 
									
										
										
										
											2003-02-01 00:10:11 +00:00
										 |  |  | 	0,				/* tp_itemsize */ | 
					
						
							|  |  |  | 	/* methods */ | 
					
						
							| 
									
										
										
										
											2003-02-09 06:40:58 +00:00
										 |  |  | 	(destructor)takewhile_dealloc,	/* tp_dealloc */ | 
					
						
							| 
									
										
										
										
											2003-02-01 00:10:11 +00:00
										 |  |  | 	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 */ | 
					
						
							| 
									
										
										
										
											2003-02-09 06:40:58 +00:00
										 |  |  | 	takewhile_doc,			/* tp_doc */ | 
					
						
							| 
									
										
										
										
											2003-02-01 00:10:11 +00:00
										 |  |  | 	(traverseproc)takewhile_traverse,    /* tp_traverse */ | 
					
						
							|  |  |  | 	0,				/* tp_clear */ | 
					
						
							|  |  |  | 	0,				/* tp_richcompare */ | 
					
						
							|  |  |  | 	0,				/* tp_weaklistoffset */ | 
					
						
							| 
									
										
										
										
											2003-03-17 19:46:11 +00:00
										 |  |  | 	PyObject_SelfIter,		/* tp_iter */ | 
					
						
							| 
									
										
										
										
											2003-02-09 06:40:58 +00:00
										 |  |  | 	(iternextfunc)takewhile_next,	/* tp_iternext */ | 
					
						
							| 
									
										
										
										
											2003-02-01 00:10:11 +00:00
										 |  |  | 	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 */ | 
					
						
							| 
									
										
										
										
											2003-05-23 03:55:42 +00:00
										 |  |  | 	0,				/* tp_alloc */ | 
					
						
							| 
									
										
										
										
											2003-02-09 06:40:58 +00:00
										 |  |  | 	takewhile_new,			/* tp_new */ | 
					
						
							| 
									
										
										
										
											2003-02-01 00:10:11 +00:00
										 |  |  | 	PyObject_GC_Del,		/* tp_free */ | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* islice object ************************************************************/ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | typedef struct { | 
					
						
							|  |  |  | 	PyObject_HEAD | 
					
						
							|  |  |  | 	PyObject *it; | 
					
						
							|  |  |  | 	long	next; | 
					
						
							|  |  |  | 	long	stop; | 
					
						
							|  |  |  | 	long	step; | 
					
						
							|  |  |  | 	long	cnt; | 
					
						
							|  |  |  | } isliceobject; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-07-14 07:07:12 +00:00
										 |  |  | static PyTypeObject islice_type; | 
					
						
							| 
									
										
										
										
											2003-02-01 00:10:11 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | static PyObject * | 
					
						
							|  |  |  | islice_new(PyTypeObject *type, PyObject *args, PyObject *kwds) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	PyObject *seq; | 
					
						
							| 
									
										
										
										
											2003-05-02 19:04:37 +00:00
										 |  |  | 	long start=0, stop=-1, step=1; | 
					
						
							|  |  |  | 	PyObject *it, *a1=NULL, *a2=NULL; | 
					
						
							| 
									
										
										
										
											2003-02-01 00:10:11 +00:00
										 |  |  | 	int numargs; | 
					
						
							|  |  |  | 	isliceobject *lz; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	numargs = PyTuple_Size(args); | 
					
						
							| 
									
										
										
										
											2003-05-02 19:44:20 +00:00
										 |  |  | 	if (!PyArg_ParseTuple(args, "OO|Ol:islice", &seq, &a1, &a2, &step)) | 
					
						
							| 
									
										
										
										
											2003-02-01 00:10:11 +00:00
										 |  |  | 		return NULL; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (numargs == 2) { | 
					
						
							| 
									
										
										
										
											2003-05-02 19:04:37 +00:00
										 |  |  | 		if (a1 != Py_None) { | 
					
						
							|  |  |  | 			stop = PyInt_AsLong(a1); | 
					
						
							|  |  |  | 			if (stop == -1) { | 
					
						
							|  |  |  | 				if (PyErr_Occurred()) | 
					
						
							|  |  |  | 					PyErr_Clear(); | 
					
						
							|  |  |  | 				PyErr_SetString(PyExc_ValueError, | 
					
						
							|  |  |  | 				   "Stop argument must be an integer or None."); | 
					
						
							|  |  |  | 				return NULL; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2003-05-02 19:44:20 +00:00
										 |  |  | 	} else { | 
					
						
							| 
									
										
										
										
											2003-05-02 19:04:37 +00:00
										 |  |  | 		start = PyInt_AsLong(a1); | 
					
						
							|  |  |  | 		if (start == -1 && PyErr_Occurred()) { | 
					
						
							|  |  |  | 			PyErr_Clear(); | 
					
						
							|  |  |  | 			PyErr_SetString(PyExc_ValueError, | 
					
						
							|  |  |  | 			   "Start argument must be an integer."); | 
					
						
							|  |  |  | 			return NULL; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		if (a2 != Py_None) { | 
					
						
							|  |  |  | 			stop = PyInt_AsLong(a2); | 
					
						
							|  |  |  | 			if (stop == -1) { | 
					
						
							|  |  |  | 				if (PyErr_Occurred()) | 
					
						
							|  |  |  | 					PyErr_Clear(); | 
					
						
							|  |  |  | 				PyErr_SetString(PyExc_ValueError, | 
					
						
							|  |  |  | 				   "Stop argument must be an integer or None."); | 
					
						
							|  |  |  | 				return NULL; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2003-02-01 00:10:11 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-05-02 19:04:37 +00:00
										 |  |  | 	if (start<0 || stop<-1) { | 
					
						
							| 
									
										
										
										
											2003-02-01 00:10:11 +00:00
										 |  |  | 		PyErr_SetString(PyExc_ValueError, | 
					
						
							|  |  |  | 		   "Indices for islice() must be positive."); | 
					
						
							|  |  |  | 		return NULL; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (step<1) { | 
					
						
							|  |  |  | 		PyErr_SetString(PyExc_ValueError, | 
					
						
							|  |  |  | 		   "Step must be one or larger for islice()."); | 
					
						
							|  |  |  | 		return NULL; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* Get iterator. */ | 
					
						
							|  |  |  | 	it = PyObject_GetIter(seq); | 
					
						
							|  |  |  | 	if (it == NULL) | 
					
						
							|  |  |  | 		return NULL; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* create isliceobject structure */ | 
					
						
							|  |  |  | 	lz = (isliceobject *)type->tp_alloc(type, 0); | 
					
						
							|  |  |  | 	if (lz == NULL) { | 
					
						
							|  |  |  | 		Py_DECREF(it); | 
					
						
							|  |  |  | 		return NULL; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	lz->it = it; | 
					
						
							|  |  |  | 	lz->next = start; | 
					
						
							|  |  |  | 	lz->stop = stop; | 
					
						
							|  |  |  | 	lz->step = step; | 
					
						
							|  |  |  | 	lz->cnt = 0L; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return (PyObject *)lz; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void | 
					
						
							|  |  |  | islice_dealloc(isliceobject *lz) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	PyObject_GC_UnTrack(lz); | 
					
						
							|  |  |  | 	Py_XDECREF(lz->it); | 
					
						
							|  |  |  | 	lz->ob_type->tp_free(lz); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static int | 
					
						
							|  |  |  | islice_traverse(isliceobject *lz, visitproc visit, void *arg) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	if (lz->it) | 
					
						
							|  |  |  | 		return visit(lz->it, arg); | 
					
						
							|  |  |  | 	return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static PyObject * | 
					
						
							|  |  |  | islice_next(isliceobject *lz) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	PyObject *item; | 
					
						
							| 
									
										
										
										
											2003-03-01 01:48:24 +00:00
										 |  |  | 	PyObject *it = lz->it; | 
					
						
							| 
									
										
										
										
											2003-02-07 05:32:58 +00:00
										 |  |  | 	long oldnext; | 
					
						
							| 
									
										
										
										
											2003-02-01 00:10:11 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	while (lz->cnt < lz->next) { | 
					
						
							| 
									
										
										
										
											2003-03-01 01:48:24 +00:00
										 |  |  | 		assert(PyIter_Check(it)); | 
					
						
							|  |  |  | 		item = (*it->ob_type->tp_iternext)(it); | 
					
						
							| 
									
										
										
										
											2003-02-01 00:10:11 +00:00
										 |  |  | 		if (item == NULL) | 
					
						
							|  |  |  | 			return NULL; | 
					
						
							|  |  |  | 		Py_DECREF(item); | 
					
						
							|  |  |  | 		lz->cnt++; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2003-05-02 19:04:37 +00:00
										 |  |  | 	if (lz->stop != -1 && lz->cnt >= lz->stop) | 
					
						
							| 
									
										
										
										
											2003-02-01 00:10:11 +00:00
										 |  |  | 		return NULL; | 
					
						
							| 
									
										
										
										
											2003-03-01 01:48:24 +00:00
										 |  |  | 	assert(PyIter_Check(it)); | 
					
						
							|  |  |  | 	item = (*it->ob_type->tp_iternext)(it); | 
					
						
							| 
									
										
										
										
											2003-02-01 00:10:11 +00:00
										 |  |  | 	if (item == NULL) | 
					
						
							|  |  |  | 		return NULL; | 
					
						
							|  |  |  | 	lz->cnt++; | 
					
						
							| 
									
										
										
										
											2003-02-07 05:32:58 +00:00
										 |  |  | 	oldnext = lz->next; | 
					
						
							| 
									
										
										
										
											2003-02-01 00:10:11 +00:00
										 |  |  | 	lz->next += lz->step; | 
					
						
							| 
									
										
										
										
											2003-02-07 05:32:58 +00:00
										 |  |  | 	if (lz->next < oldnext)	/* Check for overflow */ | 
					
						
							|  |  |  | 		lz->next = lz->stop; | 
					
						
							| 
									
										
										
										
											2003-02-01 00:10:11 +00:00
										 |  |  | 	return item; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | PyDoc_STRVAR(islice_doc, | 
					
						
							|  |  |  | "islice(iterable, [start,] stop [, step]) --> islice object\n\
 | 
					
						
							|  |  |  | \n\ | 
					
						
							|  |  |  | Return an iterator whose next() method returns selected values from an\n\ | 
					
						
							|  |  |  | iterable.  If start is specified, will skip all preceding elements;\n\ | 
					
						
							|  |  |  | otherwise, start defaults to zero.  Step defaults to one.  If\n\ | 
					
						
							|  |  |  | specified as another value, step determines how many values are \n\ | 
					
						
							|  |  |  | skipped between successive calls.  Works like a slice() on a list\n\ | 
					
						
							|  |  |  | but returns an iterator."); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-07-14 07:07:12 +00:00
										 |  |  | static PyTypeObject islice_type = { | 
					
						
							| 
									
										
										
										
											2003-02-01 00:10:11 +00:00
										 |  |  | 	PyObject_HEAD_INIT(NULL) | 
					
						
							|  |  |  | 	0,				/* ob_size */ | 
					
						
							|  |  |  | 	"itertools.islice",		/* tp_name */ | 
					
						
							|  |  |  | 	sizeof(isliceobject),		/* tp_basicsize */ | 
					
						
							|  |  |  | 	0,				/* tp_itemsize */ | 
					
						
							|  |  |  | 	/* methods */ | 
					
						
							| 
									
										
										
										
											2003-02-09 06:40:58 +00:00
										 |  |  | 	(destructor)islice_dealloc,	/* tp_dealloc */ | 
					
						
							| 
									
										
										
										
											2003-02-01 00:10:11 +00:00
										 |  |  | 	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 */ | 
					
						
							| 
									
										
										
										
											2003-02-09 06:40:58 +00:00
										 |  |  | 	islice_doc,			/* tp_doc */ | 
					
						
							|  |  |  | 	(traverseproc)islice_traverse,	/* tp_traverse */ | 
					
						
							| 
									
										
										
										
											2003-02-01 00:10:11 +00:00
										 |  |  | 	0,				/* tp_clear */ | 
					
						
							|  |  |  | 	0,				/* tp_richcompare */ | 
					
						
							|  |  |  | 	0,				/* tp_weaklistoffset */ | 
					
						
							| 
									
										
										
										
											2003-03-17 19:46:11 +00:00
										 |  |  | 	PyObject_SelfIter,		/* tp_iter */ | 
					
						
							| 
									
										
										
										
											2003-02-09 06:40:58 +00:00
										 |  |  | 	(iternextfunc)islice_next,	/* tp_iternext */ | 
					
						
							| 
									
										
										
										
											2003-02-01 00:10:11 +00:00
										 |  |  | 	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 */ | 
					
						
							| 
									
										
										
										
											2003-05-23 03:55:42 +00:00
										 |  |  | 	0,				/* tp_alloc */ | 
					
						
							| 
									
										
										
										
											2003-02-01 00:10:11 +00:00
										 |  |  | 	islice_new,			/* tp_new */ | 
					
						
							|  |  |  | 	PyObject_GC_Del,		/* tp_free */ | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* starmap object ************************************************************/ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | typedef struct { | 
					
						
							|  |  |  | 	PyObject_HEAD | 
					
						
							|  |  |  | 	PyObject *func; | 
					
						
							|  |  |  | 	PyObject *it; | 
					
						
							|  |  |  | } starmapobject; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-07-14 07:07:12 +00:00
										 |  |  | static PyTypeObject starmap_type; | 
					
						
							| 
									
										
										
										
											2003-02-01 00:10:11 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | static PyObject * | 
					
						
							|  |  |  | starmap_new(PyTypeObject *type, PyObject *args, PyObject *kwds) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	PyObject *func, *seq; | 
					
						
							|  |  |  | 	PyObject *it; | 
					
						
							|  |  |  | 	starmapobject *lz; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (!PyArg_UnpackTuple(args, "starmap", 2, 2, &func, &seq)) | 
					
						
							|  |  |  | 		return NULL; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* Get iterator. */ | 
					
						
							|  |  |  | 	it = PyObject_GetIter(seq); | 
					
						
							|  |  |  | 	if (it == NULL) | 
					
						
							|  |  |  | 		return NULL; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* create starmapobject structure */ | 
					
						
							|  |  |  | 	lz = (starmapobject *)type->tp_alloc(type, 0); | 
					
						
							|  |  |  | 	if (lz == NULL) { | 
					
						
							|  |  |  | 		Py_DECREF(it); | 
					
						
							|  |  |  | 		return NULL; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	Py_INCREF(func); | 
					
						
							|  |  |  | 	lz->func = func; | 
					
						
							|  |  |  | 	lz->it = it; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return (PyObject *)lz; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void | 
					
						
							|  |  |  | starmap_dealloc(starmapobject *lz) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	PyObject_GC_UnTrack(lz); | 
					
						
							|  |  |  | 	Py_XDECREF(lz->func); | 
					
						
							|  |  |  | 	Py_XDECREF(lz->it); | 
					
						
							|  |  |  | 	lz->ob_type->tp_free(lz); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static int | 
					
						
							|  |  |  | starmap_traverse(starmapobject *lz, visitproc visit, void *arg) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	int err; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (lz->it) { | 
					
						
							|  |  |  | 		err = visit(lz->it, arg); | 
					
						
							|  |  |  | 		if (err) | 
					
						
							|  |  |  | 			return err; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	if (lz->func) { | 
					
						
							|  |  |  | 		err = visit(lz->func, arg); | 
					
						
							|  |  |  | 		if (err) | 
					
						
							|  |  |  | 			return err; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static PyObject * | 
					
						
							|  |  |  | starmap_next(starmapobject *lz) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	PyObject *args; | 
					
						
							|  |  |  | 	PyObject *result; | 
					
						
							| 
									
										
										
										
											2003-03-01 01:48:24 +00:00
										 |  |  | 	PyObject *it = lz->it; | 
					
						
							| 
									
										
										
										
											2003-02-01 00:10:11 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-03-01 01:48:24 +00:00
										 |  |  | 	assert(PyIter_Check(it)); | 
					
						
							|  |  |  | 	args = (*it->ob_type->tp_iternext)(it); | 
					
						
							| 
									
										
										
										
											2003-02-01 00:10:11 +00:00
										 |  |  | 	if (args == NULL) | 
					
						
							|  |  |  | 		return NULL; | 
					
						
							| 
									
										
										
										
											2003-02-07 05:32:58 +00:00
										 |  |  | 	if (!PyTuple_CheckExact(args)) { | 
					
						
							|  |  |  | 		Py_DECREF(args); | 
					
						
							|  |  |  | 		PyErr_SetString(PyExc_TypeError, | 
					
						
							|  |  |  | 				"iterator must return a tuple"); | 
					
						
							|  |  |  | 		return NULL; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2003-02-01 00:10:11 +00:00
										 |  |  | 	result = PyObject_Call(lz->func, args, NULL); | 
					
						
							|  |  |  | 	Py_DECREF(args); | 
					
						
							|  |  |  | 	return result; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | PyDoc_STRVAR(starmap_doc, | 
					
						
							|  |  |  | "starmap(function, sequence) --> starmap object\n\
 | 
					
						
							|  |  |  | \n\ | 
					
						
							|  |  |  | Return an iterator whose values are returned from the function evaluated\n\ | 
					
						
							|  |  |  | with a argument tuple taken from the given sequence."); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-07-14 07:07:12 +00:00
										 |  |  | static PyTypeObject starmap_type = { | 
					
						
							| 
									
										
										
										
											2003-02-01 00:10:11 +00:00
										 |  |  | 	PyObject_HEAD_INIT(NULL) | 
					
						
							|  |  |  | 	0,				/* ob_size */ | 
					
						
							| 
									
										
										
										
											2003-02-09 06:40:58 +00:00
										 |  |  | 	"itertools.starmap",		/* tp_name */ | 
					
						
							|  |  |  | 	sizeof(starmapobject),		/* tp_basicsize */ | 
					
						
							| 
									
										
										
										
											2003-02-01 00:10:11 +00:00
										 |  |  | 	0,				/* tp_itemsize */ | 
					
						
							|  |  |  | 	/* methods */ | 
					
						
							| 
									
										
										
										
											2003-02-09 06:40:58 +00:00
										 |  |  | 	(destructor)starmap_dealloc,	/* tp_dealloc */ | 
					
						
							| 
									
										
										
										
											2003-02-01 00:10:11 +00:00
										 |  |  | 	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 */ | 
					
						
							| 
									
										
										
										
											2003-02-09 06:40:58 +00:00
										 |  |  | 	starmap_doc,			/* tp_doc */ | 
					
						
							|  |  |  | 	(traverseproc)starmap_traverse,	/* tp_traverse */ | 
					
						
							| 
									
										
										
										
											2003-02-01 00:10:11 +00:00
										 |  |  | 	0,				/* tp_clear */ | 
					
						
							|  |  |  | 	0,				/* tp_richcompare */ | 
					
						
							|  |  |  | 	0,				/* tp_weaklistoffset */ | 
					
						
							| 
									
										
										
										
											2003-03-17 19:46:11 +00:00
										 |  |  | 	PyObject_SelfIter,		/* tp_iter */ | 
					
						
							| 
									
										
										
										
											2003-02-09 06:40:58 +00:00
										 |  |  | 	(iternextfunc)starmap_next,	/* tp_iternext */ | 
					
						
							| 
									
										
										
										
											2003-02-01 00:10:11 +00:00
										 |  |  | 	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 */ | 
					
						
							| 
									
										
										
										
											2003-05-23 03:55:42 +00:00
										 |  |  | 	0,				/* tp_alloc */ | 
					
						
							| 
									
										
										
										
											2003-02-09 06:40:58 +00:00
										 |  |  | 	starmap_new,			/* tp_new */ | 
					
						
							| 
									
										
										
										
											2003-02-01 00:10:11 +00:00
										 |  |  | 	PyObject_GC_Del,		/* tp_free */ | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* imap object ************************************************************/ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | typedef struct { | 
					
						
							|  |  |  | 	PyObject_HEAD | 
					
						
							|  |  |  | 	PyObject *iters; | 
					
						
							|  |  |  | 	PyObject *func; | 
					
						
							|  |  |  | } imapobject; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-07-14 07:07:12 +00:00
										 |  |  | static PyTypeObject imap_type; | 
					
						
							| 
									
										
										
										
											2003-02-01 00:10:11 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | static PyObject * | 
					
						
							|  |  |  | imap_new(PyTypeObject *type, PyObject *args, PyObject *kwds) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2003-02-07 07:26:25 +00:00
										 |  |  | 	PyObject *it, *iters, *func; | 
					
						
							| 
									
										
										
										
											2003-02-01 00:10:11 +00:00
										 |  |  | 	imapobject *lz; | 
					
						
							|  |  |  | 	int numargs, i; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	numargs = PyTuple_Size(args); | 
					
						
							|  |  |  | 	if (numargs < 2) { | 
					
						
							|  |  |  | 		PyErr_SetString(PyExc_TypeError, | 
					
						
							|  |  |  | 		   "imap() must have at least two arguments."); | 
					
						
							|  |  |  | 		return NULL; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	iters = PyTuple_New(numargs-1); | 
					
						
							|  |  |  | 	if (iters == NULL) | 
					
						
							|  |  |  | 		return NULL; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	for (i=1 ; i<numargs ; i++) { | 
					
						
							|  |  |  | 		/* Get iterator. */ | 
					
						
							|  |  |  | 		it = PyObject_GetIter(PyTuple_GET_ITEM(args, i)); | 
					
						
							|  |  |  | 		if (it == NULL) { | 
					
						
							|  |  |  | 			Py_DECREF(iters); | 
					
						
							|  |  |  | 			return NULL; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		PyTuple_SET_ITEM(iters, i-1, it); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* create imapobject structure */ | 
					
						
							|  |  |  | 	lz = (imapobject *)type->tp_alloc(type, 0); | 
					
						
							|  |  |  | 	if (lz == NULL) { | 
					
						
							|  |  |  | 		Py_DECREF(iters); | 
					
						
							|  |  |  | 		return NULL; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	lz->iters = iters; | 
					
						
							|  |  |  | 	func = PyTuple_GET_ITEM(args, 0); | 
					
						
							|  |  |  | 	Py_INCREF(func); | 
					
						
							|  |  |  | 	lz->func = func; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return (PyObject *)lz; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void | 
					
						
							|  |  |  | imap_dealloc(imapobject *lz) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	PyObject_GC_UnTrack(lz); | 
					
						
							|  |  |  | 	Py_XDECREF(lz->iters); | 
					
						
							|  |  |  | 	Py_XDECREF(lz->func); | 
					
						
							|  |  |  | 	lz->ob_type->tp_free(lz); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static int | 
					
						
							|  |  |  | imap_traverse(imapobject *lz, visitproc visit, void *arg) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	int err; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (lz->iters) { | 
					
						
							|  |  |  | 		err = visit(lz->iters, arg); | 
					
						
							|  |  |  | 		if (err) | 
					
						
							|  |  |  | 			return err; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	if (lz->func) { | 
					
						
							|  |  |  | 		err = visit(lz->func, arg); | 
					
						
							|  |  |  | 		if (err) | 
					
						
							|  |  |  | 			return err; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-02-07 05:32:58 +00:00
										 |  |  | /*	
 | 
					
						
							|  |  |  | imap() is an iterator version of __builtins__.map() except that it does | 
					
						
							|  |  |  | not have the None fill-in feature.  That was intentionally left out for | 
					
						
							|  |  |  | the following reasons: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   1) Itertools are designed to be easily combined and chained together. | 
					
						
							|  |  |  |      Having all tools stop with the shortest input is a unifying principle | 
					
						
							|  |  |  |      that makes it easier to combine finite iterators (supplying data) with | 
					
						
							|  |  |  |      infinite iterators like count() and repeat() (for supplying sequential | 
					
						
							|  |  |  |      or constant arguments to a function). | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   2) In typical use cases for combining itertools, having one finite data  | 
					
						
							|  |  |  |      supplier run out before another is likely to be an error condition which | 
					
						
							|  |  |  |      should not pass silently by automatically supplying None. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   3) The use cases for automatic None fill-in are rare -- not many functions | 
					
						
							|  |  |  |      do something useful when a parameter suddenly switches type and becomes | 
					
						
							|  |  |  |      None.   | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   4) If a need does arise, it can be met by __builtins__.map() or by  | 
					
						
							| 
									
										
										
										
											2003-06-18 19:25:37 +00:00
										 |  |  |      writing:  chain(iterable, repeat(None)). | 
					
						
							| 
									
										
										
										
											2003-02-07 05:32:58 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |   5) Similar toolsets in Haskell and SML do not have automatic None fill-in. | 
					
						
							|  |  |  | */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-02-01 00:10:11 +00:00
										 |  |  | static PyObject * | 
					
						
							|  |  |  | imap_next(imapobject *lz) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	PyObject *val; | 
					
						
							| 
									
										
										
										
											2003-02-07 07:26:25 +00:00
										 |  |  | 	PyObject *argtuple; | 
					
						
							|  |  |  | 	PyObject *result; | 
					
						
							| 
									
										
										
										
											2003-02-01 00:10:11 +00:00
										 |  |  | 	int numargs, i; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	numargs = PyTuple_Size(lz->iters); | 
					
						
							| 
									
										
										
										
											2003-02-07 07:26:25 +00:00
										 |  |  | 	argtuple = PyTuple_New(numargs); | 
					
						
							|  |  |  | 	if (argtuple == NULL) | 
					
						
							|  |  |  | 		return NULL; | 
					
						
							| 
									
										
										
										
											2003-02-01 00:10:11 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-02-07 07:26:25 +00:00
										 |  |  | 	for (i=0 ; i<numargs ; i++) { | 
					
						
							|  |  |  | 		val = PyIter_Next(PyTuple_GET_ITEM(lz->iters, i)); | 
					
						
							|  |  |  | 		if (val == NULL) { | 
					
						
							|  |  |  | 			Py_DECREF(argtuple); | 
					
						
							|  |  |  | 			return NULL; | 
					
						
							| 
									
										
										
										
											2003-02-01 00:10:11 +00:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2003-02-07 07:26:25 +00:00
										 |  |  | 		PyTuple_SET_ITEM(argtuple, i, val); | 
					
						
							| 
									
										
										
										
											2003-02-01 00:10:11 +00:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2003-02-07 07:26:25 +00:00
										 |  |  | 	if (lz->func == Py_None)  | 
					
						
							|  |  |  | 		return argtuple; | 
					
						
							|  |  |  | 	result = PyObject_Call(lz->func, argtuple, NULL); | 
					
						
							|  |  |  | 	Py_DECREF(argtuple); | 
					
						
							|  |  |  | 	return result; | 
					
						
							| 
									
										
										
										
											2003-02-01 00:10:11 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | PyDoc_STRVAR(imap_doc, | 
					
						
							|  |  |  | "imap(func, *iterables) --> imap object\n\
 | 
					
						
							|  |  |  | \n\ | 
					
						
							|  |  |  | Make an iterator that computes the function using arguments from\n\ | 
					
						
							|  |  |  | each of the iterables.	Like map() except that it returns\n\ | 
					
						
							|  |  |  | an iterator instead of a list and that it stops when the shortest\n\ | 
					
						
							|  |  |  | iterable is exhausted instead of filling in None for shorter\n\ | 
					
						
							|  |  |  | iterables."); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-07-14 07:07:12 +00:00
										 |  |  | static PyTypeObject imap_type = { | 
					
						
							| 
									
										
										
										
											2003-02-01 00:10:11 +00:00
										 |  |  | 	PyObject_HEAD_INIT(NULL) | 
					
						
							|  |  |  | 	0,				/* ob_size */ | 
					
						
							| 
									
										
										
										
											2003-02-09 06:40:58 +00:00
										 |  |  | 	"itertools.imap",		/* tp_name */ | 
					
						
							|  |  |  | 	sizeof(imapobject),		/* tp_basicsize */ | 
					
						
							| 
									
										
										
										
											2003-02-01 00:10:11 +00:00
										 |  |  | 	0,				/* tp_itemsize */ | 
					
						
							|  |  |  | 	/* methods */ | 
					
						
							|  |  |  | 	(destructor)imap_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 */ | 
					
						
							|  |  |  | 	imap_doc,			/* tp_doc */ | 
					
						
							|  |  |  | 	(traverseproc)imap_traverse,	/* tp_traverse */ | 
					
						
							|  |  |  | 	0,				/* tp_clear */ | 
					
						
							|  |  |  | 	0,				/* tp_richcompare */ | 
					
						
							|  |  |  | 	0,				/* tp_weaklistoffset */ | 
					
						
							| 
									
										
										
										
											2003-03-17 19:46:11 +00:00
										 |  |  | 	PyObject_SelfIter,		/* tp_iter */ | 
					
						
							| 
									
										
										
										
											2003-02-01 00:10:11 +00:00
										 |  |  | 	(iternextfunc)imap_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 */ | 
					
						
							| 
									
										
										
										
											2003-05-23 03:55:42 +00:00
										 |  |  | 	0,				/* tp_alloc */ | 
					
						
							| 
									
										
										
										
											2003-02-09 06:40:58 +00:00
										 |  |  | 	imap_new,			/* tp_new */ | 
					
						
							| 
									
										
										
										
											2003-02-01 00:10:11 +00:00
										 |  |  | 	PyObject_GC_Del,		/* tp_free */ | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-02-23 04:40:07 +00:00
										 |  |  | /* chain object ************************************************************/ | 
					
						
							| 
									
										
										
										
											2003-02-01 00:10:11 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | typedef struct { | 
					
						
							|  |  |  | 	PyObject_HEAD | 
					
						
							| 
									
										
										
										
											2003-02-23 04:40:07 +00:00
										 |  |  | 	long	tuplesize; | 
					
						
							|  |  |  | 	long	iternum;		/* which iterator is active */ | 
					
						
							|  |  |  | 	PyObject *ittuple;		/* tuple of iterators */ | 
					
						
							|  |  |  | } chainobject; | 
					
						
							| 
									
										
										
										
											2003-02-01 00:10:11 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-07-14 07:07:12 +00:00
										 |  |  | static PyTypeObject chain_type; | 
					
						
							| 
									
										
										
										
											2003-02-01 00:10:11 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | static PyObject * | 
					
						
							| 
									
										
										
										
											2003-02-23 04:40:07 +00:00
										 |  |  | chain_new(PyTypeObject *type, PyObject *args, PyObject *kwds) | 
					
						
							| 
									
										
										
										
											2003-02-01 00:10:11 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2003-02-23 04:40:07 +00:00
										 |  |  | 	chainobject *lz; | 
					
						
							|  |  |  | 	int tuplesize = PySequence_Length(args); | 
					
						
							|  |  |  | 	int i; | 
					
						
							|  |  |  | 	PyObject *ittuple; | 
					
						
							| 
									
										
										
										
											2003-02-01 00:10:11 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-02-23 04:40:07 +00:00
										 |  |  | 	/* obtain iterators */ | 
					
						
							|  |  |  | 	assert(PyTuple_Check(args)); | 
					
						
							|  |  |  | 	ittuple = PyTuple_New(tuplesize); | 
					
						
							|  |  |  | 	if(ittuple == NULL) | 
					
						
							| 
									
										
										
										
											2003-02-01 00:10:11 +00:00
										 |  |  | 		return NULL; | 
					
						
							| 
									
										
										
										
											2003-02-23 04:40:07 +00:00
										 |  |  | 	for (i=0; i < tuplesize; ++i) { | 
					
						
							|  |  |  | 		PyObject *item = PyTuple_GET_ITEM(args, i); | 
					
						
							|  |  |  | 		PyObject *it = PyObject_GetIter(item); | 
					
						
							|  |  |  | 		if (it == NULL) { | 
					
						
							|  |  |  | 			if (PyErr_ExceptionMatches(PyExc_TypeError)) | 
					
						
							|  |  |  | 				PyErr_Format(PyExc_TypeError, | 
					
						
							|  |  |  | 				    "chain argument #%d must support iteration", | 
					
						
							|  |  |  | 				    i+1); | 
					
						
							|  |  |  | 			Py_DECREF(ittuple); | 
					
						
							|  |  |  | 			return NULL; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		PyTuple_SET_ITEM(ittuple, i, it); | 
					
						
							| 
									
										
										
										
											2003-02-01 00:10:11 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-02-23 04:40:07 +00:00
										 |  |  | 	/* create chainobject structure */ | 
					
						
							|  |  |  | 	lz = (chainobject *)type->tp_alloc(type, 0); | 
					
						
							| 
									
										
										
										
											2003-06-17 23:14:40 +00:00
										 |  |  | 	if (lz == NULL) { | 
					
						
							|  |  |  | 		Py_DECREF(ittuple); | 
					
						
							| 
									
										
										
										
											2003-02-01 00:10:11 +00:00
										 |  |  | 		return NULL; | 
					
						
							| 
									
										
										
										
											2003-06-17 23:14:40 +00:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2003-02-23 04:40:07 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	lz->ittuple = ittuple; | 
					
						
							|  |  |  | 	lz->iternum = 0; | 
					
						
							|  |  |  | 	lz->tuplesize = tuplesize; | 
					
						
							| 
									
										
										
										
											2003-02-01 00:10:11 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	return (PyObject *)lz; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void | 
					
						
							| 
									
										
										
										
											2003-02-23 04:40:07 +00:00
										 |  |  | chain_dealloc(chainobject *lz) | 
					
						
							| 
									
										
										
										
											2003-02-01 00:10:11 +00:00
										 |  |  | { | 
					
						
							|  |  |  | 	PyObject_GC_UnTrack(lz); | 
					
						
							| 
									
										
										
										
											2003-02-23 04:40:07 +00:00
										 |  |  | 	Py_XDECREF(lz->ittuple); | 
					
						
							| 
									
										
										
										
											2003-02-01 00:10:11 +00:00
										 |  |  | 	lz->ob_type->tp_free(lz); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-02-07 05:32:58 +00:00
										 |  |  | static int | 
					
						
							| 
									
										
										
										
											2003-02-23 04:40:07 +00:00
										 |  |  | chain_traverse(chainobject *lz, visitproc visit, void *arg) | 
					
						
							| 
									
										
										
										
											2003-02-07 05:32:58 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2003-02-23 04:40:07 +00:00
										 |  |  | 	if (lz->ittuple) | 
					
						
							|  |  |  | 		return visit(lz->ittuple, arg); | 
					
						
							| 
									
										
										
										
											2003-02-07 05:32:58 +00:00
										 |  |  | 	return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-02-01 00:10:11 +00:00
										 |  |  | static PyObject * | 
					
						
							| 
									
										
										
										
											2003-02-23 04:40:07 +00:00
										 |  |  | chain_next(chainobject *lz) | 
					
						
							| 
									
										
										
										
											2003-02-01 00:10:11 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2003-02-23 04:40:07 +00:00
										 |  |  | 	PyObject *it; | 
					
						
							|  |  |  | 	PyObject *item; | 
					
						
							| 
									
										
										
										
											2003-02-01 00:10:11 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-02-23 04:40:07 +00:00
										 |  |  | 	while (lz->iternum < lz->tuplesize) { | 
					
						
							|  |  |  | 		it = PyTuple_GET_ITEM(lz->ittuple, lz->iternum); | 
					
						
							|  |  |  | 		item = PyIter_Next(it); | 
					
						
							|  |  |  | 		if (item != NULL) | 
					
						
							|  |  |  | 			return item; | 
					
						
							|  |  |  | 		lz->iternum++; | 
					
						
							| 
									
										
										
										
											2003-02-01 00:10:11 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 	return NULL; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-02-23 04:40:07 +00:00
										 |  |  | PyDoc_STRVAR(chain_doc, | 
					
						
							|  |  |  | "chain(*iterables) --> chain object\n\
 | 
					
						
							| 
									
										
										
										
											2003-02-01 00:10:11 +00:00
										 |  |  | \n\ | 
					
						
							| 
									
										
										
										
											2003-02-23 04:40:07 +00:00
										 |  |  | Return a chain object whose .next() method returns elements from the\n\ | 
					
						
							|  |  |  | first iterable until it is exhausted, then elements from the next\n\ | 
					
						
							|  |  |  | iterable, until all of the iterables are exhausted."); | 
					
						
							| 
									
										
										
										
											2003-02-01 00:10:11 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-07-14 07:07:12 +00:00
										 |  |  | static PyTypeObject chain_type = { | 
					
						
							| 
									
										
										
										
											2003-02-01 00:10:11 +00:00
										 |  |  | 	PyObject_HEAD_INIT(NULL) | 
					
						
							|  |  |  | 	0,				/* ob_size */ | 
					
						
							| 
									
										
										
										
											2003-02-23 04:40:07 +00:00
										 |  |  | 	"itertools.chain",		/* tp_name */ | 
					
						
							|  |  |  | 	sizeof(chainobject),		/* tp_basicsize */ | 
					
						
							| 
									
										
										
										
											2003-02-01 00:10:11 +00:00
										 |  |  | 	0,				/* tp_itemsize */ | 
					
						
							|  |  |  | 	/* methods */ | 
					
						
							| 
									
										
										
										
											2003-02-23 04:40:07 +00:00
										 |  |  | 	(destructor)chain_dealloc,	/* tp_dealloc */ | 
					
						
							| 
									
										
										
										
											2003-02-01 00:10:11 +00:00
										 |  |  | 	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 */ | 
					
						
							| 
									
										
										
										
											2003-02-23 04:40:07 +00:00
										 |  |  | 	chain_doc,			/* tp_doc */ | 
					
						
							|  |  |  | 	(traverseproc)chain_traverse,	/* tp_traverse */ | 
					
						
							| 
									
										
										
										
											2003-02-01 00:10:11 +00:00
										 |  |  | 	0,				/* tp_clear */ | 
					
						
							|  |  |  | 	0,				/* tp_richcompare */ | 
					
						
							|  |  |  | 	0,				/* tp_weaklistoffset */ | 
					
						
							| 
									
										
										
										
											2003-03-17 19:46:11 +00:00
										 |  |  | 	PyObject_SelfIter,		/* tp_iter */ | 
					
						
							| 
									
										
										
										
											2003-02-23 04:40:07 +00:00
										 |  |  | 	(iternextfunc)chain_next,	/* tp_iternext */ | 
					
						
							| 
									
										
										
										
											2003-02-01 00:10:11 +00:00
										 |  |  | 	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 */ | 
					
						
							| 
									
										
										
										
											2003-05-23 03:55:42 +00:00
										 |  |  | 	0,				/* tp_alloc */ | 
					
						
							| 
									
										
										
										
											2003-02-23 04:40:07 +00:00
										 |  |  | 	chain_new,			/* tp_new */ | 
					
						
							| 
									
										
										
										
											2003-02-01 00:10:11 +00:00
										 |  |  | 	PyObject_GC_Del,		/* tp_free */ | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* ifilter object ************************************************************/ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | typedef struct { | 
					
						
							|  |  |  | 	PyObject_HEAD | 
					
						
							|  |  |  | 	PyObject *func; | 
					
						
							|  |  |  | 	PyObject *it; | 
					
						
							|  |  |  | } ifilterobject; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-07-14 07:07:12 +00:00
										 |  |  | static PyTypeObject ifilter_type; | 
					
						
							| 
									
										
										
										
											2003-02-01 00:10:11 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | static PyObject * | 
					
						
							|  |  |  | ifilter_new(PyTypeObject *type, PyObject *args, PyObject *kwds) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2003-02-09 06:40:58 +00:00
										 |  |  | 	PyObject *func, *seq; | 
					
						
							| 
									
										
										
										
											2003-02-01 00:10:11 +00:00
										 |  |  | 	PyObject *it; | 
					
						
							|  |  |  | 	ifilterobject *lz; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-02-09 06:40:58 +00:00
										 |  |  | 	if (!PyArg_UnpackTuple(args, "ifilter", 2, 2, &func, &seq)) | 
					
						
							| 
									
										
										
										
											2003-02-01 00:10:11 +00:00
										 |  |  | 		return NULL; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* Get iterator. */ | 
					
						
							|  |  |  | 	it = PyObject_GetIter(seq); | 
					
						
							|  |  |  | 	if (it == NULL) | 
					
						
							|  |  |  | 		return NULL; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* create ifilterobject structure */ | 
					
						
							|  |  |  | 	lz = (ifilterobject *)type->tp_alloc(type, 0); | 
					
						
							|  |  |  | 	if (lz == NULL) { | 
					
						
							|  |  |  | 		Py_DECREF(it); | 
					
						
							|  |  |  | 		return NULL; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	Py_INCREF(func); | 
					
						
							|  |  |  | 	lz->func = func; | 
					
						
							|  |  |  | 	lz->it = it; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return (PyObject *)lz; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void | 
					
						
							|  |  |  | ifilter_dealloc(ifilterobject *lz) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	PyObject_GC_UnTrack(lz); | 
					
						
							|  |  |  | 	Py_XDECREF(lz->func); | 
					
						
							|  |  |  | 	Py_XDECREF(lz->it); | 
					
						
							|  |  |  | 	lz->ob_type->tp_free(lz); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static int | 
					
						
							|  |  |  | ifilter_traverse(ifilterobject *lz, visitproc visit, void *arg) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	int err; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (lz->it) { | 
					
						
							|  |  |  | 		err = visit(lz->it, arg); | 
					
						
							|  |  |  | 		if (err) | 
					
						
							|  |  |  | 			return err; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	if (lz->func) { | 
					
						
							|  |  |  | 		err = visit(lz->func, arg); | 
					
						
							|  |  |  | 		if (err) | 
					
						
							|  |  |  | 			return err; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static PyObject * | 
					
						
							|  |  |  | ifilter_next(ifilterobject *lz) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	PyObject *item; | 
					
						
							| 
									
										
										
										
											2003-03-01 01:48:24 +00:00
										 |  |  | 	PyObject *it = lz->it; | 
					
						
							| 
									
										
										
										
											2003-02-01 00:10:11 +00:00
										 |  |  | 	long ok; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	for (;;) { | 
					
						
							| 
									
										
										
										
											2003-03-01 01:48:24 +00:00
										 |  |  | 		assert(PyIter_Check(it)); | 
					
						
							|  |  |  | 		item = (*it->ob_type->tp_iternext)(it); | 
					
						
							| 
									
										
										
										
											2003-02-01 00:10:11 +00:00
										 |  |  | 		if (item == NULL) | 
					
						
							|  |  |  | 			return NULL; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if (lz->func == Py_None) { | 
					
						
							|  |  |  | 			ok = PyObject_IsTrue(item); | 
					
						
							|  |  |  | 		} else { | 
					
						
							|  |  |  | 			PyObject *good; | 
					
						
							|  |  |  | 			good = PyObject_CallFunctionObjArgs(lz->func, | 
					
						
							|  |  |  | 							    item, NULL); | 
					
						
							|  |  |  | 			if (good == NULL) { | 
					
						
							|  |  |  | 				Py_DECREF(item); | 
					
						
							|  |  |  | 				return NULL; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			ok = PyObject_IsTrue(good); | 
					
						
							|  |  |  | 			Py_DECREF(good); | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2003-02-09 06:40:58 +00:00
										 |  |  | 		if (ok) | 
					
						
							| 
									
										
										
										
											2003-02-01 00:10:11 +00:00
										 |  |  | 			return item; | 
					
						
							|  |  |  | 		Py_DECREF(item); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | PyDoc_STRVAR(ifilter_doc, | 
					
						
							| 
									
										
										
										
											2003-02-09 06:40:58 +00:00
										 |  |  | "ifilter(function or None, sequence) --> ifilter object\n\
 | 
					
						
							| 
									
										
										
										
											2003-02-01 00:10:11 +00:00
										 |  |  | \n\ | 
					
						
							| 
									
										
										
										
											2003-02-09 06:40:58 +00:00
										 |  |  | Return those items of sequence for which function(item) is true.\n\ | 
					
						
							|  |  |  | If function is None, return the items that are true."); | 
					
						
							| 
									
										
										
										
											2003-02-01 00:10:11 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-07-14 07:07:12 +00:00
										 |  |  | static PyTypeObject ifilter_type = { | 
					
						
							| 
									
										
										
										
											2003-02-01 00:10:11 +00:00
										 |  |  | 	PyObject_HEAD_INIT(NULL) | 
					
						
							|  |  |  | 	0,				/* ob_size */ | 
					
						
							| 
									
										
										
										
											2003-02-09 06:40:58 +00:00
										 |  |  | 	"itertools.ifilter",		/* tp_name */ | 
					
						
							|  |  |  | 	sizeof(ifilterobject),		/* tp_basicsize */ | 
					
						
							|  |  |  | 	0,				/* tp_itemsize */ | 
					
						
							|  |  |  | 	/* methods */ | 
					
						
							|  |  |  | 	(destructor)ifilter_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 */ | 
					
						
							|  |  |  | 	ifilter_doc,			/* tp_doc */ | 
					
						
							|  |  |  | 	(traverseproc)ifilter_traverse,	/* tp_traverse */ | 
					
						
							|  |  |  | 	0,				/* tp_clear */ | 
					
						
							|  |  |  | 	0,				/* tp_richcompare */ | 
					
						
							|  |  |  | 	0,				/* tp_weaklistoffset */ | 
					
						
							| 
									
										
										
										
											2003-03-17 19:46:11 +00:00
										 |  |  | 	PyObject_SelfIter,		/* tp_iter */ | 
					
						
							| 
									
										
										
										
											2003-02-09 06:40:58 +00:00
										 |  |  | 	(iternextfunc)ifilter_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 */ | 
					
						
							| 
									
										
										
										
											2003-05-23 03:55:42 +00:00
										 |  |  | 	0,				/* tp_alloc */ | 
					
						
							| 
									
										
										
										
											2003-02-09 06:40:58 +00:00
										 |  |  | 	ifilter_new,			/* tp_new */ | 
					
						
							|  |  |  | 	PyObject_GC_Del,		/* tp_free */ | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* ifilterfalse object ************************************************************/ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | typedef struct { | 
					
						
							|  |  |  | 	PyObject_HEAD | 
					
						
							|  |  |  | 	PyObject *func; | 
					
						
							|  |  |  | 	PyObject *it; | 
					
						
							|  |  |  | } ifilterfalseobject; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-07-14 07:07:12 +00:00
										 |  |  | static PyTypeObject ifilterfalse_type; | 
					
						
							| 
									
										
										
										
											2003-02-09 06:40:58 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | static PyObject * | 
					
						
							|  |  |  | ifilterfalse_new(PyTypeObject *type, PyObject *args, PyObject *kwds) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2003-02-09 17:19:18 +00:00
										 |  |  | 	PyObject *func, *seq; | 
					
						
							| 
									
										
										
										
											2003-02-09 06:40:58 +00:00
										 |  |  | 	PyObject *it; | 
					
						
							|  |  |  | 	ifilterfalseobject *lz; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (!PyArg_UnpackTuple(args, "ifilterfalse", 2, 2, &func, &seq)) | 
					
						
							|  |  |  | 		return NULL; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* Get iterator. */ | 
					
						
							|  |  |  | 	it = PyObject_GetIter(seq); | 
					
						
							|  |  |  | 	if (it == NULL) | 
					
						
							|  |  |  | 		return NULL; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* create ifilterfalseobject structure */ | 
					
						
							|  |  |  | 	lz = (ifilterfalseobject *)type->tp_alloc(type, 0); | 
					
						
							|  |  |  | 	if (lz == NULL) { | 
					
						
							|  |  |  | 		Py_DECREF(it); | 
					
						
							|  |  |  | 		return NULL; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	Py_INCREF(func); | 
					
						
							|  |  |  | 	lz->func = func; | 
					
						
							|  |  |  | 	lz->it = it; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return (PyObject *)lz; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void | 
					
						
							|  |  |  | ifilterfalse_dealloc(ifilterfalseobject *lz) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	PyObject_GC_UnTrack(lz); | 
					
						
							|  |  |  | 	Py_XDECREF(lz->func); | 
					
						
							|  |  |  | 	Py_XDECREF(lz->it); | 
					
						
							|  |  |  | 	lz->ob_type->tp_free(lz); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static int | 
					
						
							|  |  |  | ifilterfalse_traverse(ifilterfalseobject *lz, visitproc visit, void *arg) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	int err; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (lz->it) { | 
					
						
							|  |  |  | 		err = visit(lz->it, arg); | 
					
						
							|  |  |  | 		if (err) | 
					
						
							|  |  |  | 			return err; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	if (lz->func) { | 
					
						
							|  |  |  | 		err = visit(lz->func, arg); | 
					
						
							|  |  |  | 		if (err) | 
					
						
							|  |  |  | 			return err; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static PyObject * | 
					
						
							|  |  |  | ifilterfalse_next(ifilterfalseobject *lz) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	PyObject *item; | 
					
						
							| 
									
										
										
										
											2003-03-01 01:48:24 +00:00
										 |  |  | 	PyObject *it = lz->it; | 
					
						
							| 
									
										
										
										
											2003-02-09 06:40:58 +00:00
										 |  |  | 	long ok; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	for (;;) { | 
					
						
							| 
									
										
										
										
											2003-03-01 01:48:24 +00:00
										 |  |  | 		assert(PyIter_Check(it)); | 
					
						
							|  |  |  | 		item = (*it->ob_type->tp_iternext)(it); | 
					
						
							| 
									
										
										
										
											2003-02-09 06:40:58 +00:00
										 |  |  | 		if (item == NULL) | 
					
						
							|  |  |  | 			return NULL; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if (lz->func == Py_None) { | 
					
						
							|  |  |  | 			ok = PyObject_IsTrue(item); | 
					
						
							|  |  |  | 		} else { | 
					
						
							|  |  |  | 			PyObject *good; | 
					
						
							|  |  |  | 			good = PyObject_CallFunctionObjArgs(lz->func, | 
					
						
							|  |  |  | 							    item, NULL); | 
					
						
							|  |  |  | 			if (good == NULL) { | 
					
						
							|  |  |  | 				Py_DECREF(item); | 
					
						
							|  |  |  | 				return NULL; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			ok = PyObject_IsTrue(good); | 
					
						
							|  |  |  | 			Py_DECREF(good); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		if (!ok) | 
					
						
							|  |  |  | 			return item; | 
					
						
							|  |  |  | 		Py_DECREF(item); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | PyDoc_STRVAR(ifilterfalse_doc, | 
					
						
							|  |  |  | "ifilterfalse(function or None, sequence) --> ifilterfalse object\n\
 | 
					
						
							|  |  |  | \n\ | 
					
						
							|  |  |  | Return those items of sequence for which function(item) is false.\n\ | 
					
						
							|  |  |  | If function is None, return the items that are false."); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-07-14 07:07:12 +00:00
										 |  |  | static PyTypeObject ifilterfalse_type = { | 
					
						
							| 
									
										
										
										
											2003-02-09 06:40:58 +00:00
										 |  |  | 	PyObject_HEAD_INIT(NULL) | 
					
						
							|  |  |  | 	0,				/* ob_size */ | 
					
						
							|  |  |  | 	"itertools.ifilterfalse",	/* tp_name */ | 
					
						
							|  |  |  | 	sizeof(ifilterfalseobject),	/* tp_basicsize */ | 
					
						
							| 
									
										
										
										
											2003-02-01 00:10:11 +00:00
										 |  |  | 	0,				/* tp_itemsize */ | 
					
						
							|  |  |  | 	/* methods */ | 
					
						
							| 
									
										
										
										
											2003-02-09 06:40:58 +00:00
										 |  |  | 	(destructor)ifilterfalse_dealloc,	/* tp_dealloc */ | 
					
						
							| 
									
										
										
										
											2003-02-01 00:10:11 +00:00
										 |  |  | 	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 */ | 
					
						
							| 
									
										
										
										
											2003-02-09 06:40:58 +00:00
										 |  |  | 	ifilterfalse_doc,		/* tp_doc */ | 
					
						
							|  |  |  | 	(traverseproc)ifilterfalse_traverse,	/* tp_traverse */ | 
					
						
							| 
									
										
										
										
											2003-02-01 00:10:11 +00:00
										 |  |  | 	0,				/* tp_clear */ | 
					
						
							|  |  |  | 	0,				/* tp_richcompare */ | 
					
						
							|  |  |  | 	0,				/* tp_weaklistoffset */ | 
					
						
							| 
									
										
										
										
											2003-03-17 19:46:11 +00:00
										 |  |  | 	PyObject_SelfIter,		/* tp_iter */ | 
					
						
							| 
									
										
										
										
											2003-02-09 06:40:58 +00:00
										 |  |  | 	(iternextfunc)ifilterfalse_next,	/* tp_iternext */ | 
					
						
							| 
									
										
										
										
											2003-02-01 00:10:11 +00:00
										 |  |  | 	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 */ | 
					
						
							| 
									
										
										
										
											2003-05-23 03:55:42 +00:00
										 |  |  | 	0,				/* tp_alloc */ | 
					
						
							| 
									
										
										
										
											2003-02-09 06:40:58 +00:00
										 |  |  | 	ifilterfalse_new,		/* tp_new */ | 
					
						
							| 
									
										
										
										
											2003-02-01 00:10:11 +00:00
										 |  |  | 	PyObject_GC_Del,		/* tp_free */ | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* count object ************************************************************/ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | typedef struct { | 
					
						
							|  |  |  | 	PyObject_HEAD | 
					
						
							|  |  |  | 	long	cnt; | 
					
						
							|  |  |  | } countobject; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-07-14 07:07:12 +00:00
										 |  |  | static PyTypeObject count_type; | 
					
						
							| 
									
										
										
										
											2003-02-01 00:10:11 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | static PyObject * | 
					
						
							|  |  |  | count_new(PyTypeObject *type, PyObject *args, PyObject *kwds) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	countobject *lz; | 
					
						
							|  |  |  | 	long cnt = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (!PyArg_ParseTuple(args, "|l:count", &cnt)) | 
					
						
							|  |  |  | 		return NULL; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* create countobject structure */ | 
					
						
							|  |  |  | 	lz = (countobject *)PyObject_New(countobject, &count_type); | 
					
						
							|  |  |  | 	if (lz == NULL) | 
					
						
							|  |  |  | 		return NULL; | 
					
						
							|  |  |  | 	lz->cnt = cnt; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return (PyObject *)lz; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static PyObject * | 
					
						
							|  |  |  | count_next(countobject *lz) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	return PyInt_FromLong(lz->cnt++); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | PyDoc_STRVAR(count_doc, | 
					
						
							|  |  |  | "count([firstval]) --> count object\n\
 | 
					
						
							|  |  |  | \n\ | 
					
						
							|  |  |  | Return a count object whose .next() method returns consecutive\n\ | 
					
						
							|  |  |  | integers starting from zero or, if specified, from firstval."); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-07-14 07:07:12 +00:00
										 |  |  | static PyTypeObject count_type = { | 
					
						
							| 
									
										
										
										
											2003-02-01 00:10:11 +00:00
										 |  |  | 	PyObject_HEAD_INIT(NULL) | 
					
						
							|  |  |  | 	0,				/* ob_size */ | 
					
						
							| 
									
										
										
										
											2003-02-09 06:40:58 +00:00
										 |  |  | 	"itertools.count",		/* tp_name */ | 
					
						
							|  |  |  | 	sizeof(countobject),		/* tp_basicsize */ | 
					
						
							| 
									
										
										
										
											2003-02-01 00:10:11 +00:00
										 |  |  | 	0,				/* tp_itemsize */ | 
					
						
							|  |  |  | 	/* methods */ | 
					
						
							|  |  |  | 	(destructor)PyObject_Del,	/* 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,		/* tp_flags */ | 
					
						
							| 
									
										
										
										
											2003-02-09 06:40:58 +00:00
										 |  |  | 	count_doc,			/* tp_doc */ | 
					
						
							| 
									
										
										
										
											2003-02-01 00:10:11 +00:00
										 |  |  | 	0,				/* tp_traverse */ | 
					
						
							|  |  |  | 	0,				/* tp_clear */ | 
					
						
							|  |  |  | 	0,				/* tp_richcompare */ | 
					
						
							|  |  |  | 	0,				/* tp_weaklistoffset */ | 
					
						
							| 
									
										
										
										
											2003-03-17 19:46:11 +00:00
										 |  |  | 	PyObject_SelfIter,		/* tp_iter */ | 
					
						
							| 
									
										
										
										
											2003-02-09 06:40:58 +00:00
										 |  |  | 	(iternextfunc)count_next,	/* tp_iternext */ | 
					
						
							| 
									
										
										
										
											2003-02-01 00:10:11 +00:00
										 |  |  | 	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 */ | 
					
						
							| 
									
										
										
										
											2003-05-23 03:55:42 +00:00
										 |  |  | 	0,				/* tp_alloc */ | 
					
						
							| 
									
										
										
										
											2003-02-01 00:10:11 +00:00
										 |  |  | 	count_new,			/* tp_new */ | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* izip object ************************************************************/ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include "Python.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | typedef struct { | 
					
						
							|  |  |  | 	PyObject_HEAD | 
					
						
							|  |  |  | 	long	tuplesize; | 
					
						
							|  |  |  | 	PyObject *ittuple;		/* tuple of iterators */ | 
					
						
							| 
									
										
										
										
											2003-02-07 05:32:58 +00:00
										 |  |  | 	PyObject *result; | 
					
						
							| 
									
										
										
										
											2003-02-01 00:10:11 +00:00
										 |  |  | } izipobject; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-07-14 07:07:12 +00:00
										 |  |  | static PyTypeObject izip_type; | 
					
						
							| 
									
										
										
										
											2003-02-01 00:10:11 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | static PyObject * | 
					
						
							|  |  |  | izip_new(PyTypeObject *type, PyObject *args, PyObject *kwds) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	izipobject *lz; | 
					
						
							|  |  |  | 	int i; | 
					
						
							|  |  |  | 	PyObject *ittuple;  /* tuple of iterators */ | 
					
						
							| 
									
										
										
										
											2003-02-07 05:32:58 +00:00
										 |  |  | 	PyObject *result; | 
					
						
							| 
									
										
										
										
											2003-02-01 00:10:11 +00:00
										 |  |  | 	int tuplesize = PySequence_Length(args); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (tuplesize < 1) { | 
					
						
							|  |  |  | 		PyErr_SetString(PyExc_TypeError, | 
					
						
							|  |  |  | 				"izip() requires at least one sequence"); | 
					
						
							|  |  |  | 		return NULL; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* args must be a tuple */ | 
					
						
							|  |  |  | 	assert(PyTuple_Check(args)); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* obtain iterators */ | 
					
						
							|  |  |  | 	ittuple = PyTuple_New(tuplesize); | 
					
						
							|  |  |  | 	if(ittuple == NULL) | 
					
						
							|  |  |  | 		return NULL; | 
					
						
							|  |  |  | 	for (i=0; i < tuplesize; ++i) { | 
					
						
							|  |  |  | 		PyObject *item = PyTuple_GET_ITEM(args, i); | 
					
						
							|  |  |  | 		PyObject *it = PyObject_GetIter(item); | 
					
						
							|  |  |  | 		if (it == NULL) { | 
					
						
							|  |  |  | 			if (PyErr_ExceptionMatches(PyExc_TypeError)) | 
					
						
							|  |  |  | 				PyErr_Format(PyExc_TypeError, | 
					
						
							|  |  |  | 				    "izip argument #%d must support iteration", | 
					
						
							|  |  |  | 				    i+1); | 
					
						
							|  |  |  | 			Py_DECREF(ittuple); | 
					
						
							|  |  |  | 			return NULL; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		PyTuple_SET_ITEM(ittuple, i, it); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-02-07 05:32:58 +00:00
										 |  |  | 	/* create a result holder */ | 
					
						
							|  |  |  | 	result = PyTuple_New(tuplesize); | 
					
						
							|  |  |  | 	if (result == NULL) { | 
					
						
							|  |  |  | 		Py_DECREF(ittuple); | 
					
						
							|  |  |  | 		return NULL; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	for (i=0 ; i < tuplesize ; i++) { | 
					
						
							|  |  |  | 		Py_INCREF(Py_None); | 
					
						
							|  |  |  | 		PyTuple_SET_ITEM(result, i, Py_None); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-02-01 00:10:11 +00:00
										 |  |  | 	/* create izipobject structure */ | 
					
						
							|  |  |  | 	lz = (izipobject *)type->tp_alloc(type, 0); | 
					
						
							|  |  |  | 	if (lz == NULL) { | 
					
						
							|  |  |  | 		Py_DECREF(ittuple); | 
					
						
							| 
									
										
										
										
											2003-02-07 05:32:58 +00:00
										 |  |  | 		Py_DECREF(result); | 
					
						
							| 
									
										
										
										
											2003-02-01 00:10:11 +00:00
										 |  |  | 		return NULL; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	lz->ittuple = ittuple; | 
					
						
							|  |  |  | 	lz->tuplesize = tuplesize; | 
					
						
							| 
									
										
										
										
											2003-02-07 05:32:58 +00:00
										 |  |  | 	lz->result = result; | 
					
						
							| 
									
										
										
										
											2003-02-01 00:10:11 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	return (PyObject *)lz; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void | 
					
						
							|  |  |  | izip_dealloc(izipobject *lz) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	PyObject_GC_UnTrack(lz); | 
					
						
							|  |  |  | 	Py_XDECREF(lz->ittuple); | 
					
						
							| 
									
										
										
										
											2003-02-07 05:32:58 +00:00
										 |  |  | 	Py_XDECREF(lz->result); | 
					
						
							| 
									
										
										
										
											2003-02-01 00:10:11 +00:00
										 |  |  | 	lz->ob_type->tp_free(lz); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static int | 
					
						
							|  |  |  | izip_traverse(izipobject *lz, visitproc visit, void *arg) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2003-06-18 19:25:37 +00:00
										 |  |  | 	int err; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (lz->ittuple) { | 
					
						
							|  |  |  | 		err = visit(lz->ittuple, arg); | 
					
						
							|  |  |  | 		if (err) | 
					
						
							|  |  |  | 			return err; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	if (lz->result) { | 
					
						
							|  |  |  | 		err = visit(lz->result, arg); | 
					
						
							|  |  |  | 		if (err) | 
					
						
							|  |  |  | 			return err; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2003-02-01 00:10:11 +00:00
										 |  |  | 	return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static PyObject * | 
					
						
							|  |  |  | izip_next(izipobject *lz) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	int i; | 
					
						
							|  |  |  | 	long tuplesize = lz->tuplesize; | 
					
						
							| 
									
										
										
										
											2003-02-07 05:32:58 +00:00
										 |  |  | 	PyObject *result = lz->result; | 
					
						
							| 
									
										
										
										
											2003-02-01 00:10:11 +00:00
										 |  |  | 	PyObject *it; | 
					
						
							|  |  |  | 	PyObject *item; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-02-07 05:32:58 +00:00
										 |  |  | 	if (result->ob_refcnt == 1) { | 
					
						
							|  |  |  | 		for (i=0 ; i < tuplesize ; i++) { | 
					
						
							| 
									
										
										
										
											2003-02-07 07:26:25 +00:00
										 |  |  | 			it = PyTuple_GET_ITEM(lz->ittuple, i); | 
					
						
							| 
									
										
										
										
											2003-03-01 01:48:24 +00:00
										 |  |  | 			assert(PyIter_Check(it)); | 
					
						
							|  |  |  | 			item = (*it->ob_type->tp_iternext)(it); | 
					
						
							| 
									
										
										
										
											2003-02-07 07:26:25 +00:00
										 |  |  | 			if (item == NULL) | 
					
						
							|  |  |  | 				return NULL; | 
					
						
							| 
									
										
										
										
											2003-02-07 05:32:58 +00:00
										 |  |  | 			Py_DECREF(PyTuple_GET_ITEM(result, i)); | 
					
						
							| 
									
										
										
										
											2003-02-07 07:26:25 +00:00
										 |  |  | 			PyTuple_SET_ITEM(result, i, item); | 
					
						
							| 
									
										
										
										
											2003-02-07 05:32:58 +00:00
										 |  |  | 		} | 
					
						
							|  |  |  | 		Py_INCREF(result); | 
					
						
							|  |  |  | 	} else { | 
					
						
							|  |  |  | 		result = PyTuple_New(tuplesize); | 
					
						
							|  |  |  | 		if (result == NULL) | 
					
						
							|  |  |  | 			return NULL; | 
					
						
							| 
									
										
										
										
											2003-02-07 07:26:25 +00:00
										 |  |  | 		for (i=0 ; i < tuplesize ; i++) { | 
					
						
							|  |  |  | 			it = PyTuple_GET_ITEM(lz->ittuple, i); | 
					
						
							| 
									
										
										
										
											2003-03-01 01:48:24 +00:00
										 |  |  | 			assert(PyIter_Check(it)); | 
					
						
							|  |  |  | 			item = (*it->ob_type->tp_iternext)(it); | 
					
						
							| 
									
										
										
										
											2003-02-07 07:26:25 +00:00
										 |  |  | 			if (item == NULL) { | 
					
						
							|  |  |  | 				Py_DECREF(result); | 
					
						
							|  |  |  | 				return NULL; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			PyTuple_SET_ITEM(result, i, item); | 
					
						
							| 
									
										
										
										
											2003-02-01 00:10:11 +00:00
										 |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return result; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | PyDoc_STRVAR(izip_doc, | 
					
						
							|  |  |  | "izip(iter1 [,iter2 [...]]) --> izip object\n\
 | 
					
						
							|  |  |  | \n\ | 
					
						
							|  |  |  | Return a izip object whose .next() method returns a tuple where\n\ | 
					
						
							|  |  |  | the i-th element comes from the i-th iterable argument.  The .next()\n\ | 
					
						
							|  |  |  | method continues until the shortest iterable in the argument sequence\n\ | 
					
						
							|  |  |  | is exhausted and then it raises StopIteration.  Works like the zip()\n\ | 
					
						
							|  |  |  | function but consumes less memory by returning an iterator instead of\n\ | 
					
						
							|  |  |  | a list."); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-07-14 07:07:12 +00:00
										 |  |  | static PyTypeObject izip_type = { | 
					
						
							| 
									
										
										
										
											2003-02-01 00:10:11 +00:00
										 |  |  | 	PyObject_HEAD_INIT(NULL) | 
					
						
							|  |  |  | 	0,				/* ob_size */ | 
					
						
							| 
									
										
										
										
											2003-02-09 06:40:58 +00:00
										 |  |  | 	"itertools.izip",		/* tp_name */ | 
					
						
							|  |  |  | 	sizeof(izipobject),		/* tp_basicsize */ | 
					
						
							| 
									
										
										
										
											2003-02-01 00:10:11 +00:00
										 |  |  | 	0,				/* tp_itemsize */ | 
					
						
							|  |  |  | 	/* methods */ | 
					
						
							| 
									
										
										
										
											2003-02-09 06:40:58 +00:00
										 |  |  | 	(destructor)izip_dealloc,	/* tp_dealloc */ | 
					
						
							| 
									
										
										
										
											2003-02-01 00:10:11 +00:00
										 |  |  | 	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 */ | 
					
						
							| 
									
										
										
										
											2003-02-09 06:40:58 +00:00
										 |  |  | 	izip_doc,			/* tp_doc */ | 
					
						
							| 
									
										
										
										
											2003-02-01 00:10:11 +00:00
										 |  |  | 	(traverseproc)izip_traverse,    /* tp_traverse */ | 
					
						
							|  |  |  | 	0,				/* tp_clear */ | 
					
						
							|  |  |  | 	0,				/* tp_richcompare */ | 
					
						
							|  |  |  | 	0,				/* tp_weaklistoffset */ | 
					
						
							| 
									
										
										
										
											2003-03-17 19:46:11 +00:00
										 |  |  | 	PyObject_SelfIter,		/* tp_iter */ | 
					
						
							| 
									
										
										
										
											2003-02-09 06:40:58 +00:00
										 |  |  | 	(iternextfunc)izip_next,	/* tp_iternext */ | 
					
						
							| 
									
										
										
										
											2003-02-01 00:10:11 +00:00
										 |  |  | 	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 */ | 
					
						
							| 
									
										
										
										
											2003-05-23 03:55:42 +00:00
										 |  |  | 	0,				/* tp_alloc */ | 
					
						
							| 
									
										
										
										
											2003-02-09 06:40:58 +00:00
										 |  |  | 	izip_new,			/* tp_new */ | 
					
						
							| 
									
										
										
										
											2003-02-01 00:10:11 +00:00
										 |  |  | 	PyObject_GC_Del,		/* tp_free */ | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* repeat object ************************************************************/ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | typedef struct { | 
					
						
							|  |  |  | 	PyObject_HEAD | 
					
						
							|  |  |  | 	PyObject *element; | 
					
						
							| 
									
										
										
										
											2003-02-23 04:40:07 +00:00
										 |  |  | 	long cnt; | 
					
						
							| 
									
										
										
										
											2003-02-01 00:10:11 +00:00
										 |  |  | } repeatobject; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-07-14 07:07:12 +00:00
										 |  |  | static PyTypeObject repeat_type; | 
					
						
							| 
									
										
										
										
											2003-02-01 00:10:11 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | static PyObject * | 
					
						
							|  |  |  | repeat_new(PyTypeObject *type, PyObject *args, PyObject *kwds) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	repeatobject *ro; | 
					
						
							|  |  |  | 	PyObject *element; | 
					
						
							| 
									
										
										
										
											2003-02-23 04:40:07 +00:00
										 |  |  | 	long cnt = -1; | 
					
						
							| 
									
										
										
										
											2003-02-01 00:10:11 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-02-23 04:40:07 +00:00
										 |  |  | 	if (!PyArg_ParseTuple(args, "O|l:repeat", &element, &cnt)) | 
					
						
							| 
									
										
										
										
											2003-02-01 00:10:11 +00:00
										 |  |  | 		return NULL; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-05-03 05:59:48 +00:00
										 |  |  | 	if (PyTuple_Size(args) == 2 && cnt < 0) | 
					
						
							|  |  |  | 		cnt = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-02-01 00:10:11 +00:00
										 |  |  | 	ro = (repeatobject *)type->tp_alloc(type, 0); | 
					
						
							|  |  |  | 	if (ro == NULL) | 
					
						
							|  |  |  | 		return NULL; | 
					
						
							|  |  |  | 	Py_INCREF(element); | 
					
						
							|  |  |  | 	ro->element = element; | 
					
						
							| 
									
										
										
										
											2003-02-23 04:40:07 +00:00
										 |  |  | 	ro->cnt = cnt; | 
					
						
							| 
									
										
										
										
											2003-02-01 00:10:11 +00:00
										 |  |  | 	return (PyObject *)ro; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void | 
					
						
							|  |  |  | repeat_dealloc(repeatobject *ro) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	PyObject_GC_UnTrack(ro); | 
					
						
							|  |  |  | 	Py_XDECREF(ro->element); | 
					
						
							|  |  |  | 	ro->ob_type->tp_free(ro); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static int | 
					
						
							|  |  |  | repeat_traverse(repeatobject *ro, visitproc visit, void *arg) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	if (ro->element) | 
					
						
							|  |  |  | 		return visit(ro->element, arg); | 
					
						
							|  |  |  | 	return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static PyObject * | 
					
						
							|  |  |  | repeat_next(repeatobject *ro) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2003-02-23 04:40:07 +00:00
										 |  |  | 	if (ro->cnt == 0) | 
					
						
							|  |  |  | 		return NULL; | 
					
						
							|  |  |  | 	if (ro->cnt > 0) | 
					
						
							|  |  |  | 		ro->cnt--; | 
					
						
							| 
									
										
										
										
											2003-02-01 00:10:11 +00:00
										 |  |  | 	Py_INCREF(ro->element); | 
					
						
							|  |  |  | 	return ro->element; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | PyDoc_STRVAR(repeat_doc, | 
					
						
							| 
									
										
										
										
											2003-02-23 04:40:07 +00:00
										 |  |  | "repeat(element [,times]) -> create an iterator which returns the element\n\
 | 
					
						
							|  |  |  | for the specified number of times.  If not specified, returns the element\n\ | 
					
						
							|  |  |  | endlessly."); | 
					
						
							| 
									
										
										
										
											2003-02-01 00:10:11 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-07-14 07:07:12 +00:00
										 |  |  | static PyTypeObject repeat_type = { | 
					
						
							| 
									
										
										
										
											2003-02-01 00:10:11 +00:00
										 |  |  | 	PyObject_HEAD_INIT(NULL) | 
					
						
							|  |  |  | 	0,				/* ob_size */ | 
					
						
							|  |  |  | 	"itertools.repeat",		/* tp_name */ | 
					
						
							|  |  |  | 	sizeof(repeatobject),		/* tp_basicsize */ | 
					
						
							|  |  |  | 	0,				/* tp_itemsize */ | 
					
						
							|  |  |  | 	/* methods */ | 
					
						
							| 
									
										
										
										
											2003-02-09 06:40:58 +00:00
										 |  |  | 	(destructor)repeat_dealloc,	/* tp_dealloc */ | 
					
						
							| 
									
										
										
										
											2003-02-01 00:10:11 +00:00
										 |  |  | 	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 */ | 
					
						
							| 
									
										
										
										
											2003-02-09 06:40:58 +00:00
										 |  |  | 	repeat_doc,			/* tp_doc */ | 
					
						
							|  |  |  | 	(traverseproc)repeat_traverse,	/* tp_traverse */ | 
					
						
							| 
									
										
										
										
											2003-02-01 00:10:11 +00:00
										 |  |  | 	0,				/* tp_clear */ | 
					
						
							|  |  |  | 	0,				/* tp_richcompare */ | 
					
						
							|  |  |  | 	0,				/* tp_weaklistoffset */ | 
					
						
							| 
									
										
										
										
											2003-03-17 19:46:11 +00:00
										 |  |  | 	PyObject_SelfIter,		/* tp_iter */ | 
					
						
							| 
									
										
										
										
											2003-02-09 06:40:58 +00:00
										 |  |  | 	(iternextfunc)repeat_next,	/* tp_iternext */ | 
					
						
							| 
									
										
										
										
											2003-02-01 00:10:11 +00:00
										 |  |  | 	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 */ | 
					
						
							| 
									
										
										
										
											2003-05-23 03:55:42 +00:00
										 |  |  | 	0,				/* tp_alloc */ | 
					
						
							| 
									
										
										
										
											2003-02-01 00:10:11 +00:00
										 |  |  | 	repeat_new,			/* tp_new */ | 
					
						
							|  |  |  | 	PyObject_GC_Del,		/* tp_free */ | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* module level code ********************************************************/ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | PyDoc_STRVAR(module_doc, | 
					
						
							|  |  |  | "Functional tools for creating and using iterators.\n\
 | 
					
						
							|  |  |  | \n\ | 
					
						
							|  |  |  | Infinite iterators:\n\ | 
					
						
							|  |  |  | count([n]) --> n, n+1, n+2, ...\n\ | 
					
						
							| 
									
										
										
										
											2003-02-23 04:40:07 +00:00
										 |  |  | cycle(p) --> p0, p1, ... plast, p0, p1, ...\n\ | 
					
						
							| 
									
										
										
										
											2003-04-14 15:31:27 +00:00
										 |  |  | repeat(elem [,n]) --> elem, elem, elem, ... endlessly or up to n times\n\ | 
					
						
							| 
									
										
										
										
											2003-02-01 00:10:11 +00:00
										 |  |  | \n\ | 
					
						
							|  |  |  | Iterators terminating on the shortest input sequence:\n\ | 
					
						
							|  |  |  | izip(p, q, ...) --> (p[0], q[0]), (p[1], q[1]), ... \n\ | 
					
						
							| 
									
										
										
										
											2003-02-09 06:40:58 +00:00
										 |  |  | ifilter(pred, seq) --> elements of seq where pred(elem) is True\n\ | 
					
						
							|  |  |  | ifilterfalse(pred, seq) --> elements of seq where pred(elem) is False\n\ | 
					
						
							| 
									
										
										
										
											2003-02-01 00:10:11 +00:00
										 |  |  | islice(seq, [start,] stop [, step]) --> elements from\n\ | 
					
						
							|  |  |  |        seq[start:stop:step]\n\ | 
					
						
							|  |  |  | imap(fun, p, q, ...) --> fun(p0, q0), fun(p1, q1), ...\n\ | 
					
						
							|  |  |  | starmap(fun, seq) --> fun(*seq[0]), fun(*seq[1]), ...\n\ | 
					
						
							| 
									
										
										
										
											2003-02-23 04:40:07 +00:00
										 |  |  | chain(p, q, ...) --> p0, p1, ... plast, q0, q1, ... \n\ | 
					
						
							| 
									
										
										
										
											2003-02-01 00:10:11 +00:00
										 |  |  | takewhile(pred, seq) --> seq[0], seq[1], until pred fails\n\ | 
					
						
							|  |  |  | dropwhile(pred, seq) --> seq[n], seq[n+1], starting when pred fails\n\ | 
					
						
							|  |  |  | "); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | PyMODINIT_FUNC | 
					
						
							|  |  |  | inititertools(void) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2003-02-09 06:40:58 +00:00
										 |  |  | 	int i; | 
					
						
							| 
									
										
										
										
											2003-02-01 00:10:11 +00:00
										 |  |  | 	PyObject *m; | 
					
						
							| 
									
										
										
										
											2003-02-09 06:40:58 +00:00
										 |  |  | 	char *name; | 
					
						
							|  |  |  | 	PyTypeObject *typelist[] = { | 
					
						
							| 
									
										
										
										
											2003-02-23 04:40:07 +00:00
										 |  |  | 		&cycle_type, | 
					
						
							| 
									
										
										
										
											2003-02-09 06:40:58 +00:00
										 |  |  | 		&dropwhile_type, | 
					
						
							|  |  |  | 		&takewhile_type, | 
					
						
							|  |  |  | 		&islice_type, | 
					
						
							|  |  |  | 		&starmap_type, | 
					
						
							|  |  |  | 		&imap_type, | 
					
						
							| 
									
										
										
										
											2003-02-23 04:40:07 +00:00
										 |  |  | 		&chain_type, | 
					
						
							| 
									
										
										
										
											2003-02-09 06:40:58 +00:00
										 |  |  | 		&ifilter_type, | 
					
						
							|  |  |  | 		&ifilterfalse_type, | 
					
						
							|  |  |  | 		&count_type, | 
					
						
							|  |  |  | 		&izip_type, | 
					
						
							|  |  |  | 		&repeat_type, | 
					
						
							|  |  |  | 		NULL | 
					
						
							|  |  |  | 	}; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-02-01 00:10:11 +00:00
										 |  |  | 	m = Py_InitModule3("itertools", NULL, module_doc); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-02-09 06:40:58 +00:00
										 |  |  | 	for (i=0 ; typelist[i] != NULL ; i++) { | 
					
						
							|  |  |  | 		if (PyType_Ready(typelist[i]) < 0) | 
					
						
							|  |  |  | 			return; | 
					
						
							| 
									
										
										
										
											2003-05-22 16:32:58 +00:00
										 |  |  | 		name = strchr(typelist[i]->tp_name, '.'); | 
					
						
							| 
									
										
										
										
											2003-02-23 04:40:07 +00:00
										 |  |  | 		assert (name != NULL); | 
					
						
							| 
									
										
										
										
											2003-02-09 06:40:58 +00:00
										 |  |  | 		Py_INCREF(typelist[i]); | 
					
						
							| 
									
										
										
										
											2003-05-22 16:32:58 +00:00
										 |  |  | 		PyModule_AddObject(m, name+1, (PyObject *)typelist[i]); | 
					
						
							| 
									
										
										
										
											2003-02-09 06:40:58 +00:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2003-02-01 00:10:11 +00:00
										 |  |  | } |