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