blob: be2d7356fc85d2044ade76a4bdc76d3059d2cea3 [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 Hettinger6a5b0272003-10-24 08:45:23 +000010/* independent iterator object supporting the tee object ***************/
11
12/* The tee object maintains a queue of data seen by the leading iterator
13 but not seen by the trailing iterator. When the leading iterator
14 gets data from PyIter_Next() it appends a copy to the inbasket stack.
15 When the trailing iterator needs data, it is popped from the outbasket
16 stack. If the outbasket stack is empty, then it is filled from the
17 inbasket (i.e. the queue is implemented using two stacks so that only
18 O(n) operations like append() and pop() are used to access data and
19 calls to reverse() never move any data element more than once).
20
21 If one of the independent iterators gets deallocated, it sets tee's
22 save_mode to zero so that future calls to PyIter_Next() stop getting
23 saved to the queue (because there is no longer a second iterator that
24 may need the data).
25*/
26
27typedef struct {
28 PyObject_HEAD
29 PyObject *it;
30 PyObject *inbasket;
31 PyObject *outbasket;
32 int save_mode;
33 int num_seen;
34} teeobject;
35
36typedef struct {
37 PyObject_HEAD
38 teeobject *tee;
39 int num_seen;
40} iiobject;
41
42static PyTypeObject ii_type;
43
44static PyObject *
45ii_next(iiobject *lz)
46{
47 teeobject *to = lz->tee;
48 PyObject *result, *tmp;
Raymond Hettinger45143692003-10-25 06:37:47 +000049 int n;
Raymond Hettinger6a5b0272003-10-24 08:45:23 +000050
51 if (lz->num_seen == to->num_seen) {
52 /* This instance is leading, use iter to get more data */
53 result = PyIter_Next(to->it);
54 if (result == NULL)
55 return NULL;
56 if (to->save_mode)
Raymond Hettinger45143692003-10-25 06:37:47 +000057 if(PyList_Append(to->inbasket, result) == -1){
58 Py_DECREF(result);
59 return NULL;
60 }
Raymond Hettinger6a5b0272003-10-24 08:45:23 +000061 to->num_seen++;
62 lz->num_seen++;
63 return result;
64 }
65
66 /* This instance is trailing, get data from the queue */
67 if (PyList_GET_SIZE(to->outbasket) == 0) {
68 /* outbasket is empty, so refill from the inbasket */
69 tmp = to->outbasket;
70 to->outbasket = to->inbasket;
71 to->inbasket = tmp;
72 PyList_Reverse(to->outbasket);
Raymond Hettinger6a5b0272003-10-24 08:45:23 +000073 }
74
Raymond Hettinger45143692003-10-25 06:37:47 +000075 /* Pop result from to->outbasket */
76 n = PyList_GET_SIZE(to->outbasket);
77 assert(n>0);
78 result = PyList_GET_ITEM(to->outbasket, n-1);
79 Py_INCREF(result);
80 if (PyList_SetSlice(to->outbasket, n-1, n, NULL) == -1) {
81 Py_DECREF(result);
82 return NULL;
83 }
Raymond Hettinger6a5b0272003-10-24 08:45:23 +000084 lz->num_seen++;
Raymond Hettinger45143692003-10-25 06:37:47 +000085 return result;
Raymond Hettinger6a5b0272003-10-24 08:45:23 +000086}
87
88static void
89ii_dealloc(iiobject *ii)
90{
Raymond Hettinger45143692003-10-25 06:37:47 +000091 teeobject *to = ii->tee;
92 int n;
93
Raymond Hettinger6a5b0272003-10-24 08:45:23 +000094 PyObject_GC_UnTrack(ii);
95 ii->tee->save_mode = 0; /* Stop saving data */
Raymond Hettinger45143692003-10-25 06:37:47 +000096 if (ii->num_seen < to->num_seen) {
97 /* It is the trailing iterator being freed; this means
98 that the stored queue data is no longer needed */
99 n = PyList_GET_SIZE(to->inbasket);
100 PyList_SetSlice(to->inbasket, 0, n, NULL);
101 n = PyList_GET_SIZE(to->outbasket);
102 PyList_SetSlice(to->outbasket, 0, n, NULL);
103 }
Raymond Hettinger6a5b0272003-10-24 08:45:23 +0000104 Py_XDECREF(ii->tee);
105 PyObject_GC_Del(ii);
106}
107
108static int
109ii_traverse(iiobject *ii, visitproc visit, void *arg)
110{
111 if (ii->tee)
112 return visit((PyObject *)(ii->tee), arg);
113 return 0;
114}
115
Raymond Hettingerf0c5aec2003-10-26 14:25:56 +0000116PyDoc_STRVAR(ii_doc, "Independent iterator created by tee(iterable).");
Raymond Hettinger6a5b0272003-10-24 08:45:23 +0000117
118static PyTypeObject ii_type = {
119 PyObject_HEAD_INIT(&PyType_Type)
120 0, /* ob_size */
Raymond Hettingerf0c5aec2003-10-26 14:25:56 +0000121 "itertools.tee_iterator", /* tp_name */
Raymond Hettinger6a5b0272003-10-24 08:45:23 +0000122 sizeof(iiobject), /* tp_basicsize */
123 0, /* tp_itemsize */
124 /* methods */
125 (destructor)ii_dealloc, /* tp_dealloc */
126 0, /* tp_print */
127 0, /* tp_getattr */
128 0, /* tp_setattr */
129 0, /* tp_compare */
130 0, /* tp_repr */
131 0, /* tp_as_number */
132 0, /* tp_as_sequence */
133 0, /* tp_as_mapping */
134 0, /* tp_hash */
135 0, /* tp_call */
136 0, /* tp_str */
137 PyObject_GenericGetAttr, /* tp_getattro */
138 0, /* tp_setattro */
139 0, /* tp_as_buffer */
140 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,/* tp_flags */
141 ii_doc, /* tp_doc */
142 (traverseproc)ii_traverse, /* tp_traverse */
143 0, /* tp_clear */
144 0, /* tp_richcompare */
145 0, /* tp_weaklistoffset */
146 PyObject_SelfIter, /* tp_iter */
147 (iternextfunc)ii_next, /* tp_iternext */
148 0, /* tp_methods */
149};
150
151/* tee object **********************************************************/
152
153static PyTypeObject tee_type;
154
155static PyObject *
156tee_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
157{
158 PyObject *it = NULL;
159 PyObject *iterable;
160 PyObject *inbasket = NULL, *outbasket = NULL, *result = NULL;
161 teeobject *to = NULL;
162 int i;
163
164 if (!PyArg_UnpackTuple(args, "tee", 1, 1, &iterable))
165 return NULL;
166
167 it = PyObject_GetIter(iterable);
168 if (it == NULL) goto fail;
169
170 inbasket = PyList_New(0);
171 if (inbasket == NULL) goto fail;
172
173 outbasket = PyList_New(0);
174 if (outbasket == NULL) goto fail;
175
Raymond Hettingerf0c5aec2003-10-26 14:25:56 +0000176 to = PyObject_GC_New(teeobject, &tee_type);
Raymond Hettinger6a5b0272003-10-24 08:45:23 +0000177 if (to == NULL) goto fail;
178
179 to->it = it;
180 to->inbasket = inbasket;
181 to->outbasket = outbasket;
182 to->save_mode = 1;
183 to->num_seen = 0;
Raymond Hettingerf0c5aec2003-10-26 14:25:56 +0000184 PyObject_GC_Track(to);
Raymond Hettinger6a5b0272003-10-24 08:45:23 +0000185
186 /* create independent iterators */
187 result = PyTuple_New(2);
188 if (result == NULL) goto fail;
189 for (i=0 ; i<2 ; i++) {
190 iiobject *indep_it = PyObject_GC_New(iiobject, &ii_type);
191 if (indep_it == NULL) goto fail;
192 Py_INCREF(to);
193 indep_it->tee = to;
194 indep_it->num_seen = 0;
195 PyObject_GC_Track(indep_it);
196 PyTuple_SET_ITEM(result, i, (PyObject *)indep_it);
197 }
198 goto succeed;
199fail:
200 Py_XDECREF(it);
201 Py_XDECREF(inbasket);
202 Py_XDECREF(outbasket);
203 Py_XDECREF(result);
204succeed:
205 Py_XDECREF(to);
206 return result;
207}
208
209static void
210tee_dealloc(teeobject *to)
211{
212 PyObject_GC_UnTrack(to);
213 Py_XDECREF(to->inbasket);
214 Py_XDECREF(to->outbasket);
215 Py_XDECREF(to->it);
Raymond Hettingerf0c5aec2003-10-26 14:25:56 +0000216 PyObject_GC_Del(to);
Raymond Hettinger6a5b0272003-10-24 08:45:23 +0000217}
218
219static int
220tee_traverse(teeobject *to, visitproc visit, void *arg)
221{
222 int err;
223
224 if (to->it) {
225 err = visit(to->it, arg);
226 if (err)
227 return err;
228 }
229 if (to->inbasket) {
230 err = visit(to->inbasket, arg);
231 if (err)
232 return err;
233 }
234 if (to->outbasket) {
235 err = visit(to->outbasket, arg);
236 if (err)
237 return err;
238 }
239 return 0;
240}
241
242PyDoc_STRVAR(tee_doc,
243"tee(iterable) --> (it1, it2)\n\
244\n\
Raymond Hettingerf0c5aec2003-10-26 14:25:56 +0000245Split the iterable into two independent iterables.");
Raymond Hettinger6a5b0272003-10-24 08:45:23 +0000246
247static PyTypeObject tee_type = {
248 PyObject_HEAD_INIT(NULL)
249 0, /* ob_size */
250 "itertools.tee", /* tp_name */
251 sizeof(teeobject), /* tp_basicsize */
252 0, /* tp_itemsize */
253 /* methods */
254 (destructor)tee_dealloc, /* tp_dealloc */
255 0, /* tp_print */
256 0, /* tp_getattr */
257 0, /* tp_setattr */
258 0, /* tp_compare */
259 0, /* tp_repr */
260 0, /* tp_as_number */
261 0, /* tp_as_sequence */
262 0, /* tp_as_mapping */
263 0, /* tp_hash */
264 0, /* tp_call */
265 0, /* tp_str */
Raymond Hettingerf0c5aec2003-10-26 14:25:56 +0000266 0, /* tp_getattro */
Raymond Hettinger6a5b0272003-10-24 08:45:23 +0000267 0, /* tp_setattro */
268 0, /* tp_as_buffer */
Raymond Hettingerf0c5aec2003-10-26 14:25:56 +0000269 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */
Raymond Hettinger6a5b0272003-10-24 08:45:23 +0000270 tee_doc, /* tp_doc */
271 (traverseproc)tee_traverse, /* tp_traverse */
272 0, /* tp_clear */
273 0, /* tp_richcompare */
274 0, /* tp_weaklistoffset */
275 0, /* tp_iter */
276 0, /* tp_iternext */
277 0, /* tp_methods */
278 0, /* tp_members */
279 0, /* tp_getset */
280 0, /* tp_base */
281 0, /* tp_dict */
282 0, /* tp_descr_get */
283 0, /* tp_descr_set */
284 0, /* tp_dictoffset */
285 0, /* tp_init */
286 0, /* tp_alloc */
287 tee_new, /* tp_new */
Raymond Hettinger6a5b0272003-10-24 08:45:23 +0000288};
289
Raymond Hettinger61fe64d2003-02-23 04:40:07 +0000290/* cycle object **********************************************************/
291
292typedef struct {
293 PyObject_HEAD
294 PyObject *it;
295 PyObject *saved;
296 int firstpass;
297} cycleobject;
298
Raymond Hettinger1d7a3482003-07-14 07:07:12 +0000299static PyTypeObject cycle_type;
Raymond Hettinger61fe64d2003-02-23 04:40:07 +0000300
301static PyObject *
302cycle_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
303{
304 PyObject *it;
305 PyObject *iterable;
306 PyObject *saved;
307 cycleobject *lz;
308
309 if (!PyArg_UnpackTuple(args, "cycle", 1, 1, &iterable))
310 return NULL;
311
312 /* Get iterator. */
313 it = PyObject_GetIter(iterable);
314 if (it == NULL)
315 return NULL;
316
317 saved = PyList_New(0);
318 if (saved == NULL) {
319 Py_DECREF(it);
320 return NULL;
321 }
322
323 /* create cycleobject structure */
324 lz = (cycleobject *)type->tp_alloc(type, 0);
325 if (lz == NULL) {
326 Py_DECREF(it);
327 Py_DECREF(saved);
328 return NULL;
329 }
330 lz->it = it;
331 lz->saved = saved;
332 lz->firstpass = 0;
333
334 return (PyObject *)lz;
335}
336
337static void
338cycle_dealloc(cycleobject *lz)
339{
340 PyObject_GC_UnTrack(lz);
341 Py_XDECREF(lz->saved);
342 Py_XDECREF(lz->it);
343 lz->ob_type->tp_free(lz);
344}
345
346static int
347cycle_traverse(cycleobject *lz, visitproc visit, void *arg)
348{
349 int err;
350
351 if (lz->it) {
352 err = visit(lz->it, arg);
353 if (err)
354 return err;
355 }
356 if (lz->saved) {
357 err = visit(lz->saved, arg);
358 if (err)
359 return err;
360 }
361 return 0;
362}
363
364static PyObject *
365cycle_next(cycleobject *lz)
366{
367 PyObject *item;
368 PyObject *it;
369
370 while (1) {
371 item = PyIter_Next(lz->it);
372 if (item != NULL) {
373 if (!lz->firstpass)
374 PyList_Append(lz->saved, item);
375 return item;
376 }
377 if (PyList_Size(lz->saved) == 0)
378 return NULL;
379 it = PyObject_GetIter(lz->saved);
380 if (it == NULL)
381 return NULL;
382 Py_DECREF(lz->it);
383 lz->it = it;
384 lz->firstpass = 1;
385 }
386}
387
Raymond Hettinger61fe64d2003-02-23 04:40:07 +0000388PyDoc_STRVAR(cycle_doc,
389"cycle(iterable) --> cycle object\n\
390\n\
391Return elements from the iterable until it is exhausted.\n\
392Then repeat the sequence indefinitely.");
393
Raymond Hettinger1d7a3482003-07-14 07:07:12 +0000394static PyTypeObject cycle_type = {
Raymond Hettinger61fe64d2003-02-23 04:40:07 +0000395 PyObject_HEAD_INIT(NULL)
396 0, /* ob_size */
397 "itertools.cycle", /* tp_name */
398 sizeof(cycleobject), /* tp_basicsize */
399 0, /* tp_itemsize */
400 /* methods */
401 (destructor)cycle_dealloc, /* tp_dealloc */
402 0, /* tp_print */
403 0, /* tp_getattr */
404 0, /* tp_setattr */
405 0, /* tp_compare */
406 0, /* tp_repr */
407 0, /* tp_as_number */
408 0, /* tp_as_sequence */
409 0, /* tp_as_mapping */
410 0, /* tp_hash */
411 0, /* tp_call */
412 0, /* tp_str */
413 PyObject_GenericGetAttr, /* tp_getattro */
414 0, /* tp_setattro */
415 0, /* tp_as_buffer */
416 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
417 Py_TPFLAGS_BASETYPE, /* tp_flags */
418 cycle_doc, /* tp_doc */
419 (traverseproc)cycle_traverse, /* tp_traverse */
420 0, /* tp_clear */
421 0, /* tp_richcompare */
422 0, /* tp_weaklistoffset */
Raymond Hettinger1da1dbf2003-03-17 19:46:11 +0000423 PyObject_SelfIter, /* tp_iter */
Raymond Hettinger61fe64d2003-02-23 04:40:07 +0000424 (iternextfunc)cycle_next, /* tp_iternext */
425 0, /* tp_methods */
426 0, /* tp_members */
427 0, /* tp_getset */
428 0, /* tp_base */
429 0, /* tp_dict */
430 0, /* tp_descr_get */
431 0, /* tp_descr_set */
432 0, /* tp_dictoffset */
433 0, /* tp_init */
Raymond Hettingerbfef18c2003-05-23 03:55:42 +0000434 0, /* tp_alloc */
Raymond Hettinger61fe64d2003-02-23 04:40:07 +0000435 cycle_new, /* tp_new */
436 PyObject_GC_Del, /* tp_free */
437};
438
439
Raymond Hettinger96ef8112003-02-01 00:10:11 +0000440/* dropwhile object **********************************************************/
441
442typedef struct {
443 PyObject_HEAD
444 PyObject *func;
445 PyObject *it;
446 long start;
447} dropwhileobject;
448
Raymond Hettinger1d7a3482003-07-14 07:07:12 +0000449static PyTypeObject dropwhile_type;
Raymond Hettinger96ef8112003-02-01 00:10:11 +0000450
451static PyObject *
452dropwhile_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
453{
454 PyObject *func, *seq;
455 PyObject *it;
456 dropwhileobject *lz;
457
458 if (!PyArg_UnpackTuple(args, "dropwhile", 2, 2, &func, &seq))
459 return NULL;
460
461 /* Get iterator. */
462 it = PyObject_GetIter(seq);
463 if (it == NULL)
464 return NULL;
465
466 /* create dropwhileobject structure */
467 lz = (dropwhileobject *)type->tp_alloc(type, 0);
468 if (lz == NULL) {
469 Py_DECREF(it);
470 return NULL;
471 }
472 Py_INCREF(func);
473 lz->func = func;
474 lz->it = it;
475 lz->start = 0;
476
477 return (PyObject *)lz;
478}
479
480static void
481dropwhile_dealloc(dropwhileobject *lz)
482{
483 PyObject_GC_UnTrack(lz);
484 Py_XDECREF(lz->func);
485 Py_XDECREF(lz->it);
486 lz->ob_type->tp_free(lz);
487}
488
489static int
490dropwhile_traverse(dropwhileobject *lz, visitproc visit, void *arg)
491{
492 int err;
493
494 if (lz->it) {
495 err = visit(lz->it, arg);
496 if (err)
497 return err;
498 }
499 if (lz->func) {
500 err = visit(lz->func, arg);
501 if (err)
502 return err;
503 }
504 return 0;
505}
506
507static PyObject *
508dropwhile_next(dropwhileobject *lz)
509{
510 PyObject *item, *good;
Raymond Hettingerd1a283b2003-03-01 01:48:24 +0000511 PyObject *it = lz->it;
Raymond Hettinger96ef8112003-02-01 00:10:11 +0000512 long ok;
513
514 for (;;) {
Raymond Hettingerd1a283b2003-03-01 01:48:24 +0000515 assert(PyIter_Check(it));
516 item = (*it->ob_type->tp_iternext)(it);
Raymond Hettinger96ef8112003-02-01 00:10:11 +0000517 if (item == NULL)
518 return NULL;
519 if (lz->start == 1)
520 return item;
521
522 good = PyObject_CallFunctionObjArgs(lz->func, item, NULL);
523 if (good == NULL) {
524 Py_DECREF(item);
525 return NULL;
526 }
527 ok = PyObject_IsTrue(good);
528 Py_DECREF(good);
529 if (!ok) {
530 lz->start = 1;
531 return item;
532 }
533 Py_DECREF(item);
534 }
535}
536
Raymond Hettinger96ef8112003-02-01 00:10:11 +0000537PyDoc_STRVAR(dropwhile_doc,
538"dropwhile(predicate, iterable) --> dropwhile object\n\
539\n\
540Drop items from the iterable while predicate(item) is true.\n\
541Afterwards, return every element until the iterable is exhausted.");
542
Raymond Hettinger1d7a3482003-07-14 07:07:12 +0000543static PyTypeObject dropwhile_type = {
Raymond Hettinger96ef8112003-02-01 00:10:11 +0000544 PyObject_HEAD_INIT(NULL)
545 0, /* ob_size */
Raymond Hettinger60eca932003-02-09 06:40:58 +0000546 "itertools.dropwhile", /* tp_name */
547 sizeof(dropwhileobject), /* tp_basicsize */
Raymond Hettinger96ef8112003-02-01 00:10:11 +0000548 0, /* tp_itemsize */
549 /* methods */
Raymond Hettinger60eca932003-02-09 06:40:58 +0000550 (destructor)dropwhile_dealloc, /* tp_dealloc */
Raymond Hettinger96ef8112003-02-01 00:10:11 +0000551 0, /* tp_print */
552 0, /* tp_getattr */
553 0, /* tp_setattr */
554 0, /* tp_compare */
555 0, /* tp_repr */
556 0, /* tp_as_number */
557 0, /* tp_as_sequence */
558 0, /* tp_as_mapping */
559 0, /* tp_hash */
560 0, /* tp_call */
561 0, /* tp_str */
562 PyObject_GenericGetAttr, /* tp_getattro */
563 0, /* tp_setattro */
564 0, /* tp_as_buffer */
565 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
566 Py_TPFLAGS_BASETYPE, /* tp_flags */
Raymond Hettinger60eca932003-02-09 06:40:58 +0000567 dropwhile_doc, /* tp_doc */
Raymond Hettinger96ef8112003-02-01 00:10:11 +0000568 (traverseproc)dropwhile_traverse, /* tp_traverse */
569 0, /* tp_clear */
570 0, /* tp_richcompare */
571 0, /* tp_weaklistoffset */
Raymond Hettinger1da1dbf2003-03-17 19:46:11 +0000572 PyObject_SelfIter, /* tp_iter */
Raymond Hettinger60eca932003-02-09 06:40:58 +0000573 (iternextfunc)dropwhile_next, /* tp_iternext */
Raymond Hettinger96ef8112003-02-01 00:10:11 +0000574 0, /* tp_methods */
575 0, /* tp_members */
576 0, /* tp_getset */
577 0, /* tp_base */
578 0, /* tp_dict */
579 0, /* tp_descr_get */
580 0, /* tp_descr_set */
581 0, /* tp_dictoffset */
582 0, /* tp_init */
Raymond Hettingerbfef18c2003-05-23 03:55:42 +0000583 0, /* tp_alloc */
Raymond Hettinger60eca932003-02-09 06:40:58 +0000584 dropwhile_new, /* tp_new */
Raymond Hettinger96ef8112003-02-01 00:10:11 +0000585 PyObject_GC_Del, /* tp_free */
586};
587
588
589/* takewhile object **********************************************************/
590
591typedef struct {
592 PyObject_HEAD
593 PyObject *func;
594 PyObject *it;
595 long stop;
596} takewhileobject;
597
Raymond Hettinger1d7a3482003-07-14 07:07:12 +0000598static PyTypeObject takewhile_type;
Raymond Hettinger96ef8112003-02-01 00:10:11 +0000599
600static PyObject *
601takewhile_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
602{
603 PyObject *func, *seq;
604 PyObject *it;
605 takewhileobject *lz;
606
607 if (!PyArg_UnpackTuple(args, "takewhile", 2, 2, &func, &seq))
608 return NULL;
609
610 /* Get iterator. */
611 it = PyObject_GetIter(seq);
612 if (it == NULL)
613 return NULL;
614
615 /* create takewhileobject structure */
616 lz = (takewhileobject *)type->tp_alloc(type, 0);
617 if (lz == NULL) {
618 Py_DECREF(it);
619 return NULL;
620 }
621 Py_INCREF(func);
622 lz->func = func;
623 lz->it = it;
624 lz->stop = 0;
625
626 return (PyObject *)lz;
627}
628
629static void
630takewhile_dealloc(takewhileobject *lz)
631{
632 PyObject_GC_UnTrack(lz);
633 Py_XDECREF(lz->func);
634 Py_XDECREF(lz->it);
635 lz->ob_type->tp_free(lz);
636}
637
638static int
639takewhile_traverse(takewhileobject *lz, visitproc visit, void *arg)
640{
641 int err;
642
643 if (lz->it) {
644 err = visit(lz->it, arg);
645 if (err)
646 return err;
647 }
648 if (lz->func) {
649 err = visit(lz->func, arg);
650 if (err)
651 return err;
652 }
653 return 0;
654}
655
656static PyObject *
657takewhile_next(takewhileobject *lz)
658{
659 PyObject *item, *good;
Raymond Hettingerd1a283b2003-03-01 01:48:24 +0000660 PyObject *it = lz->it;
Raymond Hettinger96ef8112003-02-01 00:10:11 +0000661 long ok;
662
663 if (lz->stop == 1)
664 return NULL;
665
Raymond Hettingerd1a283b2003-03-01 01:48:24 +0000666 assert(PyIter_Check(it));
667 item = (*it->ob_type->tp_iternext)(it);
Raymond Hettinger96ef8112003-02-01 00:10:11 +0000668 if (item == NULL)
669 return NULL;
670
671 good = PyObject_CallFunctionObjArgs(lz->func, item, NULL);
672 if (good == NULL) {
673 Py_DECREF(item);
674 return NULL;
675 }
676 ok = PyObject_IsTrue(good);
677 Py_DECREF(good);
678 if (ok)
679 return item;
680 Py_DECREF(item);
681 lz->stop = 1;
682 return NULL;
683}
684
Raymond Hettinger96ef8112003-02-01 00:10:11 +0000685PyDoc_STRVAR(takewhile_doc,
686"takewhile(predicate, iterable) --> takewhile object\n\
687\n\
688Return successive entries from an iterable as long as the \n\
689predicate evaluates to true for each entry.");
690
Raymond Hettinger1d7a3482003-07-14 07:07:12 +0000691static PyTypeObject takewhile_type = {
Raymond Hettinger96ef8112003-02-01 00:10:11 +0000692 PyObject_HEAD_INIT(NULL)
693 0, /* ob_size */
Raymond Hettinger60eca932003-02-09 06:40:58 +0000694 "itertools.takewhile", /* tp_name */
695 sizeof(takewhileobject), /* tp_basicsize */
Raymond Hettinger96ef8112003-02-01 00:10:11 +0000696 0, /* tp_itemsize */
697 /* methods */
Raymond Hettinger60eca932003-02-09 06:40:58 +0000698 (destructor)takewhile_dealloc, /* tp_dealloc */
Raymond Hettinger96ef8112003-02-01 00:10:11 +0000699 0, /* tp_print */
700 0, /* tp_getattr */
701 0, /* tp_setattr */
702 0, /* tp_compare */
703 0, /* tp_repr */
704 0, /* tp_as_number */
705 0, /* tp_as_sequence */
706 0, /* tp_as_mapping */
707 0, /* tp_hash */
708 0, /* tp_call */
709 0, /* tp_str */
710 PyObject_GenericGetAttr, /* tp_getattro */
711 0, /* tp_setattro */
712 0, /* tp_as_buffer */
713 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
714 Py_TPFLAGS_BASETYPE, /* tp_flags */
Raymond Hettinger60eca932003-02-09 06:40:58 +0000715 takewhile_doc, /* tp_doc */
Raymond Hettinger96ef8112003-02-01 00:10:11 +0000716 (traverseproc)takewhile_traverse, /* tp_traverse */
717 0, /* tp_clear */
718 0, /* tp_richcompare */
719 0, /* tp_weaklistoffset */
Raymond Hettinger1da1dbf2003-03-17 19:46:11 +0000720 PyObject_SelfIter, /* tp_iter */
Raymond Hettinger60eca932003-02-09 06:40:58 +0000721 (iternextfunc)takewhile_next, /* tp_iternext */
Raymond Hettinger96ef8112003-02-01 00:10:11 +0000722 0, /* tp_methods */
723 0, /* tp_members */
724 0, /* tp_getset */
725 0, /* tp_base */
726 0, /* tp_dict */
727 0, /* tp_descr_get */
728 0, /* tp_descr_set */
729 0, /* tp_dictoffset */
730 0, /* tp_init */
Raymond Hettingerbfef18c2003-05-23 03:55:42 +0000731 0, /* tp_alloc */
Raymond Hettinger60eca932003-02-09 06:40:58 +0000732 takewhile_new, /* tp_new */
Raymond Hettinger96ef8112003-02-01 00:10:11 +0000733 PyObject_GC_Del, /* tp_free */
734};
735
736
737/* islice object ************************************************************/
738
739typedef struct {
740 PyObject_HEAD
741 PyObject *it;
742 long next;
743 long stop;
744 long step;
745 long cnt;
746} isliceobject;
747
Raymond Hettinger1d7a3482003-07-14 07:07:12 +0000748static PyTypeObject islice_type;
Raymond Hettinger96ef8112003-02-01 00:10:11 +0000749
750static PyObject *
751islice_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
752{
753 PyObject *seq;
Raymond Hettinger14ef54c2003-05-02 19:04:37 +0000754 long start=0, stop=-1, step=1;
755 PyObject *it, *a1=NULL, *a2=NULL;
Raymond Hettinger96ef8112003-02-01 00:10:11 +0000756 int numargs;
757 isliceobject *lz;
758
759 numargs = PyTuple_Size(args);
Raymond Hettinger341deb72003-05-02 19:44:20 +0000760 if (!PyArg_ParseTuple(args, "OO|Ol:islice", &seq, &a1, &a2, &step))
Raymond Hettinger96ef8112003-02-01 00:10:11 +0000761 return NULL;
762
763 if (numargs == 2) {
Raymond Hettinger14ef54c2003-05-02 19:04:37 +0000764 if (a1 != Py_None) {
765 stop = PyInt_AsLong(a1);
766 if (stop == -1) {
767 if (PyErr_Occurred())
768 PyErr_Clear();
769 PyErr_SetString(PyExc_ValueError,
Raymond Hettinger0e4f7642003-10-28 07:32:28 +0000770 "Stop argument must be a non-negative integer or None.");
Raymond Hettinger14ef54c2003-05-02 19:04:37 +0000771 return NULL;
772 }
773 }
Raymond Hettinger341deb72003-05-02 19:44:20 +0000774 } else {
Raymond Hettinger14ef54c2003-05-02 19:04:37 +0000775 start = PyInt_AsLong(a1);
776 if (start == -1 && PyErr_Occurred()) {
777 PyErr_Clear();
778 PyErr_SetString(PyExc_ValueError,
Raymond Hettinger0e4f7642003-10-28 07:32:28 +0000779 "Start argument must be a non-negative integer.");
Raymond Hettinger14ef54c2003-05-02 19:04:37 +0000780 return NULL;
781 }
782 if (a2 != Py_None) {
783 stop = PyInt_AsLong(a2);
784 if (stop == -1) {
785 if (PyErr_Occurred())
786 PyErr_Clear();
787 PyErr_SetString(PyExc_ValueError,
Raymond Hettinger0e4f7642003-10-28 07:32:28 +0000788 "Stop argument must be a non-negative integer or None.");
Raymond Hettinger14ef54c2003-05-02 19:04:37 +0000789 return NULL;
790 }
791 }
Raymond Hettinger96ef8112003-02-01 00:10:11 +0000792 }
793
Raymond Hettinger14ef54c2003-05-02 19:04:37 +0000794 if (start<0 || stop<-1) {
Raymond Hettinger96ef8112003-02-01 00:10:11 +0000795 PyErr_SetString(PyExc_ValueError,
Raymond Hettinger0e4f7642003-10-28 07:32:28 +0000796 "Indices for islice() must be non-negative integers.");
Raymond Hettinger96ef8112003-02-01 00:10:11 +0000797 return NULL;
798 }
799
800 if (step<1) {
801 PyErr_SetString(PyExc_ValueError,
802 "Step must be one or larger for islice().");
803 return NULL;
804 }
805
806 /* Get iterator. */
807 it = PyObject_GetIter(seq);
808 if (it == NULL)
809 return NULL;
810
811 /* create isliceobject structure */
812 lz = (isliceobject *)type->tp_alloc(type, 0);
813 if (lz == NULL) {
814 Py_DECREF(it);
815 return NULL;
816 }
817 lz->it = it;
818 lz->next = start;
819 lz->stop = stop;
820 lz->step = step;
821 lz->cnt = 0L;
822
823 return (PyObject *)lz;
824}
825
826static void
827islice_dealloc(isliceobject *lz)
828{
829 PyObject_GC_UnTrack(lz);
830 Py_XDECREF(lz->it);
831 lz->ob_type->tp_free(lz);
832}
833
834static int
835islice_traverse(isliceobject *lz, visitproc visit, void *arg)
836{
837 if (lz->it)
838 return visit(lz->it, arg);
839 return 0;
840}
841
842static PyObject *
843islice_next(isliceobject *lz)
844{
845 PyObject *item;
Raymond Hettingerd1a283b2003-03-01 01:48:24 +0000846 PyObject *it = lz->it;
Raymond Hettinger2012f172003-02-07 05:32:58 +0000847 long oldnext;
Raymond Hettinger96ef8112003-02-01 00:10:11 +0000848
849 while (lz->cnt < lz->next) {
Raymond Hettingerd1a283b2003-03-01 01:48:24 +0000850 assert(PyIter_Check(it));
851 item = (*it->ob_type->tp_iternext)(it);
Raymond Hettinger96ef8112003-02-01 00:10:11 +0000852 if (item == NULL)
853 return NULL;
854 Py_DECREF(item);
855 lz->cnt++;
856 }
Raymond Hettinger14ef54c2003-05-02 19:04:37 +0000857 if (lz->stop != -1 && lz->cnt >= lz->stop)
Raymond Hettinger96ef8112003-02-01 00:10:11 +0000858 return NULL;
Raymond Hettingerd1a283b2003-03-01 01:48:24 +0000859 assert(PyIter_Check(it));
860 item = (*it->ob_type->tp_iternext)(it);
Raymond Hettinger96ef8112003-02-01 00:10:11 +0000861 if (item == NULL)
862 return NULL;
863 lz->cnt++;
Raymond Hettinger2012f172003-02-07 05:32:58 +0000864 oldnext = lz->next;
Raymond Hettinger96ef8112003-02-01 00:10:11 +0000865 lz->next += lz->step;
Raymond Hettinger2012f172003-02-07 05:32:58 +0000866 if (lz->next < oldnext) /* Check for overflow */
867 lz->next = lz->stop;
Raymond Hettinger96ef8112003-02-01 00:10:11 +0000868 return item;
869}
870
Raymond Hettinger96ef8112003-02-01 00:10:11 +0000871PyDoc_STRVAR(islice_doc,
872"islice(iterable, [start,] stop [, step]) --> islice object\n\
873\n\
874Return an iterator whose next() method returns selected values from an\n\
875iterable. If start is specified, will skip all preceding elements;\n\
876otherwise, start defaults to zero. Step defaults to one. If\n\
877specified as another value, step determines how many values are \n\
878skipped between successive calls. Works like a slice() on a list\n\
879but returns an iterator.");
880
Raymond Hettinger1d7a3482003-07-14 07:07:12 +0000881static PyTypeObject islice_type = {
Raymond Hettinger96ef8112003-02-01 00:10:11 +0000882 PyObject_HEAD_INIT(NULL)
883 0, /* ob_size */
884 "itertools.islice", /* tp_name */
885 sizeof(isliceobject), /* tp_basicsize */
886 0, /* tp_itemsize */
887 /* methods */
Raymond Hettinger60eca932003-02-09 06:40:58 +0000888 (destructor)islice_dealloc, /* tp_dealloc */
Raymond Hettinger96ef8112003-02-01 00:10:11 +0000889 0, /* tp_print */
890 0, /* tp_getattr */
891 0, /* tp_setattr */
892 0, /* tp_compare */
893 0, /* tp_repr */
894 0, /* tp_as_number */
895 0, /* tp_as_sequence */
896 0, /* tp_as_mapping */
897 0, /* tp_hash */
898 0, /* tp_call */
899 0, /* tp_str */
900 PyObject_GenericGetAttr, /* tp_getattro */
901 0, /* tp_setattro */
902 0, /* tp_as_buffer */
903 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
904 Py_TPFLAGS_BASETYPE, /* tp_flags */
Raymond Hettinger60eca932003-02-09 06:40:58 +0000905 islice_doc, /* tp_doc */
906 (traverseproc)islice_traverse, /* tp_traverse */
Raymond Hettinger96ef8112003-02-01 00:10:11 +0000907 0, /* tp_clear */
908 0, /* tp_richcompare */
909 0, /* tp_weaklistoffset */
Raymond Hettinger1da1dbf2003-03-17 19:46:11 +0000910 PyObject_SelfIter, /* tp_iter */
Raymond Hettinger60eca932003-02-09 06:40:58 +0000911 (iternextfunc)islice_next, /* tp_iternext */
Raymond Hettinger96ef8112003-02-01 00:10:11 +0000912 0, /* tp_methods */
913 0, /* tp_members */
914 0, /* tp_getset */
915 0, /* tp_base */
916 0, /* tp_dict */
917 0, /* tp_descr_get */
918 0, /* tp_descr_set */
919 0, /* tp_dictoffset */
920 0, /* tp_init */
Raymond Hettingerbfef18c2003-05-23 03:55:42 +0000921 0, /* tp_alloc */
Raymond Hettinger96ef8112003-02-01 00:10:11 +0000922 islice_new, /* tp_new */
923 PyObject_GC_Del, /* tp_free */
924};
925
926
927/* starmap object ************************************************************/
928
929typedef struct {
930 PyObject_HEAD
931 PyObject *func;
932 PyObject *it;
933} starmapobject;
934
Raymond Hettinger1d7a3482003-07-14 07:07:12 +0000935static PyTypeObject starmap_type;
Raymond Hettinger96ef8112003-02-01 00:10:11 +0000936
937static PyObject *
938starmap_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
939{
940 PyObject *func, *seq;
941 PyObject *it;
942 starmapobject *lz;
943
944 if (!PyArg_UnpackTuple(args, "starmap", 2, 2, &func, &seq))
945 return NULL;
946
947 /* Get iterator. */
948 it = PyObject_GetIter(seq);
949 if (it == NULL)
950 return NULL;
951
952 /* create starmapobject structure */
953 lz = (starmapobject *)type->tp_alloc(type, 0);
954 if (lz == NULL) {
955 Py_DECREF(it);
956 return NULL;
957 }
958 Py_INCREF(func);
959 lz->func = func;
960 lz->it = it;
961
962 return (PyObject *)lz;
963}
964
965static void
966starmap_dealloc(starmapobject *lz)
967{
968 PyObject_GC_UnTrack(lz);
969 Py_XDECREF(lz->func);
970 Py_XDECREF(lz->it);
971 lz->ob_type->tp_free(lz);
972}
973
974static int
975starmap_traverse(starmapobject *lz, visitproc visit, void *arg)
976{
977 int err;
978
979 if (lz->it) {
980 err = visit(lz->it, arg);
981 if (err)
982 return err;
983 }
984 if (lz->func) {
985 err = visit(lz->func, arg);
986 if (err)
987 return err;
988 }
989 return 0;
990}
991
992static PyObject *
993starmap_next(starmapobject *lz)
994{
995 PyObject *args;
996 PyObject *result;
Raymond Hettingerd1a283b2003-03-01 01:48:24 +0000997 PyObject *it = lz->it;
Raymond Hettinger96ef8112003-02-01 00:10:11 +0000998
Raymond Hettingerd1a283b2003-03-01 01:48:24 +0000999 assert(PyIter_Check(it));
1000 args = (*it->ob_type->tp_iternext)(it);
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001001 if (args == NULL)
1002 return NULL;
Raymond Hettinger2012f172003-02-07 05:32:58 +00001003 if (!PyTuple_CheckExact(args)) {
1004 Py_DECREF(args);
1005 PyErr_SetString(PyExc_TypeError,
1006 "iterator must return a tuple");
1007 return NULL;
1008 }
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001009 result = PyObject_Call(lz->func, args, NULL);
1010 Py_DECREF(args);
1011 return result;
1012}
1013
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001014PyDoc_STRVAR(starmap_doc,
1015"starmap(function, sequence) --> starmap object\n\
1016\n\
1017Return an iterator whose values are returned from the function evaluated\n\
1018with a argument tuple taken from the given sequence.");
1019
Raymond Hettinger1d7a3482003-07-14 07:07:12 +00001020static PyTypeObject starmap_type = {
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001021 PyObject_HEAD_INIT(NULL)
1022 0, /* ob_size */
Raymond Hettinger60eca932003-02-09 06:40:58 +00001023 "itertools.starmap", /* tp_name */
1024 sizeof(starmapobject), /* tp_basicsize */
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001025 0, /* tp_itemsize */
1026 /* methods */
Raymond Hettinger60eca932003-02-09 06:40:58 +00001027 (destructor)starmap_dealloc, /* tp_dealloc */
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001028 0, /* tp_print */
1029 0, /* tp_getattr */
1030 0, /* tp_setattr */
1031 0, /* tp_compare */
1032 0, /* tp_repr */
1033 0, /* tp_as_number */
1034 0, /* tp_as_sequence */
1035 0, /* tp_as_mapping */
1036 0, /* tp_hash */
1037 0, /* tp_call */
1038 0, /* tp_str */
1039 PyObject_GenericGetAttr, /* tp_getattro */
1040 0, /* tp_setattro */
1041 0, /* tp_as_buffer */
1042 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
1043 Py_TPFLAGS_BASETYPE, /* tp_flags */
Raymond Hettinger60eca932003-02-09 06:40:58 +00001044 starmap_doc, /* tp_doc */
1045 (traverseproc)starmap_traverse, /* tp_traverse */
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001046 0, /* tp_clear */
1047 0, /* tp_richcompare */
1048 0, /* tp_weaklistoffset */
Raymond Hettinger1da1dbf2003-03-17 19:46:11 +00001049 PyObject_SelfIter, /* tp_iter */
Raymond Hettinger60eca932003-02-09 06:40:58 +00001050 (iternextfunc)starmap_next, /* tp_iternext */
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001051 0, /* tp_methods */
1052 0, /* tp_members */
1053 0, /* tp_getset */
1054 0, /* tp_base */
1055 0, /* tp_dict */
1056 0, /* tp_descr_get */
1057 0, /* tp_descr_set */
1058 0, /* tp_dictoffset */
1059 0, /* tp_init */
Raymond Hettingerbfef18c2003-05-23 03:55:42 +00001060 0, /* tp_alloc */
Raymond Hettinger60eca932003-02-09 06:40:58 +00001061 starmap_new, /* tp_new */
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001062 PyObject_GC_Del, /* tp_free */
1063};
1064
1065
1066/* imap object ************************************************************/
1067
1068typedef struct {
1069 PyObject_HEAD
1070 PyObject *iters;
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001071 PyObject *func;
1072} imapobject;
1073
Raymond Hettinger1d7a3482003-07-14 07:07:12 +00001074static PyTypeObject imap_type;
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001075
1076static PyObject *
1077imap_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1078{
Raymond Hettingerf0c00242003-02-07 07:26:25 +00001079 PyObject *it, *iters, *func;
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001080 imapobject *lz;
1081 int numargs, i;
1082
1083 numargs = PyTuple_Size(args);
1084 if (numargs < 2) {
1085 PyErr_SetString(PyExc_TypeError,
1086 "imap() must have at least two arguments.");
1087 return NULL;
1088 }
1089
1090 iters = PyTuple_New(numargs-1);
1091 if (iters == NULL)
1092 return NULL;
1093
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001094 for (i=1 ; i<numargs ; i++) {
1095 /* Get iterator. */
1096 it = PyObject_GetIter(PyTuple_GET_ITEM(args, i));
1097 if (it == NULL) {
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001098 Py_DECREF(iters);
1099 return NULL;
1100 }
1101 PyTuple_SET_ITEM(iters, i-1, it);
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001102 }
1103
1104 /* create imapobject structure */
1105 lz = (imapobject *)type->tp_alloc(type, 0);
1106 if (lz == NULL) {
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001107 Py_DECREF(iters);
1108 return NULL;
1109 }
1110 lz->iters = iters;
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001111 func = PyTuple_GET_ITEM(args, 0);
1112 Py_INCREF(func);
1113 lz->func = func;
1114
1115 return (PyObject *)lz;
1116}
1117
1118static void
1119imap_dealloc(imapobject *lz)
1120{
1121 PyObject_GC_UnTrack(lz);
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001122 Py_XDECREF(lz->iters);
1123 Py_XDECREF(lz->func);
1124 lz->ob_type->tp_free(lz);
1125}
1126
1127static int
1128imap_traverse(imapobject *lz, visitproc visit, void *arg)
1129{
1130 int err;
1131
1132 if (lz->iters) {
1133 err = visit(lz->iters, arg);
1134 if (err)
1135 return err;
1136 }
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001137 if (lz->func) {
1138 err = visit(lz->func, arg);
1139 if (err)
1140 return err;
1141 }
1142 return 0;
1143}
1144
Raymond Hettinger2012f172003-02-07 05:32:58 +00001145/*
1146imap() is an iterator version of __builtins__.map() except that it does
1147not have the None fill-in feature. That was intentionally left out for
1148the following reasons:
1149
1150 1) Itertools are designed to be easily combined and chained together.
1151 Having all tools stop with the shortest input is a unifying principle
1152 that makes it easier to combine finite iterators (supplying data) with
1153 infinite iterators like count() and repeat() (for supplying sequential
1154 or constant arguments to a function).
1155
1156 2) In typical use cases for combining itertools, having one finite data
1157 supplier run out before another is likely to be an error condition which
1158 should not pass silently by automatically supplying None.
1159
1160 3) The use cases for automatic None fill-in are rare -- not many functions
1161 do something useful when a parameter suddenly switches type and becomes
1162 None.
1163
1164 4) If a need does arise, it can be met by __builtins__.map() or by
Raymond Hettingerbefa37d2003-06-18 19:25:37 +00001165 writing: chain(iterable, repeat(None)).
Raymond Hettinger2012f172003-02-07 05:32:58 +00001166
1167 5) Similar toolsets in Haskell and SML do not have automatic None fill-in.
1168*/
1169
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001170static PyObject *
1171imap_next(imapobject *lz)
1172{
1173 PyObject *val;
Raymond Hettingerf0c00242003-02-07 07:26:25 +00001174 PyObject *argtuple;
1175 PyObject *result;
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001176 int numargs, i;
1177
1178 numargs = PyTuple_Size(lz->iters);
Raymond Hettingerf0c00242003-02-07 07:26:25 +00001179 argtuple = PyTuple_New(numargs);
1180 if (argtuple == NULL)
1181 return NULL;
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001182
Raymond Hettingerf0c00242003-02-07 07:26:25 +00001183 for (i=0 ; i<numargs ; i++) {
1184 val = PyIter_Next(PyTuple_GET_ITEM(lz->iters, i));
1185 if (val == NULL) {
1186 Py_DECREF(argtuple);
1187 return NULL;
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001188 }
Raymond Hettingerf0c00242003-02-07 07:26:25 +00001189 PyTuple_SET_ITEM(argtuple, i, val);
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001190 }
Raymond Hettingerf0c00242003-02-07 07:26:25 +00001191 if (lz->func == Py_None)
1192 return argtuple;
1193 result = PyObject_Call(lz->func, argtuple, NULL);
1194 Py_DECREF(argtuple);
1195 return result;
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001196}
1197
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001198PyDoc_STRVAR(imap_doc,
1199"imap(func, *iterables) --> imap object\n\
1200\n\
1201Make an iterator that computes the function using arguments from\n\
1202each of the iterables. Like map() except that it returns\n\
1203an iterator instead of a list and that it stops when the shortest\n\
1204iterable is exhausted instead of filling in None for shorter\n\
1205iterables.");
1206
Raymond Hettinger1d7a3482003-07-14 07:07:12 +00001207static PyTypeObject imap_type = {
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001208 PyObject_HEAD_INIT(NULL)
1209 0, /* ob_size */
Raymond Hettinger60eca932003-02-09 06:40:58 +00001210 "itertools.imap", /* tp_name */
1211 sizeof(imapobject), /* tp_basicsize */
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001212 0, /* tp_itemsize */
1213 /* methods */
1214 (destructor)imap_dealloc, /* tp_dealloc */
1215 0, /* tp_print */
1216 0, /* tp_getattr */
1217 0, /* tp_setattr */
1218 0, /* tp_compare */
1219 0, /* tp_repr */
1220 0, /* tp_as_number */
1221 0, /* tp_as_sequence */
1222 0, /* tp_as_mapping */
1223 0, /* tp_hash */
1224 0, /* tp_call */
1225 0, /* tp_str */
1226 PyObject_GenericGetAttr, /* tp_getattro */
1227 0, /* tp_setattro */
1228 0, /* tp_as_buffer */
1229 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
1230 Py_TPFLAGS_BASETYPE, /* tp_flags */
1231 imap_doc, /* tp_doc */
1232 (traverseproc)imap_traverse, /* tp_traverse */
1233 0, /* tp_clear */
1234 0, /* tp_richcompare */
1235 0, /* tp_weaklistoffset */
Raymond Hettinger1da1dbf2003-03-17 19:46:11 +00001236 PyObject_SelfIter, /* tp_iter */
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001237 (iternextfunc)imap_next, /* tp_iternext */
1238 0, /* tp_methods */
1239 0, /* tp_members */
1240 0, /* tp_getset */
1241 0, /* tp_base */
1242 0, /* tp_dict */
1243 0, /* tp_descr_get */
1244 0, /* tp_descr_set */
1245 0, /* tp_dictoffset */
1246 0, /* tp_init */
Raymond Hettingerbfef18c2003-05-23 03:55:42 +00001247 0, /* tp_alloc */
Raymond Hettinger60eca932003-02-09 06:40:58 +00001248 imap_new, /* tp_new */
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001249 PyObject_GC_Del, /* tp_free */
1250};
1251
1252
Raymond Hettinger61fe64d2003-02-23 04:40:07 +00001253/* chain object ************************************************************/
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001254
1255typedef struct {
1256 PyObject_HEAD
Raymond Hettinger61fe64d2003-02-23 04:40:07 +00001257 long tuplesize;
1258 long iternum; /* which iterator is active */
1259 PyObject *ittuple; /* tuple of iterators */
1260} chainobject;
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001261
Raymond Hettinger1d7a3482003-07-14 07:07:12 +00001262static PyTypeObject chain_type;
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001263
1264static PyObject *
Raymond Hettinger61fe64d2003-02-23 04:40:07 +00001265chain_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001266{
Raymond Hettinger61fe64d2003-02-23 04:40:07 +00001267 chainobject *lz;
1268 int tuplesize = PySequence_Length(args);
1269 int i;
1270 PyObject *ittuple;
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001271
Raymond Hettinger61fe64d2003-02-23 04:40:07 +00001272 /* obtain iterators */
1273 assert(PyTuple_Check(args));
1274 ittuple = PyTuple_New(tuplesize);
1275 if(ittuple == NULL)
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001276 return NULL;
Raymond Hettinger61fe64d2003-02-23 04:40:07 +00001277 for (i=0; i < tuplesize; ++i) {
1278 PyObject *item = PyTuple_GET_ITEM(args, i);
1279 PyObject *it = PyObject_GetIter(item);
1280 if (it == NULL) {
1281 if (PyErr_ExceptionMatches(PyExc_TypeError))
1282 PyErr_Format(PyExc_TypeError,
1283 "chain argument #%d must support iteration",
1284 i+1);
1285 Py_DECREF(ittuple);
1286 return NULL;
1287 }
1288 PyTuple_SET_ITEM(ittuple, i, it);
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001289 }
1290
Raymond Hettinger61fe64d2003-02-23 04:40:07 +00001291 /* create chainobject structure */
1292 lz = (chainobject *)type->tp_alloc(type, 0);
Raymond Hettinger7d98fb92003-06-17 23:14:40 +00001293 if (lz == NULL) {
1294 Py_DECREF(ittuple);
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001295 return NULL;
Raymond Hettinger7d98fb92003-06-17 23:14:40 +00001296 }
Raymond Hettinger61fe64d2003-02-23 04:40:07 +00001297
1298 lz->ittuple = ittuple;
1299 lz->iternum = 0;
1300 lz->tuplesize = tuplesize;
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001301
1302 return (PyObject *)lz;
1303}
1304
1305static void
Raymond Hettinger61fe64d2003-02-23 04:40:07 +00001306chain_dealloc(chainobject *lz)
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001307{
1308 PyObject_GC_UnTrack(lz);
Raymond Hettinger61fe64d2003-02-23 04:40:07 +00001309 Py_XDECREF(lz->ittuple);
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001310 lz->ob_type->tp_free(lz);
1311}
1312
Raymond Hettinger2012f172003-02-07 05:32:58 +00001313static int
Raymond Hettinger61fe64d2003-02-23 04:40:07 +00001314chain_traverse(chainobject *lz, visitproc visit, void *arg)
Raymond Hettinger2012f172003-02-07 05:32:58 +00001315{
Raymond Hettinger61fe64d2003-02-23 04:40:07 +00001316 if (lz->ittuple)
1317 return visit(lz->ittuple, arg);
Raymond Hettinger2012f172003-02-07 05:32:58 +00001318 return 0;
1319}
1320
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001321static PyObject *
Raymond Hettinger61fe64d2003-02-23 04:40:07 +00001322chain_next(chainobject *lz)
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001323{
Raymond Hettinger61fe64d2003-02-23 04:40:07 +00001324 PyObject *it;
1325 PyObject *item;
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001326
Raymond Hettinger61fe64d2003-02-23 04:40:07 +00001327 while (lz->iternum < lz->tuplesize) {
1328 it = PyTuple_GET_ITEM(lz->ittuple, lz->iternum);
1329 item = PyIter_Next(it);
1330 if (item != NULL)
1331 return item;
1332 lz->iternum++;
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001333 }
1334 return NULL;
1335}
1336
Raymond Hettinger61fe64d2003-02-23 04:40:07 +00001337PyDoc_STRVAR(chain_doc,
1338"chain(*iterables) --> chain object\n\
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001339\n\
Raymond Hettinger61fe64d2003-02-23 04:40:07 +00001340Return a chain object whose .next() method returns elements from the\n\
1341first iterable until it is exhausted, then elements from the next\n\
1342iterable, until all of the iterables are exhausted.");
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001343
Raymond Hettinger1d7a3482003-07-14 07:07:12 +00001344static PyTypeObject chain_type = {
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001345 PyObject_HEAD_INIT(NULL)
1346 0, /* ob_size */
Raymond Hettinger61fe64d2003-02-23 04:40:07 +00001347 "itertools.chain", /* tp_name */
1348 sizeof(chainobject), /* tp_basicsize */
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001349 0, /* tp_itemsize */
1350 /* methods */
Raymond Hettinger61fe64d2003-02-23 04:40:07 +00001351 (destructor)chain_dealloc, /* tp_dealloc */
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001352 0, /* tp_print */
1353 0, /* tp_getattr */
1354 0, /* tp_setattr */
1355 0, /* tp_compare */
1356 0, /* tp_repr */
1357 0, /* tp_as_number */
1358 0, /* tp_as_sequence */
1359 0, /* tp_as_mapping */
1360 0, /* tp_hash */
1361 0, /* tp_call */
1362 0, /* tp_str */
1363 PyObject_GenericGetAttr, /* tp_getattro */
1364 0, /* tp_setattro */
1365 0, /* tp_as_buffer */
1366 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
1367 Py_TPFLAGS_BASETYPE, /* tp_flags */
Raymond Hettinger61fe64d2003-02-23 04:40:07 +00001368 chain_doc, /* tp_doc */
1369 (traverseproc)chain_traverse, /* tp_traverse */
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001370 0, /* tp_clear */
1371 0, /* tp_richcompare */
1372 0, /* tp_weaklistoffset */
Raymond Hettinger1da1dbf2003-03-17 19:46:11 +00001373 PyObject_SelfIter, /* tp_iter */
Raymond Hettinger61fe64d2003-02-23 04:40:07 +00001374 (iternextfunc)chain_next, /* tp_iternext */
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001375 0, /* tp_methods */
1376 0, /* tp_members */
1377 0, /* tp_getset */
1378 0, /* tp_base */
1379 0, /* tp_dict */
1380 0, /* tp_descr_get */
1381 0, /* tp_descr_set */
1382 0, /* tp_dictoffset */
1383 0, /* tp_init */
Raymond Hettingerbfef18c2003-05-23 03:55:42 +00001384 0, /* tp_alloc */
Raymond Hettinger61fe64d2003-02-23 04:40:07 +00001385 chain_new, /* tp_new */
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001386 PyObject_GC_Del, /* tp_free */
1387};
1388
1389
1390/* ifilter object ************************************************************/
1391
1392typedef struct {
1393 PyObject_HEAD
1394 PyObject *func;
1395 PyObject *it;
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001396} ifilterobject;
1397
Raymond Hettinger1d7a3482003-07-14 07:07:12 +00001398static PyTypeObject ifilter_type;
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001399
1400static PyObject *
1401ifilter_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1402{
Raymond Hettinger60eca932003-02-09 06:40:58 +00001403 PyObject *func, *seq;
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001404 PyObject *it;
1405 ifilterobject *lz;
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001406
Raymond Hettinger60eca932003-02-09 06:40:58 +00001407 if (!PyArg_UnpackTuple(args, "ifilter", 2, 2, &func, &seq))
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001408 return NULL;
1409
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001410 /* Get iterator. */
1411 it = PyObject_GetIter(seq);
1412 if (it == NULL)
1413 return NULL;
1414
1415 /* create ifilterobject structure */
1416 lz = (ifilterobject *)type->tp_alloc(type, 0);
1417 if (lz == NULL) {
1418 Py_DECREF(it);
1419 return NULL;
1420 }
1421 Py_INCREF(func);
1422 lz->func = func;
1423 lz->it = it;
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001424
1425 return (PyObject *)lz;
1426}
1427
1428static void
1429ifilter_dealloc(ifilterobject *lz)
1430{
1431 PyObject_GC_UnTrack(lz);
1432 Py_XDECREF(lz->func);
1433 Py_XDECREF(lz->it);
1434 lz->ob_type->tp_free(lz);
1435}
1436
1437static int
1438ifilter_traverse(ifilterobject *lz, visitproc visit, void *arg)
1439{
1440 int err;
1441
1442 if (lz->it) {
1443 err = visit(lz->it, arg);
1444 if (err)
1445 return err;
1446 }
1447 if (lz->func) {
1448 err = visit(lz->func, arg);
1449 if (err)
1450 return err;
1451 }
1452 return 0;
1453}
1454
1455static PyObject *
1456ifilter_next(ifilterobject *lz)
1457{
1458 PyObject *item;
Raymond Hettingerd1a283b2003-03-01 01:48:24 +00001459 PyObject *it = lz->it;
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001460 long ok;
1461
1462 for (;;) {
Raymond Hettingerd1a283b2003-03-01 01:48:24 +00001463 assert(PyIter_Check(it));
1464 item = (*it->ob_type->tp_iternext)(it);
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001465 if (item == NULL)
1466 return NULL;
1467
1468 if (lz->func == Py_None) {
1469 ok = PyObject_IsTrue(item);
1470 } else {
1471 PyObject *good;
1472 good = PyObject_CallFunctionObjArgs(lz->func,
1473 item, NULL);
1474 if (good == NULL) {
1475 Py_DECREF(item);
1476 return NULL;
1477 }
1478 ok = PyObject_IsTrue(good);
1479 Py_DECREF(good);
1480 }
Raymond Hettinger60eca932003-02-09 06:40:58 +00001481 if (ok)
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001482 return item;
1483 Py_DECREF(item);
1484 }
1485}
1486
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001487PyDoc_STRVAR(ifilter_doc,
Raymond Hettinger60eca932003-02-09 06:40:58 +00001488"ifilter(function or None, sequence) --> ifilter object\n\
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001489\n\
Raymond Hettinger60eca932003-02-09 06:40:58 +00001490Return those items of sequence for which function(item) is true.\n\
1491If function is None, return the items that are true.");
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001492
Raymond Hettinger1d7a3482003-07-14 07:07:12 +00001493static PyTypeObject ifilter_type = {
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001494 PyObject_HEAD_INIT(NULL)
1495 0, /* ob_size */
Raymond Hettinger60eca932003-02-09 06:40:58 +00001496 "itertools.ifilter", /* tp_name */
1497 sizeof(ifilterobject), /* tp_basicsize */
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001498 0, /* tp_itemsize */
1499 /* methods */
Raymond Hettinger60eca932003-02-09 06:40:58 +00001500 (destructor)ifilter_dealloc, /* tp_dealloc */
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001501 0, /* tp_print */
1502 0, /* tp_getattr */
1503 0, /* tp_setattr */
1504 0, /* tp_compare */
1505 0, /* tp_repr */
1506 0, /* tp_as_number */
1507 0, /* tp_as_sequence */
1508 0, /* tp_as_mapping */
1509 0, /* tp_hash */
1510 0, /* tp_call */
1511 0, /* tp_str */
1512 PyObject_GenericGetAttr, /* tp_getattro */
1513 0, /* tp_setattro */
1514 0, /* tp_as_buffer */
1515 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
1516 Py_TPFLAGS_BASETYPE, /* tp_flags */
Raymond Hettinger60eca932003-02-09 06:40:58 +00001517 ifilter_doc, /* tp_doc */
1518 (traverseproc)ifilter_traverse, /* tp_traverse */
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001519 0, /* tp_clear */
1520 0, /* tp_richcompare */
1521 0, /* tp_weaklistoffset */
Raymond Hettinger1da1dbf2003-03-17 19:46:11 +00001522 PyObject_SelfIter, /* tp_iter */
Raymond Hettinger60eca932003-02-09 06:40:58 +00001523 (iternextfunc)ifilter_next, /* tp_iternext */
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001524 0, /* tp_methods */
1525 0, /* tp_members */
1526 0, /* tp_getset */
1527 0, /* tp_base */
1528 0, /* tp_dict */
1529 0, /* tp_descr_get */
1530 0, /* tp_descr_set */
1531 0, /* tp_dictoffset */
1532 0, /* tp_init */
Raymond Hettingerbfef18c2003-05-23 03:55:42 +00001533 0, /* tp_alloc */
Raymond Hettinger60eca932003-02-09 06:40:58 +00001534 ifilter_new, /* tp_new */
1535 PyObject_GC_Del, /* tp_free */
1536};
1537
1538
1539/* ifilterfalse object ************************************************************/
1540
1541typedef struct {
1542 PyObject_HEAD
1543 PyObject *func;
1544 PyObject *it;
1545} ifilterfalseobject;
1546
Raymond Hettinger1d7a3482003-07-14 07:07:12 +00001547static PyTypeObject ifilterfalse_type;
Raymond Hettinger60eca932003-02-09 06:40:58 +00001548
1549static PyObject *
1550ifilterfalse_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1551{
Guido van Rossumd58f3fc2003-02-09 17:19:18 +00001552 PyObject *func, *seq;
Raymond Hettinger60eca932003-02-09 06:40:58 +00001553 PyObject *it;
1554 ifilterfalseobject *lz;
1555
1556 if (!PyArg_UnpackTuple(args, "ifilterfalse", 2, 2, &func, &seq))
1557 return NULL;
1558
1559 /* Get iterator. */
1560 it = PyObject_GetIter(seq);
1561 if (it == NULL)
1562 return NULL;
1563
1564 /* create ifilterfalseobject structure */
1565 lz = (ifilterfalseobject *)type->tp_alloc(type, 0);
1566 if (lz == NULL) {
1567 Py_DECREF(it);
1568 return NULL;
1569 }
1570 Py_INCREF(func);
1571 lz->func = func;
1572 lz->it = it;
1573
1574 return (PyObject *)lz;
1575}
1576
1577static void
1578ifilterfalse_dealloc(ifilterfalseobject *lz)
1579{
1580 PyObject_GC_UnTrack(lz);
1581 Py_XDECREF(lz->func);
1582 Py_XDECREF(lz->it);
1583 lz->ob_type->tp_free(lz);
1584}
1585
1586static int
1587ifilterfalse_traverse(ifilterfalseobject *lz, visitproc visit, void *arg)
1588{
1589 int err;
1590
1591 if (lz->it) {
1592 err = visit(lz->it, arg);
1593 if (err)
1594 return err;
1595 }
1596 if (lz->func) {
1597 err = visit(lz->func, arg);
1598 if (err)
1599 return err;
1600 }
1601 return 0;
1602}
1603
1604static PyObject *
1605ifilterfalse_next(ifilterfalseobject *lz)
1606{
1607 PyObject *item;
Raymond Hettingerd1a283b2003-03-01 01:48:24 +00001608 PyObject *it = lz->it;
Raymond Hettinger60eca932003-02-09 06:40:58 +00001609 long ok;
1610
1611 for (;;) {
Raymond Hettingerd1a283b2003-03-01 01:48:24 +00001612 assert(PyIter_Check(it));
1613 item = (*it->ob_type->tp_iternext)(it);
Raymond Hettinger60eca932003-02-09 06:40:58 +00001614 if (item == NULL)
1615 return NULL;
1616
1617 if (lz->func == Py_None) {
1618 ok = PyObject_IsTrue(item);
1619 } else {
1620 PyObject *good;
1621 good = PyObject_CallFunctionObjArgs(lz->func,
1622 item, NULL);
1623 if (good == NULL) {
1624 Py_DECREF(item);
1625 return NULL;
1626 }
1627 ok = PyObject_IsTrue(good);
1628 Py_DECREF(good);
1629 }
1630 if (!ok)
1631 return item;
1632 Py_DECREF(item);
1633 }
1634}
1635
Raymond Hettinger60eca932003-02-09 06:40:58 +00001636PyDoc_STRVAR(ifilterfalse_doc,
1637"ifilterfalse(function or None, sequence) --> ifilterfalse object\n\
1638\n\
1639Return those items of sequence for which function(item) is false.\n\
1640If function is None, return the items that are false.");
1641
Raymond Hettinger1d7a3482003-07-14 07:07:12 +00001642static PyTypeObject ifilterfalse_type = {
Raymond Hettinger60eca932003-02-09 06:40:58 +00001643 PyObject_HEAD_INIT(NULL)
1644 0, /* ob_size */
1645 "itertools.ifilterfalse", /* tp_name */
1646 sizeof(ifilterfalseobject), /* tp_basicsize */
1647 0, /* tp_itemsize */
1648 /* methods */
1649 (destructor)ifilterfalse_dealloc, /* tp_dealloc */
1650 0, /* tp_print */
1651 0, /* tp_getattr */
1652 0, /* tp_setattr */
1653 0, /* tp_compare */
1654 0, /* tp_repr */
1655 0, /* tp_as_number */
1656 0, /* tp_as_sequence */
1657 0, /* tp_as_mapping */
1658 0, /* tp_hash */
1659 0, /* tp_call */
1660 0, /* tp_str */
1661 PyObject_GenericGetAttr, /* tp_getattro */
1662 0, /* tp_setattro */
1663 0, /* tp_as_buffer */
1664 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
1665 Py_TPFLAGS_BASETYPE, /* tp_flags */
1666 ifilterfalse_doc, /* tp_doc */
1667 (traverseproc)ifilterfalse_traverse, /* tp_traverse */
1668 0, /* tp_clear */
1669 0, /* tp_richcompare */
1670 0, /* tp_weaklistoffset */
Raymond Hettinger1da1dbf2003-03-17 19:46:11 +00001671 PyObject_SelfIter, /* tp_iter */
Raymond Hettinger60eca932003-02-09 06:40:58 +00001672 (iternextfunc)ifilterfalse_next, /* tp_iternext */
1673 0, /* tp_methods */
1674 0, /* tp_members */
1675 0, /* tp_getset */
1676 0, /* tp_base */
1677 0, /* tp_dict */
1678 0, /* tp_descr_get */
1679 0, /* tp_descr_set */
1680 0, /* tp_dictoffset */
1681 0, /* tp_init */
Raymond Hettingerbfef18c2003-05-23 03:55:42 +00001682 0, /* tp_alloc */
Raymond Hettinger60eca932003-02-09 06:40:58 +00001683 ifilterfalse_new, /* tp_new */
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001684 PyObject_GC_Del, /* tp_free */
1685};
1686
1687
1688/* count object ************************************************************/
1689
1690typedef struct {
1691 PyObject_HEAD
1692 long cnt;
1693} countobject;
1694
Raymond Hettinger1d7a3482003-07-14 07:07:12 +00001695static PyTypeObject count_type;
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001696
1697static PyObject *
1698count_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1699{
1700 countobject *lz;
1701 long cnt = 0;
1702
1703 if (!PyArg_ParseTuple(args, "|l:count", &cnt))
1704 return NULL;
1705
1706 /* create countobject structure */
1707 lz = (countobject *)PyObject_New(countobject, &count_type);
1708 if (lz == NULL)
1709 return NULL;
1710 lz->cnt = cnt;
1711
1712 return (PyObject *)lz;
1713}
1714
1715static PyObject *
1716count_next(countobject *lz)
1717{
1718 return PyInt_FromLong(lz->cnt++);
1719}
1720
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001721PyDoc_STRVAR(count_doc,
1722"count([firstval]) --> count object\n\
1723\n\
1724Return a count object whose .next() method returns consecutive\n\
1725integers starting from zero or, if specified, from firstval.");
1726
Raymond Hettinger1d7a3482003-07-14 07:07:12 +00001727static PyTypeObject count_type = {
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001728 PyObject_HEAD_INIT(NULL)
1729 0, /* ob_size */
Raymond Hettinger60eca932003-02-09 06:40:58 +00001730 "itertools.count", /* tp_name */
1731 sizeof(countobject), /* tp_basicsize */
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001732 0, /* tp_itemsize */
1733 /* methods */
1734 (destructor)PyObject_Del, /* tp_dealloc */
1735 0, /* tp_print */
1736 0, /* tp_getattr */
1737 0, /* tp_setattr */
1738 0, /* tp_compare */
1739 0, /* tp_repr */
1740 0, /* tp_as_number */
1741 0, /* tp_as_sequence */
1742 0, /* tp_as_mapping */
1743 0, /* tp_hash */
1744 0, /* tp_call */
1745 0, /* tp_str */
1746 PyObject_GenericGetAttr, /* tp_getattro */
1747 0, /* tp_setattro */
1748 0, /* tp_as_buffer */
1749 Py_TPFLAGS_DEFAULT, /* tp_flags */
Raymond Hettinger60eca932003-02-09 06:40:58 +00001750 count_doc, /* tp_doc */
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001751 0, /* tp_traverse */
1752 0, /* tp_clear */
1753 0, /* tp_richcompare */
1754 0, /* tp_weaklistoffset */
Raymond Hettinger1da1dbf2003-03-17 19:46:11 +00001755 PyObject_SelfIter, /* tp_iter */
Raymond Hettinger60eca932003-02-09 06:40:58 +00001756 (iternextfunc)count_next, /* tp_iternext */
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001757 0, /* tp_methods */
1758 0, /* tp_members */
1759 0, /* tp_getset */
1760 0, /* tp_base */
1761 0, /* tp_dict */
1762 0, /* tp_descr_get */
1763 0, /* tp_descr_set */
1764 0, /* tp_dictoffset */
1765 0, /* tp_init */
Raymond Hettingerbfef18c2003-05-23 03:55:42 +00001766 0, /* tp_alloc */
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001767 count_new, /* tp_new */
1768};
1769
1770
1771/* izip object ************************************************************/
1772
1773#include "Python.h"
1774
1775typedef struct {
1776 PyObject_HEAD
1777 long tuplesize;
1778 PyObject *ittuple; /* tuple of iterators */
Raymond Hettinger2012f172003-02-07 05:32:58 +00001779 PyObject *result;
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001780} izipobject;
1781
Raymond Hettinger1d7a3482003-07-14 07:07:12 +00001782static PyTypeObject izip_type;
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001783
1784static PyObject *
1785izip_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1786{
1787 izipobject *lz;
1788 int i;
1789 PyObject *ittuple; /* tuple of iterators */
Raymond Hettinger2012f172003-02-07 05:32:58 +00001790 PyObject *result;
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001791 int tuplesize = PySequence_Length(args);
1792
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001793 /* args must be a tuple */
1794 assert(PyTuple_Check(args));
1795
1796 /* obtain iterators */
1797 ittuple = PyTuple_New(tuplesize);
1798 if(ittuple == NULL)
1799 return NULL;
1800 for (i=0; i < tuplesize; ++i) {
1801 PyObject *item = PyTuple_GET_ITEM(args, i);
1802 PyObject *it = PyObject_GetIter(item);
1803 if (it == NULL) {
1804 if (PyErr_ExceptionMatches(PyExc_TypeError))
1805 PyErr_Format(PyExc_TypeError,
1806 "izip argument #%d must support iteration",
1807 i+1);
1808 Py_DECREF(ittuple);
1809 return NULL;
1810 }
1811 PyTuple_SET_ITEM(ittuple, i, it);
1812 }
1813
Raymond Hettinger2012f172003-02-07 05:32:58 +00001814 /* create a result holder */
1815 result = PyTuple_New(tuplesize);
1816 if (result == NULL) {
1817 Py_DECREF(ittuple);
1818 return NULL;
1819 }
1820 for (i=0 ; i < tuplesize ; i++) {
1821 Py_INCREF(Py_None);
1822 PyTuple_SET_ITEM(result, i, Py_None);
1823 }
1824
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001825 /* create izipobject structure */
1826 lz = (izipobject *)type->tp_alloc(type, 0);
1827 if (lz == NULL) {
1828 Py_DECREF(ittuple);
Raymond Hettinger2012f172003-02-07 05:32:58 +00001829 Py_DECREF(result);
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001830 return NULL;
1831 }
1832 lz->ittuple = ittuple;
1833 lz->tuplesize = tuplesize;
Raymond Hettinger2012f172003-02-07 05:32:58 +00001834 lz->result = result;
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001835
1836 return (PyObject *)lz;
1837}
1838
1839static void
1840izip_dealloc(izipobject *lz)
1841{
1842 PyObject_GC_UnTrack(lz);
1843 Py_XDECREF(lz->ittuple);
Raymond Hettinger2012f172003-02-07 05:32:58 +00001844 Py_XDECREF(lz->result);
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001845 lz->ob_type->tp_free(lz);
1846}
1847
1848static int
1849izip_traverse(izipobject *lz, visitproc visit, void *arg)
1850{
Raymond Hettingerbefa37d2003-06-18 19:25:37 +00001851 int err;
1852
1853 if (lz->ittuple) {
1854 err = visit(lz->ittuple, arg);
1855 if (err)
1856 return err;
1857 }
1858 if (lz->result) {
1859 err = visit(lz->result, arg);
1860 if (err)
1861 return err;
1862 }
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001863 return 0;
1864}
1865
1866static PyObject *
1867izip_next(izipobject *lz)
1868{
1869 int i;
1870 long tuplesize = lz->tuplesize;
Raymond Hettinger2012f172003-02-07 05:32:58 +00001871 PyObject *result = lz->result;
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001872 PyObject *it;
1873 PyObject *item;
Raymond Hettinger4f01f892003-08-30 00:10:06 +00001874 PyObject *olditem;
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001875
Raymond Hettingerb5a42082003-08-08 05:10:41 +00001876 if (tuplesize == 0)
1877 return NULL;
Raymond Hettinger2012f172003-02-07 05:32:58 +00001878 if (result->ob_refcnt == 1) {
Raymond Hettingera56f6b62003-08-29 23:09:58 +00001879 Py_INCREF(result);
Raymond Hettinger2012f172003-02-07 05:32:58 +00001880 for (i=0 ; i < tuplesize ; i++) {
Raymond Hettingerf0c00242003-02-07 07:26:25 +00001881 it = PyTuple_GET_ITEM(lz->ittuple, i);
Raymond Hettingerd1a283b2003-03-01 01:48:24 +00001882 assert(PyIter_Check(it));
1883 item = (*it->ob_type->tp_iternext)(it);
Raymond Hettingera56f6b62003-08-29 23:09:58 +00001884 if (item == NULL) {
1885 Py_DECREF(result);
Raymond Hettingerf0c00242003-02-07 07:26:25 +00001886 return NULL;
Raymond Hettingera56f6b62003-08-29 23:09:58 +00001887 }
Raymond Hettinger4f01f892003-08-30 00:10:06 +00001888 olditem = PyTuple_GET_ITEM(result, i);
Raymond Hettingerf0c00242003-02-07 07:26:25 +00001889 PyTuple_SET_ITEM(result, i, item);
Raymond Hettinger4f01f892003-08-30 00:10:06 +00001890 Py_DECREF(olditem);
Raymond Hettinger2012f172003-02-07 05:32:58 +00001891 }
Raymond Hettinger2012f172003-02-07 05:32:58 +00001892 } else {
Raymond Hettinger2012f172003-02-07 05:32:58 +00001893 result = PyTuple_New(tuplesize);
1894 if (result == NULL)
1895 return NULL;
Raymond Hettingerf0c00242003-02-07 07:26:25 +00001896 for (i=0 ; i < tuplesize ; i++) {
1897 it = PyTuple_GET_ITEM(lz->ittuple, i);
Raymond Hettingerd1a283b2003-03-01 01:48:24 +00001898 assert(PyIter_Check(it));
1899 item = (*it->ob_type->tp_iternext)(it);
Raymond Hettingerf0c00242003-02-07 07:26:25 +00001900 if (item == NULL) {
1901 Py_DECREF(result);
1902 return NULL;
1903 }
1904 PyTuple_SET_ITEM(result, i, item);
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001905 }
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001906 }
1907 return result;
1908}
1909
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001910PyDoc_STRVAR(izip_doc,
1911"izip(iter1 [,iter2 [...]]) --> izip object\n\
1912\n\
1913Return a izip object whose .next() method returns a tuple where\n\
1914the i-th element comes from the i-th iterable argument. The .next()\n\
1915method continues until the shortest iterable in the argument sequence\n\
1916is exhausted and then it raises StopIteration. Works like the zip()\n\
1917function but consumes less memory by returning an iterator instead of\n\
1918a list.");
1919
Raymond Hettinger1d7a3482003-07-14 07:07:12 +00001920static PyTypeObject izip_type = {
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001921 PyObject_HEAD_INIT(NULL)
1922 0, /* ob_size */
Raymond Hettinger60eca932003-02-09 06:40:58 +00001923 "itertools.izip", /* tp_name */
1924 sizeof(izipobject), /* tp_basicsize */
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001925 0, /* tp_itemsize */
1926 /* methods */
Raymond Hettinger60eca932003-02-09 06:40:58 +00001927 (destructor)izip_dealloc, /* tp_dealloc */
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001928 0, /* tp_print */
1929 0, /* tp_getattr */
1930 0, /* tp_setattr */
1931 0, /* tp_compare */
1932 0, /* tp_repr */
1933 0, /* tp_as_number */
1934 0, /* tp_as_sequence */
1935 0, /* tp_as_mapping */
1936 0, /* tp_hash */
1937 0, /* tp_call */
1938 0, /* tp_str */
1939 PyObject_GenericGetAttr, /* tp_getattro */
1940 0, /* tp_setattro */
1941 0, /* tp_as_buffer */
1942 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
1943 Py_TPFLAGS_BASETYPE, /* tp_flags */
Raymond Hettinger60eca932003-02-09 06:40:58 +00001944 izip_doc, /* tp_doc */
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001945 (traverseproc)izip_traverse, /* tp_traverse */
1946 0, /* tp_clear */
1947 0, /* tp_richcompare */
1948 0, /* tp_weaklistoffset */
Raymond Hettinger1da1dbf2003-03-17 19:46:11 +00001949 PyObject_SelfIter, /* tp_iter */
Raymond Hettinger60eca932003-02-09 06:40:58 +00001950 (iternextfunc)izip_next, /* tp_iternext */
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001951 0, /* tp_methods */
1952 0, /* tp_members */
1953 0, /* tp_getset */
1954 0, /* tp_base */
1955 0, /* tp_dict */
1956 0, /* tp_descr_get */
1957 0, /* tp_descr_set */
1958 0, /* tp_dictoffset */
1959 0, /* tp_init */
Raymond Hettingerbfef18c2003-05-23 03:55:42 +00001960 0, /* tp_alloc */
Raymond Hettinger60eca932003-02-09 06:40:58 +00001961 izip_new, /* tp_new */
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001962 PyObject_GC_Del, /* tp_free */
1963};
1964
1965
1966/* repeat object ************************************************************/
1967
1968typedef struct {
1969 PyObject_HEAD
1970 PyObject *element;
Raymond Hettinger61fe64d2003-02-23 04:40:07 +00001971 long cnt;
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001972} repeatobject;
1973
Raymond Hettinger1d7a3482003-07-14 07:07:12 +00001974static PyTypeObject repeat_type;
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001975
1976static PyObject *
1977repeat_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1978{
1979 repeatobject *ro;
1980 PyObject *element;
Raymond Hettinger61fe64d2003-02-23 04:40:07 +00001981 long cnt = -1;
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001982
Raymond Hettinger61fe64d2003-02-23 04:40:07 +00001983 if (!PyArg_ParseTuple(args, "O|l:repeat", &element, &cnt))
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001984 return NULL;
1985
Raymond Hettinger7c2bb5b2003-05-03 05:59:48 +00001986 if (PyTuple_Size(args) == 2 && cnt < 0)
1987 cnt = 0;
1988
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001989 ro = (repeatobject *)type->tp_alloc(type, 0);
1990 if (ro == NULL)
1991 return NULL;
1992 Py_INCREF(element);
1993 ro->element = element;
Raymond Hettinger61fe64d2003-02-23 04:40:07 +00001994 ro->cnt = cnt;
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001995 return (PyObject *)ro;
1996}
1997
1998static void
1999repeat_dealloc(repeatobject *ro)
2000{
2001 PyObject_GC_UnTrack(ro);
2002 Py_XDECREF(ro->element);
2003 ro->ob_type->tp_free(ro);
2004}
2005
2006static int
2007repeat_traverse(repeatobject *ro, visitproc visit, void *arg)
2008{
2009 if (ro->element)
2010 return visit(ro->element, arg);
2011 return 0;
2012}
2013
2014static PyObject *
2015repeat_next(repeatobject *ro)
2016{
Raymond Hettinger61fe64d2003-02-23 04:40:07 +00002017 if (ro->cnt == 0)
2018 return NULL;
2019 if (ro->cnt > 0)
2020 ro->cnt--;
Raymond Hettinger96ef8112003-02-01 00:10:11 +00002021 Py_INCREF(ro->element);
2022 return ro->element;
2023}
2024
Raymond Hettinger96ef8112003-02-01 00:10:11 +00002025PyDoc_STRVAR(repeat_doc,
Raymond Hettinger61fe64d2003-02-23 04:40:07 +00002026"repeat(element [,times]) -> create an iterator which returns the element\n\
2027for the specified number of times. If not specified, returns the element\n\
2028endlessly.");
Raymond Hettinger96ef8112003-02-01 00:10:11 +00002029
Raymond Hettinger1d7a3482003-07-14 07:07:12 +00002030static PyTypeObject repeat_type = {
Raymond Hettinger96ef8112003-02-01 00:10:11 +00002031 PyObject_HEAD_INIT(NULL)
2032 0, /* ob_size */
2033 "itertools.repeat", /* tp_name */
2034 sizeof(repeatobject), /* tp_basicsize */
2035 0, /* tp_itemsize */
2036 /* methods */
Raymond Hettinger60eca932003-02-09 06:40:58 +00002037 (destructor)repeat_dealloc, /* tp_dealloc */
Raymond Hettinger96ef8112003-02-01 00:10:11 +00002038 0, /* tp_print */
2039 0, /* tp_getattr */
2040 0, /* tp_setattr */
2041 0, /* tp_compare */
2042 0, /* tp_repr */
2043 0, /* tp_as_number */
2044 0, /* tp_as_sequence */
2045 0, /* tp_as_mapping */
2046 0, /* tp_hash */
2047 0, /* tp_call */
2048 0, /* tp_str */
2049 PyObject_GenericGetAttr, /* tp_getattro */
2050 0, /* tp_setattro */
2051 0, /* tp_as_buffer */
2052 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
2053 Py_TPFLAGS_BASETYPE, /* tp_flags */
Raymond Hettinger60eca932003-02-09 06:40:58 +00002054 repeat_doc, /* tp_doc */
2055 (traverseproc)repeat_traverse, /* tp_traverse */
Raymond Hettinger96ef8112003-02-01 00:10:11 +00002056 0, /* tp_clear */
2057 0, /* tp_richcompare */
2058 0, /* tp_weaklistoffset */
Raymond Hettinger1da1dbf2003-03-17 19:46:11 +00002059 PyObject_SelfIter, /* tp_iter */
Raymond Hettinger60eca932003-02-09 06:40:58 +00002060 (iternextfunc)repeat_next, /* tp_iternext */
Raymond Hettinger96ef8112003-02-01 00:10:11 +00002061 0, /* tp_methods */
2062 0, /* tp_members */
2063 0, /* tp_getset */
2064 0, /* tp_base */
2065 0, /* tp_dict */
2066 0, /* tp_descr_get */
2067 0, /* tp_descr_set */
2068 0, /* tp_dictoffset */
2069 0, /* tp_init */
Raymond Hettingerbfef18c2003-05-23 03:55:42 +00002070 0, /* tp_alloc */
Raymond Hettinger96ef8112003-02-01 00:10:11 +00002071 repeat_new, /* tp_new */
2072 PyObject_GC_Del, /* tp_free */
2073};
2074
2075
2076/* module level code ********************************************************/
2077
2078PyDoc_STRVAR(module_doc,
2079"Functional tools for creating and using iterators.\n\
2080\n\
2081Infinite iterators:\n\
2082count([n]) --> n, n+1, n+2, ...\n\
Raymond Hettinger61fe64d2003-02-23 04:40:07 +00002083cycle(p) --> p0, p1, ... plast, p0, p1, ...\n\
Andrew M. Kuchlingdff694b2003-04-14 15:31:27 +00002084repeat(elem [,n]) --> elem, elem, elem, ... endlessly or up to n times\n\
Raymond Hettinger96ef8112003-02-01 00:10:11 +00002085\n\
2086Iterators terminating on the shortest input sequence:\n\
2087izip(p, q, ...) --> (p[0], q[0]), (p[1], q[1]), ... \n\
Raymond Hettinger60eca932003-02-09 06:40:58 +00002088ifilter(pred, seq) --> elements of seq where pred(elem) is True\n\
2089ifilterfalse(pred, seq) --> elements of seq where pred(elem) is False\n\
Raymond Hettinger96ef8112003-02-01 00:10:11 +00002090islice(seq, [start,] stop [, step]) --> elements from\n\
2091 seq[start:stop:step]\n\
2092imap(fun, p, q, ...) --> fun(p0, q0), fun(p1, q1), ...\n\
2093starmap(fun, seq) --> fun(*seq[0]), fun(*seq[1]), ...\n\
Raymond Hettingerf0c5aec2003-10-26 14:25:56 +00002094tee(it) --> (it1, it2) splits one iterator into two \n\
Raymond Hettinger61fe64d2003-02-23 04:40:07 +00002095chain(p, q, ...) --> p0, p1, ... plast, q0, q1, ... \n\
Raymond Hettinger96ef8112003-02-01 00:10:11 +00002096takewhile(pred, seq) --> seq[0], seq[1], until pred fails\n\
2097dropwhile(pred, seq) --> seq[n], seq[n+1], starting when pred fails\n\
2098");
2099
2100
2101PyMODINIT_FUNC
2102inititertools(void)
2103{
Raymond Hettinger60eca932003-02-09 06:40:58 +00002104 int i;
Raymond Hettinger96ef8112003-02-01 00:10:11 +00002105 PyObject *m;
Raymond Hettinger60eca932003-02-09 06:40:58 +00002106 char *name;
2107 PyTypeObject *typelist[] = {
Raymond Hettinger6a5b0272003-10-24 08:45:23 +00002108 &tee_type,
Raymond Hettinger61fe64d2003-02-23 04:40:07 +00002109 &cycle_type,
Raymond Hettinger60eca932003-02-09 06:40:58 +00002110 &dropwhile_type,
2111 &takewhile_type,
2112 &islice_type,
2113 &starmap_type,
2114 &imap_type,
Raymond Hettinger61fe64d2003-02-23 04:40:07 +00002115 &chain_type,
Raymond Hettinger60eca932003-02-09 06:40:58 +00002116 &ifilter_type,
2117 &ifilterfalse_type,
2118 &count_type,
2119 &izip_type,
2120 &repeat_type,
2121 NULL
2122 };
2123
Raymond Hettinger96ef8112003-02-01 00:10:11 +00002124 m = Py_InitModule3("itertools", NULL, module_doc);
2125
Raymond Hettinger60eca932003-02-09 06:40:58 +00002126 for (i=0 ; typelist[i] != NULL ; i++) {
2127 if (PyType_Ready(typelist[i]) < 0)
2128 return;
Raymond Hettingerd449eab2003-05-22 16:32:58 +00002129 name = strchr(typelist[i]->tp_name, '.');
Raymond Hettinger61fe64d2003-02-23 04:40:07 +00002130 assert (name != NULL);
Raymond Hettinger60eca932003-02-09 06:40:58 +00002131 Py_INCREF(typelist[i]);
Raymond Hettingerd449eab2003-05-22 16:32:58 +00002132 PyModule_AddObject(m, name+1, (PyObject *)typelist[i]);
Raymond Hettinger60eca932003-02-09 06:40:58 +00002133 }
Raymond Hettinger96ef8112003-02-01 00:10:11 +00002134}