blob: 5e359de3f50503082169614684e44636a5d28d62 [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
108static PyObject *
109cycle_getiter(PyObject *lz)
110{
111 Py_INCREF(lz);
112 return lz;
113}
114
115PyDoc_STRVAR(cycle_doc,
116"cycle(iterable) --> cycle object\n\
117\n\
118Return elements from the iterable until it is exhausted.\n\
119Then repeat the sequence indefinitely.");
120
121PyTypeObject cycle_type = {
122 PyObject_HEAD_INIT(NULL)
123 0, /* ob_size */
124 "itertools.cycle", /* tp_name */
125 sizeof(cycleobject), /* tp_basicsize */
126 0, /* tp_itemsize */
127 /* methods */
128 (destructor)cycle_dealloc, /* tp_dealloc */
129 0, /* tp_print */
130 0, /* tp_getattr */
131 0, /* tp_setattr */
132 0, /* tp_compare */
133 0, /* tp_repr */
134 0, /* tp_as_number */
135 0, /* tp_as_sequence */
136 0, /* tp_as_mapping */
137 0, /* tp_hash */
138 0, /* tp_call */
139 0, /* tp_str */
140 PyObject_GenericGetAttr, /* tp_getattro */
141 0, /* tp_setattro */
142 0, /* tp_as_buffer */
143 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
144 Py_TPFLAGS_BASETYPE, /* tp_flags */
145 cycle_doc, /* tp_doc */
146 (traverseproc)cycle_traverse, /* tp_traverse */
147 0, /* tp_clear */
148 0, /* tp_richcompare */
149 0, /* tp_weaklistoffset */
150 (getiterfunc)cycle_getiter, /* tp_iter */
151 (iternextfunc)cycle_next, /* tp_iternext */
152 0, /* tp_methods */
153 0, /* tp_members */
154 0, /* tp_getset */
155 0, /* tp_base */
156 0, /* tp_dict */
157 0, /* tp_descr_get */
158 0, /* tp_descr_set */
159 0, /* tp_dictoffset */
160 0, /* tp_init */
161 PyType_GenericAlloc, /* tp_alloc */
162 cycle_new, /* tp_new */
163 PyObject_GC_Del, /* tp_free */
164};
165
166
Raymond Hettinger96ef8112003-02-01 00:10:11 +0000167/* dropwhile object **********************************************************/
168
169typedef struct {
170 PyObject_HEAD
171 PyObject *func;
172 PyObject *it;
173 long start;
174} dropwhileobject;
175
176PyTypeObject dropwhile_type;
177
178static PyObject *
179dropwhile_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
180{
181 PyObject *func, *seq;
182 PyObject *it;
183 dropwhileobject *lz;
184
185 if (!PyArg_UnpackTuple(args, "dropwhile", 2, 2, &func, &seq))
186 return NULL;
187
188 /* Get iterator. */
189 it = PyObject_GetIter(seq);
190 if (it == NULL)
191 return NULL;
192
193 /* create dropwhileobject structure */
194 lz = (dropwhileobject *)type->tp_alloc(type, 0);
195 if (lz == NULL) {
196 Py_DECREF(it);
197 return NULL;
198 }
199 Py_INCREF(func);
200 lz->func = func;
201 lz->it = it;
202 lz->start = 0;
203
204 return (PyObject *)lz;
205}
206
207static void
208dropwhile_dealloc(dropwhileobject *lz)
209{
210 PyObject_GC_UnTrack(lz);
211 Py_XDECREF(lz->func);
212 Py_XDECREF(lz->it);
213 lz->ob_type->tp_free(lz);
214}
215
216static int
217dropwhile_traverse(dropwhileobject *lz, visitproc visit, void *arg)
218{
219 int err;
220
221 if (lz->it) {
222 err = visit(lz->it, arg);
223 if (err)
224 return err;
225 }
226 if (lz->func) {
227 err = visit(lz->func, arg);
228 if (err)
229 return err;
230 }
231 return 0;
232}
233
234static PyObject *
235dropwhile_next(dropwhileobject *lz)
236{
237 PyObject *item, *good;
Raymond Hettingerd1a283b2003-03-01 01:48:24 +0000238 PyObject *it = lz->it;
Raymond Hettinger96ef8112003-02-01 00:10:11 +0000239 long ok;
240
241 for (;;) {
Raymond Hettingerd1a283b2003-03-01 01:48:24 +0000242 assert(PyIter_Check(it));
243 item = (*it->ob_type->tp_iternext)(it);
Raymond Hettinger96ef8112003-02-01 00:10:11 +0000244 if (item == NULL)
245 return NULL;
246 if (lz->start == 1)
247 return item;
248
249 good = PyObject_CallFunctionObjArgs(lz->func, item, NULL);
250 if (good == NULL) {
251 Py_DECREF(item);
252 return NULL;
253 }
254 ok = PyObject_IsTrue(good);
255 Py_DECREF(good);
256 if (!ok) {
257 lz->start = 1;
258 return item;
259 }
260 Py_DECREF(item);
261 }
262}
263
264static PyObject *
265dropwhile_getiter(PyObject *lz)
266{
267 Py_INCREF(lz);
268 return lz;
269}
270
271PyDoc_STRVAR(dropwhile_doc,
272"dropwhile(predicate, iterable) --> dropwhile object\n\
273\n\
274Drop items from the iterable while predicate(item) is true.\n\
275Afterwards, return every element until the iterable is exhausted.");
276
277PyTypeObject dropwhile_type = {
278 PyObject_HEAD_INIT(NULL)
279 0, /* ob_size */
Raymond Hettinger60eca932003-02-09 06:40:58 +0000280 "itertools.dropwhile", /* tp_name */
281 sizeof(dropwhileobject), /* tp_basicsize */
Raymond Hettinger96ef8112003-02-01 00:10:11 +0000282 0, /* tp_itemsize */
283 /* methods */
Raymond Hettinger60eca932003-02-09 06:40:58 +0000284 (destructor)dropwhile_dealloc, /* tp_dealloc */
Raymond Hettinger96ef8112003-02-01 00:10:11 +0000285 0, /* tp_print */
286 0, /* tp_getattr */
287 0, /* tp_setattr */
288 0, /* tp_compare */
289 0, /* tp_repr */
290 0, /* tp_as_number */
291 0, /* tp_as_sequence */
292 0, /* tp_as_mapping */
293 0, /* tp_hash */
294 0, /* tp_call */
295 0, /* tp_str */
296 PyObject_GenericGetAttr, /* tp_getattro */
297 0, /* tp_setattro */
298 0, /* tp_as_buffer */
299 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
300 Py_TPFLAGS_BASETYPE, /* tp_flags */
Raymond Hettinger60eca932003-02-09 06:40:58 +0000301 dropwhile_doc, /* tp_doc */
Raymond Hettinger96ef8112003-02-01 00:10:11 +0000302 (traverseproc)dropwhile_traverse, /* tp_traverse */
303 0, /* tp_clear */
304 0, /* tp_richcompare */
305 0, /* tp_weaklistoffset */
Raymond Hettinger60eca932003-02-09 06:40:58 +0000306 (getiterfunc)dropwhile_getiter, /* tp_iter */
307 (iternextfunc)dropwhile_next, /* tp_iternext */
Raymond Hettinger96ef8112003-02-01 00:10:11 +0000308 0, /* tp_methods */
309 0, /* tp_members */
310 0, /* tp_getset */
311 0, /* tp_base */
312 0, /* tp_dict */
313 0, /* tp_descr_get */
314 0, /* tp_descr_set */
315 0, /* tp_dictoffset */
316 0, /* tp_init */
317 PyType_GenericAlloc, /* tp_alloc */
Raymond Hettinger60eca932003-02-09 06:40:58 +0000318 dropwhile_new, /* tp_new */
Raymond Hettinger96ef8112003-02-01 00:10:11 +0000319 PyObject_GC_Del, /* tp_free */
320};
321
322
323/* takewhile object **********************************************************/
324
325typedef struct {
326 PyObject_HEAD
327 PyObject *func;
328 PyObject *it;
329 long stop;
330} takewhileobject;
331
332PyTypeObject takewhile_type;
333
334static PyObject *
335takewhile_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
336{
337 PyObject *func, *seq;
338 PyObject *it;
339 takewhileobject *lz;
340
341 if (!PyArg_UnpackTuple(args, "takewhile", 2, 2, &func, &seq))
342 return NULL;
343
344 /* Get iterator. */
345 it = PyObject_GetIter(seq);
346 if (it == NULL)
347 return NULL;
348
349 /* create takewhileobject structure */
350 lz = (takewhileobject *)type->tp_alloc(type, 0);
351 if (lz == NULL) {
352 Py_DECREF(it);
353 return NULL;
354 }
355 Py_INCREF(func);
356 lz->func = func;
357 lz->it = it;
358 lz->stop = 0;
359
360 return (PyObject *)lz;
361}
362
363static void
364takewhile_dealloc(takewhileobject *lz)
365{
366 PyObject_GC_UnTrack(lz);
367 Py_XDECREF(lz->func);
368 Py_XDECREF(lz->it);
369 lz->ob_type->tp_free(lz);
370}
371
372static int
373takewhile_traverse(takewhileobject *lz, visitproc visit, void *arg)
374{
375 int err;
376
377 if (lz->it) {
378 err = visit(lz->it, arg);
379 if (err)
380 return err;
381 }
382 if (lz->func) {
383 err = visit(lz->func, arg);
384 if (err)
385 return err;
386 }
387 return 0;
388}
389
390static PyObject *
391takewhile_next(takewhileobject *lz)
392{
393 PyObject *item, *good;
Raymond Hettingerd1a283b2003-03-01 01:48:24 +0000394 PyObject *it = lz->it;
Raymond Hettinger96ef8112003-02-01 00:10:11 +0000395 long ok;
396
397 if (lz->stop == 1)
398 return NULL;
399
Raymond Hettingerd1a283b2003-03-01 01:48:24 +0000400 assert(PyIter_Check(it));
401 item = (*it->ob_type->tp_iternext)(it);
Raymond Hettinger96ef8112003-02-01 00:10:11 +0000402 if (item == NULL)
403 return NULL;
404
405 good = PyObject_CallFunctionObjArgs(lz->func, item, NULL);
406 if (good == NULL) {
407 Py_DECREF(item);
408 return NULL;
409 }
410 ok = PyObject_IsTrue(good);
411 Py_DECREF(good);
412 if (ok)
413 return item;
414 Py_DECREF(item);
415 lz->stop = 1;
416 return NULL;
417}
418
419static PyObject *
420takewhile_getiter(PyObject *lz)
421{
422 Py_INCREF(lz);
423 return lz;
424}
425
426PyDoc_STRVAR(takewhile_doc,
427"takewhile(predicate, iterable) --> takewhile object\n\
428\n\
429Return successive entries from an iterable as long as the \n\
430predicate evaluates to true for each entry.");
431
432PyTypeObject takewhile_type = {
433 PyObject_HEAD_INIT(NULL)
434 0, /* ob_size */
Raymond Hettinger60eca932003-02-09 06:40:58 +0000435 "itertools.takewhile", /* tp_name */
436 sizeof(takewhileobject), /* tp_basicsize */
Raymond Hettinger96ef8112003-02-01 00:10:11 +0000437 0, /* tp_itemsize */
438 /* methods */
Raymond Hettinger60eca932003-02-09 06:40:58 +0000439 (destructor)takewhile_dealloc, /* tp_dealloc */
Raymond Hettinger96ef8112003-02-01 00:10:11 +0000440 0, /* tp_print */
441 0, /* tp_getattr */
442 0, /* tp_setattr */
443 0, /* tp_compare */
444 0, /* tp_repr */
445 0, /* tp_as_number */
446 0, /* tp_as_sequence */
447 0, /* tp_as_mapping */
448 0, /* tp_hash */
449 0, /* tp_call */
450 0, /* tp_str */
451 PyObject_GenericGetAttr, /* tp_getattro */
452 0, /* tp_setattro */
453 0, /* tp_as_buffer */
454 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
455 Py_TPFLAGS_BASETYPE, /* tp_flags */
Raymond Hettinger60eca932003-02-09 06:40:58 +0000456 takewhile_doc, /* tp_doc */
Raymond Hettinger96ef8112003-02-01 00:10:11 +0000457 (traverseproc)takewhile_traverse, /* tp_traverse */
458 0, /* tp_clear */
459 0, /* tp_richcompare */
460 0, /* tp_weaklistoffset */
Raymond Hettinger60eca932003-02-09 06:40:58 +0000461 (getiterfunc)takewhile_getiter, /* tp_iter */
462 (iternextfunc)takewhile_next, /* tp_iternext */
Raymond Hettinger96ef8112003-02-01 00:10:11 +0000463 0, /* tp_methods */
464 0, /* tp_members */
465 0, /* tp_getset */
466 0, /* tp_base */
467 0, /* tp_dict */
468 0, /* tp_descr_get */
469 0, /* tp_descr_set */
470 0, /* tp_dictoffset */
471 0, /* tp_init */
472 PyType_GenericAlloc, /* tp_alloc */
Raymond Hettinger60eca932003-02-09 06:40:58 +0000473 takewhile_new, /* tp_new */
Raymond Hettinger96ef8112003-02-01 00:10:11 +0000474 PyObject_GC_Del, /* tp_free */
475};
476
477
478/* islice object ************************************************************/
479
480typedef struct {
481 PyObject_HEAD
482 PyObject *it;
483 long next;
484 long stop;
485 long step;
486 long cnt;
487} isliceobject;
488
489PyTypeObject islice_type;
490
491static PyObject *
492islice_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
493{
494 PyObject *seq;
495 long a1=0, a2=0, a3=0, start=0, stop=0, step=1;
496 PyObject *it;
497 int numargs;
498 isliceobject *lz;
499
500 numargs = PyTuple_Size(args);
501 if (!PyArg_ParseTuple(args, "Ol|ll:islice", &seq, &a1, &a2, &a3))
502 return NULL;
503
504 if (numargs == 2) {
505 stop = a1;
506 } else if (numargs == 3) {
507 start = a1;
508 stop = a2;
509 } else {
510 start = a1;
511 stop = a2;
512 step = a3;
513 }
514
515 if (start<0 || stop<0) {
516 PyErr_SetString(PyExc_ValueError,
517 "Indices for islice() must be positive.");
518 return NULL;
519 }
520
521 if (step<1) {
522 PyErr_SetString(PyExc_ValueError,
523 "Step must be one or larger for islice().");
524 return NULL;
525 }
526
527 /* Get iterator. */
528 it = PyObject_GetIter(seq);
529 if (it == NULL)
530 return NULL;
531
532 /* create isliceobject structure */
533 lz = (isliceobject *)type->tp_alloc(type, 0);
534 if (lz == NULL) {
535 Py_DECREF(it);
536 return NULL;
537 }
538 lz->it = it;
539 lz->next = start;
540 lz->stop = stop;
541 lz->step = step;
542 lz->cnt = 0L;
543
544 return (PyObject *)lz;
545}
546
547static void
548islice_dealloc(isliceobject *lz)
549{
550 PyObject_GC_UnTrack(lz);
551 Py_XDECREF(lz->it);
552 lz->ob_type->tp_free(lz);
553}
554
555static int
556islice_traverse(isliceobject *lz, visitproc visit, void *arg)
557{
558 if (lz->it)
559 return visit(lz->it, arg);
560 return 0;
561}
562
563static PyObject *
564islice_next(isliceobject *lz)
565{
566 PyObject *item;
Raymond Hettingerd1a283b2003-03-01 01:48:24 +0000567 PyObject *it = lz->it;
Raymond Hettinger2012f172003-02-07 05:32:58 +0000568 long oldnext;
Raymond Hettinger96ef8112003-02-01 00:10:11 +0000569
570 while (lz->cnt < lz->next) {
Raymond Hettingerd1a283b2003-03-01 01:48:24 +0000571 assert(PyIter_Check(it));
572 item = (*it->ob_type->tp_iternext)(it);
Raymond Hettinger96ef8112003-02-01 00:10:11 +0000573 if (item == NULL)
574 return NULL;
575 Py_DECREF(item);
576 lz->cnt++;
577 }
578 if (lz->cnt >= lz->stop)
579 return NULL;
Raymond Hettingerd1a283b2003-03-01 01:48:24 +0000580 assert(PyIter_Check(it));
581 item = (*it->ob_type->tp_iternext)(it);
Raymond Hettinger96ef8112003-02-01 00:10:11 +0000582 if (item == NULL)
583 return NULL;
584 lz->cnt++;
Raymond Hettinger2012f172003-02-07 05:32:58 +0000585 oldnext = lz->next;
Raymond Hettinger96ef8112003-02-01 00:10:11 +0000586 lz->next += lz->step;
Raymond Hettinger2012f172003-02-07 05:32:58 +0000587 if (lz->next < oldnext) /* Check for overflow */
588 lz->next = lz->stop;
Raymond Hettinger96ef8112003-02-01 00:10:11 +0000589 return item;
590}
591
592static PyObject *
593islice_getiter(PyObject *lz)
594{
595 Py_INCREF(lz);
596 return lz;
597}
598
599PyDoc_STRVAR(islice_doc,
600"islice(iterable, [start,] stop [, step]) --> islice object\n\
601\n\
602Return an iterator whose next() method returns selected values from an\n\
603iterable. If start is specified, will skip all preceding elements;\n\
604otherwise, start defaults to zero. Step defaults to one. If\n\
605specified as another value, step determines how many values are \n\
606skipped between successive calls. Works like a slice() on a list\n\
607but returns an iterator.");
608
609PyTypeObject islice_type = {
610 PyObject_HEAD_INIT(NULL)
611 0, /* ob_size */
612 "itertools.islice", /* tp_name */
613 sizeof(isliceobject), /* tp_basicsize */
614 0, /* tp_itemsize */
615 /* methods */
Raymond Hettinger60eca932003-02-09 06:40:58 +0000616 (destructor)islice_dealloc, /* tp_dealloc */
Raymond Hettinger96ef8112003-02-01 00:10:11 +0000617 0, /* tp_print */
618 0, /* tp_getattr */
619 0, /* tp_setattr */
620 0, /* tp_compare */
621 0, /* tp_repr */
622 0, /* tp_as_number */
623 0, /* tp_as_sequence */
624 0, /* tp_as_mapping */
625 0, /* tp_hash */
626 0, /* tp_call */
627 0, /* tp_str */
628 PyObject_GenericGetAttr, /* tp_getattro */
629 0, /* tp_setattro */
630 0, /* tp_as_buffer */
631 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
632 Py_TPFLAGS_BASETYPE, /* tp_flags */
Raymond Hettinger60eca932003-02-09 06:40:58 +0000633 islice_doc, /* tp_doc */
634 (traverseproc)islice_traverse, /* tp_traverse */
Raymond Hettinger96ef8112003-02-01 00:10:11 +0000635 0, /* tp_clear */
636 0, /* tp_richcompare */
637 0, /* tp_weaklistoffset */
Raymond Hettinger60eca932003-02-09 06:40:58 +0000638 (getiterfunc)islice_getiter, /* tp_iter */
639 (iternextfunc)islice_next, /* tp_iternext */
Raymond Hettinger96ef8112003-02-01 00:10:11 +0000640 0, /* tp_methods */
641 0, /* tp_members */
642 0, /* tp_getset */
643 0, /* tp_base */
644 0, /* tp_dict */
645 0, /* tp_descr_get */
646 0, /* tp_descr_set */
647 0, /* tp_dictoffset */
648 0, /* tp_init */
649 PyType_GenericAlloc, /* tp_alloc */
650 islice_new, /* tp_new */
651 PyObject_GC_Del, /* tp_free */
652};
653
654
655/* starmap object ************************************************************/
656
657typedef struct {
658 PyObject_HEAD
659 PyObject *func;
660 PyObject *it;
661} starmapobject;
662
663PyTypeObject starmap_type;
664
665static PyObject *
666starmap_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
667{
668 PyObject *func, *seq;
669 PyObject *it;
670 starmapobject *lz;
671
672 if (!PyArg_UnpackTuple(args, "starmap", 2, 2, &func, &seq))
673 return NULL;
674
675 /* Get iterator. */
676 it = PyObject_GetIter(seq);
677 if (it == NULL)
678 return NULL;
679
680 /* create starmapobject structure */
681 lz = (starmapobject *)type->tp_alloc(type, 0);
682 if (lz == NULL) {
683 Py_DECREF(it);
684 return NULL;
685 }
686 Py_INCREF(func);
687 lz->func = func;
688 lz->it = it;
689
690 return (PyObject *)lz;
691}
692
693static void
694starmap_dealloc(starmapobject *lz)
695{
696 PyObject_GC_UnTrack(lz);
697 Py_XDECREF(lz->func);
698 Py_XDECREF(lz->it);
699 lz->ob_type->tp_free(lz);
700}
701
702static int
703starmap_traverse(starmapobject *lz, visitproc visit, void *arg)
704{
705 int err;
706
707 if (lz->it) {
708 err = visit(lz->it, arg);
709 if (err)
710 return err;
711 }
712 if (lz->func) {
713 err = visit(lz->func, arg);
714 if (err)
715 return err;
716 }
717 return 0;
718}
719
720static PyObject *
721starmap_next(starmapobject *lz)
722{
723 PyObject *args;
724 PyObject *result;
Raymond Hettingerd1a283b2003-03-01 01:48:24 +0000725 PyObject *it = lz->it;
Raymond Hettinger96ef8112003-02-01 00:10:11 +0000726
Raymond Hettingerd1a283b2003-03-01 01:48:24 +0000727 assert(PyIter_Check(it));
728 args = (*it->ob_type->tp_iternext)(it);
Raymond Hettinger96ef8112003-02-01 00:10:11 +0000729 if (args == NULL)
730 return NULL;
Raymond Hettinger2012f172003-02-07 05:32:58 +0000731 if (!PyTuple_CheckExact(args)) {
732 Py_DECREF(args);
733 PyErr_SetString(PyExc_TypeError,
734 "iterator must return a tuple");
735 return NULL;
736 }
Raymond Hettinger96ef8112003-02-01 00:10:11 +0000737 result = PyObject_Call(lz->func, args, NULL);
738 Py_DECREF(args);
739 return result;
740}
741
742static PyObject *
743starmap_getiter(PyObject *lz)
744{
745 Py_INCREF(lz);
746 return lz;
747}
748
749PyDoc_STRVAR(starmap_doc,
750"starmap(function, sequence) --> starmap object\n\
751\n\
752Return an iterator whose values are returned from the function evaluated\n\
753with a argument tuple taken from the given sequence.");
754
755PyTypeObject starmap_type = {
756 PyObject_HEAD_INIT(NULL)
757 0, /* ob_size */
Raymond Hettinger60eca932003-02-09 06:40:58 +0000758 "itertools.starmap", /* tp_name */
759 sizeof(starmapobject), /* tp_basicsize */
Raymond Hettinger96ef8112003-02-01 00:10:11 +0000760 0, /* tp_itemsize */
761 /* methods */
Raymond Hettinger60eca932003-02-09 06:40:58 +0000762 (destructor)starmap_dealloc, /* tp_dealloc */
Raymond Hettinger96ef8112003-02-01 00:10:11 +0000763 0, /* tp_print */
764 0, /* tp_getattr */
765 0, /* tp_setattr */
766 0, /* tp_compare */
767 0, /* tp_repr */
768 0, /* tp_as_number */
769 0, /* tp_as_sequence */
770 0, /* tp_as_mapping */
771 0, /* tp_hash */
772 0, /* tp_call */
773 0, /* tp_str */
774 PyObject_GenericGetAttr, /* tp_getattro */
775 0, /* tp_setattro */
776 0, /* tp_as_buffer */
777 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
778 Py_TPFLAGS_BASETYPE, /* tp_flags */
Raymond Hettinger60eca932003-02-09 06:40:58 +0000779 starmap_doc, /* tp_doc */
780 (traverseproc)starmap_traverse, /* tp_traverse */
Raymond Hettinger96ef8112003-02-01 00:10:11 +0000781 0, /* tp_clear */
782 0, /* tp_richcompare */
783 0, /* tp_weaklistoffset */
Raymond Hettinger60eca932003-02-09 06:40:58 +0000784 (getiterfunc)starmap_getiter, /* tp_iter */
785 (iternextfunc)starmap_next, /* tp_iternext */
Raymond Hettinger96ef8112003-02-01 00:10:11 +0000786 0, /* tp_methods */
787 0, /* tp_members */
788 0, /* tp_getset */
789 0, /* tp_base */
790 0, /* tp_dict */
791 0, /* tp_descr_get */
792 0, /* tp_descr_set */
793 0, /* tp_dictoffset */
794 0, /* tp_init */
795 PyType_GenericAlloc, /* tp_alloc */
Raymond Hettinger60eca932003-02-09 06:40:58 +0000796 starmap_new, /* tp_new */
Raymond Hettinger96ef8112003-02-01 00:10:11 +0000797 PyObject_GC_Del, /* tp_free */
798};
799
800
801/* imap object ************************************************************/
802
803typedef struct {
804 PyObject_HEAD
805 PyObject *iters;
Raymond Hettinger96ef8112003-02-01 00:10:11 +0000806 PyObject *func;
807} imapobject;
808
809PyTypeObject imap_type;
810
811static PyObject *
812imap_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
813{
Raymond Hettingerf0c00242003-02-07 07:26:25 +0000814 PyObject *it, *iters, *func;
Raymond Hettinger96ef8112003-02-01 00:10:11 +0000815 imapobject *lz;
816 int numargs, i;
817
818 numargs = PyTuple_Size(args);
819 if (numargs < 2) {
820 PyErr_SetString(PyExc_TypeError,
821 "imap() must have at least two arguments.");
822 return NULL;
823 }
824
825 iters = PyTuple_New(numargs-1);
826 if (iters == NULL)
827 return NULL;
828
Raymond Hettinger96ef8112003-02-01 00:10:11 +0000829 for (i=1 ; i<numargs ; i++) {
830 /* Get iterator. */
831 it = PyObject_GetIter(PyTuple_GET_ITEM(args, i));
832 if (it == NULL) {
Raymond Hettinger96ef8112003-02-01 00:10:11 +0000833 Py_DECREF(iters);
834 return NULL;
835 }
836 PyTuple_SET_ITEM(iters, i-1, it);
Raymond Hettinger96ef8112003-02-01 00:10:11 +0000837 }
838
839 /* create imapobject structure */
840 lz = (imapobject *)type->tp_alloc(type, 0);
841 if (lz == NULL) {
Raymond Hettinger96ef8112003-02-01 00:10:11 +0000842 Py_DECREF(iters);
843 return NULL;
844 }
845 lz->iters = iters;
Raymond Hettinger96ef8112003-02-01 00:10:11 +0000846 func = PyTuple_GET_ITEM(args, 0);
847 Py_INCREF(func);
848 lz->func = func;
849
850 return (PyObject *)lz;
851}
852
853static void
854imap_dealloc(imapobject *lz)
855{
856 PyObject_GC_UnTrack(lz);
Raymond Hettinger96ef8112003-02-01 00:10:11 +0000857 Py_XDECREF(lz->iters);
858 Py_XDECREF(lz->func);
859 lz->ob_type->tp_free(lz);
860}
861
862static int
863imap_traverse(imapobject *lz, visitproc visit, void *arg)
864{
865 int err;
866
867 if (lz->iters) {
868 err = visit(lz->iters, arg);
869 if (err)
870 return err;
871 }
Raymond Hettinger96ef8112003-02-01 00:10:11 +0000872 if (lz->func) {
873 err = visit(lz->func, arg);
874 if (err)
875 return err;
876 }
877 return 0;
878}
879
Raymond Hettinger2012f172003-02-07 05:32:58 +0000880/*
881imap() is an iterator version of __builtins__.map() except that it does
882not have the None fill-in feature. That was intentionally left out for
883the following reasons:
884
885 1) Itertools are designed to be easily combined and chained together.
886 Having all tools stop with the shortest input is a unifying principle
887 that makes it easier to combine finite iterators (supplying data) with
888 infinite iterators like count() and repeat() (for supplying sequential
889 or constant arguments to a function).
890
891 2) In typical use cases for combining itertools, having one finite data
892 supplier run out before another is likely to be an error condition which
893 should not pass silently by automatically supplying None.
894
895 3) The use cases for automatic None fill-in are rare -- not many functions
896 do something useful when a parameter suddenly switches type and becomes
897 None.
898
899 4) If a need does arise, it can be met by __builtins__.map() or by
900 writing a generator.
901
902 5) Similar toolsets in Haskell and SML do not have automatic None fill-in.
903*/
904
Raymond Hettinger96ef8112003-02-01 00:10:11 +0000905static PyObject *
906imap_next(imapobject *lz)
907{
908 PyObject *val;
Raymond Hettingerf0c00242003-02-07 07:26:25 +0000909 PyObject *argtuple;
910 PyObject *result;
Raymond Hettinger96ef8112003-02-01 00:10:11 +0000911 int numargs, i;
912
913 numargs = PyTuple_Size(lz->iters);
Raymond Hettingerf0c00242003-02-07 07:26:25 +0000914 argtuple = PyTuple_New(numargs);
915 if (argtuple == NULL)
916 return NULL;
Raymond Hettinger96ef8112003-02-01 00:10:11 +0000917
Raymond Hettingerf0c00242003-02-07 07:26:25 +0000918 for (i=0 ; i<numargs ; i++) {
919 val = PyIter_Next(PyTuple_GET_ITEM(lz->iters, i));
920 if (val == NULL) {
921 Py_DECREF(argtuple);
922 return NULL;
Raymond Hettinger96ef8112003-02-01 00:10:11 +0000923 }
Raymond Hettingerf0c00242003-02-07 07:26:25 +0000924 PyTuple_SET_ITEM(argtuple, i, val);
Raymond Hettinger96ef8112003-02-01 00:10:11 +0000925 }
Raymond Hettingerf0c00242003-02-07 07:26:25 +0000926 if (lz->func == Py_None)
927 return argtuple;
928 result = PyObject_Call(lz->func, argtuple, NULL);
929 Py_DECREF(argtuple);
930 return result;
Raymond Hettinger96ef8112003-02-01 00:10:11 +0000931}
932
933static PyObject *
934imap_getiter(PyObject *lz)
935{
936 Py_INCREF(lz);
937 return lz;
938}
939
940PyDoc_STRVAR(imap_doc,
941"imap(func, *iterables) --> imap object\n\
942\n\
943Make an iterator that computes the function using arguments from\n\
944each of the iterables. Like map() except that it returns\n\
945an iterator instead of a list and that it stops when the shortest\n\
946iterable is exhausted instead of filling in None for shorter\n\
947iterables.");
948
949PyTypeObject imap_type = {
950 PyObject_HEAD_INIT(NULL)
951 0, /* ob_size */
Raymond Hettinger60eca932003-02-09 06:40:58 +0000952 "itertools.imap", /* tp_name */
953 sizeof(imapobject), /* tp_basicsize */
Raymond Hettinger96ef8112003-02-01 00:10:11 +0000954 0, /* tp_itemsize */
955 /* methods */
956 (destructor)imap_dealloc, /* tp_dealloc */
957 0, /* tp_print */
958 0, /* tp_getattr */
959 0, /* tp_setattr */
960 0, /* tp_compare */
961 0, /* tp_repr */
962 0, /* tp_as_number */
963 0, /* tp_as_sequence */
964 0, /* tp_as_mapping */
965 0, /* tp_hash */
966 0, /* tp_call */
967 0, /* tp_str */
968 PyObject_GenericGetAttr, /* tp_getattro */
969 0, /* tp_setattro */
970 0, /* tp_as_buffer */
971 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
972 Py_TPFLAGS_BASETYPE, /* tp_flags */
973 imap_doc, /* tp_doc */
974 (traverseproc)imap_traverse, /* tp_traverse */
975 0, /* tp_clear */
976 0, /* tp_richcompare */
977 0, /* tp_weaklistoffset */
978 (getiterfunc)imap_getiter, /* tp_iter */
979 (iternextfunc)imap_next, /* tp_iternext */
980 0, /* tp_methods */
981 0, /* tp_members */
982 0, /* tp_getset */
983 0, /* tp_base */
984 0, /* tp_dict */
985 0, /* tp_descr_get */
986 0, /* tp_descr_set */
987 0, /* tp_dictoffset */
988 0, /* tp_init */
989 PyType_GenericAlloc, /* tp_alloc */
Raymond Hettinger60eca932003-02-09 06:40:58 +0000990 imap_new, /* tp_new */
Raymond Hettinger96ef8112003-02-01 00:10:11 +0000991 PyObject_GC_Del, /* tp_free */
992};
993
994
Raymond Hettinger61fe64d2003-02-23 04:40:07 +0000995/* chain object ************************************************************/
Raymond Hettinger96ef8112003-02-01 00:10:11 +0000996
997typedef struct {
998 PyObject_HEAD
Raymond Hettinger61fe64d2003-02-23 04:40:07 +0000999 long tuplesize;
1000 long iternum; /* which iterator is active */
1001 PyObject *ittuple; /* tuple of iterators */
1002} chainobject;
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001003
Raymond Hettinger61fe64d2003-02-23 04:40:07 +00001004PyTypeObject chain_type;
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001005
1006static PyObject *
Raymond Hettinger61fe64d2003-02-23 04:40:07 +00001007chain_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001008{
Raymond Hettinger61fe64d2003-02-23 04:40:07 +00001009 chainobject *lz;
1010 int tuplesize = PySequence_Length(args);
1011 int i;
1012 PyObject *ittuple;
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001013
Raymond Hettinger61fe64d2003-02-23 04:40:07 +00001014 /* obtain iterators */
1015 assert(PyTuple_Check(args));
1016 ittuple = PyTuple_New(tuplesize);
1017 if(ittuple == NULL)
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001018 return NULL;
Raymond Hettinger61fe64d2003-02-23 04:40:07 +00001019 for (i=0; i < tuplesize; ++i) {
1020 PyObject *item = PyTuple_GET_ITEM(args, i);
1021 PyObject *it = PyObject_GetIter(item);
1022 if (it == NULL) {
1023 if (PyErr_ExceptionMatches(PyExc_TypeError))
1024 PyErr_Format(PyExc_TypeError,
1025 "chain argument #%d must support iteration",
1026 i+1);
1027 Py_DECREF(ittuple);
1028 return NULL;
1029 }
1030 PyTuple_SET_ITEM(ittuple, i, it);
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001031 }
1032
Raymond Hettinger61fe64d2003-02-23 04:40:07 +00001033 /* create chainobject structure */
1034 lz = (chainobject *)type->tp_alloc(type, 0);
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001035 if (lz == NULL)
1036 return NULL;
Raymond Hettinger61fe64d2003-02-23 04:40:07 +00001037
1038 lz->ittuple = ittuple;
1039 lz->iternum = 0;
1040 lz->tuplesize = tuplesize;
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001041
1042 return (PyObject *)lz;
1043}
1044
1045static void
Raymond Hettinger61fe64d2003-02-23 04:40:07 +00001046chain_dealloc(chainobject *lz)
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001047{
1048 PyObject_GC_UnTrack(lz);
Raymond Hettinger61fe64d2003-02-23 04:40:07 +00001049 Py_XDECREF(lz->ittuple);
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001050 lz->ob_type->tp_free(lz);
1051}
1052
Raymond Hettinger2012f172003-02-07 05:32:58 +00001053static int
Raymond Hettinger61fe64d2003-02-23 04:40:07 +00001054chain_traverse(chainobject *lz, visitproc visit, void *arg)
Raymond Hettinger2012f172003-02-07 05:32:58 +00001055{
Raymond Hettinger61fe64d2003-02-23 04:40:07 +00001056 if (lz->ittuple)
1057 return visit(lz->ittuple, arg);
Raymond Hettinger2012f172003-02-07 05:32:58 +00001058 return 0;
1059}
1060
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001061static PyObject *
Raymond Hettinger61fe64d2003-02-23 04:40:07 +00001062chain_next(chainobject *lz)
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001063{
Raymond Hettinger61fe64d2003-02-23 04:40:07 +00001064 PyObject *it;
1065 PyObject *item;
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001066
Raymond Hettinger61fe64d2003-02-23 04:40:07 +00001067 while (lz->iternum < lz->tuplesize) {
1068 it = PyTuple_GET_ITEM(lz->ittuple, lz->iternum);
1069 item = PyIter_Next(it);
1070 if (item != NULL)
1071 return item;
1072 lz->iternum++;
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001073 }
1074 return NULL;
1075}
1076
1077static PyObject *
Raymond Hettinger61fe64d2003-02-23 04:40:07 +00001078chain_getiter(PyObject *lz)
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001079{
1080 Py_INCREF(lz);
1081 return lz;
1082}
1083
Raymond Hettinger61fe64d2003-02-23 04:40:07 +00001084PyDoc_STRVAR(chain_doc,
1085"chain(*iterables) --> chain object\n\
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001086\n\
Raymond Hettinger61fe64d2003-02-23 04:40:07 +00001087Return a chain object whose .next() method returns elements from the\n\
1088first iterable until it is exhausted, then elements from the next\n\
1089iterable, until all of the iterables are exhausted.");
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001090
Raymond Hettinger61fe64d2003-02-23 04:40:07 +00001091PyTypeObject chain_type = {
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001092 PyObject_HEAD_INIT(NULL)
1093 0, /* ob_size */
Raymond Hettinger61fe64d2003-02-23 04:40:07 +00001094 "itertools.chain", /* tp_name */
1095 sizeof(chainobject), /* tp_basicsize */
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001096 0, /* tp_itemsize */
1097 /* methods */
Raymond Hettinger61fe64d2003-02-23 04:40:07 +00001098 (destructor)chain_dealloc, /* tp_dealloc */
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001099 0, /* tp_print */
1100 0, /* tp_getattr */
1101 0, /* tp_setattr */
1102 0, /* tp_compare */
1103 0, /* tp_repr */
1104 0, /* tp_as_number */
1105 0, /* tp_as_sequence */
1106 0, /* tp_as_mapping */
1107 0, /* tp_hash */
1108 0, /* tp_call */
1109 0, /* tp_str */
1110 PyObject_GenericGetAttr, /* tp_getattro */
1111 0, /* tp_setattro */
1112 0, /* tp_as_buffer */
1113 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
1114 Py_TPFLAGS_BASETYPE, /* tp_flags */
Raymond Hettinger61fe64d2003-02-23 04:40:07 +00001115 chain_doc, /* tp_doc */
1116 (traverseproc)chain_traverse, /* tp_traverse */
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001117 0, /* tp_clear */
1118 0, /* tp_richcompare */
1119 0, /* tp_weaklistoffset */
Raymond Hettinger61fe64d2003-02-23 04:40:07 +00001120 (getiterfunc)chain_getiter, /* tp_iter */
1121 (iternextfunc)chain_next, /* tp_iternext */
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001122 0, /* tp_methods */
1123 0, /* tp_members */
1124 0, /* tp_getset */
1125 0, /* tp_base */
1126 0, /* tp_dict */
1127 0, /* tp_descr_get */
1128 0, /* tp_descr_set */
1129 0, /* tp_dictoffset */
1130 0, /* tp_init */
1131 PyType_GenericAlloc, /* tp_alloc */
Raymond Hettinger61fe64d2003-02-23 04:40:07 +00001132 chain_new, /* tp_new */
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001133 PyObject_GC_Del, /* tp_free */
1134};
1135
1136
1137/* ifilter object ************************************************************/
1138
1139typedef struct {
1140 PyObject_HEAD
1141 PyObject *func;
1142 PyObject *it;
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001143} ifilterobject;
1144
1145PyTypeObject ifilter_type;
1146
1147static PyObject *
1148ifilter_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1149{
Raymond Hettinger60eca932003-02-09 06:40:58 +00001150 PyObject *func, *seq;
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001151 PyObject *it;
1152 ifilterobject *lz;
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001153
Raymond Hettinger60eca932003-02-09 06:40:58 +00001154 if (!PyArg_UnpackTuple(args, "ifilter", 2, 2, &func, &seq))
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001155 return NULL;
1156
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001157 /* Get iterator. */
1158 it = PyObject_GetIter(seq);
1159 if (it == NULL)
1160 return NULL;
1161
1162 /* create ifilterobject structure */
1163 lz = (ifilterobject *)type->tp_alloc(type, 0);
1164 if (lz == NULL) {
1165 Py_DECREF(it);
1166 return NULL;
1167 }
1168 Py_INCREF(func);
1169 lz->func = func;
1170 lz->it = it;
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001171
1172 return (PyObject *)lz;
1173}
1174
1175static void
1176ifilter_dealloc(ifilterobject *lz)
1177{
1178 PyObject_GC_UnTrack(lz);
1179 Py_XDECREF(lz->func);
1180 Py_XDECREF(lz->it);
1181 lz->ob_type->tp_free(lz);
1182}
1183
1184static int
1185ifilter_traverse(ifilterobject *lz, visitproc visit, void *arg)
1186{
1187 int err;
1188
1189 if (lz->it) {
1190 err = visit(lz->it, arg);
1191 if (err)
1192 return err;
1193 }
1194 if (lz->func) {
1195 err = visit(lz->func, arg);
1196 if (err)
1197 return err;
1198 }
1199 return 0;
1200}
1201
1202static PyObject *
1203ifilter_next(ifilterobject *lz)
1204{
1205 PyObject *item;
Raymond Hettingerd1a283b2003-03-01 01:48:24 +00001206 PyObject *it = lz->it;
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001207 long ok;
1208
1209 for (;;) {
Raymond Hettingerd1a283b2003-03-01 01:48:24 +00001210 assert(PyIter_Check(it));
1211 item = (*it->ob_type->tp_iternext)(it);
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001212 if (item == NULL)
1213 return NULL;
1214
1215 if (lz->func == Py_None) {
1216 ok = PyObject_IsTrue(item);
1217 } else {
1218 PyObject *good;
1219 good = PyObject_CallFunctionObjArgs(lz->func,
1220 item, NULL);
1221 if (good == NULL) {
1222 Py_DECREF(item);
1223 return NULL;
1224 }
1225 ok = PyObject_IsTrue(good);
1226 Py_DECREF(good);
1227 }
Raymond Hettinger60eca932003-02-09 06:40:58 +00001228 if (ok)
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001229 return item;
1230 Py_DECREF(item);
1231 }
1232}
1233
1234static PyObject *
1235ifilter_getiter(PyObject *lz)
1236{
1237 Py_INCREF(lz);
1238 return lz;
1239}
1240
1241PyDoc_STRVAR(ifilter_doc,
Raymond Hettinger60eca932003-02-09 06:40:58 +00001242"ifilter(function or None, sequence) --> ifilter object\n\
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001243\n\
Raymond Hettinger60eca932003-02-09 06:40:58 +00001244Return those items of sequence for which function(item) is true.\n\
1245If function is None, return the items that are true.");
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001246
1247PyTypeObject ifilter_type = {
1248 PyObject_HEAD_INIT(NULL)
1249 0, /* ob_size */
Raymond Hettinger60eca932003-02-09 06:40:58 +00001250 "itertools.ifilter", /* tp_name */
1251 sizeof(ifilterobject), /* tp_basicsize */
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001252 0, /* tp_itemsize */
1253 /* methods */
Raymond Hettinger60eca932003-02-09 06:40:58 +00001254 (destructor)ifilter_dealloc, /* tp_dealloc */
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001255 0, /* tp_print */
1256 0, /* tp_getattr */
1257 0, /* tp_setattr */
1258 0, /* tp_compare */
1259 0, /* tp_repr */
1260 0, /* tp_as_number */
1261 0, /* tp_as_sequence */
1262 0, /* tp_as_mapping */
1263 0, /* tp_hash */
1264 0, /* tp_call */
1265 0, /* tp_str */
1266 PyObject_GenericGetAttr, /* tp_getattro */
1267 0, /* tp_setattro */
1268 0, /* tp_as_buffer */
1269 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
1270 Py_TPFLAGS_BASETYPE, /* tp_flags */
Raymond Hettinger60eca932003-02-09 06:40:58 +00001271 ifilter_doc, /* tp_doc */
1272 (traverseproc)ifilter_traverse, /* tp_traverse */
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001273 0, /* tp_clear */
1274 0, /* tp_richcompare */
1275 0, /* tp_weaklistoffset */
Raymond Hettinger60eca932003-02-09 06:40:58 +00001276 (getiterfunc)ifilter_getiter, /* tp_iter */
1277 (iternextfunc)ifilter_next, /* tp_iternext */
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001278 0, /* tp_methods */
1279 0, /* tp_members */
1280 0, /* tp_getset */
1281 0, /* tp_base */
1282 0, /* tp_dict */
1283 0, /* tp_descr_get */
1284 0, /* tp_descr_set */
1285 0, /* tp_dictoffset */
1286 0, /* tp_init */
1287 PyType_GenericAlloc, /* tp_alloc */
Raymond Hettinger60eca932003-02-09 06:40:58 +00001288 ifilter_new, /* tp_new */
1289 PyObject_GC_Del, /* tp_free */
1290};
1291
1292
1293/* ifilterfalse object ************************************************************/
1294
1295typedef struct {
1296 PyObject_HEAD
1297 PyObject *func;
1298 PyObject *it;
1299} ifilterfalseobject;
1300
1301PyTypeObject ifilterfalse_type;
1302
1303static PyObject *
1304ifilterfalse_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1305{
Guido van Rossumd58f3fc2003-02-09 17:19:18 +00001306 PyObject *func, *seq;
Raymond Hettinger60eca932003-02-09 06:40:58 +00001307 PyObject *it;
1308 ifilterfalseobject *lz;
1309
1310 if (!PyArg_UnpackTuple(args, "ifilterfalse", 2, 2, &func, &seq))
1311 return NULL;
1312
1313 /* Get iterator. */
1314 it = PyObject_GetIter(seq);
1315 if (it == NULL)
1316 return NULL;
1317
1318 /* create ifilterfalseobject structure */
1319 lz = (ifilterfalseobject *)type->tp_alloc(type, 0);
1320 if (lz == NULL) {
1321 Py_DECREF(it);
1322 return NULL;
1323 }
1324 Py_INCREF(func);
1325 lz->func = func;
1326 lz->it = it;
1327
1328 return (PyObject *)lz;
1329}
1330
1331static void
1332ifilterfalse_dealloc(ifilterfalseobject *lz)
1333{
1334 PyObject_GC_UnTrack(lz);
1335 Py_XDECREF(lz->func);
1336 Py_XDECREF(lz->it);
1337 lz->ob_type->tp_free(lz);
1338}
1339
1340static int
1341ifilterfalse_traverse(ifilterfalseobject *lz, visitproc visit, void *arg)
1342{
1343 int err;
1344
1345 if (lz->it) {
1346 err = visit(lz->it, arg);
1347 if (err)
1348 return err;
1349 }
1350 if (lz->func) {
1351 err = visit(lz->func, arg);
1352 if (err)
1353 return err;
1354 }
1355 return 0;
1356}
1357
1358static PyObject *
1359ifilterfalse_next(ifilterfalseobject *lz)
1360{
1361 PyObject *item;
Raymond Hettingerd1a283b2003-03-01 01:48:24 +00001362 PyObject *it = lz->it;
Raymond Hettinger60eca932003-02-09 06:40:58 +00001363 long ok;
1364
1365 for (;;) {
Raymond Hettingerd1a283b2003-03-01 01:48:24 +00001366 assert(PyIter_Check(it));
1367 item = (*it->ob_type->tp_iternext)(it);
Raymond Hettinger60eca932003-02-09 06:40:58 +00001368 if (item == NULL)
1369 return NULL;
1370
1371 if (lz->func == Py_None) {
1372 ok = PyObject_IsTrue(item);
1373 } else {
1374 PyObject *good;
1375 good = PyObject_CallFunctionObjArgs(lz->func,
1376 item, NULL);
1377 if (good == NULL) {
1378 Py_DECREF(item);
1379 return NULL;
1380 }
1381 ok = PyObject_IsTrue(good);
1382 Py_DECREF(good);
1383 }
1384 if (!ok)
1385 return item;
1386 Py_DECREF(item);
1387 }
1388}
1389
1390static PyObject *
1391ifilterfalse_getiter(PyObject *lz)
1392{
1393 Py_INCREF(lz);
1394 return lz;
1395}
1396
1397PyDoc_STRVAR(ifilterfalse_doc,
1398"ifilterfalse(function or None, sequence) --> ifilterfalse object\n\
1399\n\
1400Return those items of sequence for which function(item) is false.\n\
1401If function is None, return the items that are false.");
1402
1403PyTypeObject ifilterfalse_type = {
1404 PyObject_HEAD_INIT(NULL)
1405 0, /* ob_size */
1406 "itertools.ifilterfalse", /* tp_name */
1407 sizeof(ifilterfalseobject), /* tp_basicsize */
1408 0, /* tp_itemsize */
1409 /* methods */
1410 (destructor)ifilterfalse_dealloc, /* tp_dealloc */
1411 0, /* tp_print */
1412 0, /* tp_getattr */
1413 0, /* tp_setattr */
1414 0, /* tp_compare */
1415 0, /* tp_repr */
1416 0, /* tp_as_number */
1417 0, /* tp_as_sequence */
1418 0, /* tp_as_mapping */
1419 0, /* tp_hash */
1420 0, /* tp_call */
1421 0, /* tp_str */
1422 PyObject_GenericGetAttr, /* tp_getattro */
1423 0, /* tp_setattro */
1424 0, /* tp_as_buffer */
1425 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
1426 Py_TPFLAGS_BASETYPE, /* tp_flags */
1427 ifilterfalse_doc, /* tp_doc */
1428 (traverseproc)ifilterfalse_traverse, /* tp_traverse */
1429 0, /* tp_clear */
1430 0, /* tp_richcompare */
1431 0, /* tp_weaklistoffset */
1432 (getiterfunc)ifilterfalse_getiter, /* tp_iter */
1433 (iternextfunc)ifilterfalse_next, /* tp_iternext */
1434 0, /* tp_methods */
1435 0, /* tp_members */
1436 0, /* tp_getset */
1437 0, /* tp_base */
1438 0, /* tp_dict */
1439 0, /* tp_descr_get */
1440 0, /* tp_descr_set */
1441 0, /* tp_dictoffset */
1442 0, /* tp_init */
1443 PyType_GenericAlloc, /* tp_alloc */
1444 ifilterfalse_new, /* tp_new */
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001445 PyObject_GC_Del, /* tp_free */
1446};
1447
1448
1449/* count object ************************************************************/
1450
1451typedef struct {
1452 PyObject_HEAD
1453 long cnt;
1454} countobject;
1455
1456PyTypeObject count_type;
1457
1458static PyObject *
1459count_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1460{
1461 countobject *lz;
1462 long cnt = 0;
1463
1464 if (!PyArg_ParseTuple(args, "|l:count", &cnt))
1465 return NULL;
1466
1467 /* create countobject structure */
1468 lz = (countobject *)PyObject_New(countobject, &count_type);
1469 if (lz == NULL)
1470 return NULL;
1471 lz->cnt = cnt;
1472
1473 return (PyObject *)lz;
1474}
1475
1476static PyObject *
1477count_next(countobject *lz)
1478{
1479 return PyInt_FromLong(lz->cnt++);
1480}
1481
1482static PyObject *
1483count_getiter(PyObject *lz)
1484{
1485 Py_INCREF(lz);
1486 return lz;
1487}
1488
1489PyDoc_STRVAR(count_doc,
1490"count([firstval]) --> count object\n\
1491\n\
1492Return a count object whose .next() method returns consecutive\n\
1493integers starting from zero or, if specified, from firstval.");
1494
1495PyTypeObject count_type = {
1496 PyObject_HEAD_INIT(NULL)
1497 0, /* ob_size */
Raymond Hettinger60eca932003-02-09 06:40:58 +00001498 "itertools.count", /* tp_name */
1499 sizeof(countobject), /* tp_basicsize */
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001500 0, /* tp_itemsize */
1501 /* methods */
1502 (destructor)PyObject_Del, /* tp_dealloc */
1503 0, /* tp_print */
1504 0, /* tp_getattr */
1505 0, /* tp_setattr */
1506 0, /* tp_compare */
1507 0, /* tp_repr */
1508 0, /* tp_as_number */
1509 0, /* tp_as_sequence */
1510 0, /* tp_as_mapping */
1511 0, /* tp_hash */
1512 0, /* tp_call */
1513 0, /* tp_str */
1514 PyObject_GenericGetAttr, /* tp_getattro */
1515 0, /* tp_setattro */
1516 0, /* tp_as_buffer */
1517 Py_TPFLAGS_DEFAULT, /* tp_flags */
Raymond Hettinger60eca932003-02-09 06:40:58 +00001518 count_doc, /* tp_doc */
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001519 0, /* tp_traverse */
1520 0, /* tp_clear */
1521 0, /* tp_richcompare */
1522 0, /* tp_weaklistoffset */
Raymond Hettinger60eca932003-02-09 06:40:58 +00001523 (getiterfunc)count_getiter, /* tp_iter */
1524 (iternextfunc)count_next, /* tp_iternext */
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001525 0, /* tp_methods */
1526 0, /* tp_members */
1527 0, /* tp_getset */
1528 0, /* tp_base */
1529 0, /* tp_dict */
1530 0, /* tp_descr_get */
1531 0, /* tp_descr_set */
1532 0, /* tp_dictoffset */
1533 0, /* tp_init */
1534 PyType_GenericAlloc, /* tp_alloc */
1535 count_new, /* tp_new */
1536};
1537
1538
1539/* izip object ************************************************************/
1540
1541#include "Python.h"
1542
1543typedef struct {
1544 PyObject_HEAD
1545 long tuplesize;
1546 PyObject *ittuple; /* tuple of iterators */
Raymond Hettinger2012f172003-02-07 05:32:58 +00001547 PyObject *result;
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001548} izipobject;
1549
1550PyTypeObject izip_type;
1551
1552static PyObject *
1553izip_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1554{
1555 izipobject *lz;
1556 int i;
1557 PyObject *ittuple; /* tuple of iterators */
Raymond Hettinger2012f172003-02-07 05:32:58 +00001558 PyObject *result;
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001559 int tuplesize = PySequence_Length(args);
1560
1561 if (tuplesize < 1) {
1562 PyErr_SetString(PyExc_TypeError,
1563 "izip() requires at least one sequence");
1564 return NULL;
1565 }
1566
1567 /* args must be a tuple */
1568 assert(PyTuple_Check(args));
1569
1570 /* obtain iterators */
1571 ittuple = PyTuple_New(tuplesize);
1572 if(ittuple == NULL)
1573 return NULL;
1574 for (i=0; i < tuplesize; ++i) {
1575 PyObject *item = PyTuple_GET_ITEM(args, i);
1576 PyObject *it = PyObject_GetIter(item);
1577 if (it == NULL) {
1578 if (PyErr_ExceptionMatches(PyExc_TypeError))
1579 PyErr_Format(PyExc_TypeError,
1580 "izip argument #%d must support iteration",
1581 i+1);
1582 Py_DECREF(ittuple);
1583 return NULL;
1584 }
1585 PyTuple_SET_ITEM(ittuple, i, it);
1586 }
1587
Raymond Hettinger2012f172003-02-07 05:32:58 +00001588 /* create a result holder */
1589 result = PyTuple_New(tuplesize);
1590 if (result == NULL) {
1591 Py_DECREF(ittuple);
1592 return NULL;
1593 }
1594 for (i=0 ; i < tuplesize ; i++) {
1595 Py_INCREF(Py_None);
1596 PyTuple_SET_ITEM(result, i, Py_None);
1597 }
1598
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001599 /* create izipobject structure */
1600 lz = (izipobject *)type->tp_alloc(type, 0);
1601 if (lz == NULL) {
1602 Py_DECREF(ittuple);
Raymond Hettinger2012f172003-02-07 05:32:58 +00001603 Py_DECREF(result);
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001604 return NULL;
1605 }
1606 lz->ittuple = ittuple;
1607 lz->tuplesize = tuplesize;
Raymond Hettinger2012f172003-02-07 05:32:58 +00001608 lz->result = result;
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001609
1610 return (PyObject *)lz;
1611}
1612
1613static void
1614izip_dealloc(izipobject *lz)
1615{
1616 PyObject_GC_UnTrack(lz);
1617 Py_XDECREF(lz->ittuple);
Raymond Hettinger2012f172003-02-07 05:32:58 +00001618 Py_XDECREF(lz->result);
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001619 lz->ob_type->tp_free(lz);
1620}
1621
1622static int
1623izip_traverse(izipobject *lz, visitproc visit, void *arg)
1624{
1625 if (lz->ittuple)
1626 return visit(lz->ittuple, arg);
1627 return 0;
1628}
1629
1630static PyObject *
1631izip_next(izipobject *lz)
1632{
1633 int i;
1634 long tuplesize = lz->tuplesize;
Raymond Hettinger2012f172003-02-07 05:32:58 +00001635 PyObject *result = lz->result;
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001636 PyObject *it;
1637 PyObject *item;
1638
Raymond Hettinger2012f172003-02-07 05:32:58 +00001639 if (result->ob_refcnt == 1) {
1640 for (i=0 ; i < tuplesize ; i++) {
Raymond Hettingerf0c00242003-02-07 07:26:25 +00001641 it = PyTuple_GET_ITEM(lz->ittuple, i);
Raymond Hettingerd1a283b2003-03-01 01:48:24 +00001642 assert(PyIter_Check(it));
1643 item = (*it->ob_type->tp_iternext)(it);
Raymond Hettingerf0c00242003-02-07 07:26:25 +00001644 if (item == NULL)
1645 return NULL;
Raymond Hettinger2012f172003-02-07 05:32:58 +00001646 Py_DECREF(PyTuple_GET_ITEM(result, i));
Raymond Hettingerf0c00242003-02-07 07:26:25 +00001647 PyTuple_SET_ITEM(result, i, item);
Raymond Hettinger2012f172003-02-07 05:32:58 +00001648 }
1649 Py_INCREF(result);
1650 } else {
Raymond Hettinger2012f172003-02-07 05:32:58 +00001651 result = PyTuple_New(tuplesize);
1652 if (result == NULL)
1653 return NULL;
Raymond Hettingerf0c00242003-02-07 07:26:25 +00001654 for (i=0 ; i < tuplesize ; i++) {
1655 it = PyTuple_GET_ITEM(lz->ittuple, i);
Raymond Hettingerd1a283b2003-03-01 01:48:24 +00001656 assert(PyIter_Check(it));
1657 item = (*it->ob_type->tp_iternext)(it);
Raymond Hettingerf0c00242003-02-07 07:26:25 +00001658 if (item == NULL) {
1659 Py_DECREF(result);
1660 return NULL;
1661 }
1662 PyTuple_SET_ITEM(result, i, item);
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001663 }
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001664 }
1665 return result;
1666}
1667
1668static PyObject *
1669izip_getiter(PyObject *lz)
1670{
1671 Py_INCREF(lz);
1672 return lz;
1673}
1674
1675PyDoc_STRVAR(izip_doc,
1676"izip(iter1 [,iter2 [...]]) --> izip object\n\
1677\n\
1678Return a izip object whose .next() method returns a tuple where\n\
1679the i-th element comes from the i-th iterable argument. The .next()\n\
1680method continues until the shortest iterable in the argument sequence\n\
1681is exhausted and then it raises StopIteration. Works like the zip()\n\
1682function but consumes less memory by returning an iterator instead of\n\
1683a list.");
1684
1685PyTypeObject izip_type = {
1686 PyObject_HEAD_INIT(NULL)
1687 0, /* ob_size */
Raymond Hettinger60eca932003-02-09 06:40:58 +00001688 "itertools.izip", /* tp_name */
1689 sizeof(izipobject), /* tp_basicsize */
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001690 0, /* tp_itemsize */
1691 /* methods */
Raymond Hettinger60eca932003-02-09 06:40:58 +00001692 (destructor)izip_dealloc, /* tp_dealloc */
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001693 0, /* tp_print */
1694 0, /* tp_getattr */
1695 0, /* tp_setattr */
1696 0, /* tp_compare */
1697 0, /* tp_repr */
1698 0, /* tp_as_number */
1699 0, /* tp_as_sequence */
1700 0, /* tp_as_mapping */
1701 0, /* tp_hash */
1702 0, /* tp_call */
1703 0, /* tp_str */
1704 PyObject_GenericGetAttr, /* tp_getattro */
1705 0, /* tp_setattro */
1706 0, /* tp_as_buffer */
1707 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
1708 Py_TPFLAGS_BASETYPE, /* tp_flags */
Raymond Hettinger60eca932003-02-09 06:40:58 +00001709 izip_doc, /* tp_doc */
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001710 (traverseproc)izip_traverse, /* tp_traverse */
1711 0, /* tp_clear */
1712 0, /* tp_richcompare */
1713 0, /* tp_weaklistoffset */
Raymond Hettinger60eca932003-02-09 06:40:58 +00001714 (getiterfunc)izip_getiter, /* tp_iter */
1715 (iternextfunc)izip_next, /* tp_iternext */
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001716 0, /* tp_methods */
1717 0, /* tp_members */
1718 0, /* tp_getset */
1719 0, /* tp_base */
1720 0, /* tp_dict */
1721 0, /* tp_descr_get */
1722 0, /* tp_descr_set */
1723 0, /* tp_dictoffset */
1724 0, /* tp_init */
1725 PyType_GenericAlloc, /* tp_alloc */
Raymond Hettinger60eca932003-02-09 06:40:58 +00001726 izip_new, /* tp_new */
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001727 PyObject_GC_Del, /* tp_free */
1728};
1729
1730
1731/* repeat object ************************************************************/
1732
1733typedef struct {
1734 PyObject_HEAD
1735 PyObject *element;
Raymond Hettinger61fe64d2003-02-23 04:40:07 +00001736 long cnt;
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001737} repeatobject;
1738
1739PyTypeObject repeat_type;
1740
1741static PyObject *
1742repeat_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1743{
1744 repeatobject *ro;
1745 PyObject *element;
Raymond Hettinger61fe64d2003-02-23 04:40:07 +00001746 long cnt = -1;
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001747
Raymond Hettinger61fe64d2003-02-23 04:40:07 +00001748 if (!PyArg_ParseTuple(args, "O|l:repeat", &element, &cnt))
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001749 return NULL;
1750
1751 ro = (repeatobject *)type->tp_alloc(type, 0);
1752 if (ro == NULL)
1753 return NULL;
1754 Py_INCREF(element);
1755 ro->element = element;
Raymond Hettinger61fe64d2003-02-23 04:40:07 +00001756 ro->cnt = cnt;
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001757 return (PyObject *)ro;
1758}
1759
1760static void
1761repeat_dealloc(repeatobject *ro)
1762{
1763 PyObject_GC_UnTrack(ro);
1764 Py_XDECREF(ro->element);
1765 ro->ob_type->tp_free(ro);
1766}
1767
1768static int
1769repeat_traverse(repeatobject *ro, visitproc visit, void *arg)
1770{
1771 if (ro->element)
1772 return visit(ro->element, arg);
1773 return 0;
1774}
1775
1776static PyObject *
1777repeat_next(repeatobject *ro)
1778{
Raymond Hettinger61fe64d2003-02-23 04:40:07 +00001779 if (ro->cnt == 0)
1780 return NULL;
1781 if (ro->cnt > 0)
1782 ro->cnt--;
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001783 Py_INCREF(ro->element);
1784 return ro->element;
1785}
1786
1787static PyObject *
1788repeat_getiter(PyObject *ro)
1789{
1790 Py_INCREF(ro);
1791 return ro;
1792}
1793
1794PyDoc_STRVAR(repeat_doc,
Raymond Hettinger61fe64d2003-02-23 04:40:07 +00001795"repeat(element [,times]) -> create an iterator which returns the element\n\
1796for the specified number of times. If not specified, returns the element\n\
1797endlessly.");
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001798
1799PyTypeObject repeat_type = {
1800 PyObject_HEAD_INIT(NULL)
1801 0, /* ob_size */
1802 "itertools.repeat", /* tp_name */
1803 sizeof(repeatobject), /* tp_basicsize */
1804 0, /* tp_itemsize */
1805 /* methods */
Raymond Hettinger60eca932003-02-09 06:40:58 +00001806 (destructor)repeat_dealloc, /* tp_dealloc */
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001807 0, /* tp_print */
1808 0, /* tp_getattr */
1809 0, /* tp_setattr */
1810 0, /* tp_compare */
1811 0, /* tp_repr */
1812 0, /* tp_as_number */
1813 0, /* tp_as_sequence */
1814 0, /* tp_as_mapping */
1815 0, /* tp_hash */
1816 0, /* tp_call */
1817 0, /* tp_str */
1818 PyObject_GenericGetAttr, /* tp_getattro */
1819 0, /* tp_setattro */
1820 0, /* tp_as_buffer */
1821 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
1822 Py_TPFLAGS_BASETYPE, /* tp_flags */
Raymond Hettinger60eca932003-02-09 06:40:58 +00001823 repeat_doc, /* tp_doc */
1824 (traverseproc)repeat_traverse, /* tp_traverse */
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001825 0, /* tp_clear */
1826 0, /* tp_richcompare */
1827 0, /* tp_weaklistoffset */
Raymond Hettinger60eca932003-02-09 06:40:58 +00001828 (getiterfunc)repeat_getiter, /* tp_iter */
1829 (iternextfunc)repeat_next, /* tp_iternext */
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001830 0, /* tp_methods */
1831 0, /* tp_members */
1832 0, /* tp_getset */
1833 0, /* tp_base */
1834 0, /* tp_dict */
1835 0, /* tp_descr_get */
1836 0, /* tp_descr_set */
1837 0, /* tp_dictoffset */
1838 0, /* tp_init */
1839 PyType_GenericAlloc, /* tp_alloc */
1840 repeat_new, /* tp_new */
1841 PyObject_GC_Del, /* tp_free */
1842};
1843
1844
1845/* module level code ********************************************************/
1846
1847PyDoc_STRVAR(module_doc,
1848"Functional tools for creating and using iterators.\n\
1849\n\
1850Infinite iterators:\n\
1851count([n]) --> n, n+1, n+2, ...\n\
Raymond Hettinger61fe64d2003-02-23 04:40:07 +00001852cycle(p) --> p0, p1, ... plast, p0, p1, ...\n\
1853repeat(elem [,n]) --> elem, elem, elem, ... endlessly or upto n times\n\
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001854\n\
1855Iterators terminating on the shortest input sequence:\n\
1856izip(p, q, ...) --> (p[0], q[0]), (p[1], q[1]), ... \n\
Raymond Hettinger60eca932003-02-09 06:40:58 +00001857ifilter(pred, seq) --> elements of seq where pred(elem) is True\n\
1858ifilterfalse(pred, seq) --> elements of seq where pred(elem) is False\n\
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001859islice(seq, [start,] stop [, step]) --> elements from\n\
1860 seq[start:stop:step]\n\
1861imap(fun, p, q, ...) --> fun(p0, q0), fun(p1, q1), ...\n\
1862starmap(fun, seq) --> fun(*seq[0]), fun(*seq[1]), ...\n\
Raymond Hettinger61fe64d2003-02-23 04:40:07 +00001863chain(p, q, ...) --> p0, p1, ... plast, q0, q1, ... \n\
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001864takewhile(pred, seq) --> seq[0], seq[1], until pred fails\n\
1865dropwhile(pred, seq) --> seq[n], seq[n+1], starting when pred fails\n\
1866");
1867
1868
1869PyMODINIT_FUNC
1870inititertools(void)
1871{
Raymond Hettinger60eca932003-02-09 06:40:58 +00001872 int i;
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001873 PyObject *m;
Raymond Hettinger60eca932003-02-09 06:40:58 +00001874 char *name;
1875 PyTypeObject *typelist[] = {
Raymond Hettinger61fe64d2003-02-23 04:40:07 +00001876 &cycle_type,
Raymond Hettinger60eca932003-02-09 06:40:58 +00001877 &dropwhile_type,
1878 &takewhile_type,
1879 &islice_type,
1880 &starmap_type,
1881 &imap_type,
Raymond Hettinger61fe64d2003-02-23 04:40:07 +00001882 &chain_type,
Raymond Hettinger60eca932003-02-09 06:40:58 +00001883 &ifilter_type,
1884 &ifilterfalse_type,
1885 &count_type,
1886 &izip_type,
1887 &repeat_type,
1888 NULL
1889 };
1890
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001891 m = Py_InitModule3("itertools", NULL, module_doc);
1892
Raymond Hettinger60eca932003-02-09 06:40:58 +00001893 for (i=0 ; typelist[i] != NULL ; i++) {
1894 if (PyType_Ready(typelist[i]) < 0)
1895 return;
1896 name = strchr(typelist[i]->tp_name, '.') + 1;
Raymond Hettinger61fe64d2003-02-23 04:40:07 +00001897 assert (name != NULL);
Raymond Hettinger60eca932003-02-09 06:40:58 +00001898 Py_INCREF(typelist[i]);
1899 PyModule_AddObject(m, name, (PyObject *)typelist[i]);
1900 }
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001901}