]> git.proxmox.com Git - mirror_edk2.git/blobdiff - AppPkg/Applications/Python/Python-2.7.10/Modules/itertoolsmodule.c
edk2: Remove AppPkg, StdLib, StdLibPrivateInternalFiles
[mirror_edk2.git] / AppPkg / Applications / Python / Python-2.7.10 / Modules / itertoolsmodule.c
diff --git a/AppPkg/Applications/Python/Python-2.7.10/Modules/itertoolsmodule.c b/AppPkg/Applications/Python/Python-2.7.10/Modules/itertoolsmodule.c
deleted file mode 100644 (file)
index 0279a72..0000000
+++ /dev/null
@@ -1,4143 +0,0 @@
-\r
-#include "Python.h"\r
-#include "structmember.h"\r
-\r
-/* Itertools module written and maintained\r
-   by Raymond D. Hettinger <python@rcn.com>\r
-   Copyright (c) 2003 Python Software Foundation.\r
-   All rights reserved.\r
-*/\r
-\r
-\r
-/* groupby object ***********************************************************/\r
-\r
-typedef struct {\r
-    PyObject_HEAD\r
-    PyObject *it;\r
-    PyObject *keyfunc;\r
-    PyObject *tgtkey;\r
-    PyObject *currkey;\r
-    PyObject *currvalue;\r
-} groupbyobject;\r
-\r
-static PyTypeObject groupby_type;\r
-static PyObject *_grouper_create(groupbyobject *, PyObject *);\r
-\r
-static PyObject *\r
-groupby_new(PyTypeObject *type, PyObject *args, PyObject *kwds)\r
-{\r
-    static char *kwargs[] = {"iterable", "key", NULL};\r
-    groupbyobject *gbo;\r
-    PyObject *it, *keyfunc = Py_None;\r
-\r
-    if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|O:groupby", kwargs,\r
-                                     &it, &keyfunc))\r
-        return NULL;\r
-\r
-    gbo = (groupbyobject *)type->tp_alloc(type, 0);\r
-    if (gbo == NULL)\r
-        return NULL;\r
-    gbo->tgtkey = NULL;\r
-    gbo->currkey = NULL;\r
-    gbo->currvalue = NULL;\r
-    gbo->keyfunc = keyfunc;\r
-    Py_INCREF(keyfunc);\r
-    gbo->it = PyObject_GetIter(it);\r
-    if (gbo->it == NULL) {\r
-        Py_DECREF(gbo);\r
-        return NULL;\r
-    }\r
-    return (PyObject *)gbo;\r
-}\r
-\r
-static void\r
-groupby_dealloc(groupbyobject *gbo)\r
-{\r
-    PyObject_GC_UnTrack(gbo);\r
-    Py_XDECREF(gbo->it);\r
-    Py_XDECREF(gbo->keyfunc);\r
-    Py_XDECREF(gbo->tgtkey);\r
-    Py_XDECREF(gbo->currkey);\r
-    Py_XDECREF(gbo->currvalue);\r
-    Py_TYPE(gbo)->tp_free(gbo);\r
-}\r
-\r
-static int\r
-groupby_traverse(groupbyobject *gbo, visitproc visit, void *arg)\r
-{\r
-    Py_VISIT(gbo->it);\r
-    Py_VISIT(gbo->keyfunc);\r
-    Py_VISIT(gbo->tgtkey);\r
-    Py_VISIT(gbo->currkey);\r
-    Py_VISIT(gbo->currvalue);\r
-    return 0;\r
-}\r
-\r
-static PyObject *\r
-groupby_next(groupbyobject *gbo)\r
-{\r
-    PyObject *newvalue, *newkey, *r, *grouper, *tmp;\r
-\r
-    /* skip to next iteration group */\r
-    for (;;) {\r
-        if (gbo->currkey == NULL)\r
-            /* pass */;\r
-        else if (gbo->tgtkey == NULL)\r
-            break;\r
-        else {\r
-            int rcmp;\r
-\r
-            rcmp = PyObject_RichCompareBool(gbo->tgtkey,\r
-                                            gbo->currkey, Py_EQ);\r
-            if (rcmp == -1)\r
-                return NULL;\r
-            else if (rcmp == 0)\r
-                break;\r
-        }\r
-\r
-        newvalue = PyIter_Next(gbo->it);\r
-        if (newvalue == NULL)\r
-            return NULL;\r
-\r
-        if (gbo->keyfunc == Py_None) {\r
-            newkey = newvalue;\r
-            Py_INCREF(newvalue);\r
-        } else {\r
-            newkey = PyObject_CallFunctionObjArgs(gbo->keyfunc,\r
-                                                  newvalue, NULL);\r
-            if (newkey == NULL) {\r
-                Py_DECREF(newvalue);\r
-                return NULL;\r
-            }\r
-        }\r
-\r
-        tmp = gbo->currkey;\r
-        gbo->currkey = newkey;\r
-        Py_XDECREF(tmp);\r
-\r
-        tmp = gbo->currvalue;\r
-        gbo->currvalue = newvalue;\r
-        Py_XDECREF(tmp);\r
-    }\r
-\r
-    Py_INCREF(gbo->currkey);\r
-    tmp = gbo->tgtkey;\r
-    gbo->tgtkey = gbo->currkey;\r
-    Py_XDECREF(tmp);\r
-\r
-    grouper = _grouper_create(gbo, gbo->tgtkey);\r
-    if (grouper == NULL)\r
-        return NULL;\r
-\r
-    r = PyTuple_Pack(2, gbo->currkey, grouper);\r
-    Py_DECREF(grouper);\r
-    return r;\r
-}\r
-\r
-PyDoc_STRVAR(groupby_doc,\r
-"groupby(iterable[, keyfunc]) -> create an iterator which returns\n\\r
-(key, sub-iterator) grouped by each value of key(value).\n");\r
-\r
-static PyTypeObject groupby_type = {\r
-    PyVarObject_HEAD_INIT(NULL, 0)\r
-    "itertools.groupby",                /* tp_name */\r
-    sizeof(groupbyobject),              /* tp_basicsize */\r
-    0,                                  /* tp_itemsize */\r
-    /* methods */\r
-    (destructor)groupby_dealloc,        /* tp_dealloc */\r
-    0,                                  /* tp_print */\r
-    0,                                  /* tp_getattr */\r
-    0,                                  /* tp_setattr */\r
-    0,                                  /* tp_compare */\r
-    0,                                  /* tp_repr */\r
-    0,                                  /* tp_as_number */\r
-    0,                                  /* tp_as_sequence */\r
-    0,                                  /* tp_as_mapping */\r
-    0,                                  /* tp_hash */\r
-    0,                                  /* tp_call */\r
-    0,                                  /* tp_str */\r
-    PyObject_GenericGetAttr,            /* tp_getattro */\r
-    0,                                  /* tp_setattro */\r
-    0,                                  /* tp_as_buffer */\r
-    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |\r
-        Py_TPFLAGS_BASETYPE,            /* tp_flags */\r
-    groupby_doc,                        /* tp_doc */\r
-    (traverseproc)groupby_traverse,     /* tp_traverse */\r
-    0,                                  /* tp_clear */\r
-    0,                                  /* tp_richcompare */\r
-    0,                                  /* tp_weaklistoffset */\r
-    PyObject_SelfIter,                  /* tp_iter */\r
-    (iternextfunc)groupby_next,         /* tp_iternext */\r
-    0,                                  /* tp_methods */\r
-    0,                                  /* tp_members */\r
-    0,                                  /* tp_getset */\r
-    0,                                  /* tp_base */\r
-    0,                                  /* tp_dict */\r
-    0,                                  /* tp_descr_get */\r
-    0,                                  /* tp_descr_set */\r
-    0,                                  /* tp_dictoffset */\r
-    0,                                  /* tp_init */\r
-    0,                                  /* tp_alloc */\r
-    groupby_new,                        /* tp_new */\r
-    PyObject_GC_Del,                    /* tp_free */\r
-};\r
-\r
-\r
-/* _grouper object (internal) ************************************************/\r
-\r
-typedef struct {\r
-    PyObject_HEAD\r
-    PyObject *parent;\r
-    PyObject *tgtkey;\r
-} _grouperobject;\r
-\r
-static PyTypeObject _grouper_type;\r
-\r
-static PyObject *\r
-_grouper_create(groupbyobject *parent, PyObject *tgtkey)\r
-{\r
-    _grouperobject *igo;\r
-\r
-    igo = PyObject_GC_New(_grouperobject, &_grouper_type);\r
-    if (igo == NULL)\r
-        return NULL;\r
-    igo->parent = (PyObject *)parent;\r
-    Py_INCREF(parent);\r
-    igo->tgtkey = tgtkey;\r
-    Py_INCREF(tgtkey);\r
-\r
-    PyObject_GC_Track(igo);\r
-    return (PyObject *)igo;\r
-}\r
-\r
-static void\r
-_grouper_dealloc(_grouperobject *igo)\r
-{\r
-    PyObject_GC_UnTrack(igo);\r
-    Py_DECREF(igo->parent);\r
-    Py_DECREF(igo->tgtkey);\r
-    PyObject_GC_Del(igo);\r
-}\r
-\r
-static int\r
-_grouper_traverse(_grouperobject *igo, visitproc visit, void *arg)\r
-{\r
-    Py_VISIT(igo->parent);\r
-    Py_VISIT(igo->tgtkey);\r
-    return 0;\r
-}\r
-\r
-static PyObject *\r
-_grouper_next(_grouperobject *igo)\r
-{\r
-    groupbyobject *gbo = (groupbyobject *)igo->parent;\r
-    PyObject *newvalue, *newkey, *r;\r
-    int rcmp;\r
-\r
-    if (gbo->currvalue == NULL) {\r
-        newvalue = PyIter_Next(gbo->it);\r
-        if (newvalue == NULL)\r
-            return NULL;\r
-\r
-        if (gbo->keyfunc == Py_None) {\r
-            newkey = newvalue;\r
-            Py_INCREF(newvalue);\r
-        } else {\r
-            newkey = PyObject_CallFunctionObjArgs(gbo->keyfunc,\r
-                                                  newvalue, NULL);\r
-            if (newkey == NULL) {\r
-                Py_DECREF(newvalue);\r
-                return NULL;\r
-            }\r
-        }\r
-\r
-        assert(gbo->currkey == NULL);\r
-        gbo->currkey = newkey;\r
-        gbo->currvalue = newvalue;\r
-    }\r
-\r
-    assert(gbo->currkey != NULL);\r
-    rcmp = PyObject_RichCompareBool(igo->tgtkey, gbo->currkey, Py_EQ);\r
-    if (rcmp <= 0)\r
-        /* got any error or current group is end */\r
-        return NULL;\r
-\r
-    r = gbo->currvalue;\r
-    gbo->currvalue = NULL;\r
-    Py_CLEAR(gbo->currkey);\r
-\r
-    return r;\r
-}\r
-\r
-static PyTypeObject _grouper_type = {\r
-    PyVarObject_HEAD_INIT(NULL, 0)\r
-    "itertools._grouper",               /* tp_name */\r
-    sizeof(_grouperobject),             /* tp_basicsize */\r
-    0,                                  /* tp_itemsize */\r
-    /* methods */\r
-    (destructor)_grouper_dealloc,       /* tp_dealloc */\r
-    0,                                  /* tp_print */\r
-    0,                                  /* tp_getattr */\r
-    0,                                  /* tp_setattr */\r
-    0,                                  /* tp_compare */\r
-    0,                                  /* tp_repr */\r
-    0,                                  /* tp_as_number */\r
-    0,                                  /* tp_as_sequence */\r
-    0,                                  /* tp_as_mapping */\r
-    0,                                  /* tp_hash */\r
-    0,                                  /* tp_call */\r
-    0,                                  /* tp_str */\r
-    PyObject_GenericGetAttr,            /* tp_getattro */\r
-    0,                                  /* tp_setattro */\r
-    0,                                  /* tp_as_buffer */\r
-    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,            /* tp_flags */\r
-    0,                                  /* tp_doc */\r
-    (traverseproc)_grouper_traverse,/* tp_traverse */\r
-    0,                                  /* tp_clear */\r
-    0,                                  /* tp_richcompare */\r
-    0,                                  /* tp_weaklistoffset */\r
-    PyObject_SelfIter,                  /* tp_iter */\r
-    (iternextfunc)_grouper_next,        /* tp_iternext */\r
-    0,                                  /* tp_methods */\r
-    0,                                  /* tp_members */\r
-    0,                                  /* tp_getset */\r
-    0,                                  /* tp_base */\r
-    0,                                  /* tp_dict */\r
-    0,                                  /* tp_descr_get */\r
-    0,                                  /* tp_descr_set */\r
-    0,                                  /* tp_dictoffset */\r
-    0,                                  /* tp_init */\r
-    0,                                  /* tp_alloc */\r
-    0,                                  /* tp_new */\r
-    PyObject_GC_Del,                    /* tp_free */\r
-};\r
-\r
-\r
-\r
-/* tee object and with supporting function and objects ***************/\r
-\r
-/* The teedataobject pre-allocates space for LINKCELLS number of objects.\r
-   To help the object fit neatly inside cache lines (space for 16 to 32\r
-   pointers), the value should be a multiple of 16 minus  space for\r
-   the other structure members including PyHEAD overhead.  The larger the\r
-   value, the less memory overhead per object and the less time spent\r
-   allocating/deallocating new links.  The smaller the number, the less\r
-   wasted space and the more rapid freeing of older data.\r
-*/\r
-#define LINKCELLS 57\r
-\r
-typedef struct {\r
-    PyObject_HEAD\r
-    PyObject *it;\r
-    int numread;\r
-    PyObject *nextlink;\r
-    PyObject *(values[LINKCELLS]);\r
-} teedataobject;\r
-\r
-typedef struct {\r
-    PyObject_HEAD\r
-    teedataobject *dataobj;\r
-    int index;\r
-    PyObject *weakreflist;\r
-} teeobject;\r
-\r
-static PyTypeObject teedataobject_type;\r
-\r
-static PyObject *\r
-teedataobject_new(PyObject *it)\r
-{\r
-    teedataobject *tdo;\r
-\r
-    tdo = PyObject_GC_New(teedataobject, &teedataobject_type);\r
-    if (tdo == NULL)\r
-        return NULL;\r
-\r
-    tdo->numread = 0;\r
-    tdo->nextlink = NULL;\r
-    Py_INCREF(it);\r
-    tdo->it = it;\r
-    PyObject_GC_Track(tdo);\r
-    return (PyObject *)tdo;\r
-}\r
-\r
-static PyObject *\r
-teedataobject_jumplink(teedataobject *tdo)\r
-{\r
-    if (tdo->nextlink == NULL)\r
-        tdo->nextlink = teedataobject_new(tdo->it);\r
-    Py_XINCREF(tdo->nextlink);\r
-    return tdo->nextlink;\r
-}\r
-\r
-static PyObject *\r
-teedataobject_getitem(teedataobject *tdo, int i)\r
-{\r
-    PyObject *value;\r
-\r
-    assert(i < LINKCELLS);\r
-    if (i < tdo->numread)\r
-        value = tdo->values[i];\r
-    else {\r
-        /* this is the lead iterator, so fetch more data */\r
-        assert(i == tdo->numread);\r
-        value = PyIter_Next(tdo->it);\r
-        if (value == NULL)\r
-            return NULL;\r
-        tdo->numread++;\r
-        tdo->values[i] = value;\r
-    }\r
-    Py_INCREF(value);\r
-    return value;\r
-}\r
-\r
-static int\r
-teedataobject_traverse(teedataobject *tdo, visitproc visit, void * arg)\r
-{\r
-    int i;\r
-    Py_VISIT(tdo->it);\r
-    for (i = 0; i < tdo->numread; i++)\r
-        Py_VISIT(tdo->values[i]);\r
-    Py_VISIT(tdo->nextlink);\r
-    return 0;\r
-}\r
-\r
-static void\r
-teedataobject_safe_decref(PyObject *obj)\r
-{\r
-    while (obj && Py_TYPE(obj) == &teedataobject_type &&\r
-           Py_REFCNT(obj) == 1) {\r
-        PyObject *nextlink = ((teedataobject *)obj)->nextlink;\r
-        ((teedataobject *)obj)->nextlink = NULL;\r
-        Py_DECREF(obj);\r
-        obj = nextlink;\r
-    }\r
-    Py_XDECREF(obj);\r
-}\r
-\r
-static int\r
-teedataobject_clear(teedataobject *tdo)\r
-{\r
-    int i;\r
-    PyObject *tmp;\r
-\r
-    Py_CLEAR(tdo->it);\r
-    for (i=0 ; i<tdo->numread ; i++)\r
-        Py_CLEAR(tdo->values[i]);\r
-    tmp = tdo->nextlink;\r
-    tdo->nextlink = NULL;\r
-    teedataobject_safe_decref(tmp);\r
-    return 0;\r
-}\r
-\r
-static void\r
-teedataobject_dealloc(teedataobject *tdo)\r
-{\r
-    PyObject_GC_UnTrack(tdo);\r
-    teedataobject_clear(tdo);\r
-    PyObject_GC_Del(tdo);\r
-}\r
-\r
-PyDoc_STRVAR(teedataobject_doc, "Data container common to multiple tee objects.");\r
-\r
-static PyTypeObject teedataobject_type = {\r
-    PyVarObject_HEAD_INIT(0, 0)         /* Must fill in type value later */\r
-    "itertools.tee_dataobject",                 /* tp_name */\r
-    sizeof(teedataobject),                      /* tp_basicsize */\r
-    0,                                          /* tp_itemsize */\r
-    /* methods */\r
-    (destructor)teedataobject_dealloc,          /* tp_dealloc */\r
-    0,                                          /* tp_print */\r
-    0,                                          /* tp_getattr */\r
-    0,                                          /* tp_setattr */\r
-    0,                                          /* tp_compare */\r
-    0,                                          /* tp_repr */\r
-    0,                                          /* tp_as_number */\r
-    0,                                          /* tp_as_sequence */\r
-    0,                                          /* tp_as_mapping */\r
-    0,                                          /* tp_hash */\r
-    0,                                          /* tp_call */\r
-    0,                                          /* tp_str */\r
-    PyObject_GenericGetAttr,                    /* tp_getattro */\r
-    0,                                          /* tp_setattro */\r
-    0,                                          /* tp_as_buffer */\r
-    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,            /* tp_flags */\r
-    teedataobject_doc,                          /* tp_doc */\r
-    (traverseproc)teedataobject_traverse,       /* tp_traverse */\r
-    (inquiry)teedataobject_clear,               /* tp_clear */\r
-    0,                                          /* tp_richcompare */\r
-    0,                                          /* tp_weaklistoffset */\r
-    0,                                          /* tp_iter */\r
-    0,                                          /* tp_iternext */\r
-    0,                                          /* tp_methods */\r
-    0,                                          /* tp_members */\r
-    0,                                          /* tp_getset */\r
-    0,                                          /* tp_base */\r
-    0,                                          /* tp_dict */\r
-    0,                                          /* tp_descr_get */\r
-    0,                                          /* tp_descr_set */\r
-    0,                                          /* tp_dictoffset */\r
-    0,                                          /* tp_init */\r
-    0,                                          /* tp_alloc */\r
-    0,                                          /* tp_new */\r
-    PyObject_GC_Del,                            /* tp_free */\r
-};\r
-\r
-\r
-static PyTypeObject tee_type;\r
-\r
-static PyObject *\r
-tee_next(teeobject *to)\r
-{\r
-    PyObject *value, *link;\r
-\r
-    if (to->index >= LINKCELLS) {\r
-        link = teedataobject_jumplink(to->dataobj);\r
-        if (link == NULL)\r
-            return NULL;\r
-        Py_DECREF(to->dataobj);\r
-        to->dataobj = (teedataobject *)link;\r
-        to->index = 0;\r
-    }\r
-    value = teedataobject_getitem(to->dataobj, to->index);\r
-    if (value == NULL)\r
-        return NULL;\r
-    to->index++;\r
-    return value;\r
-}\r
-\r
-static int\r
-tee_traverse(teeobject *to, visitproc visit, void *arg)\r
-{\r
-    Py_VISIT((PyObject *)to->dataobj);\r
-    return 0;\r
-}\r
-\r
-static PyObject *\r
-tee_copy(teeobject *to)\r
-{\r
-    teeobject *newto;\r
-\r
-    newto = PyObject_GC_New(teeobject, &tee_type);\r
-    if (newto == NULL)\r
-        return NULL;\r
-    Py_INCREF(to->dataobj);\r
-    newto->dataobj = to->dataobj;\r
-    newto->index = to->index;\r
-    newto->weakreflist = NULL;\r
-    PyObject_GC_Track(newto);\r
-    return (PyObject *)newto;\r
-}\r
-\r
-PyDoc_STRVAR(teecopy_doc, "Returns an independent iterator.");\r
-\r
-static PyObject *\r
-tee_fromiterable(PyObject *iterable)\r
-{\r
-    teeobject *to;\r
-    PyObject *it = NULL;\r
-\r
-    it = PyObject_GetIter(iterable);\r
-    if (it == NULL)\r
-        return NULL;\r
-    if (PyObject_TypeCheck(it, &tee_type)) {\r
-        to = (teeobject *)tee_copy((teeobject *)it);\r
-        goto done;\r
-    }\r
-\r
-    to = PyObject_GC_New(teeobject, &tee_type);\r
-    if (to == NULL)\r
-        goto done;\r
-    to->dataobj = (teedataobject *)teedataobject_new(it);\r
-    if (!to->dataobj) {\r
-        PyObject_GC_Del(to);\r
-        to = NULL;\r
-        goto done;\r
-    }\r
-\r
-    to->index = 0;\r
-    to->weakreflist = NULL;\r
-    PyObject_GC_Track(to);\r
-done:\r
-    Py_XDECREF(it);\r
-    return (PyObject *)to;\r
-}\r
-\r
-static PyObject *\r
-tee_new(PyTypeObject *type, PyObject *args, PyObject *kw)\r
-{\r
-    PyObject *iterable;\r
-\r
-    if (!PyArg_UnpackTuple(args, "tee", 1, 1, &iterable))\r
-        return NULL;\r
-    return tee_fromiterable(iterable);\r
-}\r
-\r
-static int\r
-tee_clear(teeobject *to)\r
-{\r
-    if (to->weakreflist != NULL)\r
-        PyObject_ClearWeakRefs((PyObject *) to);\r
-    Py_CLEAR(to->dataobj);\r
-    return 0;\r
-}\r
-\r
-static void\r
-tee_dealloc(teeobject *to)\r
-{\r
-    PyObject_GC_UnTrack(to);\r
-    tee_clear(to);\r
-    PyObject_GC_Del(to);\r
-}\r
-\r
-PyDoc_STRVAR(teeobject_doc,\r
-"Iterator wrapped to make it copyable");\r
-\r
-static PyMethodDef tee_methods[] = {\r
-    {"__copy__",        (PyCFunction)tee_copy,  METH_NOARGS, teecopy_doc},\r
-    {NULL,              NULL}           /* sentinel */\r
-};\r
-\r
-static PyTypeObject tee_type = {\r
-    PyVarObject_HEAD_INIT(NULL, 0)\r
-    "itertools.tee",                    /* tp_name */\r
-    sizeof(teeobject),                  /* tp_basicsize */\r
-    0,                                  /* tp_itemsize */\r
-    /* methods */\r
-    (destructor)tee_dealloc,            /* tp_dealloc */\r
-    0,                                  /* tp_print */\r
-    0,                                  /* tp_getattr */\r
-    0,                                  /* tp_setattr */\r
-    0,                                  /* tp_compare */\r
-    0,                                  /* tp_repr */\r
-    0,                                  /* tp_as_number */\r
-    0,                                  /* tp_as_sequence */\r
-    0,                                  /* tp_as_mapping */\r
-    0,                                  /* tp_hash */\r
-    0,                                  /* tp_call */\r
-    0,                                  /* tp_str */\r
-    0,                                  /* tp_getattro */\r
-    0,                                  /* tp_setattro */\r
-    0,                                  /* tp_as_buffer */\r
-    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,            /* tp_flags */\r
-    teeobject_doc,                      /* tp_doc */\r
-    (traverseproc)tee_traverse,         /* tp_traverse */\r
-    (inquiry)tee_clear,                 /* tp_clear */\r
-    0,                                  /* tp_richcompare */\r
-    offsetof(teeobject, weakreflist),           /* tp_weaklistoffset */\r
-    PyObject_SelfIter,                  /* tp_iter */\r
-    (iternextfunc)tee_next,             /* tp_iternext */\r
-    tee_methods,                        /* tp_methods */\r
-    0,                                  /* tp_members */\r
-    0,                                  /* tp_getset */\r
-    0,                                  /* tp_base */\r
-    0,                                  /* tp_dict */\r
-    0,                                  /* tp_descr_get */\r
-    0,                                  /* tp_descr_set */\r
-    0,                                  /* tp_dictoffset */\r
-    0,                                  /* tp_init */\r
-    0,                                  /* tp_alloc */\r
-    tee_new,                            /* tp_new */\r
-    PyObject_GC_Del,                    /* tp_free */\r
-};\r
-\r
-static PyObject *\r
-tee(PyObject *self, PyObject *args)\r
-{\r
-    Py_ssize_t i, n=2;\r
-    PyObject *it, *iterable, *copyable, *result;\r
-\r
-    if (!PyArg_ParseTuple(args, "O|n", &iterable, &n))\r
-        return NULL;\r
-    if (n < 0) {\r
-        PyErr_SetString(PyExc_ValueError, "n must be >= 0");\r
-        return NULL;\r
-    }\r
-    result = PyTuple_New(n);\r
-    if (result == NULL)\r
-        return NULL;\r
-    if (n == 0)\r
-        return result;\r
-    it = PyObject_GetIter(iterable);\r
-    if (it == NULL) {\r
-        Py_DECREF(result);\r
-        return NULL;\r
-    }\r
-    if (!PyObject_HasAttrString(it, "__copy__")) {\r
-        copyable = tee_fromiterable(it);\r
-        Py_DECREF(it);\r
-        if (copyable == NULL) {\r
-            Py_DECREF(result);\r
-            return NULL;\r
-        }\r
-    } else\r
-        copyable = it;\r
-    PyTuple_SET_ITEM(result, 0, copyable);\r
-    for (i=1 ; i<n ; i++) {\r
-        copyable = PyObject_CallMethod(copyable, "__copy__", NULL);\r
-        if (copyable == NULL) {\r
-            Py_DECREF(result);\r
-            return NULL;\r
-        }\r
-        PyTuple_SET_ITEM(result, i, copyable);\r
-    }\r
-    return result;\r
-}\r
-\r
-PyDoc_STRVAR(tee_doc,\r
-"tee(iterable, n=2) --> tuple of n independent iterators.");\r
-\r
-\r
-/* cycle object **********************************************************/\r
-\r
-typedef struct {\r
-    PyObject_HEAD\r
-    PyObject *it;\r
-    PyObject *saved;\r
-    int firstpass;\r
-} cycleobject;\r
-\r
-static PyTypeObject cycle_type;\r
-\r
-static PyObject *\r
-cycle_new(PyTypeObject *type, PyObject *args, PyObject *kwds)\r
-{\r
-    PyObject *it;\r
-    PyObject *iterable;\r
-    PyObject *saved;\r
-    cycleobject *lz;\r
-\r
-    if (type == &cycle_type && !_PyArg_NoKeywords("cycle()", kwds))\r
-        return NULL;\r
-\r
-    if (!PyArg_UnpackTuple(args, "cycle", 1, 1, &iterable))\r
-        return NULL;\r
-\r
-    /* Get iterator. */\r
-    it = PyObject_GetIter(iterable);\r
-    if (it == NULL)\r
-        return NULL;\r
-\r
-    saved = PyList_New(0);\r
-    if (saved == NULL) {\r
-        Py_DECREF(it);\r
-        return NULL;\r
-    }\r
-\r
-    /* create cycleobject structure */\r
-    lz = (cycleobject *)type->tp_alloc(type, 0);\r
-    if (lz == NULL) {\r
-        Py_DECREF(it);\r
-        Py_DECREF(saved);\r
-        return NULL;\r
-    }\r
-    lz->it = it;\r
-    lz->saved = saved;\r
-    lz->firstpass = 0;\r
-\r
-    return (PyObject *)lz;\r
-}\r
-\r
-static void\r
-cycle_dealloc(cycleobject *lz)\r
-{\r
-    PyObject_GC_UnTrack(lz);\r
-    Py_XDECREF(lz->saved);\r
-    Py_XDECREF(lz->it);\r
-    Py_TYPE(lz)->tp_free(lz);\r
-}\r
-\r
-static int\r
-cycle_traverse(cycleobject *lz, visitproc visit, void *arg)\r
-{\r
-    Py_VISIT(lz->it);\r
-    Py_VISIT(lz->saved);\r
-    return 0;\r
-}\r
-\r
-static PyObject *\r
-cycle_next(cycleobject *lz)\r
-{\r
-    PyObject *item;\r
-    PyObject *it;\r
-    PyObject *tmp;\r
-\r
-    while (1) {\r
-        item = PyIter_Next(lz->it);\r
-        if (item != NULL) {\r
-            if (!lz->firstpass && PyList_Append(lz->saved, item)) {\r
-                Py_DECREF(item);\r
-                return NULL;\r
-            }\r
-            return item;\r
-        }\r
-        if (PyErr_Occurred()) {\r
-            if (PyErr_ExceptionMatches(PyExc_StopIteration))\r
-                PyErr_Clear();\r
-            else\r
-                return NULL;\r
-        }\r
-        if (PyList_Size(lz->saved) == 0)\r
-            return NULL;\r
-        it = PyObject_GetIter(lz->saved);\r
-        if (it == NULL)\r
-            return NULL;\r
-        tmp = lz->it;\r
-        lz->it = it;\r
-        lz->firstpass = 1;\r
-        Py_DECREF(tmp);\r
-    }\r
-}\r
-\r
-PyDoc_STRVAR(cycle_doc,\r
-"cycle(iterable) --> cycle object\n\\r
-\n\\r
-Return elements from the iterable until it is exhausted.\n\\r
-Then repeat the sequence indefinitely.");\r
-\r
-static PyTypeObject cycle_type = {\r
-    PyVarObject_HEAD_INIT(NULL, 0)\r
-    "itertools.cycle",                  /* tp_name */\r
-    sizeof(cycleobject),                /* tp_basicsize */\r
-    0,                                  /* tp_itemsize */\r
-    /* methods */\r
-    (destructor)cycle_dealloc,          /* tp_dealloc */\r
-    0,                                  /* tp_print */\r
-    0,                                  /* tp_getattr */\r
-    0,                                  /* tp_setattr */\r
-    0,                                  /* tp_compare */\r
-    0,                                  /* tp_repr */\r
-    0,                                  /* tp_as_number */\r
-    0,                                  /* tp_as_sequence */\r
-    0,                                  /* tp_as_mapping */\r
-    0,                                  /* tp_hash */\r
-    0,                                  /* tp_call */\r
-    0,                                  /* tp_str */\r
-    PyObject_GenericGetAttr,            /* tp_getattro */\r
-    0,                                  /* tp_setattro */\r
-    0,                                  /* tp_as_buffer */\r
-    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |\r
-        Py_TPFLAGS_BASETYPE,            /* tp_flags */\r
-    cycle_doc,                          /* tp_doc */\r
-    (traverseproc)cycle_traverse,       /* tp_traverse */\r
-    0,                                  /* tp_clear */\r
-    0,                                  /* tp_richcompare */\r
-    0,                                  /* tp_weaklistoffset */\r
-    PyObject_SelfIter,                  /* tp_iter */\r
-    (iternextfunc)cycle_next,           /* tp_iternext */\r
-    0,                                  /* tp_methods */\r
-    0,                                  /* tp_members */\r
-    0,                                  /* tp_getset */\r
-    0,                                  /* tp_base */\r
-    0,                                  /* tp_dict */\r
-    0,                                  /* tp_descr_get */\r
-    0,                                  /* tp_descr_set */\r
-    0,                                  /* tp_dictoffset */\r
-    0,                                  /* tp_init */\r
-    0,                                  /* tp_alloc */\r
-    cycle_new,                          /* tp_new */\r
-    PyObject_GC_Del,                    /* tp_free */\r
-};\r
-\r
-\r
-/* dropwhile object **********************************************************/\r
-\r
-typedef struct {\r
-    PyObject_HEAD\r
-    PyObject *func;\r
-    PyObject *it;\r
-    long         start;\r
-} dropwhileobject;\r
-\r
-static PyTypeObject dropwhile_type;\r
-\r
-static PyObject *\r
-dropwhile_new(PyTypeObject *type, PyObject *args, PyObject *kwds)\r
-{\r
-    PyObject *func, *seq;\r
-    PyObject *it;\r
-    dropwhileobject *lz;\r
-\r
-    if (type == &dropwhile_type && !_PyArg_NoKeywords("dropwhile()", kwds))\r
-        return NULL;\r
-\r
-    if (!PyArg_UnpackTuple(args, "dropwhile", 2, 2, &func, &seq))\r
-        return NULL;\r
-\r
-    /* Get iterator. */\r
-    it = PyObject_GetIter(seq);\r
-    if (it == NULL)\r
-        return NULL;\r
-\r
-    /* create dropwhileobject structure */\r
-    lz = (dropwhileobject *)type->tp_alloc(type, 0);\r
-    if (lz == NULL) {\r
-        Py_DECREF(it);\r
-        return NULL;\r
-    }\r
-    Py_INCREF(func);\r
-    lz->func = func;\r
-    lz->it = it;\r
-    lz->start = 0;\r
-\r
-    return (PyObject *)lz;\r
-}\r
-\r
-static void\r
-dropwhile_dealloc(dropwhileobject *lz)\r
-{\r
-    PyObject_GC_UnTrack(lz);\r
-    Py_XDECREF(lz->func);\r
-    Py_XDECREF(lz->it);\r
-    Py_TYPE(lz)->tp_free(lz);\r
-}\r
-\r
-static int\r
-dropwhile_traverse(dropwhileobject *lz, visitproc visit, void *arg)\r
-{\r
-    Py_VISIT(lz->it);\r
-    Py_VISIT(lz->func);\r
-    return 0;\r
-}\r
-\r
-static PyObject *\r
-dropwhile_next(dropwhileobject *lz)\r
-{\r
-    PyObject *item, *good;\r
-    PyObject *it = lz->it;\r
-    long ok;\r
-    PyObject *(*iternext)(PyObject *);\r
-\r
-    iternext = *Py_TYPE(it)->tp_iternext;\r
-    for (;;) {\r
-        item = iternext(it);\r
-        if (item == NULL)\r
-            return NULL;\r
-        if (lz->start == 1)\r
-            return item;\r
-\r
-        good = PyObject_CallFunctionObjArgs(lz->func, item, NULL);\r
-        if (good == NULL) {\r
-            Py_DECREF(item);\r
-            return NULL;\r
-        }\r
-        ok = PyObject_IsTrue(good);\r
-        Py_DECREF(good);\r
-        if (ok == 0) {\r
-            lz->start = 1;\r
-            return item;\r
-        }\r
-        Py_DECREF(item);\r
-        if (ok < 0)\r
-            return NULL;\r
-    }\r
-}\r
-\r
-PyDoc_STRVAR(dropwhile_doc,\r
-"dropwhile(predicate, iterable) --> dropwhile object\n\\r
-\n\\r
-Drop items from the iterable while predicate(item) is true.\n\\r
-Afterwards, return every element until the iterable is exhausted.");\r
-\r
-static PyTypeObject dropwhile_type = {\r
-    PyVarObject_HEAD_INIT(NULL, 0)\r
-    "itertools.dropwhile",              /* tp_name */\r
-    sizeof(dropwhileobject),            /* tp_basicsize */\r
-    0,                                  /* tp_itemsize */\r
-    /* methods */\r
-    (destructor)dropwhile_dealloc,      /* tp_dealloc */\r
-    0,                                  /* tp_print */\r
-    0,                                  /* tp_getattr */\r
-    0,                                  /* tp_setattr */\r
-    0,                                  /* tp_compare */\r
-    0,                                  /* tp_repr */\r
-    0,                                  /* tp_as_number */\r
-    0,                                  /* tp_as_sequence */\r
-    0,                                  /* tp_as_mapping */\r
-    0,                                  /* tp_hash */\r
-    0,                                  /* tp_call */\r
-    0,                                  /* tp_str */\r
-    PyObject_GenericGetAttr,            /* tp_getattro */\r
-    0,                                  /* tp_setattro */\r
-    0,                                  /* tp_as_buffer */\r
-    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |\r
-        Py_TPFLAGS_BASETYPE,            /* tp_flags */\r
-    dropwhile_doc,                      /* tp_doc */\r
-    (traverseproc)dropwhile_traverse,    /* tp_traverse */\r
-    0,                                  /* tp_clear */\r
-    0,                                  /* tp_richcompare */\r
-    0,                                  /* tp_weaklistoffset */\r
-    PyObject_SelfIter,                  /* tp_iter */\r
-    (iternextfunc)dropwhile_next,       /* tp_iternext */\r
-    0,                                  /* tp_methods */\r
-    0,                                  /* tp_members */\r
-    0,                                  /* tp_getset */\r
-    0,                                  /* tp_base */\r
-    0,                                  /* tp_dict */\r
-    0,                                  /* tp_descr_get */\r
-    0,                                  /* tp_descr_set */\r
-    0,                                  /* tp_dictoffset */\r
-    0,                                  /* tp_init */\r
-    0,                                  /* tp_alloc */\r
-    dropwhile_new,                      /* tp_new */\r
-    PyObject_GC_Del,                    /* tp_free */\r
-};\r
-\r
-\r
-/* takewhile object **********************************************************/\r
-\r
-typedef struct {\r
-    PyObject_HEAD\r
-    PyObject *func;\r
-    PyObject *it;\r
-    long         stop;\r
-} takewhileobject;\r
-\r
-static PyTypeObject takewhile_type;\r
-\r
-static PyObject *\r
-takewhile_new(PyTypeObject *type, PyObject *args, PyObject *kwds)\r
-{\r
-    PyObject *func, *seq;\r
-    PyObject *it;\r
-    takewhileobject *lz;\r
-\r
-    if (type == &takewhile_type && !_PyArg_NoKeywords("takewhile()", kwds))\r
-        return NULL;\r
-\r
-    if (!PyArg_UnpackTuple(args, "takewhile", 2, 2, &func, &seq))\r
-        return NULL;\r
-\r
-    /* Get iterator. */\r
-    it = PyObject_GetIter(seq);\r
-    if (it == NULL)\r
-        return NULL;\r
-\r
-    /* create takewhileobject structure */\r
-    lz = (takewhileobject *)type->tp_alloc(type, 0);\r
-    if (lz == NULL) {\r
-        Py_DECREF(it);\r
-        return NULL;\r
-    }\r
-    Py_INCREF(func);\r
-    lz->func = func;\r
-    lz->it = it;\r
-    lz->stop = 0;\r
-\r
-    return (PyObject *)lz;\r
-}\r
-\r
-static void\r
-takewhile_dealloc(takewhileobject *lz)\r
-{\r
-    PyObject_GC_UnTrack(lz);\r
-    Py_XDECREF(lz->func);\r
-    Py_XDECREF(lz->it);\r
-    Py_TYPE(lz)->tp_free(lz);\r
-}\r
-\r
-static int\r
-takewhile_traverse(takewhileobject *lz, visitproc visit, void *arg)\r
-{\r
-    Py_VISIT(lz->it);\r
-    Py_VISIT(lz->func);\r
-    return 0;\r
-}\r
-\r
-static PyObject *\r
-takewhile_next(takewhileobject *lz)\r
-{\r
-    PyObject *item, *good;\r
-    PyObject *it = lz->it;\r
-    long ok;\r
-\r
-    if (lz->stop == 1)\r
-        return NULL;\r
-\r
-    item = (*Py_TYPE(it)->tp_iternext)(it);\r
-    if (item == NULL)\r
-        return NULL;\r
-\r
-    good = PyObject_CallFunctionObjArgs(lz->func, item, NULL);\r
-    if (good == NULL) {\r
-        Py_DECREF(item);\r
-        return NULL;\r
-    }\r
-    ok = PyObject_IsTrue(good);\r
-    Py_DECREF(good);\r
-    if (ok > 0)\r
-        return item;\r
-    Py_DECREF(item);\r
-    if (ok == 0)\r
-        lz->stop = 1;\r
-    return NULL;\r
-}\r
-\r
-PyDoc_STRVAR(takewhile_doc,\r
-"takewhile(predicate, iterable) --> takewhile object\n\\r
-\n\\r
-Return successive entries from an iterable as long as the \n\\r
-predicate evaluates to true for each entry.");\r
-\r
-static PyTypeObject takewhile_type = {\r
-    PyVarObject_HEAD_INIT(NULL, 0)\r
-    "itertools.takewhile",              /* tp_name */\r
-    sizeof(takewhileobject),            /* tp_basicsize */\r
-    0,                                  /* tp_itemsize */\r
-    /* methods */\r
-    (destructor)takewhile_dealloc,      /* tp_dealloc */\r
-    0,                                  /* tp_print */\r
-    0,                                  /* tp_getattr */\r
-    0,                                  /* tp_setattr */\r
-    0,                                  /* tp_compare */\r
-    0,                                  /* tp_repr */\r
-    0,                                  /* tp_as_number */\r
-    0,                                  /* tp_as_sequence */\r
-    0,                                  /* tp_as_mapping */\r
-    0,                                  /* tp_hash */\r
-    0,                                  /* tp_call */\r
-    0,                                  /* tp_str */\r
-    PyObject_GenericGetAttr,            /* tp_getattro */\r
-    0,                                  /* tp_setattro */\r
-    0,                                  /* tp_as_buffer */\r
-    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |\r
-        Py_TPFLAGS_BASETYPE,            /* tp_flags */\r
-    takewhile_doc,                      /* tp_doc */\r
-    (traverseproc)takewhile_traverse,    /* tp_traverse */\r
-    0,                                  /* tp_clear */\r
-    0,                                  /* tp_richcompare */\r
-    0,                                  /* tp_weaklistoffset */\r
-    PyObject_SelfIter,                  /* tp_iter */\r
-    (iternextfunc)takewhile_next,       /* tp_iternext */\r
-    0,                                  /* tp_methods */\r
-    0,                                  /* tp_members */\r
-    0,                                  /* tp_getset */\r
-    0,                                  /* tp_base */\r
-    0,                                  /* tp_dict */\r
-    0,                                  /* tp_descr_get */\r
-    0,                                  /* tp_descr_set */\r
-    0,                                  /* tp_dictoffset */\r
-    0,                                  /* tp_init */\r
-    0,                                  /* tp_alloc */\r
-    takewhile_new,                      /* tp_new */\r
-    PyObject_GC_Del,                    /* tp_free */\r
-};\r
-\r
-\r
-/* islice object ************************************************************/\r
-\r
-typedef struct {\r
-    PyObject_HEAD\r
-    PyObject *it;\r
-    Py_ssize_t next;\r
-    Py_ssize_t stop;\r
-    Py_ssize_t step;\r
-    Py_ssize_t cnt;\r
-} isliceobject;\r
-\r
-static PyTypeObject islice_type;\r
-\r
-static PyObject *\r
-islice_new(PyTypeObject *type, PyObject *args, PyObject *kwds)\r
-{\r
-    PyObject *seq;\r
-    Py_ssize_t start=0, stop=-1, step=1;\r
-    PyObject *it, *a1=NULL, *a2=NULL, *a3=NULL;\r
-    Py_ssize_t numargs;\r
-    isliceobject *lz;\r
-\r
-    if (type == &islice_type && !_PyArg_NoKeywords("islice()", kwds))\r
-        return NULL;\r
-\r
-    if (!PyArg_UnpackTuple(args, "islice", 2, 4, &seq, &a1, &a2, &a3))\r
-        return NULL;\r
-\r
-    numargs = PyTuple_Size(args);\r
-    if (numargs == 2) {\r
-        if (a1 != Py_None) {\r
-            stop = PyInt_AsSsize_t(a1);\r
-            if (stop == -1) {\r
-                if (PyErr_Occurred())\r
-                    PyErr_Clear();\r
-                PyErr_SetString(PyExc_ValueError,\r
-                    "Stop argument for islice() must be None or an integer: 0 <= x <= maxint.");\r
-                return NULL;\r
-            }\r
-        }\r
-    } else {\r
-        if (a1 != Py_None)\r
-            start = PyInt_AsSsize_t(a1);\r
-        if (start == -1 && PyErr_Occurred())\r
-            PyErr_Clear();\r
-        if (a2 != Py_None) {\r
-            stop = PyInt_AsSsize_t(a2);\r
-            if (stop == -1) {\r
-                if (PyErr_Occurred())\r
-                    PyErr_Clear();\r
-                PyErr_SetString(PyExc_ValueError,\r
-                   "Stop argument for islice() must be None or an integer: 0 <= x <= maxint.");\r
-                return NULL;\r
-            }\r
-        }\r
-    }\r
-    if (start<0 || stop<-1) {\r
-        PyErr_SetString(PyExc_ValueError,\r
-           "Indices for islice() must be None or an integer: 0 <= x <= maxint.");\r
-        return NULL;\r
-    }\r
-\r
-    if (a3 != NULL) {\r
-        if (a3 != Py_None)\r
-            step = PyInt_AsSsize_t(a3);\r
-        if (step == -1 && PyErr_Occurred())\r
-            PyErr_Clear();\r
-    }\r
-    if (step<1) {\r
-        PyErr_SetString(PyExc_ValueError,\r
-           "Step for islice() must be a positive integer or None.");\r
-        return NULL;\r
-    }\r
-\r
-    /* Get iterator. */\r
-    it = PyObject_GetIter(seq);\r
-    if (it == NULL)\r
-        return NULL;\r
-\r
-    /* create isliceobject structure */\r
-    lz = (isliceobject *)type->tp_alloc(type, 0);\r
-    if (lz == NULL) {\r
-        Py_DECREF(it);\r
-        return NULL;\r
-    }\r
-    lz->it = it;\r
-    lz->next = start;\r
-    lz->stop = stop;\r
-    lz->step = step;\r
-    lz->cnt = 0L;\r
-\r
-    return (PyObject *)lz;\r
-}\r
-\r
-static void\r
-islice_dealloc(isliceobject *lz)\r
-{\r
-    PyObject_GC_UnTrack(lz);\r
-    Py_XDECREF(lz->it);\r
-    Py_TYPE(lz)->tp_free(lz);\r
-}\r
-\r
-static int\r
-islice_traverse(isliceobject *lz, visitproc visit, void *arg)\r
-{\r
-    Py_VISIT(lz->it);\r
-    return 0;\r
-}\r
-\r
-static PyObject *\r
-islice_next(isliceobject *lz)\r
-{\r
-    PyObject *item;\r
-    PyObject *it = lz->it;\r
-    Py_ssize_t stop = lz->stop;\r
-    Py_ssize_t oldnext;\r
-    PyObject *(*iternext)(PyObject *);\r
-\r
-    if (it == NULL)\r
-        return NULL;\r
-\r
-    iternext = *Py_TYPE(it)->tp_iternext;\r
-    while (lz->cnt < lz->next) {\r
-        item = iternext(it);\r
-        if (item == NULL)\r
-            goto empty;\r
-        Py_DECREF(item);\r
-        lz->cnt++;\r
-    }\r
-    if (stop != -1 && lz->cnt >= stop)\r
-        goto empty;\r
-    item = iternext(it);\r
-    if (item == NULL)\r
-        goto empty;\r
-    lz->cnt++;\r
-    oldnext = lz->next;\r
-    /* The (size_t) cast below avoids the danger of undefined\r
-       behaviour from signed integer overflow. */\r
-    lz->next += (size_t)lz->step;\r
-    if (lz->next < oldnext || (stop != -1 && lz->next > stop))\r
-        lz->next = stop;\r
-    return item;\r
-\r
-empty:\r
-    Py_CLEAR(lz->it);\r
-    return NULL;\r
-}\r
-\r
-PyDoc_STRVAR(islice_doc,\r
-"islice(iterable, [start,] stop [, step]) --> islice object\n\\r
-\n\\r
-Return an iterator whose next() method returns selected values from an\n\\r
-iterable.  If start is specified, will skip all preceding elements;\n\\r
-otherwise, start defaults to zero.  Step defaults to one.  If\n\\r
-specified as another value, step determines how many values are \n\\r
-skipped between successive calls.  Works like a slice() on a list\n\\r
-but returns an iterator.");\r
-\r
-static PyTypeObject islice_type = {\r
-    PyVarObject_HEAD_INIT(NULL, 0)\r
-    "itertools.islice",                 /* tp_name */\r
-    sizeof(isliceobject),               /* tp_basicsize */\r
-    0,                                  /* tp_itemsize */\r
-    /* methods */\r
-    (destructor)islice_dealloc,         /* tp_dealloc */\r
-    0,                                  /* tp_print */\r
-    0,                                  /* tp_getattr */\r
-    0,                                  /* tp_setattr */\r
-    0,                                  /* tp_compare */\r
-    0,                                  /* tp_repr */\r
-    0,                                  /* tp_as_number */\r
-    0,                                  /* tp_as_sequence */\r
-    0,                                  /* tp_as_mapping */\r
-    0,                                  /* tp_hash */\r
-    0,                                  /* tp_call */\r
-    0,                                  /* tp_str */\r
-    PyObject_GenericGetAttr,            /* tp_getattro */\r
-    0,                                  /* tp_setattro */\r
-    0,                                  /* tp_as_buffer */\r
-    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |\r
-        Py_TPFLAGS_BASETYPE,            /* tp_flags */\r
-    islice_doc,                         /* tp_doc */\r
-    (traverseproc)islice_traverse,      /* tp_traverse */\r
-    0,                                  /* tp_clear */\r
-    0,                                  /* tp_richcompare */\r
-    0,                                  /* tp_weaklistoffset */\r
-    PyObject_SelfIter,                  /* tp_iter */\r
-    (iternextfunc)islice_next,          /* tp_iternext */\r
-    0,                                  /* tp_methods */\r
-    0,                                  /* tp_members */\r
-    0,                                  /* tp_getset */\r
-    0,                                  /* tp_base */\r
-    0,                                  /* tp_dict */\r
-    0,                                  /* tp_descr_get */\r
-    0,                                  /* tp_descr_set */\r
-    0,                                  /* tp_dictoffset */\r
-    0,                                  /* tp_init */\r
-    0,                                  /* tp_alloc */\r
-    islice_new,                         /* tp_new */\r
-    PyObject_GC_Del,                    /* tp_free */\r
-};\r
-\r
-\r
-/* starmap object ************************************************************/\r
-\r
-typedef struct {\r
-    PyObject_HEAD\r
-    PyObject *func;\r
-    PyObject *it;\r
-} starmapobject;\r
-\r
-static PyTypeObject starmap_type;\r
-\r
-static PyObject *\r
-starmap_new(PyTypeObject *type, PyObject *args, PyObject *kwds)\r
-{\r
-    PyObject *func, *seq;\r
-    PyObject *it;\r
-    starmapobject *lz;\r
-\r
-    if (type == &starmap_type && !_PyArg_NoKeywords("starmap()", kwds))\r
-        return NULL;\r
-\r
-    if (!PyArg_UnpackTuple(args, "starmap", 2, 2, &func, &seq))\r
-        return NULL;\r
-\r
-    /* Get iterator. */\r
-    it = PyObject_GetIter(seq);\r
-    if (it == NULL)\r
-        return NULL;\r
-\r
-    /* create starmapobject structure */\r
-    lz = (starmapobject *)type->tp_alloc(type, 0);\r
-    if (lz == NULL) {\r
-        Py_DECREF(it);\r
-        return NULL;\r
-    }\r
-    Py_INCREF(func);\r
-    lz->func = func;\r
-    lz->it = it;\r
-\r
-    return (PyObject *)lz;\r
-}\r
-\r
-static void\r
-starmap_dealloc(starmapobject *lz)\r
-{\r
-    PyObject_GC_UnTrack(lz);\r
-    Py_XDECREF(lz->func);\r
-    Py_XDECREF(lz->it);\r
-    Py_TYPE(lz)->tp_free(lz);\r
-}\r
-\r
-static int\r
-starmap_traverse(starmapobject *lz, visitproc visit, void *arg)\r
-{\r
-    Py_VISIT(lz->it);\r
-    Py_VISIT(lz->func);\r
-    return 0;\r
-}\r
-\r
-static PyObject *\r
-starmap_next(starmapobject *lz)\r
-{\r
-    PyObject *args;\r
-    PyObject *result;\r
-    PyObject *it = lz->it;\r
-\r
-    args = (*Py_TYPE(it)->tp_iternext)(it);\r
-    if (args == NULL)\r
-        return NULL;\r
-    if (!PyTuple_CheckExact(args)) {\r
-        PyObject *newargs = PySequence_Tuple(args);\r
-        Py_DECREF(args);\r
-        if (newargs == NULL)\r
-            return NULL;\r
-        args = newargs;\r
-    }\r
-    result = PyObject_Call(lz->func, args, NULL);\r
-    Py_DECREF(args);\r
-    return result;\r
-}\r
-\r
-PyDoc_STRVAR(starmap_doc,\r
-"starmap(function, sequence) --> starmap object\n\\r
-\n\\r
-Return an iterator whose values are returned from the function evaluated\n\\r
-with a argument tuple taken from the given sequence.");\r
-\r
-static PyTypeObject starmap_type = {\r
-    PyVarObject_HEAD_INIT(NULL, 0)\r
-    "itertools.starmap",                /* tp_name */\r
-    sizeof(starmapobject),              /* tp_basicsize */\r
-    0,                                  /* tp_itemsize */\r
-    /* methods */\r
-    (destructor)starmap_dealloc,        /* tp_dealloc */\r
-    0,                                  /* tp_print */\r
-    0,                                  /* tp_getattr */\r
-    0,                                  /* tp_setattr */\r
-    0,                                  /* tp_compare */\r
-    0,                                  /* tp_repr */\r
-    0,                                  /* tp_as_number */\r
-    0,                                  /* tp_as_sequence */\r
-    0,                                  /* tp_as_mapping */\r
-    0,                                  /* tp_hash */\r
-    0,                                  /* tp_call */\r
-    0,                                  /* tp_str */\r
-    PyObject_GenericGetAttr,            /* tp_getattro */\r
-    0,                                  /* tp_setattro */\r
-    0,                                  /* tp_as_buffer */\r
-    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |\r
-        Py_TPFLAGS_BASETYPE,            /* tp_flags */\r
-    starmap_doc,                        /* tp_doc */\r
-    (traverseproc)starmap_traverse,     /* tp_traverse */\r
-    0,                                  /* tp_clear */\r
-    0,                                  /* tp_richcompare */\r
-    0,                                  /* tp_weaklistoffset */\r
-    PyObject_SelfIter,                  /* tp_iter */\r
-    (iternextfunc)starmap_next,         /* tp_iternext */\r
-    0,                                  /* tp_methods */\r
-    0,                                  /* tp_members */\r
-    0,                                  /* tp_getset */\r
-    0,                                  /* tp_base */\r
-    0,                                  /* tp_dict */\r
-    0,                                  /* tp_descr_get */\r
-    0,                                  /* tp_descr_set */\r
-    0,                                  /* tp_dictoffset */\r
-    0,                                  /* tp_init */\r
-    0,                                  /* tp_alloc */\r
-    starmap_new,                        /* tp_new */\r
-    PyObject_GC_Del,                    /* tp_free */\r
-};\r
-\r
-\r
-/* imap object ************************************************************/\r
-\r
-typedef struct {\r
-    PyObject_HEAD\r
-    PyObject *iters;\r
-    PyObject *func;\r
-} imapobject;\r
-\r
-static PyTypeObject imap_type;\r
-\r
-static PyObject *\r
-imap_new(PyTypeObject *type, PyObject *args, PyObject *kwds)\r
-{\r
-    PyObject *it, *iters, *func;\r
-    imapobject *lz;\r
-    Py_ssize_t numargs, i;\r
-\r
-    if (type == &imap_type && !_PyArg_NoKeywords("imap()", kwds))\r
-        return NULL;\r
-\r
-    numargs = PyTuple_Size(args);\r
-    if (numargs < 2) {\r
-        PyErr_SetString(PyExc_TypeError,\r
-           "imap() must have at least two arguments.");\r
-        return NULL;\r
-    }\r
-\r
-    iters = PyTuple_New(numargs-1);\r
-    if (iters == NULL)\r
-        return NULL;\r
-\r
-    for (i=1 ; i<numargs ; i++) {\r
-        /* Get iterator. */\r
-        it = PyObject_GetIter(PyTuple_GET_ITEM(args, i));\r
-        if (it == NULL) {\r
-            Py_DECREF(iters);\r
-            return NULL;\r
-        }\r
-        PyTuple_SET_ITEM(iters, i-1, it);\r
-    }\r
-\r
-    /* create imapobject structure */\r
-    lz = (imapobject *)type->tp_alloc(type, 0);\r
-    if (lz == NULL) {\r
-        Py_DECREF(iters);\r
-        return NULL;\r
-    }\r
-    lz->iters = iters;\r
-    func = PyTuple_GET_ITEM(args, 0);\r
-    Py_INCREF(func);\r
-    lz->func = func;\r
-\r
-    return (PyObject *)lz;\r
-}\r
-\r
-static void\r
-imap_dealloc(imapobject *lz)\r
-{\r
-    PyObject_GC_UnTrack(lz);\r
-    Py_XDECREF(lz->iters);\r
-    Py_XDECREF(lz->func);\r
-    Py_TYPE(lz)->tp_free(lz);\r
-}\r
-\r
-static int\r
-imap_traverse(imapobject *lz, visitproc visit, void *arg)\r
-{\r
-    Py_VISIT(lz->iters);\r
-    Py_VISIT(lz->func);\r
-    return 0;\r
-}\r
-\r
-/*\r
-imap() is an iterator version of __builtins__.map() except that it does\r
-not have the None fill-in feature.  That was intentionally left out for\r
-the following reasons:\r
-\r
-  1) Itertools are designed to be easily combined and chained together.\r
-     Having all tools stop with the shortest input is a unifying principle\r
-     that makes it easier to combine finite iterators (supplying data) with\r
-     infinite iterators like count() and repeat() (for supplying sequential\r
-     or constant arguments to a function).\r
-\r
-  2) In typical use cases for combining itertools, having one finite data\r
-     supplier run out before another is likely to be an error condition which\r
-     should not pass silently by automatically supplying None.\r
-\r
-  3) The use cases for automatic None fill-in are rare -- not many functions\r
-     do something useful when a parameter suddenly switches type and becomes\r
-     None.\r
-\r
-  4) If a need does arise, it can be met by __builtins__.map() or by\r
-     writing:  chain(iterable, repeat(None)).\r
-\r
-  5) Similar toolsets in Haskell and SML do not have automatic None fill-in.\r
-*/\r
-\r
-static PyObject *\r
-imap_next(imapobject *lz)\r
-{\r
-    PyObject *val;\r
-    PyObject *argtuple;\r
-    PyObject *result;\r
-    Py_ssize_t numargs, i;\r
-\r
-    numargs = PyTuple_Size(lz->iters);\r
-    argtuple = PyTuple_New(numargs);\r
-    if (argtuple == NULL)\r
-        return NULL;\r
-\r
-    for (i=0 ; i<numargs ; i++) {\r
-        val = PyIter_Next(PyTuple_GET_ITEM(lz->iters, i));\r
-        if (val == NULL) {\r
-            Py_DECREF(argtuple);\r
-            return NULL;\r
-        }\r
-        PyTuple_SET_ITEM(argtuple, i, val);\r
-    }\r
-    if (lz->func == Py_None)\r
-        return argtuple;\r
-    result = PyObject_Call(lz->func, argtuple, NULL);\r
-    Py_DECREF(argtuple);\r
-    return result;\r
-}\r
-\r
-PyDoc_STRVAR(imap_doc,\r
-"imap(func, *iterables) --> imap object\n\\r
-\n\\r
-Make an iterator that computes the function using arguments from\n\\r
-each of the iterables.  Like map() except that it returns\n\\r
-an iterator instead of a list and that it stops when the shortest\n\\r
-iterable is exhausted instead of filling in None for shorter\n\\r
-iterables.");\r
-\r
-static PyTypeObject imap_type = {\r
-    PyVarObject_HEAD_INIT(NULL, 0)\r
-    "itertools.imap",                   /* tp_name */\r
-    sizeof(imapobject),                 /* tp_basicsize */\r
-    0,                                  /* tp_itemsize */\r
-    /* methods */\r
-    (destructor)imap_dealloc,           /* tp_dealloc */\r
-    0,                                  /* tp_print */\r
-    0,                                  /* tp_getattr */\r
-    0,                                  /* tp_setattr */\r
-    0,                                  /* tp_compare */\r
-    0,                                  /* tp_repr */\r
-    0,                                  /* tp_as_number */\r
-    0,                                  /* tp_as_sequence */\r
-    0,                                  /* tp_as_mapping */\r
-    0,                                  /* tp_hash */\r
-    0,                                  /* tp_call */\r
-    0,                                  /* tp_str */\r
-    PyObject_GenericGetAttr,            /* tp_getattro */\r
-    0,                                  /* tp_setattro */\r
-    0,                                  /* tp_as_buffer */\r
-    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |\r
-        Py_TPFLAGS_BASETYPE,            /* tp_flags */\r
-    imap_doc,                           /* tp_doc */\r
-    (traverseproc)imap_traverse,        /* tp_traverse */\r
-    0,                                  /* tp_clear */\r
-    0,                                  /* tp_richcompare */\r
-    0,                                  /* tp_weaklistoffset */\r
-    PyObject_SelfIter,                  /* tp_iter */\r
-    (iternextfunc)imap_next,            /* tp_iternext */\r
-    0,                                  /* tp_methods */\r
-    0,                                  /* tp_members */\r
-    0,                                  /* tp_getset */\r
-    0,                                  /* tp_base */\r
-    0,                                  /* tp_dict */\r
-    0,                                  /* tp_descr_get */\r
-    0,                                  /* tp_descr_set */\r
-    0,                                  /* tp_dictoffset */\r
-    0,                                  /* tp_init */\r
-    0,                                  /* tp_alloc */\r
-    imap_new,                           /* tp_new */\r
-    PyObject_GC_Del,                    /* tp_free */\r
-};\r
-\r
-\r
-/* chain object ************************************************************/\r
-\r
-typedef struct {\r
-    PyObject_HEAD\r
-    PyObject *source;                   /* Iterator over input iterables */\r
-    PyObject *active;                   /* Currently running input iterator */\r
-} chainobject;\r
-\r
-static PyTypeObject chain_type;\r
-\r
-static PyObject *\r
-chain_new_internal(PyTypeObject *type, PyObject *source)\r
-{\r
-    chainobject *lz;\r
-\r
-    lz = (chainobject *)type->tp_alloc(type, 0);\r
-    if (lz == NULL) {\r
-        Py_DECREF(source);\r
-        return NULL;\r
-    }\r
-\r
-    lz->source = source;\r
-    lz->active = NULL;\r
-    return (PyObject *)lz;\r
-}\r
-\r
-static PyObject *\r
-chain_new(PyTypeObject *type, PyObject *args, PyObject *kwds)\r
-{\r
-    PyObject *source;\r
-\r
-    if (type == &chain_type && !_PyArg_NoKeywords("chain()", kwds))\r
-        return NULL;\r
-\r
-    source = PyObject_GetIter(args);\r
-    if (source == NULL)\r
-        return NULL;\r
-\r
-    return chain_new_internal(type, source);\r
-}\r
-\r
-static PyObject *\r
-chain_new_from_iterable(PyTypeObject *type, PyObject *arg)\r
-{\r
-    PyObject *source;\r
-\r
-    source = PyObject_GetIter(arg);\r
-    if (source == NULL)\r
-        return NULL;\r
-\r
-    return chain_new_internal(type, source);\r
-}\r
-\r
-static void\r
-chain_dealloc(chainobject *lz)\r
-{\r
-    PyObject_GC_UnTrack(lz);\r
-    Py_XDECREF(lz->active);\r
-    Py_XDECREF(lz->source);\r
-    Py_TYPE(lz)->tp_free(lz);\r
-}\r
-\r
-static int\r
-chain_traverse(chainobject *lz, visitproc visit, void *arg)\r
-{\r
-    Py_VISIT(lz->source);\r
-    Py_VISIT(lz->active);\r
-    return 0;\r
-}\r
-\r
-static PyObject *\r
-chain_next(chainobject *lz)\r
-{\r
-    PyObject *item;\r
-\r
-    if (lz->source == NULL)\r
-        return NULL;                                    /* already stopped */\r
-\r
-    if (lz->active == NULL) {\r
-        PyObject *iterable = PyIter_Next(lz->source);\r
-        if (iterable == NULL) {\r
-            Py_CLEAR(lz->source);\r
-            return NULL;                                /* no more input sources */\r
-        }\r
-        lz->active = PyObject_GetIter(iterable);\r
-        Py_DECREF(iterable);\r
-        if (lz->active == NULL) {\r
-            Py_CLEAR(lz->source);\r
-            return NULL;                                /* input not iterable */\r
-        }\r
-    }\r
-    item = PyIter_Next(lz->active);\r
-    if (item != NULL)\r
-        return item;\r
-    if (PyErr_Occurred()) {\r
-        if (PyErr_ExceptionMatches(PyExc_StopIteration))\r
-            PyErr_Clear();\r
-        else\r
-            return NULL;                                /* input raised an exception */\r
-    }\r
-    Py_CLEAR(lz->active);\r
-    return chain_next(lz);                      /* recurse and use next active */\r
-}\r
-\r
-PyDoc_STRVAR(chain_doc,\r
-"chain(*iterables) --> chain object\n\\r
-\n\\r
-Return a chain object whose .next() method returns elements from the\n\\r
-first iterable until it is exhausted, then elements from the next\n\\r
-iterable, until all of the iterables are exhausted.");\r
-\r
-PyDoc_STRVAR(chain_from_iterable_doc,\r
-"chain.from_iterable(iterable) --> chain object\n\\r
-\n\\r
-Alternate chain() contructor taking a single iterable argument\n\\r
-that evaluates lazily.");\r
-\r
-static PyMethodDef chain_methods[] = {\r
-    {"from_iterable", (PyCFunction) chain_new_from_iterable,            METH_O | METH_CLASS,\r
-        chain_from_iterable_doc},\r
-    {NULL,              NULL}   /* sentinel */\r
-};\r
-\r
-static PyTypeObject chain_type = {\r
-    PyVarObject_HEAD_INIT(NULL, 0)\r
-    "itertools.chain",                  /* tp_name */\r
-    sizeof(chainobject),                /* tp_basicsize */\r
-    0,                                  /* tp_itemsize */\r
-    /* methods */\r
-    (destructor)chain_dealloc,          /* tp_dealloc */\r
-    0,                                  /* tp_print */\r
-    0,                                  /* tp_getattr */\r
-    0,                                  /* tp_setattr */\r
-    0,                                  /* tp_compare */\r
-    0,                                  /* tp_repr */\r
-    0,                                  /* tp_as_number */\r
-    0,                                  /* tp_as_sequence */\r
-    0,                                  /* tp_as_mapping */\r
-    0,                                  /* tp_hash */\r
-    0,                                  /* tp_call */\r
-    0,                                  /* tp_str */\r
-    PyObject_GenericGetAttr,            /* tp_getattro */\r
-    0,                                  /* tp_setattro */\r
-    0,                                  /* tp_as_buffer */\r
-    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |\r
-        Py_TPFLAGS_BASETYPE,            /* tp_flags */\r
-    chain_doc,                          /* tp_doc */\r
-    (traverseproc)chain_traverse,       /* tp_traverse */\r
-    0,                                  /* tp_clear */\r
-    0,                                  /* tp_richcompare */\r
-    0,                                  /* tp_weaklistoffset */\r
-    PyObject_SelfIter,                  /* tp_iter */\r
-    (iternextfunc)chain_next,           /* tp_iternext */\r
-    chain_methods,                      /* tp_methods */\r
-    0,                                  /* tp_members */\r
-    0,                                  /* tp_getset */\r
-    0,                                  /* tp_base */\r
-    0,                                  /* tp_dict */\r
-    0,                                  /* tp_descr_get */\r
-    0,                                  /* tp_descr_set */\r
-    0,                                  /* tp_dictoffset */\r
-    0,                                  /* tp_init */\r
-    0,                                  /* tp_alloc */\r
-    chain_new,                          /* tp_new */\r
-    PyObject_GC_Del,                    /* tp_free */\r
-};\r
-\r
-\r
-/* product object ************************************************************/\r
-\r
-typedef struct {\r
-    PyObject_HEAD\r
-    PyObject *pools;                    /* tuple of pool tuples */\r
-    Py_ssize_t *indices;            /* one index per pool */\r
-    PyObject *result;               /* most recently returned result tuple */\r
-    int stopped;                    /* set to 1 when the product iterator is exhausted */\r
-} productobject;\r
-\r
-static PyTypeObject product_type;\r
-\r
-static PyObject *\r
-product_new(PyTypeObject *type, PyObject *args, PyObject *kwds)\r
-{\r
-    productobject *lz;\r
-    Py_ssize_t nargs, npools, repeat=1;\r
-    PyObject *pools = NULL;\r
-    Py_ssize_t *indices = NULL;\r
-    Py_ssize_t i;\r
-\r
-    if (kwds != NULL) {\r
-        char *kwlist[] = {"repeat", 0};\r
-        PyObject *tmpargs = PyTuple_New(0);\r
-        if (tmpargs == NULL)\r
-            return NULL;\r
-        if (!PyArg_ParseTupleAndKeywords(tmpargs, kwds, "|n:product", kwlist, &repeat)) {\r
-            Py_DECREF(tmpargs);\r
-            return NULL;\r
-        }\r
-        Py_DECREF(tmpargs);\r
-        if (repeat < 0) {\r
-            PyErr_SetString(PyExc_ValueError,\r
-                            "repeat argument cannot be negative");\r
-            return NULL;\r
-        }\r
-    }\r
-\r
-    assert(PyTuple_CheckExact(args));\r
-    if (repeat == 0) {\r
-        nargs = 0;\r
-    } else {\r
-        nargs = PyTuple_GET_SIZE(args);\r
-        if ((size_t)nargs > PY_SSIZE_T_MAX/sizeof(Py_ssize_t)/repeat) {\r
-            PyErr_SetString(PyExc_OverflowError, "repeat argument too large");\r
-            return NULL;\r
-        }\r
-    }\r
-    npools = nargs * repeat;\r
-\r
-    indices = PyMem_New(Py_ssize_t, npools);\r
-    if (indices == NULL) {\r
-        PyErr_NoMemory();\r
-        goto error;\r
-    }\r
-\r
-    pools = PyTuple_New(npools);\r
-    if (pools == NULL)\r
-        goto error;\r
-\r
-    for (i=0; i < nargs ; ++i) {\r
-        PyObject *item = PyTuple_GET_ITEM(args, i);\r
-        PyObject *pool = PySequence_Tuple(item);\r
-        if (pool == NULL)\r
-            goto error;\r
-        PyTuple_SET_ITEM(pools, i, pool);\r
-        indices[i] = 0;\r
-    }\r
-    for ( ; i < npools; ++i) {\r
-        PyObject *pool = PyTuple_GET_ITEM(pools, i - nargs);\r
-        Py_INCREF(pool);\r
-        PyTuple_SET_ITEM(pools, i, pool);\r
-        indices[i] = 0;\r
-    }\r
-\r
-    /* create productobject structure */\r
-    lz = (productobject *)type->tp_alloc(type, 0);\r
-    if (lz == NULL)\r
-        goto error;\r
-\r
-    lz->pools = pools;\r
-    lz->indices = indices;\r
-    lz->result = NULL;\r
-    lz->stopped = 0;\r
-\r
-    return (PyObject *)lz;\r
-\r
-error:\r
-    if (indices != NULL)\r
-        PyMem_Free(indices);\r
-    Py_XDECREF(pools);\r
-    return NULL;\r
-}\r
-\r
-static void\r
-product_dealloc(productobject *lz)\r
-{\r
-    PyObject_GC_UnTrack(lz);\r
-    Py_XDECREF(lz->pools);\r
-    Py_XDECREF(lz->result);\r
-    if (lz->indices != NULL)\r
-        PyMem_Free(lz->indices);\r
-    Py_TYPE(lz)->tp_free(lz);\r
-}\r
-\r
-static int\r
-product_traverse(productobject *lz, visitproc visit, void *arg)\r
-{\r
-    Py_VISIT(lz->pools);\r
-    Py_VISIT(lz->result);\r
-    return 0;\r
-}\r
-\r
-static PyObject *\r
-product_next(productobject *lz)\r
-{\r
-    PyObject *pool;\r
-    PyObject *elem;\r
-    PyObject *oldelem;\r
-    PyObject *pools = lz->pools;\r
-    PyObject *result = lz->result;\r
-    Py_ssize_t npools = PyTuple_GET_SIZE(pools);\r
-    Py_ssize_t i;\r
-\r
-    if (lz->stopped)\r
-        return NULL;\r
-\r
-    if (result == NULL) {\r
-        /* On the first pass, return an initial tuple filled with the\r
-           first element from each pool. */\r
-        result = PyTuple_New(npools);\r
-        if (result == NULL)\r
-            goto empty;\r
-        lz->result = result;\r
-        for (i=0; i < npools; i++) {\r
-            pool = PyTuple_GET_ITEM(pools, i);\r
-            if (PyTuple_GET_SIZE(pool) == 0)\r
-                goto empty;\r
-            elem = PyTuple_GET_ITEM(pool, 0);\r
-            Py_INCREF(elem);\r
-            PyTuple_SET_ITEM(result, i, elem);\r
-        }\r
-    } else {\r
-        Py_ssize_t *indices = lz->indices;\r
-\r
-        /* Copy the previous result tuple or re-use it if available */\r
-        if (Py_REFCNT(result) > 1) {\r
-            PyObject *old_result = result;\r
-            result = PyTuple_New(npools);\r
-            if (result == NULL)\r
-                goto empty;\r
-            lz->result = result;\r
-            for (i=0; i < npools; i++) {\r
-                elem = PyTuple_GET_ITEM(old_result, i);\r
-                Py_INCREF(elem);\r
-                PyTuple_SET_ITEM(result, i, elem);\r
-            }\r
-            Py_DECREF(old_result);\r
-        }\r
-        /* Now, we've got the only copy so we can update it in-place */\r
-        assert (npools==0 || Py_REFCNT(result) == 1);\r
-\r
-        /* Update the pool indices right-to-left.  Only advance to the\r
-           next pool when the previous one rolls-over */\r
-        for (i=npools-1 ; i >= 0 ; i--) {\r
-            pool = PyTuple_GET_ITEM(pools, i);\r
-            indices[i]++;\r
-            if (indices[i] == PyTuple_GET_SIZE(pool)) {\r
-                /* Roll-over and advance to next pool */\r
-                indices[i] = 0;\r
-                elem = PyTuple_GET_ITEM(pool, 0);\r
-                Py_INCREF(elem);\r
-                oldelem = PyTuple_GET_ITEM(result, i);\r
-                PyTuple_SET_ITEM(result, i, elem);\r
-                Py_DECREF(oldelem);\r
-            } else {\r
-                /* No rollover. Just increment and stop here. */\r
-                elem = PyTuple_GET_ITEM(pool, indices[i]);\r
-                Py_INCREF(elem);\r
-                oldelem = PyTuple_GET_ITEM(result, i);\r
-                PyTuple_SET_ITEM(result, i, elem);\r
-                Py_DECREF(oldelem);\r
-                break;\r
-            }\r
-        }\r
-\r
-        /* If i is negative, then the indices have all rolled-over\r
-           and we're done. */\r
-        if (i < 0)\r
-            goto empty;\r
-    }\r
-\r
-    Py_INCREF(result);\r
-    return result;\r
-\r
-empty:\r
-    lz->stopped = 1;\r
-    return NULL;\r
-}\r
-\r
-PyDoc_STRVAR(product_doc,\r
-"product(*iterables) --> product object\n\\r
-\n\\r
-Cartesian product of input iterables.  Equivalent to nested for-loops.\n\n\\r
-For example, product(A, B) returns the same as:  ((x,y) for x in A for y in B).\n\\r
-The leftmost iterators are in the outermost for-loop, so the output tuples\n\\r
-cycle in a manner similar to an odometer (with the rightmost element changing\n\\r
-on every iteration).\n\n\\r
-To compute the product of an iterable with itself, specify the number\n\\r
-of repetitions with the optional repeat keyword argument. For example,\n\\r
-product(A, repeat=4) means the same as product(A, A, A, A).\n\n\\r
-product('ab', range(3)) --> ('a',0) ('a',1) ('a',2) ('b',0) ('b',1) ('b',2)\n\\r
-product((0,1), (0,1), (0,1)) --> (0,0,0) (0,0,1) (0,1,0) (0,1,1) (1,0,0) ...");\r
-\r
-static PyTypeObject product_type = {\r
-    PyVarObject_HEAD_INIT(NULL, 0)\r
-    "itertools.product",                /* tp_name */\r
-    sizeof(productobject),      /* tp_basicsize */\r
-    0,                                  /* tp_itemsize */\r
-    /* methods */\r
-    (destructor)product_dealloc,        /* tp_dealloc */\r
-    0,                                  /* tp_print */\r
-    0,                                  /* tp_getattr */\r
-    0,                                  /* tp_setattr */\r
-    0,                                  /* tp_compare */\r
-    0,                                  /* tp_repr */\r
-    0,                                  /* tp_as_number */\r
-    0,                                  /* tp_as_sequence */\r
-    0,                                  /* tp_as_mapping */\r
-    0,                                  /* tp_hash */\r
-    0,                                  /* tp_call */\r
-    0,                                  /* tp_str */\r
-    PyObject_GenericGetAttr,            /* tp_getattro */\r
-    0,                                  /* tp_setattro */\r
-    0,                                  /* tp_as_buffer */\r
-    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |\r
-        Py_TPFLAGS_BASETYPE,            /* tp_flags */\r
-    product_doc,                        /* tp_doc */\r
-    (traverseproc)product_traverse,     /* tp_traverse */\r
-    0,                                  /* tp_clear */\r
-    0,                                  /* tp_richcompare */\r
-    0,                                  /* tp_weaklistoffset */\r
-    PyObject_SelfIter,                  /* tp_iter */\r
-    (iternextfunc)product_next,         /* tp_iternext */\r
-    0,                                  /* tp_methods */\r
-    0,                                  /* tp_members */\r
-    0,                                  /* tp_getset */\r
-    0,                                  /* tp_base */\r
-    0,                                  /* tp_dict */\r
-    0,                                  /* tp_descr_get */\r
-    0,                                  /* tp_descr_set */\r
-    0,                                  /* tp_dictoffset */\r
-    0,                                  /* tp_init */\r
-    0,                                  /* tp_alloc */\r
-    product_new,                        /* tp_new */\r
-    PyObject_GC_Del,                    /* tp_free */\r
-};\r
-\r
-\r
-/* combinations object ************************************************************/\r
-\r
-typedef struct {\r
-    PyObject_HEAD\r
-    PyObject *pool;                     /* input converted to a tuple */\r
-    Py_ssize_t *indices;            /* one index per result element */\r
-    PyObject *result;               /* most recently returned result tuple */\r
-    Py_ssize_t r;                       /* size of result tuple */\r
-    int stopped;                        /* set to 1 when the combinations iterator is exhausted */\r
-} combinationsobject;\r
-\r
-static PyTypeObject combinations_type;\r
-\r
-static PyObject *\r
-combinations_new(PyTypeObject *type, PyObject *args, PyObject *kwds)\r
-{\r
-    combinationsobject *co;\r
-    Py_ssize_t n;\r
-    Py_ssize_t r;\r
-    PyObject *pool = NULL;\r
-    PyObject *iterable = NULL;\r
-    Py_ssize_t *indices = NULL;\r
-    Py_ssize_t i;\r
-    static char *kwargs[] = {"iterable", "r", NULL};\r
-\r
-    if (!PyArg_ParseTupleAndKeywords(args, kwds, "On:combinations", kwargs,\r
-                                     &iterable, &r))\r
-        return NULL;\r
-\r
-    pool = PySequence_Tuple(iterable);\r
-    if (pool == NULL)\r
-        goto error;\r
-    n = PyTuple_GET_SIZE(pool);\r
-    if (r < 0) {\r
-        PyErr_SetString(PyExc_ValueError, "r must be non-negative");\r
-        goto error;\r
-    }\r
-\r
-    indices = PyMem_New(Py_ssize_t, r);\r
-    if (indices == NULL) {\r
-        PyErr_NoMemory();\r
-        goto error;\r
-    }\r
-\r
-    for (i=0 ; i<r ; i++)\r
-        indices[i] = i;\r
-\r
-    /* create combinationsobject structure */\r
-    co = (combinationsobject *)type->tp_alloc(type, 0);\r
-    if (co == NULL)\r
-        goto error;\r
-\r
-    co->pool = pool;\r
-    co->indices = indices;\r
-    co->result = NULL;\r
-    co->r = r;\r
-    co->stopped = r > n ? 1 : 0;\r
-\r
-    return (PyObject *)co;\r
-\r
-error:\r
-    if (indices != NULL)\r
-        PyMem_Free(indices);\r
-    Py_XDECREF(pool);\r
-    return NULL;\r
-}\r
-\r
-static void\r
-combinations_dealloc(combinationsobject *co)\r
-{\r
-    PyObject_GC_UnTrack(co);\r
-    Py_XDECREF(co->pool);\r
-    Py_XDECREF(co->result);\r
-    if (co->indices != NULL)\r
-        PyMem_Free(co->indices);\r
-    Py_TYPE(co)->tp_free(co);\r
-}\r
-\r
-static int\r
-combinations_traverse(combinationsobject *co, visitproc visit, void *arg)\r
-{\r
-    Py_VISIT(co->pool);\r
-    Py_VISIT(co->result);\r
-    return 0;\r
-}\r
-\r
-static PyObject *\r
-combinations_next(combinationsobject *co)\r
-{\r
-    PyObject *elem;\r
-    PyObject *oldelem;\r
-    PyObject *pool = co->pool;\r
-    Py_ssize_t *indices = co->indices;\r
-    PyObject *result = co->result;\r
-    Py_ssize_t n = PyTuple_GET_SIZE(pool);\r
-    Py_ssize_t r = co->r;\r
-    Py_ssize_t i, j, index;\r
-\r
-    if (co->stopped)\r
-        return NULL;\r
-\r
-    if (result == NULL) {\r
-        /* On the first pass, initialize result tuple using the indices */\r
-        result = PyTuple_New(r);\r
-        if (result == NULL)\r
-            goto empty;\r
-        co->result = result;\r
-        for (i=0; i<r ; i++) {\r
-            index = indices[i];\r
-            elem = PyTuple_GET_ITEM(pool, index);\r
-            Py_INCREF(elem);\r
-            PyTuple_SET_ITEM(result, i, elem);\r
-        }\r
-    } else {\r
-        /* Copy the previous result tuple or re-use it if available */\r
-        if (Py_REFCNT(result) > 1) {\r
-            PyObject *old_result = result;\r
-            result = PyTuple_New(r);\r
-            if (result == NULL)\r
-                goto empty;\r
-            co->result = result;\r
-            for (i=0; i<r ; i++) {\r
-                elem = PyTuple_GET_ITEM(old_result, i);\r
-                Py_INCREF(elem);\r
-                PyTuple_SET_ITEM(result, i, elem);\r
-            }\r
-            Py_DECREF(old_result);\r
-        }\r
-        /* Now, we've got the only copy so we can update it in-place\r
-         * CPython's empty tuple is a singleton and cached in\r
-         * PyTuple's freelist.\r
-         */\r
-        assert(r == 0 || Py_REFCNT(result) == 1);\r
-\r
-        /* Scan indices right-to-left until finding one that is not\r
-           at its maximum (i + n - r). */\r
-        for (i=r-1 ; i >= 0 && indices[i] == i+n-r ; i--)\r
-            ;\r
-\r
-        /* If i is negative, then the indices are all at\r
-           their maximum value and we're done. */\r
-        if (i < 0)\r
-            goto empty;\r
-\r
-        /* Increment the current index which we know is not at its\r
-           maximum.  Then move back to the right setting each index\r
-           to its lowest possible value (one higher than the index\r
-           to its left -- this maintains the sort order invariant). */\r
-        indices[i]++;\r
-        for (j=i+1 ; j<r ; j++)\r
-            indices[j] = indices[j-1] + 1;\r
-\r
-        /* Update the result tuple for the new indices\r
-           starting with i, the leftmost index that changed */\r
-        for ( ; i<r ; i++) {\r
-            index = indices[i];\r
-            elem = PyTuple_GET_ITEM(pool, index);\r
-            Py_INCREF(elem);\r
-            oldelem = PyTuple_GET_ITEM(result, i);\r
-            PyTuple_SET_ITEM(result, i, elem);\r
-            Py_DECREF(oldelem);\r
-        }\r
-    }\r
-\r
-    Py_INCREF(result);\r
-    return result;\r
-\r
-empty:\r
-    co->stopped = 1;\r
-    return NULL;\r
-}\r
-\r
-PyDoc_STRVAR(combinations_doc,\r
-"combinations(iterable, r) --> combinations object\n\\r
-\n\\r
-Return successive r-length combinations of elements in the iterable.\n\n\\r
-combinations(range(4), 3) --> (0,1,2), (0,1,3), (0,2,3), (1,2,3)");\r
-\r
-static PyTypeObject combinations_type = {\r
-    PyVarObject_HEAD_INIT(NULL, 0)\r
-    "itertools.combinations",                   /* tp_name */\r
-    sizeof(combinationsobject),         /* tp_basicsize */\r
-    0,                                  /* tp_itemsize */\r
-    /* methods */\r
-    (destructor)combinations_dealloc,           /* tp_dealloc */\r
-    0,                                  /* tp_print */\r
-    0,                                  /* tp_getattr */\r
-    0,                                  /* tp_setattr */\r
-    0,                                  /* tp_compare */\r
-    0,                                  /* tp_repr */\r
-    0,                                  /* tp_as_number */\r
-    0,                                  /* tp_as_sequence */\r
-    0,                                  /* tp_as_mapping */\r
-    0,                                  /* tp_hash */\r
-    0,                                  /* tp_call */\r
-    0,                                  /* tp_str */\r
-    PyObject_GenericGetAttr,            /* tp_getattro */\r
-    0,                                  /* tp_setattro */\r
-    0,                                  /* tp_as_buffer */\r
-    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |\r
-        Py_TPFLAGS_BASETYPE,            /* tp_flags */\r
-    combinations_doc,                           /* tp_doc */\r
-    (traverseproc)combinations_traverse,        /* tp_traverse */\r
-    0,                                  /* tp_clear */\r
-    0,                                  /* tp_richcompare */\r
-    0,                                  /* tp_weaklistoffset */\r
-    PyObject_SelfIter,                  /* tp_iter */\r
-    (iternextfunc)combinations_next,            /* tp_iternext */\r
-    0,                                  /* tp_methods */\r
-    0,                                  /* tp_members */\r
-    0,                                  /* tp_getset */\r
-    0,                                  /* tp_base */\r
-    0,                                  /* tp_dict */\r
-    0,                                  /* tp_descr_get */\r
-    0,                                  /* tp_descr_set */\r
-    0,                                  /* tp_dictoffset */\r
-    0,                                  /* tp_init */\r
-    0,                                  /* tp_alloc */\r
-    combinations_new,                           /* tp_new */\r
-    PyObject_GC_Del,                    /* tp_free */\r
-};\r
-\r
-\r
-/* combinations with replacement object *******************************************/\r
-\r
-/* Equivalent to:\r
-\r
-        def combinations_with_replacement(iterable, r):\r
-            "combinations_with_replacement('ABC', 2) --> AA AB AC BB BC CC"\r
-            # number items returned:  (n+r-1)! / r! / (n-1)!\r
-            pool = tuple(iterable)\r
-            n = len(pool)\r
-            indices = [0] * r\r
-            yield tuple(pool[i] for i in indices)\r
-            while 1:\r
-                for i in reversed(range(r)):\r
-                    if indices[i] != n - 1:\r
-                        break\r
-                else:\r
-                    return\r
-                indices[i:] = [indices[i] + 1] * (r - i)\r
-                yield tuple(pool[i] for i in indices)\r
-\r
-        def combinations_with_replacement2(iterable, r):\r
-            'Alternate version that filters from product()'\r
-            pool = tuple(iterable)\r
-            n = len(pool)\r
-            for indices in product(range(n), repeat=r):\r
-                if sorted(indices) == list(indices):\r
-                    yield tuple(pool[i] for i in indices)\r
-*/\r
-typedef struct {\r
-    PyObject_HEAD\r
-    PyObject *pool;                     /* input converted to a tuple */\r
-    Py_ssize_t *indices;    /* one index per result element */\r
-    PyObject *result;       /* most recently returned result tuple */\r
-    Py_ssize_t r;                       /* size of result tuple */\r
-    int stopped;                        /* set to 1 when the cwr iterator is exhausted */\r
-} cwrobject;\r
-\r
-static PyTypeObject cwr_type;\r
-\r
-static PyObject *\r
-cwr_new(PyTypeObject *type, PyObject *args, PyObject *kwds)\r
-{\r
-    cwrobject *co;\r
-    Py_ssize_t n;\r
-    Py_ssize_t r;\r
-    PyObject *pool = NULL;\r
-    PyObject *iterable = NULL;\r
-    Py_ssize_t *indices = NULL;\r
-    Py_ssize_t i;\r
-    static char *kwargs[] = {"iterable", "r", NULL};\r
-\r
-    if (!PyArg_ParseTupleAndKeywords(args, kwds, "On:combinations_with_replacement", kwargs,\r
-                                     &iterable, &r))\r
-        return NULL;\r
-\r
-    pool = PySequence_Tuple(iterable);\r
-    if (pool == NULL)\r
-        goto error;\r
-    n = PyTuple_GET_SIZE(pool);\r
-    if (r < 0) {\r
-        PyErr_SetString(PyExc_ValueError, "r must be non-negative");\r
-        goto error;\r
-    }\r
-\r
-    indices = PyMem_New(Py_ssize_t, r);\r
-    if (indices == NULL) {\r
-        PyErr_NoMemory();\r
-        goto error;\r
-    }\r
-\r
-    for (i=0 ; i<r ; i++)\r
-        indices[i] = 0;\r
-\r
-    /* create cwrobject structure */\r
-    co = (cwrobject *)type->tp_alloc(type, 0);\r
-    if (co == NULL)\r
-        goto error;\r
-\r
-    co->pool = pool;\r
-    co->indices = indices;\r
-    co->result = NULL;\r
-    co->r = r;\r
-    co->stopped = !n && r;\r
-\r
-    return (PyObject *)co;\r
-\r
-error:\r
-    if (indices != NULL)\r
-        PyMem_Free(indices);\r
-    Py_XDECREF(pool);\r
-    return NULL;\r
-}\r
-\r
-static void\r
-cwr_dealloc(cwrobject *co)\r
-{\r
-    PyObject_GC_UnTrack(co);\r
-    Py_XDECREF(co->pool);\r
-    Py_XDECREF(co->result);\r
-    if (co->indices != NULL)\r
-        PyMem_Free(co->indices);\r
-    Py_TYPE(co)->tp_free(co);\r
-}\r
-\r
-static int\r
-cwr_traverse(cwrobject *co, visitproc visit, void *arg)\r
-{\r
-    Py_VISIT(co->pool);\r
-    Py_VISIT(co->result);\r
-    return 0;\r
-}\r
-\r
-static PyObject *\r
-cwr_next(cwrobject *co)\r
-{\r
-    PyObject *elem;\r
-    PyObject *oldelem;\r
-    PyObject *pool = co->pool;\r
-    Py_ssize_t *indices = co->indices;\r
-    PyObject *result = co->result;\r
-    Py_ssize_t n = PyTuple_GET_SIZE(pool);\r
-    Py_ssize_t r = co->r;\r
-    Py_ssize_t i, j, index;\r
-\r
-    if (co->stopped)\r
-        return NULL;\r
-\r
-    if (result == NULL) {\r
-        /* On the first pass, initialize result tuple using the indices */\r
-        result = PyTuple_New(r);\r
-        if (result == NULL)\r
-            goto empty;\r
-        co->result = result;\r
-        for (i=0; i<r ; i++) {\r
-            index = indices[i];\r
-            elem = PyTuple_GET_ITEM(pool, index);\r
-            Py_INCREF(elem);\r
-            PyTuple_SET_ITEM(result, i, elem);\r
-        }\r
-    } else {\r
-        /* Copy the previous result tuple or re-use it if available */\r
-        if (Py_REFCNT(result) > 1) {\r
-            PyObject *old_result = result;\r
-            result = PyTuple_New(r);\r
-            if (result == NULL)\r
-                goto empty;\r
-            co->result = result;\r
-            for (i=0; i<r ; i++) {\r
-                elem = PyTuple_GET_ITEM(old_result, i);\r
-                Py_INCREF(elem);\r
-                PyTuple_SET_ITEM(result, i, elem);\r
-            }\r
-            Py_DECREF(old_result);\r
-        }\r
-        /* Now, we've got the only copy so we can update it in-place CPython's\r
-           empty tuple is a singleton and cached in PyTuple's freelist. */\r
-        assert(r == 0 || Py_REFCNT(result) == 1);\r
-\r
-    /* Scan indices right-to-left until finding one that is not\r
-     * at its maximum (n-1). */\r
-        for (i=r-1 ; i >= 0 && indices[i] == n-1; i--)\r
-            ;\r
-\r
-        /* If i is negative, then the indices are all at\r
-       their maximum value and we're done. */\r
-        if (i < 0)\r
-            goto empty;\r
-\r
-        /* Increment the current index which we know is not at its\r
-       maximum.  Then set all to the right to the same value. */\r
-        indices[i]++;\r
-        for (j=i+1 ; j<r ; j++)\r
-            indices[j] = indices[j-1];\r
-\r
-        /* Update the result tuple for the new indices\r
-           starting with i, the leftmost index that changed */\r
-        for ( ; i<r ; i++) {\r
-            index = indices[i];\r
-            elem = PyTuple_GET_ITEM(pool, index);\r
-            Py_INCREF(elem);\r
-            oldelem = PyTuple_GET_ITEM(result, i);\r
-            PyTuple_SET_ITEM(result, i, elem);\r
-            Py_DECREF(oldelem);\r
-        }\r
-    }\r
-\r
-    Py_INCREF(result);\r
-    return result;\r
-\r
-empty:\r
-    co->stopped = 1;\r
-    return NULL;\r
-}\r
-\r
-PyDoc_STRVAR(cwr_doc,\r
-"combinations_with_replacement(iterable, r) --> combinations_with_replacement object\n\\r
-\n\\r
-Return successive r-length combinations of elements in the iterable\n\\r
-allowing individual elements to have successive repeats.\n\\r
-combinations_with_replacement('ABC', 2) --> AA AB AC BB BC CC");\r
-\r
-static PyTypeObject cwr_type = {\r
-    PyVarObject_HEAD_INIT(NULL, 0)\r
-    "itertools.combinations_with_replacement",                  /* tp_name */\r
-    sizeof(cwrobject),                  /* tp_basicsize */\r
-    0,                                                  /* tp_itemsize */\r
-    /* methods */\r
-    (destructor)cwr_dealloc,            /* tp_dealloc */\r
-    0,                                                  /* tp_print */\r
-    0,                                                  /* tp_getattr */\r
-    0,                                                  /* tp_setattr */\r
-    0,                                                  /* tp_compare */\r
-    0,                                                  /* tp_repr */\r
-    0,                                                  /* tp_as_number */\r
-    0,                                                  /* tp_as_sequence */\r
-    0,                                                  /* tp_as_mapping */\r
-    0,                                                  /* tp_hash */\r
-    0,                                                  /* tp_call */\r
-    0,                                                  /* tp_str */\r
-    PyObject_GenericGetAttr,            /* tp_getattro */\r
-    0,                                                  /* tp_setattro */\r
-    0,                                                  /* tp_as_buffer */\r
-    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |\r
-        Py_TPFLAGS_BASETYPE,            /* tp_flags */\r
-    cwr_doc,                                    /* tp_doc */\r
-    (traverseproc)cwr_traverse,         /* tp_traverse */\r
-    0,                                                  /* tp_clear */\r
-    0,                                                  /* tp_richcompare */\r
-    0,                                                  /* tp_weaklistoffset */\r
-    PyObject_SelfIter,                  /* tp_iter */\r
-    (iternextfunc)cwr_next,     /* tp_iternext */\r
-    0,                                                  /* tp_methods */\r
-    0,                                                  /* tp_members */\r
-    0,                                                  /* tp_getset */\r
-    0,                                                  /* tp_base */\r
-    0,                                                  /* tp_dict */\r
-    0,                                                  /* tp_descr_get */\r
-    0,                                                  /* tp_descr_set */\r
-    0,                                                  /* tp_dictoffset */\r
-    0,                                                  /* tp_init */\r
-    0,                                                  /* tp_alloc */\r
-    cwr_new,                                    /* tp_new */\r
-    PyObject_GC_Del,                    /* tp_free */\r
-};\r
-\r
-\r
-/* permutations object ************************************************************\r
-\r
-def permutations(iterable, r=None):\r
-    'permutations(range(3), 2) --> (0,1) (0,2) (1,0) (1,2) (2,0) (2,1)'\r
-    pool = tuple(iterable)\r
-    n = len(pool)\r
-    r = n if r is None else r\r
-    indices = range(n)\r
-    cycles = range(n-r+1, n+1)[::-1]\r
-    yield tuple(pool[i] for i in indices[:r])\r
-    while n:\r
-    for i in reversed(range(r)):\r
-        cycles[i] -= 1\r
-        if cycles[i] == 0:\r
-        indices[i:] = indices[i+1:] + indices[i:i+1]\r
-        cycles[i] = n - i\r
-        else:\r
-        j = cycles[i]\r
-        indices[i], indices[-j] = indices[-j], indices[i]\r
-        yield tuple(pool[i] for i in indices[:r])\r
-        break\r
-    else:\r
-        return\r
-*/\r
-\r
-typedef struct {\r
-    PyObject_HEAD\r
-    PyObject *pool;                     /* input converted to a tuple */\r
-    Py_ssize_t *indices;            /* one index per element in the pool */\r
-    Py_ssize_t *cycles;                 /* one rollover counter per element in the result */\r
-    PyObject *result;               /* most recently returned result tuple */\r
-    Py_ssize_t r;                       /* size of result tuple */\r
-    int stopped;                        /* set to 1 when the permutations iterator is exhausted */\r
-} permutationsobject;\r
-\r
-static PyTypeObject permutations_type;\r
-\r
-static PyObject *\r
-permutations_new(PyTypeObject *type, PyObject *args, PyObject *kwds)\r
-{\r
-    permutationsobject *po;\r
-    Py_ssize_t n;\r
-    Py_ssize_t r;\r
-    PyObject *robj = Py_None;\r
-    PyObject *pool = NULL;\r
-    PyObject *iterable = NULL;\r
-    Py_ssize_t *indices = NULL;\r
-    Py_ssize_t *cycles = NULL;\r
-    Py_ssize_t i;\r
-    static char *kwargs[] = {"iterable", "r", NULL};\r
-\r
-    if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|O:permutations", kwargs,\r
-                                     &iterable, &robj))\r
-        return NULL;\r
-\r
-    pool = PySequence_Tuple(iterable);\r
-    if (pool == NULL)\r
-        goto error;\r
-    n = PyTuple_GET_SIZE(pool);\r
-\r
-    r = n;\r
-    if (robj != Py_None) {\r
-        r = PyInt_AsSsize_t(robj);\r
-        if (r == -1 && PyErr_Occurred())\r
-            goto error;\r
-    }\r
-    if (r < 0) {\r
-        PyErr_SetString(PyExc_ValueError, "r must be non-negative");\r
-        goto error;\r
-    }\r
-\r
-    indices = PyMem_New(Py_ssize_t, n);\r
-    cycles = PyMem_New(Py_ssize_t, r);\r
-    if (indices == NULL || cycles == NULL) {\r
-        PyErr_NoMemory();\r
-        goto error;\r
-    }\r
-\r
-    for (i=0 ; i<n ; i++)\r
-        indices[i] = i;\r
-    for (i=0 ; i<r ; i++)\r
-        cycles[i] = n - i;\r
-\r
-    /* create permutationsobject structure */\r
-    po = (permutationsobject *)type->tp_alloc(type, 0);\r
-    if (po == NULL)\r
-        goto error;\r
-\r
-    po->pool = pool;\r
-    po->indices = indices;\r
-    po->cycles = cycles;\r
-    po->result = NULL;\r
-    po->r = r;\r
-    po->stopped = r > n ? 1 : 0;\r
-\r
-    return (PyObject *)po;\r
-\r
-error:\r
-    if (indices != NULL)\r
-        PyMem_Free(indices);\r
-    if (cycles != NULL)\r
-        PyMem_Free(cycles);\r
-    Py_XDECREF(pool);\r
-    return NULL;\r
-}\r
-\r
-static void\r
-permutations_dealloc(permutationsobject *po)\r
-{\r
-    PyObject_GC_UnTrack(po);\r
-    Py_XDECREF(po->pool);\r
-    Py_XDECREF(po->result);\r
-    PyMem_Free(po->indices);\r
-    PyMem_Free(po->cycles);\r
-    Py_TYPE(po)->tp_free(po);\r
-}\r
-\r
-static int\r
-permutations_traverse(permutationsobject *po, visitproc visit, void *arg)\r
-{\r
-    Py_VISIT(po->pool);\r
-    Py_VISIT(po->result);\r
-    return 0;\r
-}\r
-\r
-static PyObject *\r
-permutations_next(permutationsobject *po)\r
-{\r
-    PyObject *elem;\r
-    PyObject *oldelem;\r
-    PyObject *pool = po->pool;\r
-    Py_ssize_t *indices = po->indices;\r
-    Py_ssize_t *cycles = po->cycles;\r
-    PyObject *result = po->result;\r
-    Py_ssize_t n = PyTuple_GET_SIZE(pool);\r
-    Py_ssize_t r = po->r;\r
-    Py_ssize_t i, j, k, index;\r
-\r
-    if (po->stopped)\r
-        return NULL;\r
-\r
-    if (result == NULL) {\r
-        /* On the first pass, initialize result tuple using the indices */\r
-        result = PyTuple_New(r);\r
-        if (result == NULL)\r
-            goto empty;\r
-        po->result = result;\r
-        for (i=0; i<r ; i++) {\r
-            index = indices[i];\r
-            elem = PyTuple_GET_ITEM(pool, index);\r
-            Py_INCREF(elem);\r
-            PyTuple_SET_ITEM(result, i, elem);\r
-        }\r
-    } else {\r
-        if (n == 0)\r
-            goto empty;\r
-\r
-        /* Copy the previous result tuple or re-use it if available */\r
-        if (Py_REFCNT(result) > 1) {\r
-            PyObject *old_result = result;\r
-            result = PyTuple_New(r);\r
-            if (result == NULL)\r
-                goto empty;\r
-            po->result = result;\r
-            for (i=0; i<r ; i++) {\r
-                elem = PyTuple_GET_ITEM(old_result, i);\r
-                Py_INCREF(elem);\r
-                PyTuple_SET_ITEM(result, i, elem);\r
-            }\r
-            Py_DECREF(old_result);\r
-        }\r
-        /* Now, we've got the only copy so we can update it in-place */\r
-        assert(r == 0 || Py_REFCNT(result) == 1);\r
-\r
-        /* Decrement rightmost cycle, moving leftward upon zero rollover */\r
-        for (i=r-1 ; i>=0 ; i--) {\r
-            cycles[i] -= 1;\r
-            if (cycles[i] == 0) {\r
-                /* rotatation: indices[i:] = indices[i+1:] + indices[i:i+1] */\r
-                index = indices[i];\r
-                for (j=i ; j<n-1 ; j++)\r
-                    indices[j] = indices[j+1];\r
-                indices[n-1] = index;\r
-                cycles[i] = n - i;\r
-            } else {\r
-                j = cycles[i];\r
-                index = indices[i];\r
-                indices[i] = indices[n-j];\r
-                indices[n-j] = index;\r
-\r
-                for (k=i; k<r ; k++) {\r
-                    /* start with i, the leftmost element that changed */\r
-                    /* yield tuple(pool[k] for k in indices[:r]) */\r
-                    index = indices[k];\r
-                    elem = PyTuple_GET_ITEM(pool, index);\r
-                    Py_INCREF(elem);\r
-                    oldelem = PyTuple_GET_ITEM(result, k);\r
-                    PyTuple_SET_ITEM(result, k, elem);\r
-                    Py_DECREF(oldelem);\r
-                }\r
-                break;\r
-            }\r
-        }\r
-        /* If i is negative, then the cycles have all\r
-           rolled-over and we're done. */\r
-        if (i < 0)\r
-            goto empty;\r
-    }\r
-    Py_INCREF(result);\r
-    return result;\r
-\r
-empty:\r
-    po->stopped = 1;\r
-    return NULL;\r
-}\r
-\r
-PyDoc_STRVAR(permutations_doc,\r
-"permutations(iterable[, r]) --> permutations object\n\\r
-\n\\r
-Return successive r-length permutations of elements in the iterable.\n\n\\r
-permutations(range(3), 2) --> (0,1), (0,2), (1,0), (1,2), (2,0), (2,1)");\r
-\r
-static PyTypeObject permutations_type = {\r
-    PyVarObject_HEAD_INIT(NULL, 0)\r
-    "itertools.permutations",                   /* tp_name */\r
-    sizeof(permutationsobject),         /* tp_basicsize */\r
-    0,                                  /* tp_itemsize */\r
-    /* methods */\r
-    (destructor)permutations_dealloc,           /* tp_dealloc */\r
-    0,                                  /* tp_print */\r
-    0,                                  /* tp_getattr */\r
-    0,                                  /* tp_setattr */\r
-    0,                                  /* tp_compare */\r
-    0,                                  /* tp_repr */\r
-    0,                                  /* tp_as_number */\r
-    0,                                  /* tp_as_sequence */\r
-    0,                                  /* tp_as_mapping */\r
-    0,                                  /* tp_hash */\r
-    0,                                  /* tp_call */\r
-    0,                                  /* tp_str */\r
-    PyObject_GenericGetAttr,            /* tp_getattro */\r
-    0,                                  /* tp_setattro */\r
-    0,                                  /* tp_as_buffer */\r
-    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |\r
-        Py_TPFLAGS_BASETYPE,            /* tp_flags */\r
-    permutations_doc,                           /* tp_doc */\r
-    (traverseproc)permutations_traverse,        /* tp_traverse */\r
-    0,                                  /* tp_clear */\r
-    0,                                  /* tp_richcompare */\r
-    0,                                  /* tp_weaklistoffset */\r
-    PyObject_SelfIter,                  /* tp_iter */\r
-    (iternextfunc)permutations_next,            /* tp_iternext */\r
-    0,                                  /* tp_methods */\r
-    0,                                  /* tp_members */\r
-    0,                                  /* tp_getset */\r
-    0,                                  /* tp_base */\r
-    0,                                  /* tp_dict */\r
-    0,                                  /* tp_descr_get */\r
-    0,                                  /* tp_descr_set */\r
-    0,                                  /* tp_dictoffset */\r
-    0,                                  /* tp_init */\r
-    0,                                  /* tp_alloc */\r
-    permutations_new,                           /* tp_new */\r
-    PyObject_GC_Del,                    /* tp_free */\r
-};\r
-\r
-\r
-/* compress object ************************************************************/\r
-\r
-/* Equivalent to:\r
-\r
-    def compress(data, selectors):\r
-        "compress('ABCDEF', [1,0,1,0,1,1]) --> A C E F"\r
-        return (d for d, s in izip(data, selectors) if s)\r
-*/\r
-\r
-typedef struct {\r
-    PyObject_HEAD\r
-    PyObject *data;\r
-    PyObject *selectors;\r
-} compressobject;\r
-\r
-static PyTypeObject compress_type;\r
-\r
-static PyObject *\r
-compress_new(PyTypeObject *type, PyObject *args, PyObject *kwds)\r
-{\r
-    PyObject *seq1, *seq2;\r
-    PyObject *data=NULL, *selectors=NULL;\r
-    compressobject *lz;\r
-    static char *kwargs[] = {"data", "selectors", NULL};\r
-\r
-    if (!PyArg_ParseTupleAndKeywords(args, kwds, "OO:compress", kwargs, &seq1, &seq2))\r
-        return NULL;\r
-\r
-    data = PyObject_GetIter(seq1);\r
-    if (data == NULL)\r
-        goto fail;\r
-    selectors = PyObject_GetIter(seq2);\r
-    if (selectors == NULL)\r
-        goto fail;\r
-\r
-    /* create compressobject structure */\r
-    lz = (compressobject *)type->tp_alloc(type, 0);\r
-    if (lz == NULL)\r
-        goto fail;\r
-    lz->data = data;\r
-    lz->selectors = selectors;\r
-    return (PyObject *)lz;\r
-\r
-fail:\r
-    Py_XDECREF(data);\r
-    Py_XDECREF(selectors);\r
-    return NULL;\r
-}\r
-\r
-static void\r
-compress_dealloc(compressobject *lz)\r
-{\r
-    PyObject_GC_UnTrack(lz);\r
-    Py_XDECREF(lz->data);\r
-    Py_XDECREF(lz->selectors);\r
-    Py_TYPE(lz)->tp_free(lz);\r
-}\r
-\r
-static int\r
-compress_traverse(compressobject *lz, visitproc visit, void *arg)\r
-{\r
-    Py_VISIT(lz->data);\r
-    Py_VISIT(lz->selectors);\r
-    return 0;\r
-}\r
-\r
-static PyObject *\r
-compress_next(compressobject *lz)\r
-{\r
-    PyObject *data = lz->data, *selectors = lz->selectors;\r
-    PyObject *datum, *selector;\r
-    PyObject *(*datanext)(PyObject *) = *Py_TYPE(data)->tp_iternext;\r
-    PyObject *(*selectornext)(PyObject *) = *Py_TYPE(selectors)->tp_iternext;\r
-    int ok;\r
-\r
-    while (1) {\r
-        /* Steps:  get datum, get selector, evaluate selector.\r
-           Order is important (to match the pure python version\r
-           in terms of which input gets a chance to raise an\r
-           exception first).\r
-        */\r
-\r
-        datum = datanext(data);\r
-        if (datum == NULL)\r
-            return NULL;\r
-\r
-        selector = selectornext(selectors);\r
-        if (selector == NULL) {\r
-            Py_DECREF(datum);\r
-            return NULL;\r
-        }\r
-\r
-        ok = PyObject_IsTrue(selector);\r
-        Py_DECREF(selector);\r
-        if (ok == 1)\r
-            return datum;\r
-        Py_DECREF(datum);\r
-        if (ok == -1)\r
-            return NULL;\r
-    }\r
-}\r
-\r
-PyDoc_STRVAR(compress_doc,\r
-"compress(data, selectors) --> iterator over selected data\n\\r
-\n\\r
-Return data elements corresponding to true selector elements.\n\\r
-Forms a shorter iterator from selected data elements using the\n\\r
-selectors to choose the data elements.");\r
-\r
-static PyTypeObject compress_type = {\r
-    PyVarObject_HEAD_INIT(NULL, 0)\r
-    "itertools.compress",               /* tp_name */\r
-    sizeof(compressobject),             /* tp_basicsize */\r
-    0,                                                          /* tp_itemsize */\r
-    /* methods */\r
-    (destructor)compress_dealloc,       /* tp_dealloc */\r
-    0,                                                                  /* tp_print */\r
-    0,                                                                  /* tp_getattr */\r
-    0,                                                                  /* tp_setattr */\r
-    0,                                                                  /* tp_compare */\r
-    0,                                                                  /* tp_repr */\r
-    0,                                                                  /* tp_as_number */\r
-    0,                                                                  /* tp_as_sequence */\r
-    0,                                                                  /* tp_as_mapping */\r
-    0,                                                                  /* tp_hash */\r
-    0,                                                                  /* tp_call */\r
-    0,                                                                  /* tp_str */\r
-    PyObject_GenericGetAttr,                    /* tp_getattro */\r
-    0,                                                                  /* tp_setattro */\r
-    0,                                                                  /* tp_as_buffer */\r
-    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |\r
-        Py_TPFLAGS_BASETYPE,                    /* tp_flags */\r
-    compress_doc,                                       /* tp_doc */\r
-    (traverseproc)compress_traverse,            /* tp_traverse */\r
-    0,                                                                  /* tp_clear */\r
-    0,                                                                  /* tp_richcompare */\r
-    0,                                                                  /* tp_weaklistoffset */\r
-    PyObject_SelfIter,                                  /* tp_iter */\r
-    (iternextfunc)compress_next,        /* tp_iternext */\r
-    0,                                                                  /* tp_methods */\r
-    0,                                                                  /* tp_members */\r
-    0,                                                                  /* tp_getset */\r
-    0,                                                                  /* tp_base */\r
-    0,                                                                  /* tp_dict */\r
-    0,                                                                  /* tp_descr_get */\r
-    0,                                                                  /* tp_descr_set */\r
-    0,                                                                  /* tp_dictoffset */\r
-    0,                                                                  /* tp_init */\r
-    0,                                                                  /* tp_alloc */\r
-    compress_new,                                       /* tp_new */\r
-    PyObject_GC_Del,                                    /* tp_free */\r
-};\r
-\r
-\r
-/* ifilter object ************************************************************/\r
-\r
-typedef struct {\r
-    PyObject_HEAD\r
-    PyObject *func;\r
-    PyObject *it;\r
-} ifilterobject;\r
-\r
-static PyTypeObject ifilter_type;\r
-\r
-static PyObject *\r
-ifilter_new(PyTypeObject *type, PyObject *args, PyObject *kwds)\r
-{\r
-    PyObject *func, *seq;\r
-    PyObject *it;\r
-    ifilterobject *lz;\r
-\r
-    if (type == &ifilter_type && !_PyArg_NoKeywords("ifilter()", kwds))\r
-        return NULL;\r
-\r
-    if (!PyArg_UnpackTuple(args, "ifilter", 2, 2, &func, &seq))\r
-        return NULL;\r
-\r
-    /* Get iterator. */\r
-    it = PyObject_GetIter(seq);\r
-    if (it == NULL)\r
-        return NULL;\r
-\r
-    /* create ifilterobject structure */\r
-    lz = (ifilterobject *)type->tp_alloc(type, 0);\r
-    if (lz == NULL) {\r
-        Py_DECREF(it);\r
-        return NULL;\r
-    }\r
-    Py_INCREF(func);\r
-    lz->func = func;\r
-    lz->it = it;\r
-\r
-    return (PyObject *)lz;\r
-}\r
-\r
-static void\r
-ifilter_dealloc(ifilterobject *lz)\r
-{\r
-    PyObject_GC_UnTrack(lz);\r
-    Py_XDECREF(lz->func);\r
-    Py_XDECREF(lz->it);\r
-    Py_TYPE(lz)->tp_free(lz);\r
-}\r
-\r
-static int\r
-ifilter_traverse(ifilterobject *lz, visitproc visit, void *arg)\r
-{\r
-    Py_VISIT(lz->it);\r
-    Py_VISIT(lz->func);\r
-    return 0;\r
-}\r
-\r
-static PyObject *\r
-ifilter_next(ifilterobject *lz)\r
-{\r
-    PyObject *item;\r
-    PyObject *it = lz->it;\r
-    long ok;\r
-    PyObject *(*iternext)(PyObject *);\r
-\r
-    iternext = *Py_TYPE(it)->tp_iternext;\r
-    for (;;) {\r
-        item = iternext(it);\r
-        if (item == NULL)\r
-            return NULL;\r
-\r
-        if (lz->func == Py_None || lz->func == (PyObject *)&PyBool_Type) {\r
-            ok = PyObject_IsTrue(item);\r
-        } else {\r
-            PyObject *good;\r
-            good = PyObject_CallFunctionObjArgs(lz->func,\r
-                                                item, NULL);\r
-            if (good == NULL) {\r
-                Py_DECREF(item);\r
-                return NULL;\r
-            }\r
-            ok = PyObject_IsTrue(good);\r
-            Py_DECREF(good);\r
-        }\r
-        if (ok > 0)\r
-            return item;\r
-        Py_DECREF(item);\r
-        if (ok < 0)\r
-            return NULL;\r
-    }\r
-}\r
-\r
-PyDoc_STRVAR(ifilter_doc,\r
-"ifilter(function or None, sequence) --> ifilter object\n\\r
-\n\\r
-Return those items of sequence for which function(item) is true.\n\\r
-If function is None, return the items that are true.");\r
-\r
-static PyTypeObject ifilter_type = {\r
-    PyVarObject_HEAD_INIT(NULL, 0)\r
-    "itertools.ifilter",                /* tp_name */\r
-    sizeof(ifilterobject),              /* tp_basicsize */\r
-    0,                                  /* tp_itemsize */\r
-    /* methods */\r
-    (destructor)ifilter_dealloc,        /* tp_dealloc */\r
-    0,                                  /* tp_print */\r
-    0,                                  /* tp_getattr */\r
-    0,                                  /* tp_setattr */\r
-    0,                                  /* tp_compare */\r
-    0,                                  /* tp_repr */\r
-    0,                                  /* tp_as_number */\r
-    0,                                  /* tp_as_sequence */\r
-    0,                                  /* tp_as_mapping */\r
-    0,                                  /* tp_hash */\r
-    0,                                  /* tp_call */\r
-    0,                                  /* tp_str */\r
-    PyObject_GenericGetAttr,            /* tp_getattro */\r
-    0,                                  /* tp_setattro */\r
-    0,                                  /* tp_as_buffer */\r
-    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |\r
-        Py_TPFLAGS_BASETYPE,            /* tp_flags */\r
-    ifilter_doc,                        /* tp_doc */\r
-    (traverseproc)ifilter_traverse,     /* tp_traverse */\r
-    0,                                  /* tp_clear */\r
-    0,                                  /* tp_richcompare */\r
-    0,                                  /* tp_weaklistoffset */\r
-    PyObject_SelfIter,                  /* tp_iter */\r
-    (iternextfunc)ifilter_next,         /* tp_iternext */\r
-    0,                                  /* tp_methods */\r
-    0,                                  /* tp_members */\r
-    0,                                  /* tp_getset */\r
-    0,                                  /* tp_base */\r
-    0,                                  /* tp_dict */\r
-    0,                                  /* tp_descr_get */\r
-    0,                                  /* tp_descr_set */\r
-    0,                                  /* tp_dictoffset */\r
-    0,                                  /* tp_init */\r
-    0,                                  /* tp_alloc */\r
-    ifilter_new,                        /* tp_new */\r
-    PyObject_GC_Del,                    /* tp_free */\r
-};\r
-\r
-\r
-/* ifilterfalse object ************************************************************/\r
-\r
-typedef struct {\r
-    PyObject_HEAD\r
-    PyObject *func;\r
-    PyObject *it;\r
-} ifilterfalseobject;\r
-\r
-static PyTypeObject ifilterfalse_type;\r
-\r
-static PyObject *\r
-ifilterfalse_new(PyTypeObject *type, PyObject *args, PyObject *kwds)\r
-{\r
-    PyObject *func, *seq;\r
-    PyObject *it;\r
-    ifilterfalseobject *lz;\r
-\r
-    if (type == &ifilterfalse_type &&\r
-        !_PyArg_NoKeywords("ifilterfalse()", kwds))\r
-        return NULL;\r
-\r
-    if (!PyArg_UnpackTuple(args, "ifilterfalse", 2, 2, &func, &seq))\r
-        return NULL;\r
-\r
-    /* Get iterator. */\r
-    it = PyObject_GetIter(seq);\r
-    if (it == NULL)\r
-        return NULL;\r
-\r
-    /* create ifilterfalseobject structure */\r
-    lz = (ifilterfalseobject *)type->tp_alloc(type, 0);\r
-    if (lz == NULL) {\r
-        Py_DECREF(it);\r
-        return NULL;\r
-    }\r
-    Py_INCREF(func);\r
-    lz->func = func;\r
-    lz->it = it;\r
-\r
-    return (PyObject *)lz;\r
-}\r
-\r
-static void\r
-ifilterfalse_dealloc(ifilterfalseobject *lz)\r
-{\r
-    PyObject_GC_UnTrack(lz);\r
-    Py_XDECREF(lz->func);\r
-    Py_XDECREF(lz->it);\r
-    Py_TYPE(lz)->tp_free(lz);\r
-}\r
-\r
-static int\r
-ifilterfalse_traverse(ifilterfalseobject *lz, visitproc visit, void *arg)\r
-{\r
-    Py_VISIT(lz->it);\r
-    Py_VISIT(lz->func);\r
-    return 0;\r
-}\r
-\r
-static PyObject *\r
-ifilterfalse_next(ifilterfalseobject *lz)\r
-{\r
-    PyObject *item;\r
-    PyObject *it = lz->it;\r
-    long ok;\r
-    PyObject *(*iternext)(PyObject *);\r
-\r
-    iternext = *Py_TYPE(it)->tp_iternext;\r
-    for (;;) {\r
-        item = iternext(it);\r
-        if (item == NULL)\r
-            return NULL;\r
-\r
-        if (lz->func == Py_None || lz->func == (PyObject *)&PyBool_Type) {\r
-            ok = PyObject_IsTrue(item);\r
-        } else {\r
-            PyObject *good;\r
-            good = PyObject_CallFunctionObjArgs(lz->func,\r
-                                                item, NULL);\r
-            if (good == NULL) {\r
-                Py_DECREF(item);\r
-                return NULL;\r
-            }\r
-            ok = PyObject_IsTrue(good);\r
-            Py_DECREF(good);\r
-        }\r
-        if (ok == 0)\r
-            return item;\r
-        Py_DECREF(item);\r
-        if (ok < 0)\r
-            return NULL;\r
-    }\r
-}\r
-\r
-PyDoc_STRVAR(ifilterfalse_doc,\r
-"ifilterfalse(function or None, sequence) --> ifilterfalse object\n\\r
-\n\\r
-Return those items of sequence for which function(item) is false.\n\\r
-If function is None, return the items that are false.");\r
-\r
-static PyTypeObject ifilterfalse_type = {\r
-    PyVarObject_HEAD_INIT(NULL, 0)\r
-    "itertools.ifilterfalse",           /* tp_name */\r
-    sizeof(ifilterfalseobject),         /* tp_basicsize */\r
-    0,                                  /* tp_itemsize */\r
-    /* methods */\r
-    (destructor)ifilterfalse_dealloc,           /* tp_dealloc */\r
-    0,                                  /* tp_print */\r
-    0,                                  /* tp_getattr */\r
-    0,                                  /* tp_setattr */\r
-    0,                                  /* tp_compare */\r
-    0,                                  /* tp_repr */\r
-    0,                                  /* tp_as_number */\r
-    0,                                  /* tp_as_sequence */\r
-    0,                                  /* tp_as_mapping */\r
-    0,                                  /* tp_hash */\r
-    0,                                  /* tp_call */\r
-    0,                                  /* tp_str */\r
-    PyObject_GenericGetAttr,            /* tp_getattro */\r
-    0,                                  /* tp_setattro */\r
-    0,                                  /* tp_as_buffer */\r
-    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |\r
-        Py_TPFLAGS_BASETYPE,            /* tp_flags */\r
-    ifilterfalse_doc,                   /* tp_doc */\r
-    (traverseproc)ifilterfalse_traverse,        /* tp_traverse */\r
-    0,                                  /* tp_clear */\r
-    0,                                  /* tp_richcompare */\r
-    0,                                  /* tp_weaklistoffset */\r
-    PyObject_SelfIter,                  /* tp_iter */\r
-    (iternextfunc)ifilterfalse_next,            /* tp_iternext */\r
-    0,                                  /* tp_methods */\r
-    0,                                  /* tp_members */\r
-    0,                                  /* tp_getset */\r
-    0,                                  /* tp_base */\r
-    0,                                  /* tp_dict */\r
-    0,                                  /* tp_descr_get */\r
-    0,                                  /* tp_descr_set */\r
-    0,                                  /* tp_dictoffset */\r
-    0,                                  /* tp_init */\r
-    0,                                  /* tp_alloc */\r
-    ifilterfalse_new,                   /* tp_new */\r
-    PyObject_GC_Del,                    /* tp_free */\r
-};\r
-\r
-\r
-/* count object ************************************************************/\r
-\r
-typedef struct {\r
-    PyObject_HEAD\r
-    Py_ssize_t cnt;\r
-    PyObject *long_cnt;\r
-    PyObject *long_step;\r
-} countobject;\r
-\r
-/* Counting logic and invariants:\r
-\r
-fast_mode:  when cnt an integer < PY_SSIZE_T_MAX and no step is specified.\r
-\r
-    assert(cnt != PY_SSIZE_T_MAX && long_cnt == NULL && long_step==PyInt(1));\r
-    Advances with:  cnt += 1\r
-    When count hits Y_SSIZE_T_MAX, switch to slow_mode.\r
-\r
-slow_mode:  when cnt == PY_SSIZE_T_MAX, step is not int(1), or cnt is a float.\r
-\r
-    assert(cnt == PY_SSIZE_T_MAX && long_cnt != NULL && long_step != NULL);\r
-    All counting is done with python objects (no overflows or underflows).\r
-    Advances with:  long_cnt += long_step\r
-    Step may be zero -- effectively a slow version of repeat(cnt).\r
-    Either long_cnt or long_step may be a float, Fraction, or Decimal.\r
-*/\r
-\r
-static PyTypeObject count_type;\r
-\r
-static PyObject *\r
-count_new(PyTypeObject *type, PyObject *args, PyObject *kwds)\r
-{\r
-    countobject *lz;\r
-    int slow_mode = 0;\r
-    Py_ssize_t cnt = 0;\r
-    PyObject *long_cnt = NULL;\r
-    PyObject *long_step = NULL;\r
-    static char *kwlist[] = {"start", "step", 0};\r
-\r
-    if (!PyArg_ParseTupleAndKeywords(args, kwds, "|OO:count",\r
-                    kwlist, &long_cnt, &long_step))\r
-        return NULL;\r
-\r
-    if ((long_cnt != NULL && !PyNumber_Check(long_cnt)) ||\r
-        (long_step != NULL && !PyNumber_Check(long_step))) {\r
-                    PyErr_SetString(PyExc_TypeError, "a number is required");\r
-                    return NULL;\r
-    }\r
-\r
-    if (long_cnt != NULL) {\r
-        cnt = PyInt_AsSsize_t(long_cnt);\r
-        if ((cnt == -1 && PyErr_Occurred()) || !PyInt_Check(long_cnt)) {\r
-            PyErr_Clear();\r
-            slow_mode = 1;\r
-        }\r
-        Py_INCREF(long_cnt);\r
-    } else {\r
-        cnt = 0;\r
-        long_cnt = PyInt_FromLong(0);\r
-    }\r
-\r
-    /* If not specified, step defaults to 1 */\r
-    if (long_step == NULL) {\r
-        long_step = PyInt_FromLong(1);\r
-        if (long_step == NULL) {\r
-            Py_DECREF(long_cnt);\r
-            return NULL;\r
-        }\r
-    } else\r
-        Py_INCREF(long_step);\r
-\r
-    assert(long_cnt != NULL && long_step != NULL);\r
-\r
-    /* Fast mode only works when the step is 1 */\r
-    if (!PyInt_Check(long_step) ||\r
-        PyInt_AS_LONG(long_step) != 1) {\r
-            slow_mode = 1;\r
-    }\r
-\r
-    if (slow_mode)\r
-        cnt = PY_SSIZE_T_MAX;\r
-    else\r
-        Py_CLEAR(long_cnt);\r
-\r
-    assert((cnt != PY_SSIZE_T_MAX && long_cnt == NULL && !slow_mode) ||\r
-           (cnt == PY_SSIZE_T_MAX && long_cnt != NULL && slow_mode));\r
-    assert(slow_mode ||\r
-           (PyInt_Check(long_step) && PyInt_AS_LONG(long_step) == 1));\r
-\r
-    /* create countobject structure */\r
-    lz = (countobject *)type->tp_alloc(type, 0);\r
-    if (lz == NULL) {\r
-        Py_XDECREF(long_cnt);\r
-        return NULL;\r
-    }\r
-    lz->cnt = cnt;\r
-    lz->long_cnt = long_cnt;\r
-    lz->long_step = long_step;\r
-\r
-    return (PyObject *)lz;\r
-}\r
-\r
-static void\r
-count_dealloc(countobject *lz)\r
-{\r
-    PyObject_GC_UnTrack(lz);\r
-    Py_XDECREF(lz->long_cnt);\r
-    Py_XDECREF(lz->long_step);\r
-    Py_TYPE(lz)->tp_free(lz);\r
-}\r
-\r
-static int\r
-count_traverse(countobject *lz, visitproc visit, void *arg)\r
-{\r
-    Py_VISIT(lz->long_cnt);\r
-    Py_VISIT(lz->long_step);\r
-    return 0;\r
-}\r
-\r
-static PyObject *\r
-count_nextlong(countobject *lz)\r
-{\r
-    PyObject *long_cnt;\r
-    PyObject *stepped_up;\r
-\r
-    long_cnt = lz->long_cnt;\r
-    if (long_cnt == NULL) {\r
-        /* Switch to slow_mode */\r
-        long_cnt = PyInt_FromSsize_t(PY_SSIZE_T_MAX);\r
-        if (long_cnt == NULL)\r
-            return NULL;\r
-    }\r
-    assert(lz->cnt == PY_SSIZE_T_MAX && long_cnt != NULL);\r
-\r
-    stepped_up = PyNumber_Add(long_cnt, lz->long_step);\r
-    if (stepped_up == NULL)\r
-        return NULL;\r
-    lz->long_cnt = stepped_up;\r
-    return long_cnt;\r
-}\r
-\r
-static PyObject *\r
-count_next(countobject *lz)\r
-{\r
-    if (lz->cnt == PY_SSIZE_T_MAX)\r
-        return count_nextlong(lz);\r
-    return PyInt_FromSsize_t(lz->cnt++);\r
-}\r
-\r
-static PyObject *\r
-count_repr(countobject *lz)\r
-{\r
-    PyObject *cnt_repr, *step_repr = NULL;\r
-    PyObject *result = NULL;\r
-\r
-    if (lz->cnt != PY_SSIZE_T_MAX)\r
-                return PyString_FromFormat("count(%zd)", lz->cnt);\r
-\r
-    cnt_repr = PyObject_Repr(lz->long_cnt);\r
-    if (cnt_repr == NULL)\r
-        return NULL;\r
-\r
-    if (PyInt_Check(lz->long_step) && PyInt_AS_LONG(lz->long_step) == 1) {\r
-                    /* Don't display step when it is an integer equal to 1 */\r
-            result = PyString_FromFormat("count(%s)",\r
-                                                                     PyString_AS_STRING(cnt_repr));\r
-    } else {\r
-        step_repr = PyObject_Repr(lz->long_step);\r
-        if (step_repr != NULL)\r
-            result = PyString_FromFormat("count(%s, %s)",\r
-                                                                    PyString_AS_STRING(cnt_repr),\r
-                                                                    PyString_AS_STRING(step_repr));\r
-    }\r
-    Py_DECREF(cnt_repr);\r
-    Py_XDECREF(step_repr);\r
-    return result;\r
-}\r
-\r
-static PyObject *\r
-count_reduce(countobject *lz)\r
-{\r
-    if (lz->cnt == PY_SSIZE_T_MAX)\r
-        return Py_BuildValue("O(OO)", Py_TYPE(lz), lz->long_cnt, lz->long_step);\r
-    return Py_BuildValue("O(n)", Py_TYPE(lz), lz->cnt);\r
-}\r
-\r
-PyDoc_STRVAR(count_reduce_doc, "Return state information for pickling.");\r
-\r
-static PyMethodDef count_methods[] = {\r
-    {"__reduce__",      (PyCFunction)count_reduce,      METH_NOARGS,\r
-     count_reduce_doc},\r
-    {NULL,              NULL}   /* sentinel */\r
-};\r
-\r
-PyDoc_STRVAR(count_doc,\r
-                         "count(start=0, step=1) --> count object\n\\r
-\n\\r
-Return a count object whose .next() method returns consecutive values.\n\\r
-Equivalent to:\n\n\\r
-    def count(firstval=0, step=1):\n\\r
-        x = firstval\n\\r
-        while 1:\n\\r
-            yield x\n\\r
-            x += step\n");\r
-\r
-static PyTypeObject count_type = {\r
-    PyVarObject_HEAD_INIT(NULL, 0)\r
-    "itertools.count",                  /* tp_name */\r
-    sizeof(countobject),                /* tp_basicsize */\r
-    0,                                  /* tp_itemsize */\r
-    /* methods */\r
-    (destructor)count_dealloc,          /* tp_dealloc */\r
-    0,                                  /* tp_print */\r
-    0,                                  /* tp_getattr */\r
-    0,                                  /* tp_setattr */\r
-    0,                                  /* tp_compare */\r
-    (reprfunc)count_repr,               /* tp_repr */\r
-    0,                                  /* tp_as_number */\r
-    0,                                  /* tp_as_sequence */\r
-    0,                                  /* tp_as_mapping */\r
-    0,                                  /* tp_hash */\r
-    0,                                  /* tp_call */\r
-    0,                                  /* tp_str */\r
-    PyObject_GenericGetAttr,            /* tp_getattro */\r
-    0,                                  /* tp_setattro */\r
-    0,                                  /* tp_as_buffer */\r
-    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |\r
-        Py_TPFLAGS_BASETYPE,                    /* tp_flags */\r
-    count_doc,                          /* tp_doc */\r
-    (traverseproc)count_traverse,                               /* tp_traverse */\r
-    0,                                  /* tp_clear */\r
-    0,                                  /* tp_richcompare */\r
-    0,                                  /* tp_weaklistoffset */\r
-    PyObject_SelfIter,                  /* tp_iter */\r
-    (iternextfunc)count_next,           /* tp_iternext */\r
-    count_methods,                              /* tp_methods */\r
-    0,                                  /* tp_members */\r
-    0,                                  /* tp_getset */\r
-    0,                                  /* tp_base */\r
-    0,                                  /* tp_dict */\r
-    0,                                  /* tp_descr_get */\r
-    0,                                  /* tp_descr_set */\r
-    0,                                  /* tp_dictoffset */\r
-    0,                                  /* tp_init */\r
-    0,                                  /* tp_alloc */\r
-    count_new,                          /* tp_new */\r
-    PyObject_GC_Del,                    /* tp_free */\r
-};\r
-\r
-\r
-/* izip object ************************************************************/\r
-\r
-#include "Python.h"\r
-\r
-typedef struct {\r
-    PyObject_HEAD\r
-    Py_ssize_t          tuplesize;\r
-    PyObject *ittuple;                  /* tuple of iterators */\r
-    PyObject *result;\r
-} izipobject;\r
-\r
-static PyTypeObject izip_type;\r
-\r
-static PyObject *\r
-izip_new(PyTypeObject *type, PyObject *args, PyObject *kwds)\r
-{\r
-    izipobject *lz;\r
-    Py_ssize_t i;\r
-    PyObject *ittuple;  /* tuple of iterators */\r
-    PyObject *result;\r
-    Py_ssize_t tuplesize = PySequence_Length(args);\r
-\r
-    if (type == &izip_type && !_PyArg_NoKeywords("izip()", kwds))\r
-        return NULL;\r
-\r
-    /* args must be a tuple */\r
-    assert(PyTuple_Check(args));\r
-\r
-    /* obtain iterators */\r
-    ittuple = PyTuple_New(tuplesize);\r
-    if (ittuple == NULL)\r
-        return NULL;\r
-    for (i=0; i < tuplesize; ++i) {\r
-        PyObject *item = PyTuple_GET_ITEM(args, i);\r
-        PyObject *it = PyObject_GetIter(item);\r
-        if (it == NULL) {\r
-            if (PyErr_ExceptionMatches(PyExc_TypeError))\r
-                PyErr_Format(PyExc_TypeError,\r
-                    "izip argument #%zd must support iteration",\r
-                    i+1);\r
-            Py_DECREF(ittuple);\r
-            return NULL;\r
-        }\r
-        PyTuple_SET_ITEM(ittuple, i, it);\r
-    }\r
-\r
-    /* create a result holder */\r
-    result = PyTuple_New(tuplesize);\r
-    if (result == NULL) {\r
-        Py_DECREF(ittuple);\r
-        return NULL;\r
-    }\r
-    for (i=0 ; i < tuplesize ; i++) {\r
-        Py_INCREF(Py_None);\r
-        PyTuple_SET_ITEM(result, i, Py_None);\r
-    }\r
-\r
-    /* create izipobject structure */\r
-    lz = (izipobject *)type->tp_alloc(type, 0);\r
-    if (lz == NULL) {\r
-        Py_DECREF(ittuple);\r
-        Py_DECREF(result);\r
-        return NULL;\r
-    }\r
-    lz->ittuple = ittuple;\r
-    lz->tuplesize = tuplesize;\r
-    lz->result = result;\r
-\r
-    return (PyObject *)lz;\r
-}\r
-\r
-static void\r
-izip_dealloc(izipobject *lz)\r
-{\r
-    PyObject_GC_UnTrack(lz);\r
-    Py_XDECREF(lz->ittuple);\r
-    Py_XDECREF(lz->result);\r
-    Py_TYPE(lz)->tp_free(lz);\r
-}\r
-\r
-static int\r
-izip_traverse(izipobject *lz, visitproc visit, void *arg)\r
-{\r
-    Py_VISIT(lz->ittuple);\r
-    Py_VISIT(lz->result);\r
-    return 0;\r
-}\r
-\r
-static PyObject *\r
-izip_next(izipobject *lz)\r
-{\r
-    Py_ssize_t i;\r
-    Py_ssize_t tuplesize = lz->tuplesize;\r
-    PyObject *result = lz->result;\r
-    PyObject *it;\r
-    PyObject *item;\r
-    PyObject *olditem;\r
-\r
-    if (tuplesize == 0)\r
-        return NULL;\r
-    if (Py_REFCNT(result) == 1) {\r
-        Py_INCREF(result);\r
-        for (i=0 ; i < tuplesize ; i++) {\r
-            it = PyTuple_GET_ITEM(lz->ittuple, i);\r
-            item = (*Py_TYPE(it)->tp_iternext)(it);\r
-            if (item == NULL) {\r
-                Py_DECREF(result);\r
-                return NULL;\r
-            }\r
-            olditem = PyTuple_GET_ITEM(result, i);\r
-            PyTuple_SET_ITEM(result, i, item);\r
-            Py_DECREF(olditem);\r
-        }\r
-    } else {\r
-        result = PyTuple_New(tuplesize);\r
-        if (result == NULL)\r
-            return NULL;\r
-        for (i=0 ; i < tuplesize ; i++) {\r
-            it = PyTuple_GET_ITEM(lz->ittuple, i);\r
-            item = (*Py_TYPE(it)->tp_iternext)(it);\r
-            if (item == NULL) {\r
-                Py_DECREF(result);\r
-                return NULL;\r
-            }\r
-            PyTuple_SET_ITEM(result, i, item);\r
-        }\r
-    }\r
-    return result;\r
-}\r
-\r
-PyDoc_STRVAR(izip_doc,\r
-"izip(iter1 [,iter2 [...]]) --> izip object\n\\r
-\n\\r
-Return a izip object whose .next() method returns a tuple where\n\\r
-the i-th element comes from the i-th iterable argument.  The .next()\n\\r
-method continues until the shortest iterable in the argument sequence\n\\r
-is exhausted and then it raises StopIteration.  Works like the zip()\n\\r
-function but consumes less memory by returning an iterator instead of\n\\r
-a list.");\r
-\r
-static PyTypeObject izip_type = {\r
-    PyVarObject_HEAD_INIT(NULL, 0)\r
-    "itertools.izip",                   /* tp_name */\r
-    sizeof(izipobject),                 /* tp_basicsize */\r
-    0,                                  /* tp_itemsize */\r
-    /* methods */\r
-    (destructor)izip_dealloc,           /* tp_dealloc */\r
-    0,                                  /* tp_print */\r
-    0,                                  /* tp_getattr */\r
-    0,                                  /* tp_setattr */\r
-    0,                                  /* tp_compare */\r
-    0,                                  /* tp_repr */\r
-    0,                                  /* tp_as_number */\r
-    0,                                  /* tp_as_sequence */\r
-    0,                                  /* tp_as_mapping */\r
-    0,                                  /* tp_hash */\r
-    0,                                  /* tp_call */\r
-    0,                                  /* tp_str */\r
-    PyObject_GenericGetAttr,            /* tp_getattro */\r
-    0,                                  /* tp_setattro */\r
-    0,                                  /* tp_as_buffer */\r
-    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |\r
-        Py_TPFLAGS_BASETYPE,            /* tp_flags */\r
-    izip_doc,                           /* tp_doc */\r
-    (traverseproc)izip_traverse,    /* tp_traverse */\r
-    0,                                  /* tp_clear */\r
-    0,                                  /* tp_richcompare */\r
-    0,                                  /* tp_weaklistoffset */\r
-    PyObject_SelfIter,                  /* tp_iter */\r
-    (iternextfunc)izip_next,            /* tp_iternext */\r
-    0,                                  /* tp_methods */\r
-    0,                                  /* tp_members */\r
-    0,                                  /* tp_getset */\r
-    0,                                  /* tp_base */\r
-    0,                                  /* tp_dict */\r
-    0,                                  /* tp_descr_get */\r
-    0,                                  /* tp_descr_set */\r
-    0,                                  /* tp_dictoffset */\r
-    0,                                  /* tp_init */\r
-    0,                                  /* tp_alloc */\r
-    izip_new,                           /* tp_new */\r
-    PyObject_GC_Del,                    /* tp_free */\r
-};\r
-\r
-\r
-/* repeat object ************************************************************/\r
-\r
-typedef struct {\r
-    PyObject_HEAD\r
-    PyObject *element;\r
-    Py_ssize_t cnt;\r
-} repeatobject;\r
-\r
-static PyTypeObject repeat_type;\r
-\r
-static PyObject *\r
-repeat_new(PyTypeObject *type, PyObject *args, PyObject *kwds)\r
-{\r
-    repeatobject *ro;\r
-    PyObject *element;\r
-    Py_ssize_t cnt = -1, n_kwds = 0;\r
-    static char *kwargs[] = {"object", "times", NULL};\r
-\r
-    if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|n:repeat", kwargs,\r
-                                     &element, &cnt))\r
-        return NULL;\r
-\r
-    if (kwds != NULL)\r
-        n_kwds = PyDict_Size(kwds);\r
-    /* Does user supply times argument? */\r
-    if ((PyTuple_Size(args) + n_kwds == 2) && cnt < 0)\r
-        cnt = 0;\r
-\r
-    ro = (repeatobject *)type->tp_alloc(type, 0);\r
-    if (ro == NULL)\r
-        return NULL;\r
-    Py_INCREF(element);\r
-    ro->element = element;\r
-    ro->cnt = cnt;\r
-    return (PyObject *)ro;\r
-}\r
-\r
-static void\r
-repeat_dealloc(repeatobject *ro)\r
-{\r
-    PyObject_GC_UnTrack(ro);\r
-    Py_XDECREF(ro->element);\r
-    Py_TYPE(ro)->tp_free(ro);\r
-}\r
-\r
-static int\r
-repeat_traverse(repeatobject *ro, visitproc visit, void *arg)\r
-{\r
-    Py_VISIT(ro->element);\r
-    return 0;\r
-}\r
-\r
-static PyObject *\r
-repeat_next(repeatobject *ro)\r
-{\r
-    if (ro->cnt == 0)\r
-        return NULL;\r
-    if (ro->cnt > 0)\r
-        ro->cnt--;\r
-    Py_INCREF(ro->element);\r
-    return ro->element;\r
-}\r
-\r
-static PyObject *\r
-repeat_repr(repeatobject *ro)\r
-{\r
-    PyObject *result, *objrepr;\r
-\r
-    objrepr = PyObject_Repr(ro->element);\r
-    if (objrepr == NULL)\r
-        return NULL;\r
-\r
-    if (ro->cnt == -1)\r
-        result = PyString_FromFormat("repeat(%s)",\r
-            PyString_AS_STRING(objrepr));\r
-    else\r
-        result = PyString_FromFormat("repeat(%s, %zd)",\r
-            PyString_AS_STRING(objrepr), ro->cnt);\r
-    Py_DECREF(objrepr);\r
-    return result;\r
-}\r
-\r
-static PyObject *\r
-repeat_len(repeatobject *ro)\r
-{\r
-    if (ro->cnt == -1) {\r
-        PyErr_SetString(PyExc_TypeError, "len() of unsized object");\r
-        return NULL;\r
-    }\r
-    return PyInt_FromSize_t(ro->cnt);\r
-}\r
-\r
-PyDoc_STRVAR(length_hint_doc, "Private method returning an estimate of len(list(it)).");\r
-\r
-static PyMethodDef repeat_methods[] = {\r
-    {"__length_hint__", (PyCFunction)repeat_len, METH_NOARGS, length_hint_doc},\r
-    {NULL,              NULL}           /* sentinel */\r
-};\r
-\r
-PyDoc_STRVAR(repeat_doc,\r
-"repeat(object [,times]) -> create an iterator which returns the object\n\\r
-for the specified number of times.  If not specified, returns the object\n\\r
-endlessly.");\r
-\r
-static PyTypeObject repeat_type = {\r
-    PyVarObject_HEAD_INIT(NULL, 0)\r
-    "itertools.repeat",                 /* tp_name */\r
-    sizeof(repeatobject),               /* tp_basicsize */\r
-    0,                                  /* tp_itemsize */\r
-    /* methods */\r
-    (destructor)repeat_dealloc,         /* tp_dealloc */\r
-    0,                                  /* tp_print */\r
-    0,                                  /* tp_getattr */\r
-    0,                                  /* tp_setattr */\r
-    0,                                  /* tp_compare */\r
-    (reprfunc)repeat_repr,              /* tp_repr */\r
-    0,                                  /* tp_as_number */\r
-    0,                                  /* tp_as_sequence */\r
-    0,                                  /* tp_as_mapping */\r
-    0,                                  /* tp_hash */\r
-    0,                                  /* tp_call */\r
-    0,                                  /* tp_str */\r
-    PyObject_GenericGetAttr,            /* tp_getattro */\r
-    0,                                  /* tp_setattro */\r
-    0,                                  /* tp_as_buffer */\r
-    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |\r
-        Py_TPFLAGS_BASETYPE,            /* tp_flags */\r
-    repeat_doc,                         /* tp_doc */\r
-    (traverseproc)repeat_traverse,      /* tp_traverse */\r
-    0,                                  /* tp_clear */\r
-    0,                                  /* tp_richcompare */\r
-    0,                                  /* tp_weaklistoffset */\r
-    PyObject_SelfIter,                  /* tp_iter */\r
-    (iternextfunc)repeat_next,          /* tp_iternext */\r
-    repeat_methods,                     /* tp_methods */\r
-    0,                                  /* tp_members */\r
-    0,                                  /* tp_getset */\r
-    0,                                  /* tp_base */\r
-    0,                                  /* tp_dict */\r
-    0,                                  /* tp_descr_get */\r
-    0,                                  /* tp_descr_set */\r
-    0,                                  /* tp_dictoffset */\r
-    0,                                  /* tp_init */\r
-    0,                                  /* tp_alloc */\r
-    repeat_new,                         /* tp_new */\r
-    PyObject_GC_Del,                    /* tp_free */\r
-};\r
-\r
-/* iziplongest object ************************************************************/\r
-\r
-#include "Python.h"\r
-\r
-typedef struct {\r
-    PyObject_HEAD\r
-    Py_ssize_t tuplesize;\r
-    Py_ssize_t numactive;\r
-    PyObject *ittuple;                  /* tuple of iterators */\r
-    PyObject *result;\r
-    PyObject *fillvalue;\r
-} iziplongestobject;\r
-\r
-static PyTypeObject iziplongest_type;\r
-\r
-static PyObject *\r
-izip_longest_new(PyTypeObject *type, PyObject *args, PyObject *kwds)\r
-{\r
-    iziplongestobject *lz;\r
-    Py_ssize_t i;\r
-    PyObject *ittuple;  /* tuple of iterators */\r
-    PyObject *result;\r
-    PyObject *fillvalue = Py_None;\r
-    Py_ssize_t tuplesize = PySequence_Length(args);\r
-\r
-    if (kwds != NULL && PyDict_CheckExact(kwds) && PyDict_Size(kwds) > 0) {\r
-        fillvalue = PyDict_GetItemString(kwds, "fillvalue");\r
-        if (fillvalue == NULL  ||  PyDict_Size(kwds) > 1) {\r
-            PyErr_SetString(PyExc_TypeError,\r
-                "izip_longest() got an unexpected keyword argument");\r
-            return NULL;\r
-        }\r
-    }\r
-\r
-    /* args must be a tuple */\r
-    assert(PyTuple_Check(args));\r
-\r
-    /* obtain iterators */\r
-    ittuple = PyTuple_New(tuplesize);\r
-    if (ittuple == NULL)\r
-        return NULL;\r
-    for (i=0; i < tuplesize; ++i) {\r
-        PyObject *item = PyTuple_GET_ITEM(args, i);\r
-        PyObject *it = PyObject_GetIter(item);\r
-        if (it == NULL) {\r
-            if (PyErr_ExceptionMatches(PyExc_TypeError))\r
-                PyErr_Format(PyExc_TypeError,\r
-                    "izip_longest argument #%zd must support iteration",\r
-                    i+1);\r
-            Py_DECREF(ittuple);\r
-            return NULL;\r
-        }\r
-        PyTuple_SET_ITEM(ittuple, i, it);\r
-    }\r
-\r
-    /* create a result holder */\r
-    result = PyTuple_New(tuplesize);\r
-    if (result == NULL) {\r
-        Py_DECREF(ittuple);\r
-        return NULL;\r
-    }\r
-    for (i=0 ; i < tuplesize ; i++) {\r
-        Py_INCREF(Py_None);\r
-        PyTuple_SET_ITEM(result, i, Py_None);\r
-    }\r
-\r
-    /* create iziplongestobject structure */\r
-    lz = (iziplongestobject *)type->tp_alloc(type, 0);\r
-    if (lz == NULL) {\r
-        Py_DECREF(ittuple);\r
-        Py_DECREF(result);\r
-        return NULL;\r
-    }\r
-    lz->ittuple = ittuple;\r
-    lz->tuplesize = tuplesize;\r
-    lz->numactive = tuplesize;\r
-    lz->result = result;\r
-    Py_INCREF(fillvalue);\r
-    lz->fillvalue = fillvalue;\r
-    return (PyObject *)lz;\r
-}\r
-\r
-static void\r
-izip_longest_dealloc(iziplongestobject *lz)\r
-{\r
-    PyObject_GC_UnTrack(lz);\r
-    Py_XDECREF(lz->ittuple);\r
-    Py_XDECREF(lz->result);\r
-    Py_XDECREF(lz->fillvalue);\r
-    Py_TYPE(lz)->tp_free(lz);\r
-}\r
-\r
-static int\r
-izip_longest_traverse(iziplongestobject *lz, visitproc visit, void *arg)\r
-{\r
-    Py_VISIT(lz->ittuple);\r
-    Py_VISIT(lz->result);\r
-    Py_VISIT(lz->fillvalue);\r
-    return 0;\r
-}\r
-\r
-static PyObject *\r
-izip_longest_next(iziplongestobject *lz)\r
-{\r
-    Py_ssize_t i;\r
-    Py_ssize_t tuplesize = lz->tuplesize;\r
-    PyObject *result = lz->result;\r
-    PyObject *it;\r
-    PyObject *item;\r
-    PyObject *olditem;\r
-\r
-    if (tuplesize == 0)\r
-        return NULL;\r
-    if (lz->numactive == 0)\r
-        return NULL;\r
-    if (Py_REFCNT(result) == 1) {\r
-        Py_INCREF(result);\r
-        for (i=0 ; i < tuplesize ; i++) {\r
-            it = PyTuple_GET_ITEM(lz->ittuple, i);\r
-            if (it == NULL) {\r
-                Py_INCREF(lz->fillvalue);\r
-                item = lz->fillvalue;\r
-            } else {\r
-                item = PyIter_Next(it);\r
-                if (item == NULL) {\r
-                    lz->numactive -= 1;\r
-                    if (lz->numactive == 0 || PyErr_Occurred()) {\r
-                        lz->numactive = 0;\r
-                        Py_DECREF(result);\r
-                        return NULL;\r
-                    } else {\r
-                        Py_INCREF(lz->fillvalue);\r
-                        item = lz->fillvalue;\r
-                        PyTuple_SET_ITEM(lz->ittuple, i, NULL);\r
-                        Py_DECREF(it);\r
-                    }\r
-                }\r
-            }\r
-            olditem = PyTuple_GET_ITEM(result, i);\r
-            PyTuple_SET_ITEM(result, i, item);\r
-            Py_DECREF(olditem);\r
-        }\r
-    } else {\r
-        result = PyTuple_New(tuplesize);\r
-        if (result == NULL)\r
-            return NULL;\r
-        for (i=0 ; i < tuplesize ; i++) {\r
-            it = PyTuple_GET_ITEM(lz->ittuple, i);\r
-            if (it == NULL) {\r
-                Py_INCREF(lz->fillvalue);\r
-                item = lz->fillvalue;\r
-            } else {\r
-                item = PyIter_Next(it);\r
-                if (item == NULL) {\r
-                    lz->numactive -= 1;\r
-                    if (lz->numactive == 0 || PyErr_Occurred()) {\r
-                        lz->numactive = 0;\r
-                        Py_DECREF(result);\r
-                        return NULL;\r
-                    } else {\r
-                        Py_INCREF(lz->fillvalue);\r
-                        item = lz->fillvalue;\r
-                        PyTuple_SET_ITEM(lz->ittuple, i, NULL);\r
-                        Py_DECREF(it);\r
-                    }\r
-                }\r
-            }\r
-            PyTuple_SET_ITEM(result, i, item);\r
-        }\r
-    }\r
-    return result;\r
-}\r
-\r
-PyDoc_STRVAR(izip_longest_doc,\r
-"izip_longest(iter1 [,iter2 [...]], [fillvalue=None]) --> izip_longest object\n\\r
-\n\\r
-Return an izip_longest object whose .next() method returns a tuple where\n\\r
-the i-th element comes from the i-th iterable argument.  The .next()\n\\r
-method continues until the longest iterable in the argument sequence\n\\r
-is exhausted and then it raises StopIteration.  When the shorter iterables\n\\r
-are exhausted, the fillvalue is substituted in their place.  The fillvalue\n\\r
-defaults to None or can be specified by a keyword argument.\n\\r
-");\r
-\r
-static PyTypeObject iziplongest_type = {\r
-    PyVarObject_HEAD_INIT(NULL, 0)\r
-    "itertools.izip_longest",           /* tp_name */\r
-    sizeof(iziplongestobject),          /* tp_basicsize */\r
-    0,                                  /* tp_itemsize */\r
-    /* methods */\r
-    (destructor)izip_longest_dealloc,           /* tp_dealloc */\r
-    0,                                  /* tp_print */\r
-    0,                                  /* tp_getattr */\r
-    0,                                  /* tp_setattr */\r
-    0,                                  /* tp_compare */\r
-    0,                                  /* tp_repr */\r
-    0,                                  /* tp_as_number */\r
-    0,                                  /* tp_as_sequence */\r
-    0,                                  /* tp_as_mapping */\r
-    0,                                  /* tp_hash */\r
-    0,                                  /* tp_call */\r
-    0,                                  /* tp_str */\r
-    PyObject_GenericGetAttr,            /* tp_getattro */\r
-    0,                                  /* tp_setattro */\r
-    0,                                  /* tp_as_buffer */\r
-    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |\r
-        Py_TPFLAGS_BASETYPE,            /* tp_flags */\r
-    izip_longest_doc,                           /* tp_doc */\r
-    (traverseproc)izip_longest_traverse,    /* tp_traverse */\r
-    0,                                  /* tp_clear */\r
-    0,                                  /* tp_richcompare */\r
-    0,                                  /* tp_weaklistoffset */\r
-    PyObject_SelfIter,                  /* tp_iter */\r
-    (iternextfunc)izip_longest_next,            /* tp_iternext */\r
-    0,                                  /* tp_methods */\r
-    0,                                  /* tp_members */\r
-    0,                                  /* tp_getset */\r
-    0,                                  /* tp_base */\r
-    0,                                  /* tp_dict */\r
-    0,                                  /* tp_descr_get */\r
-    0,                                  /* tp_descr_set */\r
-    0,                                  /* tp_dictoffset */\r
-    0,                                  /* tp_init */\r
-    0,                                  /* tp_alloc */\r
-    izip_longest_new,                           /* tp_new */\r
-    PyObject_GC_Del,                    /* tp_free */\r
-};\r
-\r
-/* module level code ********************************************************/\r
-\r
-PyDoc_STRVAR(module_doc,\r
-"Functional tools for creating and using iterators.\n\\r
-\n\\r
-Infinite iterators:\n\\r
-count([n]) --> n, n+1, n+2, ...\n\\r
-cycle(p) --> p0, p1, ... plast, p0, p1, ...\n\\r
-repeat(elem [,n]) --> elem, elem, elem, ... endlessly or up to n times\n\\r
-\n\\r
-Iterators terminating on the shortest input sequence:\n\\r
-chain(p, q, ...) --> p0, p1, ... plast, q0, q1, ... \n\\r
-compress(data, selectors) --> (d[0] if s[0]), (d[1] if s[1]), ...\n\\r
-dropwhile(pred, seq) --> seq[n], seq[n+1], starting when pred fails\n\\r
-groupby(iterable[, keyfunc]) --> sub-iterators grouped by value of keyfunc(v)\n\\r
-ifilter(pred, seq) --> elements of seq where pred(elem) is True\n\\r
-ifilterfalse(pred, seq) --> elements of seq where pred(elem) is False\n\\r
-islice(seq, [start,] stop [, step]) --> elements from\n\\r
-       seq[start:stop:step]\n\\r
-imap(fun, p, q, ...) --> fun(p0, q0), fun(p1, q1), ...\n\\r
-starmap(fun, seq) --> fun(*seq[0]), fun(*seq[1]), ...\n\\r
-tee(it, n=2) --> (it1, it2 , ... itn) splits one iterator into n\n\\r
-takewhile(pred, seq) --> seq[0], seq[1], until pred fails\n\\r
-izip(p, q, ...) --> (p[0], q[0]), (p[1], q[1]), ... \n\\r
-izip_longest(p, q, ...) --> (p[0], q[0]), (p[1], q[1]), ... \n\\r
-\n\\r
-Combinatoric generators:\n\\r
-product(p, q, ... [repeat=1]) --> cartesian product\n\\r
-permutations(p[, r])\n\\r
-combinations(p, r)\n\\r
-combinations_with_replacement(p, r)\n\\r
-");\r
-\r
-\r
-static PyMethodDef module_methods[] = {\r
-    {"tee",     (PyCFunction)tee,       METH_VARARGS, tee_doc},\r
-    {NULL,              NULL}           /* sentinel */\r
-};\r
-\r
-PyMODINIT_FUNC\r
-inititertools(void)\r
-{\r
-    int i;\r
-    PyObject *m;\r
-    char *name;\r
-    PyTypeObject *typelist[] = {\r
-        &combinations_type,\r
-        &cwr_type,\r
-        &cycle_type,\r
-        &dropwhile_type,\r
-        &takewhile_type,\r
-        &islice_type,\r
-        &starmap_type,\r
-        &imap_type,\r
-        &chain_type,\r
-        &compress_type,\r
-        &ifilter_type,\r
-        &ifilterfalse_type,\r
-        &count_type,\r
-        &izip_type,\r
-        &iziplongest_type,\r
-        &permutations_type,\r
-        &product_type,\r
-        &repeat_type,\r
-        &groupby_type,\r
-        NULL\r
-    };\r
-\r
-    Py_TYPE(&teedataobject_type) = &PyType_Type;\r
-    m = Py_InitModule3("itertools", module_methods, module_doc);\r
-    if (m == NULL)\r
-        return;\r
-\r
-    for (i=0 ; typelist[i] != NULL ; i++) {\r
-        if (PyType_Ready(typelist[i]) < 0)\r
-            return;\r
-        name = strchr(typelist[i]->tp_name, '.');\r
-        assert (name != NULL);\r
-        Py_INCREF(typelist[i]);\r
-        PyModule_AddObject(m, name+1, (PyObject *)typelist[i]);\r
-    }\r
-\r
-    if (PyType_Ready(&teedataobject_type) < 0)\r
-        return;\r
-    if (PyType_Ready(&tee_type) < 0)\r
-        return;\r
-    if (PyType_Ready(&_grouper_type) < 0)\r
-        return;\r
-}\r