Line data Source code
1 :
2 : #include "Python.h"
3 : #include "structmember.h"
4 :
5 : /* Itertools module written and maintained
6 : by Raymond D. Hettinger <python@rcn.com>
7 : */
8 :
9 :
10 : /* groupby object ***********************************************************/
11 :
12 : typedef struct {
13 : PyObject_HEAD
14 : PyObject *it;
15 : PyObject *keyfunc;
16 : PyObject *tgtkey;
17 : PyObject *currkey;
18 : PyObject *currvalue;
19 : } groupbyobject;
20 :
21 : static PyTypeObject groupby_type;
22 : static PyObject *_grouper_create(groupbyobject *, PyObject *);
23 :
24 : static PyObject *
25 0 : groupby_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
26 : {
27 : static char *kwargs[] = {"iterable", "key", NULL};
28 : groupbyobject *gbo;
29 0 : PyObject *it, *keyfunc = Py_None;
30 :
31 0 : if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|O:groupby", kwargs,
32 : &it, &keyfunc))
33 0 : return NULL;
34 :
35 0 : gbo = (groupbyobject *)type->tp_alloc(type, 0);
36 0 : if (gbo == NULL)
37 0 : return NULL;
38 0 : gbo->tgtkey = NULL;
39 0 : gbo->currkey = NULL;
40 0 : gbo->currvalue = NULL;
41 0 : gbo->keyfunc = keyfunc;
42 0 : Py_INCREF(keyfunc);
43 0 : gbo->it = PyObject_GetIter(it);
44 0 : if (gbo->it == NULL) {
45 0 : Py_DECREF(gbo);
46 0 : return NULL;
47 : }
48 0 : return (PyObject *)gbo;
49 : }
50 :
51 : static void
52 0 : groupby_dealloc(groupbyobject *gbo)
53 : {
54 0 : PyObject_GC_UnTrack(gbo);
55 0 : Py_XDECREF(gbo->it);
56 0 : Py_XDECREF(gbo->keyfunc);
57 0 : Py_XDECREF(gbo->tgtkey);
58 0 : Py_XDECREF(gbo->currkey);
59 0 : Py_XDECREF(gbo->currvalue);
60 0 : Py_TYPE(gbo)->tp_free(gbo);
61 0 : }
62 :
63 : static int
64 0 : groupby_traverse(groupbyobject *gbo, visitproc visit, void *arg)
65 : {
66 0 : Py_VISIT(gbo->it);
67 0 : Py_VISIT(gbo->keyfunc);
68 0 : Py_VISIT(gbo->tgtkey);
69 0 : Py_VISIT(gbo->currkey);
70 0 : Py_VISIT(gbo->currvalue);
71 0 : return 0;
72 : }
73 :
74 : static PyObject *
75 0 : groupby_next(groupbyobject *gbo)
76 : {
77 : PyObject *newvalue, *newkey, *r, *grouper, *tmp;
78 :
79 : /* skip to next iteration group */
80 : for (;;) {
81 0 : if (gbo->currkey == NULL)
82 : /* pass */;
83 0 : else if (gbo->tgtkey == NULL)
84 0 : break;
85 : else {
86 : int rcmp;
87 :
88 0 : rcmp = PyObject_RichCompareBool(gbo->tgtkey,
89 : gbo->currkey, Py_EQ);
90 0 : if (rcmp == -1)
91 0 : return NULL;
92 0 : else if (rcmp == 0)
93 0 : break;
94 : }
95 :
96 0 : newvalue = PyIter_Next(gbo->it);
97 0 : if (newvalue == NULL)
98 0 : return NULL;
99 :
100 0 : if (gbo->keyfunc == Py_None) {
101 0 : newkey = newvalue;
102 0 : Py_INCREF(newvalue);
103 : } else {
104 0 : newkey = PyObject_CallFunctionObjArgs(gbo->keyfunc,
105 : newvalue, NULL);
106 0 : if (newkey == NULL) {
107 0 : Py_DECREF(newvalue);
108 0 : return NULL;
109 : }
110 : }
111 :
112 0 : tmp = gbo->currkey;
113 0 : gbo->currkey = newkey;
114 0 : Py_XDECREF(tmp);
115 :
116 0 : tmp = gbo->currvalue;
117 0 : gbo->currvalue = newvalue;
118 0 : Py_XDECREF(tmp);
119 0 : }
120 :
121 0 : Py_INCREF(gbo->currkey);
122 0 : tmp = gbo->tgtkey;
123 0 : gbo->tgtkey = gbo->currkey;
124 0 : Py_XDECREF(tmp);
125 :
126 0 : grouper = _grouper_create(gbo, gbo->tgtkey);
127 0 : if (grouper == NULL)
128 0 : return NULL;
129 :
130 0 : r = PyTuple_Pack(2, gbo->currkey, grouper);
131 0 : Py_DECREF(grouper);
132 0 : return r;
133 : }
134 :
135 : PyDoc_STRVAR(groupby_doc,
136 : "groupby(iterable[, keyfunc]) -> create an iterator which returns\n\
137 : (key, sub-iterator) grouped by each value of key(value).\n");
138 :
139 : static PyTypeObject groupby_type = {
140 : PyVarObject_HEAD_INIT(NULL, 0)
141 : "itertools.groupby", /* tp_name */
142 : sizeof(groupbyobject), /* tp_basicsize */
143 : 0, /* tp_itemsize */
144 : /* methods */
145 : (destructor)groupby_dealloc, /* tp_dealloc */
146 : 0, /* tp_print */
147 : 0, /* tp_getattr */
148 : 0, /* tp_setattr */
149 : 0, /* tp_compare */
150 : 0, /* tp_repr */
151 : 0, /* tp_as_number */
152 : 0, /* tp_as_sequence */
153 : 0, /* tp_as_mapping */
154 : 0, /* tp_hash */
155 : 0, /* tp_call */
156 : 0, /* tp_str */
157 : PyObject_GenericGetAttr, /* tp_getattro */
158 : 0, /* tp_setattro */
159 : 0, /* tp_as_buffer */
160 : Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
161 : Py_TPFLAGS_BASETYPE, /* tp_flags */
162 : groupby_doc, /* tp_doc */
163 : (traverseproc)groupby_traverse, /* tp_traverse */
164 : 0, /* tp_clear */
165 : 0, /* tp_richcompare */
166 : 0, /* tp_weaklistoffset */
167 : PyObject_SelfIter, /* tp_iter */
168 : (iternextfunc)groupby_next, /* tp_iternext */
169 : 0, /* tp_methods */
170 : 0, /* tp_members */
171 : 0, /* tp_getset */
172 : 0, /* tp_base */
173 : 0, /* tp_dict */
174 : 0, /* tp_descr_get */
175 : 0, /* tp_descr_set */
176 : 0, /* tp_dictoffset */
177 : 0, /* tp_init */
178 : 0, /* tp_alloc */
179 : groupby_new, /* tp_new */
180 : PyObject_GC_Del, /* tp_free */
181 : };
182 :
183 :
184 : /* _grouper object (internal) ************************************************/
185 :
186 : typedef struct {
187 : PyObject_HEAD
188 : PyObject *parent;
189 : PyObject *tgtkey;
190 : } _grouperobject;
191 :
192 : static PyTypeObject _grouper_type;
193 :
194 : static PyObject *
195 0 : _grouper_create(groupbyobject *parent, PyObject *tgtkey)
196 : {
197 : _grouperobject *igo;
198 :
199 0 : igo = PyObject_GC_New(_grouperobject, &_grouper_type);
200 0 : if (igo == NULL)
201 0 : return NULL;
202 0 : igo->parent = (PyObject *)parent;
203 0 : Py_INCREF(parent);
204 0 : igo->tgtkey = tgtkey;
205 0 : Py_INCREF(tgtkey);
206 :
207 0 : PyObject_GC_Track(igo);
208 0 : return (PyObject *)igo;
209 : }
210 :
211 : static void
212 0 : _grouper_dealloc(_grouperobject *igo)
213 : {
214 0 : PyObject_GC_UnTrack(igo);
215 0 : Py_DECREF(igo->parent);
216 0 : Py_DECREF(igo->tgtkey);
217 0 : PyObject_GC_Del(igo);
218 0 : }
219 :
220 : static int
221 0 : _grouper_traverse(_grouperobject *igo, visitproc visit, void *arg)
222 : {
223 0 : Py_VISIT(igo->parent);
224 0 : Py_VISIT(igo->tgtkey);
225 0 : return 0;
226 : }
227 :
228 : static PyObject *
229 0 : _grouper_next(_grouperobject *igo)
230 : {
231 0 : groupbyobject *gbo = (groupbyobject *)igo->parent;
232 : PyObject *newvalue, *newkey, *r;
233 : int rcmp;
234 :
235 0 : if (gbo->currvalue == NULL) {
236 0 : newvalue = PyIter_Next(gbo->it);
237 0 : if (newvalue == NULL)
238 0 : return NULL;
239 :
240 0 : if (gbo->keyfunc == Py_None) {
241 0 : newkey = newvalue;
242 0 : Py_INCREF(newvalue);
243 : } else {
244 0 : newkey = PyObject_CallFunctionObjArgs(gbo->keyfunc,
245 : newvalue, NULL);
246 0 : if (newkey == NULL) {
247 0 : Py_DECREF(newvalue);
248 0 : return NULL;
249 : }
250 : }
251 :
252 : assert(gbo->currkey == NULL);
253 0 : gbo->currkey = newkey;
254 0 : gbo->currvalue = newvalue;
255 : }
256 :
257 : assert(gbo->currkey != NULL);
258 0 : rcmp = PyObject_RichCompareBool(igo->tgtkey, gbo->currkey, Py_EQ);
259 0 : if (rcmp <= 0)
260 : /* got any error or current group is end */
261 0 : return NULL;
262 :
263 0 : r = gbo->currvalue;
264 0 : gbo->currvalue = NULL;
265 0 : Py_CLEAR(gbo->currkey);
266 :
267 0 : return r;
268 : }
269 :
270 : static PyTypeObject _grouper_type = {
271 : PyVarObject_HEAD_INIT(NULL, 0)
272 : "itertools._grouper", /* tp_name */
273 : sizeof(_grouperobject), /* tp_basicsize */
274 : 0, /* tp_itemsize */
275 : /* methods */
276 : (destructor)_grouper_dealloc, /* tp_dealloc */
277 : 0, /* tp_print */
278 : 0, /* tp_getattr */
279 : 0, /* tp_setattr */
280 : 0, /* tp_compare */
281 : 0, /* tp_repr */
282 : 0, /* tp_as_number */
283 : 0, /* tp_as_sequence */
284 : 0, /* tp_as_mapping */
285 : 0, /* tp_hash */
286 : 0, /* tp_call */
287 : 0, /* tp_str */
288 : PyObject_GenericGetAttr, /* tp_getattro */
289 : 0, /* tp_setattro */
290 : 0, /* tp_as_buffer */
291 : Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */
292 : 0, /* tp_doc */
293 : (traverseproc)_grouper_traverse,/* tp_traverse */
294 : 0, /* tp_clear */
295 : 0, /* tp_richcompare */
296 : 0, /* tp_weaklistoffset */
297 : PyObject_SelfIter, /* tp_iter */
298 : (iternextfunc)_grouper_next, /* tp_iternext */
299 : 0, /* tp_methods */
300 : 0, /* tp_members */
301 : 0, /* tp_getset */
302 : 0, /* tp_base */
303 : 0, /* tp_dict */
304 : 0, /* tp_descr_get */
305 : 0, /* tp_descr_set */
306 : 0, /* tp_dictoffset */
307 : 0, /* tp_init */
308 : 0, /* tp_alloc */
309 : 0, /* tp_new */
310 : PyObject_GC_Del, /* tp_free */
311 : };
312 :
313 :
314 :
315 : /* tee object and with supporting function and objects ***************/
316 :
317 : /* The teedataobject pre-allocates space for LINKCELLS number of objects.
318 : To help the object fit neatly inside cache lines (space for 16 to 32
319 : pointers), the value should be a multiple of 16 minus space for
320 : the other structure members including PyHEAD overhead. The larger the
321 : value, the less memory overhead per object and the less time spent
322 : allocating/deallocating new links. The smaller the number, the less
323 : wasted space and the more rapid freeing of older data.
324 : */
325 : #define LINKCELLS 57
326 :
327 : typedef struct {
328 : PyObject_HEAD
329 : PyObject *it;
330 : int numread;
331 : PyObject *nextlink;
332 : PyObject *(values[LINKCELLS]);
333 : } teedataobject;
334 :
335 : typedef struct {
336 : PyObject_HEAD
337 : teedataobject *dataobj;
338 : int index;
339 : PyObject *weakreflist;
340 : } teeobject;
341 :
342 : static PyTypeObject teedataobject_type;
343 :
344 : static PyObject *
345 0 : teedataobject_new(PyObject *it)
346 : {
347 : teedataobject *tdo;
348 :
349 0 : tdo = PyObject_GC_New(teedataobject, &teedataobject_type);
350 0 : if (tdo == NULL)
351 0 : return NULL;
352 :
353 0 : tdo->numread = 0;
354 0 : tdo->nextlink = NULL;
355 0 : Py_INCREF(it);
356 0 : tdo->it = it;
357 0 : PyObject_GC_Track(tdo);
358 0 : return (PyObject *)tdo;
359 : }
360 :
361 : static PyObject *
362 0 : teedataobject_jumplink(teedataobject *tdo)
363 : {
364 0 : if (tdo->nextlink == NULL)
365 0 : tdo->nextlink = teedataobject_new(tdo->it);
366 0 : Py_XINCREF(tdo->nextlink);
367 0 : return tdo->nextlink;
368 : }
369 :
370 : static PyObject *
371 0 : teedataobject_getitem(teedataobject *tdo, int i)
372 : {
373 : PyObject *value;
374 :
375 : assert(i < LINKCELLS);
376 0 : if (i < tdo->numread)
377 0 : value = tdo->values[i];
378 : else {
379 : /* this is the lead iterator, so fetch more data */
380 : assert(i == tdo->numread);
381 0 : value = PyIter_Next(tdo->it);
382 0 : if (value == NULL)
383 0 : return NULL;
384 0 : tdo->numread++;
385 0 : tdo->values[i] = value;
386 : }
387 0 : Py_INCREF(value);
388 0 : return value;
389 : }
390 :
391 : static int
392 0 : teedataobject_traverse(teedataobject *tdo, visitproc visit, void * arg)
393 : {
394 : int i;
395 0 : Py_VISIT(tdo->it);
396 0 : for (i = 0; i < tdo->numread; i++)
397 0 : Py_VISIT(tdo->values[i]);
398 0 : Py_VISIT(tdo->nextlink);
399 0 : return 0;
400 : }
401 :
402 : static void
403 0 : teedataobject_safe_decref(PyObject *obj)
404 : {
405 0 : while (obj && Py_TYPE(obj) == &teedataobject_type &&
406 0 : Py_REFCNT(obj) == 1) {
407 0 : PyObject *nextlink = ((teedataobject *)obj)->nextlink;
408 0 : ((teedataobject *)obj)->nextlink = NULL;
409 0 : Py_DECREF(obj);
410 0 : obj = nextlink;
411 : }
412 0 : Py_XDECREF(obj);
413 0 : }
414 :
415 : static int
416 0 : teedataobject_clear(teedataobject *tdo)
417 : {
418 : int i;
419 : PyObject *tmp;
420 :
421 0 : Py_CLEAR(tdo->it);
422 0 : for (i=0 ; i<tdo->numread ; i++)
423 0 : Py_CLEAR(tdo->values[i]);
424 0 : tmp = tdo->nextlink;
425 0 : tdo->nextlink = NULL;
426 0 : teedataobject_safe_decref(tmp);
427 0 : return 0;
428 : }
429 :
430 : static void
431 0 : teedataobject_dealloc(teedataobject *tdo)
432 : {
433 0 : PyObject_GC_UnTrack(tdo);
434 0 : teedataobject_clear(tdo);
435 0 : PyObject_GC_Del(tdo);
436 0 : }
437 :
438 : PyDoc_STRVAR(teedataobject_doc, "Data container common to multiple tee objects.");
439 :
440 : static PyTypeObject teedataobject_type = {
441 : PyVarObject_HEAD_INIT(0, 0) /* Must fill in type value later */
442 : "itertools.tee_dataobject", /* tp_name */
443 : sizeof(teedataobject), /* tp_basicsize */
444 : 0, /* tp_itemsize */
445 : /* methods */
446 : (destructor)teedataobject_dealloc, /* tp_dealloc */
447 : 0, /* tp_print */
448 : 0, /* tp_getattr */
449 : 0, /* tp_setattr */
450 : 0, /* tp_compare */
451 : 0, /* tp_repr */
452 : 0, /* tp_as_number */
453 : 0, /* tp_as_sequence */
454 : 0, /* tp_as_mapping */
455 : 0, /* tp_hash */
456 : 0, /* tp_call */
457 : 0, /* tp_str */
458 : PyObject_GenericGetAttr, /* tp_getattro */
459 : 0, /* tp_setattro */
460 : 0, /* tp_as_buffer */
461 : Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */
462 : teedataobject_doc, /* tp_doc */
463 : (traverseproc)teedataobject_traverse, /* tp_traverse */
464 : (inquiry)teedataobject_clear, /* tp_clear */
465 : 0, /* tp_richcompare */
466 : 0, /* tp_weaklistoffset */
467 : 0, /* tp_iter */
468 : 0, /* tp_iternext */
469 : 0, /* tp_methods */
470 : 0, /* tp_members */
471 : 0, /* tp_getset */
472 : 0, /* tp_base */
473 : 0, /* tp_dict */
474 : 0, /* tp_descr_get */
475 : 0, /* tp_descr_set */
476 : 0, /* tp_dictoffset */
477 : 0, /* tp_init */
478 : 0, /* tp_alloc */
479 : 0, /* tp_new */
480 : PyObject_GC_Del, /* tp_free */
481 : };
482 :
483 :
484 : static PyTypeObject tee_type;
485 :
486 : static PyObject *
487 0 : tee_next(teeobject *to)
488 : {
489 : PyObject *value, *link;
490 :
491 0 : if (to->index >= LINKCELLS) {
492 0 : link = teedataobject_jumplink(to->dataobj);
493 0 : if (link == NULL)
494 0 : return NULL;
495 0 : Py_SETREF(to->dataobj, (teedataobject *)link);
496 0 : to->index = 0;
497 : }
498 0 : value = teedataobject_getitem(to->dataobj, to->index);
499 0 : if (value == NULL)
500 0 : return NULL;
501 0 : to->index++;
502 0 : return value;
503 : }
504 :
505 : static int
506 0 : tee_traverse(teeobject *to, visitproc visit, void *arg)
507 : {
508 0 : Py_VISIT((PyObject *)to->dataobj);
509 0 : return 0;
510 : }
511 :
512 : static PyObject *
513 0 : tee_copy(teeobject *to)
514 : {
515 : teeobject *newto;
516 :
517 0 : newto = PyObject_GC_New(teeobject, &tee_type);
518 0 : if (newto == NULL)
519 0 : return NULL;
520 0 : Py_INCREF(to->dataobj);
521 0 : newto->dataobj = to->dataobj;
522 0 : newto->index = to->index;
523 0 : newto->weakreflist = NULL;
524 0 : PyObject_GC_Track(newto);
525 0 : return (PyObject *)newto;
526 : }
527 :
528 : PyDoc_STRVAR(teecopy_doc, "Returns an independent iterator.");
529 :
530 : static PyObject *
531 0 : tee_fromiterable(PyObject *iterable)
532 : {
533 : teeobject *to;
534 0 : PyObject *it = NULL;
535 :
536 0 : it = PyObject_GetIter(iterable);
537 0 : if (it == NULL)
538 0 : return NULL;
539 0 : if (PyObject_TypeCheck(it, &tee_type)) {
540 0 : to = (teeobject *)tee_copy((teeobject *)it);
541 0 : goto done;
542 : }
543 :
544 0 : to = PyObject_GC_New(teeobject, &tee_type);
545 0 : if (to == NULL)
546 0 : goto done;
547 0 : to->dataobj = (teedataobject *)teedataobject_new(it);
548 0 : if (!to->dataobj) {
549 0 : PyObject_GC_Del(to);
550 0 : to = NULL;
551 0 : goto done;
552 : }
553 :
554 0 : to->index = 0;
555 0 : to->weakreflist = NULL;
556 0 : PyObject_GC_Track(to);
557 : done:
558 0 : Py_XDECREF(it);
559 0 : return (PyObject *)to;
560 : }
561 :
562 : static PyObject *
563 0 : tee_new(PyTypeObject *type, PyObject *args, PyObject *kw)
564 : {
565 : PyObject *iterable;
566 :
567 0 : if (!PyArg_UnpackTuple(args, "tee", 1, 1, &iterable))
568 0 : return NULL;
569 0 : return tee_fromiterable(iterable);
570 : }
571 :
572 : static int
573 0 : tee_clear(teeobject *to)
574 : {
575 0 : if (to->weakreflist != NULL)
576 0 : PyObject_ClearWeakRefs((PyObject *) to);
577 0 : Py_CLEAR(to->dataobj);
578 0 : return 0;
579 : }
580 :
581 : static void
582 0 : tee_dealloc(teeobject *to)
583 : {
584 0 : PyObject_GC_UnTrack(to);
585 0 : tee_clear(to);
586 0 : PyObject_GC_Del(to);
587 0 : }
588 :
589 : PyDoc_STRVAR(teeobject_doc,
590 : "Iterator wrapped to make it copyable");
591 :
592 : static PyMethodDef tee_methods[] = {
593 : {"__copy__", (PyCFunction)tee_copy, METH_NOARGS, teecopy_doc},
594 : {NULL, NULL} /* sentinel */
595 : };
596 :
597 : static PyTypeObject tee_type = {
598 : PyVarObject_HEAD_INIT(NULL, 0)
599 : "itertools.tee", /* tp_name */
600 : sizeof(teeobject), /* tp_basicsize */
601 : 0, /* tp_itemsize */
602 : /* methods */
603 : (destructor)tee_dealloc, /* tp_dealloc */
604 : 0, /* tp_print */
605 : 0, /* tp_getattr */
606 : 0, /* tp_setattr */
607 : 0, /* tp_compare */
608 : 0, /* tp_repr */
609 : 0, /* tp_as_number */
610 : 0, /* tp_as_sequence */
611 : 0, /* tp_as_mapping */
612 : 0, /* tp_hash */
613 : 0, /* tp_call */
614 : 0, /* tp_str */
615 : 0, /* tp_getattro */
616 : 0, /* tp_setattro */
617 : 0, /* tp_as_buffer */
618 : Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */
619 : teeobject_doc, /* tp_doc */
620 : (traverseproc)tee_traverse, /* tp_traverse */
621 : (inquiry)tee_clear, /* tp_clear */
622 : 0, /* tp_richcompare */
623 : offsetof(teeobject, weakreflist), /* tp_weaklistoffset */
624 : PyObject_SelfIter, /* tp_iter */
625 : (iternextfunc)tee_next, /* tp_iternext */
626 : tee_methods, /* tp_methods */
627 : 0, /* tp_members */
628 : 0, /* tp_getset */
629 : 0, /* tp_base */
630 : 0, /* tp_dict */
631 : 0, /* tp_descr_get */
632 : 0, /* tp_descr_set */
633 : 0, /* tp_dictoffset */
634 : 0, /* tp_init */
635 : 0, /* tp_alloc */
636 : tee_new, /* tp_new */
637 : PyObject_GC_Del, /* tp_free */
638 : };
639 :
640 : static PyObject *
641 0 : tee(PyObject *self, PyObject *args)
642 : {
643 0 : Py_ssize_t i, n=2;
644 : PyObject *it, *iterable, *copyable, *result;
645 :
646 0 : if (!PyArg_ParseTuple(args, "O|n", &iterable, &n))
647 0 : return NULL;
648 0 : if (n < 0) {
649 0 : PyErr_SetString(PyExc_ValueError, "n must be >= 0");
650 0 : return NULL;
651 : }
652 0 : result = PyTuple_New(n);
653 0 : if (result == NULL)
654 0 : return NULL;
655 0 : if (n == 0)
656 0 : return result;
657 0 : it = PyObject_GetIter(iterable);
658 0 : if (it == NULL) {
659 0 : Py_DECREF(result);
660 0 : return NULL;
661 : }
662 0 : if (!PyObject_HasAttrString(it, "__copy__")) {
663 0 : copyable = tee_fromiterable(it);
664 0 : Py_DECREF(it);
665 0 : if (copyable == NULL) {
666 0 : Py_DECREF(result);
667 0 : return NULL;
668 : }
669 : } else
670 0 : copyable = it;
671 0 : PyTuple_SET_ITEM(result, 0, copyable);
672 0 : for (i=1 ; i<n ; i++) {
673 0 : copyable = PyObject_CallMethod(copyable, "__copy__", NULL);
674 0 : if (copyable == NULL) {
675 0 : Py_DECREF(result);
676 0 : return NULL;
677 : }
678 0 : PyTuple_SET_ITEM(result, i, copyable);
679 : }
680 0 : return result;
681 : }
682 :
683 : PyDoc_STRVAR(tee_doc,
684 : "tee(iterable, n=2) --> tuple of n independent iterators.");
685 :
686 :
687 : /* cycle object **********************************************************/
688 :
689 : typedef struct {
690 : PyObject_HEAD
691 : PyObject *it;
692 : PyObject *saved;
693 : int firstpass;
694 : } cycleobject;
695 :
696 : static PyTypeObject cycle_type;
697 :
698 : static PyObject *
699 0 : cycle_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
700 : {
701 : PyObject *it;
702 : PyObject *iterable;
703 : PyObject *saved;
704 : cycleobject *lz;
705 :
706 0 : if (type == &cycle_type && !_PyArg_NoKeywords("cycle()", kwds))
707 0 : return NULL;
708 :
709 0 : if (!PyArg_UnpackTuple(args, "cycle", 1, 1, &iterable))
710 0 : return NULL;
711 :
712 : /* Get iterator. */
713 0 : it = PyObject_GetIter(iterable);
714 0 : if (it == NULL)
715 0 : return NULL;
716 :
717 0 : saved = PyList_New(0);
718 0 : if (saved == NULL) {
719 0 : Py_DECREF(it);
720 0 : return NULL;
721 : }
722 :
723 : /* create cycleobject structure */
724 0 : lz = (cycleobject *)type->tp_alloc(type, 0);
725 0 : if (lz == NULL) {
726 0 : Py_DECREF(it);
727 0 : Py_DECREF(saved);
728 0 : return NULL;
729 : }
730 0 : lz->it = it;
731 0 : lz->saved = saved;
732 0 : lz->firstpass = 0;
733 :
734 0 : return (PyObject *)lz;
735 : }
736 :
737 : static void
738 0 : cycle_dealloc(cycleobject *lz)
739 : {
740 0 : PyObject_GC_UnTrack(lz);
741 0 : Py_XDECREF(lz->saved);
742 0 : Py_XDECREF(lz->it);
743 0 : Py_TYPE(lz)->tp_free(lz);
744 0 : }
745 :
746 : static int
747 0 : cycle_traverse(cycleobject *lz, visitproc visit, void *arg)
748 : {
749 0 : Py_VISIT(lz->it);
750 0 : Py_VISIT(lz->saved);
751 0 : return 0;
752 : }
753 :
754 : static PyObject *
755 0 : cycle_next(cycleobject *lz)
756 : {
757 : PyObject *item;
758 : PyObject *it;
759 : PyObject *tmp;
760 :
761 : while (1) {
762 0 : item = PyIter_Next(lz->it);
763 0 : if (item != NULL) {
764 0 : if (!lz->firstpass && PyList_Append(lz->saved, item)) {
765 0 : Py_DECREF(item);
766 0 : return NULL;
767 : }
768 0 : return item;
769 : }
770 0 : if (PyErr_Occurred()) {
771 0 : if (PyErr_ExceptionMatches(PyExc_StopIteration))
772 0 : PyErr_Clear();
773 : else
774 0 : return NULL;
775 : }
776 0 : if (PyList_Size(lz->saved) == 0)
777 0 : return NULL;
778 0 : it = PyObject_GetIter(lz->saved);
779 0 : if (it == NULL)
780 0 : return NULL;
781 0 : tmp = lz->it;
782 0 : lz->it = it;
783 0 : lz->firstpass = 1;
784 0 : Py_DECREF(tmp);
785 0 : }
786 : }
787 :
788 : PyDoc_STRVAR(cycle_doc,
789 : "cycle(iterable) --> cycle object\n\
790 : \n\
791 : Return elements from the iterable until it is exhausted.\n\
792 : Then repeat the sequence indefinitely.");
793 :
794 : static PyTypeObject cycle_type = {
795 : PyVarObject_HEAD_INIT(NULL, 0)
796 : "itertools.cycle", /* tp_name */
797 : sizeof(cycleobject), /* tp_basicsize */
798 : 0, /* tp_itemsize */
799 : /* methods */
800 : (destructor)cycle_dealloc, /* tp_dealloc */
801 : 0, /* tp_print */
802 : 0, /* tp_getattr */
803 : 0, /* tp_setattr */
804 : 0, /* tp_compare */
805 : 0, /* tp_repr */
806 : 0, /* tp_as_number */
807 : 0, /* tp_as_sequence */
808 : 0, /* tp_as_mapping */
809 : 0, /* tp_hash */
810 : 0, /* tp_call */
811 : 0, /* tp_str */
812 : PyObject_GenericGetAttr, /* tp_getattro */
813 : 0, /* tp_setattro */
814 : 0, /* tp_as_buffer */
815 : Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
816 : Py_TPFLAGS_BASETYPE, /* tp_flags */
817 : cycle_doc, /* tp_doc */
818 : (traverseproc)cycle_traverse, /* tp_traverse */
819 : 0, /* tp_clear */
820 : 0, /* tp_richcompare */
821 : 0, /* tp_weaklistoffset */
822 : PyObject_SelfIter, /* tp_iter */
823 : (iternextfunc)cycle_next, /* tp_iternext */
824 : 0, /* tp_methods */
825 : 0, /* tp_members */
826 : 0, /* tp_getset */
827 : 0, /* tp_base */
828 : 0, /* tp_dict */
829 : 0, /* tp_descr_get */
830 : 0, /* tp_descr_set */
831 : 0, /* tp_dictoffset */
832 : 0, /* tp_init */
833 : 0, /* tp_alloc */
834 : cycle_new, /* tp_new */
835 : PyObject_GC_Del, /* tp_free */
836 : };
837 :
838 :
839 : /* dropwhile object **********************************************************/
840 :
841 : typedef struct {
842 : PyObject_HEAD
843 : PyObject *func;
844 : PyObject *it;
845 : long start;
846 : } dropwhileobject;
847 :
848 : static PyTypeObject dropwhile_type;
849 :
850 : static PyObject *
851 0 : dropwhile_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
852 : {
853 : PyObject *func, *seq;
854 : PyObject *it;
855 : dropwhileobject *lz;
856 :
857 0 : if (type == &dropwhile_type && !_PyArg_NoKeywords("dropwhile()", kwds))
858 0 : return NULL;
859 :
860 0 : if (!PyArg_UnpackTuple(args, "dropwhile", 2, 2, &func, &seq))
861 0 : return NULL;
862 :
863 : /* Get iterator. */
864 0 : it = PyObject_GetIter(seq);
865 0 : if (it == NULL)
866 0 : return NULL;
867 :
868 : /* create dropwhileobject structure */
869 0 : lz = (dropwhileobject *)type->tp_alloc(type, 0);
870 0 : if (lz == NULL) {
871 0 : Py_DECREF(it);
872 0 : return NULL;
873 : }
874 0 : Py_INCREF(func);
875 0 : lz->func = func;
876 0 : lz->it = it;
877 0 : lz->start = 0;
878 :
879 0 : return (PyObject *)lz;
880 : }
881 :
882 : static void
883 0 : dropwhile_dealloc(dropwhileobject *lz)
884 : {
885 0 : PyObject_GC_UnTrack(lz);
886 0 : Py_XDECREF(lz->func);
887 0 : Py_XDECREF(lz->it);
888 0 : Py_TYPE(lz)->tp_free(lz);
889 0 : }
890 :
891 : static int
892 0 : dropwhile_traverse(dropwhileobject *lz, visitproc visit, void *arg)
893 : {
894 0 : Py_VISIT(lz->it);
895 0 : Py_VISIT(lz->func);
896 0 : return 0;
897 : }
898 :
899 : static PyObject *
900 0 : dropwhile_next(dropwhileobject *lz)
901 : {
902 : PyObject *item, *good;
903 0 : PyObject *it = lz->it;
904 : long ok;
905 : PyObject *(*iternext)(PyObject *);
906 :
907 0 : iternext = *Py_TYPE(it)->tp_iternext;
908 : for (;;) {
909 0 : item = iternext(it);
910 0 : if (item == NULL)
911 0 : return NULL;
912 0 : if (lz->start == 1)
913 0 : return item;
914 :
915 0 : good = PyObject_CallFunctionObjArgs(lz->func, item, NULL);
916 0 : if (good == NULL) {
917 0 : Py_DECREF(item);
918 0 : return NULL;
919 : }
920 0 : ok = PyObject_IsTrue(good);
921 0 : Py_DECREF(good);
922 0 : if (ok == 0) {
923 0 : lz->start = 1;
924 0 : return item;
925 : }
926 0 : Py_DECREF(item);
927 0 : if (ok < 0)
928 0 : return NULL;
929 0 : }
930 : }
931 :
932 : PyDoc_STRVAR(dropwhile_doc,
933 : "dropwhile(predicate, iterable) --> dropwhile object\n\
934 : \n\
935 : Drop items from the iterable while predicate(item) is true.\n\
936 : Afterwards, return every element until the iterable is exhausted.");
937 :
938 : static PyTypeObject dropwhile_type = {
939 : PyVarObject_HEAD_INIT(NULL, 0)
940 : "itertools.dropwhile", /* tp_name */
941 : sizeof(dropwhileobject), /* tp_basicsize */
942 : 0, /* tp_itemsize */
943 : /* methods */
944 : (destructor)dropwhile_dealloc, /* tp_dealloc */
945 : 0, /* tp_print */
946 : 0, /* tp_getattr */
947 : 0, /* tp_setattr */
948 : 0, /* tp_compare */
949 : 0, /* tp_repr */
950 : 0, /* tp_as_number */
951 : 0, /* tp_as_sequence */
952 : 0, /* tp_as_mapping */
953 : 0, /* tp_hash */
954 : 0, /* tp_call */
955 : 0, /* tp_str */
956 : PyObject_GenericGetAttr, /* tp_getattro */
957 : 0, /* tp_setattro */
958 : 0, /* tp_as_buffer */
959 : Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
960 : Py_TPFLAGS_BASETYPE, /* tp_flags */
961 : dropwhile_doc, /* tp_doc */
962 : (traverseproc)dropwhile_traverse, /* tp_traverse */
963 : 0, /* tp_clear */
964 : 0, /* tp_richcompare */
965 : 0, /* tp_weaklistoffset */
966 : PyObject_SelfIter, /* tp_iter */
967 : (iternextfunc)dropwhile_next, /* tp_iternext */
968 : 0, /* tp_methods */
969 : 0, /* tp_members */
970 : 0, /* tp_getset */
971 : 0, /* tp_base */
972 : 0, /* tp_dict */
973 : 0, /* tp_descr_get */
974 : 0, /* tp_descr_set */
975 : 0, /* tp_dictoffset */
976 : 0, /* tp_init */
977 : 0, /* tp_alloc */
978 : dropwhile_new, /* tp_new */
979 : PyObject_GC_Del, /* tp_free */
980 : };
981 :
982 :
983 : /* takewhile object **********************************************************/
984 :
985 : typedef struct {
986 : PyObject_HEAD
987 : PyObject *func;
988 : PyObject *it;
989 : long stop;
990 : } takewhileobject;
991 :
992 : static PyTypeObject takewhile_type;
993 :
994 : static PyObject *
995 0 : takewhile_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
996 : {
997 : PyObject *func, *seq;
998 : PyObject *it;
999 : takewhileobject *lz;
1000 :
1001 0 : if (type == &takewhile_type && !_PyArg_NoKeywords("takewhile()", kwds))
1002 0 : return NULL;
1003 :
1004 0 : if (!PyArg_UnpackTuple(args, "takewhile", 2, 2, &func, &seq))
1005 0 : return NULL;
1006 :
1007 : /* Get iterator. */
1008 0 : it = PyObject_GetIter(seq);
1009 0 : if (it == NULL)
1010 0 : return NULL;
1011 :
1012 : /* create takewhileobject structure */
1013 0 : lz = (takewhileobject *)type->tp_alloc(type, 0);
1014 0 : if (lz == NULL) {
1015 0 : Py_DECREF(it);
1016 0 : return NULL;
1017 : }
1018 0 : Py_INCREF(func);
1019 0 : lz->func = func;
1020 0 : lz->it = it;
1021 0 : lz->stop = 0;
1022 :
1023 0 : return (PyObject *)lz;
1024 : }
1025 :
1026 : static void
1027 0 : takewhile_dealloc(takewhileobject *lz)
1028 : {
1029 0 : PyObject_GC_UnTrack(lz);
1030 0 : Py_XDECREF(lz->func);
1031 0 : Py_XDECREF(lz->it);
1032 0 : Py_TYPE(lz)->tp_free(lz);
1033 0 : }
1034 :
1035 : static int
1036 0 : takewhile_traverse(takewhileobject *lz, visitproc visit, void *arg)
1037 : {
1038 0 : Py_VISIT(lz->it);
1039 0 : Py_VISIT(lz->func);
1040 0 : return 0;
1041 : }
1042 :
1043 : static PyObject *
1044 0 : takewhile_next(takewhileobject *lz)
1045 : {
1046 : PyObject *item, *good;
1047 0 : PyObject *it = lz->it;
1048 : long ok;
1049 :
1050 0 : if (lz->stop == 1)
1051 0 : return NULL;
1052 :
1053 0 : item = (*Py_TYPE(it)->tp_iternext)(it);
1054 0 : if (item == NULL)
1055 0 : return NULL;
1056 :
1057 0 : good = PyObject_CallFunctionObjArgs(lz->func, item, NULL);
1058 0 : if (good == NULL) {
1059 0 : Py_DECREF(item);
1060 0 : return NULL;
1061 : }
1062 0 : ok = PyObject_IsTrue(good);
1063 0 : Py_DECREF(good);
1064 0 : if (ok > 0)
1065 0 : return item;
1066 0 : Py_DECREF(item);
1067 0 : if (ok == 0)
1068 0 : lz->stop = 1;
1069 0 : return NULL;
1070 : }
1071 :
1072 : PyDoc_STRVAR(takewhile_doc,
1073 : "takewhile(predicate, iterable) --> takewhile object\n\
1074 : \n\
1075 : Return successive entries from an iterable as long as the \n\
1076 : predicate evaluates to true for each entry.");
1077 :
1078 : static PyTypeObject takewhile_type = {
1079 : PyVarObject_HEAD_INIT(NULL, 0)
1080 : "itertools.takewhile", /* tp_name */
1081 : sizeof(takewhileobject), /* tp_basicsize */
1082 : 0, /* tp_itemsize */
1083 : /* methods */
1084 : (destructor)takewhile_dealloc, /* tp_dealloc */
1085 : 0, /* tp_print */
1086 : 0, /* tp_getattr */
1087 : 0, /* tp_setattr */
1088 : 0, /* tp_compare */
1089 : 0, /* tp_repr */
1090 : 0, /* tp_as_number */
1091 : 0, /* tp_as_sequence */
1092 : 0, /* tp_as_mapping */
1093 : 0, /* tp_hash */
1094 : 0, /* tp_call */
1095 : 0, /* tp_str */
1096 : PyObject_GenericGetAttr, /* tp_getattro */
1097 : 0, /* tp_setattro */
1098 : 0, /* tp_as_buffer */
1099 : Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
1100 : Py_TPFLAGS_BASETYPE, /* tp_flags */
1101 : takewhile_doc, /* tp_doc */
1102 : (traverseproc)takewhile_traverse, /* tp_traverse */
1103 : 0, /* tp_clear */
1104 : 0, /* tp_richcompare */
1105 : 0, /* tp_weaklistoffset */
1106 : PyObject_SelfIter, /* tp_iter */
1107 : (iternextfunc)takewhile_next, /* tp_iternext */
1108 : 0, /* tp_methods */
1109 : 0, /* tp_members */
1110 : 0, /* tp_getset */
1111 : 0, /* tp_base */
1112 : 0, /* tp_dict */
1113 : 0, /* tp_descr_get */
1114 : 0, /* tp_descr_set */
1115 : 0, /* tp_dictoffset */
1116 : 0, /* tp_init */
1117 : 0, /* tp_alloc */
1118 : takewhile_new, /* tp_new */
1119 : PyObject_GC_Del, /* tp_free */
1120 : };
1121 :
1122 :
1123 : /* islice object ************************************************************/
1124 :
1125 : typedef struct {
1126 : PyObject_HEAD
1127 : PyObject *it;
1128 : Py_ssize_t next;
1129 : Py_ssize_t stop;
1130 : Py_ssize_t step;
1131 : Py_ssize_t cnt;
1132 : } isliceobject;
1133 :
1134 : static PyTypeObject islice_type;
1135 :
1136 : static PyObject *
1137 0 : islice_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1138 : {
1139 : PyObject *seq;
1140 0 : Py_ssize_t start=0, stop=-1, step=1;
1141 0 : PyObject *it, *a1=NULL, *a2=NULL, *a3=NULL;
1142 : Py_ssize_t numargs;
1143 : isliceobject *lz;
1144 :
1145 0 : if (type == &islice_type && !_PyArg_NoKeywords("islice()", kwds))
1146 0 : return NULL;
1147 :
1148 0 : if (!PyArg_UnpackTuple(args, "islice", 2, 4, &seq, &a1, &a2, &a3))
1149 0 : return NULL;
1150 :
1151 0 : numargs = PyTuple_Size(args);
1152 0 : if (numargs == 2) {
1153 0 : if (a1 != Py_None) {
1154 0 : stop = PyInt_AsSsize_t(a1);
1155 0 : if (stop == -1) {
1156 0 : if (PyErr_Occurred())
1157 0 : PyErr_Clear();
1158 0 : PyErr_SetString(PyExc_ValueError,
1159 : "Stop argument for islice() must be None or an integer: 0 <= x <= maxint.");
1160 0 : return NULL;
1161 : }
1162 : }
1163 : } else {
1164 0 : if (a1 != Py_None)
1165 0 : start = PyInt_AsSsize_t(a1);
1166 0 : if (start == -1 && PyErr_Occurred())
1167 0 : PyErr_Clear();
1168 0 : if (a2 != Py_None) {
1169 0 : stop = PyInt_AsSsize_t(a2);
1170 0 : if (stop == -1) {
1171 0 : if (PyErr_Occurred())
1172 0 : PyErr_Clear();
1173 0 : PyErr_SetString(PyExc_ValueError,
1174 : "Stop argument for islice() must be None or an integer: 0 <= x <= maxint.");
1175 0 : return NULL;
1176 : }
1177 : }
1178 : }
1179 0 : if (start<0 || stop<-1) {
1180 0 : PyErr_SetString(PyExc_ValueError,
1181 : "Indices for islice() must be None or an integer: 0 <= x <= maxint.");
1182 0 : return NULL;
1183 : }
1184 :
1185 0 : if (a3 != NULL) {
1186 0 : if (a3 != Py_None)
1187 0 : step = PyInt_AsSsize_t(a3);
1188 0 : if (step == -1 && PyErr_Occurred())
1189 0 : PyErr_Clear();
1190 : }
1191 0 : if (step<1) {
1192 0 : PyErr_SetString(PyExc_ValueError,
1193 : "Step for islice() must be a positive integer or None.");
1194 0 : return NULL;
1195 : }
1196 :
1197 : /* Get iterator. */
1198 0 : it = PyObject_GetIter(seq);
1199 0 : if (it == NULL)
1200 0 : return NULL;
1201 :
1202 : /* create isliceobject structure */
1203 0 : lz = (isliceobject *)type->tp_alloc(type, 0);
1204 0 : if (lz == NULL) {
1205 0 : Py_DECREF(it);
1206 0 : return NULL;
1207 : }
1208 0 : lz->it = it;
1209 0 : lz->next = start;
1210 0 : lz->stop = stop;
1211 0 : lz->step = step;
1212 0 : lz->cnt = 0L;
1213 :
1214 0 : return (PyObject *)lz;
1215 : }
1216 :
1217 : static void
1218 0 : islice_dealloc(isliceobject *lz)
1219 : {
1220 0 : PyObject_GC_UnTrack(lz);
1221 0 : Py_XDECREF(lz->it);
1222 0 : Py_TYPE(lz)->tp_free(lz);
1223 0 : }
1224 :
1225 : static int
1226 0 : islice_traverse(isliceobject *lz, visitproc visit, void *arg)
1227 : {
1228 0 : Py_VISIT(lz->it);
1229 0 : return 0;
1230 : }
1231 :
1232 : static PyObject *
1233 0 : islice_next(isliceobject *lz)
1234 : {
1235 : PyObject *item;
1236 0 : PyObject *it = lz->it;
1237 0 : Py_ssize_t stop = lz->stop;
1238 : Py_ssize_t oldnext;
1239 : PyObject *(*iternext)(PyObject *);
1240 :
1241 0 : if (it == NULL)
1242 0 : return NULL;
1243 :
1244 0 : iternext = *Py_TYPE(it)->tp_iternext;
1245 0 : while (lz->cnt < lz->next) {
1246 0 : item = iternext(it);
1247 0 : if (item == NULL)
1248 0 : goto empty;
1249 0 : Py_DECREF(item);
1250 0 : lz->cnt++;
1251 : }
1252 0 : if (stop != -1 && lz->cnt >= stop)
1253 0 : goto empty;
1254 0 : item = iternext(it);
1255 0 : if (item == NULL)
1256 0 : goto empty;
1257 0 : lz->cnt++;
1258 0 : oldnext = lz->next;
1259 : /* The (size_t) cast below avoids the danger of undefined
1260 : behaviour from signed integer overflow. */
1261 0 : lz->next += (size_t)lz->step;
1262 0 : if (lz->next < oldnext || (stop != -1 && lz->next > stop))
1263 0 : lz->next = stop;
1264 0 : return item;
1265 :
1266 : empty:
1267 0 : Py_CLEAR(lz->it);
1268 0 : return NULL;
1269 : }
1270 :
1271 : PyDoc_STRVAR(islice_doc,
1272 : "islice(iterable, [start,] stop [, step]) --> islice object\n\
1273 : \n\
1274 : Return an iterator whose next() method returns selected values from an\n\
1275 : iterable. If start is specified, will skip all preceding elements;\n\
1276 : otherwise, start defaults to zero. Step defaults to one. If\n\
1277 : specified as another value, step determines how many values are \n\
1278 : skipped between successive calls. Works like a slice() on a list\n\
1279 : but returns an iterator.");
1280 :
1281 : static PyTypeObject islice_type = {
1282 : PyVarObject_HEAD_INIT(NULL, 0)
1283 : "itertools.islice", /* tp_name */
1284 : sizeof(isliceobject), /* tp_basicsize */
1285 : 0, /* tp_itemsize */
1286 : /* methods */
1287 : (destructor)islice_dealloc, /* tp_dealloc */
1288 : 0, /* tp_print */
1289 : 0, /* tp_getattr */
1290 : 0, /* tp_setattr */
1291 : 0, /* tp_compare */
1292 : 0, /* tp_repr */
1293 : 0, /* tp_as_number */
1294 : 0, /* tp_as_sequence */
1295 : 0, /* tp_as_mapping */
1296 : 0, /* tp_hash */
1297 : 0, /* tp_call */
1298 : 0, /* tp_str */
1299 : PyObject_GenericGetAttr, /* tp_getattro */
1300 : 0, /* tp_setattro */
1301 : 0, /* tp_as_buffer */
1302 : Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
1303 : Py_TPFLAGS_BASETYPE, /* tp_flags */
1304 : islice_doc, /* tp_doc */
1305 : (traverseproc)islice_traverse, /* tp_traverse */
1306 : 0, /* tp_clear */
1307 : 0, /* tp_richcompare */
1308 : 0, /* tp_weaklistoffset */
1309 : PyObject_SelfIter, /* tp_iter */
1310 : (iternextfunc)islice_next, /* tp_iternext */
1311 : 0, /* tp_methods */
1312 : 0, /* tp_members */
1313 : 0, /* tp_getset */
1314 : 0, /* tp_base */
1315 : 0, /* tp_dict */
1316 : 0, /* tp_descr_get */
1317 : 0, /* tp_descr_set */
1318 : 0, /* tp_dictoffset */
1319 : 0, /* tp_init */
1320 : 0, /* tp_alloc */
1321 : islice_new, /* tp_new */
1322 : PyObject_GC_Del, /* tp_free */
1323 : };
1324 :
1325 :
1326 : /* starmap object ************************************************************/
1327 :
1328 : typedef struct {
1329 : PyObject_HEAD
1330 : PyObject *func;
1331 : PyObject *it;
1332 : } starmapobject;
1333 :
1334 : static PyTypeObject starmap_type;
1335 :
1336 : static PyObject *
1337 0 : starmap_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1338 : {
1339 : PyObject *func, *seq;
1340 : PyObject *it;
1341 : starmapobject *lz;
1342 :
1343 0 : if (type == &starmap_type && !_PyArg_NoKeywords("starmap()", kwds))
1344 0 : return NULL;
1345 :
1346 0 : if (!PyArg_UnpackTuple(args, "starmap", 2, 2, &func, &seq))
1347 0 : return NULL;
1348 :
1349 : /* Get iterator. */
1350 0 : it = PyObject_GetIter(seq);
1351 0 : if (it == NULL)
1352 0 : return NULL;
1353 :
1354 : /* create starmapobject structure */
1355 0 : lz = (starmapobject *)type->tp_alloc(type, 0);
1356 0 : if (lz == NULL) {
1357 0 : Py_DECREF(it);
1358 0 : return NULL;
1359 : }
1360 0 : Py_INCREF(func);
1361 0 : lz->func = func;
1362 0 : lz->it = it;
1363 :
1364 0 : return (PyObject *)lz;
1365 : }
1366 :
1367 : static void
1368 0 : starmap_dealloc(starmapobject *lz)
1369 : {
1370 0 : PyObject_GC_UnTrack(lz);
1371 0 : Py_XDECREF(lz->func);
1372 0 : Py_XDECREF(lz->it);
1373 0 : Py_TYPE(lz)->tp_free(lz);
1374 0 : }
1375 :
1376 : static int
1377 0 : starmap_traverse(starmapobject *lz, visitproc visit, void *arg)
1378 : {
1379 0 : Py_VISIT(lz->it);
1380 0 : Py_VISIT(lz->func);
1381 0 : return 0;
1382 : }
1383 :
1384 : static PyObject *
1385 0 : starmap_next(starmapobject *lz)
1386 : {
1387 : PyObject *args;
1388 : PyObject *result;
1389 0 : PyObject *it = lz->it;
1390 :
1391 0 : args = (*Py_TYPE(it)->tp_iternext)(it);
1392 0 : if (args == NULL)
1393 0 : return NULL;
1394 0 : if (!PyTuple_CheckExact(args)) {
1395 0 : PyObject *newargs = PySequence_Tuple(args);
1396 0 : Py_DECREF(args);
1397 0 : if (newargs == NULL)
1398 0 : return NULL;
1399 0 : args = newargs;
1400 : }
1401 0 : result = PyObject_Call(lz->func, args, NULL);
1402 0 : Py_DECREF(args);
1403 0 : return result;
1404 : }
1405 :
1406 : PyDoc_STRVAR(starmap_doc,
1407 : "starmap(function, sequence) --> starmap object\n\
1408 : \n\
1409 : Return an iterator whose values are returned from the function evaluated\n\
1410 : with an argument tuple taken from the given sequence.");
1411 :
1412 : static PyTypeObject starmap_type = {
1413 : PyVarObject_HEAD_INIT(NULL, 0)
1414 : "itertools.starmap", /* tp_name */
1415 : sizeof(starmapobject), /* tp_basicsize */
1416 : 0, /* tp_itemsize */
1417 : /* methods */
1418 : (destructor)starmap_dealloc, /* tp_dealloc */
1419 : 0, /* tp_print */
1420 : 0, /* tp_getattr */
1421 : 0, /* tp_setattr */
1422 : 0, /* tp_compare */
1423 : 0, /* tp_repr */
1424 : 0, /* tp_as_number */
1425 : 0, /* tp_as_sequence */
1426 : 0, /* tp_as_mapping */
1427 : 0, /* tp_hash */
1428 : 0, /* tp_call */
1429 : 0, /* tp_str */
1430 : PyObject_GenericGetAttr, /* tp_getattro */
1431 : 0, /* tp_setattro */
1432 : 0, /* tp_as_buffer */
1433 : Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
1434 : Py_TPFLAGS_BASETYPE, /* tp_flags */
1435 : starmap_doc, /* tp_doc */
1436 : (traverseproc)starmap_traverse, /* tp_traverse */
1437 : 0, /* tp_clear */
1438 : 0, /* tp_richcompare */
1439 : 0, /* tp_weaklistoffset */
1440 : PyObject_SelfIter, /* tp_iter */
1441 : (iternextfunc)starmap_next, /* tp_iternext */
1442 : 0, /* tp_methods */
1443 : 0, /* tp_members */
1444 : 0, /* tp_getset */
1445 : 0, /* tp_base */
1446 : 0, /* tp_dict */
1447 : 0, /* tp_descr_get */
1448 : 0, /* tp_descr_set */
1449 : 0, /* tp_dictoffset */
1450 : 0, /* tp_init */
1451 : 0, /* tp_alloc */
1452 : starmap_new, /* tp_new */
1453 : PyObject_GC_Del, /* tp_free */
1454 : };
1455 :
1456 :
1457 : /* imap object ************************************************************/
1458 :
1459 : typedef struct {
1460 : PyObject_HEAD
1461 : PyObject *iters;
1462 : PyObject *func;
1463 : } imapobject;
1464 :
1465 : static PyTypeObject imap_type;
1466 :
1467 : static PyObject *
1468 0 : imap_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1469 : {
1470 : PyObject *it, *iters, *func;
1471 : imapobject *lz;
1472 : Py_ssize_t numargs, i;
1473 :
1474 0 : if (type == &imap_type && !_PyArg_NoKeywords("imap()", kwds))
1475 0 : return NULL;
1476 :
1477 0 : numargs = PyTuple_Size(args);
1478 0 : if (numargs < 2) {
1479 0 : PyErr_SetString(PyExc_TypeError,
1480 : "imap() must have at least two arguments.");
1481 0 : return NULL;
1482 : }
1483 :
1484 0 : iters = PyTuple_New(numargs-1);
1485 0 : if (iters == NULL)
1486 0 : return NULL;
1487 :
1488 0 : for (i=1 ; i<numargs ; i++) {
1489 : /* Get iterator. */
1490 0 : it = PyObject_GetIter(PyTuple_GET_ITEM(args, i));
1491 0 : if (it == NULL) {
1492 0 : Py_DECREF(iters);
1493 0 : return NULL;
1494 : }
1495 0 : PyTuple_SET_ITEM(iters, i-1, it);
1496 : }
1497 :
1498 : /* create imapobject structure */
1499 0 : lz = (imapobject *)type->tp_alloc(type, 0);
1500 0 : if (lz == NULL) {
1501 0 : Py_DECREF(iters);
1502 0 : return NULL;
1503 : }
1504 0 : lz->iters = iters;
1505 0 : func = PyTuple_GET_ITEM(args, 0);
1506 0 : Py_INCREF(func);
1507 0 : lz->func = func;
1508 :
1509 0 : return (PyObject *)lz;
1510 : }
1511 :
1512 : static void
1513 0 : imap_dealloc(imapobject *lz)
1514 : {
1515 0 : PyObject_GC_UnTrack(lz);
1516 0 : Py_XDECREF(lz->iters);
1517 0 : Py_XDECREF(lz->func);
1518 0 : Py_TYPE(lz)->tp_free(lz);
1519 0 : }
1520 :
1521 : static int
1522 0 : imap_traverse(imapobject *lz, visitproc visit, void *arg)
1523 : {
1524 0 : Py_VISIT(lz->iters);
1525 0 : Py_VISIT(lz->func);
1526 0 : return 0;
1527 : }
1528 :
1529 : /*
1530 : imap() is an iterator version of __builtins__.map() except that it does
1531 : not have the None fill-in feature. That was intentionally left out for
1532 : the following reasons:
1533 :
1534 : 1) Itertools are designed to be easily combined and chained together.
1535 : Having all tools stop with the shortest input is a unifying principle
1536 : that makes it easier to combine finite iterators (supplying data) with
1537 : infinite iterators like count() and repeat() (for supplying sequential
1538 : or constant arguments to a function).
1539 :
1540 : 2) In typical use cases for combining itertools, having one finite data
1541 : supplier run out before another is likely to be an error condition which
1542 : should not pass silently by automatically supplying None.
1543 :
1544 : 3) The use cases for automatic None fill-in are rare -- not many functions
1545 : do something useful when a parameter suddenly switches type and becomes
1546 : None.
1547 :
1548 : 4) If a need does arise, it can be met by __builtins__.map() or by
1549 : writing: chain(iterable, repeat(None)).
1550 :
1551 : 5) Similar toolsets in Haskell and SML do not have automatic None fill-in.
1552 : */
1553 :
1554 : static PyObject *
1555 0 : imap_next(imapobject *lz)
1556 : {
1557 : PyObject *val;
1558 : PyObject *argtuple;
1559 : PyObject *result;
1560 : Py_ssize_t numargs, i;
1561 :
1562 0 : numargs = PyTuple_Size(lz->iters);
1563 0 : argtuple = PyTuple_New(numargs);
1564 0 : if (argtuple == NULL)
1565 0 : return NULL;
1566 :
1567 0 : for (i=0 ; i<numargs ; i++) {
1568 0 : val = PyIter_Next(PyTuple_GET_ITEM(lz->iters, i));
1569 0 : if (val == NULL) {
1570 0 : Py_DECREF(argtuple);
1571 0 : return NULL;
1572 : }
1573 0 : PyTuple_SET_ITEM(argtuple, i, val);
1574 : }
1575 0 : if (lz->func == Py_None)
1576 0 : return argtuple;
1577 0 : result = PyObject_Call(lz->func, argtuple, NULL);
1578 0 : Py_DECREF(argtuple);
1579 0 : return result;
1580 : }
1581 :
1582 : PyDoc_STRVAR(imap_doc,
1583 : "imap(func, *iterables) --> imap object\n\
1584 : \n\
1585 : Make an iterator that computes the function using arguments from\n\
1586 : each of the iterables. Like map() except that it returns\n\
1587 : an iterator instead of a list and that it stops when the shortest\n\
1588 : iterable is exhausted instead of filling in None for shorter\n\
1589 : iterables.");
1590 :
1591 : static PyTypeObject imap_type = {
1592 : PyVarObject_HEAD_INIT(NULL, 0)
1593 : "itertools.imap", /* tp_name */
1594 : sizeof(imapobject), /* tp_basicsize */
1595 : 0, /* tp_itemsize */
1596 : /* methods */
1597 : (destructor)imap_dealloc, /* tp_dealloc */
1598 : 0, /* tp_print */
1599 : 0, /* tp_getattr */
1600 : 0, /* tp_setattr */
1601 : 0, /* tp_compare */
1602 : 0, /* tp_repr */
1603 : 0, /* tp_as_number */
1604 : 0, /* tp_as_sequence */
1605 : 0, /* tp_as_mapping */
1606 : 0, /* tp_hash */
1607 : 0, /* tp_call */
1608 : 0, /* tp_str */
1609 : PyObject_GenericGetAttr, /* tp_getattro */
1610 : 0, /* tp_setattro */
1611 : 0, /* tp_as_buffer */
1612 : Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
1613 : Py_TPFLAGS_BASETYPE, /* tp_flags */
1614 : imap_doc, /* tp_doc */
1615 : (traverseproc)imap_traverse, /* tp_traverse */
1616 : 0, /* tp_clear */
1617 : 0, /* tp_richcompare */
1618 : 0, /* tp_weaklistoffset */
1619 : PyObject_SelfIter, /* tp_iter */
1620 : (iternextfunc)imap_next, /* tp_iternext */
1621 : 0, /* tp_methods */
1622 : 0, /* tp_members */
1623 : 0, /* tp_getset */
1624 : 0, /* tp_base */
1625 : 0, /* tp_dict */
1626 : 0, /* tp_descr_get */
1627 : 0, /* tp_descr_set */
1628 : 0, /* tp_dictoffset */
1629 : 0, /* tp_init */
1630 : 0, /* tp_alloc */
1631 : imap_new, /* tp_new */
1632 : PyObject_GC_Del, /* tp_free */
1633 : };
1634 :
1635 :
1636 : /* chain object ************************************************************/
1637 :
1638 : typedef struct {
1639 : PyObject_HEAD
1640 : PyObject *source; /* Iterator over input iterables */
1641 : PyObject *active; /* Currently running input iterator */
1642 : } chainobject;
1643 :
1644 : static PyTypeObject chain_type;
1645 :
1646 : static PyObject *
1647 0 : chain_new_internal(PyTypeObject *type, PyObject *source)
1648 : {
1649 : chainobject *lz;
1650 :
1651 0 : lz = (chainobject *)type->tp_alloc(type, 0);
1652 0 : if (lz == NULL) {
1653 0 : Py_DECREF(source);
1654 0 : return NULL;
1655 : }
1656 :
1657 0 : lz->source = source;
1658 0 : lz->active = NULL;
1659 0 : return (PyObject *)lz;
1660 : }
1661 :
1662 : static PyObject *
1663 0 : chain_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1664 : {
1665 : PyObject *source;
1666 :
1667 0 : if (type == &chain_type && !_PyArg_NoKeywords("chain()", kwds))
1668 0 : return NULL;
1669 :
1670 0 : source = PyObject_GetIter(args);
1671 0 : if (source == NULL)
1672 0 : return NULL;
1673 :
1674 0 : return chain_new_internal(type, source);
1675 : }
1676 :
1677 : static PyObject *
1678 0 : chain_new_from_iterable(PyTypeObject *type, PyObject *arg)
1679 : {
1680 : PyObject *source;
1681 :
1682 0 : source = PyObject_GetIter(arg);
1683 0 : if (source == NULL)
1684 0 : return NULL;
1685 :
1686 0 : return chain_new_internal(type, source);
1687 : }
1688 :
1689 : static void
1690 0 : chain_dealloc(chainobject *lz)
1691 : {
1692 0 : PyObject_GC_UnTrack(lz);
1693 0 : Py_XDECREF(lz->active);
1694 0 : Py_XDECREF(lz->source);
1695 0 : Py_TYPE(lz)->tp_free(lz);
1696 0 : }
1697 :
1698 : static int
1699 0 : chain_traverse(chainobject *lz, visitproc visit, void *arg)
1700 : {
1701 0 : Py_VISIT(lz->source);
1702 0 : Py_VISIT(lz->active);
1703 0 : return 0;
1704 : }
1705 :
1706 : static PyObject *
1707 0 : chain_next(chainobject *lz)
1708 : {
1709 : PyObject *item;
1710 :
1711 0 : if (lz->source == NULL)
1712 0 : return NULL; /* already stopped */
1713 :
1714 0 : if (lz->active == NULL) {
1715 0 : PyObject *iterable = PyIter_Next(lz->source);
1716 0 : if (iterable == NULL) {
1717 0 : Py_CLEAR(lz->source);
1718 0 : return NULL; /* no more input sources */
1719 : }
1720 0 : lz->active = PyObject_GetIter(iterable);
1721 0 : Py_DECREF(iterable);
1722 0 : if (lz->active == NULL) {
1723 0 : Py_CLEAR(lz->source);
1724 0 : return NULL; /* input not iterable */
1725 : }
1726 : }
1727 0 : item = PyIter_Next(lz->active);
1728 0 : if (item != NULL)
1729 0 : return item;
1730 0 : if (PyErr_Occurred()) {
1731 0 : if (PyErr_ExceptionMatches(PyExc_StopIteration))
1732 0 : PyErr_Clear();
1733 : else
1734 0 : return NULL; /* input raised an exception */
1735 : }
1736 0 : Py_CLEAR(lz->active);
1737 0 : return chain_next(lz); /* recurse and use next active */
1738 : }
1739 :
1740 : PyDoc_STRVAR(chain_doc,
1741 : "chain(*iterables) --> chain object\n\
1742 : \n\
1743 : Return a chain object whose .next() method returns elements from the\n\
1744 : first iterable until it is exhausted, then elements from the next\n\
1745 : iterable, until all of the iterables are exhausted.");
1746 :
1747 : PyDoc_STRVAR(chain_from_iterable_doc,
1748 : "chain.from_iterable(iterable) --> chain object\n\
1749 : \n\
1750 : Alternate chain() constructor taking a single iterable argument\n\
1751 : that evaluates lazily.");
1752 :
1753 : static PyMethodDef chain_methods[] = {
1754 : {"from_iterable", (PyCFunction) chain_new_from_iterable, METH_O | METH_CLASS,
1755 : chain_from_iterable_doc},
1756 : {NULL, NULL} /* sentinel */
1757 : };
1758 :
1759 : static PyTypeObject chain_type = {
1760 : PyVarObject_HEAD_INIT(NULL, 0)
1761 : "itertools.chain", /* tp_name */
1762 : sizeof(chainobject), /* tp_basicsize */
1763 : 0, /* tp_itemsize */
1764 : /* methods */
1765 : (destructor)chain_dealloc, /* tp_dealloc */
1766 : 0, /* tp_print */
1767 : 0, /* tp_getattr */
1768 : 0, /* tp_setattr */
1769 : 0, /* tp_compare */
1770 : 0, /* tp_repr */
1771 : 0, /* tp_as_number */
1772 : 0, /* tp_as_sequence */
1773 : 0, /* tp_as_mapping */
1774 : 0, /* tp_hash */
1775 : 0, /* tp_call */
1776 : 0, /* tp_str */
1777 : PyObject_GenericGetAttr, /* tp_getattro */
1778 : 0, /* tp_setattro */
1779 : 0, /* tp_as_buffer */
1780 : Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
1781 : Py_TPFLAGS_BASETYPE, /* tp_flags */
1782 : chain_doc, /* tp_doc */
1783 : (traverseproc)chain_traverse, /* tp_traverse */
1784 : 0, /* tp_clear */
1785 : 0, /* tp_richcompare */
1786 : 0, /* tp_weaklistoffset */
1787 : PyObject_SelfIter, /* tp_iter */
1788 : (iternextfunc)chain_next, /* tp_iternext */
1789 : chain_methods, /* tp_methods */
1790 : 0, /* tp_members */
1791 : 0, /* tp_getset */
1792 : 0, /* tp_base */
1793 : 0, /* tp_dict */
1794 : 0, /* tp_descr_get */
1795 : 0, /* tp_descr_set */
1796 : 0, /* tp_dictoffset */
1797 : 0, /* tp_init */
1798 : 0, /* tp_alloc */
1799 : chain_new, /* tp_new */
1800 : PyObject_GC_Del, /* tp_free */
1801 : };
1802 :
1803 :
1804 : /* product object ************************************************************/
1805 :
1806 : typedef struct {
1807 : PyObject_HEAD
1808 : PyObject *pools; /* tuple of pool tuples */
1809 : Py_ssize_t *indices; /* one index per pool */
1810 : PyObject *result; /* most recently returned result tuple */
1811 : int stopped; /* set to 1 when the product iterator is exhausted */
1812 : } productobject;
1813 :
1814 : static PyTypeObject product_type;
1815 :
1816 : static PyObject *
1817 0 : product_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1818 : {
1819 : productobject *lz;
1820 0 : Py_ssize_t nargs, npools, repeat=1;
1821 0 : PyObject *pools = NULL;
1822 0 : Py_ssize_t *indices = NULL;
1823 : Py_ssize_t i;
1824 :
1825 0 : if (kwds != NULL) {
1826 0 : char *kwlist[] = {"repeat", 0};
1827 0 : PyObject *tmpargs = PyTuple_New(0);
1828 0 : if (tmpargs == NULL)
1829 0 : return NULL;
1830 0 : if (!PyArg_ParseTupleAndKeywords(tmpargs, kwds, "|n:product", kwlist, &repeat)) {
1831 0 : Py_DECREF(tmpargs);
1832 0 : return NULL;
1833 : }
1834 0 : Py_DECREF(tmpargs);
1835 0 : if (repeat < 0) {
1836 0 : PyErr_SetString(PyExc_ValueError,
1837 : "repeat argument cannot be negative");
1838 0 : return NULL;
1839 : }
1840 : }
1841 :
1842 : assert(PyTuple_CheckExact(args));
1843 0 : if (repeat == 0) {
1844 0 : nargs = 0;
1845 : } else {
1846 0 : nargs = PyTuple_GET_SIZE(args);
1847 0 : if ((size_t)nargs > PY_SSIZE_T_MAX/sizeof(Py_ssize_t)/repeat) {
1848 0 : PyErr_SetString(PyExc_OverflowError, "repeat argument too large");
1849 0 : return NULL;
1850 : }
1851 : }
1852 0 : npools = nargs * repeat;
1853 :
1854 0 : indices = PyMem_New(Py_ssize_t, npools);
1855 0 : if (indices == NULL) {
1856 0 : PyErr_NoMemory();
1857 0 : goto error;
1858 : }
1859 :
1860 0 : pools = PyTuple_New(npools);
1861 0 : if (pools == NULL)
1862 0 : goto error;
1863 :
1864 0 : for (i=0; i < nargs ; ++i) {
1865 0 : PyObject *item = PyTuple_GET_ITEM(args, i);
1866 0 : PyObject *pool = PySequence_Tuple(item);
1867 0 : if (pool == NULL)
1868 0 : goto error;
1869 0 : PyTuple_SET_ITEM(pools, i, pool);
1870 0 : indices[i] = 0;
1871 : }
1872 0 : for ( ; i < npools; ++i) {
1873 0 : PyObject *pool = PyTuple_GET_ITEM(pools, i - nargs);
1874 0 : Py_INCREF(pool);
1875 0 : PyTuple_SET_ITEM(pools, i, pool);
1876 0 : indices[i] = 0;
1877 : }
1878 :
1879 : /* create productobject structure */
1880 0 : lz = (productobject *)type->tp_alloc(type, 0);
1881 0 : if (lz == NULL)
1882 0 : goto error;
1883 :
1884 0 : lz->pools = pools;
1885 0 : lz->indices = indices;
1886 0 : lz->result = NULL;
1887 0 : lz->stopped = 0;
1888 :
1889 0 : return (PyObject *)lz;
1890 :
1891 : error:
1892 0 : if (indices != NULL)
1893 0 : PyMem_Free(indices);
1894 0 : Py_XDECREF(pools);
1895 0 : return NULL;
1896 : }
1897 :
1898 : static void
1899 0 : product_dealloc(productobject *lz)
1900 : {
1901 0 : PyObject_GC_UnTrack(lz);
1902 0 : Py_XDECREF(lz->pools);
1903 0 : Py_XDECREF(lz->result);
1904 0 : if (lz->indices != NULL)
1905 0 : PyMem_Free(lz->indices);
1906 0 : Py_TYPE(lz)->tp_free(lz);
1907 0 : }
1908 :
1909 : static int
1910 0 : product_traverse(productobject *lz, visitproc visit, void *arg)
1911 : {
1912 0 : Py_VISIT(lz->pools);
1913 0 : Py_VISIT(lz->result);
1914 0 : return 0;
1915 : }
1916 :
1917 : static PyObject *
1918 0 : product_next(productobject *lz)
1919 : {
1920 : PyObject *pool;
1921 : PyObject *elem;
1922 : PyObject *oldelem;
1923 0 : PyObject *pools = lz->pools;
1924 0 : PyObject *result = lz->result;
1925 0 : Py_ssize_t npools = PyTuple_GET_SIZE(pools);
1926 : Py_ssize_t i;
1927 :
1928 0 : if (lz->stopped)
1929 0 : return NULL;
1930 :
1931 0 : if (result == NULL) {
1932 : /* On the first pass, return an initial tuple filled with the
1933 : first element from each pool. */
1934 0 : result = PyTuple_New(npools);
1935 0 : if (result == NULL)
1936 0 : goto empty;
1937 0 : lz->result = result;
1938 0 : for (i=0; i < npools; i++) {
1939 0 : pool = PyTuple_GET_ITEM(pools, i);
1940 0 : if (PyTuple_GET_SIZE(pool) == 0)
1941 0 : goto empty;
1942 0 : elem = PyTuple_GET_ITEM(pool, 0);
1943 0 : Py_INCREF(elem);
1944 0 : PyTuple_SET_ITEM(result, i, elem);
1945 : }
1946 : } else {
1947 0 : Py_ssize_t *indices = lz->indices;
1948 :
1949 : /* Copy the previous result tuple or re-use it if available */
1950 0 : if (Py_REFCNT(result) > 1) {
1951 0 : PyObject *old_result = result;
1952 0 : result = PyTuple_New(npools);
1953 0 : if (result == NULL)
1954 0 : goto empty;
1955 0 : lz->result = result;
1956 0 : for (i=0; i < npools; i++) {
1957 0 : elem = PyTuple_GET_ITEM(old_result, i);
1958 0 : Py_INCREF(elem);
1959 0 : PyTuple_SET_ITEM(result, i, elem);
1960 : }
1961 0 : Py_DECREF(old_result);
1962 : }
1963 : /* Now, we've got the only copy so we can update it in-place */
1964 : assert (npools==0 || Py_REFCNT(result) == 1);
1965 :
1966 : /* Update the pool indices right-to-left. Only advance to the
1967 : next pool when the previous one rolls-over */
1968 0 : for (i=npools-1 ; i >= 0 ; i--) {
1969 0 : pool = PyTuple_GET_ITEM(pools, i);
1970 0 : indices[i]++;
1971 0 : if (indices[i] == PyTuple_GET_SIZE(pool)) {
1972 : /* Roll-over and advance to next pool */
1973 0 : indices[i] = 0;
1974 0 : elem = PyTuple_GET_ITEM(pool, 0);
1975 0 : Py_INCREF(elem);
1976 0 : oldelem = PyTuple_GET_ITEM(result, i);
1977 0 : PyTuple_SET_ITEM(result, i, elem);
1978 0 : Py_DECREF(oldelem);
1979 : } else {
1980 : /* No rollover. Just increment and stop here. */
1981 0 : elem = PyTuple_GET_ITEM(pool, indices[i]);
1982 0 : Py_INCREF(elem);
1983 0 : oldelem = PyTuple_GET_ITEM(result, i);
1984 0 : PyTuple_SET_ITEM(result, i, elem);
1985 0 : Py_DECREF(oldelem);
1986 0 : break;
1987 : }
1988 : }
1989 :
1990 : /* If i is negative, then the indices have all rolled-over
1991 : and we're done. */
1992 0 : if (i < 0)
1993 0 : goto empty;
1994 : }
1995 :
1996 0 : Py_INCREF(result);
1997 0 : return result;
1998 :
1999 : empty:
2000 0 : lz->stopped = 1;
2001 0 : return NULL;
2002 : }
2003 :
2004 : PyDoc_STRVAR(product_doc,
2005 : "product(*iterables) --> product object\n\
2006 : \n\
2007 : Cartesian product of input iterables. Equivalent to nested for-loops.\n\n\
2008 : For example, product(A, B) returns the same as: ((x,y) for x in A for y in B).\n\
2009 : The leftmost iterators are in the outermost for-loop, so the output tuples\n\
2010 : cycle in a manner similar to an odometer (with the rightmost element changing\n\
2011 : on every iteration).\n\n\
2012 : To compute the product of an iterable with itself, specify the number\n\
2013 : of repetitions with the optional repeat keyword argument. For example,\n\
2014 : product(A, repeat=4) means the same as product(A, A, A, A).\n\n\
2015 : product('ab', range(3)) --> ('a',0) ('a',1) ('a',2) ('b',0) ('b',1) ('b',2)\n\
2016 : product((0,1), (0,1), (0,1)) --> (0,0,0) (0,0,1) (0,1,0) (0,1,1) (1,0,0) ...");
2017 :
2018 : static PyTypeObject product_type = {
2019 : PyVarObject_HEAD_INIT(NULL, 0)
2020 : "itertools.product", /* tp_name */
2021 : sizeof(productobject), /* tp_basicsize */
2022 : 0, /* tp_itemsize */
2023 : /* methods */
2024 : (destructor)product_dealloc, /* tp_dealloc */
2025 : 0, /* tp_print */
2026 : 0, /* tp_getattr */
2027 : 0, /* tp_setattr */
2028 : 0, /* tp_compare */
2029 : 0, /* tp_repr */
2030 : 0, /* tp_as_number */
2031 : 0, /* tp_as_sequence */
2032 : 0, /* tp_as_mapping */
2033 : 0, /* tp_hash */
2034 : 0, /* tp_call */
2035 : 0, /* tp_str */
2036 : PyObject_GenericGetAttr, /* tp_getattro */
2037 : 0, /* tp_setattro */
2038 : 0, /* tp_as_buffer */
2039 : Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
2040 : Py_TPFLAGS_BASETYPE, /* tp_flags */
2041 : product_doc, /* tp_doc */
2042 : (traverseproc)product_traverse, /* tp_traverse */
2043 : 0, /* tp_clear */
2044 : 0, /* tp_richcompare */
2045 : 0, /* tp_weaklistoffset */
2046 : PyObject_SelfIter, /* tp_iter */
2047 : (iternextfunc)product_next, /* tp_iternext */
2048 : 0, /* tp_methods */
2049 : 0, /* tp_members */
2050 : 0, /* tp_getset */
2051 : 0, /* tp_base */
2052 : 0, /* tp_dict */
2053 : 0, /* tp_descr_get */
2054 : 0, /* tp_descr_set */
2055 : 0, /* tp_dictoffset */
2056 : 0, /* tp_init */
2057 : 0, /* tp_alloc */
2058 : product_new, /* tp_new */
2059 : PyObject_GC_Del, /* tp_free */
2060 : };
2061 :
2062 :
2063 : /* combinations object ************************************************************/
2064 :
2065 : typedef struct {
2066 : PyObject_HEAD
2067 : PyObject *pool; /* input converted to a tuple */
2068 : Py_ssize_t *indices; /* one index per result element */
2069 : PyObject *result; /* most recently returned result tuple */
2070 : Py_ssize_t r; /* size of result tuple */
2071 : int stopped; /* set to 1 when the combinations iterator is exhausted */
2072 : } combinationsobject;
2073 :
2074 : static PyTypeObject combinations_type;
2075 :
2076 : static PyObject *
2077 0 : combinations_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
2078 : {
2079 : combinationsobject *co;
2080 : Py_ssize_t n;
2081 : Py_ssize_t r;
2082 0 : PyObject *pool = NULL;
2083 0 : PyObject *iterable = NULL;
2084 0 : Py_ssize_t *indices = NULL;
2085 : Py_ssize_t i;
2086 : static char *kwargs[] = {"iterable", "r", NULL};
2087 :
2088 0 : if (!PyArg_ParseTupleAndKeywords(args, kwds, "On:combinations", kwargs,
2089 : &iterable, &r))
2090 0 : return NULL;
2091 :
2092 0 : pool = PySequence_Tuple(iterable);
2093 0 : if (pool == NULL)
2094 0 : goto error;
2095 0 : n = PyTuple_GET_SIZE(pool);
2096 0 : if (r < 0) {
2097 0 : PyErr_SetString(PyExc_ValueError, "r must be non-negative");
2098 0 : goto error;
2099 : }
2100 :
2101 0 : indices = PyMem_New(Py_ssize_t, r);
2102 0 : if (indices == NULL) {
2103 0 : PyErr_NoMemory();
2104 0 : goto error;
2105 : }
2106 :
2107 0 : for (i=0 ; i<r ; i++)
2108 0 : indices[i] = i;
2109 :
2110 : /* create combinationsobject structure */
2111 0 : co = (combinationsobject *)type->tp_alloc(type, 0);
2112 0 : if (co == NULL)
2113 0 : goto error;
2114 :
2115 0 : co->pool = pool;
2116 0 : co->indices = indices;
2117 0 : co->result = NULL;
2118 0 : co->r = r;
2119 0 : co->stopped = r > n ? 1 : 0;
2120 :
2121 0 : return (PyObject *)co;
2122 :
2123 : error:
2124 0 : if (indices != NULL)
2125 0 : PyMem_Free(indices);
2126 0 : Py_XDECREF(pool);
2127 0 : return NULL;
2128 : }
2129 :
2130 : static void
2131 0 : combinations_dealloc(combinationsobject *co)
2132 : {
2133 0 : PyObject_GC_UnTrack(co);
2134 0 : Py_XDECREF(co->pool);
2135 0 : Py_XDECREF(co->result);
2136 0 : if (co->indices != NULL)
2137 0 : PyMem_Free(co->indices);
2138 0 : Py_TYPE(co)->tp_free(co);
2139 0 : }
2140 :
2141 : static int
2142 0 : combinations_traverse(combinationsobject *co, visitproc visit, void *arg)
2143 : {
2144 0 : Py_VISIT(co->pool);
2145 0 : Py_VISIT(co->result);
2146 0 : return 0;
2147 : }
2148 :
2149 : static PyObject *
2150 0 : combinations_next(combinationsobject *co)
2151 : {
2152 : PyObject *elem;
2153 : PyObject *oldelem;
2154 0 : PyObject *pool = co->pool;
2155 0 : Py_ssize_t *indices = co->indices;
2156 0 : PyObject *result = co->result;
2157 0 : Py_ssize_t n = PyTuple_GET_SIZE(pool);
2158 0 : Py_ssize_t r = co->r;
2159 : Py_ssize_t i, j, index;
2160 :
2161 0 : if (co->stopped)
2162 0 : return NULL;
2163 :
2164 0 : if (result == NULL) {
2165 : /* On the first pass, initialize result tuple using the indices */
2166 0 : result = PyTuple_New(r);
2167 0 : if (result == NULL)
2168 0 : goto empty;
2169 0 : co->result = result;
2170 0 : for (i=0; i<r ; i++) {
2171 0 : index = indices[i];
2172 0 : elem = PyTuple_GET_ITEM(pool, index);
2173 0 : Py_INCREF(elem);
2174 0 : PyTuple_SET_ITEM(result, i, elem);
2175 : }
2176 : } else {
2177 : /* Copy the previous result tuple or re-use it if available */
2178 0 : if (Py_REFCNT(result) > 1) {
2179 0 : PyObject *old_result = result;
2180 0 : result = PyTuple_New(r);
2181 0 : if (result == NULL)
2182 0 : goto empty;
2183 0 : co->result = result;
2184 0 : for (i=0; i<r ; i++) {
2185 0 : elem = PyTuple_GET_ITEM(old_result, i);
2186 0 : Py_INCREF(elem);
2187 0 : PyTuple_SET_ITEM(result, i, elem);
2188 : }
2189 0 : Py_DECREF(old_result);
2190 : }
2191 : /* Now, we've got the only copy so we can update it in-place
2192 : * CPython's empty tuple is a singleton and cached in
2193 : * PyTuple's freelist.
2194 : */
2195 : assert(r == 0 || Py_REFCNT(result) == 1);
2196 :
2197 : /* Scan indices right-to-left until finding one that is not
2198 : at its maximum (i + n - r). */
2199 0 : for (i=r-1 ; i >= 0 && indices[i] == i+n-r ; i--)
2200 : ;
2201 :
2202 : /* If i is negative, then the indices are all at
2203 : their maximum value and we're done. */
2204 0 : if (i < 0)
2205 0 : goto empty;
2206 :
2207 : /* Increment the current index which we know is not at its
2208 : maximum. Then move back to the right setting each index
2209 : to its lowest possible value (one higher than the index
2210 : to its left -- this maintains the sort order invariant). */
2211 0 : indices[i]++;
2212 0 : for (j=i+1 ; j<r ; j++)
2213 0 : indices[j] = indices[j-1] + 1;
2214 :
2215 : /* Update the result tuple for the new indices
2216 : starting with i, the leftmost index that changed */
2217 0 : for ( ; i<r ; i++) {
2218 0 : index = indices[i];
2219 0 : elem = PyTuple_GET_ITEM(pool, index);
2220 0 : Py_INCREF(elem);
2221 0 : oldelem = PyTuple_GET_ITEM(result, i);
2222 0 : PyTuple_SET_ITEM(result, i, elem);
2223 0 : Py_DECREF(oldelem);
2224 : }
2225 : }
2226 :
2227 0 : Py_INCREF(result);
2228 0 : return result;
2229 :
2230 : empty:
2231 0 : co->stopped = 1;
2232 0 : return NULL;
2233 : }
2234 :
2235 : PyDoc_STRVAR(combinations_doc,
2236 : "combinations(iterable, r) --> combinations object\n\
2237 : \n\
2238 : Return successive r-length combinations of elements in the iterable.\n\n\
2239 : combinations(range(4), 3) --> (0,1,2), (0,1,3), (0,2,3), (1,2,3)");
2240 :
2241 : static PyTypeObject combinations_type = {
2242 : PyVarObject_HEAD_INIT(NULL, 0)
2243 : "itertools.combinations", /* tp_name */
2244 : sizeof(combinationsobject), /* tp_basicsize */
2245 : 0, /* tp_itemsize */
2246 : /* methods */
2247 : (destructor)combinations_dealloc, /* tp_dealloc */
2248 : 0, /* tp_print */
2249 : 0, /* tp_getattr */
2250 : 0, /* tp_setattr */
2251 : 0, /* tp_compare */
2252 : 0, /* tp_repr */
2253 : 0, /* tp_as_number */
2254 : 0, /* tp_as_sequence */
2255 : 0, /* tp_as_mapping */
2256 : 0, /* tp_hash */
2257 : 0, /* tp_call */
2258 : 0, /* tp_str */
2259 : PyObject_GenericGetAttr, /* tp_getattro */
2260 : 0, /* tp_setattro */
2261 : 0, /* tp_as_buffer */
2262 : Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
2263 : Py_TPFLAGS_BASETYPE, /* tp_flags */
2264 : combinations_doc, /* tp_doc */
2265 : (traverseproc)combinations_traverse, /* tp_traverse */
2266 : 0, /* tp_clear */
2267 : 0, /* tp_richcompare */
2268 : 0, /* tp_weaklistoffset */
2269 : PyObject_SelfIter, /* tp_iter */
2270 : (iternextfunc)combinations_next, /* tp_iternext */
2271 : 0, /* tp_methods */
2272 : 0, /* tp_members */
2273 : 0, /* tp_getset */
2274 : 0, /* tp_base */
2275 : 0, /* tp_dict */
2276 : 0, /* tp_descr_get */
2277 : 0, /* tp_descr_set */
2278 : 0, /* tp_dictoffset */
2279 : 0, /* tp_init */
2280 : 0, /* tp_alloc */
2281 : combinations_new, /* tp_new */
2282 : PyObject_GC_Del, /* tp_free */
2283 : };
2284 :
2285 :
2286 : /* combinations with replacement object *******************************************/
2287 :
2288 : /* Equivalent to:
2289 :
2290 : def combinations_with_replacement(iterable, r):
2291 : "combinations_with_replacement('ABC', 2) --> AA AB AC BB BC CC"
2292 : # number items returned: (n+r-1)! / r! / (n-1)!
2293 : pool = tuple(iterable)
2294 : n = len(pool)
2295 : indices = [0] * r
2296 : yield tuple(pool[i] for i in indices)
2297 : while 1:
2298 : for i in reversed(range(r)):
2299 : if indices[i] != n - 1:
2300 : break
2301 : else:
2302 : return
2303 : indices[i:] = [indices[i] + 1] * (r - i)
2304 : yield tuple(pool[i] for i in indices)
2305 :
2306 : def combinations_with_replacement2(iterable, r):
2307 : 'Alternate version that filters from product()'
2308 : pool = tuple(iterable)
2309 : n = len(pool)
2310 : for indices in product(range(n), repeat=r):
2311 : if sorted(indices) == list(indices):
2312 : yield tuple(pool[i] for i in indices)
2313 : */
2314 : typedef struct {
2315 : PyObject_HEAD
2316 : PyObject *pool; /* input converted to a tuple */
2317 : Py_ssize_t *indices; /* one index per result element */
2318 : PyObject *result; /* most recently returned result tuple */
2319 : Py_ssize_t r; /* size of result tuple */
2320 : int stopped; /* set to 1 when the cwr iterator is exhausted */
2321 : } cwrobject;
2322 :
2323 : static PyTypeObject cwr_type;
2324 :
2325 : static PyObject *
2326 0 : cwr_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
2327 : {
2328 : cwrobject *co;
2329 : Py_ssize_t n;
2330 : Py_ssize_t r;
2331 0 : PyObject *pool = NULL;
2332 0 : PyObject *iterable = NULL;
2333 0 : Py_ssize_t *indices = NULL;
2334 : Py_ssize_t i;
2335 : static char *kwargs[] = {"iterable", "r", NULL};
2336 :
2337 0 : if (!PyArg_ParseTupleAndKeywords(args, kwds, "On:combinations_with_replacement", kwargs,
2338 : &iterable, &r))
2339 0 : return NULL;
2340 :
2341 0 : pool = PySequence_Tuple(iterable);
2342 0 : if (pool == NULL)
2343 0 : goto error;
2344 0 : n = PyTuple_GET_SIZE(pool);
2345 0 : if (r < 0) {
2346 0 : PyErr_SetString(PyExc_ValueError, "r must be non-negative");
2347 0 : goto error;
2348 : }
2349 :
2350 0 : indices = PyMem_New(Py_ssize_t, r);
2351 0 : if (indices == NULL) {
2352 0 : PyErr_NoMemory();
2353 0 : goto error;
2354 : }
2355 :
2356 0 : for (i=0 ; i<r ; i++)
2357 0 : indices[i] = 0;
2358 :
2359 : /* create cwrobject structure */
2360 0 : co = (cwrobject *)type->tp_alloc(type, 0);
2361 0 : if (co == NULL)
2362 0 : goto error;
2363 :
2364 0 : co->pool = pool;
2365 0 : co->indices = indices;
2366 0 : co->result = NULL;
2367 0 : co->r = r;
2368 0 : co->stopped = !n && r;
2369 :
2370 0 : return (PyObject *)co;
2371 :
2372 : error:
2373 0 : if (indices != NULL)
2374 0 : PyMem_Free(indices);
2375 0 : Py_XDECREF(pool);
2376 0 : return NULL;
2377 : }
2378 :
2379 : static void
2380 0 : cwr_dealloc(cwrobject *co)
2381 : {
2382 0 : PyObject_GC_UnTrack(co);
2383 0 : Py_XDECREF(co->pool);
2384 0 : Py_XDECREF(co->result);
2385 0 : if (co->indices != NULL)
2386 0 : PyMem_Free(co->indices);
2387 0 : Py_TYPE(co)->tp_free(co);
2388 0 : }
2389 :
2390 : static int
2391 0 : cwr_traverse(cwrobject *co, visitproc visit, void *arg)
2392 : {
2393 0 : Py_VISIT(co->pool);
2394 0 : Py_VISIT(co->result);
2395 0 : return 0;
2396 : }
2397 :
2398 : static PyObject *
2399 0 : cwr_next(cwrobject *co)
2400 : {
2401 : PyObject *elem;
2402 : PyObject *oldelem;
2403 0 : PyObject *pool = co->pool;
2404 0 : Py_ssize_t *indices = co->indices;
2405 0 : PyObject *result = co->result;
2406 0 : Py_ssize_t n = PyTuple_GET_SIZE(pool);
2407 0 : Py_ssize_t r = co->r;
2408 : Py_ssize_t i, j, index;
2409 :
2410 0 : if (co->stopped)
2411 0 : return NULL;
2412 :
2413 0 : if (result == NULL) {
2414 : /* On the first pass, initialize result tuple using the indices */
2415 0 : result = PyTuple_New(r);
2416 0 : if (result == NULL)
2417 0 : goto empty;
2418 0 : co->result = result;
2419 0 : for (i=0; i<r ; i++) {
2420 0 : index = indices[i];
2421 0 : elem = PyTuple_GET_ITEM(pool, index);
2422 0 : Py_INCREF(elem);
2423 0 : PyTuple_SET_ITEM(result, i, elem);
2424 : }
2425 : } else {
2426 : /* Copy the previous result tuple or re-use it if available */
2427 0 : if (Py_REFCNT(result) > 1) {
2428 0 : PyObject *old_result = result;
2429 0 : result = PyTuple_New(r);
2430 0 : if (result == NULL)
2431 0 : goto empty;
2432 0 : co->result = result;
2433 0 : for (i=0; i<r ; i++) {
2434 0 : elem = PyTuple_GET_ITEM(old_result, i);
2435 0 : Py_INCREF(elem);
2436 0 : PyTuple_SET_ITEM(result, i, elem);
2437 : }
2438 0 : Py_DECREF(old_result);
2439 : }
2440 : /* Now, we've got the only copy so we can update it in-place CPython's
2441 : empty tuple is a singleton and cached in PyTuple's freelist. */
2442 : assert(r == 0 || Py_REFCNT(result) == 1);
2443 :
2444 : /* Scan indices right-to-left until finding one that is not
2445 : * at its maximum (n-1). */
2446 0 : for (i=r-1 ; i >= 0 && indices[i] == n-1; i--)
2447 : ;
2448 :
2449 : /* If i is negative, then the indices are all at
2450 : their maximum value and we're done. */
2451 0 : if (i < 0)
2452 0 : goto empty;
2453 :
2454 : /* Increment the current index which we know is not at its
2455 : maximum. Then set all to the right to the same value. */
2456 0 : indices[i]++;
2457 0 : for (j=i+1 ; j<r ; j++)
2458 0 : indices[j] = indices[j-1];
2459 :
2460 : /* Update the result tuple for the new indices
2461 : starting with i, the leftmost index that changed */
2462 0 : for ( ; i<r ; i++) {
2463 0 : index = indices[i];
2464 0 : elem = PyTuple_GET_ITEM(pool, index);
2465 0 : Py_INCREF(elem);
2466 0 : oldelem = PyTuple_GET_ITEM(result, i);
2467 0 : PyTuple_SET_ITEM(result, i, elem);
2468 0 : Py_DECREF(oldelem);
2469 : }
2470 : }
2471 :
2472 0 : Py_INCREF(result);
2473 0 : return result;
2474 :
2475 : empty:
2476 0 : co->stopped = 1;
2477 0 : return NULL;
2478 : }
2479 :
2480 : PyDoc_STRVAR(cwr_doc,
2481 : "combinations_with_replacement(iterable, r) --> combinations_with_replacement object\n\
2482 : \n\
2483 : Return successive r-length combinations of elements in the iterable\n\
2484 : allowing individual elements to have successive repeats.\n\
2485 : combinations_with_replacement('ABC', 2) --> AA AB AC BB BC CC");
2486 :
2487 : static PyTypeObject cwr_type = {
2488 : PyVarObject_HEAD_INIT(NULL, 0)
2489 : "itertools.combinations_with_replacement", /* tp_name */
2490 : sizeof(cwrobject), /* tp_basicsize */
2491 : 0, /* tp_itemsize */
2492 : /* methods */
2493 : (destructor)cwr_dealloc, /* tp_dealloc */
2494 : 0, /* tp_print */
2495 : 0, /* tp_getattr */
2496 : 0, /* tp_setattr */
2497 : 0, /* tp_compare */
2498 : 0, /* tp_repr */
2499 : 0, /* tp_as_number */
2500 : 0, /* tp_as_sequence */
2501 : 0, /* tp_as_mapping */
2502 : 0, /* tp_hash */
2503 : 0, /* tp_call */
2504 : 0, /* tp_str */
2505 : PyObject_GenericGetAttr, /* tp_getattro */
2506 : 0, /* tp_setattro */
2507 : 0, /* tp_as_buffer */
2508 : Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
2509 : Py_TPFLAGS_BASETYPE, /* tp_flags */
2510 : cwr_doc, /* tp_doc */
2511 : (traverseproc)cwr_traverse, /* tp_traverse */
2512 : 0, /* tp_clear */
2513 : 0, /* tp_richcompare */
2514 : 0, /* tp_weaklistoffset */
2515 : PyObject_SelfIter, /* tp_iter */
2516 : (iternextfunc)cwr_next, /* tp_iternext */
2517 : 0, /* tp_methods */
2518 : 0, /* tp_members */
2519 : 0, /* tp_getset */
2520 : 0, /* tp_base */
2521 : 0, /* tp_dict */
2522 : 0, /* tp_descr_get */
2523 : 0, /* tp_descr_set */
2524 : 0, /* tp_dictoffset */
2525 : 0, /* tp_init */
2526 : 0, /* tp_alloc */
2527 : cwr_new, /* tp_new */
2528 : PyObject_GC_Del, /* tp_free */
2529 : };
2530 :
2531 :
2532 : /* permutations object ************************************************************
2533 :
2534 : def permutations(iterable, r=None):
2535 : 'permutations(range(3), 2) --> (0,1) (0,2) (1,0) (1,2) (2,0) (2,1)'
2536 : pool = tuple(iterable)
2537 : n = len(pool)
2538 : r = n if r is None else r
2539 : indices = range(n)
2540 : cycles = range(n-r+1, n+1)[::-1]
2541 : yield tuple(pool[i] for i in indices[:r])
2542 : while n:
2543 : for i in reversed(range(r)):
2544 : cycles[i] -= 1
2545 : if cycles[i] == 0:
2546 : indices[i:] = indices[i+1:] + indices[i:i+1]
2547 : cycles[i] = n - i
2548 : else:
2549 : j = cycles[i]
2550 : indices[i], indices[-j] = indices[-j], indices[i]
2551 : yield tuple(pool[i] for i in indices[:r])
2552 : break
2553 : else:
2554 : return
2555 : */
2556 :
2557 : typedef struct {
2558 : PyObject_HEAD
2559 : PyObject *pool; /* input converted to a tuple */
2560 : Py_ssize_t *indices; /* one index per element in the pool */
2561 : Py_ssize_t *cycles; /* one rollover counter per element in the result */
2562 : PyObject *result; /* most recently returned result tuple */
2563 : Py_ssize_t r; /* size of result tuple */
2564 : int stopped; /* set to 1 when the permutations iterator is exhausted */
2565 : } permutationsobject;
2566 :
2567 : static PyTypeObject permutations_type;
2568 :
2569 : static PyObject *
2570 0 : permutations_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
2571 : {
2572 : permutationsobject *po;
2573 : Py_ssize_t n;
2574 : Py_ssize_t r;
2575 0 : PyObject *robj = Py_None;
2576 0 : PyObject *pool = NULL;
2577 0 : PyObject *iterable = NULL;
2578 0 : Py_ssize_t *indices = NULL;
2579 0 : Py_ssize_t *cycles = NULL;
2580 : Py_ssize_t i;
2581 : static char *kwargs[] = {"iterable", "r", NULL};
2582 :
2583 0 : if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|O:permutations", kwargs,
2584 : &iterable, &robj))
2585 0 : return NULL;
2586 :
2587 0 : pool = PySequence_Tuple(iterable);
2588 0 : if (pool == NULL)
2589 0 : goto error;
2590 0 : n = PyTuple_GET_SIZE(pool);
2591 :
2592 0 : r = n;
2593 0 : if (robj != Py_None) {
2594 0 : r = PyInt_AsSsize_t(robj);
2595 0 : if (r == -1 && PyErr_Occurred())
2596 0 : goto error;
2597 : }
2598 0 : if (r < 0) {
2599 0 : PyErr_SetString(PyExc_ValueError, "r must be non-negative");
2600 0 : goto error;
2601 : }
2602 :
2603 0 : indices = PyMem_New(Py_ssize_t, n);
2604 0 : cycles = PyMem_New(Py_ssize_t, r);
2605 0 : if (indices == NULL || cycles == NULL) {
2606 0 : PyErr_NoMemory();
2607 0 : goto error;
2608 : }
2609 :
2610 0 : for (i=0 ; i<n ; i++)
2611 0 : indices[i] = i;
2612 0 : for (i=0 ; i<r ; i++)
2613 0 : cycles[i] = n - i;
2614 :
2615 : /* create permutationsobject structure */
2616 0 : po = (permutationsobject *)type->tp_alloc(type, 0);
2617 0 : if (po == NULL)
2618 0 : goto error;
2619 :
2620 0 : po->pool = pool;
2621 0 : po->indices = indices;
2622 0 : po->cycles = cycles;
2623 0 : po->result = NULL;
2624 0 : po->r = r;
2625 0 : po->stopped = r > n ? 1 : 0;
2626 :
2627 0 : return (PyObject *)po;
2628 :
2629 : error:
2630 0 : if (indices != NULL)
2631 0 : PyMem_Free(indices);
2632 0 : if (cycles != NULL)
2633 0 : PyMem_Free(cycles);
2634 0 : Py_XDECREF(pool);
2635 0 : return NULL;
2636 : }
2637 :
2638 : static void
2639 0 : permutations_dealloc(permutationsobject *po)
2640 : {
2641 0 : PyObject_GC_UnTrack(po);
2642 0 : Py_XDECREF(po->pool);
2643 0 : Py_XDECREF(po->result);
2644 0 : PyMem_Free(po->indices);
2645 0 : PyMem_Free(po->cycles);
2646 0 : Py_TYPE(po)->tp_free(po);
2647 0 : }
2648 :
2649 : static int
2650 0 : permutations_traverse(permutationsobject *po, visitproc visit, void *arg)
2651 : {
2652 0 : Py_VISIT(po->pool);
2653 0 : Py_VISIT(po->result);
2654 0 : return 0;
2655 : }
2656 :
2657 : static PyObject *
2658 0 : permutations_next(permutationsobject *po)
2659 : {
2660 : PyObject *elem;
2661 : PyObject *oldelem;
2662 0 : PyObject *pool = po->pool;
2663 0 : Py_ssize_t *indices = po->indices;
2664 0 : Py_ssize_t *cycles = po->cycles;
2665 0 : PyObject *result = po->result;
2666 0 : Py_ssize_t n = PyTuple_GET_SIZE(pool);
2667 0 : Py_ssize_t r = po->r;
2668 : Py_ssize_t i, j, k, index;
2669 :
2670 0 : if (po->stopped)
2671 0 : return NULL;
2672 :
2673 0 : if (result == NULL) {
2674 : /* On the first pass, initialize result tuple using the indices */
2675 0 : result = PyTuple_New(r);
2676 0 : if (result == NULL)
2677 0 : goto empty;
2678 0 : po->result = result;
2679 0 : for (i=0; i<r ; i++) {
2680 0 : index = indices[i];
2681 0 : elem = PyTuple_GET_ITEM(pool, index);
2682 0 : Py_INCREF(elem);
2683 0 : PyTuple_SET_ITEM(result, i, elem);
2684 : }
2685 : } else {
2686 0 : if (n == 0)
2687 0 : goto empty;
2688 :
2689 : /* Copy the previous result tuple or re-use it if available */
2690 0 : if (Py_REFCNT(result) > 1) {
2691 0 : PyObject *old_result = result;
2692 0 : result = PyTuple_New(r);
2693 0 : if (result == NULL)
2694 0 : goto empty;
2695 0 : po->result = result;
2696 0 : for (i=0; i<r ; i++) {
2697 0 : elem = PyTuple_GET_ITEM(old_result, i);
2698 0 : Py_INCREF(elem);
2699 0 : PyTuple_SET_ITEM(result, i, elem);
2700 : }
2701 0 : Py_DECREF(old_result);
2702 : }
2703 : /* Now, we've got the only copy so we can update it in-place */
2704 : assert(r == 0 || Py_REFCNT(result) == 1);
2705 :
2706 : /* Decrement rightmost cycle, moving leftward upon zero rollover */
2707 0 : for (i=r-1 ; i>=0 ; i--) {
2708 0 : cycles[i] -= 1;
2709 0 : if (cycles[i] == 0) {
2710 : /* rotatation: indices[i:] = indices[i+1:] + indices[i:i+1] */
2711 0 : index = indices[i];
2712 0 : for (j=i ; j<n-1 ; j++)
2713 0 : indices[j] = indices[j+1];
2714 0 : indices[n-1] = index;
2715 0 : cycles[i] = n - i;
2716 : } else {
2717 0 : j = cycles[i];
2718 0 : index = indices[i];
2719 0 : indices[i] = indices[n-j];
2720 0 : indices[n-j] = index;
2721 :
2722 0 : for (k=i; k<r ; k++) {
2723 : /* start with i, the leftmost element that changed */
2724 : /* yield tuple(pool[k] for k in indices[:r]) */
2725 0 : index = indices[k];
2726 0 : elem = PyTuple_GET_ITEM(pool, index);
2727 0 : Py_INCREF(elem);
2728 0 : oldelem = PyTuple_GET_ITEM(result, k);
2729 0 : PyTuple_SET_ITEM(result, k, elem);
2730 0 : Py_DECREF(oldelem);
2731 : }
2732 0 : break;
2733 : }
2734 : }
2735 : /* If i is negative, then the cycles have all
2736 : rolled-over and we're done. */
2737 0 : if (i < 0)
2738 0 : goto empty;
2739 : }
2740 0 : Py_INCREF(result);
2741 0 : return result;
2742 :
2743 : empty:
2744 0 : po->stopped = 1;
2745 0 : return NULL;
2746 : }
2747 :
2748 : PyDoc_STRVAR(permutations_doc,
2749 : "permutations(iterable[, r]) --> permutations object\n\
2750 : \n\
2751 : Return successive r-length permutations of elements in the iterable.\n\n\
2752 : permutations(range(3), 2) --> (0,1), (0,2), (1,0), (1,2), (2,0), (2,1)");
2753 :
2754 : static PyTypeObject permutations_type = {
2755 : PyVarObject_HEAD_INIT(NULL, 0)
2756 : "itertools.permutations", /* tp_name */
2757 : sizeof(permutationsobject), /* tp_basicsize */
2758 : 0, /* tp_itemsize */
2759 : /* methods */
2760 : (destructor)permutations_dealloc, /* tp_dealloc */
2761 : 0, /* tp_print */
2762 : 0, /* tp_getattr */
2763 : 0, /* tp_setattr */
2764 : 0, /* tp_compare */
2765 : 0, /* tp_repr */
2766 : 0, /* tp_as_number */
2767 : 0, /* tp_as_sequence */
2768 : 0, /* tp_as_mapping */
2769 : 0, /* tp_hash */
2770 : 0, /* tp_call */
2771 : 0, /* tp_str */
2772 : PyObject_GenericGetAttr, /* tp_getattro */
2773 : 0, /* tp_setattro */
2774 : 0, /* tp_as_buffer */
2775 : Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
2776 : Py_TPFLAGS_BASETYPE, /* tp_flags */
2777 : permutations_doc, /* tp_doc */
2778 : (traverseproc)permutations_traverse, /* tp_traverse */
2779 : 0, /* tp_clear */
2780 : 0, /* tp_richcompare */
2781 : 0, /* tp_weaklistoffset */
2782 : PyObject_SelfIter, /* tp_iter */
2783 : (iternextfunc)permutations_next, /* tp_iternext */
2784 : 0, /* tp_methods */
2785 : 0, /* tp_members */
2786 : 0, /* tp_getset */
2787 : 0, /* tp_base */
2788 : 0, /* tp_dict */
2789 : 0, /* tp_descr_get */
2790 : 0, /* tp_descr_set */
2791 : 0, /* tp_dictoffset */
2792 : 0, /* tp_init */
2793 : 0, /* tp_alloc */
2794 : permutations_new, /* tp_new */
2795 : PyObject_GC_Del, /* tp_free */
2796 : };
2797 :
2798 :
2799 : /* compress object ************************************************************/
2800 :
2801 : /* Equivalent to:
2802 :
2803 : def compress(data, selectors):
2804 : "compress('ABCDEF', [1,0,1,0,1,1]) --> A C E F"
2805 : return (d for d, s in izip(data, selectors) if s)
2806 : */
2807 :
2808 : typedef struct {
2809 : PyObject_HEAD
2810 : PyObject *data;
2811 : PyObject *selectors;
2812 : } compressobject;
2813 :
2814 : static PyTypeObject compress_type;
2815 :
2816 : static PyObject *
2817 0 : compress_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
2818 : {
2819 : PyObject *seq1, *seq2;
2820 0 : PyObject *data=NULL, *selectors=NULL;
2821 : compressobject *lz;
2822 : static char *kwargs[] = {"data", "selectors", NULL};
2823 :
2824 0 : if (!PyArg_ParseTupleAndKeywords(args, kwds, "OO:compress", kwargs, &seq1, &seq2))
2825 0 : return NULL;
2826 :
2827 0 : data = PyObject_GetIter(seq1);
2828 0 : if (data == NULL)
2829 0 : goto fail;
2830 0 : selectors = PyObject_GetIter(seq2);
2831 0 : if (selectors == NULL)
2832 0 : goto fail;
2833 :
2834 : /* create compressobject structure */
2835 0 : lz = (compressobject *)type->tp_alloc(type, 0);
2836 0 : if (lz == NULL)
2837 0 : goto fail;
2838 0 : lz->data = data;
2839 0 : lz->selectors = selectors;
2840 0 : return (PyObject *)lz;
2841 :
2842 : fail:
2843 0 : Py_XDECREF(data);
2844 0 : Py_XDECREF(selectors);
2845 0 : return NULL;
2846 : }
2847 :
2848 : static void
2849 0 : compress_dealloc(compressobject *lz)
2850 : {
2851 0 : PyObject_GC_UnTrack(lz);
2852 0 : Py_XDECREF(lz->data);
2853 0 : Py_XDECREF(lz->selectors);
2854 0 : Py_TYPE(lz)->tp_free(lz);
2855 0 : }
2856 :
2857 : static int
2858 0 : compress_traverse(compressobject *lz, visitproc visit, void *arg)
2859 : {
2860 0 : Py_VISIT(lz->data);
2861 0 : Py_VISIT(lz->selectors);
2862 0 : return 0;
2863 : }
2864 :
2865 : static PyObject *
2866 0 : compress_next(compressobject *lz)
2867 : {
2868 0 : PyObject *data = lz->data, *selectors = lz->selectors;
2869 : PyObject *datum, *selector;
2870 0 : PyObject *(*datanext)(PyObject *) = *Py_TYPE(data)->tp_iternext;
2871 0 : PyObject *(*selectornext)(PyObject *) = *Py_TYPE(selectors)->tp_iternext;
2872 : int ok;
2873 :
2874 : while (1) {
2875 : /* Steps: get datum, get selector, evaluate selector.
2876 : Order is important (to match the pure python version
2877 : in terms of which input gets a chance to raise an
2878 : exception first).
2879 : */
2880 :
2881 0 : datum = datanext(data);
2882 0 : if (datum == NULL)
2883 0 : return NULL;
2884 :
2885 0 : selector = selectornext(selectors);
2886 0 : if (selector == NULL) {
2887 0 : Py_DECREF(datum);
2888 0 : return NULL;
2889 : }
2890 :
2891 0 : ok = PyObject_IsTrue(selector);
2892 0 : Py_DECREF(selector);
2893 0 : if (ok == 1)
2894 0 : return datum;
2895 0 : Py_DECREF(datum);
2896 0 : if (ok == -1)
2897 0 : return NULL;
2898 0 : }
2899 : }
2900 :
2901 : PyDoc_STRVAR(compress_doc,
2902 : "compress(data, selectors) --> iterator over selected data\n\
2903 : \n\
2904 : Return data elements corresponding to true selector elements.\n\
2905 : Forms a shorter iterator from selected data elements using the\n\
2906 : selectors to choose the data elements.");
2907 :
2908 : static PyTypeObject compress_type = {
2909 : PyVarObject_HEAD_INIT(NULL, 0)
2910 : "itertools.compress", /* tp_name */
2911 : sizeof(compressobject), /* tp_basicsize */
2912 : 0, /* tp_itemsize */
2913 : /* methods */
2914 : (destructor)compress_dealloc, /* tp_dealloc */
2915 : 0, /* tp_print */
2916 : 0, /* tp_getattr */
2917 : 0, /* tp_setattr */
2918 : 0, /* tp_compare */
2919 : 0, /* tp_repr */
2920 : 0, /* tp_as_number */
2921 : 0, /* tp_as_sequence */
2922 : 0, /* tp_as_mapping */
2923 : 0, /* tp_hash */
2924 : 0, /* tp_call */
2925 : 0, /* tp_str */
2926 : PyObject_GenericGetAttr, /* tp_getattro */
2927 : 0, /* tp_setattro */
2928 : 0, /* tp_as_buffer */
2929 : Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
2930 : Py_TPFLAGS_BASETYPE, /* tp_flags */
2931 : compress_doc, /* tp_doc */
2932 : (traverseproc)compress_traverse, /* tp_traverse */
2933 : 0, /* tp_clear */
2934 : 0, /* tp_richcompare */
2935 : 0, /* tp_weaklistoffset */
2936 : PyObject_SelfIter, /* tp_iter */
2937 : (iternextfunc)compress_next, /* tp_iternext */
2938 : 0, /* tp_methods */
2939 : 0, /* tp_members */
2940 : 0, /* tp_getset */
2941 : 0, /* tp_base */
2942 : 0, /* tp_dict */
2943 : 0, /* tp_descr_get */
2944 : 0, /* tp_descr_set */
2945 : 0, /* tp_dictoffset */
2946 : 0, /* tp_init */
2947 : 0, /* tp_alloc */
2948 : compress_new, /* tp_new */
2949 : PyObject_GC_Del, /* tp_free */
2950 : };
2951 :
2952 :
2953 : /* ifilter object ************************************************************/
2954 :
2955 : typedef struct {
2956 : PyObject_HEAD
2957 : PyObject *func;
2958 : PyObject *it;
2959 : } ifilterobject;
2960 :
2961 : static PyTypeObject ifilter_type;
2962 :
2963 : static PyObject *
2964 0 : ifilter_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
2965 : {
2966 : PyObject *func, *seq;
2967 : PyObject *it;
2968 : ifilterobject *lz;
2969 :
2970 0 : if (type == &ifilter_type && !_PyArg_NoKeywords("ifilter()", kwds))
2971 0 : return NULL;
2972 :
2973 0 : if (!PyArg_UnpackTuple(args, "ifilter", 2, 2, &func, &seq))
2974 0 : return NULL;
2975 :
2976 : /* Get iterator. */
2977 0 : it = PyObject_GetIter(seq);
2978 0 : if (it == NULL)
2979 0 : return NULL;
2980 :
2981 : /* create ifilterobject structure */
2982 0 : lz = (ifilterobject *)type->tp_alloc(type, 0);
2983 0 : if (lz == NULL) {
2984 0 : Py_DECREF(it);
2985 0 : return NULL;
2986 : }
2987 0 : Py_INCREF(func);
2988 0 : lz->func = func;
2989 0 : lz->it = it;
2990 :
2991 0 : return (PyObject *)lz;
2992 : }
2993 :
2994 : static void
2995 0 : ifilter_dealloc(ifilterobject *lz)
2996 : {
2997 0 : PyObject_GC_UnTrack(lz);
2998 0 : Py_XDECREF(lz->func);
2999 0 : Py_XDECREF(lz->it);
3000 0 : Py_TYPE(lz)->tp_free(lz);
3001 0 : }
3002 :
3003 : static int
3004 0 : ifilter_traverse(ifilterobject *lz, visitproc visit, void *arg)
3005 : {
3006 0 : Py_VISIT(lz->it);
3007 0 : Py_VISIT(lz->func);
3008 0 : return 0;
3009 : }
3010 :
3011 : static PyObject *
3012 0 : ifilter_next(ifilterobject *lz)
3013 : {
3014 : PyObject *item;
3015 0 : PyObject *it = lz->it;
3016 : long ok;
3017 : PyObject *(*iternext)(PyObject *);
3018 :
3019 0 : iternext = *Py_TYPE(it)->tp_iternext;
3020 : for (;;) {
3021 0 : item = iternext(it);
3022 0 : if (item == NULL)
3023 0 : return NULL;
3024 :
3025 0 : if (lz->func == Py_None || lz->func == (PyObject *)&PyBool_Type) {
3026 0 : ok = PyObject_IsTrue(item);
3027 : } else {
3028 : PyObject *good;
3029 0 : good = PyObject_CallFunctionObjArgs(lz->func,
3030 : item, NULL);
3031 0 : if (good == NULL) {
3032 0 : Py_DECREF(item);
3033 0 : return NULL;
3034 : }
3035 0 : ok = PyObject_IsTrue(good);
3036 0 : Py_DECREF(good);
3037 : }
3038 0 : if (ok > 0)
3039 0 : return item;
3040 0 : Py_DECREF(item);
3041 0 : if (ok < 0)
3042 0 : return NULL;
3043 0 : }
3044 : }
3045 :
3046 : PyDoc_STRVAR(ifilter_doc,
3047 : "ifilter(function or None, sequence) --> ifilter object\n\
3048 : \n\
3049 : Return those items of sequence for which function(item) is true.\n\
3050 : If function is None, return the items that are true.");
3051 :
3052 : static PyTypeObject ifilter_type = {
3053 : PyVarObject_HEAD_INIT(NULL, 0)
3054 : "itertools.ifilter", /* tp_name */
3055 : sizeof(ifilterobject), /* tp_basicsize */
3056 : 0, /* tp_itemsize */
3057 : /* methods */
3058 : (destructor)ifilter_dealloc, /* tp_dealloc */
3059 : 0, /* tp_print */
3060 : 0, /* tp_getattr */
3061 : 0, /* tp_setattr */
3062 : 0, /* tp_compare */
3063 : 0, /* tp_repr */
3064 : 0, /* tp_as_number */
3065 : 0, /* tp_as_sequence */
3066 : 0, /* tp_as_mapping */
3067 : 0, /* tp_hash */
3068 : 0, /* tp_call */
3069 : 0, /* tp_str */
3070 : PyObject_GenericGetAttr, /* tp_getattro */
3071 : 0, /* tp_setattro */
3072 : 0, /* tp_as_buffer */
3073 : Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
3074 : Py_TPFLAGS_BASETYPE, /* tp_flags */
3075 : ifilter_doc, /* tp_doc */
3076 : (traverseproc)ifilter_traverse, /* tp_traverse */
3077 : 0, /* tp_clear */
3078 : 0, /* tp_richcompare */
3079 : 0, /* tp_weaklistoffset */
3080 : PyObject_SelfIter, /* tp_iter */
3081 : (iternextfunc)ifilter_next, /* tp_iternext */
3082 : 0, /* tp_methods */
3083 : 0, /* tp_members */
3084 : 0, /* tp_getset */
3085 : 0, /* tp_base */
3086 : 0, /* tp_dict */
3087 : 0, /* tp_descr_get */
3088 : 0, /* tp_descr_set */
3089 : 0, /* tp_dictoffset */
3090 : 0, /* tp_init */
3091 : 0, /* tp_alloc */
3092 : ifilter_new, /* tp_new */
3093 : PyObject_GC_Del, /* tp_free */
3094 : };
3095 :
3096 :
3097 : /* ifilterfalse object ************************************************************/
3098 :
3099 : typedef struct {
3100 : PyObject_HEAD
3101 : PyObject *func;
3102 : PyObject *it;
3103 : } ifilterfalseobject;
3104 :
3105 : static PyTypeObject ifilterfalse_type;
3106 :
3107 : static PyObject *
3108 0 : ifilterfalse_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
3109 : {
3110 : PyObject *func, *seq;
3111 : PyObject *it;
3112 : ifilterfalseobject *lz;
3113 :
3114 0 : if (type == &ifilterfalse_type &&
3115 0 : !_PyArg_NoKeywords("ifilterfalse()", kwds))
3116 0 : return NULL;
3117 :
3118 0 : if (!PyArg_UnpackTuple(args, "ifilterfalse", 2, 2, &func, &seq))
3119 0 : return NULL;
3120 :
3121 : /* Get iterator. */
3122 0 : it = PyObject_GetIter(seq);
3123 0 : if (it == NULL)
3124 0 : return NULL;
3125 :
3126 : /* create ifilterfalseobject structure */
3127 0 : lz = (ifilterfalseobject *)type->tp_alloc(type, 0);
3128 0 : if (lz == NULL) {
3129 0 : Py_DECREF(it);
3130 0 : return NULL;
3131 : }
3132 0 : Py_INCREF(func);
3133 0 : lz->func = func;
3134 0 : lz->it = it;
3135 :
3136 0 : return (PyObject *)lz;
3137 : }
3138 :
3139 : static void
3140 0 : ifilterfalse_dealloc(ifilterfalseobject *lz)
3141 : {
3142 0 : PyObject_GC_UnTrack(lz);
3143 0 : Py_XDECREF(lz->func);
3144 0 : Py_XDECREF(lz->it);
3145 0 : Py_TYPE(lz)->tp_free(lz);
3146 0 : }
3147 :
3148 : static int
3149 0 : ifilterfalse_traverse(ifilterfalseobject *lz, visitproc visit, void *arg)
3150 : {
3151 0 : Py_VISIT(lz->it);
3152 0 : Py_VISIT(lz->func);
3153 0 : return 0;
3154 : }
3155 :
3156 : static PyObject *
3157 0 : ifilterfalse_next(ifilterfalseobject *lz)
3158 : {
3159 : PyObject *item;
3160 0 : PyObject *it = lz->it;
3161 : long ok;
3162 : PyObject *(*iternext)(PyObject *);
3163 :
3164 0 : iternext = *Py_TYPE(it)->tp_iternext;
3165 : for (;;) {
3166 0 : item = iternext(it);
3167 0 : if (item == NULL)
3168 0 : return NULL;
3169 :
3170 0 : if (lz->func == Py_None || lz->func == (PyObject *)&PyBool_Type) {
3171 0 : ok = PyObject_IsTrue(item);
3172 : } else {
3173 : PyObject *good;
3174 0 : good = PyObject_CallFunctionObjArgs(lz->func,
3175 : item, NULL);
3176 0 : if (good == NULL) {
3177 0 : Py_DECREF(item);
3178 0 : return NULL;
3179 : }
3180 0 : ok = PyObject_IsTrue(good);
3181 0 : Py_DECREF(good);
3182 : }
3183 0 : if (ok == 0)
3184 0 : return item;
3185 0 : Py_DECREF(item);
3186 0 : if (ok < 0)
3187 0 : return NULL;
3188 0 : }
3189 : }
3190 :
3191 : PyDoc_STRVAR(ifilterfalse_doc,
3192 : "ifilterfalse(function or None, sequence) --> ifilterfalse object\n\
3193 : \n\
3194 : Return those items of sequence for which function(item) is false.\n\
3195 : If function is None, return the items that are false.");
3196 :
3197 : static PyTypeObject ifilterfalse_type = {
3198 : PyVarObject_HEAD_INIT(NULL, 0)
3199 : "itertools.ifilterfalse", /* tp_name */
3200 : sizeof(ifilterfalseobject), /* tp_basicsize */
3201 : 0, /* tp_itemsize */
3202 : /* methods */
3203 : (destructor)ifilterfalse_dealloc, /* tp_dealloc */
3204 : 0, /* tp_print */
3205 : 0, /* tp_getattr */
3206 : 0, /* tp_setattr */
3207 : 0, /* tp_compare */
3208 : 0, /* tp_repr */
3209 : 0, /* tp_as_number */
3210 : 0, /* tp_as_sequence */
3211 : 0, /* tp_as_mapping */
3212 : 0, /* tp_hash */
3213 : 0, /* tp_call */
3214 : 0, /* tp_str */
3215 : PyObject_GenericGetAttr, /* tp_getattro */
3216 : 0, /* tp_setattro */
3217 : 0, /* tp_as_buffer */
3218 : Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
3219 : Py_TPFLAGS_BASETYPE, /* tp_flags */
3220 : ifilterfalse_doc, /* tp_doc */
3221 : (traverseproc)ifilterfalse_traverse, /* tp_traverse */
3222 : 0, /* tp_clear */
3223 : 0, /* tp_richcompare */
3224 : 0, /* tp_weaklistoffset */
3225 : PyObject_SelfIter, /* tp_iter */
3226 : (iternextfunc)ifilterfalse_next, /* tp_iternext */
3227 : 0, /* tp_methods */
3228 : 0, /* tp_members */
3229 : 0, /* tp_getset */
3230 : 0, /* tp_base */
3231 : 0, /* tp_dict */
3232 : 0, /* tp_descr_get */
3233 : 0, /* tp_descr_set */
3234 : 0, /* tp_dictoffset */
3235 : 0, /* tp_init */
3236 : 0, /* tp_alloc */
3237 : ifilterfalse_new, /* tp_new */
3238 : PyObject_GC_Del, /* tp_free */
3239 : };
3240 :
3241 :
3242 : /* count object ************************************************************/
3243 :
3244 : typedef struct {
3245 : PyObject_HEAD
3246 : Py_ssize_t cnt;
3247 : PyObject *long_cnt;
3248 : PyObject *long_step;
3249 : } countobject;
3250 :
3251 : /* Counting logic and invariants:
3252 :
3253 : fast_mode: when cnt an integer < PY_SSIZE_T_MAX and no step is specified.
3254 :
3255 : assert(cnt != PY_SSIZE_T_MAX && long_cnt == NULL && long_step==PyInt(1));
3256 : Advances with: cnt += 1
3257 : When count hits Y_SSIZE_T_MAX, switch to slow_mode.
3258 :
3259 : slow_mode: when cnt == PY_SSIZE_T_MAX, step is not int(1), or cnt is a float.
3260 :
3261 : assert(cnt == PY_SSIZE_T_MAX && long_cnt != NULL && long_step != NULL);
3262 : All counting is done with python objects (no overflows or underflows).
3263 : Advances with: long_cnt += long_step
3264 : Step may be zero -- effectively a slow version of repeat(cnt).
3265 : Either long_cnt or long_step may be a float, Fraction, or Decimal.
3266 : */
3267 :
3268 : static PyTypeObject count_type;
3269 :
3270 : static PyObject *
3271 0 : count_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
3272 : {
3273 : countobject *lz;
3274 0 : int slow_mode = 0;
3275 0 : Py_ssize_t cnt = 0;
3276 0 : PyObject *long_cnt = NULL;
3277 0 : PyObject *long_step = NULL;
3278 : static char *kwlist[] = {"start", "step", 0};
3279 :
3280 0 : if (!PyArg_ParseTupleAndKeywords(args, kwds, "|OO:count",
3281 : kwlist, &long_cnt, &long_step))
3282 0 : return NULL;
3283 :
3284 0 : if ((long_cnt != NULL && !PyNumber_Check(long_cnt)) ||
3285 0 : (long_step != NULL && !PyNumber_Check(long_step))) {
3286 0 : PyErr_SetString(PyExc_TypeError, "a number is required");
3287 0 : return NULL;
3288 : }
3289 :
3290 0 : if (long_cnt != NULL) {
3291 0 : cnt = PyInt_AsSsize_t(long_cnt);
3292 0 : if ((cnt == -1 && PyErr_Occurred()) || !PyInt_Check(long_cnt)) {
3293 0 : PyErr_Clear();
3294 0 : slow_mode = 1;
3295 : }
3296 0 : Py_INCREF(long_cnt);
3297 : } else {
3298 0 : cnt = 0;
3299 0 : long_cnt = PyInt_FromLong(0);
3300 : }
3301 :
3302 : /* If not specified, step defaults to 1 */
3303 0 : if (long_step == NULL) {
3304 0 : long_step = PyInt_FromLong(1);
3305 0 : if (long_step == NULL) {
3306 0 : Py_DECREF(long_cnt);
3307 0 : return NULL;
3308 : }
3309 : } else
3310 0 : Py_INCREF(long_step);
3311 :
3312 : assert(long_cnt != NULL && long_step != NULL);
3313 :
3314 : /* Fast mode only works when the step is 1 */
3315 0 : if (!PyInt_Check(long_step) ||
3316 0 : PyInt_AS_LONG(long_step) != 1) {
3317 0 : slow_mode = 1;
3318 : }
3319 :
3320 0 : if (slow_mode)
3321 0 : cnt = PY_SSIZE_T_MAX;
3322 : else
3323 0 : Py_CLEAR(long_cnt);
3324 :
3325 : assert((cnt != PY_SSIZE_T_MAX && long_cnt == NULL && !slow_mode) ||
3326 : (cnt == PY_SSIZE_T_MAX && long_cnt != NULL && slow_mode));
3327 : assert(slow_mode ||
3328 : (PyInt_Check(long_step) && PyInt_AS_LONG(long_step) == 1));
3329 :
3330 : /* create countobject structure */
3331 0 : lz = (countobject *)type->tp_alloc(type, 0);
3332 0 : if (lz == NULL) {
3333 0 : Py_XDECREF(long_cnt);
3334 0 : return NULL;
3335 : }
3336 0 : lz->cnt = cnt;
3337 0 : lz->long_cnt = long_cnt;
3338 0 : lz->long_step = long_step;
3339 :
3340 0 : return (PyObject *)lz;
3341 : }
3342 :
3343 : static void
3344 0 : count_dealloc(countobject *lz)
3345 : {
3346 0 : PyObject_GC_UnTrack(lz);
3347 0 : Py_XDECREF(lz->long_cnt);
3348 0 : Py_XDECREF(lz->long_step);
3349 0 : Py_TYPE(lz)->tp_free(lz);
3350 0 : }
3351 :
3352 : static int
3353 0 : count_traverse(countobject *lz, visitproc visit, void *arg)
3354 : {
3355 0 : Py_VISIT(lz->long_cnt);
3356 0 : Py_VISIT(lz->long_step);
3357 0 : return 0;
3358 : }
3359 :
3360 : static PyObject *
3361 0 : count_nextlong(countobject *lz)
3362 : {
3363 : PyObject *long_cnt;
3364 : PyObject *stepped_up;
3365 :
3366 0 : long_cnt = lz->long_cnt;
3367 0 : if (long_cnt == NULL) {
3368 : /* Switch to slow_mode */
3369 0 : long_cnt = PyInt_FromSsize_t(PY_SSIZE_T_MAX);
3370 0 : if (long_cnt == NULL)
3371 0 : return NULL;
3372 : }
3373 : assert(lz->cnt == PY_SSIZE_T_MAX && long_cnt != NULL);
3374 :
3375 0 : stepped_up = PyNumber_Add(long_cnt, lz->long_step);
3376 0 : if (stepped_up == NULL)
3377 0 : return NULL;
3378 0 : lz->long_cnt = stepped_up;
3379 0 : return long_cnt;
3380 : }
3381 :
3382 : static PyObject *
3383 0 : count_next(countobject *lz)
3384 : {
3385 0 : if (lz->cnt == PY_SSIZE_T_MAX)
3386 0 : return count_nextlong(lz);
3387 0 : return PyInt_FromSsize_t(lz->cnt++);
3388 : }
3389 :
3390 : static PyObject *
3391 0 : count_repr(countobject *lz)
3392 : {
3393 0 : PyObject *cnt_repr, *step_repr = NULL;
3394 0 : PyObject *result = NULL;
3395 :
3396 0 : if (lz->cnt != PY_SSIZE_T_MAX)
3397 0 : return PyString_FromFormat("count(%zd)", lz->cnt);
3398 :
3399 0 : cnt_repr = PyObject_Repr(lz->long_cnt);
3400 0 : if (cnt_repr == NULL)
3401 0 : return NULL;
3402 :
3403 0 : if (PyInt_Check(lz->long_step) && PyInt_AS_LONG(lz->long_step) == 1) {
3404 : /* Don't display step when it is an integer equal to 1 */
3405 0 : result = PyString_FromFormat("count(%s)",
3406 0 : PyString_AS_STRING(cnt_repr));
3407 : } else {
3408 0 : step_repr = PyObject_Repr(lz->long_step);
3409 0 : if (step_repr != NULL)
3410 0 : result = PyString_FromFormat("count(%s, %s)",
3411 0 : PyString_AS_STRING(cnt_repr),
3412 0 : PyString_AS_STRING(step_repr));
3413 : }
3414 0 : Py_DECREF(cnt_repr);
3415 0 : Py_XDECREF(step_repr);
3416 0 : return result;
3417 : }
3418 :
3419 : static PyObject *
3420 0 : count_reduce(countobject *lz)
3421 : {
3422 0 : if (lz->cnt == PY_SSIZE_T_MAX)
3423 0 : return Py_BuildValue("O(OO)", Py_TYPE(lz), lz->long_cnt, lz->long_step);
3424 0 : return Py_BuildValue("O(n)", Py_TYPE(lz), lz->cnt);
3425 : }
3426 :
3427 : PyDoc_STRVAR(count_reduce_doc, "Return state information for pickling.");
3428 :
3429 : static PyMethodDef count_methods[] = {
3430 : {"__reduce__", (PyCFunction)count_reduce, METH_NOARGS,
3431 : count_reduce_doc},
3432 : {NULL, NULL} /* sentinel */
3433 : };
3434 :
3435 : PyDoc_STRVAR(count_doc,
3436 : "count(start=0, step=1) --> count object\n\
3437 : \n\
3438 : Return a count object whose .next() method returns consecutive values.\n\
3439 : Equivalent to:\n\n\
3440 : def count(firstval=0, step=1):\n\
3441 : x = firstval\n\
3442 : while 1:\n\
3443 : yield x\n\
3444 : x += step\n");
3445 :
3446 : static PyTypeObject count_type = {
3447 : PyVarObject_HEAD_INIT(NULL, 0)
3448 : "itertools.count", /* tp_name */
3449 : sizeof(countobject), /* tp_basicsize */
3450 : 0, /* tp_itemsize */
3451 : /* methods */
3452 : (destructor)count_dealloc, /* tp_dealloc */
3453 : 0, /* tp_print */
3454 : 0, /* tp_getattr */
3455 : 0, /* tp_setattr */
3456 : 0, /* tp_compare */
3457 : (reprfunc)count_repr, /* tp_repr */
3458 : 0, /* tp_as_number */
3459 : 0, /* tp_as_sequence */
3460 : 0, /* tp_as_mapping */
3461 : 0, /* tp_hash */
3462 : 0, /* tp_call */
3463 : 0, /* tp_str */
3464 : PyObject_GenericGetAttr, /* tp_getattro */
3465 : 0, /* tp_setattro */
3466 : 0, /* tp_as_buffer */
3467 : Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
3468 : Py_TPFLAGS_BASETYPE, /* tp_flags */
3469 : count_doc, /* tp_doc */
3470 : (traverseproc)count_traverse, /* tp_traverse */
3471 : 0, /* tp_clear */
3472 : 0, /* tp_richcompare */
3473 : 0, /* tp_weaklistoffset */
3474 : PyObject_SelfIter, /* tp_iter */
3475 : (iternextfunc)count_next, /* tp_iternext */
3476 : count_methods, /* tp_methods */
3477 : 0, /* tp_members */
3478 : 0, /* tp_getset */
3479 : 0, /* tp_base */
3480 : 0, /* tp_dict */
3481 : 0, /* tp_descr_get */
3482 : 0, /* tp_descr_set */
3483 : 0, /* tp_dictoffset */
3484 : 0, /* tp_init */
3485 : 0, /* tp_alloc */
3486 : count_new, /* tp_new */
3487 : PyObject_GC_Del, /* tp_free */
3488 : };
3489 :
3490 :
3491 : /* izip object ************************************************************/
3492 :
3493 : #include "Python.h"
3494 :
3495 : typedef struct {
3496 : PyObject_HEAD
3497 : Py_ssize_t tuplesize;
3498 : PyObject *ittuple; /* tuple of iterators */
3499 : PyObject *result;
3500 : } izipobject;
3501 :
3502 : static PyTypeObject izip_type;
3503 :
3504 : static PyObject *
3505 0 : izip_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
3506 : {
3507 : izipobject *lz;
3508 : Py_ssize_t i;
3509 : PyObject *ittuple; /* tuple of iterators */
3510 : PyObject *result;
3511 0 : Py_ssize_t tuplesize = PySequence_Length(args);
3512 :
3513 0 : if (type == &izip_type && !_PyArg_NoKeywords("izip()", kwds))
3514 0 : return NULL;
3515 :
3516 : /* args must be a tuple */
3517 : assert(PyTuple_Check(args));
3518 :
3519 : /* obtain iterators */
3520 0 : ittuple = PyTuple_New(tuplesize);
3521 0 : if (ittuple == NULL)
3522 0 : return NULL;
3523 0 : for (i=0; i < tuplesize; ++i) {
3524 0 : PyObject *item = PyTuple_GET_ITEM(args, i);
3525 0 : PyObject *it = PyObject_GetIter(item);
3526 0 : if (it == NULL) {
3527 0 : if (PyErr_ExceptionMatches(PyExc_TypeError))
3528 0 : PyErr_Format(PyExc_TypeError,
3529 : "izip argument #%zd must support iteration",
3530 : i+1);
3531 0 : Py_DECREF(ittuple);
3532 0 : return NULL;
3533 : }
3534 0 : PyTuple_SET_ITEM(ittuple, i, it);
3535 : }
3536 :
3537 : /* create a result holder */
3538 0 : result = PyTuple_New(tuplesize);
3539 0 : if (result == NULL) {
3540 0 : Py_DECREF(ittuple);
3541 0 : return NULL;
3542 : }
3543 0 : for (i=0 ; i < tuplesize ; i++) {
3544 0 : Py_INCREF(Py_None);
3545 0 : PyTuple_SET_ITEM(result, i, Py_None);
3546 : }
3547 :
3548 : /* create izipobject structure */
3549 0 : lz = (izipobject *)type->tp_alloc(type, 0);
3550 0 : if (lz == NULL) {
3551 0 : Py_DECREF(ittuple);
3552 0 : Py_DECREF(result);
3553 0 : return NULL;
3554 : }
3555 0 : lz->ittuple = ittuple;
3556 0 : lz->tuplesize = tuplesize;
3557 0 : lz->result = result;
3558 :
3559 0 : return (PyObject *)lz;
3560 : }
3561 :
3562 : static void
3563 0 : izip_dealloc(izipobject *lz)
3564 : {
3565 0 : PyObject_GC_UnTrack(lz);
3566 0 : Py_XDECREF(lz->ittuple);
3567 0 : Py_XDECREF(lz->result);
3568 0 : Py_TYPE(lz)->tp_free(lz);
3569 0 : }
3570 :
3571 : static int
3572 0 : izip_traverse(izipobject *lz, visitproc visit, void *arg)
3573 : {
3574 0 : Py_VISIT(lz->ittuple);
3575 0 : Py_VISIT(lz->result);
3576 0 : return 0;
3577 : }
3578 :
3579 : static PyObject *
3580 0 : izip_next(izipobject *lz)
3581 : {
3582 : Py_ssize_t i;
3583 0 : Py_ssize_t tuplesize = lz->tuplesize;
3584 0 : PyObject *result = lz->result;
3585 : PyObject *it;
3586 : PyObject *item;
3587 : PyObject *olditem;
3588 :
3589 0 : if (tuplesize == 0)
3590 0 : return NULL;
3591 0 : if (Py_REFCNT(result) == 1) {
3592 0 : Py_INCREF(result);
3593 0 : for (i=0 ; i < tuplesize ; i++) {
3594 0 : it = PyTuple_GET_ITEM(lz->ittuple, i);
3595 0 : item = (*Py_TYPE(it)->tp_iternext)(it);
3596 0 : if (item == NULL) {
3597 0 : Py_DECREF(result);
3598 0 : return NULL;
3599 : }
3600 0 : olditem = PyTuple_GET_ITEM(result, i);
3601 0 : PyTuple_SET_ITEM(result, i, item);
3602 0 : Py_DECREF(olditem);
3603 : }
3604 : } else {
3605 0 : result = PyTuple_New(tuplesize);
3606 0 : if (result == NULL)
3607 0 : return NULL;
3608 0 : for (i=0 ; i < tuplesize ; i++) {
3609 0 : it = PyTuple_GET_ITEM(lz->ittuple, i);
3610 0 : item = (*Py_TYPE(it)->tp_iternext)(it);
3611 0 : if (item == NULL) {
3612 0 : Py_DECREF(result);
3613 0 : return NULL;
3614 : }
3615 0 : PyTuple_SET_ITEM(result, i, item);
3616 : }
3617 : }
3618 0 : return result;
3619 : }
3620 :
3621 : PyDoc_STRVAR(izip_doc,
3622 : "izip(iter1 [,iter2 [...]]) --> izip object\n\
3623 : \n\
3624 : Return a izip object whose .next() method returns a tuple where\n\
3625 : the i-th element comes from the i-th iterable argument. The .next()\n\
3626 : method continues until the shortest iterable in the argument sequence\n\
3627 : is exhausted and then it raises StopIteration. Works like the zip()\n\
3628 : function but consumes less memory by returning an iterator instead of\n\
3629 : a list.");
3630 :
3631 : static PyTypeObject izip_type = {
3632 : PyVarObject_HEAD_INIT(NULL, 0)
3633 : "itertools.izip", /* tp_name */
3634 : sizeof(izipobject), /* tp_basicsize */
3635 : 0, /* tp_itemsize */
3636 : /* methods */
3637 : (destructor)izip_dealloc, /* tp_dealloc */
3638 : 0, /* tp_print */
3639 : 0, /* tp_getattr */
3640 : 0, /* tp_setattr */
3641 : 0, /* tp_compare */
3642 : 0, /* tp_repr */
3643 : 0, /* tp_as_number */
3644 : 0, /* tp_as_sequence */
3645 : 0, /* tp_as_mapping */
3646 : 0, /* tp_hash */
3647 : 0, /* tp_call */
3648 : 0, /* tp_str */
3649 : PyObject_GenericGetAttr, /* tp_getattro */
3650 : 0, /* tp_setattro */
3651 : 0, /* tp_as_buffer */
3652 : Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
3653 : Py_TPFLAGS_BASETYPE, /* tp_flags */
3654 : izip_doc, /* tp_doc */
3655 : (traverseproc)izip_traverse, /* tp_traverse */
3656 : 0, /* tp_clear */
3657 : 0, /* tp_richcompare */
3658 : 0, /* tp_weaklistoffset */
3659 : PyObject_SelfIter, /* tp_iter */
3660 : (iternextfunc)izip_next, /* tp_iternext */
3661 : 0, /* tp_methods */
3662 : 0, /* tp_members */
3663 : 0, /* tp_getset */
3664 : 0, /* tp_base */
3665 : 0, /* tp_dict */
3666 : 0, /* tp_descr_get */
3667 : 0, /* tp_descr_set */
3668 : 0, /* tp_dictoffset */
3669 : 0, /* tp_init */
3670 : 0, /* tp_alloc */
3671 : izip_new, /* tp_new */
3672 : PyObject_GC_Del, /* tp_free */
3673 : };
3674 :
3675 :
3676 : /* repeat object ************************************************************/
3677 :
3678 : typedef struct {
3679 : PyObject_HEAD
3680 : PyObject *element;
3681 : Py_ssize_t cnt;
3682 : } repeatobject;
3683 :
3684 : static PyTypeObject repeat_type;
3685 :
3686 : static PyObject *
3687 0 : repeat_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
3688 : {
3689 : repeatobject *ro;
3690 : PyObject *element;
3691 0 : Py_ssize_t cnt = -1, n_kwds = 0;
3692 : static char *kwargs[] = {"object", "times", NULL};
3693 :
3694 0 : if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|n:repeat", kwargs,
3695 : &element, &cnt))
3696 0 : return NULL;
3697 :
3698 0 : if (kwds != NULL)
3699 0 : n_kwds = PyDict_Size(kwds);
3700 : /* Does user supply times argument? */
3701 0 : if ((PyTuple_Size(args) + n_kwds == 2) && cnt < 0)
3702 0 : cnt = 0;
3703 :
3704 0 : ro = (repeatobject *)type->tp_alloc(type, 0);
3705 0 : if (ro == NULL)
3706 0 : return NULL;
3707 0 : Py_INCREF(element);
3708 0 : ro->element = element;
3709 0 : ro->cnt = cnt;
3710 0 : return (PyObject *)ro;
3711 : }
3712 :
3713 : static void
3714 0 : repeat_dealloc(repeatobject *ro)
3715 : {
3716 0 : PyObject_GC_UnTrack(ro);
3717 0 : Py_XDECREF(ro->element);
3718 0 : Py_TYPE(ro)->tp_free(ro);
3719 0 : }
3720 :
3721 : static int
3722 0 : repeat_traverse(repeatobject *ro, visitproc visit, void *arg)
3723 : {
3724 0 : Py_VISIT(ro->element);
3725 0 : return 0;
3726 : }
3727 :
3728 : static PyObject *
3729 0 : repeat_next(repeatobject *ro)
3730 : {
3731 0 : if (ro->cnt == 0)
3732 0 : return NULL;
3733 0 : if (ro->cnt > 0)
3734 0 : ro->cnt--;
3735 0 : Py_INCREF(ro->element);
3736 0 : return ro->element;
3737 : }
3738 :
3739 : static PyObject *
3740 0 : repeat_repr(repeatobject *ro)
3741 : {
3742 : PyObject *result, *objrepr;
3743 :
3744 0 : objrepr = PyObject_Repr(ro->element);
3745 0 : if (objrepr == NULL)
3746 0 : return NULL;
3747 :
3748 0 : if (ro->cnt == -1)
3749 0 : result = PyString_FromFormat("repeat(%s)",
3750 0 : PyString_AS_STRING(objrepr));
3751 : else
3752 0 : result = PyString_FromFormat("repeat(%s, %zd)",
3753 0 : PyString_AS_STRING(objrepr), ro->cnt);
3754 0 : Py_DECREF(objrepr);
3755 0 : return result;
3756 : }
3757 :
3758 : static PyObject *
3759 0 : repeat_len(repeatobject *ro)
3760 : {
3761 0 : if (ro->cnt == -1) {
3762 0 : PyErr_SetString(PyExc_TypeError, "len() of unsized object");
3763 0 : return NULL;
3764 : }
3765 0 : return PyInt_FromSize_t(ro->cnt);
3766 : }
3767 :
3768 : PyDoc_STRVAR(length_hint_doc, "Private method returning an estimate of len(list(it)).");
3769 :
3770 : static PyMethodDef repeat_methods[] = {
3771 : {"__length_hint__", (PyCFunction)repeat_len, METH_NOARGS, length_hint_doc},
3772 : {NULL, NULL} /* sentinel */
3773 : };
3774 :
3775 : PyDoc_STRVAR(repeat_doc,
3776 : "repeat(object [,times]) -> create an iterator which returns the object\n\
3777 : for the specified number of times. If not specified, returns the object\n\
3778 : endlessly.");
3779 :
3780 : static PyTypeObject repeat_type = {
3781 : PyVarObject_HEAD_INIT(NULL, 0)
3782 : "itertools.repeat", /* tp_name */
3783 : sizeof(repeatobject), /* tp_basicsize */
3784 : 0, /* tp_itemsize */
3785 : /* methods */
3786 : (destructor)repeat_dealloc, /* tp_dealloc */
3787 : 0, /* tp_print */
3788 : 0, /* tp_getattr */
3789 : 0, /* tp_setattr */
3790 : 0, /* tp_compare */
3791 : (reprfunc)repeat_repr, /* tp_repr */
3792 : 0, /* tp_as_number */
3793 : 0, /* tp_as_sequence */
3794 : 0, /* tp_as_mapping */
3795 : 0, /* tp_hash */
3796 : 0, /* tp_call */
3797 : 0, /* tp_str */
3798 : PyObject_GenericGetAttr, /* tp_getattro */
3799 : 0, /* tp_setattro */
3800 : 0, /* tp_as_buffer */
3801 : Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
3802 : Py_TPFLAGS_BASETYPE, /* tp_flags */
3803 : repeat_doc, /* tp_doc */
3804 : (traverseproc)repeat_traverse, /* tp_traverse */
3805 : 0, /* tp_clear */
3806 : 0, /* tp_richcompare */
3807 : 0, /* tp_weaklistoffset */
3808 : PyObject_SelfIter, /* tp_iter */
3809 : (iternextfunc)repeat_next, /* tp_iternext */
3810 : repeat_methods, /* tp_methods */
3811 : 0, /* tp_members */
3812 : 0, /* tp_getset */
3813 : 0, /* tp_base */
3814 : 0, /* tp_dict */
3815 : 0, /* tp_descr_get */
3816 : 0, /* tp_descr_set */
3817 : 0, /* tp_dictoffset */
3818 : 0, /* tp_init */
3819 : 0, /* tp_alloc */
3820 : repeat_new, /* tp_new */
3821 : PyObject_GC_Del, /* tp_free */
3822 : };
3823 :
3824 : /* iziplongest object ************************************************************/
3825 :
3826 : #include "Python.h"
3827 :
3828 : typedef struct {
3829 : PyObject_HEAD
3830 : Py_ssize_t tuplesize;
3831 : Py_ssize_t numactive;
3832 : PyObject *ittuple; /* tuple of iterators */
3833 : PyObject *result;
3834 : PyObject *fillvalue;
3835 : } iziplongestobject;
3836 :
3837 : static PyTypeObject iziplongest_type;
3838 :
3839 : static PyObject *
3840 0 : izip_longest_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
3841 : {
3842 : iziplongestobject *lz;
3843 : Py_ssize_t i;
3844 : PyObject *ittuple; /* tuple of iterators */
3845 : PyObject *result;
3846 0 : PyObject *fillvalue = Py_None;
3847 0 : Py_ssize_t tuplesize = PySequence_Length(args);
3848 :
3849 0 : if (kwds != NULL && PyDict_CheckExact(kwds) && PyDict_Size(kwds) > 0) {
3850 0 : fillvalue = PyDict_GetItemString(kwds, "fillvalue");
3851 0 : if (fillvalue == NULL || PyDict_Size(kwds) > 1) {
3852 0 : PyErr_SetString(PyExc_TypeError,
3853 : "izip_longest() got an unexpected keyword argument");
3854 0 : return NULL;
3855 : }
3856 : }
3857 :
3858 : /* args must be a tuple */
3859 : assert(PyTuple_Check(args));
3860 :
3861 : /* obtain iterators */
3862 0 : ittuple = PyTuple_New(tuplesize);
3863 0 : if (ittuple == NULL)
3864 0 : return NULL;
3865 0 : for (i=0; i < tuplesize; ++i) {
3866 0 : PyObject *item = PyTuple_GET_ITEM(args, i);
3867 0 : PyObject *it = PyObject_GetIter(item);
3868 0 : if (it == NULL) {
3869 0 : if (PyErr_ExceptionMatches(PyExc_TypeError))
3870 0 : PyErr_Format(PyExc_TypeError,
3871 : "izip_longest argument #%zd must support iteration",
3872 : i+1);
3873 0 : Py_DECREF(ittuple);
3874 0 : return NULL;
3875 : }
3876 0 : PyTuple_SET_ITEM(ittuple, i, it);
3877 : }
3878 :
3879 : /* create a result holder */
3880 0 : result = PyTuple_New(tuplesize);
3881 0 : if (result == NULL) {
3882 0 : Py_DECREF(ittuple);
3883 0 : return NULL;
3884 : }
3885 0 : for (i=0 ; i < tuplesize ; i++) {
3886 0 : Py_INCREF(Py_None);
3887 0 : PyTuple_SET_ITEM(result, i, Py_None);
3888 : }
3889 :
3890 : /* create iziplongestobject structure */
3891 0 : lz = (iziplongestobject *)type->tp_alloc(type, 0);
3892 0 : if (lz == NULL) {
3893 0 : Py_DECREF(ittuple);
3894 0 : Py_DECREF(result);
3895 0 : return NULL;
3896 : }
3897 0 : lz->ittuple = ittuple;
3898 0 : lz->tuplesize = tuplesize;
3899 0 : lz->numactive = tuplesize;
3900 0 : lz->result = result;
3901 0 : Py_INCREF(fillvalue);
3902 0 : lz->fillvalue = fillvalue;
3903 0 : return (PyObject *)lz;
3904 : }
3905 :
3906 : static void
3907 0 : izip_longest_dealloc(iziplongestobject *lz)
3908 : {
3909 0 : PyObject_GC_UnTrack(lz);
3910 0 : Py_XDECREF(lz->ittuple);
3911 0 : Py_XDECREF(lz->result);
3912 0 : Py_XDECREF(lz->fillvalue);
3913 0 : Py_TYPE(lz)->tp_free(lz);
3914 0 : }
3915 :
3916 : static int
3917 0 : izip_longest_traverse(iziplongestobject *lz, visitproc visit, void *arg)
3918 : {
3919 0 : Py_VISIT(lz->ittuple);
3920 0 : Py_VISIT(lz->result);
3921 0 : Py_VISIT(lz->fillvalue);
3922 0 : return 0;
3923 : }
3924 :
3925 : static PyObject *
3926 0 : izip_longest_next(iziplongestobject *lz)
3927 : {
3928 : Py_ssize_t i;
3929 0 : Py_ssize_t tuplesize = lz->tuplesize;
3930 0 : PyObject *result = lz->result;
3931 : PyObject *it;
3932 : PyObject *item;
3933 : PyObject *olditem;
3934 :
3935 0 : if (tuplesize == 0)
3936 0 : return NULL;
3937 0 : if (lz->numactive == 0)
3938 0 : return NULL;
3939 0 : if (Py_REFCNT(result) == 1) {
3940 0 : Py_INCREF(result);
3941 0 : for (i=0 ; i < tuplesize ; i++) {
3942 0 : it = PyTuple_GET_ITEM(lz->ittuple, i);
3943 0 : if (it == NULL) {
3944 0 : Py_INCREF(lz->fillvalue);
3945 0 : item = lz->fillvalue;
3946 : } else {
3947 0 : item = PyIter_Next(it);
3948 0 : if (item == NULL) {
3949 0 : lz->numactive -= 1;
3950 0 : if (lz->numactive == 0 || PyErr_Occurred()) {
3951 0 : lz->numactive = 0;
3952 0 : Py_DECREF(result);
3953 0 : return NULL;
3954 : } else {
3955 0 : Py_INCREF(lz->fillvalue);
3956 0 : item = lz->fillvalue;
3957 0 : PyTuple_SET_ITEM(lz->ittuple, i, NULL);
3958 0 : Py_DECREF(it);
3959 : }
3960 : }
3961 : }
3962 0 : olditem = PyTuple_GET_ITEM(result, i);
3963 0 : PyTuple_SET_ITEM(result, i, item);
3964 0 : Py_DECREF(olditem);
3965 : }
3966 : } else {
3967 0 : result = PyTuple_New(tuplesize);
3968 0 : if (result == NULL)
3969 0 : return NULL;
3970 0 : for (i=0 ; i < tuplesize ; i++) {
3971 0 : it = PyTuple_GET_ITEM(lz->ittuple, i);
3972 0 : if (it == NULL) {
3973 0 : Py_INCREF(lz->fillvalue);
3974 0 : item = lz->fillvalue;
3975 : } else {
3976 0 : item = PyIter_Next(it);
3977 0 : if (item == NULL) {
3978 0 : lz->numactive -= 1;
3979 0 : if (lz->numactive == 0 || PyErr_Occurred()) {
3980 0 : lz->numactive = 0;
3981 0 : Py_DECREF(result);
3982 0 : return NULL;
3983 : } else {
3984 0 : Py_INCREF(lz->fillvalue);
3985 0 : item = lz->fillvalue;
3986 0 : PyTuple_SET_ITEM(lz->ittuple, i, NULL);
3987 0 : Py_DECREF(it);
3988 : }
3989 : }
3990 : }
3991 0 : PyTuple_SET_ITEM(result, i, item);
3992 : }
3993 : }
3994 0 : return result;
3995 : }
3996 :
3997 : PyDoc_STRVAR(izip_longest_doc,
3998 : "izip_longest(iter1 [,iter2 [...]], [fillvalue=None]) --> izip_longest object\n\
3999 : \n\
4000 : Return an izip_longest object whose .next() method returns a tuple where\n\
4001 : the i-th element comes from the i-th iterable argument. The .next()\n\
4002 : method continues until the longest iterable in the argument sequence\n\
4003 : is exhausted and then it raises StopIteration. When the shorter iterables\n\
4004 : are exhausted, the fillvalue is substituted in their place. The fillvalue\n\
4005 : defaults to None or can be specified by a keyword argument.\n\
4006 : ");
4007 :
4008 : static PyTypeObject iziplongest_type = {
4009 : PyVarObject_HEAD_INIT(NULL, 0)
4010 : "itertools.izip_longest", /* tp_name */
4011 : sizeof(iziplongestobject), /* tp_basicsize */
4012 : 0, /* tp_itemsize */
4013 : /* methods */
4014 : (destructor)izip_longest_dealloc, /* tp_dealloc */
4015 : 0, /* tp_print */
4016 : 0, /* tp_getattr */
4017 : 0, /* tp_setattr */
4018 : 0, /* tp_compare */
4019 : 0, /* tp_repr */
4020 : 0, /* tp_as_number */
4021 : 0, /* tp_as_sequence */
4022 : 0, /* tp_as_mapping */
4023 : 0, /* tp_hash */
4024 : 0, /* tp_call */
4025 : 0, /* tp_str */
4026 : PyObject_GenericGetAttr, /* tp_getattro */
4027 : 0, /* tp_setattro */
4028 : 0, /* tp_as_buffer */
4029 : Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
4030 : Py_TPFLAGS_BASETYPE, /* tp_flags */
4031 : izip_longest_doc, /* tp_doc */
4032 : (traverseproc)izip_longest_traverse, /* tp_traverse */
4033 : 0, /* tp_clear */
4034 : 0, /* tp_richcompare */
4035 : 0, /* tp_weaklistoffset */
4036 : PyObject_SelfIter, /* tp_iter */
4037 : (iternextfunc)izip_longest_next, /* tp_iternext */
4038 : 0, /* tp_methods */
4039 : 0, /* tp_members */
4040 : 0, /* tp_getset */
4041 : 0, /* tp_base */
4042 : 0, /* tp_dict */
4043 : 0, /* tp_descr_get */
4044 : 0, /* tp_descr_set */
4045 : 0, /* tp_dictoffset */
4046 : 0, /* tp_init */
4047 : 0, /* tp_alloc */
4048 : izip_longest_new, /* tp_new */
4049 : PyObject_GC_Del, /* tp_free */
4050 : };
4051 :
4052 : /* module level code ********************************************************/
4053 :
4054 : PyDoc_STRVAR(module_doc,
4055 : "Functional tools for creating and using iterators.\n\
4056 : \n\
4057 : Infinite iterators:\n\
4058 : count([n]) --> n, n+1, n+2, ...\n\
4059 : cycle(p) --> p0, p1, ... plast, p0, p1, ...\n\
4060 : repeat(elem [,n]) --> elem, elem, elem, ... endlessly or up to n times\n\
4061 : \n\
4062 : Iterators terminating on the shortest input sequence:\n\
4063 : chain(p, q, ...) --> p0, p1, ... plast, q0, q1, ... \n\
4064 : compress(data, selectors) --> (d[0] if s[0]), (d[1] if s[1]), ...\n\
4065 : dropwhile(pred, seq) --> seq[n], seq[n+1], starting when pred fails\n\
4066 : groupby(iterable[, keyfunc]) --> sub-iterators grouped by value of keyfunc(v)\n\
4067 : ifilter(pred, seq) --> elements of seq where pred(elem) is True\n\
4068 : ifilterfalse(pred, seq) --> elements of seq where pred(elem) is False\n\
4069 : islice(seq, [start,] stop [, step]) --> elements from\n\
4070 : seq[start:stop:step]\n\
4071 : imap(fun, p, q, ...) --> fun(p0, q0), fun(p1, q1), ...\n\
4072 : starmap(fun, seq) --> fun(*seq[0]), fun(*seq[1]), ...\n\
4073 : tee(it, n=2) --> (it1, it2 , ... itn) splits one iterator into n\n\
4074 : takewhile(pred, seq) --> seq[0], seq[1], until pred fails\n\
4075 : izip(p, q, ...) --> (p[0], q[0]), (p[1], q[1]), ... \n\
4076 : izip_longest(p, q, ...) --> (p[0], q[0]), (p[1], q[1]), ... \n\
4077 : \n\
4078 : Combinatoric generators:\n\
4079 : product(p, q, ... [repeat=1]) --> cartesian product\n\
4080 : permutations(p[, r])\n\
4081 : combinations(p, r)\n\
4082 : combinations_with_replacement(p, r)\n\
4083 : ");
4084 :
4085 :
4086 : static PyMethodDef module_methods[] = {
4087 : {"tee", (PyCFunction)tee, METH_VARARGS, tee_doc},
4088 : {NULL, NULL} /* sentinel */
4089 : };
4090 :
4091 : PyMODINIT_FUNC
4092 3 : inititertools(void)
4093 : {
4094 : int i;
4095 : PyObject *m;
4096 : char *name;
4097 3 : PyTypeObject *typelist[] = {
4098 : &combinations_type,
4099 : &cwr_type,
4100 : &cycle_type,
4101 : &dropwhile_type,
4102 : &takewhile_type,
4103 : &islice_type,
4104 : &starmap_type,
4105 : &imap_type,
4106 : &chain_type,
4107 : &compress_type,
4108 : &ifilter_type,
4109 : &ifilterfalse_type,
4110 : &count_type,
4111 : &izip_type,
4112 : &iziplongest_type,
4113 : &permutations_type,
4114 : &product_type,
4115 : &repeat_type,
4116 : &groupby_type,
4117 : NULL
4118 : };
4119 :
4120 3 : Py_TYPE(&teedataobject_type) = &PyType_Type;
4121 3 : m = Py_InitModule3("itertools", module_methods, module_doc);
4122 3 : if (m == NULL)
4123 0 : return;
4124 :
4125 60 : for (i=0 ; typelist[i] != NULL ; i++) {
4126 57 : if (PyType_Ready(typelist[i]) < 0)
4127 0 : return;
4128 57 : name = strchr(typelist[i]->tp_name, '.');
4129 : assert (name != NULL);
4130 57 : Py_INCREF(typelist[i]);
4131 57 : PyModule_AddObject(m, name+1, (PyObject *)typelist[i]);
4132 : }
4133 :
4134 3 : if (PyType_Ready(&teedataobject_type) < 0)
4135 0 : return;
4136 3 : if (PyType_Ready(&tee_type) < 0)
4137 0 : return;
4138 3 : if (PyType_Ready(&_grouper_type) < 0)
4139 0 : return;
4140 : }
|