blob: 69ee3d4eae36f5d3ddd26204401e9079bdb58f41 [file] [log] [blame]
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001
2#include "Python.h"
3
4/* Itertools module written and maintained
5 by Raymond D. Hettinger <python@rcn.com>
6 Copyright (c) 2003 Python Software Foundation.
7 All rights reserved.
8*/
9
10/* dropwhile object **********************************************************/
11
12typedef struct {
13 PyObject_HEAD
14 PyObject *func;
15 PyObject *it;
16 long start;
17} dropwhileobject;
18
19PyTypeObject dropwhile_type;
20
21static PyObject *
22dropwhile_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
23{
24 PyObject *func, *seq;
25 PyObject *it;
26 dropwhileobject *lz;
27
28 if (!PyArg_UnpackTuple(args, "dropwhile", 2, 2, &func, &seq))
29 return NULL;
30
31 /* Get iterator. */
32 it = PyObject_GetIter(seq);
33 if (it == NULL)
34 return NULL;
35
36 /* create dropwhileobject structure */
37 lz = (dropwhileobject *)type->tp_alloc(type, 0);
38 if (lz == NULL) {
39 Py_DECREF(it);
40 return NULL;
41 }
42 Py_INCREF(func);
43 lz->func = func;
44 lz->it = it;
45 lz->start = 0;
46
47 return (PyObject *)lz;
48}
49
50static void
51dropwhile_dealloc(dropwhileobject *lz)
52{
53 PyObject_GC_UnTrack(lz);
54 Py_XDECREF(lz->func);
55 Py_XDECREF(lz->it);
56 lz->ob_type->tp_free(lz);
57}
58
59static int
60dropwhile_traverse(dropwhileobject *lz, visitproc visit, void *arg)
61{
62 int err;
63
64 if (lz->it) {
65 err = visit(lz->it, arg);
66 if (err)
67 return err;
68 }
69 if (lz->func) {
70 err = visit(lz->func, arg);
71 if (err)
72 return err;
73 }
74 return 0;
75}
76
77static PyObject *
78dropwhile_next(dropwhileobject *lz)
79{
80 PyObject *item, *good;
81 long ok;
82
83 for (;;) {
84 item = PyIter_Next(lz->it);
85 if (item == NULL)
86 return NULL;
87 if (lz->start == 1)
88 return item;
89
90 good = PyObject_CallFunctionObjArgs(lz->func, item, NULL);
91 if (good == NULL) {
92 Py_DECREF(item);
93 return NULL;
94 }
95 ok = PyObject_IsTrue(good);
96 Py_DECREF(good);
97 if (!ok) {
98 lz->start = 1;
99 return item;
100 }
101 Py_DECREF(item);
102 }
103}
104
105static PyObject *
106dropwhile_getiter(PyObject *lz)
107{
108 Py_INCREF(lz);
109 return lz;
110}
111
112PyDoc_STRVAR(dropwhile_doc,
113"dropwhile(predicate, iterable) --> dropwhile object\n\
114\n\
115Drop items from the iterable while predicate(item) is true.\n\
116Afterwards, return every element until the iterable is exhausted.");
117
118PyTypeObject dropwhile_type = {
119 PyObject_HEAD_INIT(NULL)
120 0, /* ob_size */
121 "itertools.dropwhile", /* tp_name */
122 sizeof(dropwhileobject), /* tp_basicsize */
123 0, /* tp_itemsize */
124 /* methods */
125 (destructor)dropwhile_dealloc, /* tp_dealloc */
126 0, /* tp_print */
127 0, /* tp_getattr */
128 0, /* tp_setattr */
129 0, /* tp_compare */
130 0, /* tp_repr */
131 0, /* tp_as_number */
132 0, /* tp_as_sequence */
133 0, /* tp_as_mapping */
134 0, /* tp_hash */
135 0, /* tp_call */
136 0, /* tp_str */
137 PyObject_GenericGetAttr, /* tp_getattro */
138 0, /* tp_setattro */
139 0, /* tp_as_buffer */
140 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
141 Py_TPFLAGS_BASETYPE, /* tp_flags */
142 dropwhile_doc, /* tp_doc */
143 (traverseproc)dropwhile_traverse, /* tp_traverse */
144 0, /* tp_clear */
145 0, /* tp_richcompare */
146 0, /* tp_weaklistoffset */
147 (getiterfunc)dropwhile_getiter, /* tp_iter */
148 (iternextfunc)dropwhile_next, /* tp_iternext */
149 0, /* tp_methods */
150 0, /* tp_members */
151 0, /* tp_getset */
152 0, /* tp_base */
153 0, /* tp_dict */
154 0, /* tp_descr_get */
155 0, /* tp_descr_set */
156 0, /* tp_dictoffset */
157 0, /* tp_init */
158 PyType_GenericAlloc, /* tp_alloc */
159 dropwhile_new, /* tp_new */
160 PyObject_GC_Del, /* tp_free */
161};
162
163
164/* takewhile object **********************************************************/
165
166typedef struct {
167 PyObject_HEAD
168 PyObject *func;
169 PyObject *it;
170 long stop;
171} takewhileobject;
172
173PyTypeObject takewhile_type;
174
175static PyObject *
176takewhile_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
177{
178 PyObject *func, *seq;
179 PyObject *it;
180 takewhileobject *lz;
181
182 if (!PyArg_UnpackTuple(args, "takewhile", 2, 2, &func, &seq))
183 return NULL;
184
185 /* Get iterator. */
186 it = PyObject_GetIter(seq);
187 if (it == NULL)
188 return NULL;
189
190 /* create takewhileobject structure */
191 lz = (takewhileobject *)type->tp_alloc(type, 0);
192 if (lz == NULL) {
193 Py_DECREF(it);
194 return NULL;
195 }
196 Py_INCREF(func);
197 lz->func = func;
198 lz->it = it;
199 lz->stop = 0;
200
201 return (PyObject *)lz;
202}
203
204static void
205takewhile_dealloc(takewhileobject *lz)
206{
207 PyObject_GC_UnTrack(lz);
208 Py_XDECREF(lz->func);
209 Py_XDECREF(lz->it);
210 lz->ob_type->tp_free(lz);
211}
212
213static int
214takewhile_traverse(takewhileobject *lz, visitproc visit, void *arg)
215{
216 int err;
217
218 if (lz->it) {
219 err = visit(lz->it, arg);
220 if (err)
221 return err;
222 }
223 if (lz->func) {
224 err = visit(lz->func, arg);
225 if (err)
226 return err;
227 }
228 return 0;
229}
230
231static PyObject *
232takewhile_next(takewhileobject *lz)
233{
234 PyObject *item, *good;
235 long ok;
236
237 if (lz->stop == 1)
238 return NULL;
239
240 item = PyIter_Next(lz->it);
241 if (item == NULL)
242 return NULL;
243
244 good = PyObject_CallFunctionObjArgs(lz->func, item, NULL);
245 if (good == NULL) {
246 Py_DECREF(item);
247 return NULL;
248 }
249 ok = PyObject_IsTrue(good);
250 Py_DECREF(good);
251 if (ok)
252 return item;
253 Py_DECREF(item);
254 lz->stop = 1;
255 return NULL;
256}
257
258static PyObject *
259takewhile_getiter(PyObject *lz)
260{
261 Py_INCREF(lz);
262 return lz;
263}
264
265PyDoc_STRVAR(takewhile_doc,
266"takewhile(predicate, iterable) --> takewhile object\n\
267\n\
268Return successive entries from an iterable as long as the \n\
269predicate evaluates to true for each entry.");
270
271PyTypeObject takewhile_type = {
272 PyObject_HEAD_INIT(NULL)
273 0, /* ob_size */
274 "itertools.takewhile", /* tp_name */
275 sizeof(takewhileobject), /* tp_basicsize */
276 0, /* tp_itemsize */
277 /* methods */
278 (destructor)takewhile_dealloc, /* tp_dealloc */
279 0, /* tp_print */
280 0, /* tp_getattr */
281 0, /* tp_setattr */
282 0, /* tp_compare */
283 0, /* tp_repr */
284 0, /* tp_as_number */
285 0, /* tp_as_sequence */
286 0, /* tp_as_mapping */
287 0, /* tp_hash */
288 0, /* tp_call */
289 0, /* tp_str */
290 PyObject_GenericGetAttr, /* tp_getattro */
291 0, /* tp_setattro */
292 0, /* tp_as_buffer */
293 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
294 Py_TPFLAGS_BASETYPE, /* tp_flags */
295 takewhile_doc, /* tp_doc */
296 (traverseproc)takewhile_traverse, /* tp_traverse */
297 0, /* tp_clear */
298 0, /* tp_richcompare */
299 0, /* tp_weaklistoffset */
300 (getiterfunc)takewhile_getiter, /* tp_iter */
301 (iternextfunc)takewhile_next, /* tp_iternext */
302 0, /* tp_methods */
303 0, /* tp_members */
304 0, /* tp_getset */
305 0, /* tp_base */
306 0, /* tp_dict */
307 0, /* tp_descr_get */
308 0, /* tp_descr_set */
309 0, /* tp_dictoffset */
310 0, /* tp_init */
311 PyType_GenericAlloc, /* tp_alloc */
312 takewhile_new, /* tp_new */
313 PyObject_GC_Del, /* tp_free */
314};
315
316
317/* islice object ************************************************************/
318
319typedef struct {
320 PyObject_HEAD
321 PyObject *it;
322 long next;
323 long stop;
324 long step;
325 long cnt;
326} isliceobject;
327
328PyTypeObject islice_type;
329
330static PyObject *
331islice_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
332{
333 PyObject *seq;
334 long a1=0, a2=0, a3=0, start=0, stop=0, step=1;
335 PyObject *it;
336 int numargs;
337 isliceobject *lz;
338
339 numargs = PyTuple_Size(args);
340 if (!PyArg_ParseTuple(args, "Ol|ll:islice", &seq, &a1, &a2, &a3))
341 return NULL;
342
343 if (numargs == 2) {
344 stop = a1;
345 } else if (numargs == 3) {
346 start = a1;
347 stop = a2;
348 } else {
349 start = a1;
350 stop = a2;
351 step = a3;
352 }
353
354 if (start<0 || stop<0) {
355 PyErr_SetString(PyExc_ValueError,
356 "Indices for islice() must be positive.");
357 return NULL;
358 }
359
360 if (step<1) {
361 PyErr_SetString(PyExc_ValueError,
362 "Step must be one or larger for islice().");
363 return NULL;
364 }
365
366 /* Get iterator. */
367 it = PyObject_GetIter(seq);
368 if (it == NULL)
369 return NULL;
370
371 /* create isliceobject structure */
372 lz = (isliceobject *)type->tp_alloc(type, 0);
373 if (lz == NULL) {
374 Py_DECREF(it);
375 return NULL;
376 }
377 lz->it = it;
378 lz->next = start;
379 lz->stop = stop;
380 lz->step = step;
381 lz->cnt = 0L;
382
383 return (PyObject *)lz;
384}
385
386static void
387islice_dealloc(isliceobject *lz)
388{
389 PyObject_GC_UnTrack(lz);
390 Py_XDECREF(lz->it);
391 lz->ob_type->tp_free(lz);
392}
393
394static int
395islice_traverse(isliceobject *lz, visitproc visit, void *arg)
396{
397 if (lz->it)
398 return visit(lz->it, arg);
399 return 0;
400}
401
402static PyObject *
403islice_next(isliceobject *lz)
404{
405 PyObject *item;
Raymond Hettinger2012f172003-02-07 05:32:58 +0000406 long oldnext;
Raymond Hettinger96ef8112003-02-01 00:10:11 +0000407
408 while (lz->cnt < lz->next) {
409 item = PyIter_Next(lz->it);
410 if (item == NULL)
411 return NULL;
412 Py_DECREF(item);
413 lz->cnt++;
414 }
415 if (lz->cnt >= lz->stop)
416 return NULL;
417 item = PyIter_Next(lz->it);
418 if (item == NULL)
419 return NULL;
420 lz->cnt++;
Raymond Hettinger2012f172003-02-07 05:32:58 +0000421 oldnext = lz->next;
Raymond Hettinger96ef8112003-02-01 00:10:11 +0000422 lz->next += lz->step;
Raymond Hettinger2012f172003-02-07 05:32:58 +0000423 if (lz->next < oldnext) /* Check for overflow */
424 lz->next = lz->stop;
Raymond Hettinger96ef8112003-02-01 00:10:11 +0000425 return item;
426}
427
428static PyObject *
429islice_getiter(PyObject *lz)
430{
431 Py_INCREF(lz);
432 return lz;
433}
434
435PyDoc_STRVAR(islice_doc,
436"islice(iterable, [start,] stop [, step]) --> islice object\n\
437\n\
438Return an iterator whose next() method returns selected values from an\n\
439iterable. If start is specified, will skip all preceding elements;\n\
440otherwise, start defaults to zero. Step defaults to one. If\n\
441specified as another value, step determines how many values are \n\
442skipped between successive calls. Works like a slice() on a list\n\
443but returns an iterator.");
444
445PyTypeObject islice_type = {
446 PyObject_HEAD_INIT(NULL)
447 0, /* ob_size */
448 "itertools.islice", /* tp_name */
449 sizeof(isliceobject), /* tp_basicsize */
450 0, /* tp_itemsize */
451 /* methods */
452 (destructor)islice_dealloc, /* tp_dealloc */
453 0, /* tp_print */
454 0, /* tp_getattr */
455 0, /* tp_setattr */
456 0, /* tp_compare */
457 0, /* tp_repr */
458 0, /* tp_as_number */
459 0, /* tp_as_sequence */
460 0, /* tp_as_mapping */
461 0, /* tp_hash */
462 0, /* tp_call */
463 0, /* tp_str */
464 PyObject_GenericGetAttr, /* tp_getattro */
465 0, /* tp_setattro */
466 0, /* tp_as_buffer */
467 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
468 Py_TPFLAGS_BASETYPE, /* tp_flags */
469 islice_doc, /* tp_doc */
470 (traverseproc)islice_traverse, /* tp_traverse */
471 0, /* tp_clear */
472 0, /* tp_richcompare */
473 0, /* tp_weaklistoffset */
474 (getiterfunc)islice_getiter, /* tp_iter */
475 (iternextfunc)islice_next, /* tp_iternext */
476 0, /* tp_methods */
477 0, /* tp_members */
478 0, /* tp_getset */
479 0, /* tp_base */
480 0, /* tp_dict */
481 0, /* tp_descr_get */
482 0, /* tp_descr_set */
483 0, /* tp_dictoffset */
484 0, /* tp_init */
485 PyType_GenericAlloc, /* tp_alloc */
486 islice_new, /* tp_new */
487 PyObject_GC_Del, /* tp_free */
488};
489
490
491/* starmap object ************************************************************/
492
493typedef struct {
494 PyObject_HEAD
495 PyObject *func;
496 PyObject *it;
497} starmapobject;
498
499PyTypeObject starmap_type;
500
501static PyObject *
502starmap_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
503{
504 PyObject *func, *seq;
505 PyObject *it;
506 starmapobject *lz;
507
508 if (!PyArg_UnpackTuple(args, "starmap", 2, 2, &func, &seq))
509 return NULL;
510
511 /* Get iterator. */
512 it = PyObject_GetIter(seq);
513 if (it == NULL)
514 return NULL;
515
516 /* create starmapobject structure */
517 lz = (starmapobject *)type->tp_alloc(type, 0);
518 if (lz == NULL) {
519 Py_DECREF(it);
520 return NULL;
521 }
522 Py_INCREF(func);
523 lz->func = func;
524 lz->it = it;
525
526 return (PyObject *)lz;
527}
528
529static void
530starmap_dealloc(starmapobject *lz)
531{
532 PyObject_GC_UnTrack(lz);
533 Py_XDECREF(lz->func);
534 Py_XDECREF(lz->it);
535 lz->ob_type->tp_free(lz);
536}
537
538static int
539starmap_traverse(starmapobject *lz, visitproc visit, void *arg)
540{
541 int err;
542
543 if (lz->it) {
544 err = visit(lz->it, arg);
545 if (err)
546 return err;
547 }
548 if (lz->func) {
549 err = visit(lz->func, arg);
550 if (err)
551 return err;
552 }
553 return 0;
554}
555
556static PyObject *
557starmap_next(starmapobject *lz)
558{
559 PyObject *args;
560 PyObject *result;
561
562 args = PyIter_Next(lz->it);
563 if (args == NULL)
564 return NULL;
Raymond Hettinger2012f172003-02-07 05:32:58 +0000565 if (!PyTuple_CheckExact(args)) {
566 Py_DECREF(args);
567 PyErr_SetString(PyExc_TypeError,
568 "iterator must return a tuple");
569 return NULL;
570 }
Raymond Hettinger96ef8112003-02-01 00:10:11 +0000571 result = PyObject_Call(lz->func, args, NULL);
572 Py_DECREF(args);
573 return result;
574}
575
576static PyObject *
577starmap_getiter(PyObject *lz)
578{
579 Py_INCREF(lz);
580 return lz;
581}
582
583PyDoc_STRVAR(starmap_doc,
584"starmap(function, sequence) --> starmap object\n\
585\n\
586Return an iterator whose values are returned from the function evaluated\n\
587with a argument tuple taken from the given sequence.");
588
589PyTypeObject starmap_type = {
590 PyObject_HEAD_INIT(NULL)
591 0, /* ob_size */
592 "itertools.starmap", /* tp_name */
593 sizeof(starmapobject), /* tp_basicsize */
594 0, /* tp_itemsize */
595 /* methods */
596 (destructor)starmap_dealloc, /* tp_dealloc */
597 0, /* tp_print */
598 0, /* tp_getattr */
599 0, /* tp_setattr */
600 0, /* tp_compare */
601 0, /* tp_repr */
602 0, /* tp_as_number */
603 0, /* tp_as_sequence */
604 0, /* tp_as_mapping */
605 0, /* tp_hash */
606 0, /* tp_call */
607 0, /* tp_str */
608 PyObject_GenericGetAttr, /* tp_getattro */
609 0, /* tp_setattro */
610 0, /* tp_as_buffer */
611 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
612 Py_TPFLAGS_BASETYPE, /* tp_flags */
613 starmap_doc, /* tp_doc */
614 (traverseproc)starmap_traverse, /* tp_traverse */
615 0, /* tp_clear */
616 0, /* tp_richcompare */
617 0, /* tp_weaklistoffset */
618 (getiterfunc)starmap_getiter, /* tp_iter */
619 (iternextfunc)starmap_next, /* tp_iternext */
620 0, /* tp_methods */
621 0, /* tp_members */
622 0, /* tp_getset */
623 0, /* tp_base */
624 0, /* tp_dict */
625 0, /* tp_descr_get */
626 0, /* tp_descr_set */
627 0, /* tp_dictoffset */
628 0, /* tp_init */
629 PyType_GenericAlloc, /* tp_alloc */
630 starmap_new, /* tp_new */
631 PyObject_GC_Del, /* tp_free */
632};
633
634
635/* imap object ************************************************************/
636
637typedef struct {
638 PyObject_HEAD
639 PyObject *iters;
640 PyObject *argtuple;
641 PyObject *func;
642} imapobject;
643
644PyTypeObject imap_type;
645
646static PyObject *
647imap_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
648{
649 PyObject *it, *iters, *argtuple, *func;
650 imapobject *lz;
651 int numargs, i;
652
653 numargs = PyTuple_Size(args);
654 if (numargs < 2) {
655 PyErr_SetString(PyExc_TypeError,
656 "imap() must have at least two arguments.");
657 return NULL;
658 }
659
660 iters = PyTuple_New(numargs-1);
661 if (iters == NULL)
662 return NULL;
663
664 argtuple = PyTuple_New(numargs-1);
665 if (argtuple == NULL) {
666 Py_DECREF(iters);
667 return NULL;
668 }
669
670 for (i=1 ; i<numargs ; i++) {
671 /* Get iterator. */
672 it = PyObject_GetIter(PyTuple_GET_ITEM(args, i));
673 if (it == NULL) {
674 Py_DECREF(argtuple);
675 Py_DECREF(iters);
676 return NULL;
677 }
678 PyTuple_SET_ITEM(iters, i-1, it);
679 Py_INCREF(Py_None);
680 PyTuple_SET_ITEM(argtuple, i-1, Py_None);
681 }
682
683 /* create imapobject structure */
684 lz = (imapobject *)type->tp_alloc(type, 0);
685 if (lz == NULL) {
686 Py_DECREF(argtuple);
687 Py_DECREF(iters);
688 return NULL;
689 }
690 lz->iters = iters;
691 lz->argtuple = argtuple;
692 func = PyTuple_GET_ITEM(args, 0);
693 Py_INCREF(func);
694 lz->func = func;
695
696 return (PyObject *)lz;
697}
698
699static void
700imap_dealloc(imapobject *lz)
701{
702 PyObject_GC_UnTrack(lz);
703 Py_XDECREF(lz->argtuple);
704 Py_XDECREF(lz->iters);
705 Py_XDECREF(lz->func);
706 lz->ob_type->tp_free(lz);
707}
708
709static int
710imap_traverse(imapobject *lz, visitproc visit, void *arg)
711{
712 int err;
713
714 if (lz->iters) {
715 err = visit(lz->iters, arg);
716 if (err)
717 return err;
718 }
719 if (lz->argtuple) {
720 err = visit(lz->argtuple, arg);
721 if (err)
722 return err;
723 }
724 if (lz->func) {
725 err = visit(lz->func, arg);
726 if (err)
727 return err;
728 }
729 return 0;
730}
731
Raymond Hettinger2012f172003-02-07 05:32:58 +0000732/*
733imap() is an iterator version of __builtins__.map() except that it does
734not have the None fill-in feature. That was intentionally left out for
735the following reasons:
736
737 1) Itertools are designed to be easily combined and chained together.
738 Having all tools stop with the shortest input is a unifying principle
739 that makes it easier to combine finite iterators (supplying data) with
740 infinite iterators like count() and repeat() (for supplying sequential
741 or constant arguments to a function).
742
743 2) In typical use cases for combining itertools, having one finite data
744 supplier run out before another is likely to be an error condition which
745 should not pass silently by automatically supplying None.
746
747 3) The use cases for automatic None fill-in are rare -- not many functions
748 do something useful when a parameter suddenly switches type and becomes
749 None.
750
751 4) If a need does arise, it can be met by __builtins__.map() or by
752 writing a generator.
753
754 5) Similar toolsets in Haskell and SML do not have automatic None fill-in.
755*/
756
Raymond Hettinger96ef8112003-02-01 00:10:11 +0000757static PyObject *
758imap_next(imapobject *lz)
759{
760 PyObject *val;
761 PyObject *argtuple=lz->argtuple;
762 int numargs, i;
763
764 numargs = PyTuple_Size(lz->iters);
765 if (lz->func == Py_None) {
766 argtuple = PyTuple_New(numargs);
767 if (argtuple == NULL)
768 return NULL;
769
770 for (i=0 ; i<numargs ; i++) {
771 val = PyIter_Next(PyTuple_GET_ITEM(lz->iters, i));
772 if (val == NULL) {
773 Py_DECREF(argtuple);
774 return NULL;
775 }
776 PyTuple_SET_ITEM(argtuple, i, val);
777 }
778 return argtuple;
779 } else {
Raymond Hettinger2012f172003-02-07 05:32:58 +0000780 if (argtuple->ob_refcnt > 1) {
781 argtuple = PyTuple_New(numargs);
782 if (argtuple == NULL)
783 return NULL;
784 }
Raymond Hettinger96ef8112003-02-01 00:10:11 +0000785 for (i=0 ; i<numargs ; i++) {
786 val = PyIter_Next(PyTuple_GET_ITEM(lz->iters, i));
787 if (val == NULL)
788 return NULL;
789 Py_DECREF(PyTuple_GET_ITEM(argtuple, i));
790 PyTuple_SET_ITEM(argtuple, i, val);
791 }
792 return PyObject_Call(lz->func, argtuple, NULL);
793 }
794}
795
796static PyObject *
797imap_getiter(PyObject *lz)
798{
799 Py_INCREF(lz);
800 return lz;
801}
802
803PyDoc_STRVAR(imap_doc,
804"imap(func, *iterables) --> imap object\n\
805\n\
806Make an iterator that computes the function using arguments from\n\
807each of the iterables. Like map() except that it returns\n\
808an iterator instead of a list and that it stops when the shortest\n\
809iterable is exhausted instead of filling in None for shorter\n\
810iterables.");
811
812PyTypeObject imap_type = {
813 PyObject_HEAD_INIT(NULL)
814 0, /* ob_size */
815 "itertools.imap", /* tp_name */
816 sizeof(imapobject), /* tp_basicsize */
817 0, /* tp_itemsize */
818 /* methods */
819 (destructor)imap_dealloc, /* tp_dealloc */
820 0, /* tp_print */
821 0, /* tp_getattr */
822 0, /* tp_setattr */
823 0, /* tp_compare */
824 0, /* tp_repr */
825 0, /* tp_as_number */
826 0, /* tp_as_sequence */
827 0, /* tp_as_mapping */
828 0, /* tp_hash */
829 0, /* tp_call */
830 0, /* tp_str */
831 PyObject_GenericGetAttr, /* tp_getattro */
832 0, /* tp_setattro */
833 0, /* tp_as_buffer */
834 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
835 Py_TPFLAGS_BASETYPE, /* tp_flags */
836 imap_doc, /* tp_doc */
837 (traverseproc)imap_traverse, /* tp_traverse */
838 0, /* tp_clear */
839 0, /* tp_richcompare */
840 0, /* tp_weaklistoffset */
841 (getiterfunc)imap_getiter, /* tp_iter */
842 (iternextfunc)imap_next, /* tp_iternext */
843 0, /* tp_methods */
844 0, /* tp_members */
845 0, /* tp_getset */
846 0, /* tp_base */
847 0, /* tp_dict */
848 0, /* tp_descr_get */
849 0, /* tp_descr_set */
850 0, /* tp_dictoffset */
851 0, /* tp_init */
852 PyType_GenericAlloc, /* tp_alloc */
853 imap_new, /* tp_new */
854 PyObject_GC_Del, /* tp_free */
855};
856
857
858/* times object ************************************************************/
859
860typedef struct {
861 PyObject_HEAD
862 PyObject *obj;
863 long cnt;
864} timesobject;
865
866PyTypeObject times_type;
867
868static PyObject *
869times_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
870{
871 timesobject *lz;
872 PyObject *obj = Py_None;
873 long cnt;
874
875 if (!PyArg_ParseTuple(args, "l|O:times", &cnt, &obj))
876 return NULL;
877
878 if (cnt < 0) {
879 PyErr_SetString(PyExc_ValueError,
Raymond Hettinger2012f172003-02-07 05:32:58 +0000880 "count for times() cannot be negative.");
Raymond Hettinger96ef8112003-02-01 00:10:11 +0000881 return NULL;
882 }
883
884 /* create timesobject structure */
885 lz = (timesobject *)type->tp_alloc(type, 0);
886 if (lz == NULL)
887 return NULL;
888 lz->cnt = cnt;
889 Py_INCREF(obj);
890 lz->obj = obj;
891
892 return (PyObject *)lz;
893}
894
895static void
896times_dealloc(timesobject *lz)
897{
898 PyObject_GC_UnTrack(lz);
899 Py_XDECREF(lz->obj);
900 lz->ob_type->tp_free(lz);
901}
902
Raymond Hettinger2012f172003-02-07 05:32:58 +0000903static int
904times_traverse(timesobject *lz, visitproc visit, void *arg)
905{
906 if (lz->obj)
907 return visit(lz->obj, arg);
908 return 0;
909}
910
Raymond Hettinger96ef8112003-02-01 00:10:11 +0000911static PyObject *
912times_next(timesobject *lz)
913{
914 PyObject *obj = lz->obj;
915
916 if (lz->cnt > 0) {
917 lz->cnt--;
918 Py_INCREF(obj);
919 return obj;
920 }
921 return NULL;
922}
923
924static PyObject *
925times_getiter(PyObject *lz)
926{
927 Py_INCREF(lz);
928 return lz;
929}
930
931PyDoc_STRVAR(times_doc,
932"times(n [,obj]) --> times object\n\
933\n\
934Return a times object whose .next() method returns n consecutive\n\
935instances of obj (default is None).");
936
937PyTypeObject times_type = {
938 PyObject_HEAD_INIT(NULL)
939 0, /* ob_size */
940 "itertools.times", /* tp_name */
941 sizeof(timesobject), /* tp_basicsize */
942 0, /* tp_itemsize */
943 /* methods */
944 (destructor)times_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 times_doc, /* tp_doc */
Raymond Hettinger2012f172003-02-07 05:32:58 +0000962 (traverseproc)times_traverse, /* tp_traverse */
Raymond Hettinger96ef8112003-02-01 00:10:11 +0000963 0, /* tp_clear */
964 0, /* tp_richcompare */
965 0, /* tp_weaklistoffset */
966 (getiterfunc)times_getiter, /* tp_iter */
967 (iternextfunc)times_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 PyType_GenericAlloc, /* tp_alloc */
978 times_new, /* tp_new */
979 PyObject_GC_Del, /* tp_free */
980};
981
982
983/* ifilter object ************************************************************/
984
985typedef struct {
986 PyObject_HEAD
987 PyObject *func;
988 PyObject *it;
989 long invert;
990} ifilterobject;
991
992PyTypeObject ifilter_type;
993
994static PyObject *
995ifilter_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
996{
997 PyObject *func, *seq, *invert=NULL;
998 PyObject *it;
999 ifilterobject *lz;
1000 long inv=0;
1001
1002 if (!PyArg_UnpackTuple(args, "ifilter", 2, 3, &func, &seq, &invert))
1003 return NULL;
1004
1005 if (invert != NULL && PyObject_IsTrue(invert))
1006 inv = 1;
1007
1008 /* Get iterator. */
1009 it = PyObject_GetIter(seq);
1010 if (it == NULL)
1011 return NULL;
1012
1013 /* create ifilterobject structure */
1014 lz = (ifilterobject *)type->tp_alloc(type, 0);
1015 if (lz == NULL) {
1016 Py_DECREF(it);
1017 return NULL;
1018 }
1019 Py_INCREF(func);
1020 lz->func = func;
1021 lz->it = it;
1022 lz->invert = inv;
1023
1024 return (PyObject *)lz;
1025}
1026
1027static void
1028ifilter_dealloc(ifilterobject *lz)
1029{
1030 PyObject_GC_UnTrack(lz);
1031 Py_XDECREF(lz->func);
1032 Py_XDECREF(lz->it);
1033 lz->ob_type->tp_free(lz);
1034}
1035
1036static int
1037ifilter_traverse(ifilterobject *lz, visitproc visit, void *arg)
1038{
1039 int err;
1040
1041 if (lz->it) {
1042 err = visit(lz->it, arg);
1043 if (err)
1044 return err;
1045 }
1046 if (lz->func) {
1047 err = visit(lz->func, arg);
1048 if (err)
1049 return err;
1050 }
1051 return 0;
1052}
1053
1054static PyObject *
1055ifilter_next(ifilterobject *lz)
1056{
1057 PyObject *item;
1058 long ok;
1059
1060 for (;;) {
1061 item = PyIter_Next(lz->it);
1062 if (item == NULL)
1063 return NULL;
1064
1065 if (lz->func == Py_None) {
1066 ok = PyObject_IsTrue(item);
1067 } else {
1068 PyObject *good;
1069 good = PyObject_CallFunctionObjArgs(lz->func,
1070 item, NULL);
1071 if (good == NULL) {
1072 Py_DECREF(item);
1073 return NULL;
1074 }
1075 ok = PyObject_IsTrue(good);
1076 Py_DECREF(good);
1077 }
1078 if (ok ^ lz->invert)
1079 return item;
1080 Py_DECREF(item);
1081 }
1082}
1083
1084static PyObject *
1085ifilter_getiter(PyObject *lz)
1086{
1087 Py_INCREF(lz);
1088 return lz;
1089}
1090
1091PyDoc_STRVAR(ifilter_doc,
1092"ifilter(function or None, sequence [, invert]) --> ifilter object\n\
1093\n\
1094Return those items of sequence for which function(item) is true. If\n\
1095invert is set to True, return items for which function(item) if False.\n\
1096If function is None, return the items that are true (unless invert is set).");
1097
1098PyTypeObject ifilter_type = {
1099 PyObject_HEAD_INIT(NULL)
1100 0, /* ob_size */
1101 "itertools.ifilter", /* tp_name */
1102 sizeof(ifilterobject), /* tp_basicsize */
1103 0, /* tp_itemsize */
1104 /* methods */
1105 (destructor)ifilter_dealloc, /* tp_dealloc */
1106 0, /* tp_print */
1107 0, /* tp_getattr */
1108 0, /* tp_setattr */
1109 0, /* tp_compare */
1110 0, /* tp_repr */
1111 0, /* tp_as_number */
1112 0, /* tp_as_sequence */
1113 0, /* tp_as_mapping */
1114 0, /* tp_hash */
1115 0, /* tp_call */
1116 0, /* tp_str */
1117 PyObject_GenericGetAttr, /* tp_getattro */
1118 0, /* tp_setattro */
1119 0, /* tp_as_buffer */
1120 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
1121 Py_TPFLAGS_BASETYPE, /* tp_flags */
1122 ifilter_doc, /* tp_doc */
1123 (traverseproc)ifilter_traverse, /* tp_traverse */
1124 0, /* tp_clear */
1125 0, /* tp_richcompare */
1126 0, /* tp_weaklistoffset */
1127 (getiterfunc)ifilter_getiter, /* tp_iter */
1128 (iternextfunc)ifilter_next, /* tp_iternext */
1129 0, /* tp_methods */
1130 0, /* tp_members */
1131 0, /* tp_getset */
1132 0, /* tp_base */
1133 0, /* tp_dict */
1134 0, /* tp_descr_get */
1135 0, /* tp_descr_set */
1136 0, /* tp_dictoffset */
1137 0, /* tp_init */
1138 PyType_GenericAlloc, /* tp_alloc */
1139 ifilter_new, /* tp_new */
1140 PyObject_GC_Del, /* tp_free */
1141};
1142
1143
1144/* count object ************************************************************/
1145
1146typedef struct {
1147 PyObject_HEAD
1148 long cnt;
1149} countobject;
1150
1151PyTypeObject count_type;
1152
1153static PyObject *
1154count_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1155{
1156 countobject *lz;
1157 long cnt = 0;
1158
1159 if (!PyArg_ParseTuple(args, "|l:count", &cnt))
1160 return NULL;
1161
1162 /* create countobject structure */
1163 lz = (countobject *)PyObject_New(countobject, &count_type);
1164 if (lz == NULL)
1165 return NULL;
1166 lz->cnt = cnt;
1167
1168 return (PyObject *)lz;
1169}
1170
1171static PyObject *
1172count_next(countobject *lz)
1173{
1174 return PyInt_FromLong(lz->cnt++);
1175}
1176
1177static PyObject *
1178count_getiter(PyObject *lz)
1179{
1180 Py_INCREF(lz);
1181 return lz;
1182}
1183
1184PyDoc_STRVAR(count_doc,
1185"count([firstval]) --> count object\n\
1186\n\
1187Return a count object whose .next() method returns consecutive\n\
1188integers starting from zero or, if specified, from firstval.");
1189
1190PyTypeObject count_type = {
1191 PyObject_HEAD_INIT(NULL)
1192 0, /* ob_size */
1193 "itertools.count", /* tp_name */
1194 sizeof(countobject), /* tp_basicsize */
1195 0, /* tp_itemsize */
1196 /* methods */
1197 (destructor)PyObject_Del, /* tp_dealloc */
1198 0, /* tp_print */
1199 0, /* tp_getattr */
1200 0, /* tp_setattr */
1201 0, /* tp_compare */
1202 0, /* tp_repr */
1203 0, /* tp_as_number */
1204 0, /* tp_as_sequence */
1205 0, /* tp_as_mapping */
1206 0, /* tp_hash */
1207 0, /* tp_call */
1208 0, /* tp_str */
1209 PyObject_GenericGetAttr, /* tp_getattro */
1210 0, /* tp_setattro */
1211 0, /* tp_as_buffer */
1212 Py_TPFLAGS_DEFAULT, /* tp_flags */
1213 count_doc, /* tp_doc */
1214 0, /* tp_traverse */
1215 0, /* tp_clear */
1216 0, /* tp_richcompare */
1217 0, /* tp_weaklistoffset */
1218 (getiterfunc)count_getiter, /* tp_iter */
1219 (iternextfunc)count_next, /* tp_iternext */
1220 0, /* tp_methods */
1221 0, /* tp_members */
1222 0, /* tp_getset */
1223 0, /* tp_base */
1224 0, /* tp_dict */
1225 0, /* tp_descr_get */
1226 0, /* tp_descr_set */
1227 0, /* tp_dictoffset */
1228 0, /* tp_init */
1229 PyType_GenericAlloc, /* tp_alloc */
1230 count_new, /* tp_new */
1231};
1232
1233
1234/* izip object ************************************************************/
1235
1236#include "Python.h"
1237
1238typedef struct {
1239 PyObject_HEAD
1240 long tuplesize;
1241 PyObject *ittuple; /* tuple of iterators */
Raymond Hettinger2012f172003-02-07 05:32:58 +00001242 PyObject *result;
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001243} izipobject;
1244
1245PyTypeObject izip_type;
1246
1247static PyObject *
1248izip_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1249{
1250 izipobject *lz;
1251 int i;
1252 PyObject *ittuple; /* tuple of iterators */
Raymond Hettinger2012f172003-02-07 05:32:58 +00001253 PyObject *result;
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001254 int tuplesize = PySequence_Length(args);
1255
1256 if (tuplesize < 1) {
1257 PyErr_SetString(PyExc_TypeError,
1258 "izip() requires at least one sequence");
1259 return NULL;
1260 }
1261
1262 /* args must be a tuple */
1263 assert(PyTuple_Check(args));
1264
1265 /* obtain iterators */
1266 ittuple = PyTuple_New(tuplesize);
1267 if(ittuple == NULL)
1268 return NULL;
1269 for (i=0; i < tuplesize; ++i) {
1270 PyObject *item = PyTuple_GET_ITEM(args, i);
1271 PyObject *it = PyObject_GetIter(item);
1272 if (it == NULL) {
1273 if (PyErr_ExceptionMatches(PyExc_TypeError))
1274 PyErr_Format(PyExc_TypeError,
1275 "izip argument #%d must support iteration",
1276 i+1);
1277 Py_DECREF(ittuple);
1278 return NULL;
1279 }
1280 PyTuple_SET_ITEM(ittuple, i, it);
1281 }
1282
Raymond Hettinger2012f172003-02-07 05:32:58 +00001283 /* create a result holder */
1284 result = PyTuple_New(tuplesize);
1285 if (result == NULL) {
1286 Py_DECREF(ittuple);
1287 return NULL;
1288 }
1289 for (i=0 ; i < tuplesize ; i++) {
1290 Py_INCREF(Py_None);
1291 PyTuple_SET_ITEM(result, i, Py_None);
1292 }
1293
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001294 /* create izipobject structure */
1295 lz = (izipobject *)type->tp_alloc(type, 0);
1296 if (lz == NULL) {
1297 Py_DECREF(ittuple);
Raymond Hettinger2012f172003-02-07 05:32:58 +00001298 Py_DECREF(result);
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001299 return NULL;
1300 }
1301 lz->ittuple = ittuple;
1302 lz->tuplesize = tuplesize;
Raymond Hettinger2012f172003-02-07 05:32:58 +00001303 lz->result = result;
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001304
1305 return (PyObject *)lz;
1306}
1307
1308static void
1309izip_dealloc(izipobject *lz)
1310{
1311 PyObject_GC_UnTrack(lz);
1312 Py_XDECREF(lz->ittuple);
Raymond Hettinger2012f172003-02-07 05:32:58 +00001313 Py_XDECREF(lz->result);
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001314 lz->ob_type->tp_free(lz);
1315}
1316
1317static int
1318izip_traverse(izipobject *lz, visitproc visit, void *arg)
1319{
1320 if (lz->ittuple)
1321 return visit(lz->ittuple, arg);
1322 return 0;
1323}
1324
1325static PyObject *
1326izip_next(izipobject *lz)
1327{
1328 int i;
1329 long tuplesize = lz->tuplesize;
Raymond Hettinger2012f172003-02-07 05:32:58 +00001330 PyObject *result = lz->result;
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001331 PyObject *it;
1332 PyObject *item;
1333
Raymond Hettinger2012f172003-02-07 05:32:58 +00001334 assert(result->ob_refcnt >= 1);
1335 if (result->ob_refcnt == 1) {
1336 for (i=0 ; i < tuplesize ; i++) {
1337 Py_DECREF(PyTuple_GET_ITEM(result, i));
1338 PyTuple_SET_ITEM(result, i, NULL);
1339 }
1340 Py_INCREF(result);
1341 } else {
1342 Py_DECREF(result);
1343 result = PyTuple_New(tuplesize);
1344 if (result == NULL)
1345 return NULL;
1346 Py_INCREF(result);
1347 lz->result = result;
1348 }
1349 assert(lz->result == result);
1350 assert(result->ob_refcnt == 2);
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001351
1352 for (i=0 ; i < tuplesize ; i++) {
1353 it = PyTuple_GET_ITEM(lz->ittuple, i);
1354 item = PyIter_Next(it);
1355 if (item == NULL) {
1356 Py_DECREF(result);
1357 return NULL;
1358 }
1359 PyTuple_SET_ITEM(result, i, item);
1360 }
1361 return result;
1362}
1363
1364static PyObject *
1365izip_getiter(PyObject *lz)
1366{
1367 Py_INCREF(lz);
1368 return lz;
1369}
1370
1371PyDoc_STRVAR(izip_doc,
1372"izip(iter1 [,iter2 [...]]) --> izip object\n\
1373\n\
1374Return a izip object whose .next() method returns a tuple where\n\
1375the i-th element comes from the i-th iterable argument. The .next()\n\
1376method continues until the shortest iterable in the argument sequence\n\
1377is exhausted and then it raises StopIteration. Works like the zip()\n\
1378function but consumes less memory by returning an iterator instead of\n\
1379a list.");
1380
1381PyTypeObject izip_type = {
1382 PyObject_HEAD_INIT(NULL)
1383 0, /* ob_size */
1384 "itertools.izip", /* tp_name */
1385 sizeof(izipobject), /* tp_basicsize */
1386 0, /* tp_itemsize */
1387 /* methods */
1388 (destructor)izip_dealloc, /* tp_dealloc */
1389 0, /* tp_print */
1390 0, /* tp_getattr */
1391 0, /* tp_setattr */
1392 0, /* tp_compare */
1393 0, /* tp_repr */
1394 0, /* tp_as_number */
1395 0, /* tp_as_sequence */
1396 0, /* tp_as_mapping */
1397 0, /* tp_hash */
1398 0, /* tp_call */
1399 0, /* tp_str */
1400 PyObject_GenericGetAttr, /* tp_getattro */
1401 0, /* tp_setattro */
1402 0, /* tp_as_buffer */
1403 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
1404 Py_TPFLAGS_BASETYPE, /* tp_flags */
1405 izip_doc, /* tp_doc */
1406 (traverseproc)izip_traverse, /* tp_traverse */
1407 0, /* tp_clear */
1408 0, /* tp_richcompare */
1409 0, /* tp_weaklistoffset */
1410 (getiterfunc)izip_getiter, /* tp_iter */
1411 (iternextfunc)izip_next, /* tp_iternext */
1412 0, /* tp_methods */
1413 0, /* tp_members */
1414 0, /* tp_getset */
1415 0, /* tp_base */
1416 0, /* tp_dict */
1417 0, /* tp_descr_get */
1418 0, /* tp_descr_set */
1419 0, /* tp_dictoffset */
1420 0, /* tp_init */
1421 PyType_GenericAlloc, /* tp_alloc */
1422 izip_new, /* tp_new */
1423 PyObject_GC_Del, /* tp_free */
1424};
1425
1426
1427/* repeat object ************************************************************/
1428
1429typedef struct {
1430 PyObject_HEAD
1431 PyObject *element;
1432} repeatobject;
1433
1434PyTypeObject repeat_type;
1435
1436static PyObject *
1437repeat_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1438{
1439 repeatobject *ro;
1440 PyObject *element;
1441
1442 if (!PyArg_UnpackTuple(args, "repeat", 1, 1, &element))
1443 return NULL;
1444
1445 ro = (repeatobject *)type->tp_alloc(type, 0);
1446 if (ro == NULL)
1447 return NULL;
1448 Py_INCREF(element);
1449 ro->element = element;
1450 return (PyObject *)ro;
1451}
1452
1453static void
1454repeat_dealloc(repeatobject *ro)
1455{
1456 PyObject_GC_UnTrack(ro);
1457 Py_XDECREF(ro->element);
1458 ro->ob_type->tp_free(ro);
1459}
1460
1461static int
1462repeat_traverse(repeatobject *ro, visitproc visit, void *arg)
1463{
1464 if (ro->element)
1465 return visit(ro->element, arg);
1466 return 0;
1467}
1468
1469static PyObject *
1470repeat_next(repeatobject *ro)
1471{
1472 Py_INCREF(ro->element);
1473 return ro->element;
1474}
1475
1476static PyObject *
1477repeat_getiter(PyObject *ro)
1478{
1479 Py_INCREF(ro);
1480 return ro;
1481}
1482
1483PyDoc_STRVAR(repeat_doc,
1484"repeat(element) -> create an iterator which returns the element endlessly.");
1485
1486PyTypeObject repeat_type = {
1487 PyObject_HEAD_INIT(NULL)
1488 0, /* ob_size */
1489 "itertools.repeat", /* tp_name */
1490 sizeof(repeatobject), /* tp_basicsize */
1491 0, /* tp_itemsize */
1492 /* methods */
1493 (destructor)repeat_dealloc, /* tp_dealloc */
1494 0, /* tp_print */
1495 0, /* tp_getattr */
1496 0, /* tp_setattr */
1497 0, /* tp_compare */
1498 0, /* tp_repr */
1499 0, /* tp_as_number */
1500 0, /* tp_as_sequence */
1501 0, /* tp_as_mapping */
1502 0, /* tp_hash */
1503 0, /* tp_call */
1504 0, /* tp_str */
1505 PyObject_GenericGetAttr, /* tp_getattro */
1506 0, /* tp_setattro */
1507 0, /* tp_as_buffer */
1508 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
1509 Py_TPFLAGS_BASETYPE, /* tp_flags */
1510 repeat_doc, /* tp_doc */
1511 (traverseproc)repeat_traverse, /* tp_traverse */
1512 0, /* tp_clear */
1513 0, /* tp_richcompare */
1514 0, /* tp_weaklistoffset */
1515 (getiterfunc)repeat_getiter, /* tp_iter */
1516 (iternextfunc)repeat_next, /* tp_iternext */
1517 0, /* tp_methods */
1518 0, /* tp_members */
1519 0, /* tp_getset */
1520 0, /* tp_base */
1521 0, /* tp_dict */
1522 0, /* tp_descr_get */
1523 0, /* tp_descr_set */
1524 0, /* tp_dictoffset */
1525 0, /* tp_init */
1526 PyType_GenericAlloc, /* tp_alloc */
1527 repeat_new, /* tp_new */
1528 PyObject_GC_Del, /* tp_free */
1529};
1530
1531
1532/* module level code ********************************************************/
1533
1534PyDoc_STRVAR(module_doc,
1535"Functional tools for creating and using iterators.\n\
1536\n\
1537Infinite iterators:\n\
1538count([n]) --> n, n+1, n+2, ...\n\
1539repeat(elem) --> elem, elem, elem, ...\n\
1540\n\
1541Iterators terminating on the shortest input sequence:\n\
1542izip(p, q, ...) --> (p[0], q[0]), (p[1], q[1]), ... \n\
1543ifilter(pred, seq, invert=False) --> elements of seq where\n\
1544 pred(elem) is True (or False if invert is set)\n\
1545islice(seq, [start,] stop [, step]) --> elements from\n\
1546 seq[start:stop:step]\n\
1547imap(fun, p, q, ...) --> fun(p0, q0), fun(p1, q1), ...\n\
1548starmap(fun, seq) --> fun(*seq[0]), fun(*seq[1]), ...\n\
1549times(n, [obj]) --> obj, obj, ... for n times. obj defaults to None\n\
1550takewhile(pred, seq) --> seq[0], seq[1], until pred fails\n\
1551dropwhile(pred, seq) --> seq[n], seq[n+1], starting when pred fails\n\
1552");
1553
1554
1555PyMODINIT_FUNC
1556inititertools(void)
1557{
1558 PyObject *m;
1559 m = Py_InitModule3("itertools", NULL, module_doc);
1560
1561 PyModule_AddObject(m, "dropwhile", (PyObject *)&dropwhile_type);
1562 if (PyType_Ready(&dropwhile_type) < 0)
1563 return;
1564 Py_INCREF(&dropwhile_type);
1565
1566 PyModule_AddObject(m, "takewhile", (PyObject *)&takewhile_type);
1567 if (PyType_Ready(&takewhile_type) < 0)
1568 return;
1569 Py_INCREF(&takewhile_type);
1570
1571 PyModule_AddObject(m, "islice", (PyObject *)&islice_type);
1572 if (PyType_Ready(&islice_type) < 0)
1573 return;
1574 Py_INCREF(&islice_type);
1575
1576 PyModule_AddObject(m, "starmap", (PyObject *)&starmap_type);
1577 if (PyType_Ready(&starmap_type) < 0)
1578 return;
1579 Py_INCREF(&starmap_type);
1580
1581 PyModule_AddObject(m, "imap", (PyObject *)&imap_type);
1582 if (PyType_Ready(&imap_type) < 0)
1583 return;
1584 Py_INCREF(&imap_type);
1585
1586 PyModule_AddObject(m, "times", (PyObject *)&times_type);
1587 if (PyType_Ready(&times_type) < 0)
1588 return;
1589 Py_INCREF(&times_type);
1590
1591 if (PyType_Ready(&ifilter_type) < 0)
1592 return;
1593 Py_INCREF(&ifilter_type);
1594 PyModule_AddObject(m, "ifilter", (PyObject *)&ifilter_type);
1595
1596 if (PyType_Ready(&count_type) < 0)
1597 return;
1598 Py_INCREF(&count_type);
1599 PyModule_AddObject(m, "count", (PyObject *)&count_type);
1600
1601 if (PyType_Ready(&izip_type) < 0)
1602 return;
1603 Py_INCREF(&izip_type);
1604 PyModule_AddObject(m, "izip", (PyObject *)&izip_type);
1605
1606 if (PyType_Ready(&repeat_type) < 0)
1607 return;
1608 Py_INCREF(&repeat_type);
1609 PyModule_AddObject(m, "repeat", (PyObject *)&repeat_type);
1610}