blob: 35fa1d07da92329fc940ff42faf07ae93cb14636 [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
Raymond Hettinger61fe64d2003-02-23 04:40:07 +000010/* cycle object **********************************************************/
11
12typedef struct {
13 PyObject_HEAD
14 PyObject *it;
15 PyObject *saved;
16 int firstpass;
17} cycleobject;
18
19PyTypeObject cycle_type;
20
21static PyObject *
22cycle_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
23{
24 PyObject *it;
25 PyObject *iterable;
26 PyObject *saved;
27 cycleobject *lz;
28
29 if (!PyArg_UnpackTuple(args, "cycle", 1, 1, &iterable))
30 return NULL;
31
32 /* Get iterator. */
33 it = PyObject_GetIter(iterable);
34 if (it == NULL)
35 return NULL;
36
37 saved = PyList_New(0);
38 if (saved == NULL) {
39 Py_DECREF(it);
40 return NULL;
41 }
42
43 /* create cycleobject structure */
44 lz = (cycleobject *)type->tp_alloc(type, 0);
45 if (lz == NULL) {
46 Py_DECREF(it);
47 Py_DECREF(saved);
48 return NULL;
49 }
50 lz->it = it;
51 lz->saved = saved;
52 lz->firstpass = 0;
53
54 return (PyObject *)lz;
55}
56
57static void
58cycle_dealloc(cycleobject *lz)
59{
60 PyObject_GC_UnTrack(lz);
61 Py_XDECREF(lz->saved);
62 Py_XDECREF(lz->it);
63 lz->ob_type->tp_free(lz);
64}
65
66static int
67cycle_traverse(cycleobject *lz, visitproc visit, void *arg)
68{
69 int err;
70
71 if (lz->it) {
72 err = visit(lz->it, arg);
73 if (err)
74 return err;
75 }
76 if (lz->saved) {
77 err = visit(lz->saved, arg);
78 if (err)
79 return err;
80 }
81 return 0;
82}
83
84static PyObject *
85cycle_next(cycleobject *lz)
86{
87 PyObject *item;
88 PyObject *it;
89
90 while (1) {
91 item = PyIter_Next(lz->it);
92 if (item != NULL) {
93 if (!lz->firstpass)
94 PyList_Append(lz->saved, item);
95 return item;
96 }
97 if (PyList_Size(lz->saved) == 0)
98 return NULL;
99 it = PyObject_GetIter(lz->saved);
100 if (it == NULL)
101 return NULL;
102 Py_DECREF(lz->it);
103 lz->it = it;
104 lz->firstpass = 1;
105 }
106}
107
Raymond Hettinger61fe64d2003-02-23 04:40:07 +0000108PyDoc_STRVAR(cycle_doc,
109"cycle(iterable) --> cycle object\n\
110\n\
111Return elements from the iterable until it is exhausted.\n\
112Then repeat the sequence indefinitely.");
113
114PyTypeObject cycle_type = {
115 PyObject_HEAD_INIT(NULL)
116 0, /* ob_size */
117 "itertools.cycle", /* tp_name */
118 sizeof(cycleobject), /* tp_basicsize */
119 0, /* tp_itemsize */
120 /* methods */
121 (destructor)cycle_dealloc, /* tp_dealloc */
122 0, /* tp_print */
123 0, /* tp_getattr */
124 0, /* tp_setattr */
125 0, /* tp_compare */
126 0, /* tp_repr */
127 0, /* tp_as_number */
128 0, /* tp_as_sequence */
129 0, /* tp_as_mapping */
130 0, /* tp_hash */
131 0, /* tp_call */
132 0, /* tp_str */
133 PyObject_GenericGetAttr, /* tp_getattro */
134 0, /* tp_setattro */
135 0, /* tp_as_buffer */
136 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
137 Py_TPFLAGS_BASETYPE, /* tp_flags */
138 cycle_doc, /* tp_doc */
139 (traverseproc)cycle_traverse, /* tp_traverse */
140 0, /* tp_clear */
141 0, /* tp_richcompare */
142 0, /* tp_weaklistoffset */
Raymond Hettinger1da1dbf2003-03-17 19:46:11 +0000143 PyObject_SelfIter, /* tp_iter */
Raymond Hettinger61fe64d2003-02-23 04:40:07 +0000144 (iternextfunc)cycle_next, /* tp_iternext */
145 0, /* tp_methods */
146 0, /* tp_members */
147 0, /* tp_getset */
148 0, /* tp_base */
149 0, /* tp_dict */
150 0, /* tp_descr_get */
151 0, /* tp_descr_set */
152 0, /* tp_dictoffset */
153 0, /* tp_init */
154 PyType_GenericAlloc, /* tp_alloc */
155 cycle_new, /* tp_new */
156 PyObject_GC_Del, /* tp_free */
157};
158
159
Raymond Hettinger96ef8112003-02-01 00:10:11 +0000160/* dropwhile object **********************************************************/
161
162typedef struct {
163 PyObject_HEAD
164 PyObject *func;
165 PyObject *it;
166 long start;
167} dropwhileobject;
168
169PyTypeObject dropwhile_type;
170
171static PyObject *
172dropwhile_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
173{
174 PyObject *func, *seq;
175 PyObject *it;
176 dropwhileobject *lz;
177
178 if (!PyArg_UnpackTuple(args, "dropwhile", 2, 2, &func, &seq))
179 return NULL;
180
181 /* Get iterator. */
182 it = PyObject_GetIter(seq);
183 if (it == NULL)
184 return NULL;
185
186 /* create dropwhileobject structure */
187 lz = (dropwhileobject *)type->tp_alloc(type, 0);
188 if (lz == NULL) {
189 Py_DECREF(it);
190 return NULL;
191 }
192 Py_INCREF(func);
193 lz->func = func;
194 lz->it = it;
195 lz->start = 0;
196
197 return (PyObject *)lz;
198}
199
200static void
201dropwhile_dealloc(dropwhileobject *lz)
202{
203 PyObject_GC_UnTrack(lz);
204 Py_XDECREF(lz->func);
205 Py_XDECREF(lz->it);
206 lz->ob_type->tp_free(lz);
207}
208
209static int
210dropwhile_traverse(dropwhileobject *lz, visitproc visit, void *arg)
211{
212 int err;
213
214 if (lz->it) {
215 err = visit(lz->it, arg);
216 if (err)
217 return err;
218 }
219 if (lz->func) {
220 err = visit(lz->func, arg);
221 if (err)
222 return err;
223 }
224 return 0;
225}
226
227static PyObject *
228dropwhile_next(dropwhileobject *lz)
229{
230 PyObject *item, *good;
Raymond Hettingerd1a283b2003-03-01 01:48:24 +0000231 PyObject *it = lz->it;
Raymond Hettinger96ef8112003-02-01 00:10:11 +0000232 long ok;
233
234 for (;;) {
Raymond Hettingerd1a283b2003-03-01 01:48:24 +0000235 assert(PyIter_Check(it));
236 item = (*it->ob_type->tp_iternext)(it);
Raymond Hettinger96ef8112003-02-01 00:10:11 +0000237 if (item == NULL)
238 return NULL;
239 if (lz->start == 1)
240 return item;
241
242 good = PyObject_CallFunctionObjArgs(lz->func, item, NULL);
243 if (good == NULL) {
244 Py_DECREF(item);
245 return NULL;
246 }
247 ok = PyObject_IsTrue(good);
248 Py_DECREF(good);
249 if (!ok) {
250 lz->start = 1;
251 return item;
252 }
253 Py_DECREF(item);
254 }
255}
256
Raymond Hettinger96ef8112003-02-01 00:10:11 +0000257PyDoc_STRVAR(dropwhile_doc,
258"dropwhile(predicate, iterable) --> dropwhile object\n\
259\n\
260Drop items from the iterable while predicate(item) is true.\n\
261Afterwards, return every element until the iterable is exhausted.");
262
263PyTypeObject dropwhile_type = {
264 PyObject_HEAD_INIT(NULL)
265 0, /* ob_size */
Raymond Hettinger60eca932003-02-09 06:40:58 +0000266 "itertools.dropwhile", /* tp_name */
267 sizeof(dropwhileobject), /* tp_basicsize */
Raymond Hettinger96ef8112003-02-01 00:10:11 +0000268 0, /* tp_itemsize */
269 /* methods */
Raymond Hettinger60eca932003-02-09 06:40:58 +0000270 (destructor)dropwhile_dealloc, /* tp_dealloc */
Raymond Hettinger96ef8112003-02-01 00:10:11 +0000271 0, /* tp_print */
272 0, /* tp_getattr */
273 0, /* tp_setattr */
274 0, /* tp_compare */
275 0, /* tp_repr */
276 0, /* tp_as_number */
277 0, /* tp_as_sequence */
278 0, /* tp_as_mapping */
279 0, /* tp_hash */
280 0, /* tp_call */
281 0, /* tp_str */
282 PyObject_GenericGetAttr, /* tp_getattro */
283 0, /* tp_setattro */
284 0, /* tp_as_buffer */
285 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
286 Py_TPFLAGS_BASETYPE, /* tp_flags */
Raymond Hettinger60eca932003-02-09 06:40:58 +0000287 dropwhile_doc, /* tp_doc */
Raymond Hettinger96ef8112003-02-01 00:10:11 +0000288 (traverseproc)dropwhile_traverse, /* tp_traverse */
289 0, /* tp_clear */
290 0, /* tp_richcompare */
291 0, /* tp_weaklistoffset */
Raymond Hettinger1da1dbf2003-03-17 19:46:11 +0000292 PyObject_SelfIter, /* tp_iter */
Raymond Hettinger60eca932003-02-09 06:40:58 +0000293 (iternextfunc)dropwhile_next, /* tp_iternext */
Raymond Hettinger96ef8112003-02-01 00:10:11 +0000294 0, /* tp_methods */
295 0, /* tp_members */
296 0, /* tp_getset */
297 0, /* tp_base */
298 0, /* tp_dict */
299 0, /* tp_descr_get */
300 0, /* tp_descr_set */
301 0, /* tp_dictoffset */
302 0, /* tp_init */
303 PyType_GenericAlloc, /* tp_alloc */
Raymond Hettinger60eca932003-02-09 06:40:58 +0000304 dropwhile_new, /* tp_new */
Raymond Hettinger96ef8112003-02-01 00:10:11 +0000305 PyObject_GC_Del, /* tp_free */
306};
307
308
309/* takewhile object **********************************************************/
310
311typedef struct {
312 PyObject_HEAD
313 PyObject *func;
314 PyObject *it;
315 long stop;
316} takewhileobject;
317
318PyTypeObject takewhile_type;
319
320static PyObject *
321takewhile_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
322{
323 PyObject *func, *seq;
324 PyObject *it;
325 takewhileobject *lz;
326
327 if (!PyArg_UnpackTuple(args, "takewhile", 2, 2, &func, &seq))
328 return NULL;
329
330 /* Get iterator. */
331 it = PyObject_GetIter(seq);
332 if (it == NULL)
333 return NULL;
334
335 /* create takewhileobject structure */
336 lz = (takewhileobject *)type->tp_alloc(type, 0);
337 if (lz == NULL) {
338 Py_DECREF(it);
339 return NULL;
340 }
341 Py_INCREF(func);
342 lz->func = func;
343 lz->it = it;
344 lz->stop = 0;
345
346 return (PyObject *)lz;
347}
348
349static void
350takewhile_dealloc(takewhileobject *lz)
351{
352 PyObject_GC_UnTrack(lz);
353 Py_XDECREF(lz->func);
354 Py_XDECREF(lz->it);
355 lz->ob_type->tp_free(lz);
356}
357
358static int
359takewhile_traverse(takewhileobject *lz, visitproc visit, void *arg)
360{
361 int err;
362
363 if (lz->it) {
364 err = visit(lz->it, arg);
365 if (err)
366 return err;
367 }
368 if (lz->func) {
369 err = visit(lz->func, arg);
370 if (err)
371 return err;
372 }
373 return 0;
374}
375
376static PyObject *
377takewhile_next(takewhileobject *lz)
378{
379 PyObject *item, *good;
Raymond Hettingerd1a283b2003-03-01 01:48:24 +0000380 PyObject *it = lz->it;
Raymond Hettinger96ef8112003-02-01 00:10:11 +0000381 long ok;
382
383 if (lz->stop == 1)
384 return NULL;
385
Raymond Hettingerd1a283b2003-03-01 01:48:24 +0000386 assert(PyIter_Check(it));
387 item = (*it->ob_type->tp_iternext)(it);
Raymond Hettinger96ef8112003-02-01 00:10:11 +0000388 if (item == NULL)
389 return NULL;
390
391 good = PyObject_CallFunctionObjArgs(lz->func, item, NULL);
392 if (good == NULL) {
393 Py_DECREF(item);
394 return NULL;
395 }
396 ok = PyObject_IsTrue(good);
397 Py_DECREF(good);
398 if (ok)
399 return item;
400 Py_DECREF(item);
401 lz->stop = 1;
402 return NULL;
403}
404
Raymond Hettinger96ef8112003-02-01 00:10:11 +0000405PyDoc_STRVAR(takewhile_doc,
406"takewhile(predicate, iterable) --> takewhile object\n\
407\n\
408Return successive entries from an iterable as long as the \n\
409predicate evaluates to true for each entry.");
410
411PyTypeObject takewhile_type = {
412 PyObject_HEAD_INIT(NULL)
413 0, /* ob_size */
Raymond Hettinger60eca932003-02-09 06:40:58 +0000414 "itertools.takewhile", /* tp_name */
415 sizeof(takewhileobject), /* tp_basicsize */
Raymond Hettinger96ef8112003-02-01 00:10:11 +0000416 0, /* tp_itemsize */
417 /* methods */
Raymond Hettinger60eca932003-02-09 06:40:58 +0000418 (destructor)takewhile_dealloc, /* tp_dealloc */
Raymond Hettinger96ef8112003-02-01 00:10:11 +0000419 0, /* tp_print */
420 0, /* tp_getattr */
421 0, /* tp_setattr */
422 0, /* tp_compare */
423 0, /* tp_repr */
424 0, /* tp_as_number */
425 0, /* tp_as_sequence */
426 0, /* tp_as_mapping */
427 0, /* tp_hash */
428 0, /* tp_call */
429 0, /* tp_str */
430 PyObject_GenericGetAttr, /* tp_getattro */
431 0, /* tp_setattro */
432 0, /* tp_as_buffer */
433 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
434 Py_TPFLAGS_BASETYPE, /* tp_flags */
Raymond Hettinger60eca932003-02-09 06:40:58 +0000435 takewhile_doc, /* tp_doc */
Raymond Hettinger96ef8112003-02-01 00:10:11 +0000436 (traverseproc)takewhile_traverse, /* tp_traverse */
437 0, /* tp_clear */
438 0, /* tp_richcompare */
439 0, /* tp_weaklistoffset */
Raymond Hettinger1da1dbf2003-03-17 19:46:11 +0000440 PyObject_SelfIter, /* tp_iter */
Raymond Hettinger60eca932003-02-09 06:40:58 +0000441 (iternextfunc)takewhile_next, /* tp_iternext */
Raymond Hettinger96ef8112003-02-01 00:10:11 +0000442 0, /* tp_methods */
443 0, /* tp_members */
444 0, /* tp_getset */
445 0, /* tp_base */
446 0, /* tp_dict */
447 0, /* tp_descr_get */
448 0, /* tp_descr_set */
449 0, /* tp_dictoffset */
450 0, /* tp_init */
451 PyType_GenericAlloc, /* tp_alloc */
Raymond Hettinger60eca932003-02-09 06:40:58 +0000452 takewhile_new, /* tp_new */
Raymond Hettinger96ef8112003-02-01 00:10:11 +0000453 PyObject_GC_Del, /* tp_free */
454};
455
456
457/* islice object ************************************************************/
458
459typedef struct {
460 PyObject_HEAD
461 PyObject *it;
462 long next;
463 long stop;
464 long step;
465 long cnt;
466} isliceobject;
467
468PyTypeObject islice_type;
469
470static PyObject *
471islice_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
472{
473 PyObject *seq;
474 long a1=0, a2=0, a3=0, start=0, stop=0, step=1;
475 PyObject *it;
476 int numargs;
477 isliceobject *lz;
478
479 numargs = PyTuple_Size(args);
480 if (!PyArg_ParseTuple(args, "Ol|ll:islice", &seq, &a1, &a2, &a3))
481 return NULL;
482
483 if (numargs == 2) {
484 stop = a1;
485 } else if (numargs == 3) {
486 start = a1;
487 stop = a2;
488 } else {
489 start = a1;
490 stop = a2;
491 step = a3;
492 }
493
494 if (start<0 || stop<0) {
495 PyErr_SetString(PyExc_ValueError,
496 "Indices for islice() must be positive.");
497 return NULL;
498 }
499
500 if (step<1) {
501 PyErr_SetString(PyExc_ValueError,
502 "Step must be one or larger for islice().");
503 return NULL;
504 }
505
506 /* Get iterator. */
507 it = PyObject_GetIter(seq);
508 if (it == NULL)
509 return NULL;
510
511 /* create isliceobject structure */
512 lz = (isliceobject *)type->tp_alloc(type, 0);
513 if (lz == NULL) {
514 Py_DECREF(it);
515 return NULL;
516 }
517 lz->it = it;
518 lz->next = start;
519 lz->stop = stop;
520 lz->step = step;
521 lz->cnt = 0L;
522
523 return (PyObject *)lz;
524}
525
526static void
527islice_dealloc(isliceobject *lz)
528{
529 PyObject_GC_UnTrack(lz);
530 Py_XDECREF(lz->it);
531 lz->ob_type->tp_free(lz);
532}
533
534static int
535islice_traverse(isliceobject *lz, visitproc visit, void *arg)
536{
537 if (lz->it)
538 return visit(lz->it, arg);
539 return 0;
540}
541
542static PyObject *
543islice_next(isliceobject *lz)
544{
545 PyObject *item;
Raymond Hettingerd1a283b2003-03-01 01:48:24 +0000546 PyObject *it = lz->it;
Raymond Hettinger2012f172003-02-07 05:32:58 +0000547 long oldnext;
Raymond Hettinger96ef8112003-02-01 00:10:11 +0000548
549 while (lz->cnt < lz->next) {
Raymond Hettingerd1a283b2003-03-01 01:48:24 +0000550 assert(PyIter_Check(it));
551 item = (*it->ob_type->tp_iternext)(it);
Raymond Hettinger96ef8112003-02-01 00:10:11 +0000552 if (item == NULL)
553 return NULL;
554 Py_DECREF(item);
555 lz->cnt++;
556 }
557 if (lz->cnt >= lz->stop)
558 return NULL;
Raymond Hettingerd1a283b2003-03-01 01:48:24 +0000559 assert(PyIter_Check(it));
560 item = (*it->ob_type->tp_iternext)(it);
Raymond Hettinger96ef8112003-02-01 00:10:11 +0000561 if (item == NULL)
562 return NULL;
563 lz->cnt++;
Raymond Hettinger2012f172003-02-07 05:32:58 +0000564 oldnext = lz->next;
Raymond Hettinger96ef8112003-02-01 00:10:11 +0000565 lz->next += lz->step;
Raymond Hettinger2012f172003-02-07 05:32:58 +0000566 if (lz->next < oldnext) /* Check for overflow */
567 lz->next = lz->stop;
Raymond Hettinger96ef8112003-02-01 00:10:11 +0000568 return item;
569}
570
Raymond Hettinger96ef8112003-02-01 00:10:11 +0000571PyDoc_STRVAR(islice_doc,
572"islice(iterable, [start,] stop [, step]) --> islice object\n\
573\n\
574Return an iterator whose next() method returns selected values from an\n\
575iterable. If start is specified, will skip all preceding elements;\n\
576otherwise, start defaults to zero. Step defaults to one. If\n\
577specified as another value, step determines how many values are \n\
578skipped between successive calls. Works like a slice() on a list\n\
579but returns an iterator.");
580
581PyTypeObject islice_type = {
582 PyObject_HEAD_INIT(NULL)
583 0, /* ob_size */
584 "itertools.islice", /* tp_name */
585 sizeof(isliceobject), /* tp_basicsize */
586 0, /* tp_itemsize */
587 /* methods */
Raymond Hettinger60eca932003-02-09 06:40:58 +0000588 (destructor)islice_dealloc, /* tp_dealloc */
Raymond Hettinger96ef8112003-02-01 00:10:11 +0000589 0, /* tp_print */
590 0, /* tp_getattr */
591 0, /* tp_setattr */
592 0, /* tp_compare */
593 0, /* tp_repr */
594 0, /* tp_as_number */
595 0, /* tp_as_sequence */
596 0, /* tp_as_mapping */
597 0, /* tp_hash */
598 0, /* tp_call */
599 0, /* tp_str */
600 PyObject_GenericGetAttr, /* tp_getattro */
601 0, /* tp_setattro */
602 0, /* tp_as_buffer */
603 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
604 Py_TPFLAGS_BASETYPE, /* tp_flags */
Raymond Hettinger60eca932003-02-09 06:40:58 +0000605 islice_doc, /* tp_doc */
606 (traverseproc)islice_traverse, /* tp_traverse */
Raymond Hettinger96ef8112003-02-01 00:10:11 +0000607 0, /* tp_clear */
608 0, /* tp_richcompare */
609 0, /* tp_weaklistoffset */
Raymond Hettinger1da1dbf2003-03-17 19:46:11 +0000610 PyObject_SelfIter, /* tp_iter */
Raymond Hettinger60eca932003-02-09 06:40:58 +0000611 (iternextfunc)islice_next, /* tp_iternext */
Raymond Hettinger96ef8112003-02-01 00:10:11 +0000612 0, /* tp_methods */
613 0, /* tp_members */
614 0, /* tp_getset */
615 0, /* tp_base */
616 0, /* tp_dict */
617 0, /* tp_descr_get */
618 0, /* tp_descr_set */
619 0, /* tp_dictoffset */
620 0, /* tp_init */
621 PyType_GenericAlloc, /* tp_alloc */
622 islice_new, /* tp_new */
623 PyObject_GC_Del, /* tp_free */
624};
625
626
627/* starmap object ************************************************************/
628
629typedef struct {
630 PyObject_HEAD
631 PyObject *func;
632 PyObject *it;
633} starmapobject;
634
635PyTypeObject starmap_type;
636
637static PyObject *
638starmap_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
639{
640 PyObject *func, *seq;
641 PyObject *it;
642 starmapobject *lz;
643
644 if (!PyArg_UnpackTuple(args, "starmap", 2, 2, &func, &seq))
645 return NULL;
646
647 /* Get iterator. */
648 it = PyObject_GetIter(seq);
649 if (it == NULL)
650 return NULL;
651
652 /* create starmapobject structure */
653 lz = (starmapobject *)type->tp_alloc(type, 0);
654 if (lz == NULL) {
655 Py_DECREF(it);
656 return NULL;
657 }
658 Py_INCREF(func);
659 lz->func = func;
660 lz->it = it;
661
662 return (PyObject *)lz;
663}
664
665static void
666starmap_dealloc(starmapobject *lz)
667{
668 PyObject_GC_UnTrack(lz);
669 Py_XDECREF(lz->func);
670 Py_XDECREF(lz->it);
671 lz->ob_type->tp_free(lz);
672}
673
674static int
675starmap_traverse(starmapobject *lz, visitproc visit, void *arg)
676{
677 int err;
678
679 if (lz->it) {
680 err = visit(lz->it, arg);
681 if (err)
682 return err;
683 }
684 if (lz->func) {
685 err = visit(lz->func, arg);
686 if (err)
687 return err;
688 }
689 return 0;
690}
691
692static PyObject *
693starmap_next(starmapobject *lz)
694{
695 PyObject *args;
696 PyObject *result;
Raymond Hettingerd1a283b2003-03-01 01:48:24 +0000697 PyObject *it = lz->it;
Raymond Hettinger96ef8112003-02-01 00:10:11 +0000698
Raymond Hettingerd1a283b2003-03-01 01:48:24 +0000699 assert(PyIter_Check(it));
700 args = (*it->ob_type->tp_iternext)(it);
Raymond Hettinger96ef8112003-02-01 00:10:11 +0000701 if (args == NULL)
702 return NULL;
Raymond Hettinger2012f172003-02-07 05:32:58 +0000703 if (!PyTuple_CheckExact(args)) {
704 Py_DECREF(args);
705 PyErr_SetString(PyExc_TypeError,
706 "iterator must return a tuple");
707 return NULL;
708 }
Raymond Hettinger96ef8112003-02-01 00:10:11 +0000709 result = PyObject_Call(lz->func, args, NULL);
710 Py_DECREF(args);
711 return result;
712}
713
Raymond Hettinger96ef8112003-02-01 00:10:11 +0000714PyDoc_STRVAR(starmap_doc,
715"starmap(function, sequence) --> starmap object\n\
716\n\
717Return an iterator whose values are returned from the function evaluated\n\
718with a argument tuple taken from the given sequence.");
719
720PyTypeObject starmap_type = {
721 PyObject_HEAD_INIT(NULL)
722 0, /* ob_size */
Raymond Hettinger60eca932003-02-09 06:40:58 +0000723 "itertools.starmap", /* tp_name */
724 sizeof(starmapobject), /* tp_basicsize */
Raymond Hettinger96ef8112003-02-01 00:10:11 +0000725 0, /* tp_itemsize */
726 /* methods */
Raymond Hettinger60eca932003-02-09 06:40:58 +0000727 (destructor)starmap_dealloc, /* tp_dealloc */
Raymond Hettinger96ef8112003-02-01 00:10:11 +0000728 0, /* tp_print */
729 0, /* tp_getattr */
730 0, /* tp_setattr */
731 0, /* tp_compare */
732 0, /* tp_repr */
733 0, /* tp_as_number */
734 0, /* tp_as_sequence */
735 0, /* tp_as_mapping */
736 0, /* tp_hash */
737 0, /* tp_call */
738 0, /* tp_str */
739 PyObject_GenericGetAttr, /* tp_getattro */
740 0, /* tp_setattro */
741 0, /* tp_as_buffer */
742 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
743 Py_TPFLAGS_BASETYPE, /* tp_flags */
Raymond Hettinger60eca932003-02-09 06:40:58 +0000744 starmap_doc, /* tp_doc */
745 (traverseproc)starmap_traverse, /* tp_traverse */
Raymond Hettinger96ef8112003-02-01 00:10:11 +0000746 0, /* tp_clear */
747 0, /* tp_richcompare */
748 0, /* tp_weaklistoffset */
Raymond Hettinger1da1dbf2003-03-17 19:46:11 +0000749 PyObject_SelfIter, /* tp_iter */
Raymond Hettinger60eca932003-02-09 06:40:58 +0000750 (iternextfunc)starmap_next, /* tp_iternext */
Raymond Hettinger96ef8112003-02-01 00:10:11 +0000751 0, /* tp_methods */
752 0, /* tp_members */
753 0, /* tp_getset */
754 0, /* tp_base */
755 0, /* tp_dict */
756 0, /* tp_descr_get */
757 0, /* tp_descr_set */
758 0, /* tp_dictoffset */
759 0, /* tp_init */
760 PyType_GenericAlloc, /* tp_alloc */
Raymond Hettinger60eca932003-02-09 06:40:58 +0000761 starmap_new, /* tp_new */
Raymond Hettinger96ef8112003-02-01 00:10:11 +0000762 PyObject_GC_Del, /* tp_free */
763};
764
765
766/* imap object ************************************************************/
767
768typedef struct {
769 PyObject_HEAD
770 PyObject *iters;
Raymond Hettinger96ef8112003-02-01 00:10:11 +0000771 PyObject *func;
772} imapobject;
773
774PyTypeObject imap_type;
775
776static PyObject *
777imap_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
778{
Raymond Hettingerf0c00242003-02-07 07:26:25 +0000779 PyObject *it, *iters, *func;
Raymond Hettinger96ef8112003-02-01 00:10:11 +0000780 imapobject *lz;
781 int numargs, i;
782
783 numargs = PyTuple_Size(args);
784 if (numargs < 2) {
785 PyErr_SetString(PyExc_TypeError,
786 "imap() must have at least two arguments.");
787 return NULL;
788 }
789
790 iters = PyTuple_New(numargs-1);
791 if (iters == NULL)
792 return NULL;
793
Raymond Hettinger96ef8112003-02-01 00:10:11 +0000794 for (i=1 ; i<numargs ; i++) {
795 /* Get iterator. */
796 it = PyObject_GetIter(PyTuple_GET_ITEM(args, i));
797 if (it == NULL) {
Raymond Hettinger96ef8112003-02-01 00:10:11 +0000798 Py_DECREF(iters);
799 return NULL;
800 }
801 PyTuple_SET_ITEM(iters, i-1, it);
Raymond Hettinger96ef8112003-02-01 00:10:11 +0000802 }
803
804 /* create imapobject structure */
805 lz = (imapobject *)type->tp_alloc(type, 0);
806 if (lz == NULL) {
Raymond Hettinger96ef8112003-02-01 00:10:11 +0000807 Py_DECREF(iters);
808 return NULL;
809 }
810 lz->iters = iters;
Raymond Hettinger96ef8112003-02-01 00:10:11 +0000811 func = PyTuple_GET_ITEM(args, 0);
812 Py_INCREF(func);
813 lz->func = func;
814
815 return (PyObject *)lz;
816}
817
818static void
819imap_dealloc(imapobject *lz)
820{
821 PyObject_GC_UnTrack(lz);
Raymond Hettinger96ef8112003-02-01 00:10:11 +0000822 Py_XDECREF(lz->iters);
823 Py_XDECREF(lz->func);
824 lz->ob_type->tp_free(lz);
825}
826
827static int
828imap_traverse(imapobject *lz, visitproc visit, void *arg)
829{
830 int err;
831
832 if (lz->iters) {
833 err = visit(lz->iters, arg);
834 if (err)
835 return err;
836 }
Raymond Hettinger96ef8112003-02-01 00:10:11 +0000837 if (lz->func) {
838 err = visit(lz->func, arg);
839 if (err)
840 return err;
841 }
842 return 0;
843}
844
Raymond Hettinger2012f172003-02-07 05:32:58 +0000845/*
846imap() is an iterator version of __builtins__.map() except that it does
847not have the None fill-in feature. That was intentionally left out for
848the following reasons:
849
850 1) Itertools are designed to be easily combined and chained together.
851 Having all tools stop with the shortest input is a unifying principle
852 that makes it easier to combine finite iterators (supplying data) with
853 infinite iterators like count() and repeat() (for supplying sequential
854 or constant arguments to a function).
855
856 2) In typical use cases for combining itertools, having one finite data
857 supplier run out before another is likely to be an error condition which
858 should not pass silently by automatically supplying None.
859
860 3) The use cases for automatic None fill-in are rare -- not many functions
861 do something useful when a parameter suddenly switches type and becomes
862 None.
863
864 4) If a need does arise, it can be met by __builtins__.map() or by
865 writing a generator.
866
867 5) Similar toolsets in Haskell and SML do not have automatic None fill-in.
868*/
869
Raymond Hettinger96ef8112003-02-01 00:10:11 +0000870static PyObject *
871imap_next(imapobject *lz)
872{
873 PyObject *val;
Raymond Hettingerf0c00242003-02-07 07:26:25 +0000874 PyObject *argtuple;
875 PyObject *result;
Raymond Hettinger96ef8112003-02-01 00:10:11 +0000876 int numargs, i;
877
878 numargs = PyTuple_Size(lz->iters);
Raymond Hettingerf0c00242003-02-07 07:26:25 +0000879 argtuple = PyTuple_New(numargs);
880 if (argtuple == NULL)
881 return NULL;
Raymond Hettinger96ef8112003-02-01 00:10:11 +0000882
Raymond Hettingerf0c00242003-02-07 07:26:25 +0000883 for (i=0 ; i<numargs ; i++) {
884 val = PyIter_Next(PyTuple_GET_ITEM(lz->iters, i));
885 if (val == NULL) {
886 Py_DECREF(argtuple);
887 return NULL;
Raymond Hettinger96ef8112003-02-01 00:10:11 +0000888 }
Raymond Hettingerf0c00242003-02-07 07:26:25 +0000889 PyTuple_SET_ITEM(argtuple, i, val);
Raymond Hettinger96ef8112003-02-01 00:10:11 +0000890 }
Raymond Hettingerf0c00242003-02-07 07:26:25 +0000891 if (lz->func == Py_None)
892 return argtuple;
893 result = PyObject_Call(lz->func, argtuple, NULL);
894 Py_DECREF(argtuple);
895 return result;
Raymond Hettinger96ef8112003-02-01 00:10:11 +0000896}
897
Raymond Hettinger96ef8112003-02-01 00:10:11 +0000898PyDoc_STRVAR(imap_doc,
899"imap(func, *iterables) --> imap object\n\
900\n\
901Make an iterator that computes the function using arguments from\n\
902each of the iterables. Like map() except that it returns\n\
903an iterator instead of a list and that it stops when the shortest\n\
904iterable is exhausted instead of filling in None for shorter\n\
905iterables.");
906
907PyTypeObject imap_type = {
908 PyObject_HEAD_INIT(NULL)
909 0, /* ob_size */
Raymond Hettinger60eca932003-02-09 06:40:58 +0000910 "itertools.imap", /* tp_name */
911 sizeof(imapobject), /* tp_basicsize */
Raymond Hettinger96ef8112003-02-01 00:10:11 +0000912 0, /* tp_itemsize */
913 /* methods */
914 (destructor)imap_dealloc, /* tp_dealloc */
915 0, /* tp_print */
916 0, /* tp_getattr */
917 0, /* tp_setattr */
918 0, /* tp_compare */
919 0, /* tp_repr */
920 0, /* tp_as_number */
921 0, /* tp_as_sequence */
922 0, /* tp_as_mapping */
923 0, /* tp_hash */
924 0, /* tp_call */
925 0, /* tp_str */
926 PyObject_GenericGetAttr, /* tp_getattro */
927 0, /* tp_setattro */
928 0, /* tp_as_buffer */
929 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
930 Py_TPFLAGS_BASETYPE, /* tp_flags */
931 imap_doc, /* tp_doc */
932 (traverseproc)imap_traverse, /* tp_traverse */
933 0, /* tp_clear */
934 0, /* tp_richcompare */
935 0, /* tp_weaklistoffset */
Raymond Hettinger1da1dbf2003-03-17 19:46:11 +0000936 PyObject_SelfIter, /* tp_iter */
Raymond Hettinger96ef8112003-02-01 00:10:11 +0000937 (iternextfunc)imap_next, /* tp_iternext */
938 0, /* tp_methods */
939 0, /* tp_members */
940 0, /* tp_getset */
941 0, /* tp_base */
942 0, /* tp_dict */
943 0, /* tp_descr_get */
944 0, /* tp_descr_set */
945 0, /* tp_dictoffset */
946 0, /* tp_init */
947 PyType_GenericAlloc, /* tp_alloc */
Raymond Hettinger60eca932003-02-09 06:40:58 +0000948 imap_new, /* tp_new */
Raymond Hettinger96ef8112003-02-01 00:10:11 +0000949 PyObject_GC_Del, /* tp_free */
950};
951
952
Raymond Hettinger61fe64d2003-02-23 04:40:07 +0000953/* chain object ************************************************************/
Raymond Hettinger96ef8112003-02-01 00:10:11 +0000954
955typedef struct {
956 PyObject_HEAD
Raymond Hettinger61fe64d2003-02-23 04:40:07 +0000957 long tuplesize;
958 long iternum; /* which iterator is active */
959 PyObject *ittuple; /* tuple of iterators */
960} chainobject;
Raymond Hettinger96ef8112003-02-01 00:10:11 +0000961
Raymond Hettinger61fe64d2003-02-23 04:40:07 +0000962PyTypeObject chain_type;
Raymond Hettinger96ef8112003-02-01 00:10:11 +0000963
964static PyObject *
Raymond Hettinger61fe64d2003-02-23 04:40:07 +0000965chain_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
Raymond Hettinger96ef8112003-02-01 00:10:11 +0000966{
Raymond Hettinger61fe64d2003-02-23 04:40:07 +0000967 chainobject *lz;
968 int tuplesize = PySequence_Length(args);
969 int i;
970 PyObject *ittuple;
Raymond Hettinger96ef8112003-02-01 00:10:11 +0000971
Raymond Hettinger61fe64d2003-02-23 04:40:07 +0000972 /* obtain iterators */
973 assert(PyTuple_Check(args));
974 ittuple = PyTuple_New(tuplesize);
975 if(ittuple == NULL)
Raymond Hettinger96ef8112003-02-01 00:10:11 +0000976 return NULL;
Raymond Hettinger61fe64d2003-02-23 04:40:07 +0000977 for (i=0; i < tuplesize; ++i) {
978 PyObject *item = PyTuple_GET_ITEM(args, i);
979 PyObject *it = PyObject_GetIter(item);
980 if (it == NULL) {
981 if (PyErr_ExceptionMatches(PyExc_TypeError))
982 PyErr_Format(PyExc_TypeError,
983 "chain argument #%d must support iteration",
984 i+1);
985 Py_DECREF(ittuple);
986 return NULL;
987 }
988 PyTuple_SET_ITEM(ittuple, i, it);
Raymond Hettinger96ef8112003-02-01 00:10:11 +0000989 }
990
Raymond Hettinger61fe64d2003-02-23 04:40:07 +0000991 /* create chainobject structure */
992 lz = (chainobject *)type->tp_alloc(type, 0);
Raymond Hettinger96ef8112003-02-01 00:10:11 +0000993 if (lz == NULL)
994 return NULL;
Raymond Hettinger61fe64d2003-02-23 04:40:07 +0000995
996 lz->ittuple = ittuple;
997 lz->iternum = 0;
998 lz->tuplesize = tuplesize;
Raymond Hettinger96ef8112003-02-01 00:10:11 +0000999
1000 return (PyObject *)lz;
1001}
1002
1003static void
Raymond Hettinger61fe64d2003-02-23 04:40:07 +00001004chain_dealloc(chainobject *lz)
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001005{
1006 PyObject_GC_UnTrack(lz);
Raymond Hettinger61fe64d2003-02-23 04:40:07 +00001007 Py_XDECREF(lz->ittuple);
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001008 lz->ob_type->tp_free(lz);
1009}
1010
Raymond Hettinger2012f172003-02-07 05:32:58 +00001011static int
Raymond Hettinger61fe64d2003-02-23 04:40:07 +00001012chain_traverse(chainobject *lz, visitproc visit, void *arg)
Raymond Hettinger2012f172003-02-07 05:32:58 +00001013{
Raymond Hettinger61fe64d2003-02-23 04:40:07 +00001014 if (lz->ittuple)
1015 return visit(lz->ittuple, arg);
Raymond Hettinger2012f172003-02-07 05:32:58 +00001016 return 0;
1017}
1018
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001019static PyObject *
Raymond Hettinger61fe64d2003-02-23 04:40:07 +00001020chain_next(chainobject *lz)
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001021{
Raymond Hettinger61fe64d2003-02-23 04:40:07 +00001022 PyObject *it;
1023 PyObject *item;
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001024
Raymond Hettinger61fe64d2003-02-23 04:40:07 +00001025 while (lz->iternum < lz->tuplesize) {
1026 it = PyTuple_GET_ITEM(lz->ittuple, lz->iternum);
1027 item = PyIter_Next(it);
1028 if (item != NULL)
1029 return item;
1030 lz->iternum++;
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001031 }
1032 return NULL;
1033}
1034
Raymond Hettinger61fe64d2003-02-23 04:40:07 +00001035PyDoc_STRVAR(chain_doc,
1036"chain(*iterables) --> chain object\n\
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001037\n\
Raymond Hettinger61fe64d2003-02-23 04:40:07 +00001038Return a chain object whose .next() method returns elements from the\n\
1039first iterable until it is exhausted, then elements from the next\n\
1040iterable, until all of the iterables are exhausted.");
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001041
Raymond Hettinger61fe64d2003-02-23 04:40:07 +00001042PyTypeObject chain_type = {
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001043 PyObject_HEAD_INIT(NULL)
1044 0, /* ob_size */
Raymond Hettinger61fe64d2003-02-23 04:40:07 +00001045 "itertools.chain", /* tp_name */
1046 sizeof(chainobject), /* tp_basicsize */
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001047 0, /* tp_itemsize */
1048 /* methods */
Raymond Hettinger61fe64d2003-02-23 04:40:07 +00001049 (destructor)chain_dealloc, /* tp_dealloc */
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001050 0, /* tp_print */
1051 0, /* tp_getattr */
1052 0, /* tp_setattr */
1053 0, /* tp_compare */
1054 0, /* tp_repr */
1055 0, /* tp_as_number */
1056 0, /* tp_as_sequence */
1057 0, /* tp_as_mapping */
1058 0, /* tp_hash */
1059 0, /* tp_call */
1060 0, /* tp_str */
1061 PyObject_GenericGetAttr, /* tp_getattro */
1062 0, /* tp_setattro */
1063 0, /* tp_as_buffer */
1064 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
1065 Py_TPFLAGS_BASETYPE, /* tp_flags */
Raymond Hettinger61fe64d2003-02-23 04:40:07 +00001066 chain_doc, /* tp_doc */
1067 (traverseproc)chain_traverse, /* tp_traverse */
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001068 0, /* tp_clear */
1069 0, /* tp_richcompare */
1070 0, /* tp_weaklistoffset */
Raymond Hettinger1da1dbf2003-03-17 19:46:11 +00001071 PyObject_SelfIter, /* tp_iter */
Raymond Hettinger61fe64d2003-02-23 04:40:07 +00001072 (iternextfunc)chain_next, /* tp_iternext */
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001073 0, /* tp_methods */
1074 0, /* tp_members */
1075 0, /* tp_getset */
1076 0, /* tp_base */
1077 0, /* tp_dict */
1078 0, /* tp_descr_get */
1079 0, /* tp_descr_set */
1080 0, /* tp_dictoffset */
1081 0, /* tp_init */
1082 PyType_GenericAlloc, /* tp_alloc */
Raymond Hettinger61fe64d2003-02-23 04:40:07 +00001083 chain_new, /* tp_new */
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001084 PyObject_GC_Del, /* tp_free */
1085};
1086
1087
1088/* ifilter object ************************************************************/
1089
1090typedef struct {
1091 PyObject_HEAD
1092 PyObject *func;
1093 PyObject *it;
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001094} ifilterobject;
1095
1096PyTypeObject ifilter_type;
1097
1098static PyObject *
1099ifilter_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1100{
Raymond Hettinger60eca932003-02-09 06:40:58 +00001101 PyObject *func, *seq;
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001102 PyObject *it;
1103 ifilterobject *lz;
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001104
Raymond Hettinger60eca932003-02-09 06:40:58 +00001105 if (!PyArg_UnpackTuple(args, "ifilter", 2, 2, &func, &seq))
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001106 return NULL;
1107
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001108 /* Get iterator. */
1109 it = PyObject_GetIter(seq);
1110 if (it == NULL)
1111 return NULL;
1112
1113 /* create ifilterobject structure */
1114 lz = (ifilterobject *)type->tp_alloc(type, 0);
1115 if (lz == NULL) {
1116 Py_DECREF(it);
1117 return NULL;
1118 }
1119 Py_INCREF(func);
1120 lz->func = func;
1121 lz->it = it;
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001122
1123 return (PyObject *)lz;
1124}
1125
1126static void
1127ifilter_dealloc(ifilterobject *lz)
1128{
1129 PyObject_GC_UnTrack(lz);
1130 Py_XDECREF(lz->func);
1131 Py_XDECREF(lz->it);
1132 lz->ob_type->tp_free(lz);
1133}
1134
1135static int
1136ifilter_traverse(ifilterobject *lz, visitproc visit, void *arg)
1137{
1138 int err;
1139
1140 if (lz->it) {
1141 err = visit(lz->it, arg);
1142 if (err)
1143 return err;
1144 }
1145 if (lz->func) {
1146 err = visit(lz->func, arg);
1147 if (err)
1148 return err;
1149 }
1150 return 0;
1151}
1152
1153static PyObject *
1154ifilter_next(ifilterobject *lz)
1155{
1156 PyObject *item;
Raymond Hettingerd1a283b2003-03-01 01:48:24 +00001157 PyObject *it = lz->it;
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001158 long ok;
1159
1160 for (;;) {
Raymond Hettingerd1a283b2003-03-01 01:48:24 +00001161 assert(PyIter_Check(it));
1162 item = (*it->ob_type->tp_iternext)(it);
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001163 if (item == NULL)
1164 return NULL;
1165
1166 if (lz->func == Py_None) {
1167 ok = PyObject_IsTrue(item);
1168 } else {
1169 PyObject *good;
1170 good = PyObject_CallFunctionObjArgs(lz->func,
1171 item, NULL);
1172 if (good == NULL) {
1173 Py_DECREF(item);
1174 return NULL;
1175 }
1176 ok = PyObject_IsTrue(good);
1177 Py_DECREF(good);
1178 }
Raymond Hettinger60eca932003-02-09 06:40:58 +00001179 if (ok)
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001180 return item;
1181 Py_DECREF(item);
1182 }
1183}
1184
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001185PyDoc_STRVAR(ifilter_doc,
Raymond Hettinger60eca932003-02-09 06:40:58 +00001186"ifilter(function or None, sequence) --> ifilter object\n\
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001187\n\
Raymond Hettinger60eca932003-02-09 06:40:58 +00001188Return those items of sequence for which function(item) is true.\n\
1189If function is None, return the items that are true.");
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001190
1191PyTypeObject ifilter_type = {
1192 PyObject_HEAD_INIT(NULL)
1193 0, /* ob_size */
Raymond Hettinger60eca932003-02-09 06:40:58 +00001194 "itertools.ifilter", /* tp_name */
1195 sizeof(ifilterobject), /* tp_basicsize */
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001196 0, /* tp_itemsize */
1197 /* methods */
Raymond Hettinger60eca932003-02-09 06:40:58 +00001198 (destructor)ifilter_dealloc, /* tp_dealloc */
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001199 0, /* tp_print */
1200 0, /* tp_getattr */
1201 0, /* tp_setattr */
1202 0, /* tp_compare */
1203 0, /* tp_repr */
1204 0, /* tp_as_number */
1205 0, /* tp_as_sequence */
1206 0, /* tp_as_mapping */
1207 0, /* tp_hash */
1208 0, /* tp_call */
1209 0, /* tp_str */
1210 PyObject_GenericGetAttr, /* tp_getattro */
1211 0, /* tp_setattro */
1212 0, /* tp_as_buffer */
1213 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
1214 Py_TPFLAGS_BASETYPE, /* tp_flags */
Raymond Hettinger60eca932003-02-09 06:40:58 +00001215 ifilter_doc, /* tp_doc */
1216 (traverseproc)ifilter_traverse, /* tp_traverse */
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001217 0, /* tp_clear */
1218 0, /* tp_richcompare */
1219 0, /* tp_weaklistoffset */
Raymond Hettinger1da1dbf2003-03-17 19:46:11 +00001220 PyObject_SelfIter, /* tp_iter */
Raymond Hettinger60eca932003-02-09 06:40:58 +00001221 (iternextfunc)ifilter_next, /* tp_iternext */
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001222 0, /* tp_methods */
1223 0, /* tp_members */
1224 0, /* tp_getset */
1225 0, /* tp_base */
1226 0, /* tp_dict */
1227 0, /* tp_descr_get */
1228 0, /* tp_descr_set */
1229 0, /* tp_dictoffset */
1230 0, /* tp_init */
1231 PyType_GenericAlloc, /* tp_alloc */
Raymond Hettinger60eca932003-02-09 06:40:58 +00001232 ifilter_new, /* tp_new */
1233 PyObject_GC_Del, /* tp_free */
1234};
1235
1236
1237/* ifilterfalse object ************************************************************/
1238
1239typedef struct {
1240 PyObject_HEAD
1241 PyObject *func;
1242 PyObject *it;
1243} ifilterfalseobject;
1244
1245PyTypeObject ifilterfalse_type;
1246
1247static PyObject *
1248ifilterfalse_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1249{
Guido van Rossumd58f3fc2003-02-09 17:19:18 +00001250 PyObject *func, *seq;
Raymond Hettinger60eca932003-02-09 06:40:58 +00001251 PyObject *it;
1252 ifilterfalseobject *lz;
1253
1254 if (!PyArg_UnpackTuple(args, "ifilterfalse", 2, 2, &func, &seq))
1255 return NULL;
1256
1257 /* Get iterator. */
1258 it = PyObject_GetIter(seq);
1259 if (it == NULL)
1260 return NULL;
1261
1262 /* create ifilterfalseobject structure */
1263 lz = (ifilterfalseobject *)type->tp_alloc(type, 0);
1264 if (lz == NULL) {
1265 Py_DECREF(it);
1266 return NULL;
1267 }
1268 Py_INCREF(func);
1269 lz->func = func;
1270 lz->it = it;
1271
1272 return (PyObject *)lz;
1273}
1274
1275static void
1276ifilterfalse_dealloc(ifilterfalseobject *lz)
1277{
1278 PyObject_GC_UnTrack(lz);
1279 Py_XDECREF(lz->func);
1280 Py_XDECREF(lz->it);
1281 lz->ob_type->tp_free(lz);
1282}
1283
1284static int
1285ifilterfalse_traverse(ifilterfalseobject *lz, visitproc visit, void *arg)
1286{
1287 int err;
1288
1289 if (lz->it) {
1290 err = visit(lz->it, arg);
1291 if (err)
1292 return err;
1293 }
1294 if (lz->func) {
1295 err = visit(lz->func, arg);
1296 if (err)
1297 return err;
1298 }
1299 return 0;
1300}
1301
1302static PyObject *
1303ifilterfalse_next(ifilterfalseobject *lz)
1304{
1305 PyObject *item;
Raymond Hettingerd1a283b2003-03-01 01:48:24 +00001306 PyObject *it = lz->it;
Raymond Hettinger60eca932003-02-09 06:40:58 +00001307 long ok;
1308
1309 for (;;) {
Raymond Hettingerd1a283b2003-03-01 01:48:24 +00001310 assert(PyIter_Check(it));
1311 item = (*it->ob_type->tp_iternext)(it);
Raymond Hettinger60eca932003-02-09 06:40:58 +00001312 if (item == NULL)
1313 return NULL;
1314
1315 if (lz->func == Py_None) {
1316 ok = PyObject_IsTrue(item);
1317 } else {
1318 PyObject *good;
1319 good = PyObject_CallFunctionObjArgs(lz->func,
1320 item, NULL);
1321 if (good == NULL) {
1322 Py_DECREF(item);
1323 return NULL;
1324 }
1325 ok = PyObject_IsTrue(good);
1326 Py_DECREF(good);
1327 }
1328 if (!ok)
1329 return item;
1330 Py_DECREF(item);
1331 }
1332}
1333
Raymond Hettinger60eca932003-02-09 06:40:58 +00001334PyDoc_STRVAR(ifilterfalse_doc,
1335"ifilterfalse(function or None, sequence) --> ifilterfalse object\n\
1336\n\
1337Return those items of sequence for which function(item) is false.\n\
1338If function is None, return the items that are false.");
1339
1340PyTypeObject ifilterfalse_type = {
1341 PyObject_HEAD_INIT(NULL)
1342 0, /* ob_size */
1343 "itertools.ifilterfalse", /* tp_name */
1344 sizeof(ifilterfalseobject), /* tp_basicsize */
1345 0, /* tp_itemsize */
1346 /* methods */
1347 (destructor)ifilterfalse_dealloc, /* tp_dealloc */
1348 0, /* tp_print */
1349 0, /* tp_getattr */
1350 0, /* tp_setattr */
1351 0, /* tp_compare */
1352 0, /* tp_repr */
1353 0, /* tp_as_number */
1354 0, /* tp_as_sequence */
1355 0, /* tp_as_mapping */
1356 0, /* tp_hash */
1357 0, /* tp_call */
1358 0, /* tp_str */
1359 PyObject_GenericGetAttr, /* tp_getattro */
1360 0, /* tp_setattro */
1361 0, /* tp_as_buffer */
1362 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
1363 Py_TPFLAGS_BASETYPE, /* tp_flags */
1364 ifilterfalse_doc, /* tp_doc */
1365 (traverseproc)ifilterfalse_traverse, /* tp_traverse */
1366 0, /* tp_clear */
1367 0, /* tp_richcompare */
1368 0, /* tp_weaklistoffset */
Raymond Hettinger1da1dbf2003-03-17 19:46:11 +00001369 PyObject_SelfIter, /* tp_iter */
Raymond Hettinger60eca932003-02-09 06:40:58 +00001370 (iternextfunc)ifilterfalse_next, /* tp_iternext */
1371 0, /* tp_methods */
1372 0, /* tp_members */
1373 0, /* tp_getset */
1374 0, /* tp_base */
1375 0, /* tp_dict */
1376 0, /* tp_descr_get */
1377 0, /* tp_descr_set */
1378 0, /* tp_dictoffset */
1379 0, /* tp_init */
1380 PyType_GenericAlloc, /* tp_alloc */
1381 ifilterfalse_new, /* tp_new */
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001382 PyObject_GC_Del, /* tp_free */
1383};
1384
1385
1386/* count object ************************************************************/
1387
1388typedef struct {
1389 PyObject_HEAD
1390 long cnt;
1391} countobject;
1392
1393PyTypeObject count_type;
1394
1395static PyObject *
1396count_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1397{
1398 countobject *lz;
1399 long cnt = 0;
1400
1401 if (!PyArg_ParseTuple(args, "|l:count", &cnt))
1402 return NULL;
1403
1404 /* create countobject structure */
1405 lz = (countobject *)PyObject_New(countobject, &count_type);
1406 if (lz == NULL)
1407 return NULL;
1408 lz->cnt = cnt;
1409
1410 return (PyObject *)lz;
1411}
1412
1413static PyObject *
1414count_next(countobject *lz)
1415{
1416 return PyInt_FromLong(lz->cnt++);
1417}
1418
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001419PyDoc_STRVAR(count_doc,
1420"count([firstval]) --> count object\n\
1421\n\
1422Return a count object whose .next() method returns consecutive\n\
1423integers starting from zero or, if specified, from firstval.");
1424
1425PyTypeObject count_type = {
1426 PyObject_HEAD_INIT(NULL)
1427 0, /* ob_size */
Raymond Hettinger60eca932003-02-09 06:40:58 +00001428 "itertools.count", /* tp_name */
1429 sizeof(countobject), /* tp_basicsize */
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001430 0, /* tp_itemsize */
1431 /* methods */
1432 (destructor)PyObject_Del, /* tp_dealloc */
1433 0, /* tp_print */
1434 0, /* tp_getattr */
1435 0, /* tp_setattr */
1436 0, /* tp_compare */
1437 0, /* tp_repr */
1438 0, /* tp_as_number */
1439 0, /* tp_as_sequence */
1440 0, /* tp_as_mapping */
1441 0, /* tp_hash */
1442 0, /* tp_call */
1443 0, /* tp_str */
1444 PyObject_GenericGetAttr, /* tp_getattro */
1445 0, /* tp_setattro */
1446 0, /* tp_as_buffer */
1447 Py_TPFLAGS_DEFAULT, /* tp_flags */
Raymond Hettinger60eca932003-02-09 06:40:58 +00001448 count_doc, /* tp_doc */
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001449 0, /* tp_traverse */
1450 0, /* tp_clear */
1451 0, /* tp_richcompare */
1452 0, /* tp_weaklistoffset */
Raymond Hettinger1da1dbf2003-03-17 19:46:11 +00001453 PyObject_SelfIter, /* tp_iter */
Raymond Hettinger60eca932003-02-09 06:40:58 +00001454 (iternextfunc)count_next, /* tp_iternext */
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001455 0, /* tp_methods */
1456 0, /* tp_members */
1457 0, /* tp_getset */
1458 0, /* tp_base */
1459 0, /* tp_dict */
1460 0, /* tp_descr_get */
1461 0, /* tp_descr_set */
1462 0, /* tp_dictoffset */
1463 0, /* tp_init */
1464 PyType_GenericAlloc, /* tp_alloc */
1465 count_new, /* tp_new */
1466};
1467
1468
1469/* izip object ************************************************************/
1470
1471#include "Python.h"
1472
1473typedef struct {
1474 PyObject_HEAD
1475 long tuplesize;
1476 PyObject *ittuple; /* tuple of iterators */
Raymond Hettinger2012f172003-02-07 05:32:58 +00001477 PyObject *result;
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001478} izipobject;
1479
1480PyTypeObject izip_type;
1481
1482static PyObject *
1483izip_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1484{
1485 izipobject *lz;
1486 int i;
1487 PyObject *ittuple; /* tuple of iterators */
Raymond Hettinger2012f172003-02-07 05:32:58 +00001488 PyObject *result;
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001489 int tuplesize = PySequence_Length(args);
1490
1491 if (tuplesize < 1) {
1492 PyErr_SetString(PyExc_TypeError,
1493 "izip() requires at least one sequence");
1494 return NULL;
1495 }
1496
1497 /* args must be a tuple */
1498 assert(PyTuple_Check(args));
1499
1500 /* obtain iterators */
1501 ittuple = PyTuple_New(tuplesize);
1502 if(ittuple == NULL)
1503 return NULL;
1504 for (i=0; i < tuplesize; ++i) {
1505 PyObject *item = PyTuple_GET_ITEM(args, i);
1506 PyObject *it = PyObject_GetIter(item);
1507 if (it == NULL) {
1508 if (PyErr_ExceptionMatches(PyExc_TypeError))
1509 PyErr_Format(PyExc_TypeError,
1510 "izip argument #%d must support iteration",
1511 i+1);
1512 Py_DECREF(ittuple);
1513 return NULL;
1514 }
1515 PyTuple_SET_ITEM(ittuple, i, it);
1516 }
1517
Raymond Hettinger2012f172003-02-07 05:32:58 +00001518 /* create a result holder */
1519 result = PyTuple_New(tuplesize);
1520 if (result == NULL) {
1521 Py_DECREF(ittuple);
1522 return NULL;
1523 }
1524 for (i=0 ; i < tuplesize ; i++) {
1525 Py_INCREF(Py_None);
1526 PyTuple_SET_ITEM(result, i, Py_None);
1527 }
1528
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001529 /* create izipobject structure */
1530 lz = (izipobject *)type->tp_alloc(type, 0);
1531 if (lz == NULL) {
1532 Py_DECREF(ittuple);
Raymond Hettinger2012f172003-02-07 05:32:58 +00001533 Py_DECREF(result);
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001534 return NULL;
1535 }
1536 lz->ittuple = ittuple;
1537 lz->tuplesize = tuplesize;
Raymond Hettinger2012f172003-02-07 05:32:58 +00001538 lz->result = result;
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001539
1540 return (PyObject *)lz;
1541}
1542
1543static void
1544izip_dealloc(izipobject *lz)
1545{
1546 PyObject_GC_UnTrack(lz);
1547 Py_XDECREF(lz->ittuple);
Raymond Hettinger2012f172003-02-07 05:32:58 +00001548 Py_XDECREF(lz->result);
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001549 lz->ob_type->tp_free(lz);
1550}
1551
1552static int
1553izip_traverse(izipobject *lz, visitproc visit, void *arg)
1554{
1555 if (lz->ittuple)
1556 return visit(lz->ittuple, arg);
1557 return 0;
1558}
1559
1560static PyObject *
1561izip_next(izipobject *lz)
1562{
1563 int i;
1564 long tuplesize = lz->tuplesize;
Raymond Hettinger2012f172003-02-07 05:32:58 +00001565 PyObject *result = lz->result;
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001566 PyObject *it;
1567 PyObject *item;
1568
Raymond Hettinger2012f172003-02-07 05:32:58 +00001569 if (result->ob_refcnt == 1) {
1570 for (i=0 ; i < tuplesize ; i++) {
Raymond Hettingerf0c00242003-02-07 07:26:25 +00001571 it = PyTuple_GET_ITEM(lz->ittuple, i);
Raymond Hettingerd1a283b2003-03-01 01:48:24 +00001572 assert(PyIter_Check(it));
1573 item = (*it->ob_type->tp_iternext)(it);
Raymond Hettingerf0c00242003-02-07 07:26:25 +00001574 if (item == NULL)
1575 return NULL;
Raymond Hettinger2012f172003-02-07 05:32:58 +00001576 Py_DECREF(PyTuple_GET_ITEM(result, i));
Raymond Hettingerf0c00242003-02-07 07:26:25 +00001577 PyTuple_SET_ITEM(result, i, item);
Raymond Hettinger2012f172003-02-07 05:32:58 +00001578 }
1579 Py_INCREF(result);
1580 } else {
Raymond Hettinger2012f172003-02-07 05:32:58 +00001581 result = PyTuple_New(tuplesize);
1582 if (result == NULL)
1583 return NULL;
Raymond Hettingerf0c00242003-02-07 07:26:25 +00001584 for (i=0 ; i < tuplesize ; i++) {
1585 it = PyTuple_GET_ITEM(lz->ittuple, i);
Raymond Hettingerd1a283b2003-03-01 01:48:24 +00001586 assert(PyIter_Check(it));
1587 item = (*it->ob_type->tp_iternext)(it);
Raymond Hettingerf0c00242003-02-07 07:26:25 +00001588 if (item == NULL) {
1589 Py_DECREF(result);
1590 return NULL;
1591 }
1592 PyTuple_SET_ITEM(result, i, item);
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001593 }
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001594 }
1595 return result;
1596}
1597
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001598PyDoc_STRVAR(izip_doc,
1599"izip(iter1 [,iter2 [...]]) --> izip object\n\
1600\n\
1601Return a izip object whose .next() method returns a tuple where\n\
1602the i-th element comes from the i-th iterable argument. The .next()\n\
1603method continues until the shortest iterable in the argument sequence\n\
1604is exhausted and then it raises StopIteration. Works like the zip()\n\
1605function but consumes less memory by returning an iterator instead of\n\
1606a list.");
1607
1608PyTypeObject izip_type = {
1609 PyObject_HEAD_INIT(NULL)
1610 0, /* ob_size */
Raymond Hettinger60eca932003-02-09 06:40:58 +00001611 "itertools.izip", /* tp_name */
1612 sizeof(izipobject), /* tp_basicsize */
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001613 0, /* tp_itemsize */
1614 /* methods */
Raymond Hettinger60eca932003-02-09 06:40:58 +00001615 (destructor)izip_dealloc, /* tp_dealloc */
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001616 0, /* tp_print */
1617 0, /* tp_getattr */
1618 0, /* tp_setattr */
1619 0, /* tp_compare */
1620 0, /* tp_repr */
1621 0, /* tp_as_number */
1622 0, /* tp_as_sequence */
1623 0, /* tp_as_mapping */
1624 0, /* tp_hash */
1625 0, /* tp_call */
1626 0, /* tp_str */
1627 PyObject_GenericGetAttr, /* tp_getattro */
1628 0, /* tp_setattro */
1629 0, /* tp_as_buffer */
1630 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
1631 Py_TPFLAGS_BASETYPE, /* tp_flags */
Raymond Hettinger60eca932003-02-09 06:40:58 +00001632 izip_doc, /* tp_doc */
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001633 (traverseproc)izip_traverse, /* tp_traverse */
1634 0, /* tp_clear */
1635 0, /* tp_richcompare */
1636 0, /* tp_weaklistoffset */
Raymond Hettinger1da1dbf2003-03-17 19:46:11 +00001637 PyObject_SelfIter, /* tp_iter */
Raymond Hettinger60eca932003-02-09 06:40:58 +00001638 (iternextfunc)izip_next, /* tp_iternext */
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001639 0, /* tp_methods */
1640 0, /* tp_members */
1641 0, /* tp_getset */
1642 0, /* tp_base */
1643 0, /* tp_dict */
1644 0, /* tp_descr_get */
1645 0, /* tp_descr_set */
1646 0, /* tp_dictoffset */
1647 0, /* tp_init */
1648 PyType_GenericAlloc, /* tp_alloc */
Raymond Hettinger60eca932003-02-09 06:40:58 +00001649 izip_new, /* tp_new */
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001650 PyObject_GC_Del, /* tp_free */
1651};
1652
1653
1654/* repeat object ************************************************************/
1655
1656typedef struct {
1657 PyObject_HEAD
1658 PyObject *element;
Raymond Hettinger61fe64d2003-02-23 04:40:07 +00001659 long cnt;
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001660} repeatobject;
1661
1662PyTypeObject repeat_type;
1663
1664static PyObject *
1665repeat_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1666{
1667 repeatobject *ro;
1668 PyObject *element;
Raymond Hettinger61fe64d2003-02-23 04:40:07 +00001669 long cnt = -1;
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001670
Raymond Hettinger61fe64d2003-02-23 04:40:07 +00001671 if (!PyArg_ParseTuple(args, "O|l:repeat", &element, &cnt))
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001672 return NULL;
1673
1674 ro = (repeatobject *)type->tp_alloc(type, 0);
1675 if (ro == NULL)
1676 return NULL;
1677 Py_INCREF(element);
1678 ro->element = element;
Raymond Hettinger61fe64d2003-02-23 04:40:07 +00001679 ro->cnt = cnt;
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001680 return (PyObject *)ro;
1681}
1682
1683static void
1684repeat_dealloc(repeatobject *ro)
1685{
1686 PyObject_GC_UnTrack(ro);
1687 Py_XDECREF(ro->element);
1688 ro->ob_type->tp_free(ro);
1689}
1690
1691static int
1692repeat_traverse(repeatobject *ro, visitproc visit, void *arg)
1693{
1694 if (ro->element)
1695 return visit(ro->element, arg);
1696 return 0;
1697}
1698
1699static PyObject *
1700repeat_next(repeatobject *ro)
1701{
Raymond Hettinger61fe64d2003-02-23 04:40:07 +00001702 if (ro->cnt == 0)
1703 return NULL;
1704 if (ro->cnt > 0)
1705 ro->cnt--;
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001706 Py_INCREF(ro->element);
1707 return ro->element;
1708}
1709
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001710PyDoc_STRVAR(repeat_doc,
Raymond Hettinger61fe64d2003-02-23 04:40:07 +00001711"repeat(element [,times]) -> create an iterator which returns the element\n\
1712for the specified number of times. If not specified, returns the element\n\
1713endlessly.");
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001714
1715PyTypeObject repeat_type = {
1716 PyObject_HEAD_INIT(NULL)
1717 0, /* ob_size */
1718 "itertools.repeat", /* tp_name */
1719 sizeof(repeatobject), /* tp_basicsize */
1720 0, /* tp_itemsize */
1721 /* methods */
Raymond Hettinger60eca932003-02-09 06:40:58 +00001722 (destructor)repeat_dealloc, /* tp_dealloc */
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001723 0, /* tp_print */
1724 0, /* tp_getattr */
1725 0, /* tp_setattr */
1726 0, /* tp_compare */
1727 0, /* tp_repr */
1728 0, /* tp_as_number */
1729 0, /* tp_as_sequence */
1730 0, /* tp_as_mapping */
1731 0, /* tp_hash */
1732 0, /* tp_call */
1733 0, /* tp_str */
1734 PyObject_GenericGetAttr, /* tp_getattro */
1735 0, /* tp_setattro */
1736 0, /* tp_as_buffer */
1737 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
1738 Py_TPFLAGS_BASETYPE, /* tp_flags */
Raymond Hettinger60eca932003-02-09 06:40:58 +00001739 repeat_doc, /* tp_doc */
1740 (traverseproc)repeat_traverse, /* tp_traverse */
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001741 0, /* tp_clear */
1742 0, /* tp_richcompare */
1743 0, /* tp_weaklistoffset */
Raymond Hettinger1da1dbf2003-03-17 19:46:11 +00001744 PyObject_SelfIter, /* tp_iter */
Raymond Hettinger60eca932003-02-09 06:40:58 +00001745 (iternextfunc)repeat_next, /* tp_iternext */
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001746 0, /* tp_methods */
1747 0, /* tp_members */
1748 0, /* tp_getset */
1749 0, /* tp_base */
1750 0, /* tp_dict */
1751 0, /* tp_descr_get */
1752 0, /* tp_descr_set */
1753 0, /* tp_dictoffset */
1754 0, /* tp_init */
1755 PyType_GenericAlloc, /* tp_alloc */
1756 repeat_new, /* tp_new */
1757 PyObject_GC_Del, /* tp_free */
1758};
1759
1760
1761/* module level code ********************************************************/
1762
1763PyDoc_STRVAR(module_doc,
1764"Functional tools for creating and using iterators.\n\
1765\n\
1766Infinite iterators:\n\
1767count([n]) --> n, n+1, n+2, ...\n\
Raymond Hettinger61fe64d2003-02-23 04:40:07 +00001768cycle(p) --> p0, p1, ... plast, p0, p1, ...\n\
Andrew M. Kuchlingdff694b2003-04-14 15:31:27 +00001769repeat(elem [,n]) --> elem, elem, elem, ... endlessly or up to n times\n\
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001770\n\
1771Iterators terminating on the shortest input sequence:\n\
1772izip(p, q, ...) --> (p[0], q[0]), (p[1], q[1]), ... \n\
Raymond Hettinger60eca932003-02-09 06:40:58 +00001773ifilter(pred, seq) --> elements of seq where pred(elem) is True\n\
1774ifilterfalse(pred, seq) --> elements of seq where pred(elem) is False\n\
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001775islice(seq, [start,] stop [, step]) --> elements from\n\
1776 seq[start:stop:step]\n\
1777imap(fun, p, q, ...) --> fun(p0, q0), fun(p1, q1), ...\n\
1778starmap(fun, seq) --> fun(*seq[0]), fun(*seq[1]), ...\n\
Raymond Hettinger61fe64d2003-02-23 04:40:07 +00001779chain(p, q, ...) --> p0, p1, ... plast, q0, q1, ... \n\
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001780takewhile(pred, seq) --> seq[0], seq[1], until pred fails\n\
1781dropwhile(pred, seq) --> seq[n], seq[n+1], starting when pred fails\n\
1782");
1783
1784
1785PyMODINIT_FUNC
1786inititertools(void)
1787{
Raymond Hettinger60eca932003-02-09 06:40:58 +00001788 int i;
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001789 PyObject *m;
Raymond Hettinger60eca932003-02-09 06:40:58 +00001790 char *name;
1791 PyTypeObject *typelist[] = {
Raymond Hettinger61fe64d2003-02-23 04:40:07 +00001792 &cycle_type,
Raymond Hettinger60eca932003-02-09 06:40:58 +00001793 &dropwhile_type,
1794 &takewhile_type,
1795 &islice_type,
1796 &starmap_type,
1797 &imap_type,
Raymond Hettinger61fe64d2003-02-23 04:40:07 +00001798 &chain_type,
Raymond Hettinger60eca932003-02-09 06:40:58 +00001799 &ifilter_type,
1800 &ifilterfalse_type,
1801 &count_type,
1802 &izip_type,
1803 &repeat_type,
1804 NULL
1805 };
1806
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001807 m = Py_InitModule3("itertools", NULL, module_doc);
1808
Raymond Hettinger60eca932003-02-09 06:40:58 +00001809 for (i=0 ; typelist[i] != NULL ; i++) {
1810 if (PyType_Ready(typelist[i]) < 0)
1811 return;
1812 name = strchr(typelist[i]->tp_name, '.') + 1;
Raymond Hettinger61fe64d2003-02-23 04:40:07 +00001813 assert (name != NULL);
Raymond Hettinger60eca932003-02-09 06:40:58 +00001814 Py_INCREF(typelist[i]);
1815 PyModule_AddObject(m, name, (PyObject *)typelist[i]);
1816 }
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001817}