LCOV - code coverage report
Current view: top level - libreoffice/workdir/unxlngi6.pro/UnpackedTarball/python3/Modules - itertoolsmodule.c (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 11 1700 0.6 %
Date: 2012-12-17 Functions: 1 128 0.8 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.10