17db96d56Sopenharmony_ci#define PY_SSIZE_T_CLEAN 27db96d56Sopenharmony_ci#include "Python.h" 37db96d56Sopenharmony_ci#include "pycore_call.h" // _PyObject_CallNoArgs() 47db96d56Sopenharmony_ci#include "pycore_long.h" // _PyLong_GetZero() 57db96d56Sopenharmony_ci#include "pycore_object.h" // _PyObject_GC_TRACK() 67db96d56Sopenharmony_ci#include "pycore_tuple.h" // _PyTuple_ITEMS() 77db96d56Sopenharmony_ci#include <stddef.h> // offsetof() 87db96d56Sopenharmony_ci 97db96d56Sopenharmony_ci/* Itertools module written and maintained 107db96d56Sopenharmony_ci by Raymond D. Hettinger <python@rcn.com> 117db96d56Sopenharmony_ci*/ 127db96d56Sopenharmony_ci 137db96d56Sopenharmony_ci/*[clinic input] 147db96d56Sopenharmony_cimodule itertools 157db96d56Sopenharmony_ciclass itertools.groupby "groupbyobject *" "&groupby_type" 167db96d56Sopenharmony_ciclass itertools._grouper "_grouperobject *" "&_grouper_type" 177db96d56Sopenharmony_ciclass itertools.teedataobject "teedataobject *" "&teedataobject_type" 187db96d56Sopenharmony_ciclass itertools._tee "teeobject *" "&tee_type" 197db96d56Sopenharmony_ciclass itertools.cycle "cycleobject *" "&cycle_type" 207db96d56Sopenharmony_ciclass itertools.dropwhile "dropwhileobject *" "&dropwhile_type" 217db96d56Sopenharmony_ciclass itertools.takewhile "takewhileobject *" "&takewhile_type" 227db96d56Sopenharmony_ciclass itertools.starmap "starmapobject *" "&starmap_type" 237db96d56Sopenharmony_ciclass itertools.chain "chainobject *" "&chain_type" 247db96d56Sopenharmony_ciclass itertools.combinations "combinationsobject *" "&combinations_type" 257db96d56Sopenharmony_ciclass itertools.combinations_with_replacement "cwr_object *" "&cwr_type" 267db96d56Sopenharmony_ciclass itertools.permutations "permutationsobject *" "&permutations_type" 277db96d56Sopenharmony_ciclass itertools.accumulate "accumulateobject *" "&accumulate_type" 287db96d56Sopenharmony_ciclass itertools.compress "compressobject *" "&compress_type" 297db96d56Sopenharmony_ciclass itertools.filterfalse "filterfalseobject *" "&filterfalse_type" 307db96d56Sopenharmony_ciclass itertools.count "countobject *" "&count_type" 317db96d56Sopenharmony_ciclass itertools.pairwise "pairwiseobject *" "&pairwise_type" 327db96d56Sopenharmony_ci[clinic start generated code]*/ 337db96d56Sopenharmony_ci/*[clinic end generated code: output=da39a3ee5e6b4b0d input=6498ed21fbe1bf94]*/ 347db96d56Sopenharmony_ci 357db96d56Sopenharmony_cistatic PyTypeObject groupby_type; 367db96d56Sopenharmony_cistatic PyTypeObject _grouper_type; 377db96d56Sopenharmony_cistatic PyTypeObject teedataobject_type; 387db96d56Sopenharmony_cistatic PyTypeObject tee_type; 397db96d56Sopenharmony_cistatic PyTypeObject cycle_type; 407db96d56Sopenharmony_cistatic PyTypeObject dropwhile_type; 417db96d56Sopenharmony_cistatic PyTypeObject takewhile_type; 427db96d56Sopenharmony_cistatic PyTypeObject starmap_type; 437db96d56Sopenharmony_cistatic PyTypeObject combinations_type; 447db96d56Sopenharmony_cistatic PyTypeObject cwr_type; 457db96d56Sopenharmony_cistatic PyTypeObject permutations_type; 467db96d56Sopenharmony_cistatic PyTypeObject accumulate_type; 477db96d56Sopenharmony_cistatic PyTypeObject compress_type; 487db96d56Sopenharmony_cistatic PyTypeObject filterfalse_type; 497db96d56Sopenharmony_cistatic PyTypeObject count_type; 507db96d56Sopenharmony_cistatic PyTypeObject pairwise_type; 517db96d56Sopenharmony_ci 527db96d56Sopenharmony_ci#include "clinic/itertoolsmodule.c.h" 537db96d56Sopenharmony_ci 547db96d56Sopenharmony_ci/* pairwise object ***********************************************************/ 557db96d56Sopenharmony_ci 567db96d56Sopenharmony_citypedef struct { 577db96d56Sopenharmony_ci PyObject_HEAD 587db96d56Sopenharmony_ci PyObject *it; 597db96d56Sopenharmony_ci PyObject *old; 607db96d56Sopenharmony_ci} pairwiseobject; 617db96d56Sopenharmony_ci 627db96d56Sopenharmony_ci/*[clinic input] 637db96d56Sopenharmony_ci@classmethod 647db96d56Sopenharmony_ciitertools.pairwise.__new__ as pairwise_new 657db96d56Sopenharmony_ci iterable: object 667db96d56Sopenharmony_ci / 677db96d56Sopenharmony_ciReturn an iterator of overlapping pairs taken from the input iterator. 687db96d56Sopenharmony_ci 697db96d56Sopenharmony_ci s -> (s0,s1), (s1,s2), (s2, s3), ... 707db96d56Sopenharmony_ci 717db96d56Sopenharmony_ci[clinic start generated code]*/ 727db96d56Sopenharmony_ci 737db96d56Sopenharmony_cistatic PyObject * 747db96d56Sopenharmony_cipairwise_new_impl(PyTypeObject *type, PyObject *iterable) 757db96d56Sopenharmony_ci/*[clinic end generated code: output=9f0267062d384456 input=6e7c3cddb431a8d6]*/ 767db96d56Sopenharmony_ci{ 777db96d56Sopenharmony_ci PyObject *it; 787db96d56Sopenharmony_ci pairwiseobject *po; 797db96d56Sopenharmony_ci 807db96d56Sopenharmony_ci it = PyObject_GetIter(iterable); 817db96d56Sopenharmony_ci if (it == NULL) { 827db96d56Sopenharmony_ci return NULL; 837db96d56Sopenharmony_ci } 847db96d56Sopenharmony_ci po = (pairwiseobject *)type->tp_alloc(type, 0); 857db96d56Sopenharmony_ci if (po == NULL) { 867db96d56Sopenharmony_ci Py_DECREF(it); 877db96d56Sopenharmony_ci return NULL; 887db96d56Sopenharmony_ci } 897db96d56Sopenharmony_ci po->it = it; 907db96d56Sopenharmony_ci po->old = NULL; 917db96d56Sopenharmony_ci return (PyObject *)po; 927db96d56Sopenharmony_ci} 937db96d56Sopenharmony_ci 947db96d56Sopenharmony_cistatic void 957db96d56Sopenharmony_cipairwise_dealloc(pairwiseobject *po) 967db96d56Sopenharmony_ci{ 977db96d56Sopenharmony_ci PyObject_GC_UnTrack(po); 987db96d56Sopenharmony_ci Py_XDECREF(po->it); 997db96d56Sopenharmony_ci Py_XDECREF(po->old); 1007db96d56Sopenharmony_ci Py_TYPE(po)->tp_free(po); 1017db96d56Sopenharmony_ci} 1027db96d56Sopenharmony_ci 1037db96d56Sopenharmony_cistatic int 1047db96d56Sopenharmony_cipairwise_traverse(pairwiseobject *po, visitproc visit, void *arg) 1057db96d56Sopenharmony_ci{ 1067db96d56Sopenharmony_ci Py_VISIT(po->it); 1077db96d56Sopenharmony_ci Py_VISIT(po->old); 1087db96d56Sopenharmony_ci return 0; 1097db96d56Sopenharmony_ci} 1107db96d56Sopenharmony_ci 1117db96d56Sopenharmony_cistatic PyObject * 1127db96d56Sopenharmony_cipairwise_next(pairwiseobject *po) 1137db96d56Sopenharmony_ci{ 1147db96d56Sopenharmony_ci PyObject *it = po->it; 1157db96d56Sopenharmony_ci PyObject *old = po->old; 1167db96d56Sopenharmony_ci PyObject *new, *result; 1177db96d56Sopenharmony_ci 1187db96d56Sopenharmony_ci if (it == NULL) { 1197db96d56Sopenharmony_ci return NULL; 1207db96d56Sopenharmony_ci } 1217db96d56Sopenharmony_ci if (old == NULL) { 1227db96d56Sopenharmony_ci po->old = old = (*Py_TYPE(it)->tp_iternext)(it); 1237db96d56Sopenharmony_ci if (old == NULL) { 1247db96d56Sopenharmony_ci Py_CLEAR(po->it); 1257db96d56Sopenharmony_ci return NULL; 1267db96d56Sopenharmony_ci } 1277db96d56Sopenharmony_ci } 1287db96d56Sopenharmony_ci new = (*Py_TYPE(it)->tp_iternext)(it); 1297db96d56Sopenharmony_ci if (new == NULL) { 1307db96d56Sopenharmony_ci Py_CLEAR(po->it); 1317db96d56Sopenharmony_ci Py_CLEAR(po->old); 1327db96d56Sopenharmony_ci return NULL; 1337db96d56Sopenharmony_ci } 1347db96d56Sopenharmony_ci /* Future optimization: Reuse the result tuple as we do in enumerate() */ 1357db96d56Sopenharmony_ci result = PyTuple_Pack(2, old, new); 1367db96d56Sopenharmony_ci Py_SETREF(po->old, new); 1377db96d56Sopenharmony_ci return result; 1387db96d56Sopenharmony_ci} 1397db96d56Sopenharmony_ci 1407db96d56Sopenharmony_cistatic PyTypeObject pairwise_type = { 1417db96d56Sopenharmony_ci PyVarObject_HEAD_INIT(&PyType_Type, 0) 1427db96d56Sopenharmony_ci "itertools.pairwise", /* tp_name */ 1437db96d56Sopenharmony_ci sizeof(pairwiseobject), /* tp_basicsize */ 1447db96d56Sopenharmony_ci 0, /* tp_itemsize */ 1457db96d56Sopenharmony_ci /* methods */ 1467db96d56Sopenharmony_ci (destructor)pairwise_dealloc, /* tp_dealloc */ 1477db96d56Sopenharmony_ci 0, /* tp_vectorcall_offset */ 1487db96d56Sopenharmony_ci 0, /* tp_getattr */ 1497db96d56Sopenharmony_ci 0, /* tp_setattr */ 1507db96d56Sopenharmony_ci 0, /* tp_as_async */ 1517db96d56Sopenharmony_ci 0, /* tp_repr */ 1527db96d56Sopenharmony_ci 0, /* tp_as_number */ 1537db96d56Sopenharmony_ci 0, /* tp_as_sequence */ 1547db96d56Sopenharmony_ci 0, /* tp_as_mapping */ 1557db96d56Sopenharmony_ci 0, /* tp_hash */ 1567db96d56Sopenharmony_ci 0, /* tp_call */ 1577db96d56Sopenharmony_ci 0, /* tp_str */ 1587db96d56Sopenharmony_ci PyObject_GenericGetAttr, /* tp_getattro */ 1597db96d56Sopenharmony_ci 0, /* tp_setattro */ 1607db96d56Sopenharmony_ci 0, /* tp_as_buffer */ 1617db96d56Sopenharmony_ci Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | 1627db96d56Sopenharmony_ci Py_TPFLAGS_BASETYPE, /* tp_flags */ 1637db96d56Sopenharmony_ci pairwise_new__doc__, /* tp_doc */ 1647db96d56Sopenharmony_ci (traverseproc)pairwise_traverse, /* tp_traverse */ 1657db96d56Sopenharmony_ci 0, /* tp_clear */ 1667db96d56Sopenharmony_ci 0, /* tp_richcompare */ 1677db96d56Sopenharmony_ci 0, /* tp_weaklistoffset */ 1687db96d56Sopenharmony_ci PyObject_SelfIter, /* tp_iter */ 1697db96d56Sopenharmony_ci (iternextfunc)pairwise_next, /* tp_iternext */ 1707db96d56Sopenharmony_ci 0, /* tp_methods */ 1717db96d56Sopenharmony_ci 0, /* tp_members */ 1727db96d56Sopenharmony_ci 0, /* tp_getset */ 1737db96d56Sopenharmony_ci 0, /* tp_base */ 1747db96d56Sopenharmony_ci 0, /* tp_dict */ 1757db96d56Sopenharmony_ci 0, /* tp_descr_get */ 1767db96d56Sopenharmony_ci 0, /* tp_descr_set */ 1777db96d56Sopenharmony_ci 0, /* tp_dictoffset */ 1787db96d56Sopenharmony_ci 0, /* tp_init */ 1797db96d56Sopenharmony_ci PyType_GenericAlloc, /* tp_alloc */ 1807db96d56Sopenharmony_ci pairwise_new, /* tp_new */ 1817db96d56Sopenharmony_ci PyObject_GC_Del, /* tp_free */ 1827db96d56Sopenharmony_ci}; 1837db96d56Sopenharmony_ci 1847db96d56Sopenharmony_ci 1857db96d56Sopenharmony_ci/* groupby object ************************************************************/ 1867db96d56Sopenharmony_ci 1877db96d56Sopenharmony_citypedef struct { 1887db96d56Sopenharmony_ci PyObject_HEAD 1897db96d56Sopenharmony_ci PyObject *it; 1907db96d56Sopenharmony_ci PyObject *keyfunc; 1917db96d56Sopenharmony_ci PyObject *tgtkey; 1927db96d56Sopenharmony_ci PyObject *currkey; 1937db96d56Sopenharmony_ci PyObject *currvalue; 1947db96d56Sopenharmony_ci const void *currgrouper; /* borrowed reference */ 1957db96d56Sopenharmony_ci} groupbyobject; 1967db96d56Sopenharmony_ci 1977db96d56Sopenharmony_cistatic PyObject *_grouper_create(groupbyobject *, PyObject *); 1987db96d56Sopenharmony_ci 1997db96d56Sopenharmony_ci/*[clinic input] 2007db96d56Sopenharmony_ci@classmethod 2017db96d56Sopenharmony_ciitertools.groupby.__new__ 2027db96d56Sopenharmony_ci 2037db96d56Sopenharmony_ci iterable as it: object 2047db96d56Sopenharmony_ci Elements to divide into groups according to the key function. 2057db96d56Sopenharmony_ci key as keyfunc: object = None 2067db96d56Sopenharmony_ci A function for computing the group category for each element. 2077db96d56Sopenharmony_ci If the key function is not specified or is None, the element itself 2087db96d56Sopenharmony_ci is used for grouping. 2097db96d56Sopenharmony_ci 2107db96d56Sopenharmony_cimake an iterator that returns consecutive keys and groups from the iterable 2117db96d56Sopenharmony_ci[clinic start generated code]*/ 2127db96d56Sopenharmony_ci 2137db96d56Sopenharmony_cistatic PyObject * 2147db96d56Sopenharmony_ciitertools_groupby_impl(PyTypeObject *type, PyObject *it, PyObject *keyfunc) 2157db96d56Sopenharmony_ci/*[clinic end generated code: output=cbb1ae3a90fd4141 input=6b3d123e87ff65a1]*/ 2167db96d56Sopenharmony_ci{ 2177db96d56Sopenharmony_ci groupbyobject *gbo; 2187db96d56Sopenharmony_ci 2197db96d56Sopenharmony_ci gbo = (groupbyobject *)type->tp_alloc(type, 0); 2207db96d56Sopenharmony_ci if (gbo == NULL) 2217db96d56Sopenharmony_ci return NULL; 2227db96d56Sopenharmony_ci gbo->tgtkey = NULL; 2237db96d56Sopenharmony_ci gbo->currkey = NULL; 2247db96d56Sopenharmony_ci gbo->currvalue = NULL; 2257db96d56Sopenharmony_ci gbo->keyfunc = keyfunc; 2267db96d56Sopenharmony_ci Py_INCREF(keyfunc); 2277db96d56Sopenharmony_ci gbo->it = PyObject_GetIter(it); 2287db96d56Sopenharmony_ci if (gbo->it == NULL) { 2297db96d56Sopenharmony_ci Py_DECREF(gbo); 2307db96d56Sopenharmony_ci return NULL; 2317db96d56Sopenharmony_ci } 2327db96d56Sopenharmony_ci return (PyObject *)gbo; 2337db96d56Sopenharmony_ci} 2347db96d56Sopenharmony_ci 2357db96d56Sopenharmony_cistatic void 2367db96d56Sopenharmony_cigroupby_dealloc(groupbyobject *gbo) 2377db96d56Sopenharmony_ci{ 2387db96d56Sopenharmony_ci PyObject_GC_UnTrack(gbo); 2397db96d56Sopenharmony_ci Py_XDECREF(gbo->it); 2407db96d56Sopenharmony_ci Py_XDECREF(gbo->keyfunc); 2417db96d56Sopenharmony_ci Py_XDECREF(gbo->tgtkey); 2427db96d56Sopenharmony_ci Py_XDECREF(gbo->currkey); 2437db96d56Sopenharmony_ci Py_XDECREF(gbo->currvalue); 2447db96d56Sopenharmony_ci Py_TYPE(gbo)->tp_free(gbo); 2457db96d56Sopenharmony_ci} 2467db96d56Sopenharmony_ci 2477db96d56Sopenharmony_cistatic int 2487db96d56Sopenharmony_cigroupby_traverse(groupbyobject *gbo, visitproc visit, void *arg) 2497db96d56Sopenharmony_ci{ 2507db96d56Sopenharmony_ci Py_VISIT(gbo->it); 2517db96d56Sopenharmony_ci Py_VISIT(gbo->keyfunc); 2527db96d56Sopenharmony_ci Py_VISIT(gbo->tgtkey); 2537db96d56Sopenharmony_ci Py_VISIT(gbo->currkey); 2547db96d56Sopenharmony_ci Py_VISIT(gbo->currvalue); 2557db96d56Sopenharmony_ci return 0; 2567db96d56Sopenharmony_ci} 2577db96d56Sopenharmony_ci 2587db96d56Sopenharmony_ciPy_LOCAL_INLINE(int) 2597db96d56Sopenharmony_cigroupby_step(groupbyobject *gbo) 2607db96d56Sopenharmony_ci{ 2617db96d56Sopenharmony_ci PyObject *newvalue, *newkey, *oldvalue; 2627db96d56Sopenharmony_ci 2637db96d56Sopenharmony_ci newvalue = PyIter_Next(gbo->it); 2647db96d56Sopenharmony_ci if (newvalue == NULL) 2657db96d56Sopenharmony_ci return -1; 2667db96d56Sopenharmony_ci 2677db96d56Sopenharmony_ci if (gbo->keyfunc == Py_None) { 2687db96d56Sopenharmony_ci newkey = newvalue; 2697db96d56Sopenharmony_ci Py_INCREF(newvalue); 2707db96d56Sopenharmony_ci } else { 2717db96d56Sopenharmony_ci newkey = PyObject_CallOneArg(gbo->keyfunc, newvalue); 2727db96d56Sopenharmony_ci if (newkey == NULL) { 2737db96d56Sopenharmony_ci Py_DECREF(newvalue); 2747db96d56Sopenharmony_ci return -1; 2757db96d56Sopenharmony_ci } 2767db96d56Sopenharmony_ci } 2777db96d56Sopenharmony_ci 2787db96d56Sopenharmony_ci oldvalue = gbo->currvalue; 2797db96d56Sopenharmony_ci gbo->currvalue = newvalue; 2807db96d56Sopenharmony_ci Py_XSETREF(gbo->currkey, newkey); 2817db96d56Sopenharmony_ci Py_XDECREF(oldvalue); 2827db96d56Sopenharmony_ci return 0; 2837db96d56Sopenharmony_ci} 2847db96d56Sopenharmony_ci 2857db96d56Sopenharmony_cistatic PyObject * 2867db96d56Sopenharmony_cigroupby_next(groupbyobject *gbo) 2877db96d56Sopenharmony_ci{ 2887db96d56Sopenharmony_ci PyObject *r, *grouper; 2897db96d56Sopenharmony_ci 2907db96d56Sopenharmony_ci gbo->currgrouper = NULL; 2917db96d56Sopenharmony_ci /* skip to next iteration group */ 2927db96d56Sopenharmony_ci for (;;) { 2937db96d56Sopenharmony_ci if (gbo->currkey == NULL) 2947db96d56Sopenharmony_ci /* pass */; 2957db96d56Sopenharmony_ci else if (gbo->tgtkey == NULL) 2967db96d56Sopenharmony_ci break; 2977db96d56Sopenharmony_ci else { 2987db96d56Sopenharmony_ci int rcmp; 2997db96d56Sopenharmony_ci 3007db96d56Sopenharmony_ci rcmp = PyObject_RichCompareBool(gbo->tgtkey, gbo->currkey, Py_EQ); 3017db96d56Sopenharmony_ci if (rcmp == -1) 3027db96d56Sopenharmony_ci return NULL; 3037db96d56Sopenharmony_ci else if (rcmp == 0) 3047db96d56Sopenharmony_ci break; 3057db96d56Sopenharmony_ci } 3067db96d56Sopenharmony_ci 3077db96d56Sopenharmony_ci if (groupby_step(gbo) < 0) 3087db96d56Sopenharmony_ci return NULL; 3097db96d56Sopenharmony_ci } 3107db96d56Sopenharmony_ci Py_INCREF(gbo->currkey); 3117db96d56Sopenharmony_ci Py_XSETREF(gbo->tgtkey, gbo->currkey); 3127db96d56Sopenharmony_ci 3137db96d56Sopenharmony_ci grouper = _grouper_create(gbo, gbo->tgtkey); 3147db96d56Sopenharmony_ci if (grouper == NULL) 3157db96d56Sopenharmony_ci return NULL; 3167db96d56Sopenharmony_ci 3177db96d56Sopenharmony_ci r = PyTuple_Pack(2, gbo->currkey, grouper); 3187db96d56Sopenharmony_ci Py_DECREF(grouper); 3197db96d56Sopenharmony_ci return r; 3207db96d56Sopenharmony_ci} 3217db96d56Sopenharmony_ci 3227db96d56Sopenharmony_cistatic PyObject * 3237db96d56Sopenharmony_cigroupby_reduce(groupbyobject *lz, PyObject *Py_UNUSED(ignored)) 3247db96d56Sopenharmony_ci{ 3257db96d56Sopenharmony_ci /* reduce as a 'new' call with an optional 'setstate' if groupby 3267db96d56Sopenharmony_ci * has started 3277db96d56Sopenharmony_ci */ 3287db96d56Sopenharmony_ci PyObject *value; 3297db96d56Sopenharmony_ci if (lz->tgtkey && lz->currkey && lz->currvalue) 3307db96d56Sopenharmony_ci value = Py_BuildValue("O(OO)(OOO)", Py_TYPE(lz), 3317db96d56Sopenharmony_ci lz->it, lz->keyfunc, lz->currkey, lz->currvalue, lz->tgtkey); 3327db96d56Sopenharmony_ci else 3337db96d56Sopenharmony_ci value = Py_BuildValue("O(OO)", Py_TYPE(lz), 3347db96d56Sopenharmony_ci lz->it, lz->keyfunc); 3357db96d56Sopenharmony_ci 3367db96d56Sopenharmony_ci return value; 3377db96d56Sopenharmony_ci} 3387db96d56Sopenharmony_ci 3397db96d56Sopenharmony_ciPyDoc_STRVAR(reduce_doc, "Return state information for pickling."); 3407db96d56Sopenharmony_ci 3417db96d56Sopenharmony_cistatic PyObject * 3427db96d56Sopenharmony_cigroupby_setstate(groupbyobject *lz, PyObject *state) 3437db96d56Sopenharmony_ci{ 3447db96d56Sopenharmony_ci PyObject *currkey, *currvalue, *tgtkey; 3457db96d56Sopenharmony_ci if (!PyTuple_Check(state)) { 3467db96d56Sopenharmony_ci PyErr_SetString(PyExc_TypeError, "state is not a tuple"); 3477db96d56Sopenharmony_ci return NULL; 3487db96d56Sopenharmony_ci } 3497db96d56Sopenharmony_ci if (!PyArg_ParseTuple(state, "OOO", &currkey, &currvalue, &tgtkey)) { 3507db96d56Sopenharmony_ci return NULL; 3517db96d56Sopenharmony_ci } 3527db96d56Sopenharmony_ci Py_INCREF(currkey); 3537db96d56Sopenharmony_ci Py_XSETREF(lz->currkey, currkey); 3547db96d56Sopenharmony_ci Py_INCREF(currvalue); 3557db96d56Sopenharmony_ci Py_XSETREF(lz->currvalue, currvalue); 3567db96d56Sopenharmony_ci Py_INCREF(tgtkey); 3577db96d56Sopenharmony_ci Py_XSETREF(lz->tgtkey, tgtkey); 3587db96d56Sopenharmony_ci Py_RETURN_NONE; 3597db96d56Sopenharmony_ci} 3607db96d56Sopenharmony_ci 3617db96d56Sopenharmony_ciPyDoc_STRVAR(setstate_doc, "Set state information for unpickling."); 3627db96d56Sopenharmony_ci 3637db96d56Sopenharmony_cistatic PyMethodDef groupby_methods[] = { 3647db96d56Sopenharmony_ci {"__reduce__", (PyCFunction)groupby_reduce, METH_NOARGS, 3657db96d56Sopenharmony_ci reduce_doc}, 3667db96d56Sopenharmony_ci {"__setstate__", (PyCFunction)groupby_setstate, METH_O, 3677db96d56Sopenharmony_ci setstate_doc}, 3687db96d56Sopenharmony_ci {NULL, NULL} /* sentinel */ 3697db96d56Sopenharmony_ci}; 3707db96d56Sopenharmony_ci 3717db96d56Sopenharmony_cistatic PyTypeObject groupby_type = { 3727db96d56Sopenharmony_ci PyVarObject_HEAD_INIT(NULL, 0) 3737db96d56Sopenharmony_ci "itertools.groupby", /* tp_name */ 3747db96d56Sopenharmony_ci sizeof(groupbyobject), /* tp_basicsize */ 3757db96d56Sopenharmony_ci 0, /* tp_itemsize */ 3767db96d56Sopenharmony_ci /* methods */ 3777db96d56Sopenharmony_ci (destructor)groupby_dealloc, /* tp_dealloc */ 3787db96d56Sopenharmony_ci 0, /* tp_vectorcall_offset */ 3797db96d56Sopenharmony_ci 0, /* tp_getattr */ 3807db96d56Sopenharmony_ci 0, /* tp_setattr */ 3817db96d56Sopenharmony_ci 0, /* tp_as_async */ 3827db96d56Sopenharmony_ci 0, /* tp_repr */ 3837db96d56Sopenharmony_ci 0, /* tp_as_number */ 3847db96d56Sopenharmony_ci 0, /* tp_as_sequence */ 3857db96d56Sopenharmony_ci 0, /* tp_as_mapping */ 3867db96d56Sopenharmony_ci 0, /* tp_hash */ 3877db96d56Sopenharmony_ci 0, /* tp_call */ 3887db96d56Sopenharmony_ci 0, /* tp_str */ 3897db96d56Sopenharmony_ci PyObject_GenericGetAttr, /* tp_getattro */ 3907db96d56Sopenharmony_ci 0, /* tp_setattro */ 3917db96d56Sopenharmony_ci 0, /* tp_as_buffer */ 3927db96d56Sopenharmony_ci Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | 3937db96d56Sopenharmony_ci Py_TPFLAGS_BASETYPE, /* tp_flags */ 3947db96d56Sopenharmony_ci itertools_groupby__doc__, /* tp_doc */ 3957db96d56Sopenharmony_ci (traverseproc)groupby_traverse, /* tp_traverse */ 3967db96d56Sopenharmony_ci 0, /* tp_clear */ 3977db96d56Sopenharmony_ci 0, /* tp_richcompare */ 3987db96d56Sopenharmony_ci 0, /* tp_weaklistoffset */ 3997db96d56Sopenharmony_ci PyObject_SelfIter, /* tp_iter */ 4007db96d56Sopenharmony_ci (iternextfunc)groupby_next, /* tp_iternext */ 4017db96d56Sopenharmony_ci groupby_methods, /* tp_methods */ 4027db96d56Sopenharmony_ci 0, /* tp_members */ 4037db96d56Sopenharmony_ci 0, /* tp_getset */ 4047db96d56Sopenharmony_ci 0, /* tp_base */ 4057db96d56Sopenharmony_ci 0, /* tp_dict */ 4067db96d56Sopenharmony_ci 0, /* tp_descr_get */ 4077db96d56Sopenharmony_ci 0, /* tp_descr_set */ 4087db96d56Sopenharmony_ci 0, /* tp_dictoffset */ 4097db96d56Sopenharmony_ci 0, /* tp_init */ 4107db96d56Sopenharmony_ci 0, /* tp_alloc */ 4117db96d56Sopenharmony_ci itertools_groupby, /* tp_new */ 4127db96d56Sopenharmony_ci PyObject_GC_Del, /* tp_free */ 4137db96d56Sopenharmony_ci}; 4147db96d56Sopenharmony_ci 4157db96d56Sopenharmony_ci 4167db96d56Sopenharmony_ci/* _grouper object (internal) ************************************************/ 4177db96d56Sopenharmony_ci 4187db96d56Sopenharmony_citypedef struct { 4197db96d56Sopenharmony_ci PyObject_HEAD 4207db96d56Sopenharmony_ci PyObject *parent; 4217db96d56Sopenharmony_ci PyObject *tgtkey; 4227db96d56Sopenharmony_ci} _grouperobject; 4237db96d56Sopenharmony_ci 4247db96d56Sopenharmony_ci/*[clinic input] 4257db96d56Sopenharmony_ci@classmethod 4267db96d56Sopenharmony_ciitertools._grouper.__new__ 4277db96d56Sopenharmony_ci 4287db96d56Sopenharmony_ci parent: object(subclass_of='&groupby_type') 4297db96d56Sopenharmony_ci tgtkey: object 4307db96d56Sopenharmony_ci / 4317db96d56Sopenharmony_ci[clinic start generated code]*/ 4327db96d56Sopenharmony_ci 4337db96d56Sopenharmony_cistatic PyObject * 4347db96d56Sopenharmony_ciitertools__grouper_impl(PyTypeObject *type, PyObject *parent, 4357db96d56Sopenharmony_ci PyObject *tgtkey) 4367db96d56Sopenharmony_ci/*[clinic end generated code: output=462efb1cdebb5914 input=dc180d7771fc8c59]*/ 4377db96d56Sopenharmony_ci{ 4387db96d56Sopenharmony_ci return _grouper_create((groupbyobject*) parent, tgtkey); 4397db96d56Sopenharmony_ci} 4407db96d56Sopenharmony_ci 4417db96d56Sopenharmony_cistatic PyObject * 4427db96d56Sopenharmony_ci_grouper_create(groupbyobject *parent, PyObject *tgtkey) 4437db96d56Sopenharmony_ci{ 4447db96d56Sopenharmony_ci _grouperobject *igo; 4457db96d56Sopenharmony_ci 4467db96d56Sopenharmony_ci igo = PyObject_GC_New(_grouperobject, &_grouper_type); 4477db96d56Sopenharmony_ci if (igo == NULL) 4487db96d56Sopenharmony_ci return NULL; 4497db96d56Sopenharmony_ci igo->parent = (PyObject *)parent; 4507db96d56Sopenharmony_ci Py_INCREF(parent); 4517db96d56Sopenharmony_ci igo->tgtkey = tgtkey; 4527db96d56Sopenharmony_ci Py_INCREF(tgtkey); 4537db96d56Sopenharmony_ci parent->currgrouper = igo; /* borrowed reference */ 4547db96d56Sopenharmony_ci 4557db96d56Sopenharmony_ci PyObject_GC_Track(igo); 4567db96d56Sopenharmony_ci return (PyObject *)igo; 4577db96d56Sopenharmony_ci} 4587db96d56Sopenharmony_ci 4597db96d56Sopenharmony_cistatic void 4607db96d56Sopenharmony_ci_grouper_dealloc(_grouperobject *igo) 4617db96d56Sopenharmony_ci{ 4627db96d56Sopenharmony_ci PyObject_GC_UnTrack(igo); 4637db96d56Sopenharmony_ci Py_DECREF(igo->parent); 4647db96d56Sopenharmony_ci Py_DECREF(igo->tgtkey); 4657db96d56Sopenharmony_ci PyObject_GC_Del(igo); 4667db96d56Sopenharmony_ci} 4677db96d56Sopenharmony_ci 4687db96d56Sopenharmony_cistatic int 4697db96d56Sopenharmony_ci_grouper_traverse(_grouperobject *igo, visitproc visit, void *arg) 4707db96d56Sopenharmony_ci{ 4717db96d56Sopenharmony_ci Py_VISIT(igo->parent); 4727db96d56Sopenharmony_ci Py_VISIT(igo->tgtkey); 4737db96d56Sopenharmony_ci return 0; 4747db96d56Sopenharmony_ci} 4757db96d56Sopenharmony_ci 4767db96d56Sopenharmony_cistatic PyObject * 4777db96d56Sopenharmony_ci_grouper_next(_grouperobject *igo) 4787db96d56Sopenharmony_ci{ 4797db96d56Sopenharmony_ci groupbyobject *gbo = (groupbyobject *)igo->parent; 4807db96d56Sopenharmony_ci PyObject *r; 4817db96d56Sopenharmony_ci int rcmp; 4827db96d56Sopenharmony_ci 4837db96d56Sopenharmony_ci if (gbo->currgrouper != igo) 4847db96d56Sopenharmony_ci return NULL; 4857db96d56Sopenharmony_ci if (gbo->currvalue == NULL) { 4867db96d56Sopenharmony_ci if (groupby_step(gbo) < 0) 4877db96d56Sopenharmony_ci return NULL; 4887db96d56Sopenharmony_ci } 4897db96d56Sopenharmony_ci 4907db96d56Sopenharmony_ci assert(gbo->currkey != NULL); 4917db96d56Sopenharmony_ci rcmp = PyObject_RichCompareBool(igo->tgtkey, gbo->currkey, Py_EQ); 4927db96d56Sopenharmony_ci if (rcmp <= 0) 4937db96d56Sopenharmony_ci /* got any error or current group is end */ 4947db96d56Sopenharmony_ci return NULL; 4957db96d56Sopenharmony_ci 4967db96d56Sopenharmony_ci r = gbo->currvalue; 4977db96d56Sopenharmony_ci gbo->currvalue = NULL; 4987db96d56Sopenharmony_ci Py_CLEAR(gbo->currkey); 4997db96d56Sopenharmony_ci 5007db96d56Sopenharmony_ci return r; 5017db96d56Sopenharmony_ci} 5027db96d56Sopenharmony_ci 5037db96d56Sopenharmony_cistatic PyObject * 5047db96d56Sopenharmony_ci_grouper_reduce(_grouperobject *lz, PyObject *Py_UNUSED(ignored)) 5057db96d56Sopenharmony_ci{ 5067db96d56Sopenharmony_ci if (((groupbyobject *)lz->parent)->currgrouper != lz) { 5077db96d56Sopenharmony_ci return Py_BuildValue("N(())", _PyEval_GetBuiltin(&_Py_ID(iter))); 5087db96d56Sopenharmony_ci } 5097db96d56Sopenharmony_ci return Py_BuildValue("O(OO)", Py_TYPE(lz), lz->parent, lz->tgtkey); 5107db96d56Sopenharmony_ci} 5117db96d56Sopenharmony_ci 5127db96d56Sopenharmony_cistatic PyMethodDef _grouper_methods[] = { 5137db96d56Sopenharmony_ci {"__reduce__", (PyCFunction)_grouper_reduce, METH_NOARGS, 5147db96d56Sopenharmony_ci reduce_doc}, 5157db96d56Sopenharmony_ci {NULL, NULL} /* sentinel */ 5167db96d56Sopenharmony_ci}; 5177db96d56Sopenharmony_ci 5187db96d56Sopenharmony_ci 5197db96d56Sopenharmony_cistatic PyTypeObject _grouper_type = { 5207db96d56Sopenharmony_ci PyVarObject_HEAD_INIT(NULL, 0) 5217db96d56Sopenharmony_ci "itertools._grouper", /* tp_name */ 5227db96d56Sopenharmony_ci sizeof(_grouperobject), /* tp_basicsize */ 5237db96d56Sopenharmony_ci 0, /* tp_itemsize */ 5247db96d56Sopenharmony_ci /* methods */ 5257db96d56Sopenharmony_ci (destructor)_grouper_dealloc, /* tp_dealloc */ 5267db96d56Sopenharmony_ci 0, /* tp_vectorcall_offset */ 5277db96d56Sopenharmony_ci 0, /* tp_getattr */ 5287db96d56Sopenharmony_ci 0, /* tp_setattr */ 5297db96d56Sopenharmony_ci 0, /* tp_as_async */ 5307db96d56Sopenharmony_ci 0, /* tp_repr */ 5317db96d56Sopenharmony_ci 0, /* tp_as_number */ 5327db96d56Sopenharmony_ci 0, /* tp_as_sequence */ 5337db96d56Sopenharmony_ci 0, /* tp_as_mapping */ 5347db96d56Sopenharmony_ci 0, /* tp_hash */ 5357db96d56Sopenharmony_ci 0, /* tp_call */ 5367db96d56Sopenharmony_ci 0, /* tp_str */ 5377db96d56Sopenharmony_ci PyObject_GenericGetAttr, /* tp_getattro */ 5387db96d56Sopenharmony_ci 0, /* tp_setattro */ 5397db96d56Sopenharmony_ci 0, /* tp_as_buffer */ 5407db96d56Sopenharmony_ci Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */ 5417db96d56Sopenharmony_ci 0, /* tp_doc */ 5427db96d56Sopenharmony_ci (traverseproc)_grouper_traverse, /* tp_traverse */ 5437db96d56Sopenharmony_ci 0, /* tp_clear */ 5447db96d56Sopenharmony_ci 0, /* tp_richcompare */ 5457db96d56Sopenharmony_ci 0, /* tp_weaklistoffset */ 5467db96d56Sopenharmony_ci PyObject_SelfIter, /* tp_iter */ 5477db96d56Sopenharmony_ci (iternextfunc)_grouper_next, /* tp_iternext */ 5487db96d56Sopenharmony_ci _grouper_methods, /* tp_methods */ 5497db96d56Sopenharmony_ci 0, /* tp_members */ 5507db96d56Sopenharmony_ci 0, /* tp_getset */ 5517db96d56Sopenharmony_ci 0, /* tp_base */ 5527db96d56Sopenharmony_ci 0, /* tp_dict */ 5537db96d56Sopenharmony_ci 0, /* tp_descr_get */ 5547db96d56Sopenharmony_ci 0, /* tp_descr_set */ 5557db96d56Sopenharmony_ci 0, /* tp_dictoffset */ 5567db96d56Sopenharmony_ci 0, /* tp_init */ 5577db96d56Sopenharmony_ci 0, /* tp_alloc */ 5587db96d56Sopenharmony_ci itertools__grouper, /* tp_new */ 5597db96d56Sopenharmony_ci PyObject_GC_Del, /* tp_free */ 5607db96d56Sopenharmony_ci}; 5617db96d56Sopenharmony_ci 5627db96d56Sopenharmony_ci 5637db96d56Sopenharmony_ci/* tee object and with supporting function and objects ***********************/ 5647db96d56Sopenharmony_ci 5657db96d56Sopenharmony_ci/* The teedataobject pre-allocates space for LINKCELLS number of objects. 5667db96d56Sopenharmony_ci To help the object fit neatly inside cache lines (space for 16 to 32 5677db96d56Sopenharmony_ci pointers), the value should be a multiple of 16 minus space for 5687db96d56Sopenharmony_ci the other structure members including PyHEAD overhead. The larger the 5697db96d56Sopenharmony_ci value, the less memory overhead per object and the less time spent 5707db96d56Sopenharmony_ci allocating/deallocating new links. The smaller the number, the less 5717db96d56Sopenharmony_ci wasted space and the more rapid freeing of older data. 5727db96d56Sopenharmony_ci*/ 5737db96d56Sopenharmony_ci#define LINKCELLS 57 5747db96d56Sopenharmony_ci 5757db96d56Sopenharmony_citypedef struct { 5767db96d56Sopenharmony_ci PyObject_HEAD 5777db96d56Sopenharmony_ci PyObject *it; 5787db96d56Sopenharmony_ci int numread; /* 0 <= numread <= LINKCELLS */ 5797db96d56Sopenharmony_ci int running; 5807db96d56Sopenharmony_ci PyObject *nextlink; 5817db96d56Sopenharmony_ci PyObject *(values[LINKCELLS]); 5827db96d56Sopenharmony_ci} teedataobject; 5837db96d56Sopenharmony_ci 5847db96d56Sopenharmony_citypedef struct { 5857db96d56Sopenharmony_ci PyObject_HEAD 5867db96d56Sopenharmony_ci teedataobject *dataobj; 5877db96d56Sopenharmony_ci int index; /* 0 <= index <= LINKCELLS */ 5887db96d56Sopenharmony_ci PyObject *weakreflist; 5897db96d56Sopenharmony_ci} teeobject; 5907db96d56Sopenharmony_ci 5917db96d56Sopenharmony_cistatic PyObject * 5927db96d56Sopenharmony_citeedataobject_newinternal(PyObject *it) 5937db96d56Sopenharmony_ci{ 5947db96d56Sopenharmony_ci teedataobject *tdo; 5957db96d56Sopenharmony_ci 5967db96d56Sopenharmony_ci tdo = PyObject_GC_New(teedataobject, &teedataobject_type); 5977db96d56Sopenharmony_ci if (tdo == NULL) 5987db96d56Sopenharmony_ci return NULL; 5997db96d56Sopenharmony_ci 6007db96d56Sopenharmony_ci tdo->running = 0; 6017db96d56Sopenharmony_ci tdo->numread = 0; 6027db96d56Sopenharmony_ci tdo->nextlink = NULL; 6037db96d56Sopenharmony_ci Py_INCREF(it); 6047db96d56Sopenharmony_ci tdo->it = it; 6057db96d56Sopenharmony_ci PyObject_GC_Track(tdo); 6067db96d56Sopenharmony_ci return (PyObject *)tdo; 6077db96d56Sopenharmony_ci} 6087db96d56Sopenharmony_ci 6097db96d56Sopenharmony_cistatic PyObject * 6107db96d56Sopenharmony_citeedataobject_jumplink(teedataobject *tdo) 6117db96d56Sopenharmony_ci{ 6127db96d56Sopenharmony_ci if (tdo->nextlink == NULL) 6137db96d56Sopenharmony_ci tdo->nextlink = teedataobject_newinternal(tdo->it); 6147db96d56Sopenharmony_ci Py_XINCREF(tdo->nextlink); 6157db96d56Sopenharmony_ci return tdo->nextlink; 6167db96d56Sopenharmony_ci} 6177db96d56Sopenharmony_ci 6187db96d56Sopenharmony_cistatic PyObject * 6197db96d56Sopenharmony_citeedataobject_getitem(teedataobject *tdo, int i) 6207db96d56Sopenharmony_ci{ 6217db96d56Sopenharmony_ci PyObject *value; 6227db96d56Sopenharmony_ci 6237db96d56Sopenharmony_ci assert(i < LINKCELLS); 6247db96d56Sopenharmony_ci if (i < tdo->numread) 6257db96d56Sopenharmony_ci value = tdo->values[i]; 6267db96d56Sopenharmony_ci else { 6277db96d56Sopenharmony_ci /* this is the lead iterator, so fetch more data */ 6287db96d56Sopenharmony_ci assert(i == tdo->numread); 6297db96d56Sopenharmony_ci if (tdo->running) { 6307db96d56Sopenharmony_ci PyErr_SetString(PyExc_RuntimeError, 6317db96d56Sopenharmony_ci "cannot re-enter the tee iterator"); 6327db96d56Sopenharmony_ci return NULL; 6337db96d56Sopenharmony_ci } 6347db96d56Sopenharmony_ci tdo->running = 1; 6357db96d56Sopenharmony_ci value = PyIter_Next(tdo->it); 6367db96d56Sopenharmony_ci tdo->running = 0; 6377db96d56Sopenharmony_ci if (value == NULL) 6387db96d56Sopenharmony_ci return NULL; 6397db96d56Sopenharmony_ci tdo->numread++; 6407db96d56Sopenharmony_ci tdo->values[i] = value; 6417db96d56Sopenharmony_ci } 6427db96d56Sopenharmony_ci Py_INCREF(value); 6437db96d56Sopenharmony_ci return value; 6447db96d56Sopenharmony_ci} 6457db96d56Sopenharmony_ci 6467db96d56Sopenharmony_cistatic int 6477db96d56Sopenharmony_citeedataobject_traverse(teedataobject *tdo, visitproc visit, void * arg) 6487db96d56Sopenharmony_ci{ 6497db96d56Sopenharmony_ci int i; 6507db96d56Sopenharmony_ci 6517db96d56Sopenharmony_ci Py_VISIT(tdo->it); 6527db96d56Sopenharmony_ci for (i = 0; i < tdo->numread; i++) 6537db96d56Sopenharmony_ci Py_VISIT(tdo->values[i]); 6547db96d56Sopenharmony_ci Py_VISIT(tdo->nextlink); 6557db96d56Sopenharmony_ci return 0; 6567db96d56Sopenharmony_ci} 6577db96d56Sopenharmony_ci 6587db96d56Sopenharmony_cistatic void 6597db96d56Sopenharmony_citeedataobject_safe_decref(PyObject *obj) 6607db96d56Sopenharmony_ci{ 6617db96d56Sopenharmony_ci while (obj && Py_IS_TYPE(obj, &teedataobject_type) && 6627db96d56Sopenharmony_ci Py_REFCNT(obj) == 1) { 6637db96d56Sopenharmony_ci PyObject *nextlink = ((teedataobject *)obj)->nextlink; 6647db96d56Sopenharmony_ci ((teedataobject *)obj)->nextlink = NULL; 6657db96d56Sopenharmony_ci Py_DECREF(obj); 6667db96d56Sopenharmony_ci obj = nextlink; 6677db96d56Sopenharmony_ci } 6687db96d56Sopenharmony_ci Py_XDECREF(obj); 6697db96d56Sopenharmony_ci} 6707db96d56Sopenharmony_ci 6717db96d56Sopenharmony_cistatic int 6727db96d56Sopenharmony_citeedataobject_clear(teedataobject *tdo) 6737db96d56Sopenharmony_ci{ 6747db96d56Sopenharmony_ci int i; 6757db96d56Sopenharmony_ci PyObject *tmp; 6767db96d56Sopenharmony_ci 6777db96d56Sopenharmony_ci Py_CLEAR(tdo->it); 6787db96d56Sopenharmony_ci for (i=0 ; i<tdo->numread ; i++) 6797db96d56Sopenharmony_ci Py_CLEAR(tdo->values[i]); 6807db96d56Sopenharmony_ci tmp = tdo->nextlink; 6817db96d56Sopenharmony_ci tdo->nextlink = NULL; 6827db96d56Sopenharmony_ci teedataobject_safe_decref(tmp); 6837db96d56Sopenharmony_ci return 0; 6847db96d56Sopenharmony_ci} 6857db96d56Sopenharmony_ci 6867db96d56Sopenharmony_cistatic void 6877db96d56Sopenharmony_citeedataobject_dealloc(teedataobject *tdo) 6887db96d56Sopenharmony_ci{ 6897db96d56Sopenharmony_ci PyObject_GC_UnTrack(tdo); 6907db96d56Sopenharmony_ci teedataobject_clear(tdo); 6917db96d56Sopenharmony_ci PyObject_GC_Del(tdo); 6927db96d56Sopenharmony_ci} 6937db96d56Sopenharmony_ci 6947db96d56Sopenharmony_cistatic PyObject * 6957db96d56Sopenharmony_citeedataobject_reduce(teedataobject *tdo, PyObject *Py_UNUSED(ignored)) 6967db96d56Sopenharmony_ci{ 6977db96d56Sopenharmony_ci int i; 6987db96d56Sopenharmony_ci /* create a temporary list of already iterated values */ 6997db96d56Sopenharmony_ci PyObject *values = PyList_New(tdo->numread); 7007db96d56Sopenharmony_ci 7017db96d56Sopenharmony_ci if (!values) 7027db96d56Sopenharmony_ci return NULL; 7037db96d56Sopenharmony_ci for (i=0 ; i<tdo->numread ; i++) { 7047db96d56Sopenharmony_ci Py_INCREF(tdo->values[i]); 7057db96d56Sopenharmony_ci PyList_SET_ITEM(values, i, tdo->values[i]); 7067db96d56Sopenharmony_ci } 7077db96d56Sopenharmony_ci return Py_BuildValue("O(ONO)", Py_TYPE(tdo), tdo->it, 7087db96d56Sopenharmony_ci values, 7097db96d56Sopenharmony_ci tdo->nextlink ? tdo->nextlink : Py_None); 7107db96d56Sopenharmony_ci} 7117db96d56Sopenharmony_ci 7127db96d56Sopenharmony_ci/*[clinic input] 7137db96d56Sopenharmony_ci@classmethod 7147db96d56Sopenharmony_ciitertools.teedataobject.__new__ 7157db96d56Sopenharmony_ci iterable as it: object 7167db96d56Sopenharmony_ci values: object(subclass_of='&PyList_Type') 7177db96d56Sopenharmony_ci next: object 7187db96d56Sopenharmony_ci / 7197db96d56Sopenharmony_ciData container common to multiple tee objects. 7207db96d56Sopenharmony_ci[clinic start generated code]*/ 7217db96d56Sopenharmony_ci 7227db96d56Sopenharmony_cistatic PyObject * 7237db96d56Sopenharmony_ciitertools_teedataobject_impl(PyTypeObject *type, PyObject *it, 7247db96d56Sopenharmony_ci PyObject *values, PyObject *next) 7257db96d56Sopenharmony_ci/*[clinic end generated code: output=3343ceb07e08df5e input=be60f2fabd2b72ba]*/ 7267db96d56Sopenharmony_ci{ 7277db96d56Sopenharmony_ci teedataobject *tdo; 7287db96d56Sopenharmony_ci Py_ssize_t i, len; 7297db96d56Sopenharmony_ci 7307db96d56Sopenharmony_ci assert(type == &teedataobject_type); 7317db96d56Sopenharmony_ci 7327db96d56Sopenharmony_ci tdo = (teedataobject *)teedataobject_newinternal(it); 7337db96d56Sopenharmony_ci if (!tdo) 7347db96d56Sopenharmony_ci return NULL; 7357db96d56Sopenharmony_ci 7367db96d56Sopenharmony_ci len = PyList_GET_SIZE(values); 7377db96d56Sopenharmony_ci if (len > LINKCELLS) 7387db96d56Sopenharmony_ci goto err; 7397db96d56Sopenharmony_ci for (i=0; i<len; i++) { 7407db96d56Sopenharmony_ci tdo->values[i] = PyList_GET_ITEM(values, i); 7417db96d56Sopenharmony_ci Py_INCREF(tdo->values[i]); 7427db96d56Sopenharmony_ci } 7437db96d56Sopenharmony_ci /* len <= LINKCELLS < INT_MAX */ 7447db96d56Sopenharmony_ci tdo->numread = Py_SAFE_DOWNCAST(len, Py_ssize_t, int); 7457db96d56Sopenharmony_ci 7467db96d56Sopenharmony_ci if (len == LINKCELLS) { 7477db96d56Sopenharmony_ci if (next != Py_None) { 7487db96d56Sopenharmony_ci if (!Py_IS_TYPE(next, &teedataobject_type)) 7497db96d56Sopenharmony_ci goto err; 7507db96d56Sopenharmony_ci assert(tdo->nextlink == NULL); 7517db96d56Sopenharmony_ci Py_INCREF(next); 7527db96d56Sopenharmony_ci tdo->nextlink = next; 7537db96d56Sopenharmony_ci } 7547db96d56Sopenharmony_ci } else { 7557db96d56Sopenharmony_ci if (next != Py_None) 7567db96d56Sopenharmony_ci goto err; /* shouldn't have a next if we are not full */ 7577db96d56Sopenharmony_ci } 7587db96d56Sopenharmony_ci return (PyObject*)tdo; 7597db96d56Sopenharmony_ci 7607db96d56Sopenharmony_cierr: 7617db96d56Sopenharmony_ci Py_XDECREF(tdo); 7627db96d56Sopenharmony_ci PyErr_SetString(PyExc_ValueError, "Invalid arguments"); 7637db96d56Sopenharmony_ci return NULL; 7647db96d56Sopenharmony_ci} 7657db96d56Sopenharmony_ci 7667db96d56Sopenharmony_cistatic PyMethodDef teedataobject_methods[] = { 7677db96d56Sopenharmony_ci {"__reduce__", (PyCFunction)teedataobject_reduce, METH_NOARGS, 7687db96d56Sopenharmony_ci reduce_doc}, 7697db96d56Sopenharmony_ci {NULL, NULL} /* sentinel */ 7707db96d56Sopenharmony_ci}; 7717db96d56Sopenharmony_ci 7727db96d56Sopenharmony_cistatic PyTypeObject teedataobject_type = { 7737db96d56Sopenharmony_ci PyVarObject_HEAD_INIT(0, 0) /* Must fill in type value later */ 7747db96d56Sopenharmony_ci "itertools._tee_dataobject", /* tp_name */ 7757db96d56Sopenharmony_ci sizeof(teedataobject), /* tp_basicsize */ 7767db96d56Sopenharmony_ci 0, /* tp_itemsize */ 7777db96d56Sopenharmony_ci /* methods */ 7787db96d56Sopenharmony_ci (destructor)teedataobject_dealloc, /* tp_dealloc */ 7797db96d56Sopenharmony_ci 0, /* tp_vectorcall_offset */ 7807db96d56Sopenharmony_ci 0, /* tp_getattr */ 7817db96d56Sopenharmony_ci 0, /* tp_setattr */ 7827db96d56Sopenharmony_ci 0, /* tp_as_async */ 7837db96d56Sopenharmony_ci 0, /* tp_repr */ 7847db96d56Sopenharmony_ci 0, /* tp_as_number */ 7857db96d56Sopenharmony_ci 0, /* tp_as_sequence */ 7867db96d56Sopenharmony_ci 0, /* tp_as_mapping */ 7877db96d56Sopenharmony_ci 0, /* tp_hash */ 7887db96d56Sopenharmony_ci 0, /* tp_call */ 7897db96d56Sopenharmony_ci 0, /* tp_str */ 7907db96d56Sopenharmony_ci PyObject_GenericGetAttr, /* tp_getattro */ 7917db96d56Sopenharmony_ci 0, /* tp_setattro */ 7927db96d56Sopenharmony_ci 0, /* tp_as_buffer */ 7937db96d56Sopenharmony_ci Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */ 7947db96d56Sopenharmony_ci itertools_teedataobject__doc__, /* tp_doc */ 7957db96d56Sopenharmony_ci (traverseproc)teedataobject_traverse, /* tp_traverse */ 7967db96d56Sopenharmony_ci (inquiry)teedataobject_clear, /* tp_clear */ 7977db96d56Sopenharmony_ci 0, /* tp_richcompare */ 7987db96d56Sopenharmony_ci 0, /* tp_weaklistoffset */ 7997db96d56Sopenharmony_ci 0, /* tp_iter */ 8007db96d56Sopenharmony_ci 0, /* tp_iternext */ 8017db96d56Sopenharmony_ci teedataobject_methods, /* tp_methods */ 8027db96d56Sopenharmony_ci 0, /* tp_members */ 8037db96d56Sopenharmony_ci 0, /* tp_getset */ 8047db96d56Sopenharmony_ci 0, /* tp_base */ 8057db96d56Sopenharmony_ci 0, /* tp_dict */ 8067db96d56Sopenharmony_ci 0, /* tp_descr_get */ 8077db96d56Sopenharmony_ci 0, /* tp_descr_set */ 8087db96d56Sopenharmony_ci 0, /* tp_dictoffset */ 8097db96d56Sopenharmony_ci 0, /* tp_init */ 8107db96d56Sopenharmony_ci 0, /* tp_alloc */ 8117db96d56Sopenharmony_ci itertools_teedataobject, /* tp_new */ 8127db96d56Sopenharmony_ci PyObject_GC_Del, /* tp_free */ 8137db96d56Sopenharmony_ci}; 8147db96d56Sopenharmony_ci 8157db96d56Sopenharmony_ci 8167db96d56Sopenharmony_cistatic PyObject * 8177db96d56Sopenharmony_citee_next(teeobject *to) 8187db96d56Sopenharmony_ci{ 8197db96d56Sopenharmony_ci PyObject *value, *link; 8207db96d56Sopenharmony_ci 8217db96d56Sopenharmony_ci if (to->index >= LINKCELLS) { 8227db96d56Sopenharmony_ci link = teedataobject_jumplink(to->dataobj); 8237db96d56Sopenharmony_ci if (link == NULL) 8247db96d56Sopenharmony_ci return NULL; 8257db96d56Sopenharmony_ci Py_SETREF(to->dataobj, (teedataobject *)link); 8267db96d56Sopenharmony_ci to->index = 0; 8277db96d56Sopenharmony_ci } 8287db96d56Sopenharmony_ci value = teedataobject_getitem(to->dataobj, to->index); 8297db96d56Sopenharmony_ci if (value == NULL) 8307db96d56Sopenharmony_ci return NULL; 8317db96d56Sopenharmony_ci to->index++; 8327db96d56Sopenharmony_ci return value; 8337db96d56Sopenharmony_ci} 8347db96d56Sopenharmony_ci 8357db96d56Sopenharmony_cistatic int 8367db96d56Sopenharmony_citee_traverse(teeobject *to, visitproc visit, void *arg) 8377db96d56Sopenharmony_ci{ 8387db96d56Sopenharmony_ci Py_VISIT((PyObject *)to->dataobj); 8397db96d56Sopenharmony_ci return 0; 8407db96d56Sopenharmony_ci} 8417db96d56Sopenharmony_ci 8427db96d56Sopenharmony_cistatic PyObject * 8437db96d56Sopenharmony_citee_copy(teeobject *to, PyObject *Py_UNUSED(ignored)) 8447db96d56Sopenharmony_ci{ 8457db96d56Sopenharmony_ci teeobject *newto; 8467db96d56Sopenharmony_ci 8477db96d56Sopenharmony_ci newto = PyObject_GC_New(teeobject, &tee_type); 8487db96d56Sopenharmony_ci if (newto == NULL) 8497db96d56Sopenharmony_ci return NULL; 8507db96d56Sopenharmony_ci Py_INCREF(to->dataobj); 8517db96d56Sopenharmony_ci newto->dataobj = to->dataobj; 8527db96d56Sopenharmony_ci newto->index = to->index; 8537db96d56Sopenharmony_ci newto->weakreflist = NULL; 8547db96d56Sopenharmony_ci PyObject_GC_Track(newto); 8557db96d56Sopenharmony_ci return (PyObject *)newto; 8567db96d56Sopenharmony_ci} 8577db96d56Sopenharmony_ci 8587db96d56Sopenharmony_ciPyDoc_STRVAR(teecopy_doc, "Returns an independent iterator."); 8597db96d56Sopenharmony_ci 8607db96d56Sopenharmony_cistatic PyObject * 8617db96d56Sopenharmony_citee_fromiterable(PyObject *iterable) 8627db96d56Sopenharmony_ci{ 8637db96d56Sopenharmony_ci teeobject *to; 8647db96d56Sopenharmony_ci PyObject *it; 8657db96d56Sopenharmony_ci 8667db96d56Sopenharmony_ci it = PyObject_GetIter(iterable); 8677db96d56Sopenharmony_ci if (it == NULL) 8687db96d56Sopenharmony_ci return NULL; 8697db96d56Sopenharmony_ci if (PyObject_TypeCheck(it, &tee_type)) { 8707db96d56Sopenharmony_ci to = (teeobject *)tee_copy((teeobject *)it, NULL); 8717db96d56Sopenharmony_ci goto done; 8727db96d56Sopenharmony_ci } 8737db96d56Sopenharmony_ci 8747db96d56Sopenharmony_ci PyObject *dataobj = teedataobject_newinternal(it); 8757db96d56Sopenharmony_ci if (!dataobj) { 8767db96d56Sopenharmony_ci to = NULL; 8777db96d56Sopenharmony_ci goto done; 8787db96d56Sopenharmony_ci } 8797db96d56Sopenharmony_ci to = PyObject_GC_New(teeobject, &tee_type); 8807db96d56Sopenharmony_ci if (to == NULL) { 8817db96d56Sopenharmony_ci Py_DECREF(dataobj); 8827db96d56Sopenharmony_ci goto done; 8837db96d56Sopenharmony_ci } 8847db96d56Sopenharmony_ci to->dataobj = (teedataobject *)dataobj; 8857db96d56Sopenharmony_ci to->index = 0; 8867db96d56Sopenharmony_ci to->weakreflist = NULL; 8877db96d56Sopenharmony_ci PyObject_GC_Track(to); 8887db96d56Sopenharmony_cidone: 8897db96d56Sopenharmony_ci Py_DECREF(it); 8907db96d56Sopenharmony_ci return (PyObject *)to; 8917db96d56Sopenharmony_ci} 8927db96d56Sopenharmony_ci 8937db96d56Sopenharmony_ci/*[clinic input] 8947db96d56Sopenharmony_ci@classmethod 8957db96d56Sopenharmony_ciitertools._tee.__new__ 8967db96d56Sopenharmony_ci iterable: object 8977db96d56Sopenharmony_ci / 8987db96d56Sopenharmony_ciIterator wrapped to make it copyable. 8997db96d56Sopenharmony_ci[clinic start generated code]*/ 9007db96d56Sopenharmony_ci 9017db96d56Sopenharmony_cistatic PyObject * 9027db96d56Sopenharmony_ciitertools__tee_impl(PyTypeObject *type, PyObject *iterable) 9037db96d56Sopenharmony_ci/*[clinic end generated code: output=b02d3fd26c810c3f input=adc0779d2afe37a2]*/ 9047db96d56Sopenharmony_ci{ 9057db96d56Sopenharmony_ci return tee_fromiterable(iterable); 9067db96d56Sopenharmony_ci} 9077db96d56Sopenharmony_ci 9087db96d56Sopenharmony_cistatic int 9097db96d56Sopenharmony_citee_clear(teeobject *to) 9107db96d56Sopenharmony_ci{ 9117db96d56Sopenharmony_ci if (to->weakreflist != NULL) 9127db96d56Sopenharmony_ci PyObject_ClearWeakRefs((PyObject *) to); 9137db96d56Sopenharmony_ci Py_CLEAR(to->dataobj); 9147db96d56Sopenharmony_ci return 0; 9157db96d56Sopenharmony_ci} 9167db96d56Sopenharmony_ci 9177db96d56Sopenharmony_cistatic void 9187db96d56Sopenharmony_citee_dealloc(teeobject *to) 9197db96d56Sopenharmony_ci{ 9207db96d56Sopenharmony_ci PyObject_GC_UnTrack(to); 9217db96d56Sopenharmony_ci tee_clear(to); 9227db96d56Sopenharmony_ci PyObject_GC_Del(to); 9237db96d56Sopenharmony_ci} 9247db96d56Sopenharmony_ci 9257db96d56Sopenharmony_cistatic PyObject * 9267db96d56Sopenharmony_citee_reduce(teeobject *to, PyObject *Py_UNUSED(ignored)) 9277db96d56Sopenharmony_ci{ 9287db96d56Sopenharmony_ci return Py_BuildValue("O(())(Oi)", Py_TYPE(to), to->dataobj, to->index); 9297db96d56Sopenharmony_ci} 9307db96d56Sopenharmony_ci 9317db96d56Sopenharmony_cistatic PyObject * 9327db96d56Sopenharmony_citee_setstate(teeobject *to, PyObject *state) 9337db96d56Sopenharmony_ci{ 9347db96d56Sopenharmony_ci teedataobject *tdo; 9357db96d56Sopenharmony_ci int index; 9367db96d56Sopenharmony_ci if (!PyTuple_Check(state)) { 9377db96d56Sopenharmony_ci PyErr_SetString(PyExc_TypeError, "state is not a tuple"); 9387db96d56Sopenharmony_ci return NULL; 9397db96d56Sopenharmony_ci } 9407db96d56Sopenharmony_ci if (!PyArg_ParseTuple(state, "O!i", &teedataobject_type, &tdo, &index)) { 9417db96d56Sopenharmony_ci return NULL; 9427db96d56Sopenharmony_ci } 9437db96d56Sopenharmony_ci if (index < 0 || index > LINKCELLS) { 9447db96d56Sopenharmony_ci PyErr_SetString(PyExc_ValueError, "Index out of range"); 9457db96d56Sopenharmony_ci return NULL; 9467db96d56Sopenharmony_ci } 9477db96d56Sopenharmony_ci Py_INCREF(tdo); 9487db96d56Sopenharmony_ci Py_XSETREF(to->dataobj, tdo); 9497db96d56Sopenharmony_ci to->index = index; 9507db96d56Sopenharmony_ci Py_RETURN_NONE; 9517db96d56Sopenharmony_ci} 9527db96d56Sopenharmony_ci 9537db96d56Sopenharmony_cistatic PyMethodDef tee_methods[] = { 9547db96d56Sopenharmony_ci {"__copy__", (PyCFunction)tee_copy, METH_NOARGS, teecopy_doc}, 9557db96d56Sopenharmony_ci {"__reduce__", (PyCFunction)tee_reduce, METH_NOARGS, reduce_doc}, 9567db96d56Sopenharmony_ci {"__setstate__", (PyCFunction)tee_setstate, METH_O, setstate_doc}, 9577db96d56Sopenharmony_ci {NULL, NULL} /* sentinel */ 9587db96d56Sopenharmony_ci}; 9597db96d56Sopenharmony_ci 9607db96d56Sopenharmony_cistatic PyTypeObject tee_type = { 9617db96d56Sopenharmony_ci PyVarObject_HEAD_INIT(NULL, 0) 9627db96d56Sopenharmony_ci "itertools._tee", /* tp_name */ 9637db96d56Sopenharmony_ci sizeof(teeobject), /* tp_basicsize */ 9647db96d56Sopenharmony_ci 0, /* tp_itemsize */ 9657db96d56Sopenharmony_ci /* methods */ 9667db96d56Sopenharmony_ci (destructor)tee_dealloc, /* tp_dealloc */ 9677db96d56Sopenharmony_ci 0, /* tp_vectorcall_offset */ 9687db96d56Sopenharmony_ci 0, /* tp_getattr */ 9697db96d56Sopenharmony_ci 0, /* tp_setattr */ 9707db96d56Sopenharmony_ci 0, /* tp_as_async */ 9717db96d56Sopenharmony_ci 0, /* tp_repr */ 9727db96d56Sopenharmony_ci 0, /* tp_as_number */ 9737db96d56Sopenharmony_ci 0, /* tp_as_sequence */ 9747db96d56Sopenharmony_ci 0, /* tp_as_mapping */ 9757db96d56Sopenharmony_ci 0, /* tp_hash */ 9767db96d56Sopenharmony_ci 0, /* tp_call */ 9777db96d56Sopenharmony_ci 0, /* tp_str */ 9787db96d56Sopenharmony_ci 0, /* tp_getattro */ 9797db96d56Sopenharmony_ci 0, /* tp_setattro */ 9807db96d56Sopenharmony_ci 0, /* tp_as_buffer */ 9817db96d56Sopenharmony_ci Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */ 9827db96d56Sopenharmony_ci itertools__tee__doc__, /* tp_doc */ 9837db96d56Sopenharmony_ci (traverseproc)tee_traverse, /* tp_traverse */ 9847db96d56Sopenharmony_ci (inquiry)tee_clear, /* tp_clear */ 9857db96d56Sopenharmony_ci 0, /* tp_richcompare */ 9867db96d56Sopenharmony_ci offsetof(teeobject, weakreflist), /* tp_weaklistoffset */ 9877db96d56Sopenharmony_ci PyObject_SelfIter, /* tp_iter */ 9887db96d56Sopenharmony_ci (iternextfunc)tee_next, /* tp_iternext */ 9897db96d56Sopenharmony_ci tee_methods, /* tp_methods */ 9907db96d56Sopenharmony_ci 0, /* tp_members */ 9917db96d56Sopenharmony_ci 0, /* tp_getset */ 9927db96d56Sopenharmony_ci 0, /* tp_base */ 9937db96d56Sopenharmony_ci 0, /* tp_dict */ 9947db96d56Sopenharmony_ci 0, /* tp_descr_get */ 9957db96d56Sopenharmony_ci 0, /* tp_descr_set */ 9967db96d56Sopenharmony_ci 0, /* tp_dictoffset */ 9977db96d56Sopenharmony_ci 0, /* tp_init */ 9987db96d56Sopenharmony_ci 0, /* tp_alloc */ 9997db96d56Sopenharmony_ci itertools__tee, /* tp_new */ 10007db96d56Sopenharmony_ci PyObject_GC_Del, /* tp_free */ 10017db96d56Sopenharmony_ci}; 10027db96d56Sopenharmony_ci 10037db96d56Sopenharmony_ci/*[clinic input] 10047db96d56Sopenharmony_ciitertools.tee 10057db96d56Sopenharmony_ci iterable: object 10067db96d56Sopenharmony_ci n: Py_ssize_t = 2 10077db96d56Sopenharmony_ci / 10087db96d56Sopenharmony_ciReturns a tuple of n independent iterators. 10097db96d56Sopenharmony_ci[clinic start generated code]*/ 10107db96d56Sopenharmony_ci 10117db96d56Sopenharmony_cistatic PyObject * 10127db96d56Sopenharmony_ciitertools_tee_impl(PyObject *module, PyObject *iterable, Py_ssize_t n) 10137db96d56Sopenharmony_ci/*[clinic end generated code: output=1c64519cd859c2f0 input=c99a1472c425d66d]*/ 10147db96d56Sopenharmony_ci{ 10157db96d56Sopenharmony_ci Py_ssize_t i; 10167db96d56Sopenharmony_ci PyObject *it, *copyable, *copyfunc, *result; 10177db96d56Sopenharmony_ci 10187db96d56Sopenharmony_ci if (n < 0) { 10197db96d56Sopenharmony_ci PyErr_SetString(PyExc_ValueError, "n must be >= 0"); 10207db96d56Sopenharmony_ci return NULL; 10217db96d56Sopenharmony_ci } 10227db96d56Sopenharmony_ci result = PyTuple_New(n); 10237db96d56Sopenharmony_ci if (result == NULL) 10247db96d56Sopenharmony_ci return NULL; 10257db96d56Sopenharmony_ci if (n == 0) 10267db96d56Sopenharmony_ci return result; 10277db96d56Sopenharmony_ci it = PyObject_GetIter(iterable); 10287db96d56Sopenharmony_ci if (it == NULL) { 10297db96d56Sopenharmony_ci Py_DECREF(result); 10307db96d56Sopenharmony_ci return NULL; 10317db96d56Sopenharmony_ci } 10327db96d56Sopenharmony_ci 10337db96d56Sopenharmony_ci if (_PyObject_LookupAttr(it, &_Py_ID(__copy__), ©func) < 0) { 10347db96d56Sopenharmony_ci Py_DECREF(it); 10357db96d56Sopenharmony_ci Py_DECREF(result); 10367db96d56Sopenharmony_ci return NULL; 10377db96d56Sopenharmony_ci } 10387db96d56Sopenharmony_ci if (copyfunc != NULL) { 10397db96d56Sopenharmony_ci copyable = it; 10407db96d56Sopenharmony_ci } 10417db96d56Sopenharmony_ci else { 10427db96d56Sopenharmony_ci copyable = tee_fromiterable(it); 10437db96d56Sopenharmony_ci Py_DECREF(it); 10447db96d56Sopenharmony_ci if (copyable == NULL) { 10457db96d56Sopenharmony_ci Py_DECREF(result); 10467db96d56Sopenharmony_ci return NULL; 10477db96d56Sopenharmony_ci } 10487db96d56Sopenharmony_ci copyfunc = PyObject_GetAttr(copyable, &_Py_ID(__copy__)); 10497db96d56Sopenharmony_ci if (copyfunc == NULL) { 10507db96d56Sopenharmony_ci Py_DECREF(copyable); 10517db96d56Sopenharmony_ci Py_DECREF(result); 10527db96d56Sopenharmony_ci return NULL; 10537db96d56Sopenharmony_ci } 10547db96d56Sopenharmony_ci } 10557db96d56Sopenharmony_ci 10567db96d56Sopenharmony_ci PyTuple_SET_ITEM(result, 0, copyable); 10577db96d56Sopenharmony_ci for (i = 1; i < n; i++) { 10587db96d56Sopenharmony_ci copyable = _PyObject_CallNoArgs(copyfunc); 10597db96d56Sopenharmony_ci if (copyable == NULL) { 10607db96d56Sopenharmony_ci Py_DECREF(copyfunc); 10617db96d56Sopenharmony_ci Py_DECREF(result); 10627db96d56Sopenharmony_ci return NULL; 10637db96d56Sopenharmony_ci } 10647db96d56Sopenharmony_ci PyTuple_SET_ITEM(result, i, copyable); 10657db96d56Sopenharmony_ci } 10667db96d56Sopenharmony_ci Py_DECREF(copyfunc); 10677db96d56Sopenharmony_ci return result; 10687db96d56Sopenharmony_ci} 10697db96d56Sopenharmony_ci 10707db96d56Sopenharmony_ci 10717db96d56Sopenharmony_ci/* cycle object **************************************************************/ 10727db96d56Sopenharmony_ci 10737db96d56Sopenharmony_citypedef struct { 10747db96d56Sopenharmony_ci PyObject_HEAD 10757db96d56Sopenharmony_ci PyObject *it; 10767db96d56Sopenharmony_ci PyObject *saved; 10777db96d56Sopenharmony_ci Py_ssize_t index; 10787db96d56Sopenharmony_ci int firstpass; 10797db96d56Sopenharmony_ci} cycleobject; 10807db96d56Sopenharmony_ci 10817db96d56Sopenharmony_ci/*[clinic input] 10827db96d56Sopenharmony_ci@classmethod 10837db96d56Sopenharmony_ciitertools.cycle.__new__ 10847db96d56Sopenharmony_ci iterable: object 10857db96d56Sopenharmony_ci / 10867db96d56Sopenharmony_ciReturn elements from the iterable until it is exhausted. Then repeat the sequence indefinitely. 10877db96d56Sopenharmony_ci[clinic start generated code]*/ 10887db96d56Sopenharmony_ci 10897db96d56Sopenharmony_cistatic PyObject * 10907db96d56Sopenharmony_ciitertools_cycle_impl(PyTypeObject *type, PyObject *iterable) 10917db96d56Sopenharmony_ci/*[clinic end generated code: output=f60e5ec17a45b35c input=9d1d84bcf66e908b]*/ 10927db96d56Sopenharmony_ci{ 10937db96d56Sopenharmony_ci PyObject *it; 10947db96d56Sopenharmony_ci PyObject *saved; 10957db96d56Sopenharmony_ci cycleobject *lz; 10967db96d56Sopenharmony_ci 10977db96d56Sopenharmony_ci /* Get iterator. */ 10987db96d56Sopenharmony_ci it = PyObject_GetIter(iterable); 10997db96d56Sopenharmony_ci if (it == NULL) 11007db96d56Sopenharmony_ci return NULL; 11017db96d56Sopenharmony_ci 11027db96d56Sopenharmony_ci saved = PyList_New(0); 11037db96d56Sopenharmony_ci if (saved == NULL) { 11047db96d56Sopenharmony_ci Py_DECREF(it); 11057db96d56Sopenharmony_ci return NULL; 11067db96d56Sopenharmony_ci } 11077db96d56Sopenharmony_ci 11087db96d56Sopenharmony_ci /* create cycleobject structure */ 11097db96d56Sopenharmony_ci lz = (cycleobject *)type->tp_alloc(type, 0); 11107db96d56Sopenharmony_ci if (lz == NULL) { 11117db96d56Sopenharmony_ci Py_DECREF(it); 11127db96d56Sopenharmony_ci Py_DECREF(saved); 11137db96d56Sopenharmony_ci return NULL; 11147db96d56Sopenharmony_ci } 11157db96d56Sopenharmony_ci lz->it = it; 11167db96d56Sopenharmony_ci lz->saved = saved; 11177db96d56Sopenharmony_ci lz->index = 0; 11187db96d56Sopenharmony_ci lz->firstpass = 0; 11197db96d56Sopenharmony_ci 11207db96d56Sopenharmony_ci return (PyObject *)lz; 11217db96d56Sopenharmony_ci} 11227db96d56Sopenharmony_ci 11237db96d56Sopenharmony_cistatic void 11247db96d56Sopenharmony_cicycle_dealloc(cycleobject *lz) 11257db96d56Sopenharmony_ci{ 11267db96d56Sopenharmony_ci PyObject_GC_UnTrack(lz); 11277db96d56Sopenharmony_ci Py_XDECREF(lz->it); 11287db96d56Sopenharmony_ci Py_XDECREF(lz->saved); 11297db96d56Sopenharmony_ci Py_TYPE(lz)->tp_free(lz); 11307db96d56Sopenharmony_ci} 11317db96d56Sopenharmony_ci 11327db96d56Sopenharmony_cistatic int 11337db96d56Sopenharmony_cicycle_traverse(cycleobject *lz, visitproc visit, void *arg) 11347db96d56Sopenharmony_ci{ 11357db96d56Sopenharmony_ci Py_VISIT(lz->it); 11367db96d56Sopenharmony_ci Py_VISIT(lz->saved); 11377db96d56Sopenharmony_ci return 0; 11387db96d56Sopenharmony_ci} 11397db96d56Sopenharmony_ci 11407db96d56Sopenharmony_cistatic PyObject * 11417db96d56Sopenharmony_cicycle_next(cycleobject *lz) 11427db96d56Sopenharmony_ci{ 11437db96d56Sopenharmony_ci PyObject *item; 11447db96d56Sopenharmony_ci 11457db96d56Sopenharmony_ci if (lz->it != NULL) { 11467db96d56Sopenharmony_ci item = PyIter_Next(lz->it); 11477db96d56Sopenharmony_ci if (item != NULL) { 11487db96d56Sopenharmony_ci if (lz->firstpass) 11497db96d56Sopenharmony_ci return item; 11507db96d56Sopenharmony_ci if (PyList_Append(lz->saved, item)) { 11517db96d56Sopenharmony_ci Py_DECREF(item); 11527db96d56Sopenharmony_ci return NULL; 11537db96d56Sopenharmony_ci } 11547db96d56Sopenharmony_ci return item; 11557db96d56Sopenharmony_ci } 11567db96d56Sopenharmony_ci /* Note: StopIteration is already cleared by PyIter_Next() */ 11577db96d56Sopenharmony_ci if (PyErr_Occurred()) 11587db96d56Sopenharmony_ci return NULL; 11597db96d56Sopenharmony_ci Py_CLEAR(lz->it); 11607db96d56Sopenharmony_ci } 11617db96d56Sopenharmony_ci if (PyList_GET_SIZE(lz->saved) == 0) 11627db96d56Sopenharmony_ci return NULL; 11637db96d56Sopenharmony_ci item = PyList_GET_ITEM(lz->saved, lz->index); 11647db96d56Sopenharmony_ci lz->index++; 11657db96d56Sopenharmony_ci if (lz->index >= PyList_GET_SIZE(lz->saved)) 11667db96d56Sopenharmony_ci lz->index = 0; 11677db96d56Sopenharmony_ci Py_INCREF(item); 11687db96d56Sopenharmony_ci return item; 11697db96d56Sopenharmony_ci} 11707db96d56Sopenharmony_ci 11717db96d56Sopenharmony_cistatic PyObject * 11727db96d56Sopenharmony_cicycle_reduce(cycleobject *lz, PyObject *Py_UNUSED(ignored)) 11737db96d56Sopenharmony_ci{ 11747db96d56Sopenharmony_ci /* Create a new cycle with the iterator tuple, then set the saved state */ 11757db96d56Sopenharmony_ci if (lz->it == NULL) { 11767db96d56Sopenharmony_ci PyObject *it = PyObject_GetIter(lz->saved); 11777db96d56Sopenharmony_ci if (it == NULL) 11787db96d56Sopenharmony_ci return NULL; 11797db96d56Sopenharmony_ci if (lz->index != 0) { 11807db96d56Sopenharmony_ci PyObject *res = _PyObject_CallMethod(it, &_Py_ID(__setstate__), 11817db96d56Sopenharmony_ci "n", lz->index); 11827db96d56Sopenharmony_ci if (res == NULL) { 11837db96d56Sopenharmony_ci Py_DECREF(it); 11847db96d56Sopenharmony_ci return NULL; 11857db96d56Sopenharmony_ci } 11867db96d56Sopenharmony_ci Py_DECREF(res); 11877db96d56Sopenharmony_ci } 11887db96d56Sopenharmony_ci return Py_BuildValue("O(N)(OO)", Py_TYPE(lz), it, lz->saved, Py_True); 11897db96d56Sopenharmony_ci } 11907db96d56Sopenharmony_ci return Py_BuildValue("O(O)(OO)", Py_TYPE(lz), lz->it, lz->saved, 11917db96d56Sopenharmony_ci lz->firstpass ? Py_True : Py_False); 11927db96d56Sopenharmony_ci} 11937db96d56Sopenharmony_ci 11947db96d56Sopenharmony_cistatic PyObject * 11957db96d56Sopenharmony_cicycle_setstate(cycleobject *lz, PyObject *state) 11967db96d56Sopenharmony_ci{ 11977db96d56Sopenharmony_ci PyObject *saved=NULL; 11987db96d56Sopenharmony_ci int firstpass; 11997db96d56Sopenharmony_ci if (!PyTuple_Check(state)) { 12007db96d56Sopenharmony_ci PyErr_SetString(PyExc_TypeError, "state is not a tuple"); 12017db96d56Sopenharmony_ci return NULL; 12027db96d56Sopenharmony_ci } 12037db96d56Sopenharmony_ci // The second item can be 1/0 in old pickles and True/False in new pickles 12047db96d56Sopenharmony_ci if (!PyArg_ParseTuple(state, "O!i", &PyList_Type, &saved, &firstpass)) { 12057db96d56Sopenharmony_ci return NULL; 12067db96d56Sopenharmony_ci } 12077db96d56Sopenharmony_ci Py_INCREF(saved); 12087db96d56Sopenharmony_ci Py_XSETREF(lz->saved, saved); 12097db96d56Sopenharmony_ci lz->firstpass = firstpass != 0; 12107db96d56Sopenharmony_ci lz->index = 0; 12117db96d56Sopenharmony_ci Py_RETURN_NONE; 12127db96d56Sopenharmony_ci} 12137db96d56Sopenharmony_ci 12147db96d56Sopenharmony_cistatic PyMethodDef cycle_methods[] = { 12157db96d56Sopenharmony_ci {"__reduce__", (PyCFunction)cycle_reduce, METH_NOARGS, 12167db96d56Sopenharmony_ci reduce_doc}, 12177db96d56Sopenharmony_ci {"__setstate__", (PyCFunction)cycle_setstate, METH_O, 12187db96d56Sopenharmony_ci setstate_doc}, 12197db96d56Sopenharmony_ci {NULL, NULL} /* sentinel */ 12207db96d56Sopenharmony_ci}; 12217db96d56Sopenharmony_ci 12227db96d56Sopenharmony_cistatic PyTypeObject cycle_type = { 12237db96d56Sopenharmony_ci PyVarObject_HEAD_INIT(NULL, 0) 12247db96d56Sopenharmony_ci "itertools.cycle", /* tp_name */ 12257db96d56Sopenharmony_ci sizeof(cycleobject), /* tp_basicsize */ 12267db96d56Sopenharmony_ci 0, /* tp_itemsize */ 12277db96d56Sopenharmony_ci /* methods */ 12287db96d56Sopenharmony_ci (destructor)cycle_dealloc, /* tp_dealloc */ 12297db96d56Sopenharmony_ci 0, /* tp_vectorcall_offset */ 12307db96d56Sopenharmony_ci 0, /* tp_getattr */ 12317db96d56Sopenharmony_ci 0, /* tp_setattr */ 12327db96d56Sopenharmony_ci 0, /* tp_as_async */ 12337db96d56Sopenharmony_ci 0, /* tp_repr */ 12347db96d56Sopenharmony_ci 0, /* tp_as_number */ 12357db96d56Sopenharmony_ci 0, /* tp_as_sequence */ 12367db96d56Sopenharmony_ci 0, /* tp_as_mapping */ 12377db96d56Sopenharmony_ci 0, /* tp_hash */ 12387db96d56Sopenharmony_ci 0, /* tp_call */ 12397db96d56Sopenharmony_ci 0, /* tp_str */ 12407db96d56Sopenharmony_ci PyObject_GenericGetAttr, /* tp_getattro */ 12417db96d56Sopenharmony_ci 0, /* tp_setattro */ 12427db96d56Sopenharmony_ci 0, /* tp_as_buffer */ 12437db96d56Sopenharmony_ci Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | 12447db96d56Sopenharmony_ci Py_TPFLAGS_BASETYPE, /* tp_flags */ 12457db96d56Sopenharmony_ci itertools_cycle__doc__, /* tp_doc */ 12467db96d56Sopenharmony_ci (traverseproc)cycle_traverse, /* tp_traverse */ 12477db96d56Sopenharmony_ci 0, /* tp_clear */ 12487db96d56Sopenharmony_ci 0, /* tp_richcompare */ 12497db96d56Sopenharmony_ci 0, /* tp_weaklistoffset */ 12507db96d56Sopenharmony_ci PyObject_SelfIter, /* tp_iter */ 12517db96d56Sopenharmony_ci (iternextfunc)cycle_next, /* tp_iternext */ 12527db96d56Sopenharmony_ci cycle_methods, /* tp_methods */ 12537db96d56Sopenharmony_ci 0, /* tp_members */ 12547db96d56Sopenharmony_ci 0, /* tp_getset */ 12557db96d56Sopenharmony_ci 0, /* tp_base */ 12567db96d56Sopenharmony_ci 0, /* tp_dict */ 12577db96d56Sopenharmony_ci 0, /* tp_descr_get */ 12587db96d56Sopenharmony_ci 0, /* tp_descr_set */ 12597db96d56Sopenharmony_ci 0, /* tp_dictoffset */ 12607db96d56Sopenharmony_ci 0, /* tp_init */ 12617db96d56Sopenharmony_ci 0, /* tp_alloc */ 12627db96d56Sopenharmony_ci itertools_cycle, /* tp_new */ 12637db96d56Sopenharmony_ci PyObject_GC_Del, /* tp_free */ 12647db96d56Sopenharmony_ci}; 12657db96d56Sopenharmony_ci 12667db96d56Sopenharmony_ci 12677db96d56Sopenharmony_ci/* dropwhile object **********************************************************/ 12687db96d56Sopenharmony_ci 12697db96d56Sopenharmony_citypedef struct { 12707db96d56Sopenharmony_ci PyObject_HEAD 12717db96d56Sopenharmony_ci PyObject *func; 12727db96d56Sopenharmony_ci PyObject *it; 12737db96d56Sopenharmony_ci long start; 12747db96d56Sopenharmony_ci} dropwhileobject; 12757db96d56Sopenharmony_ci 12767db96d56Sopenharmony_ci/*[clinic input] 12777db96d56Sopenharmony_ci@classmethod 12787db96d56Sopenharmony_ciitertools.dropwhile.__new__ 12797db96d56Sopenharmony_ci predicate as func: object 12807db96d56Sopenharmony_ci iterable as seq: object 12817db96d56Sopenharmony_ci / 12827db96d56Sopenharmony_ciDrop items from the iterable while predicate(item) is true. 12837db96d56Sopenharmony_ci 12847db96d56Sopenharmony_ciAfterwards, return every element until the iterable is exhausted. 12857db96d56Sopenharmony_ci[clinic start generated code]*/ 12867db96d56Sopenharmony_ci 12877db96d56Sopenharmony_cistatic PyObject * 12887db96d56Sopenharmony_ciitertools_dropwhile_impl(PyTypeObject *type, PyObject *func, PyObject *seq) 12897db96d56Sopenharmony_ci/*[clinic end generated code: output=92f9d0d89af149e4 input=d39737147c9f0a26]*/ 12907db96d56Sopenharmony_ci{ 12917db96d56Sopenharmony_ci PyObject *it; 12927db96d56Sopenharmony_ci dropwhileobject *lz; 12937db96d56Sopenharmony_ci 12947db96d56Sopenharmony_ci /* Get iterator. */ 12957db96d56Sopenharmony_ci it = PyObject_GetIter(seq); 12967db96d56Sopenharmony_ci if (it == NULL) 12977db96d56Sopenharmony_ci return NULL; 12987db96d56Sopenharmony_ci 12997db96d56Sopenharmony_ci /* create dropwhileobject structure */ 13007db96d56Sopenharmony_ci lz = (dropwhileobject *)type->tp_alloc(type, 0); 13017db96d56Sopenharmony_ci if (lz == NULL) { 13027db96d56Sopenharmony_ci Py_DECREF(it); 13037db96d56Sopenharmony_ci return NULL; 13047db96d56Sopenharmony_ci } 13057db96d56Sopenharmony_ci Py_INCREF(func); 13067db96d56Sopenharmony_ci lz->func = func; 13077db96d56Sopenharmony_ci lz->it = it; 13087db96d56Sopenharmony_ci lz->start = 0; 13097db96d56Sopenharmony_ci 13107db96d56Sopenharmony_ci return (PyObject *)lz; 13117db96d56Sopenharmony_ci} 13127db96d56Sopenharmony_ci 13137db96d56Sopenharmony_cistatic void 13147db96d56Sopenharmony_cidropwhile_dealloc(dropwhileobject *lz) 13157db96d56Sopenharmony_ci{ 13167db96d56Sopenharmony_ci PyObject_GC_UnTrack(lz); 13177db96d56Sopenharmony_ci Py_XDECREF(lz->func); 13187db96d56Sopenharmony_ci Py_XDECREF(lz->it); 13197db96d56Sopenharmony_ci Py_TYPE(lz)->tp_free(lz); 13207db96d56Sopenharmony_ci} 13217db96d56Sopenharmony_ci 13227db96d56Sopenharmony_cistatic int 13237db96d56Sopenharmony_cidropwhile_traverse(dropwhileobject *lz, visitproc visit, void *arg) 13247db96d56Sopenharmony_ci{ 13257db96d56Sopenharmony_ci Py_VISIT(lz->it); 13267db96d56Sopenharmony_ci Py_VISIT(lz->func); 13277db96d56Sopenharmony_ci return 0; 13287db96d56Sopenharmony_ci} 13297db96d56Sopenharmony_ci 13307db96d56Sopenharmony_cistatic PyObject * 13317db96d56Sopenharmony_cidropwhile_next(dropwhileobject *lz) 13327db96d56Sopenharmony_ci{ 13337db96d56Sopenharmony_ci PyObject *item, *good; 13347db96d56Sopenharmony_ci PyObject *it = lz->it; 13357db96d56Sopenharmony_ci long ok; 13367db96d56Sopenharmony_ci PyObject *(*iternext)(PyObject *); 13377db96d56Sopenharmony_ci 13387db96d56Sopenharmony_ci iternext = *Py_TYPE(it)->tp_iternext; 13397db96d56Sopenharmony_ci for (;;) { 13407db96d56Sopenharmony_ci item = iternext(it); 13417db96d56Sopenharmony_ci if (item == NULL) 13427db96d56Sopenharmony_ci return NULL; 13437db96d56Sopenharmony_ci if (lz->start == 1) 13447db96d56Sopenharmony_ci return item; 13457db96d56Sopenharmony_ci 13467db96d56Sopenharmony_ci good = PyObject_CallOneArg(lz->func, item); 13477db96d56Sopenharmony_ci if (good == NULL) { 13487db96d56Sopenharmony_ci Py_DECREF(item); 13497db96d56Sopenharmony_ci return NULL; 13507db96d56Sopenharmony_ci } 13517db96d56Sopenharmony_ci ok = PyObject_IsTrue(good); 13527db96d56Sopenharmony_ci Py_DECREF(good); 13537db96d56Sopenharmony_ci if (ok == 0) { 13547db96d56Sopenharmony_ci lz->start = 1; 13557db96d56Sopenharmony_ci return item; 13567db96d56Sopenharmony_ci } 13577db96d56Sopenharmony_ci Py_DECREF(item); 13587db96d56Sopenharmony_ci if (ok < 0) 13597db96d56Sopenharmony_ci return NULL; 13607db96d56Sopenharmony_ci } 13617db96d56Sopenharmony_ci} 13627db96d56Sopenharmony_ci 13637db96d56Sopenharmony_cistatic PyObject * 13647db96d56Sopenharmony_cidropwhile_reduce(dropwhileobject *lz, PyObject *Py_UNUSED(ignored)) 13657db96d56Sopenharmony_ci{ 13667db96d56Sopenharmony_ci return Py_BuildValue("O(OO)l", Py_TYPE(lz), lz->func, lz->it, lz->start); 13677db96d56Sopenharmony_ci} 13687db96d56Sopenharmony_ci 13697db96d56Sopenharmony_cistatic PyObject * 13707db96d56Sopenharmony_cidropwhile_setstate(dropwhileobject *lz, PyObject *state) 13717db96d56Sopenharmony_ci{ 13727db96d56Sopenharmony_ci int start = PyObject_IsTrue(state); 13737db96d56Sopenharmony_ci if (start < 0) 13747db96d56Sopenharmony_ci return NULL; 13757db96d56Sopenharmony_ci lz->start = start; 13767db96d56Sopenharmony_ci Py_RETURN_NONE; 13777db96d56Sopenharmony_ci} 13787db96d56Sopenharmony_ci 13797db96d56Sopenharmony_cistatic PyMethodDef dropwhile_methods[] = { 13807db96d56Sopenharmony_ci {"__reduce__", (PyCFunction)dropwhile_reduce, METH_NOARGS, 13817db96d56Sopenharmony_ci reduce_doc}, 13827db96d56Sopenharmony_ci {"__setstate__", (PyCFunction)dropwhile_setstate, METH_O, 13837db96d56Sopenharmony_ci setstate_doc}, 13847db96d56Sopenharmony_ci {NULL, NULL} /* sentinel */ 13857db96d56Sopenharmony_ci}; 13867db96d56Sopenharmony_ci 13877db96d56Sopenharmony_cistatic PyTypeObject dropwhile_type = { 13887db96d56Sopenharmony_ci PyVarObject_HEAD_INIT(NULL, 0) 13897db96d56Sopenharmony_ci "itertools.dropwhile", /* tp_name */ 13907db96d56Sopenharmony_ci sizeof(dropwhileobject), /* tp_basicsize */ 13917db96d56Sopenharmony_ci 0, /* tp_itemsize */ 13927db96d56Sopenharmony_ci /* methods */ 13937db96d56Sopenharmony_ci (destructor)dropwhile_dealloc, /* tp_dealloc */ 13947db96d56Sopenharmony_ci 0, /* tp_vectorcall_offset */ 13957db96d56Sopenharmony_ci 0, /* tp_getattr */ 13967db96d56Sopenharmony_ci 0, /* tp_setattr */ 13977db96d56Sopenharmony_ci 0, /* tp_as_async */ 13987db96d56Sopenharmony_ci 0, /* tp_repr */ 13997db96d56Sopenharmony_ci 0, /* tp_as_number */ 14007db96d56Sopenharmony_ci 0, /* tp_as_sequence */ 14017db96d56Sopenharmony_ci 0, /* tp_as_mapping */ 14027db96d56Sopenharmony_ci 0, /* tp_hash */ 14037db96d56Sopenharmony_ci 0, /* tp_call */ 14047db96d56Sopenharmony_ci 0, /* tp_str */ 14057db96d56Sopenharmony_ci PyObject_GenericGetAttr, /* tp_getattro */ 14067db96d56Sopenharmony_ci 0, /* tp_setattro */ 14077db96d56Sopenharmony_ci 0, /* tp_as_buffer */ 14087db96d56Sopenharmony_ci Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | 14097db96d56Sopenharmony_ci Py_TPFLAGS_BASETYPE, /* tp_flags */ 14107db96d56Sopenharmony_ci itertools_dropwhile__doc__, /* tp_doc */ 14117db96d56Sopenharmony_ci (traverseproc)dropwhile_traverse, /* tp_traverse */ 14127db96d56Sopenharmony_ci 0, /* tp_clear */ 14137db96d56Sopenharmony_ci 0, /* tp_richcompare */ 14147db96d56Sopenharmony_ci 0, /* tp_weaklistoffset */ 14157db96d56Sopenharmony_ci PyObject_SelfIter, /* tp_iter */ 14167db96d56Sopenharmony_ci (iternextfunc)dropwhile_next, /* tp_iternext */ 14177db96d56Sopenharmony_ci dropwhile_methods, /* tp_methods */ 14187db96d56Sopenharmony_ci 0, /* tp_members */ 14197db96d56Sopenharmony_ci 0, /* tp_getset */ 14207db96d56Sopenharmony_ci 0, /* tp_base */ 14217db96d56Sopenharmony_ci 0, /* tp_dict */ 14227db96d56Sopenharmony_ci 0, /* tp_descr_get */ 14237db96d56Sopenharmony_ci 0, /* tp_descr_set */ 14247db96d56Sopenharmony_ci 0, /* tp_dictoffset */ 14257db96d56Sopenharmony_ci 0, /* tp_init */ 14267db96d56Sopenharmony_ci 0, /* tp_alloc */ 14277db96d56Sopenharmony_ci itertools_dropwhile, /* tp_new */ 14287db96d56Sopenharmony_ci PyObject_GC_Del, /* tp_free */ 14297db96d56Sopenharmony_ci}; 14307db96d56Sopenharmony_ci 14317db96d56Sopenharmony_ci 14327db96d56Sopenharmony_ci/* takewhile object **********************************************************/ 14337db96d56Sopenharmony_ci 14347db96d56Sopenharmony_citypedef struct { 14357db96d56Sopenharmony_ci PyObject_HEAD 14367db96d56Sopenharmony_ci PyObject *func; 14377db96d56Sopenharmony_ci PyObject *it; 14387db96d56Sopenharmony_ci long stop; 14397db96d56Sopenharmony_ci} takewhileobject; 14407db96d56Sopenharmony_ci 14417db96d56Sopenharmony_ci/*[clinic input] 14427db96d56Sopenharmony_ci@classmethod 14437db96d56Sopenharmony_ciitertools.takewhile.__new__ 14447db96d56Sopenharmony_ci predicate as func: object 14457db96d56Sopenharmony_ci iterable as seq: object 14467db96d56Sopenharmony_ci / 14477db96d56Sopenharmony_ciReturn successive entries from an iterable as long as the predicate evaluates to true for each entry. 14487db96d56Sopenharmony_ci[clinic start generated code]*/ 14497db96d56Sopenharmony_ci 14507db96d56Sopenharmony_cistatic PyObject * 14517db96d56Sopenharmony_ciitertools_takewhile_impl(PyTypeObject *type, PyObject *func, PyObject *seq) 14527db96d56Sopenharmony_ci/*[clinic end generated code: output=bb179ea7864e2ef6 input=ba5255f7519aa119]*/ 14537db96d56Sopenharmony_ci{ 14547db96d56Sopenharmony_ci PyObject *it; 14557db96d56Sopenharmony_ci takewhileobject *lz; 14567db96d56Sopenharmony_ci 14577db96d56Sopenharmony_ci /* Get iterator. */ 14587db96d56Sopenharmony_ci it = PyObject_GetIter(seq); 14597db96d56Sopenharmony_ci if (it == NULL) 14607db96d56Sopenharmony_ci return NULL; 14617db96d56Sopenharmony_ci 14627db96d56Sopenharmony_ci /* create takewhileobject structure */ 14637db96d56Sopenharmony_ci lz = (takewhileobject *)type->tp_alloc(type, 0); 14647db96d56Sopenharmony_ci if (lz == NULL) { 14657db96d56Sopenharmony_ci Py_DECREF(it); 14667db96d56Sopenharmony_ci return NULL; 14677db96d56Sopenharmony_ci } 14687db96d56Sopenharmony_ci Py_INCREF(func); 14697db96d56Sopenharmony_ci lz->func = func; 14707db96d56Sopenharmony_ci lz->it = it; 14717db96d56Sopenharmony_ci lz->stop = 0; 14727db96d56Sopenharmony_ci 14737db96d56Sopenharmony_ci return (PyObject *)lz; 14747db96d56Sopenharmony_ci} 14757db96d56Sopenharmony_ci 14767db96d56Sopenharmony_cistatic void 14777db96d56Sopenharmony_citakewhile_dealloc(takewhileobject *lz) 14787db96d56Sopenharmony_ci{ 14797db96d56Sopenharmony_ci PyObject_GC_UnTrack(lz); 14807db96d56Sopenharmony_ci Py_XDECREF(lz->func); 14817db96d56Sopenharmony_ci Py_XDECREF(lz->it); 14827db96d56Sopenharmony_ci Py_TYPE(lz)->tp_free(lz); 14837db96d56Sopenharmony_ci} 14847db96d56Sopenharmony_ci 14857db96d56Sopenharmony_cistatic int 14867db96d56Sopenharmony_citakewhile_traverse(takewhileobject *lz, visitproc visit, void *arg) 14877db96d56Sopenharmony_ci{ 14887db96d56Sopenharmony_ci Py_VISIT(lz->it); 14897db96d56Sopenharmony_ci Py_VISIT(lz->func); 14907db96d56Sopenharmony_ci return 0; 14917db96d56Sopenharmony_ci} 14927db96d56Sopenharmony_ci 14937db96d56Sopenharmony_cistatic PyObject * 14947db96d56Sopenharmony_citakewhile_next(takewhileobject *lz) 14957db96d56Sopenharmony_ci{ 14967db96d56Sopenharmony_ci PyObject *item, *good; 14977db96d56Sopenharmony_ci PyObject *it = lz->it; 14987db96d56Sopenharmony_ci long ok; 14997db96d56Sopenharmony_ci 15007db96d56Sopenharmony_ci if (lz->stop == 1) 15017db96d56Sopenharmony_ci return NULL; 15027db96d56Sopenharmony_ci 15037db96d56Sopenharmony_ci item = (*Py_TYPE(it)->tp_iternext)(it); 15047db96d56Sopenharmony_ci if (item == NULL) 15057db96d56Sopenharmony_ci return NULL; 15067db96d56Sopenharmony_ci 15077db96d56Sopenharmony_ci good = PyObject_CallOneArg(lz->func, item); 15087db96d56Sopenharmony_ci if (good == NULL) { 15097db96d56Sopenharmony_ci Py_DECREF(item); 15107db96d56Sopenharmony_ci return NULL; 15117db96d56Sopenharmony_ci } 15127db96d56Sopenharmony_ci ok = PyObject_IsTrue(good); 15137db96d56Sopenharmony_ci Py_DECREF(good); 15147db96d56Sopenharmony_ci if (ok > 0) 15157db96d56Sopenharmony_ci return item; 15167db96d56Sopenharmony_ci Py_DECREF(item); 15177db96d56Sopenharmony_ci if (ok == 0) 15187db96d56Sopenharmony_ci lz->stop = 1; 15197db96d56Sopenharmony_ci return NULL; 15207db96d56Sopenharmony_ci} 15217db96d56Sopenharmony_ci 15227db96d56Sopenharmony_cistatic PyObject * 15237db96d56Sopenharmony_citakewhile_reduce(takewhileobject *lz, PyObject *Py_UNUSED(ignored)) 15247db96d56Sopenharmony_ci{ 15257db96d56Sopenharmony_ci return Py_BuildValue("O(OO)l", Py_TYPE(lz), lz->func, lz->it, lz->stop); 15267db96d56Sopenharmony_ci} 15277db96d56Sopenharmony_ci 15287db96d56Sopenharmony_cistatic PyObject * 15297db96d56Sopenharmony_citakewhile_reduce_setstate(takewhileobject *lz, PyObject *state) 15307db96d56Sopenharmony_ci{ 15317db96d56Sopenharmony_ci int stop = PyObject_IsTrue(state); 15327db96d56Sopenharmony_ci 15337db96d56Sopenharmony_ci if (stop < 0) 15347db96d56Sopenharmony_ci return NULL; 15357db96d56Sopenharmony_ci lz->stop = stop; 15367db96d56Sopenharmony_ci Py_RETURN_NONE; 15377db96d56Sopenharmony_ci} 15387db96d56Sopenharmony_ci 15397db96d56Sopenharmony_cistatic PyMethodDef takewhile_reduce_methods[] = { 15407db96d56Sopenharmony_ci {"__reduce__", (PyCFunction)takewhile_reduce, METH_NOARGS, 15417db96d56Sopenharmony_ci reduce_doc}, 15427db96d56Sopenharmony_ci {"__setstate__", (PyCFunction)takewhile_reduce_setstate, METH_O, 15437db96d56Sopenharmony_ci setstate_doc}, 15447db96d56Sopenharmony_ci {NULL, NULL} /* sentinel */ 15457db96d56Sopenharmony_ci}; 15467db96d56Sopenharmony_ci 15477db96d56Sopenharmony_cistatic PyTypeObject takewhile_type = { 15487db96d56Sopenharmony_ci PyVarObject_HEAD_INIT(NULL, 0) 15497db96d56Sopenharmony_ci "itertools.takewhile", /* tp_name */ 15507db96d56Sopenharmony_ci sizeof(takewhileobject), /* tp_basicsize */ 15517db96d56Sopenharmony_ci 0, /* tp_itemsize */ 15527db96d56Sopenharmony_ci /* methods */ 15537db96d56Sopenharmony_ci (destructor)takewhile_dealloc, /* tp_dealloc */ 15547db96d56Sopenharmony_ci 0, /* tp_vectorcall_offset */ 15557db96d56Sopenharmony_ci 0, /* tp_getattr */ 15567db96d56Sopenharmony_ci 0, /* tp_setattr */ 15577db96d56Sopenharmony_ci 0, /* tp_as_async */ 15587db96d56Sopenharmony_ci 0, /* tp_repr */ 15597db96d56Sopenharmony_ci 0, /* tp_as_number */ 15607db96d56Sopenharmony_ci 0, /* tp_as_sequence */ 15617db96d56Sopenharmony_ci 0, /* tp_as_mapping */ 15627db96d56Sopenharmony_ci 0, /* tp_hash */ 15637db96d56Sopenharmony_ci 0, /* tp_call */ 15647db96d56Sopenharmony_ci 0, /* tp_str */ 15657db96d56Sopenharmony_ci PyObject_GenericGetAttr, /* tp_getattro */ 15667db96d56Sopenharmony_ci 0, /* tp_setattro */ 15677db96d56Sopenharmony_ci 0, /* tp_as_buffer */ 15687db96d56Sopenharmony_ci Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | 15697db96d56Sopenharmony_ci Py_TPFLAGS_BASETYPE, /* tp_flags */ 15707db96d56Sopenharmony_ci itertools_takewhile__doc__, /* tp_doc */ 15717db96d56Sopenharmony_ci (traverseproc)takewhile_traverse, /* tp_traverse */ 15727db96d56Sopenharmony_ci 0, /* tp_clear */ 15737db96d56Sopenharmony_ci 0, /* tp_richcompare */ 15747db96d56Sopenharmony_ci 0, /* tp_weaklistoffset */ 15757db96d56Sopenharmony_ci PyObject_SelfIter, /* tp_iter */ 15767db96d56Sopenharmony_ci (iternextfunc)takewhile_next, /* tp_iternext */ 15777db96d56Sopenharmony_ci takewhile_reduce_methods, /* tp_methods */ 15787db96d56Sopenharmony_ci 0, /* tp_members */ 15797db96d56Sopenharmony_ci 0, /* tp_getset */ 15807db96d56Sopenharmony_ci 0, /* tp_base */ 15817db96d56Sopenharmony_ci 0, /* tp_dict */ 15827db96d56Sopenharmony_ci 0, /* tp_descr_get */ 15837db96d56Sopenharmony_ci 0, /* tp_descr_set */ 15847db96d56Sopenharmony_ci 0, /* tp_dictoffset */ 15857db96d56Sopenharmony_ci 0, /* tp_init */ 15867db96d56Sopenharmony_ci 0, /* tp_alloc */ 15877db96d56Sopenharmony_ci itertools_takewhile, /* tp_new */ 15887db96d56Sopenharmony_ci PyObject_GC_Del, /* tp_free */ 15897db96d56Sopenharmony_ci}; 15907db96d56Sopenharmony_ci 15917db96d56Sopenharmony_ci 15927db96d56Sopenharmony_ci/* islice object *************************************************************/ 15937db96d56Sopenharmony_ci 15947db96d56Sopenharmony_citypedef struct { 15957db96d56Sopenharmony_ci PyObject_HEAD 15967db96d56Sopenharmony_ci PyObject *it; 15977db96d56Sopenharmony_ci Py_ssize_t next; 15987db96d56Sopenharmony_ci Py_ssize_t stop; 15997db96d56Sopenharmony_ci Py_ssize_t step; 16007db96d56Sopenharmony_ci Py_ssize_t cnt; 16017db96d56Sopenharmony_ci} isliceobject; 16027db96d56Sopenharmony_ci 16037db96d56Sopenharmony_cistatic PyTypeObject islice_type; 16047db96d56Sopenharmony_ci 16057db96d56Sopenharmony_cistatic PyObject * 16067db96d56Sopenharmony_ciislice_new(PyTypeObject *type, PyObject *args, PyObject *kwds) 16077db96d56Sopenharmony_ci{ 16087db96d56Sopenharmony_ci PyObject *seq; 16097db96d56Sopenharmony_ci Py_ssize_t start=0, stop=-1, step=1; 16107db96d56Sopenharmony_ci PyObject *it, *a1=NULL, *a2=NULL, *a3=NULL; 16117db96d56Sopenharmony_ci Py_ssize_t numargs; 16127db96d56Sopenharmony_ci isliceobject *lz; 16137db96d56Sopenharmony_ci 16147db96d56Sopenharmony_ci if ((type == &islice_type || type->tp_init == islice_type.tp_init) && 16157db96d56Sopenharmony_ci !_PyArg_NoKeywords("islice", kwds)) 16167db96d56Sopenharmony_ci return NULL; 16177db96d56Sopenharmony_ci 16187db96d56Sopenharmony_ci if (!PyArg_UnpackTuple(args, "islice", 2, 4, &seq, &a1, &a2, &a3)) 16197db96d56Sopenharmony_ci return NULL; 16207db96d56Sopenharmony_ci 16217db96d56Sopenharmony_ci numargs = PyTuple_Size(args); 16227db96d56Sopenharmony_ci if (numargs == 2) { 16237db96d56Sopenharmony_ci if (a1 != Py_None) { 16247db96d56Sopenharmony_ci stop = PyNumber_AsSsize_t(a1, PyExc_OverflowError); 16257db96d56Sopenharmony_ci if (stop == -1) { 16267db96d56Sopenharmony_ci if (PyErr_Occurred()) 16277db96d56Sopenharmony_ci PyErr_Clear(); 16287db96d56Sopenharmony_ci PyErr_SetString(PyExc_ValueError, 16297db96d56Sopenharmony_ci "Stop argument for islice() must be None or " 16307db96d56Sopenharmony_ci "an integer: 0 <= x <= sys.maxsize."); 16317db96d56Sopenharmony_ci return NULL; 16327db96d56Sopenharmony_ci } 16337db96d56Sopenharmony_ci } 16347db96d56Sopenharmony_ci } else { 16357db96d56Sopenharmony_ci if (a1 != Py_None) 16367db96d56Sopenharmony_ci start = PyNumber_AsSsize_t(a1, PyExc_OverflowError); 16377db96d56Sopenharmony_ci if (start == -1 && PyErr_Occurred()) 16387db96d56Sopenharmony_ci PyErr_Clear(); 16397db96d56Sopenharmony_ci if (a2 != Py_None) { 16407db96d56Sopenharmony_ci stop = PyNumber_AsSsize_t(a2, PyExc_OverflowError); 16417db96d56Sopenharmony_ci if (stop == -1) { 16427db96d56Sopenharmony_ci if (PyErr_Occurred()) 16437db96d56Sopenharmony_ci PyErr_Clear(); 16447db96d56Sopenharmony_ci PyErr_SetString(PyExc_ValueError, 16457db96d56Sopenharmony_ci "Stop argument for islice() must be None or " 16467db96d56Sopenharmony_ci "an integer: 0 <= x <= sys.maxsize."); 16477db96d56Sopenharmony_ci return NULL; 16487db96d56Sopenharmony_ci } 16497db96d56Sopenharmony_ci } 16507db96d56Sopenharmony_ci } 16517db96d56Sopenharmony_ci if (start<0 || stop<-1) { 16527db96d56Sopenharmony_ci PyErr_SetString(PyExc_ValueError, 16537db96d56Sopenharmony_ci "Indices for islice() must be None or " 16547db96d56Sopenharmony_ci "an integer: 0 <= x <= sys.maxsize."); 16557db96d56Sopenharmony_ci return NULL; 16567db96d56Sopenharmony_ci } 16577db96d56Sopenharmony_ci 16587db96d56Sopenharmony_ci if (a3 != NULL) { 16597db96d56Sopenharmony_ci if (a3 != Py_None) 16607db96d56Sopenharmony_ci step = PyNumber_AsSsize_t(a3, PyExc_OverflowError); 16617db96d56Sopenharmony_ci if (step == -1 && PyErr_Occurred()) 16627db96d56Sopenharmony_ci PyErr_Clear(); 16637db96d56Sopenharmony_ci } 16647db96d56Sopenharmony_ci if (step<1) { 16657db96d56Sopenharmony_ci PyErr_SetString(PyExc_ValueError, 16667db96d56Sopenharmony_ci "Step for islice() must be a positive integer or None."); 16677db96d56Sopenharmony_ci return NULL; 16687db96d56Sopenharmony_ci } 16697db96d56Sopenharmony_ci 16707db96d56Sopenharmony_ci /* Get iterator. */ 16717db96d56Sopenharmony_ci it = PyObject_GetIter(seq); 16727db96d56Sopenharmony_ci if (it == NULL) 16737db96d56Sopenharmony_ci return NULL; 16747db96d56Sopenharmony_ci 16757db96d56Sopenharmony_ci /* create isliceobject structure */ 16767db96d56Sopenharmony_ci lz = (isliceobject *)type->tp_alloc(type, 0); 16777db96d56Sopenharmony_ci if (lz == NULL) { 16787db96d56Sopenharmony_ci Py_DECREF(it); 16797db96d56Sopenharmony_ci return NULL; 16807db96d56Sopenharmony_ci } 16817db96d56Sopenharmony_ci lz->it = it; 16827db96d56Sopenharmony_ci lz->next = start; 16837db96d56Sopenharmony_ci lz->stop = stop; 16847db96d56Sopenharmony_ci lz->step = step; 16857db96d56Sopenharmony_ci lz->cnt = 0L; 16867db96d56Sopenharmony_ci 16877db96d56Sopenharmony_ci return (PyObject *)lz; 16887db96d56Sopenharmony_ci} 16897db96d56Sopenharmony_ci 16907db96d56Sopenharmony_cistatic void 16917db96d56Sopenharmony_ciislice_dealloc(isliceobject *lz) 16927db96d56Sopenharmony_ci{ 16937db96d56Sopenharmony_ci PyObject_GC_UnTrack(lz); 16947db96d56Sopenharmony_ci Py_XDECREF(lz->it); 16957db96d56Sopenharmony_ci Py_TYPE(lz)->tp_free(lz); 16967db96d56Sopenharmony_ci} 16977db96d56Sopenharmony_ci 16987db96d56Sopenharmony_cistatic int 16997db96d56Sopenharmony_ciislice_traverse(isliceobject *lz, visitproc visit, void *arg) 17007db96d56Sopenharmony_ci{ 17017db96d56Sopenharmony_ci Py_VISIT(lz->it); 17027db96d56Sopenharmony_ci return 0; 17037db96d56Sopenharmony_ci} 17047db96d56Sopenharmony_ci 17057db96d56Sopenharmony_cistatic PyObject * 17067db96d56Sopenharmony_ciislice_next(isliceobject *lz) 17077db96d56Sopenharmony_ci{ 17087db96d56Sopenharmony_ci PyObject *item; 17097db96d56Sopenharmony_ci PyObject *it = lz->it; 17107db96d56Sopenharmony_ci Py_ssize_t stop = lz->stop; 17117db96d56Sopenharmony_ci Py_ssize_t oldnext; 17127db96d56Sopenharmony_ci PyObject *(*iternext)(PyObject *); 17137db96d56Sopenharmony_ci 17147db96d56Sopenharmony_ci if (it == NULL) 17157db96d56Sopenharmony_ci return NULL; 17167db96d56Sopenharmony_ci 17177db96d56Sopenharmony_ci iternext = *Py_TYPE(it)->tp_iternext; 17187db96d56Sopenharmony_ci while (lz->cnt < lz->next) { 17197db96d56Sopenharmony_ci item = iternext(it); 17207db96d56Sopenharmony_ci if (item == NULL) 17217db96d56Sopenharmony_ci goto empty; 17227db96d56Sopenharmony_ci Py_DECREF(item); 17237db96d56Sopenharmony_ci lz->cnt++; 17247db96d56Sopenharmony_ci } 17257db96d56Sopenharmony_ci if (stop != -1 && lz->cnt >= stop) 17267db96d56Sopenharmony_ci goto empty; 17277db96d56Sopenharmony_ci item = iternext(it); 17287db96d56Sopenharmony_ci if (item == NULL) 17297db96d56Sopenharmony_ci goto empty; 17307db96d56Sopenharmony_ci lz->cnt++; 17317db96d56Sopenharmony_ci oldnext = lz->next; 17327db96d56Sopenharmony_ci /* The (size_t) cast below avoids the danger of undefined 17337db96d56Sopenharmony_ci behaviour from signed integer overflow. */ 17347db96d56Sopenharmony_ci lz->next += (size_t)lz->step; 17357db96d56Sopenharmony_ci if (lz->next < oldnext || (stop != -1 && lz->next > stop)) 17367db96d56Sopenharmony_ci lz->next = stop; 17377db96d56Sopenharmony_ci return item; 17387db96d56Sopenharmony_ci 17397db96d56Sopenharmony_ciempty: 17407db96d56Sopenharmony_ci Py_CLEAR(lz->it); 17417db96d56Sopenharmony_ci return NULL; 17427db96d56Sopenharmony_ci} 17437db96d56Sopenharmony_ci 17447db96d56Sopenharmony_cistatic PyObject * 17457db96d56Sopenharmony_ciislice_reduce(isliceobject *lz, PyObject *Py_UNUSED(ignored)) 17467db96d56Sopenharmony_ci{ 17477db96d56Sopenharmony_ci /* When unpickled, generate a new object with the same bounds, 17487db96d56Sopenharmony_ci * then 'setstate' with the next and count 17497db96d56Sopenharmony_ci */ 17507db96d56Sopenharmony_ci PyObject *stop; 17517db96d56Sopenharmony_ci 17527db96d56Sopenharmony_ci if (lz->it == NULL) { 17537db96d56Sopenharmony_ci PyObject *empty_list; 17547db96d56Sopenharmony_ci PyObject *empty_it; 17557db96d56Sopenharmony_ci empty_list = PyList_New(0); 17567db96d56Sopenharmony_ci if (empty_list == NULL) 17577db96d56Sopenharmony_ci return NULL; 17587db96d56Sopenharmony_ci empty_it = PyObject_GetIter(empty_list); 17597db96d56Sopenharmony_ci Py_DECREF(empty_list); 17607db96d56Sopenharmony_ci if (empty_it == NULL) 17617db96d56Sopenharmony_ci return NULL; 17627db96d56Sopenharmony_ci return Py_BuildValue("O(Nn)n", Py_TYPE(lz), empty_it, 0, 0); 17637db96d56Sopenharmony_ci } 17647db96d56Sopenharmony_ci if (lz->stop == -1) { 17657db96d56Sopenharmony_ci stop = Py_None; 17667db96d56Sopenharmony_ci Py_INCREF(stop); 17677db96d56Sopenharmony_ci } else { 17687db96d56Sopenharmony_ci stop = PyLong_FromSsize_t(lz->stop); 17697db96d56Sopenharmony_ci if (stop == NULL) 17707db96d56Sopenharmony_ci return NULL; 17717db96d56Sopenharmony_ci } 17727db96d56Sopenharmony_ci return Py_BuildValue("O(OnNn)n", Py_TYPE(lz), 17737db96d56Sopenharmony_ci lz->it, lz->next, stop, lz->step, 17747db96d56Sopenharmony_ci lz->cnt); 17757db96d56Sopenharmony_ci} 17767db96d56Sopenharmony_ci 17777db96d56Sopenharmony_cistatic PyObject * 17787db96d56Sopenharmony_ciislice_setstate(isliceobject *lz, PyObject *state) 17797db96d56Sopenharmony_ci{ 17807db96d56Sopenharmony_ci Py_ssize_t cnt = PyLong_AsSsize_t(state); 17817db96d56Sopenharmony_ci 17827db96d56Sopenharmony_ci if (cnt == -1 && PyErr_Occurred()) 17837db96d56Sopenharmony_ci return NULL; 17847db96d56Sopenharmony_ci lz->cnt = cnt; 17857db96d56Sopenharmony_ci Py_RETURN_NONE; 17867db96d56Sopenharmony_ci} 17877db96d56Sopenharmony_ci 17887db96d56Sopenharmony_cistatic PyMethodDef islice_methods[] = { 17897db96d56Sopenharmony_ci {"__reduce__", (PyCFunction)islice_reduce, METH_NOARGS, 17907db96d56Sopenharmony_ci reduce_doc}, 17917db96d56Sopenharmony_ci {"__setstate__", (PyCFunction)islice_setstate, METH_O, 17927db96d56Sopenharmony_ci setstate_doc}, 17937db96d56Sopenharmony_ci {NULL, NULL} /* sentinel */ 17947db96d56Sopenharmony_ci}; 17957db96d56Sopenharmony_ci 17967db96d56Sopenharmony_ciPyDoc_STRVAR(islice_doc, 17977db96d56Sopenharmony_ci"islice(iterable, stop) --> islice object\n\ 17987db96d56Sopenharmony_ciislice(iterable, start, stop[, step]) --> islice object\n\ 17997db96d56Sopenharmony_ci\n\ 18007db96d56Sopenharmony_ciReturn an iterator whose next() method returns selected values from an\n\ 18017db96d56Sopenharmony_ciiterable. If start is specified, will skip all preceding elements;\n\ 18027db96d56Sopenharmony_ciotherwise, start defaults to zero. Step defaults to one. If\n\ 18037db96d56Sopenharmony_cispecified as another value, step determines how many values are\n\ 18047db96d56Sopenharmony_ciskipped between successive calls. Works like a slice() on a list\n\ 18057db96d56Sopenharmony_cibut returns an iterator."); 18067db96d56Sopenharmony_ci 18077db96d56Sopenharmony_cistatic PyTypeObject islice_type = { 18087db96d56Sopenharmony_ci PyVarObject_HEAD_INIT(NULL, 0) 18097db96d56Sopenharmony_ci "itertools.islice", /* tp_name */ 18107db96d56Sopenharmony_ci sizeof(isliceobject), /* tp_basicsize */ 18117db96d56Sopenharmony_ci 0, /* tp_itemsize */ 18127db96d56Sopenharmony_ci /* methods */ 18137db96d56Sopenharmony_ci (destructor)islice_dealloc, /* tp_dealloc */ 18147db96d56Sopenharmony_ci 0, /* tp_vectorcall_offset */ 18157db96d56Sopenharmony_ci 0, /* tp_getattr */ 18167db96d56Sopenharmony_ci 0, /* tp_setattr */ 18177db96d56Sopenharmony_ci 0, /* tp_as_async */ 18187db96d56Sopenharmony_ci 0, /* tp_repr */ 18197db96d56Sopenharmony_ci 0, /* tp_as_number */ 18207db96d56Sopenharmony_ci 0, /* tp_as_sequence */ 18217db96d56Sopenharmony_ci 0, /* tp_as_mapping */ 18227db96d56Sopenharmony_ci 0, /* tp_hash */ 18237db96d56Sopenharmony_ci 0, /* tp_call */ 18247db96d56Sopenharmony_ci 0, /* tp_str */ 18257db96d56Sopenharmony_ci PyObject_GenericGetAttr, /* tp_getattro */ 18267db96d56Sopenharmony_ci 0, /* tp_setattro */ 18277db96d56Sopenharmony_ci 0, /* tp_as_buffer */ 18287db96d56Sopenharmony_ci Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | 18297db96d56Sopenharmony_ci Py_TPFLAGS_BASETYPE, /* tp_flags */ 18307db96d56Sopenharmony_ci islice_doc, /* tp_doc */ 18317db96d56Sopenharmony_ci (traverseproc)islice_traverse, /* tp_traverse */ 18327db96d56Sopenharmony_ci 0, /* tp_clear */ 18337db96d56Sopenharmony_ci 0, /* tp_richcompare */ 18347db96d56Sopenharmony_ci 0, /* tp_weaklistoffset */ 18357db96d56Sopenharmony_ci PyObject_SelfIter, /* tp_iter */ 18367db96d56Sopenharmony_ci (iternextfunc)islice_next, /* tp_iternext */ 18377db96d56Sopenharmony_ci islice_methods, /* tp_methods */ 18387db96d56Sopenharmony_ci 0, /* tp_members */ 18397db96d56Sopenharmony_ci 0, /* tp_getset */ 18407db96d56Sopenharmony_ci 0, /* tp_base */ 18417db96d56Sopenharmony_ci 0, /* tp_dict */ 18427db96d56Sopenharmony_ci 0, /* tp_descr_get */ 18437db96d56Sopenharmony_ci 0, /* tp_descr_set */ 18447db96d56Sopenharmony_ci 0, /* tp_dictoffset */ 18457db96d56Sopenharmony_ci 0, /* tp_init */ 18467db96d56Sopenharmony_ci 0, /* tp_alloc */ 18477db96d56Sopenharmony_ci islice_new, /* tp_new */ 18487db96d56Sopenharmony_ci PyObject_GC_Del, /* tp_free */ 18497db96d56Sopenharmony_ci}; 18507db96d56Sopenharmony_ci 18517db96d56Sopenharmony_ci 18527db96d56Sopenharmony_ci/* starmap object ************************************************************/ 18537db96d56Sopenharmony_ci 18547db96d56Sopenharmony_citypedef struct { 18557db96d56Sopenharmony_ci PyObject_HEAD 18567db96d56Sopenharmony_ci PyObject *func; 18577db96d56Sopenharmony_ci PyObject *it; 18587db96d56Sopenharmony_ci} starmapobject; 18597db96d56Sopenharmony_ci 18607db96d56Sopenharmony_ci/*[clinic input] 18617db96d56Sopenharmony_ci@classmethod 18627db96d56Sopenharmony_ciitertools.starmap.__new__ 18637db96d56Sopenharmony_ci function as func: object 18647db96d56Sopenharmony_ci iterable as seq: object 18657db96d56Sopenharmony_ci / 18667db96d56Sopenharmony_ciReturn an iterator whose values are returned from the function evaluated with an argument tuple taken from the given sequence. 18677db96d56Sopenharmony_ci[clinic start generated code]*/ 18687db96d56Sopenharmony_ci 18697db96d56Sopenharmony_cistatic PyObject * 18707db96d56Sopenharmony_ciitertools_starmap_impl(PyTypeObject *type, PyObject *func, PyObject *seq) 18717db96d56Sopenharmony_ci/*[clinic end generated code: output=79eeb81d452c6e8d input=844766df6a0d4dad]*/ 18727db96d56Sopenharmony_ci{ 18737db96d56Sopenharmony_ci PyObject *it; 18747db96d56Sopenharmony_ci starmapobject *lz; 18757db96d56Sopenharmony_ci 18767db96d56Sopenharmony_ci /* Get iterator. */ 18777db96d56Sopenharmony_ci it = PyObject_GetIter(seq); 18787db96d56Sopenharmony_ci if (it == NULL) 18797db96d56Sopenharmony_ci return NULL; 18807db96d56Sopenharmony_ci 18817db96d56Sopenharmony_ci /* create starmapobject structure */ 18827db96d56Sopenharmony_ci lz = (starmapobject *)type->tp_alloc(type, 0); 18837db96d56Sopenharmony_ci if (lz == NULL) { 18847db96d56Sopenharmony_ci Py_DECREF(it); 18857db96d56Sopenharmony_ci return NULL; 18867db96d56Sopenharmony_ci } 18877db96d56Sopenharmony_ci Py_INCREF(func); 18887db96d56Sopenharmony_ci lz->func = func; 18897db96d56Sopenharmony_ci lz->it = it; 18907db96d56Sopenharmony_ci 18917db96d56Sopenharmony_ci return (PyObject *)lz; 18927db96d56Sopenharmony_ci} 18937db96d56Sopenharmony_ci 18947db96d56Sopenharmony_cistatic void 18957db96d56Sopenharmony_cistarmap_dealloc(starmapobject *lz) 18967db96d56Sopenharmony_ci{ 18977db96d56Sopenharmony_ci PyObject_GC_UnTrack(lz); 18987db96d56Sopenharmony_ci Py_XDECREF(lz->func); 18997db96d56Sopenharmony_ci Py_XDECREF(lz->it); 19007db96d56Sopenharmony_ci Py_TYPE(lz)->tp_free(lz); 19017db96d56Sopenharmony_ci} 19027db96d56Sopenharmony_ci 19037db96d56Sopenharmony_cistatic int 19047db96d56Sopenharmony_cistarmap_traverse(starmapobject *lz, visitproc visit, void *arg) 19057db96d56Sopenharmony_ci{ 19067db96d56Sopenharmony_ci Py_VISIT(lz->it); 19077db96d56Sopenharmony_ci Py_VISIT(lz->func); 19087db96d56Sopenharmony_ci return 0; 19097db96d56Sopenharmony_ci} 19107db96d56Sopenharmony_ci 19117db96d56Sopenharmony_cistatic PyObject * 19127db96d56Sopenharmony_cistarmap_next(starmapobject *lz) 19137db96d56Sopenharmony_ci{ 19147db96d56Sopenharmony_ci PyObject *args; 19157db96d56Sopenharmony_ci PyObject *result; 19167db96d56Sopenharmony_ci PyObject *it = lz->it; 19177db96d56Sopenharmony_ci 19187db96d56Sopenharmony_ci args = (*Py_TYPE(it)->tp_iternext)(it); 19197db96d56Sopenharmony_ci if (args == NULL) 19207db96d56Sopenharmony_ci return NULL; 19217db96d56Sopenharmony_ci if (!PyTuple_CheckExact(args)) { 19227db96d56Sopenharmony_ci PyObject *newargs = PySequence_Tuple(args); 19237db96d56Sopenharmony_ci Py_DECREF(args); 19247db96d56Sopenharmony_ci if (newargs == NULL) 19257db96d56Sopenharmony_ci return NULL; 19267db96d56Sopenharmony_ci args = newargs; 19277db96d56Sopenharmony_ci } 19287db96d56Sopenharmony_ci result = PyObject_Call(lz->func, args, NULL); 19297db96d56Sopenharmony_ci Py_DECREF(args); 19307db96d56Sopenharmony_ci return result; 19317db96d56Sopenharmony_ci} 19327db96d56Sopenharmony_ci 19337db96d56Sopenharmony_cistatic PyObject * 19347db96d56Sopenharmony_cistarmap_reduce(starmapobject *lz, PyObject *Py_UNUSED(ignored)) 19357db96d56Sopenharmony_ci{ 19367db96d56Sopenharmony_ci /* Just pickle the iterator */ 19377db96d56Sopenharmony_ci return Py_BuildValue("O(OO)", Py_TYPE(lz), lz->func, lz->it); 19387db96d56Sopenharmony_ci} 19397db96d56Sopenharmony_ci 19407db96d56Sopenharmony_cistatic PyMethodDef starmap_methods[] = { 19417db96d56Sopenharmony_ci {"__reduce__", (PyCFunction)starmap_reduce, METH_NOARGS, 19427db96d56Sopenharmony_ci reduce_doc}, 19437db96d56Sopenharmony_ci {NULL, NULL} /* sentinel */ 19447db96d56Sopenharmony_ci}; 19457db96d56Sopenharmony_ci 19467db96d56Sopenharmony_cistatic PyTypeObject starmap_type = { 19477db96d56Sopenharmony_ci PyVarObject_HEAD_INIT(NULL, 0) 19487db96d56Sopenharmony_ci "itertools.starmap", /* tp_name */ 19497db96d56Sopenharmony_ci sizeof(starmapobject), /* tp_basicsize */ 19507db96d56Sopenharmony_ci 0, /* tp_itemsize */ 19517db96d56Sopenharmony_ci /* methods */ 19527db96d56Sopenharmony_ci (destructor)starmap_dealloc, /* tp_dealloc */ 19537db96d56Sopenharmony_ci 0, /* tp_vectorcall_offset */ 19547db96d56Sopenharmony_ci 0, /* tp_getattr */ 19557db96d56Sopenharmony_ci 0, /* tp_setattr */ 19567db96d56Sopenharmony_ci 0, /* tp_as_async */ 19577db96d56Sopenharmony_ci 0, /* tp_repr */ 19587db96d56Sopenharmony_ci 0, /* tp_as_number */ 19597db96d56Sopenharmony_ci 0, /* tp_as_sequence */ 19607db96d56Sopenharmony_ci 0, /* tp_as_mapping */ 19617db96d56Sopenharmony_ci 0, /* tp_hash */ 19627db96d56Sopenharmony_ci 0, /* tp_call */ 19637db96d56Sopenharmony_ci 0, /* tp_str */ 19647db96d56Sopenharmony_ci PyObject_GenericGetAttr, /* tp_getattro */ 19657db96d56Sopenharmony_ci 0, /* tp_setattro */ 19667db96d56Sopenharmony_ci 0, /* tp_as_buffer */ 19677db96d56Sopenharmony_ci Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | 19687db96d56Sopenharmony_ci Py_TPFLAGS_BASETYPE, /* tp_flags */ 19697db96d56Sopenharmony_ci itertools_starmap__doc__, /* tp_doc */ 19707db96d56Sopenharmony_ci (traverseproc)starmap_traverse, /* tp_traverse */ 19717db96d56Sopenharmony_ci 0, /* tp_clear */ 19727db96d56Sopenharmony_ci 0, /* tp_richcompare */ 19737db96d56Sopenharmony_ci 0, /* tp_weaklistoffset */ 19747db96d56Sopenharmony_ci PyObject_SelfIter, /* tp_iter */ 19757db96d56Sopenharmony_ci (iternextfunc)starmap_next, /* tp_iternext */ 19767db96d56Sopenharmony_ci starmap_methods, /* tp_methods */ 19777db96d56Sopenharmony_ci 0, /* tp_members */ 19787db96d56Sopenharmony_ci 0, /* tp_getset */ 19797db96d56Sopenharmony_ci 0, /* tp_base */ 19807db96d56Sopenharmony_ci 0, /* tp_dict */ 19817db96d56Sopenharmony_ci 0, /* tp_descr_get */ 19827db96d56Sopenharmony_ci 0, /* tp_descr_set */ 19837db96d56Sopenharmony_ci 0, /* tp_dictoffset */ 19847db96d56Sopenharmony_ci 0, /* tp_init */ 19857db96d56Sopenharmony_ci 0, /* tp_alloc */ 19867db96d56Sopenharmony_ci itertools_starmap, /* tp_new */ 19877db96d56Sopenharmony_ci PyObject_GC_Del, /* tp_free */ 19887db96d56Sopenharmony_ci}; 19897db96d56Sopenharmony_ci 19907db96d56Sopenharmony_ci 19917db96d56Sopenharmony_ci/* chain object **************************************************************/ 19927db96d56Sopenharmony_ci 19937db96d56Sopenharmony_citypedef struct { 19947db96d56Sopenharmony_ci PyObject_HEAD 19957db96d56Sopenharmony_ci PyObject *source; /* Iterator over input iterables */ 19967db96d56Sopenharmony_ci PyObject *active; /* Currently running input iterator */ 19977db96d56Sopenharmony_ci} chainobject; 19987db96d56Sopenharmony_ci 19997db96d56Sopenharmony_cistatic PyTypeObject chain_type; 20007db96d56Sopenharmony_ci 20017db96d56Sopenharmony_cistatic PyObject * 20027db96d56Sopenharmony_cichain_new_internal(PyTypeObject *type, PyObject *source) 20037db96d56Sopenharmony_ci{ 20047db96d56Sopenharmony_ci chainobject *lz; 20057db96d56Sopenharmony_ci 20067db96d56Sopenharmony_ci lz = (chainobject *)type->tp_alloc(type, 0); 20077db96d56Sopenharmony_ci if (lz == NULL) { 20087db96d56Sopenharmony_ci Py_DECREF(source); 20097db96d56Sopenharmony_ci return NULL; 20107db96d56Sopenharmony_ci } 20117db96d56Sopenharmony_ci 20127db96d56Sopenharmony_ci lz->source = source; 20137db96d56Sopenharmony_ci lz->active = NULL; 20147db96d56Sopenharmony_ci return (PyObject *)lz; 20157db96d56Sopenharmony_ci} 20167db96d56Sopenharmony_ci 20177db96d56Sopenharmony_cistatic PyObject * 20187db96d56Sopenharmony_cichain_new(PyTypeObject *type, PyObject *args, PyObject *kwds) 20197db96d56Sopenharmony_ci{ 20207db96d56Sopenharmony_ci PyObject *source; 20217db96d56Sopenharmony_ci 20227db96d56Sopenharmony_ci if ((type == &chain_type || type->tp_init == chain_type.tp_init) && 20237db96d56Sopenharmony_ci !_PyArg_NoKeywords("chain", kwds)) 20247db96d56Sopenharmony_ci return NULL; 20257db96d56Sopenharmony_ci 20267db96d56Sopenharmony_ci source = PyObject_GetIter(args); 20277db96d56Sopenharmony_ci if (source == NULL) 20287db96d56Sopenharmony_ci return NULL; 20297db96d56Sopenharmony_ci 20307db96d56Sopenharmony_ci return chain_new_internal(type, source); 20317db96d56Sopenharmony_ci} 20327db96d56Sopenharmony_ci 20337db96d56Sopenharmony_ci/*[clinic input] 20347db96d56Sopenharmony_ci@classmethod 20357db96d56Sopenharmony_ciitertools.chain.from_iterable 20367db96d56Sopenharmony_ci iterable as arg: object 20377db96d56Sopenharmony_ci / 20387db96d56Sopenharmony_ciAlternative chain() constructor taking a single iterable argument that evaluates lazily. 20397db96d56Sopenharmony_ci[clinic start generated code]*/ 20407db96d56Sopenharmony_ci 20417db96d56Sopenharmony_cistatic PyObject * 20427db96d56Sopenharmony_ciitertools_chain_from_iterable(PyTypeObject *type, PyObject *arg) 20437db96d56Sopenharmony_ci/*[clinic end generated code: output=667ae7a7f7b68654 input=72c39e3a2ca3be85]*/ 20447db96d56Sopenharmony_ci{ 20457db96d56Sopenharmony_ci PyObject *source; 20467db96d56Sopenharmony_ci 20477db96d56Sopenharmony_ci source = PyObject_GetIter(arg); 20487db96d56Sopenharmony_ci if (source == NULL) 20497db96d56Sopenharmony_ci return NULL; 20507db96d56Sopenharmony_ci 20517db96d56Sopenharmony_ci return chain_new_internal(type, source); 20527db96d56Sopenharmony_ci} 20537db96d56Sopenharmony_ci 20547db96d56Sopenharmony_cistatic void 20557db96d56Sopenharmony_cichain_dealloc(chainobject *lz) 20567db96d56Sopenharmony_ci{ 20577db96d56Sopenharmony_ci PyObject_GC_UnTrack(lz); 20587db96d56Sopenharmony_ci Py_XDECREF(lz->active); 20597db96d56Sopenharmony_ci Py_XDECREF(lz->source); 20607db96d56Sopenharmony_ci Py_TYPE(lz)->tp_free(lz); 20617db96d56Sopenharmony_ci} 20627db96d56Sopenharmony_ci 20637db96d56Sopenharmony_cistatic int 20647db96d56Sopenharmony_cichain_traverse(chainobject *lz, visitproc visit, void *arg) 20657db96d56Sopenharmony_ci{ 20667db96d56Sopenharmony_ci Py_VISIT(lz->source); 20677db96d56Sopenharmony_ci Py_VISIT(lz->active); 20687db96d56Sopenharmony_ci return 0; 20697db96d56Sopenharmony_ci} 20707db96d56Sopenharmony_ci 20717db96d56Sopenharmony_cistatic PyObject * 20727db96d56Sopenharmony_cichain_next(chainobject *lz) 20737db96d56Sopenharmony_ci{ 20747db96d56Sopenharmony_ci PyObject *item; 20757db96d56Sopenharmony_ci 20767db96d56Sopenharmony_ci /* lz->source is the iterator of iterables. If it's NULL, we've already 20777db96d56Sopenharmony_ci * consumed them all. lz->active is the current iterator. If it's NULL, 20787db96d56Sopenharmony_ci * we should grab a new one from lz->source. */ 20797db96d56Sopenharmony_ci while (lz->source != NULL) { 20807db96d56Sopenharmony_ci if (lz->active == NULL) { 20817db96d56Sopenharmony_ci PyObject *iterable = PyIter_Next(lz->source); 20827db96d56Sopenharmony_ci if (iterable == NULL) { 20837db96d56Sopenharmony_ci Py_CLEAR(lz->source); 20847db96d56Sopenharmony_ci return NULL; /* no more input sources */ 20857db96d56Sopenharmony_ci } 20867db96d56Sopenharmony_ci lz->active = PyObject_GetIter(iterable); 20877db96d56Sopenharmony_ci Py_DECREF(iterable); 20887db96d56Sopenharmony_ci if (lz->active == NULL) { 20897db96d56Sopenharmony_ci Py_CLEAR(lz->source); 20907db96d56Sopenharmony_ci return NULL; /* input not iterable */ 20917db96d56Sopenharmony_ci } 20927db96d56Sopenharmony_ci } 20937db96d56Sopenharmony_ci item = (*Py_TYPE(lz->active)->tp_iternext)(lz->active); 20947db96d56Sopenharmony_ci if (item != NULL) 20957db96d56Sopenharmony_ci return item; 20967db96d56Sopenharmony_ci if (PyErr_Occurred()) { 20977db96d56Sopenharmony_ci if (PyErr_ExceptionMatches(PyExc_StopIteration)) 20987db96d56Sopenharmony_ci PyErr_Clear(); 20997db96d56Sopenharmony_ci else 21007db96d56Sopenharmony_ci return NULL; /* input raised an exception */ 21017db96d56Sopenharmony_ci } 21027db96d56Sopenharmony_ci /* lz->active is consumed, try with the next iterable. */ 21037db96d56Sopenharmony_ci Py_CLEAR(lz->active); 21047db96d56Sopenharmony_ci } 21057db96d56Sopenharmony_ci /* Everything had been consumed already. */ 21067db96d56Sopenharmony_ci return NULL; 21077db96d56Sopenharmony_ci} 21087db96d56Sopenharmony_ci 21097db96d56Sopenharmony_cistatic PyObject * 21107db96d56Sopenharmony_cichain_reduce(chainobject *lz, PyObject *Py_UNUSED(ignored)) 21117db96d56Sopenharmony_ci{ 21127db96d56Sopenharmony_ci if (lz->source) { 21137db96d56Sopenharmony_ci /* we can't pickle function objects (itertools.from_iterable) so 21147db96d56Sopenharmony_ci * we must use setstate to replace the iterable. One day we 21157db96d56Sopenharmony_ci * will fix pickling of functions 21167db96d56Sopenharmony_ci */ 21177db96d56Sopenharmony_ci if (lz->active) { 21187db96d56Sopenharmony_ci return Py_BuildValue("O()(OO)", Py_TYPE(lz), lz->source, lz->active); 21197db96d56Sopenharmony_ci } else { 21207db96d56Sopenharmony_ci return Py_BuildValue("O()(O)", Py_TYPE(lz), lz->source); 21217db96d56Sopenharmony_ci } 21227db96d56Sopenharmony_ci } else { 21237db96d56Sopenharmony_ci return Py_BuildValue("O()", Py_TYPE(lz)); /* exhausted */ 21247db96d56Sopenharmony_ci } 21257db96d56Sopenharmony_ci return NULL; 21267db96d56Sopenharmony_ci} 21277db96d56Sopenharmony_ci 21287db96d56Sopenharmony_cistatic PyObject * 21297db96d56Sopenharmony_cichain_setstate(chainobject *lz, PyObject *state) 21307db96d56Sopenharmony_ci{ 21317db96d56Sopenharmony_ci PyObject *source, *active=NULL; 21327db96d56Sopenharmony_ci 21337db96d56Sopenharmony_ci if (!PyTuple_Check(state)) { 21347db96d56Sopenharmony_ci PyErr_SetString(PyExc_TypeError, "state is not a tuple"); 21357db96d56Sopenharmony_ci return NULL; 21367db96d56Sopenharmony_ci } 21377db96d56Sopenharmony_ci if (!PyArg_ParseTuple(state, "O|O", &source, &active)) { 21387db96d56Sopenharmony_ci return NULL; 21397db96d56Sopenharmony_ci } 21407db96d56Sopenharmony_ci if (!PyIter_Check(source) || (active != NULL && !PyIter_Check(active))) { 21417db96d56Sopenharmony_ci PyErr_SetString(PyExc_TypeError, "Arguments must be iterators."); 21427db96d56Sopenharmony_ci return NULL; 21437db96d56Sopenharmony_ci } 21447db96d56Sopenharmony_ci 21457db96d56Sopenharmony_ci Py_INCREF(source); 21467db96d56Sopenharmony_ci Py_XSETREF(lz->source, source); 21477db96d56Sopenharmony_ci Py_XINCREF(active); 21487db96d56Sopenharmony_ci Py_XSETREF(lz->active, active); 21497db96d56Sopenharmony_ci Py_RETURN_NONE; 21507db96d56Sopenharmony_ci} 21517db96d56Sopenharmony_ci 21527db96d56Sopenharmony_ciPyDoc_STRVAR(chain_doc, 21537db96d56Sopenharmony_ci"chain(*iterables) --> chain object\n\ 21547db96d56Sopenharmony_ci\n\ 21557db96d56Sopenharmony_ciReturn a chain object whose .__next__() method returns elements from the\n\ 21567db96d56Sopenharmony_cifirst iterable until it is exhausted, then elements from the next\n\ 21577db96d56Sopenharmony_ciiterable, until all of the iterables are exhausted."); 21587db96d56Sopenharmony_ci 21597db96d56Sopenharmony_cistatic PyMethodDef chain_methods[] = { 21607db96d56Sopenharmony_ci ITERTOOLS_CHAIN_FROM_ITERABLE_METHODDEF 21617db96d56Sopenharmony_ci {"__reduce__", (PyCFunction)chain_reduce, METH_NOARGS, 21627db96d56Sopenharmony_ci reduce_doc}, 21637db96d56Sopenharmony_ci {"__setstate__", (PyCFunction)chain_setstate, METH_O, 21647db96d56Sopenharmony_ci setstate_doc}, 21657db96d56Sopenharmony_ci {"__class_getitem__", Py_GenericAlias, 21667db96d56Sopenharmony_ci METH_O|METH_CLASS, PyDoc_STR("See PEP 585")}, 21677db96d56Sopenharmony_ci {NULL, NULL} /* sentinel */ 21687db96d56Sopenharmony_ci}; 21697db96d56Sopenharmony_ci 21707db96d56Sopenharmony_cistatic PyTypeObject chain_type = { 21717db96d56Sopenharmony_ci PyVarObject_HEAD_INIT(NULL, 0) 21727db96d56Sopenharmony_ci "itertools.chain", /* tp_name */ 21737db96d56Sopenharmony_ci sizeof(chainobject), /* tp_basicsize */ 21747db96d56Sopenharmony_ci 0, /* tp_itemsize */ 21757db96d56Sopenharmony_ci /* methods */ 21767db96d56Sopenharmony_ci (destructor)chain_dealloc, /* tp_dealloc */ 21777db96d56Sopenharmony_ci 0, /* tp_vectorcall_offset */ 21787db96d56Sopenharmony_ci 0, /* tp_getattr */ 21797db96d56Sopenharmony_ci 0, /* tp_setattr */ 21807db96d56Sopenharmony_ci 0, /* tp_as_async */ 21817db96d56Sopenharmony_ci 0, /* tp_repr */ 21827db96d56Sopenharmony_ci 0, /* tp_as_number */ 21837db96d56Sopenharmony_ci 0, /* tp_as_sequence */ 21847db96d56Sopenharmony_ci 0, /* tp_as_mapping */ 21857db96d56Sopenharmony_ci 0, /* tp_hash */ 21867db96d56Sopenharmony_ci 0, /* tp_call */ 21877db96d56Sopenharmony_ci 0, /* tp_str */ 21887db96d56Sopenharmony_ci PyObject_GenericGetAttr, /* tp_getattro */ 21897db96d56Sopenharmony_ci 0, /* tp_setattro */ 21907db96d56Sopenharmony_ci 0, /* tp_as_buffer */ 21917db96d56Sopenharmony_ci Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | 21927db96d56Sopenharmony_ci Py_TPFLAGS_BASETYPE, /* tp_flags */ 21937db96d56Sopenharmony_ci chain_doc, /* tp_doc */ 21947db96d56Sopenharmony_ci (traverseproc)chain_traverse, /* tp_traverse */ 21957db96d56Sopenharmony_ci 0, /* tp_clear */ 21967db96d56Sopenharmony_ci 0, /* tp_richcompare */ 21977db96d56Sopenharmony_ci 0, /* tp_weaklistoffset */ 21987db96d56Sopenharmony_ci PyObject_SelfIter, /* tp_iter */ 21997db96d56Sopenharmony_ci (iternextfunc)chain_next, /* tp_iternext */ 22007db96d56Sopenharmony_ci chain_methods, /* tp_methods */ 22017db96d56Sopenharmony_ci 0, /* tp_members */ 22027db96d56Sopenharmony_ci 0, /* tp_getset */ 22037db96d56Sopenharmony_ci 0, /* tp_base */ 22047db96d56Sopenharmony_ci 0, /* tp_dict */ 22057db96d56Sopenharmony_ci 0, /* tp_descr_get */ 22067db96d56Sopenharmony_ci 0, /* tp_descr_set */ 22077db96d56Sopenharmony_ci 0, /* tp_dictoffset */ 22087db96d56Sopenharmony_ci 0, /* tp_init */ 22097db96d56Sopenharmony_ci 0, /* tp_alloc */ 22107db96d56Sopenharmony_ci chain_new, /* tp_new */ 22117db96d56Sopenharmony_ci PyObject_GC_Del, /* tp_free */ 22127db96d56Sopenharmony_ci}; 22137db96d56Sopenharmony_ci 22147db96d56Sopenharmony_ci 22157db96d56Sopenharmony_ci/* product object ************************************************************/ 22167db96d56Sopenharmony_ci 22177db96d56Sopenharmony_citypedef struct { 22187db96d56Sopenharmony_ci PyObject_HEAD 22197db96d56Sopenharmony_ci PyObject *pools; /* tuple of pool tuples */ 22207db96d56Sopenharmony_ci Py_ssize_t *indices; /* one index per pool */ 22217db96d56Sopenharmony_ci PyObject *result; /* most recently returned result tuple */ 22227db96d56Sopenharmony_ci int stopped; /* set to 1 when the iterator is exhausted */ 22237db96d56Sopenharmony_ci} productobject; 22247db96d56Sopenharmony_ci 22257db96d56Sopenharmony_cistatic PyTypeObject product_type; 22267db96d56Sopenharmony_ci 22277db96d56Sopenharmony_cistatic PyObject * 22287db96d56Sopenharmony_ciproduct_new(PyTypeObject *type, PyObject *args, PyObject *kwds) 22297db96d56Sopenharmony_ci{ 22307db96d56Sopenharmony_ci productobject *lz; 22317db96d56Sopenharmony_ci Py_ssize_t nargs, npools, repeat=1; 22327db96d56Sopenharmony_ci PyObject *pools = NULL; 22337db96d56Sopenharmony_ci Py_ssize_t *indices = NULL; 22347db96d56Sopenharmony_ci Py_ssize_t i; 22357db96d56Sopenharmony_ci 22367db96d56Sopenharmony_ci if (kwds != NULL) { 22377db96d56Sopenharmony_ci char *kwlist[] = {"repeat", 0}; 22387db96d56Sopenharmony_ci PyObject *tmpargs = PyTuple_New(0); 22397db96d56Sopenharmony_ci if (tmpargs == NULL) 22407db96d56Sopenharmony_ci return NULL; 22417db96d56Sopenharmony_ci if (!PyArg_ParseTupleAndKeywords(tmpargs, kwds, "|n:product", 22427db96d56Sopenharmony_ci kwlist, &repeat)) { 22437db96d56Sopenharmony_ci Py_DECREF(tmpargs); 22447db96d56Sopenharmony_ci return NULL; 22457db96d56Sopenharmony_ci } 22467db96d56Sopenharmony_ci Py_DECREF(tmpargs); 22477db96d56Sopenharmony_ci if (repeat < 0) { 22487db96d56Sopenharmony_ci PyErr_SetString(PyExc_ValueError, 22497db96d56Sopenharmony_ci "repeat argument cannot be negative"); 22507db96d56Sopenharmony_ci return NULL; 22517db96d56Sopenharmony_ci } 22527db96d56Sopenharmony_ci } 22537db96d56Sopenharmony_ci 22547db96d56Sopenharmony_ci assert(PyTuple_CheckExact(args)); 22557db96d56Sopenharmony_ci if (repeat == 0) { 22567db96d56Sopenharmony_ci nargs = 0; 22577db96d56Sopenharmony_ci } else { 22587db96d56Sopenharmony_ci nargs = PyTuple_GET_SIZE(args); 22597db96d56Sopenharmony_ci if ((size_t)nargs > PY_SSIZE_T_MAX/sizeof(Py_ssize_t)/repeat) { 22607db96d56Sopenharmony_ci PyErr_SetString(PyExc_OverflowError, "repeat argument too large"); 22617db96d56Sopenharmony_ci return NULL; 22627db96d56Sopenharmony_ci } 22637db96d56Sopenharmony_ci } 22647db96d56Sopenharmony_ci npools = nargs * repeat; 22657db96d56Sopenharmony_ci 22667db96d56Sopenharmony_ci indices = PyMem_New(Py_ssize_t, npools); 22677db96d56Sopenharmony_ci if (indices == NULL) { 22687db96d56Sopenharmony_ci PyErr_NoMemory(); 22697db96d56Sopenharmony_ci goto error; 22707db96d56Sopenharmony_ci } 22717db96d56Sopenharmony_ci 22727db96d56Sopenharmony_ci pools = PyTuple_New(npools); 22737db96d56Sopenharmony_ci if (pools == NULL) 22747db96d56Sopenharmony_ci goto error; 22757db96d56Sopenharmony_ci 22767db96d56Sopenharmony_ci for (i=0; i < nargs ; ++i) { 22777db96d56Sopenharmony_ci PyObject *item = PyTuple_GET_ITEM(args, i); 22787db96d56Sopenharmony_ci PyObject *pool = PySequence_Tuple(item); 22797db96d56Sopenharmony_ci if (pool == NULL) 22807db96d56Sopenharmony_ci goto error; 22817db96d56Sopenharmony_ci PyTuple_SET_ITEM(pools, i, pool); 22827db96d56Sopenharmony_ci indices[i] = 0; 22837db96d56Sopenharmony_ci } 22847db96d56Sopenharmony_ci for ( ; i < npools; ++i) { 22857db96d56Sopenharmony_ci PyObject *pool = PyTuple_GET_ITEM(pools, i - nargs); 22867db96d56Sopenharmony_ci Py_INCREF(pool); 22877db96d56Sopenharmony_ci PyTuple_SET_ITEM(pools, i, pool); 22887db96d56Sopenharmony_ci indices[i] = 0; 22897db96d56Sopenharmony_ci } 22907db96d56Sopenharmony_ci 22917db96d56Sopenharmony_ci /* create productobject structure */ 22927db96d56Sopenharmony_ci lz = (productobject *)type->tp_alloc(type, 0); 22937db96d56Sopenharmony_ci if (lz == NULL) 22947db96d56Sopenharmony_ci goto error; 22957db96d56Sopenharmony_ci 22967db96d56Sopenharmony_ci lz->pools = pools; 22977db96d56Sopenharmony_ci lz->indices = indices; 22987db96d56Sopenharmony_ci lz->result = NULL; 22997db96d56Sopenharmony_ci lz->stopped = 0; 23007db96d56Sopenharmony_ci 23017db96d56Sopenharmony_ci return (PyObject *)lz; 23027db96d56Sopenharmony_ci 23037db96d56Sopenharmony_cierror: 23047db96d56Sopenharmony_ci if (indices != NULL) 23057db96d56Sopenharmony_ci PyMem_Free(indices); 23067db96d56Sopenharmony_ci Py_XDECREF(pools); 23077db96d56Sopenharmony_ci return NULL; 23087db96d56Sopenharmony_ci} 23097db96d56Sopenharmony_ci 23107db96d56Sopenharmony_cistatic void 23117db96d56Sopenharmony_ciproduct_dealloc(productobject *lz) 23127db96d56Sopenharmony_ci{ 23137db96d56Sopenharmony_ci PyObject_GC_UnTrack(lz); 23147db96d56Sopenharmony_ci Py_XDECREF(lz->pools); 23157db96d56Sopenharmony_ci Py_XDECREF(lz->result); 23167db96d56Sopenharmony_ci if (lz->indices != NULL) 23177db96d56Sopenharmony_ci PyMem_Free(lz->indices); 23187db96d56Sopenharmony_ci Py_TYPE(lz)->tp_free(lz); 23197db96d56Sopenharmony_ci} 23207db96d56Sopenharmony_ci 23217db96d56Sopenharmony_cistatic PyObject * 23227db96d56Sopenharmony_ciproduct_sizeof(productobject *lz, void *unused) 23237db96d56Sopenharmony_ci{ 23247db96d56Sopenharmony_ci Py_ssize_t res; 23257db96d56Sopenharmony_ci 23267db96d56Sopenharmony_ci res = _PyObject_SIZE(Py_TYPE(lz)); 23277db96d56Sopenharmony_ci res += PyTuple_GET_SIZE(lz->pools) * sizeof(Py_ssize_t); 23287db96d56Sopenharmony_ci return PyLong_FromSsize_t(res); 23297db96d56Sopenharmony_ci} 23307db96d56Sopenharmony_ci 23317db96d56Sopenharmony_ciPyDoc_STRVAR(sizeof_doc, "Returns size in memory, in bytes."); 23327db96d56Sopenharmony_ci 23337db96d56Sopenharmony_cistatic int 23347db96d56Sopenharmony_ciproduct_traverse(productobject *lz, visitproc visit, void *arg) 23357db96d56Sopenharmony_ci{ 23367db96d56Sopenharmony_ci Py_VISIT(lz->pools); 23377db96d56Sopenharmony_ci Py_VISIT(lz->result); 23387db96d56Sopenharmony_ci return 0; 23397db96d56Sopenharmony_ci} 23407db96d56Sopenharmony_ci 23417db96d56Sopenharmony_cistatic PyObject * 23427db96d56Sopenharmony_ciproduct_next(productobject *lz) 23437db96d56Sopenharmony_ci{ 23447db96d56Sopenharmony_ci PyObject *pool; 23457db96d56Sopenharmony_ci PyObject *elem; 23467db96d56Sopenharmony_ci PyObject *oldelem; 23477db96d56Sopenharmony_ci PyObject *pools = lz->pools; 23487db96d56Sopenharmony_ci PyObject *result = lz->result; 23497db96d56Sopenharmony_ci Py_ssize_t npools = PyTuple_GET_SIZE(pools); 23507db96d56Sopenharmony_ci Py_ssize_t i; 23517db96d56Sopenharmony_ci 23527db96d56Sopenharmony_ci if (lz->stopped) 23537db96d56Sopenharmony_ci return NULL; 23547db96d56Sopenharmony_ci 23557db96d56Sopenharmony_ci if (result == NULL) { 23567db96d56Sopenharmony_ci /* On the first pass, return an initial tuple filled with the 23577db96d56Sopenharmony_ci first element from each pool. */ 23587db96d56Sopenharmony_ci result = PyTuple_New(npools); 23597db96d56Sopenharmony_ci if (result == NULL) 23607db96d56Sopenharmony_ci goto empty; 23617db96d56Sopenharmony_ci lz->result = result; 23627db96d56Sopenharmony_ci for (i=0; i < npools; i++) { 23637db96d56Sopenharmony_ci pool = PyTuple_GET_ITEM(pools, i); 23647db96d56Sopenharmony_ci if (PyTuple_GET_SIZE(pool) == 0) 23657db96d56Sopenharmony_ci goto empty; 23667db96d56Sopenharmony_ci elem = PyTuple_GET_ITEM(pool, 0); 23677db96d56Sopenharmony_ci Py_INCREF(elem); 23687db96d56Sopenharmony_ci PyTuple_SET_ITEM(result, i, elem); 23697db96d56Sopenharmony_ci } 23707db96d56Sopenharmony_ci } else { 23717db96d56Sopenharmony_ci Py_ssize_t *indices = lz->indices; 23727db96d56Sopenharmony_ci 23737db96d56Sopenharmony_ci /* Copy the previous result tuple or re-use it if available */ 23747db96d56Sopenharmony_ci if (Py_REFCNT(result) > 1) { 23757db96d56Sopenharmony_ci PyObject *old_result = result; 23767db96d56Sopenharmony_ci result = _PyTuple_FromArray(_PyTuple_ITEMS(old_result), npools); 23777db96d56Sopenharmony_ci if (result == NULL) 23787db96d56Sopenharmony_ci goto empty; 23797db96d56Sopenharmony_ci lz->result = result; 23807db96d56Sopenharmony_ci Py_DECREF(old_result); 23817db96d56Sopenharmony_ci } 23827db96d56Sopenharmony_ci // bpo-42536: The GC may have untracked this result tuple. Since we're 23837db96d56Sopenharmony_ci // recycling it, make sure it's tracked again: 23847db96d56Sopenharmony_ci else if (!_PyObject_GC_IS_TRACKED(result)) { 23857db96d56Sopenharmony_ci _PyObject_GC_TRACK(result); 23867db96d56Sopenharmony_ci } 23877db96d56Sopenharmony_ci /* Now, we've got the only copy so we can update it in-place */ 23887db96d56Sopenharmony_ci assert (npools==0 || Py_REFCNT(result) == 1); 23897db96d56Sopenharmony_ci 23907db96d56Sopenharmony_ci /* Update the pool indices right-to-left. Only advance to the 23917db96d56Sopenharmony_ci next pool when the previous one rolls-over */ 23927db96d56Sopenharmony_ci for (i=npools-1 ; i >= 0 ; i--) { 23937db96d56Sopenharmony_ci pool = PyTuple_GET_ITEM(pools, i); 23947db96d56Sopenharmony_ci indices[i]++; 23957db96d56Sopenharmony_ci if (indices[i] == PyTuple_GET_SIZE(pool)) { 23967db96d56Sopenharmony_ci /* Roll-over and advance to next pool */ 23977db96d56Sopenharmony_ci indices[i] = 0; 23987db96d56Sopenharmony_ci elem = PyTuple_GET_ITEM(pool, 0); 23997db96d56Sopenharmony_ci Py_INCREF(elem); 24007db96d56Sopenharmony_ci oldelem = PyTuple_GET_ITEM(result, i); 24017db96d56Sopenharmony_ci PyTuple_SET_ITEM(result, i, elem); 24027db96d56Sopenharmony_ci Py_DECREF(oldelem); 24037db96d56Sopenharmony_ci } else { 24047db96d56Sopenharmony_ci /* No rollover. Just increment and stop here. */ 24057db96d56Sopenharmony_ci elem = PyTuple_GET_ITEM(pool, indices[i]); 24067db96d56Sopenharmony_ci Py_INCREF(elem); 24077db96d56Sopenharmony_ci oldelem = PyTuple_GET_ITEM(result, i); 24087db96d56Sopenharmony_ci PyTuple_SET_ITEM(result, i, elem); 24097db96d56Sopenharmony_ci Py_DECREF(oldelem); 24107db96d56Sopenharmony_ci break; 24117db96d56Sopenharmony_ci } 24127db96d56Sopenharmony_ci } 24137db96d56Sopenharmony_ci 24147db96d56Sopenharmony_ci /* If i is negative, then the indices have all rolled-over 24157db96d56Sopenharmony_ci and we're done. */ 24167db96d56Sopenharmony_ci if (i < 0) 24177db96d56Sopenharmony_ci goto empty; 24187db96d56Sopenharmony_ci } 24197db96d56Sopenharmony_ci 24207db96d56Sopenharmony_ci Py_INCREF(result); 24217db96d56Sopenharmony_ci return result; 24227db96d56Sopenharmony_ci 24237db96d56Sopenharmony_ciempty: 24247db96d56Sopenharmony_ci lz->stopped = 1; 24257db96d56Sopenharmony_ci return NULL; 24267db96d56Sopenharmony_ci} 24277db96d56Sopenharmony_ci 24287db96d56Sopenharmony_cistatic PyObject * 24297db96d56Sopenharmony_ciproduct_reduce(productobject *lz, PyObject *Py_UNUSED(ignored)) 24307db96d56Sopenharmony_ci{ 24317db96d56Sopenharmony_ci if (lz->stopped) { 24327db96d56Sopenharmony_ci return Py_BuildValue("O(())", Py_TYPE(lz)); 24337db96d56Sopenharmony_ci } else if (lz->result == NULL) { 24347db96d56Sopenharmony_ci return Py_BuildValue("OO", Py_TYPE(lz), lz->pools); 24357db96d56Sopenharmony_ci } else { 24367db96d56Sopenharmony_ci PyObject *indices; 24377db96d56Sopenharmony_ci Py_ssize_t n, i; 24387db96d56Sopenharmony_ci 24397db96d56Sopenharmony_ci /* we must pickle the indices use them for setstate, and 24407db96d56Sopenharmony_ci * additionally indicate that the iterator has started 24417db96d56Sopenharmony_ci */ 24427db96d56Sopenharmony_ci n = PyTuple_GET_SIZE(lz->pools); 24437db96d56Sopenharmony_ci indices = PyTuple_New(n); 24447db96d56Sopenharmony_ci if (indices == NULL) 24457db96d56Sopenharmony_ci return NULL; 24467db96d56Sopenharmony_ci for (i=0; i<n; i++){ 24477db96d56Sopenharmony_ci PyObject* index = PyLong_FromSsize_t(lz->indices[i]); 24487db96d56Sopenharmony_ci if (!index) { 24497db96d56Sopenharmony_ci Py_DECREF(indices); 24507db96d56Sopenharmony_ci return NULL; 24517db96d56Sopenharmony_ci } 24527db96d56Sopenharmony_ci PyTuple_SET_ITEM(indices, i, index); 24537db96d56Sopenharmony_ci } 24547db96d56Sopenharmony_ci return Py_BuildValue("OON", Py_TYPE(lz), lz->pools, indices); 24557db96d56Sopenharmony_ci } 24567db96d56Sopenharmony_ci} 24577db96d56Sopenharmony_ci 24587db96d56Sopenharmony_cistatic PyObject * 24597db96d56Sopenharmony_ciproduct_setstate(productobject *lz, PyObject *state) 24607db96d56Sopenharmony_ci{ 24617db96d56Sopenharmony_ci PyObject *result; 24627db96d56Sopenharmony_ci Py_ssize_t n, i; 24637db96d56Sopenharmony_ci 24647db96d56Sopenharmony_ci n = PyTuple_GET_SIZE(lz->pools); 24657db96d56Sopenharmony_ci if (!PyTuple_Check(state) || PyTuple_GET_SIZE(state) != n) { 24667db96d56Sopenharmony_ci PyErr_SetString(PyExc_ValueError, "invalid arguments"); 24677db96d56Sopenharmony_ci return NULL; 24687db96d56Sopenharmony_ci } 24697db96d56Sopenharmony_ci for (i=0; i<n; i++) 24707db96d56Sopenharmony_ci { 24717db96d56Sopenharmony_ci PyObject* indexObject = PyTuple_GET_ITEM(state, i); 24727db96d56Sopenharmony_ci Py_ssize_t index = PyLong_AsSsize_t(indexObject); 24737db96d56Sopenharmony_ci PyObject* pool; 24747db96d56Sopenharmony_ci Py_ssize_t poolsize; 24757db96d56Sopenharmony_ci if (index < 0 && PyErr_Occurred()) 24767db96d56Sopenharmony_ci return NULL; /* not an integer */ 24777db96d56Sopenharmony_ci pool = PyTuple_GET_ITEM(lz->pools, i); 24787db96d56Sopenharmony_ci poolsize = PyTuple_GET_SIZE(pool); 24797db96d56Sopenharmony_ci if (poolsize == 0) { 24807db96d56Sopenharmony_ci lz->stopped = 1; 24817db96d56Sopenharmony_ci Py_RETURN_NONE; 24827db96d56Sopenharmony_ci } 24837db96d56Sopenharmony_ci /* clamp the index */ 24847db96d56Sopenharmony_ci if (index < 0) 24857db96d56Sopenharmony_ci index = 0; 24867db96d56Sopenharmony_ci else if (index > poolsize-1) 24877db96d56Sopenharmony_ci index = poolsize-1; 24887db96d56Sopenharmony_ci lz->indices[i] = index; 24897db96d56Sopenharmony_ci } 24907db96d56Sopenharmony_ci 24917db96d56Sopenharmony_ci result = PyTuple_New(n); 24927db96d56Sopenharmony_ci if (!result) 24937db96d56Sopenharmony_ci return NULL; 24947db96d56Sopenharmony_ci for (i=0; i<n; i++) { 24957db96d56Sopenharmony_ci PyObject *pool = PyTuple_GET_ITEM(lz->pools, i); 24967db96d56Sopenharmony_ci PyObject *element = PyTuple_GET_ITEM(pool, lz->indices[i]); 24977db96d56Sopenharmony_ci Py_INCREF(element); 24987db96d56Sopenharmony_ci PyTuple_SET_ITEM(result, i, element); 24997db96d56Sopenharmony_ci } 25007db96d56Sopenharmony_ci Py_XSETREF(lz->result, result); 25017db96d56Sopenharmony_ci Py_RETURN_NONE; 25027db96d56Sopenharmony_ci} 25037db96d56Sopenharmony_ci 25047db96d56Sopenharmony_cistatic PyMethodDef product_methods[] = { 25057db96d56Sopenharmony_ci {"__reduce__", (PyCFunction)product_reduce, METH_NOARGS, 25067db96d56Sopenharmony_ci reduce_doc}, 25077db96d56Sopenharmony_ci {"__setstate__", (PyCFunction)product_setstate, METH_O, 25087db96d56Sopenharmony_ci setstate_doc}, 25097db96d56Sopenharmony_ci {"__sizeof__", (PyCFunction)product_sizeof, METH_NOARGS, 25107db96d56Sopenharmony_ci sizeof_doc}, 25117db96d56Sopenharmony_ci {NULL, NULL} /* sentinel */ 25127db96d56Sopenharmony_ci}; 25137db96d56Sopenharmony_ci 25147db96d56Sopenharmony_ciPyDoc_STRVAR(product_doc, 25157db96d56Sopenharmony_ci"product(*iterables, repeat=1) --> product object\n\ 25167db96d56Sopenharmony_ci\n\ 25177db96d56Sopenharmony_ciCartesian product of input iterables. Equivalent to nested for-loops.\n\n\ 25187db96d56Sopenharmony_ciFor example, product(A, B) returns the same as: ((x,y) for x in A for y in B).\n\ 25197db96d56Sopenharmony_ciThe leftmost iterators are in the outermost for-loop, so the output tuples\n\ 25207db96d56Sopenharmony_cicycle in a manner similar to an odometer (with the rightmost element changing\n\ 25217db96d56Sopenharmony_cion every iteration).\n\n\ 25227db96d56Sopenharmony_ciTo compute the product of an iterable with itself, specify the number\n\ 25237db96d56Sopenharmony_ciof repetitions with the optional repeat keyword argument. For example,\n\ 25247db96d56Sopenharmony_ciproduct(A, repeat=4) means the same as product(A, A, A, A).\n\n\ 25257db96d56Sopenharmony_ciproduct('ab', range(3)) --> ('a',0) ('a',1) ('a',2) ('b',0) ('b',1) ('b',2)\n\ 25267db96d56Sopenharmony_ciproduct((0,1), (0,1), (0,1)) --> (0,0,0) (0,0,1) (0,1,0) (0,1,1) (1,0,0) ..."); 25277db96d56Sopenharmony_ci 25287db96d56Sopenharmony_cistatic PyTypeObject product_type = { 25297db96d56Sopenharmony_ci PyVarObject_HEAD_INIT(NULL, 0) 25307db96d56Sopenharmony_ci "itertools.product", /* tp_name */ 25317db96d56Sopenharmony_ci sizeof(productobject), /* tp_basicsize */ 25327db96d56Sopenharmony_ci 0, /* tp_itemsize */ 25337db96d56Sopenharmony_ci /* methods */ 25347db96d56Sopenharmony_ci (destructor)product_dealloc, /* tp_dealloc */ 25357db96d56Sopenharmony_ci 0, /* tp_vectorcall_offset */ 25367db96d56Sopenharmony_ci 0, /* tp_getattr */ 25377db96d56Sopenharmony_ci 0, /* tp_setattr */ 25387db96d56Sopenharmony_ci 0, /* tp_as_async */ 25397db96d56Sopenharmony_ci 0, /* tp_repr */ 25407db96d56Sopenharmony_ci 0, /* tp_as_number */ 25417db96d56Sopenharmony_ci 0, /* tp_as_sequence */ 25427db96d56Sopenharmony_ci 0, /* tp_as_mapping */ 25437db96d56Sopenharmony_ci 0, /* tp_hash */ 25447db96d56Sopenharmony_ci 0, /* tp_call */ 25457db96d56Sopenharmony_ci 0, /* tp_str */ 25467db96d56Sopenharmony_ci PyObject_GenericGetAttr, /* tp_getattro */ 25477db96d56Sopenharmony_ci 0, /* tp_setattro */ 25487db96d56Sopenharmony_ci 0, /* tp_as_buffer */ 25497db96d56Sopenharmony_ci Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | 25507db96d56Sopenharmony_ci Py_TPFLAGS_BASETYPE, /* tp_flags */ 25517db96d56Sopenharmony_ci product_doc, /* tp_doc */ 25527db96d56Sopenharmony_ci (traverseproc)product_traverse, /* tp_traverse */ 25537db96d56Sopenharmony_ci 0, /* tp_clear */ 25547db96d56Sopenharmony_ci 0, /* tp_richcompare */ 25557db96d56Sopenharmony_ci 0, /* tp_weaklistoffset */ 25567db96d56Sopenharmony_ci PyObject_SelfIter, /* tp_iter */ 25577db96d56Sopenharmony_ci (iternextfunc)product_next, /* tp_iternext */ 25587db96d56Sopenharmony_ci product_methods, /* tp_methods */ 25597db96d56Sopenharmony_ci 0, /* tp_members */ 25607db96d56Sopenharmony_ci 0, /* tp_getset */ 25617db96d56Sopenharmony_ci 0, /* tp_base */ 25627db96d56Sopenharmony_ci 0, /* tp_dict */ 25637db96d56Sopenharmony_ci 0, /* tp_descr_get */ 25647db96d56Sopenharmony_ci 0, /* tp_descr_set */ 25657db96d56Sopenharmony_ci 0, /* tp_dictoffset */ 25667db96d56Sopenharmony_ci 0, /* tp_init */ 25677db96d56Sopenharmony_ci 0, /* tp_alloc */ 25687db96d56Sopenharmony_ci product_new, /* tp_new */ 25697db96d56Sopenharmony_ci PyObject_GC_Del, /* tp_free */ 25707db96d56Sopenharmony_ci}; 25717db96d56Sopenharmony_ci 25727db96d56Sopenharmony_ci 25737db96d56Sopenharmony_ci/* combinations object *******************************************************/ 25747db96d56Sopenharmony_ci 25757db96d56Sopenharmony_citypedef struct { 25767db96d56Sopenharmony_ci PyObject_HEAD 25777db96d56Sopenharmony_ci PyObject *pool; /* input converted to a tuple */ 25787db96d56Sopenharmony_ci Py_ssize_t *indices; /* one index per result element */ 25797db96d56Sopenharmony_ci PyObject *result; /* most recently returned result tuple */ 25807db96d56Sopenharmony_ci Py_ssize_t r; /* size of result tuple */ 25817db96d56Sopenharmony_ci int stopped; /* set to 1 when the iterator is exhausted */ 25827db96d56Sopenharmony_ci} combinationsobject; 25837db96d56Sopenharmony_ci 25847db96d56Sopenharmony_ci 25857db96d56Sopenharmony_ci/*[clinic input] 25867db96d56Sopenharmony_ci@classmethod 25877db96d56Sopenharmony_ciitertools.combinations.__new__ 25887db96d56Sopenharmony_ci iterable: object 25897db96d56Sopenharmony_ci r: Py_ssize_t 25907db96d56Sopenharmony_ciReturn successive r-length combinations of elements in the iterable. 25917db96d56Sopenharmony_ci 25927db96d56Sopenharmony_cicombinations(range(4), 3) --> (0,1,2), (0,1,3), (0,2,3), (1,2,3) 25937db96d56Sopenharmony_ci[clinic start generated code]*/ 25947db96d56Sopenharmony_ci 25957db96d56Sopenharmony_cistatic PyObject * 25967db96d56Sopenharmony_ciitertools_combinations_impl(PyTypeObject *type, PyObject *iterable, 25977db96d56Sopenharmony_ci Py_ssize_t r) 25987db96d56Sopenharmony_ci/*[clinic end generated code: output=87a689b39c40039c input=06bede09e3da20f8]*/ 25997db96d56Sopenharmony_ci{ 26007db96d56Sopenharmony_ci combinationsobject *co; 26017db96d56Sopenharmony_ci Py_ssize_t n; 26027db96d56Sopenharmony_ci PyObject *pool = NULL; 26037db96d56Sopenharmony_ci Py_ssize_t *indices = NULL; 26047db96d56Sopenharmony_ci Py_ssize_t i; 26057db96d56Sopenharmony_ci 26067db96d56Sopenharmony_ci pool = PySequence_Tuple(iterable); 26077db96d56Sopenharmony_ci if (pool == NULL) 26087db96d56Sopenharmony_ci goto error; 26097db96d56Sopenharmony_ci n = PyTuple_GET_SIZE(pool); 26107db96d56Sopenharmony_ci if (r < 0) { 26117db96d56Sopenharmony_ci PyErr_SetString(PyExc_ValueError, "r must be non-negative"); 26127db96d56Sopenharmony_ci goto error; 26137db96d56Sopenharmony_ci } 26147db96d56Sopenharmony_ci 26157db96d56Sopenharmony_ci indices = PyMem_New(Py_ssize_t, r); 26167db96d56Sopenharmony_ci if (indices == NULL) { 26177db96d56Sopenharmony_ci PyErr_NoMemory(); 26187db96d56Sopenharmony_ci goto error; 26197db96d56Sopenharmony_ci } 26207db96d56Sopenharmony_ci 26217db96d56Sopenharmony_ci for (i=0 ; i<r ; i++) 26227db96d56Sopenharmony_ci indices[i] = i; 26237db96d56Sopenharmony_ci 26247db96d56Sopenharmony_ci /* create combinationsobject structure */ 26257db96d56Sopenharmony_ci co = (combinationsobject *)type->tp_alloc(type, 0); 26267db96d56Sopenharmony_ci if (co == NULL) 26277db96d56Sopenharmony_ci goto error; 26287db96d56Sopenharmony_ci 26297db96d56Sopenharmony_ci co->pool = pool; 26307db96d56Sopenharmony_ci co->indices = indices; 26317db96d56Sopenharmony_ci co->result = NULL; 26327db96d56Sopenharmony_ci co->r = r; 26337db96d56Sopenharmony_ci co->stopped = r > n ? 1 : 0; 26347db96d56Sopenharmony_ci 26357db96d56Sopenharmony_ci return (PyObject *)co; 26367db96d56Sopenharmony_ci 26377db96d56Sopenharmony_cierror: 26387db96d56Sopenharmony_ci if (indices != NULL) 26397db96d56Sopenharmony_ci PyMem_Free(indices); 26407db96d56Sopenharmony_ci Py_XDECREF(pool); 26417db96d56Sopenharmony_ci return NULL; 26427db96d56Sopenharmony_ci} 26437db96d56Sopenharmony_ci 26447db96d56Sopenharmony_cistatic void 26457db96d56Sopenharmony_cicombinations_dealloc(combinationsobject *co) 26467db96d56Sopenharmony_ci{ 26477db96d56Sopenharmony_ci PyObject_GC_UnTrack(co); 26487db96d56Sopenharmony_ci Py_XDECREF(co->pool); 26497db96d56Sopenharmony_ci Py_XDECREF(co->result); 26507db96d56Sopenharmony_ci if (co->indices != NULL) 26517db96d56Sopenharmony_ci PyMem_Free(co->indices); 26527db96d56Sopenharmony_ci Py_TYPE(co)->tp_free(co); 26537db96d56Sopenharmony_ci} 26547db96d56Sopenharmony_ci 26557db96d56Sopenharmony_cistatic PyObject * 26567db96d56Sopenharmony_cicombinations_sizeof(combinationsobject *co, void *unused) 26577db96d56Sopenharmony_ci{ 26587db96d56Sopenharmony_ci Py_ssize_t res; 26597db96d56Sopenharmony_ci 26607db96d56Sopenharmony_ci res = _PyObject_SIZE(Py_TYPE(co)); 26617db96d56Sopenharmony_ci res += co->r * sizeof(Py_ssize_t); 26627db96d56Sopenharmony_ci return PyLong_FromSsize_t(res); 26637db96d56Sopenharmony_ci} 26647db96d56Sopenharmony_ci 26657db96d56Sopenharmony_cistatic int 26667db96d56Sopenharmony_cicombinations_traverse(combinationsobject *co, visitproc visit, void *arg) 26677db96d56Sopenharmony_ci{ 26687db96d56Sopenharmony_ci Py_VISIT(co->pool); 26697db96d56Sopenharmony_ci Py_VISIT(co->result); 26707db96d56Sopenharmony_ci return 0; 26717db96d56Sopenharmony_ci} 26727db96d56Sopenharmony_ci 26737db96d56Sopenharmony_cistatic PyObject * 26747db96d56Sopenharmony_cicombinations_next(combinationsobject *co) 26757db96d56Sopenharmony_ci{ 26767db96d56Sopenharmony_ci PyObject *elem; 26777db96d56Sopenharmony_ci PyObject *oldelem; 26787db96d56Sopenharmony_ci PyObject *pool = co->pool; 26797db96d56Sopenharmony_ci Py_ssize_t *indices = co->indices; 26807db96d56Sopenharmony_ci PyObject *result = co->result; 26817db96d56Sopenharmony_ci Py_ssize_t n = PyTuple_GET_SIZE(pool); 26827db96d56Sopenharmony_ci Py_ssize_t r = co->r; 26837db96d56Sopenharmony_ci Py_ssize_t i, j, index; 26847db96d56Sopenharmony_ci 26857db96d56Sopenharmony_ci if (co->stopped) 26867db96d56Sopenharmony_ci return NULL; 26877db96d56Sopenharmony_ci 26887db96d56Sopenharmony_ci if (result == NULL) { 26897db96d56Sopenharmony_ci /* On the first pass, initialize result tuple using the indices */ 26907db96d56Sopenharmony_ci result = PyTuple_New(r); 26917db96d56Sopenharmony_ci if (result == NULL) 26927db96d56Sopenharmony_ci goto empty; 26937db96d56Sopenharmony_ci co->result = result; 26947db96d56Sopenharmony_ci for (i=0; i<r ; i++) { 26957db96d56Sopenharmony_ci index = indices[i]; 26967db96d56Sopenharmony_ci elem = PyTuple_GET_ITEM(pool, index); 26977db96d56Sopenharmony_ci Py_INCREF(elem); 26987db96d56Sopenharmony_ci PyTuple_SET_ITEM(result, i, elem); 26997db96d56Sopenharmony_ci } 27007db96d56Sopenharmony_ci } else { 27017db96d56Sopenharmony_ci /* Copy the previous result tuple or re-use it if available */ 27027db96d56Sopenharmony_ci if (Py_REFCNT(result) > 1) { 27037db96d56Sopenharmony_ci PyObject *old_result = result; 27047db96d56Sopenharmony_ci result = _PyTuple_FromArray(_PyTuple_ITEMS(old_result), r); 27057db96d56Sopenharmony_ci if (result == NULL) 27067db96d56Sopenharmony_ci goto empty; 27077db96d56Sopenharmony_ci co->result = result; 27087db96d56Sopenharmony_ci Py_DECREF(old_result); 27097db96d56Sopenharmony_ci } 27107db96d56Sopenharmony_ci // bpo-42536: The GC may have untracked this result tuple. Since we're 27117db96d56Sopenharmony_ci // recycling it, make sure it's tracked again: 27127db96d56Sopenharmony_ci else if (!_PyObject_GC_IS_TRACKED(result)) { 27137db96d56Sopenharmony_ci _PyObject_GC_TRACK(result); 27147db96d56Sopenharmony_ci } 27157db96d56Sopenharmony_ci /* Now, we've got the only copy so we can update it in-place 27167db96d56Sopenharmony_ci * CPython's empty tuple is a singleton and cached in 27177db96d56Sopenharmony_ci * PyTuple's freelist. 27187db96d56Sopenharmony_ci */ 27197db96d56Sopenharmony_ci assert(r == 0 || Py_REFCNT(result) == 1); 27207db96d56Sopenharmony_ci 27217db96d56Sopenharmony_ci /* Scan indices right-to-left until finding one that is not 27227db96d56Sopenharmony_ci at its maximum (i + n - r). */ 27237db96d56Sopenharmony_ci for (i=r-1 ; i >= 0 && indices[i] == i+n-r ; i--) 27247db96d56Sopenharmony_ci ; 27257db96d56Sopenharmony_ci 27267db96d56Sopenharmony_ci /* If i is negative, then the indices are all at 27277db96d56Sopenharmony_ci their maximum value and we're done. */ 27287db96d56Sopenharmony_ci if (i < 0) 27297db96d56Sopenharmony_ci goto empty; 27307db96d56Sopenharmony_ci 27317db96d56Sopenharmony_ci /* Increment the current index which we know is not at its 27327db96d56Sopenharmony_ci maximum. Then move back to the right setting each index 27337db96d56Sopenharmony_ci to its lowest possible value (one higher than the index 27347db96d56Sopenharmony_ci to its left -- this maintains the sort order invariant). */ 27357db96d56Sopenharmony_ci indices[i]++; 27367db96d56Sopenharmony_ci for (j=i+1 ; j<r ; j++) 27377db96d56Sopenharmony_ci indices[j] = indices[j-1] + 1; 27387db96d56Sopenharmony_ci 27397db96d56Sopenharmony_ci /* Update the result tuple for the new indices 27407db96d56Sopenharmony_ci starting with i, the leftmost index that changed */ 27417db96d56Sopenharmony_ci for ( ; i<r ; i++) { 27427db96d56Sopenharmony_ci index = indices[i]; 27437db96d56Sopenharmony_ci elem = PyTuple_GET_ITEM(pool, index); 27447db96d56Sopenharmony_ci Py_INCREF(elem); 27457db96d56Sopenharmony_ci oldelem = PyTuple_GET_ITEM(result, i); 27467db96d56Sopenharmony_ci PyTuple_SET_ITEM(result, i, elem); 27477db96d56Sopenharmony_ci Py_DECREF(oldelem); 27487db96d56Sopenharmony_ci } 27497db96d56Sopenharmony_ci } 27507db96d56Sopenharmony_ci 27517db96d56Sopenharmony_ci Py_INCREF(result); 27527db96d56Sopenharmony_ci return result; 27537db96d56Sopenharmony_ci 27547db96d56Sopenharmony_ciempty: 27557db96d56Sopenharmony_ci co->stopped = 1; 27567db96d56Sopenharmony_ci return NULL; 27577db96d56Sopenharmony_ci} 27587db96d56Sopenharmony_ci 27597db96d56Sopenharmony_cistatic PyObject * 27607db96d56Sopenharmony_cicombinations_reduce(combinationsobject *lz, PyObject *Py_UNUSED(ignored)) 27617db96d56Sopenharmony_ci{ 27627db96d56Sopenharmony_ci if (lz->result == NULL) { 27637db96d56Sopenharmony_ci return Py_BuildValue("O(On)", Py_TYPE(lz), lz->pool, lz->r); 27647db96d56Sopenharmony_ci } else if (lz->stopped) { 27657db96d56Sopenharmony_ci return Py_BuildValue("O(()n)", Py_TYPE(lz), lz->r); 27667db96d56Sopenharmony_ci } else { 27677db96d56Sopenharmony_ci PyObject *indices; 27687db96d56Sopenharmony_ci Py_ssize_t i; 27697db96d56Sopenharmony_ci 27707db96d56Sopenharmony_ci /* we must pickle the indices and use them for setstate */ 27717db96d56Sopenharmony_ci indices = PyTuple_New(lz->r); 27727db96d56Sopenharmony_ci if (!indices) 27737db96d56Sopenharmony_ci return NULL; 27747db96d56Sopenharmony_ci for (i=0; i<lz->r; i++) 27757db96d56Sopenharmony_ci { 27767db96d56Sopenharmony_ci PyObject* index = PyLong_FromSsize_t(lz->indices[i]); 27777db96d56Sopenharmony_ci if (!index) { 27787db96d56Sopenharmony_ci Py_DECREF(indices); 27797db96d56Sopenharmony_ci return NULL; 27807db96d56Sopenharmony_ci } 27817db96d56Sopenharmony_ci PyTuple_SET_ITEM(indices, i, index); 27827db96d56Sopenharmony_ci } 27837db96d56Sopenharmony_ci 27847db96d56Sopenharmony_ci return Py_BuildValue("O(On)N", Py_TYPE(lz), lz->pool, lz->r, indices); 27857db96d56Sopenharmony_ci } 27867db96d56Sopenharmony_ci} 27877db96d56Sopenharmony_ci 27887db96d56Sopenharmony_cistatic PyObject * 27897db96d56Sopenharmony_cicombinations_setstate(combinationsobject *lz, PyObject *state) 27907db96d56Sopenharmony_ci{ 27917db96d56Sopenharmony_ci PyObject *result; 27927db96d56Sopenharmony_ci Py_ssize_t i; 27937db96d56Sopenharmony_ci Py_ssize_t n = PyTuple_GET_SIZE(lz->pool); 27947db96d56Sopenharmony_ci 27957db96d56Sopenharmony_ci if (!PyTuple_Check(state) || PyTuple_GET_SIZE(state) != lz->r) { 27967db96d56Sopenharmony_ci PyErr_SetString(PyExc_ValueError, "invalid arguments"); 27977db96d56Sopenharmony_ci return NULL; 27987db96d56Sopenharmony_ci } 27997db96d56Sopenharmony_ci 28007db96d56Sopenharmony_ci for (i=0; i<lz->r; i++) { 28017db96d56Sopenharmony_ci Py_ssize_t max; 28027db96d56Sopenharmony_ci PyObject* indexObject = PyTuple_GET_ITEM(state, i); 28037db96d56Sopenharmony_ci Py_ssize_t index = PyLong_AsSsize_t(indexObject); 28047db96d56Sopenharmony_ci 28057db96d56Sopenharmony_ci if (index == -1 && PyErr_Occurred()) 28067db96d56Sopenharmony_ci return NULL; /* not an integer */ 28077db96d56Sopenharmony_ci max = i + n - lz->r; 28087db96d56Sopenharmony_ci /* clamp the index (beware of negative max) */ 28097db96d56Sopenharmony_ci if (index > max) 28107db96d56Sopenharmony_ci index = max; 28117db96d56Sopenharmony_ci if (index < 0) 28127db96d56Sopenharmony_ci index = 0; 28137db96d56Sopenharmony_ci lz->indices[i] = index; 28147db96d56Sopenharmony_ci } 28157db96d56Sopenharmony_ci 28167db96d56Sopenharmony_ci result = PyTuple_New(lz->r); 28177db96d56Sopenharmony_ci if (result == NULL) 28187db96d56Sopenharmony_ci return NULL; 28197db96d56Sopenharmony_ci for (i=0; i<lz->r; i++) { 28207db96d56Sopenharmony_ci PyObject *element = PyTuple_GET_ITEM(lz->pool, lz->indices[i]); 28217db96d56Sopenharmony_ci Py_INCREF(element); 28227db96d56Sopenharmony_ci PyTuple_SET_ITEM(result, i, element); 28237db96d56Sopenharmony_ci } 28247db96d56Sopenharmony_ci 28257db96d56Sopenharmony_ci Py_XSETREF(lz->result, result); 28267db96d56Sopenharmony_ci Py_RETURN_NONE; 28277db96d56Sopenharmony_ci} 28287db96d56Sopenharmony_ci 28297db96d56Sopenharmony_cistatic PyMethodDef combinations_methods[] = { 28307db96d56Sopenharmony_ci {"__reduce__", (PyCFunction)combinations_reduce, METH_NOARGS, 28317db96d56Sopenharmony_ci reduce_doc}, 28327db96d56Sopenharmony_ci {"__setstate__", (PyCFunction)combinations_setstate, METH_O, 28337db96d56Sopenharmony_ci setstate_doc}, 28347db96d56Sopenharmony_ci {"__sizeof__", (PyCFunction)combinations_sizeof, METH_NOARGS, 28357db96d56Sopenharmony_ci sizeof_doc}, 28367db96d56Sopenharmony_ci {NULL, NULL} /* sentinel */ 28377db96d56Sopenharmony_ci}; 28387db96d56Sopenharmony_ci 28397db96d56Sopenharmony_cistatic PyTypeObject combinations_type = { 28407db96d56Sopenharmony_ci PyVarObject_HEAD_INIT(NULL, 0) 28417db96d56Sopenharmony_ci "itertools.combinations", /* tp_name */ 28427db96d56Sopenharmony_ci sizeof(combinationsobject), /* tp_basicsize */ 28437db96d56Sopenharmony_ci 0, /* tp_itemsize */ 28447db96d56Sopenharmony_ci /* methods */ 28457db96d56Sopenharmony_ci (destructor)combinations_dealloc, /* tp_dealloc */ 28467db96d56Sopenharmony_ci 0, /* tp_vectorcall_offset */ 28477db96d56Sopenharmony_ci 0, /* tp_getattr */ 28487db96d56Sopenharmony_ci 0, /* tp_setattr */ 28497db96d56Sopenharmony_ci 0, /* tp_as_async */ 28507db96d56Sopenharmony_ci 0, /* tp_repr */ 28517db96d56Sopenharmony_ci 0, /* tp_as_number */ 28527db96d56Sopenharmony_ci 0, /* tp_as_sequence */ 28537db96d56Sopenharmony_ci 0, /* tp_as_mapping */ 28547db96d56Sopenharmony_ci 0, /* tp_hash */ 28557db96d56Sopenharmony_ci 0, /* tp_call */ 28567db96d56Sopenharmony_ci 0, /* tp_str */ 28577db96d56Sopenharmony_ci PyObject_GenericGetAttr, /* tp_getattro */ 28587db96d56Sopenharmony_ci 0, /* tp_setattro */ 28597db96d56Sopenharmony_ci 0, /* tp_as_buffer */ 28607db96d56Sopenharmony_ci Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | 28617db96d56Sopenharmony_ci Py_TPFLAGS_BASETYPE, /* tp_flags */ 28627db96d56Sopenharmony_ci itertools_combinations__doc__, /* tp_doc */ 28637db96d56Sopenharmony_ci (traverseproc)combinations_traverse,/* tp_traverse */ 28647db96d56Sopenharmony_ci 0, /* tp_clear */ 28657db96d56Sopenharmony_ci 0, /* tp_richcompare */ 28667db96d56Sopenharmony_ci 0, /* tp_weaklistoffset */ 28677db96d56Sopenharmony_ci PyObject_SelfIter, /* tp_iter */ 28687db96d56Sopenharmony_ci (iternextfunc)combinations_next, /* tp_iternext */ 28697db96d56Sopenharmony_ci combinations_methods, /* tp_methods */ 28707db96d56Sopenharmony_ci 0, /* tp_members */ 28717db96d56Sopenharmony_ci 0, /* tp_getset */ 28727db96d56Sopenharmony_ci 0, /* tp_base */ 28737db96d56Sopenharmony_ci 0, /* tp_dict */ 28747db96d56Sopenharmony_ci 0, /* tp_descr_get */ 28757db96d56Sopenharmony_ci 0, /* tp_descr_set */ 28767db96d56Sopenharmony_ci 0, /* tp_dictoffset */ 28777db96d56Sopenharmony_ci 0, /* tp_init */ 28787db96d56Sopenharmony_ci 0, /* tp_alloc */ 28797db96d56Sopenharmony_ci itertools_combinations, /* tp_new */ 28807db96d56Sopenharmony_ci PyObject_GC_Del, /* tp_free */ 28817db96d56Sopenharmony_ci}; 28827db96d56Sopenharmony_ci 28837db96d56Sopenharmony_ci 28847db96d56Sopenharmony_ci/* combinations with replacement object **************************************/ 28857db96d56Sopenharmony_ci 28867db96d56Sopenharmony_ci/* Equivalent to: 28877db96d56Sopenharmony_ci 28887db96d56Sopenharmony_ci def combinations_with_replacement(iterable, r): 28897db96d56Sopenharmony_ci "combinations_with_replacement('ABC', 2) --> AA AB AC BB BC CC" 28907db96d56Sopenharmony_ci # number items returned: (n+r-1)! / r! / (n-1)! 28917db96d56Sopenharmony_ci pool = tuple(iterable) 28927db96d56Sopenharmony_ci n = len(pool) 28937db96d56Sopenharmony_ci indices = [0] * r 28947db96d56Sopenharmony_ci yield tuple(pool[i] for i in indices) 28957db96d56Sopenharmony_ci while 1: 28967db96d56Sopenharmony_ci for i in reversed(range(r)): 28977db96d56Sopenharmony_ci if indices[i] != n - 1: 28987db96d56Sopenharmony_ci break 28997db96d56Sopenharmony_ci else: 29007db96d56Sopenharmony_ci return 29017db96d56Sopenharmony_ci indices[i:] = [indices[i] + 1] * (r - i) 29027db96d56Sopenharmony_ci yield tuple(pool[i] for i in indices) 29037db96d56Sopenharmony_ci 29047db96d56Sopenharmony_ci def combinations_with_replacement2(iterable, r): 29057db96d56Sopenharmony_ci 'Alternate version that filters from product()' 29067db96d56Sopenharmony_ci pool = tuple(iterable) 29077db96d56Sopenharmony_ci n = len(pool) 29087db96d56Sopenharmony_ci for indices in product(range(n), repeat=r): 29097db96d56Sopenharmony_ci if sorted(indices) == list(indices): 29107db96d56Sopenharmony_ci yield tuple(pool[i] for i in indices) 29117db96d56Sopenharmony_ci*/ 29127db96d56Sopenharmony_citypedef struct { 29137db96d56Sopenharmony_ci PyObject_HEAD 29147db96d56Sopenharmony_ci PyObject *pool; /* input converted to a tuple */ 29157db96d56Sopenharmony_ci Py_ssize_t *indices; /* one index per result element */ 29167db96d56Sopenharmony_ci PyObject *result; /* most recently returned result tuple */ 29177db96d56Sopenharmony_ci Py_ssize_t r; /* size of result tuple */ 29187db96d56Sopenharmony_ci int stopped; /* set to 1 when the cwr iterator is exhausted */ 29197db96d56Sopenharmony_ci} cwrobject; 29207db96d56Sopenharmony_ci 29217db96d56Sopenharmony_ci/*[clinic input] 29227db96d56Sopenharmony_ci@classmethod 29237db96d56Sopenharmony_ciitertools.combinations_with_replacement.__new__ 29247db96d56Sopenharmony_ci iterable: object 29257db96d56Sopenharmony_ci r: Py_ssize_t 29267db96d56Sopenharmony_ciReturn successive r-length combinations of elements in the iterable allowing individual elements to have successive repeats. 29277db96d56Sopenharmony_ci 29287db96d56Sopenharmony_cicombinations_with_replacement('ABC', 2) --> ('A','A'), ('A','B'), ('A','C'), ('B','B'), ('B','C'), ('C','C') 29297db96d56Sopenharmony_ci[clinic start generated code]*/ 29307db96d56Sopenharmony_ci 29317db96d56Sopenharmony_cistatic PyObject * 29327db96d56Sopenharmony_ciitertools_combinations_with_replacement_impl(PyTypeObject *type, 29337db96d56Sopenharmony_ci PyObject *iterable, 29347db96d56Sopenharmony_ci Py_ssize_t r) 29357db96d56Sopenharmony_ci/*[clinic end generated code: output=48b26856d4e659ca input=1dc58e82a0878fdc]*/ 29367db96d56Sopenharmony_ci{ 29377db96d56Sopenharmony_ci cwrobject *co; 29387db96d56Sopenharmony_ci Py_ssize_t n; 29397db96d56Sopenharmony_ci PyObject *pool = NULL; 29407db96d56Sopenharmony_ci Py_ssize_t *indices = NULL; 29417db96d56Sopenharmony_ci Py_ssize_t i; 29427db96d56Sopenharmony_ci 29437db96d56Sopenharmony_ci pool = PySequence_Tuple(iterable); 29447db96d56Sopenharmony_ci if (pool == NULL) 29457db96d56Sopenharmony_ci goto error; 29467db96d56Sopenharmony_ci n = PyTuple_GET_SIZE(pool); 29477db96d56Sopenharmony_ci if (r < 0) { 29487db96d56Sopenharmony_ci PyErr_SetString(PyExc_ValueError, "r must be non-negative"); 29497db96d56Sopenharmony_ci goto error; 29507db96d56Sopenharmony_ci } 29517db96d56Sopenharmony_ci 29527db96d56Sopenharmony_ci indices = PyMem_New(Py_ssize_t, r); 29537db96d56Sopenharmony_ci if (indices == NULL) { 29547db96d56Sopenharmony_ci PyErr_NoMemory(); 29557db96d56Sopenharmony_ci goto error; 29567db96d56Sopenharmony_ci } 29577db96d56Sopenharmony_ci 29587db96d56Sopenharmony_ci for (i=0 ; i<r ; i++) 29597db96d56Sopenharmony_ci indices[i] = 0; 29607db96d56Sopenharmony_ci 29617db96d56Sopenharmony_ci /* create cwrobject structure */ 29627db96d56Sopenharmony_ci co = (cwrobject *)type->tp_alloc(type, 0); 29637db96d56Sopenharmony_ci if (co == NULL) 29647db96d56Sopenharmony_ci goto error; 29657db96d56Sopenharmony_ci 29667db96d56Sopenharmony_ci co->pool = pool; 29677db96d56Sopenharmony_ci co->indices = indices; 29687db96d56Sopenharmony_ci co->result = NULL; 29697db96d56Sopenharmony_ci co->r = r; 29707db96d56Sopenharmony_ci co->stopped = !n && r; 29717db96d56Sopenharmony_ci 29727db96d56Sopenharmony_ci return (PyObject *)co; 29737db96d56Sopenharmony_ci 29747db96d56Sopenharmony_cierror: 29757db96d56Sopenharmony_ci if (indices != NULL) 29767db96d56Sopenharmony_ci PyMem_Free(indices); 29777db96d56Sopenharmony_ci Py_XDECREF(pool); 29787db96d56Sopenharmony_ci return NULL; 29797db96d56Sopenharmony_ci} 29807db96d56Sopenharmony_ci 29817db96d56Sopenharmony_cistatic void 29827db96d56Sopenharmony_cicwr_dealloc(cwrobject *co) 29837db96d56Sopenharmony_ci{ 29847db96d56Sopenharmony_ci PyObject_GC_UnTrack(co); 29857db96d56Sopenharmony_ci Py_XDECREF(co->pool); 29867db96d56Sopenharmony_ci Py_XDECREF(co->result); 29877db96d56Sopenharmony_ci if (co->indices != NULL) 29887db96d56Sopenharmony_ci PyMem_Free(co->indices); 29897db96d56Sopenharmony_ci Py_TYPE(co)->tp_free(co); 29907db96d56Sopenharmony_ci} 29917db96d56Sopenharmony_ci 29927db96d56Sopenharmony_cistatic PyObject * 29937db96d56Sopenharmony_cicwr_sizeof(cwrobject *co, void *unused) 29947db96d56Sopenharmony_ci{ 29957db96d56Sopenharmony_ci Py_ssize_t res; 29967db96d56Sopenharmony_ci 29977db96d56Sopenharmony_ci res = _PyObject_SIZE(Py_TYPE(co)); 29987db96d56Sopenharmony_ci res += co->r * sizeof(Py_ssize_t); 29997db96d56Sopenharmony_ci return PyLong_FromSsize_t(res); 30007db96d56Sopenharmony_ci} 30017db96d56Sopenharmony_ci 30027db96d56Sopenharmony_cistatic int 30037db96d56Sopenharmony_cicwr_traverse(cwrobject *co, visitproc visit, void *arg) 30047db96d56Sopenharmony_ci{ 30057db96d56Sopenharmony_ci Py_VISIT(co->pool); 30067db96d56Sopenharmony_ci Py_VISIT(co->result); 30077db96d56Sopenharmony_ci return 0; 30087db96d56Sopenharmony_ci} 30097db96d56Sopenharmony_ci 30107db96d56Sopenharmony_cistatic PyObject * 30117db96d56Sopenharmony_cicwr_next(cwrobject *co) 30127db96d56Sopenharmony_ci{ 30137db96d56Sopenharmony_ci PyObject *elem; 30147db96d56Sopenharmony_ci PyObject *oldelem; 30157db96d56Sopenharmony_ci PyObject *pool = co->pool; 30167db96d56Sopenharmony_ci Py_ssize_t *indices = co->indices; 30177db96d56Sopenharmony_ci PyObject *result = co->result; 30187db96d56Sopenharmony_ci Py_ssize_t n = PyTuple_GET_SIZE(pool); 30197db96d56Sopenharmony_ci Py_ssize_t r = co->r; 30207db96d56Sopenharmony_ci Py_ssize_t i, index; 30217db96d56Sopenharmony_ci 30227db96d56Sopenharmony_ci if (co->stopped) 30237db96d56Sopenharmony_ci return NULL; 30247db96d56Sopenharmony_ci 30257db96d56Sopenharmony_ci if (result == NULL) { 30267db96d56Sopenharmony_ci /* On the first pass, initialize result tuple with pool[0] */ 30277db96d56Sopenharmony_ci result = PyTuple_New(r); 30287db96d56Sopenharmony_ci if (result == NULL) 30297db96d56Sopenharmony_ci goto empty; 30307db96d56Sopenharmony_ci co->result = result; 30317db96d56Sopenharmony_ci if (n > 0) { 30327db96d56Sopenharmony_ci elem = PyTuple_GET_ITEM(pool, 0); 30337db96d56Sopenharmony_ci for (i=0; i<r ; i++) { 30347db96d56Sopenharmony_ci assert(indices[i] == 0); 30357db96d56Sopenharmony_ci Py_INCREF(elem); 30367db96d56Sopenharmony_ci PyTuple_SET_ITEM(result, i, elem); 30377db96d56Sopenharmony_ci } 30387db96d56Sopenharmony_ci } 30397db96d56Sopenharmony_ci } else { 30407db96d56Sopenharmony_ci /* Copy the previous result tuple or re-use it if available */ 30417db96d56Sopenharmony_ci if (Py_REFCNT(result) > 1) { 30427db96d56Sopenharmony_ci PyObject *old_result = result; 30437db96d56Sopenharmony_ci result = _PyTuple_FromArray(_PyTuple_ITEMS(old_result), r); 30447db96d56Sopenharmony_ci if (result == NULL) 30457db96d56Sopenharmony_ci goto empty; 30467db96d56Sopenharmony_ci co->result = result; 30477db96d56Sopenharmony_ci Py_DECREF(old_result); 30487db96d56Sopenharmony_ci } 30497db96d56Sopenharmony_ci // bpo-42536: The GC may have untracked this result tuple. Since we're 30507db96d56Sopenharmony_ci // recycling it, make sure it's tracked again: 30517db96d56Sopenharmony_ci else if (!_PyObject_GC_IS_TRACKED(result)) { 30527db96d56Sopenharmony_ci _PyObject_GC_TRACK(result); 30537db96d56Sopenharmony_ci } 30547db96d56Sopenharmony_ci /* Now, we've got the only copy so we can update it in-place CPython's 30557db96d56Sopenharmony_ci empty tuple is a singleton and cached in PyTuple's freelist. */ 30567db96d56Sopenharmony_ci assert(r == 0 || Py_REFCNT(result) == 1); 30577db96d56Sopenharmony_ci 30587db96d56Sopenharmony_ci /* Scan indices right-to-left until finding one that is not 30597db96d56Sopenharmony_ci * at its maximum (n-1). */ 30607db96d56Sopenharmony_ci for (i=r-1 ; i >= 0 && indices[i] == n-1; i--) 30617db96d56Sopenharmony_ci ; 30627db96d56Sopenharmony_ci 30637db96d56Sopenharmony_ci /* If i is negative, then the indices are all at 30647db96d56Sopenharmony_ci their maximum value and we're done. */ 30657db96d56Sopenharmony_ci if (i < 0) 30667db96d56Sopenharmony_ci goto empty; 30677db96d56Sopenharmony_ci 30687db96d56Sopenharmony_ci /* Increment the current index which we know is not at its 30697db96d56Sopenharmony_ci maximum. Then set all to the right to the same value. */ 30707db96d56Sopenharmony_ci index = indices[i] + 1; 30717db96d56Sopenharmony_ci assert(index < n); 30727db96d56Sopenharmony_ci elem = PyTuple_GET_ITEM(pool, index); 30737db96d56Sopenharmony_ci for ( ; i<r ; i++) { 30747db96d56Sopenharmony_ci indices[i] = index; 30757db96d56Sopenharmony_ci Py_INCREF(elem); 30767db96d56Sopenharmony_ci oldelem = PyTuple_GET_ITEM(result, i); 30777db96d56Sopenharmony_ci PyTuple_SET_ITEM(result, i, elem); 30787db96d56Sopenharmony_ci Py_DECREF(oldelem); 30797db96d56Sopenharmony_ci } 30807db96d56Sopenharmony_ci } 30817db96d56Sopenharmony_ci 30827db96d56Sopenharmony_ci Py_INCREF(result); 30837db96d56Sopenharmony_ci return result; 30847db96d56Sopenharmony_ci 30857db96d56Sopenharmony_ciempty: 30867db96d56Sopenharmony_ci co->stopped = 1; 30877db96d56Sopenharmony_ci return NULL; 30887db96d56Sopenharmony_ci} 30897db96d56Sopenharmony_ci 30907db96d56Sopenharmony_cistatic PyObject * 30917db96d56Sopenharmony_cicwr_reduce(cwrobject *lz, PyObject *Py_UNUSED(ignored)) 30927db96d56Sopenharmony_ci{ 30937db96d56Sopenharmony_ci if (lz->result == NULL) { 30947db96d56Sopenharmony_ci return Py_BuildValue("O(On)", Py_TYPE(lz), lz->pool, lz->r); 30957db96d56Sopenharmony_ci } else if (lz->stopped) { 30967db96d56Sopenharmony_ci return Py_BuildValue("O(()n)", Py_TYPE(lz), lz->r); 30977db96d56Sopenharmony_ci } else { 30987db96d56Sopenharmony_ci PyObject *indices; 30997db96d56Sopenharmony_ci Py_ssize_t i; 31007db96d56Sopenharmony_ci 31017db96d56Sopenharmony_ci /* we must pickle the indices and use them for setstate */ 31027db96d56Sopenharmony_ci indices = PyTuple_New(lz->r); 31037db96d56Sopenharmony_ci if (!indices) 31047db96d56Sopenharmony_ci return NULL; 31057db96d56Sopenharmony_ci for (i=0; i<lz->r; i++) { 31067db96d56Sopenharmony_ci PyObject* index = PyLong_FromSsize_t(lz->indices[i]); 31077db96d56Sopenharmony_ci if (!index) { 31087db96d56Sopenharmony_ci Py_DECREF(indices); 31097db96d56Sopenharmony_ci return NULL; 31107db96d56Sopenharmony_ci } 31117db96d56Sopenharmony_ci PyTuple_SET_ITEM(indices, i, index); 31127db96d56Sopenharmony_ci } 31137db96d56Sopenharmony_ci 31147db96d56Sopenharmony_ci return Py_BuildValue("O(On)N", Py_TYPE(lz), lz->pool, lz->r, indices); 31157db96d56Sopenharmony_ci } 31167db96d56Sopenharmony_ci} 31177db96d56Sopenharmony_ci 31187db96d56Sopenharmony_cistatic PyObject * 31197db96d56Sopenharmony_cicwr_setstate(cwrobject *lz, PyObject *state) 31207db96d56Sopenharmony_ci{ 31217db96d56Sopenharmony_ci PyObject *result; 31227db96d56Sopenharmony_ci Py_ssize_t n, i; 31237db96d56Sopenharmony_ci 31247db96d56Sopenharmony_ci if (!PyTuple_Check(state) || PyTuple_GET_SIZE(state) != lz->r) 31257db96d56Sopenharmony_ci { 31267db96d56Sopenharmony_ci PyErr_SetString(PyExc_ValueError, "invalid arguments"); 31277db96d56Sopenharmony_ci return NULL; 31287db96d56Sopenharmony_ci } 31297db96d56Sopenharmony_ci 31307db96d56Sopenharmony_ci n = PyTuple_GET_SIZE(lz->pool); 31317db96d56Sopenharmony_ci for (i=0; i<lz->r; i++) { 31327db96d56Sopenharmony_ci PyObject* indexObject = PyTuple_GET_ITEM(state, i); 31337db96d56Sopenharmony_ci Py_ssize_t index = PyLong_AsSsize_t(indexObject); 31347db96d56Sopenharmony_ci 31357db96d56Sopenharmony_ci if (index < 0 && PyErr_Occurred()) 31367db96d56Sopenharmony_ci return NULL; /* not an integer */ 31377db96d56Sopenharmony_ci /* clamp the index */ 31387db96d56Sopenharmony_ci if (index < 0) 31397db96d56Sopenharmony_ci index = 0; 31407db96d56Sopenharmony_ci else if (index > n-1) 31417db96d56Sopenharmony_ci index = n-1; 31427db96d56Sopenharmony_ci lz->indices[i] = index; 31437db96d56Sopenharmony_ci } 31447db96d56Sopenharmony_ci result = PyTuple_New(lz->r); 31457db96d56Sopenharmony_ci if (result == NULL) 31467db96d56Sopenharmony_ci return NULL; 31477db96d56Sopenharmony_ci for (i=0; i<lz->r; i++) { 31487db96d56Sopenharmony_ci PyObject *element = PyTuple_GET_ITEM(lz->pool, lz->indices[i]); 31497db96d56Sopenharmony_ci Py_INCREF(element); 31507db96d56Sopenharmony_ci PyTuple_SET_ITEM(result, i, element); 31517db96d56Sopenharmony_ci } 31527db96d56Sopenharmony_ci Py_XSETREF(lz->result, result); 31537db96d56Sopenharmony_ci Py_RETURN_NONE; 31547db96d56Sopenharmony_ci} 31557db96d56Sopenharmony_ci 31567db96d56Sopenharmony_cistatic PyMethodDef cwr_methods[] = { 31577db96d56Sopenharmony_ci {"__reduce__", (PyCFunction)cwr_reduce, METH_NOARGS, 31587db96d56Sopenharmony_ci reduce_doc}, 31597db96d56Sopenharmony_ci {"__setstate__", (PyCFunction)cwr_setstate, METH_O, 31607db96d56Sopenharmony_ci setstate_doc}, 31617db96d56Sopenharmony_ci {"__sizeof__", (PyCFunction)cwr_sizeof, METH_NOARGS, 31627db96d56Sopenharmony_ci sizeof_doc}, 31637db96d56Sopenharmony_ci {NULL, NULL} /* sentinel */ 31647db96d56Sopenharmony_ci}; 31657db96d56Sopenharmony_ci 31667db96d56Sopenharmony_cistatic PyTypeObject cwr_type = { 31677db96d56Sopenharmony_ci PyVarObject_HEAD_INIT(NULL, 0) 31687db96d56Sopenharmony_ci "itertools.combinations_with_replacement", /* tp_name */ 31697db96d56Sopenharmony_ci sizeof(cwrobject), /* tp_basicsize */ 31707db96d56Sopenharmony_ci 0, /* tp_itemsize */ 31717db96d56Sopenharmony_ci /* methods */ 31727db96d56Sopenharmony_ci (destructor)cwr_dealloc, /* tp_dealloc */ 31737db96d56Sopenharmony_ci 0, /* tp_vectorcall_offset */ 31747db96d56Sopenharmony_ci 0, /* tp_getattr */ 31757db96d56Sopenharmony_ci 0, /* tp_setattr */ 31767db96d56Sopenharmony_ci 0, /* tp_as_async */ 31777db96d56Sopenharmony_ci 0, /* tp_repr */ 31787db96d56Sopenharmony_ci 0, /* tp_as_number */ 31797db96d56Sopenharmony_ci 0, /* tp_as_sequence */ 31807db96d56Sopenharmony_ci 0, /* tp_as_mapping */ 31817db96d56Sopenharmony_ci 0, /* tp_hash */ 31827db96d56Sopenharmony_ci 0, /* tp_call */ 31837db96d56Sopenharmony_ci 0, /* tp_str */ 31847db96d56Sopenharmony_ci PyObject_GenericGetAttr, /* tp_getattro */ 31857db96d56Sopenharmony_ci 0, /* tp_setattro */ 31867db96d56Sopenharmony_ci 0, /* tp_as_buffer */ 31877db96d56Sopenharmony_ci Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | 31887db96d56Sopenharmony_ci Py_TPFLAGS_BASETYPE, /* tp_flags */ 31897db96d56Sopenharmony_ci itertools_combinations_with_replacement__doc__, /* tp_doc */ 31907db96d56Sopenharmony_ci (traverseproc)cwr_traverse, /* tp_traverse */ 31917db96d56Sopenharmony_ci 0, /* tp_clear */ 31927db96d56Sopenharmony_ci 0, /* tp_richcompare */ 31937db96d56Sopenharmony_ci 0, /* tp_weaklistoffset */ 31947db96d56Sopenharmony_ci PyObject_SelfIter, /* tp_iter */ 31957db96d56Sopenharmony_ci (iternextfunc)cwr_next, /* tp_iternext */ 31967db96d56Sopenharmony_ci cwr_methods, /* tp_methods */ 31977db96d56Sopenharmony_ci 0, /* tp_members */ 31987db96d56Sopenharmony_ci 0, /* tp_getset */ 31997db96d56Sopenharmony_ci 0, /* tp_base */ 32007db96d56Sopenharmony_ci 0, /* tp_dict */ 32017db96d56Sopenharmony_ci 0, /* tp_descr_get */ 32027db96d56Sopenharmony_ci 0, /* tp_descr_set */ 32037db96d56Sopenharmony_ci 0, /* tp_dictoffset */ 32047db96d56Sopenharmony_ci 0, /* tp_init */ 32057db96d56Sopenharmony_ci 0, /* tp_alloc */ 32067db96d56Sopenharmony_ci itertools_combinations_with_replacement, /* tp_new */ 32077db96d56Sopenharmony_ci PyObject_GC_Del, /* tp_free */ 32087db96d56Sopenharmony_ci}; 32097db96d56Sopenharmony_ci 32107db96d56Sopenharmony_ci 32117db96d56Sopenharmony_ci/* permutations object ******************************************************** 32127db96d56Sopenharmony_ci 32137db96d56Sopenharmony_cidef permutations(iterable, r=None): 32147db96d56Sopenharmony_ci # permutations('ABCD', 2) --> AB AC AD BA BC BD CA CB CD DA DB DC 32157db96d56Sopenharmony_ci # permutations(range(3)) --> 012 021 102 120 201 210 32167db96d56Sopenharmony_ci pool = tuple(iterable) 32177db96d56Sopenharmony_ci n = len(pool) 32187db96d56Sopenharmony_ci r = n if r is None else r 32197db96d56Sopenharmony_ci if r > n: 32207db96d56Sopenharmony_ci return 32217db96d56Sopenharmony_ci indices = list(range(n)) 32227db96d56Sopenharmony_ci cycles = list(range(n, n-r, -1)) 32237db96d56Sopenharmony_ci yield tuple(pool[i] for i in indices[:r]) 32247db96d56Sopenharmony_ci while n: 32257db96d56Sopenharmony_ci for i in reversed(range(r)): 32267db96d56Sopenharmony_ci cycles[i] -= 1 32277db96d56Sopenharmony_ci if cycles[i] == 0: 32287db96d56Sopenharmony_ci indices[i:] = indices[i+1:] + indices[i:i+1] 32297db96d56Sopenharmony_ci cycles[i] = n - i 32307db96d56Sopenharmony_ci else: 32317db96d56Sopenharmony_ci j = cycles[i] 32327db96d56Sopenharmony_ci indices[i], indices[-j] = indices[-j], indices[i] 32337db96d56Sopenharmony_ci yield tuple(pool[i] for i in indices[:r]) 32347db96d56Sopenharmony_ci break 32357db96d56Sopenharmony_ci else: 32367db96d56Sopenharmony_ci return 32377db96d56Sopenharmony_ci*/ 32387db96d56Sopenharmony_ci 32397db96d56Sopenharmony_citypedef struct { 32407db96d56Sopenharmony_ci PyObject_HEAD 32417db96d56Sopenharmony_ci PyObject *pool; /* input converted to a tuple */ 32427db96d56Sopenharmony_ci Py_ssize_t *indices; /* one index per element in the pool */ 32437db96d56Sopenharmony_ci Py_ssize_t *cycles; /* one rollover counter per element in the result */ 32447db96d56Sopenharmony_ci PyObject *result; /* most recently returned result tuple */ 32457db96d56Sopenharmony_ci Py_ssize_t r; /* size of result tuple */ 32467db96d56Sopenharmony_ci int stopped; /* set to 1 when the iterator is exhausted */ 32477db96d56Sopenharmony_ci} permutationsobject; 32487db96d56Sopenharmony_ci 32497db96d56Sopenharmony_ci/*[clinic input] 32507db96d56Sopenharmony_ci@classmethod 32517db96d56Sopenharmony_ciitertools.permutations.__new__ 32527db96d56Sopenharmony_ci iterable: object 32537db96d56Sopenharmony_ci r as robj: object = None 32547db96d56Sopenharmony_ciReturn successive r-length permutations of elements in the iterable. 32557db96d56Sopenharmony_ci 32567db96d56Sopenharmony_cipermutations(range(3), 2) --> (0,1), (0,2), (1,0), (1,2), (2,0), (2,1) 32577db96d56Sopenharmony_ci[clinic start generated code]*/ 32587db96d56Sopenharmony_ci 32597db96d56Sopenharmony_cistatic PyObject * 32607db96d56Sopenharmony_ciitertools_permutations_impl(PyTypeObject *type, PyObject *iterable, 32617db96d56Sopenharmony_ci PyObject *robj) 32627db96d56Sopenharmony_ci/*[clinic end generated code: output=296a72fa76d620ea input=57d0170a4ac0ec7a]*/ 32637db96d56Sopenharmony_ci{ 32647db96d56Sopenharmony_ci permutationsobject *po; 32657db96d56Sopenharmony_ci Py_ssize_t n; 32667db96d56Sopenharmony_ci Py_ssize_t r; 32677db96d56Sopenharmony_ci PyObject *pool = NULL; 32687db96d56Sopenharmony_ci Py_ssize_t *indices = NULL; 32697db96d56Sopenharmony_ci Py_ssize_t *cycles = NULL; 32707db96d56Sopenharmony_ci Py_ssize_t i; 32717db96d56Sopenharmony_ci 32727db96d56Sopenharmony_ci pool = PySequence_Tuple(iterable); 32737db96d56Sopenharmony_ci if (pool == NULL) 32747db96d56Sopenharmony_ci goto error; 32757db96d56Sopenharmony_ci n = PyTuple_GET_SIZE(pool); 32767db96d56Sopenharmony_ci 32777db96d56Sopenharmony_ci r = n; 32787db96d56Sopenharmony_ci if (robj != Py_None) { 32797db96d56Sopenharmony_ci if (!PyLong_Check(robj)) { 32807db96d56Sopenharmony_ci PyErr_SetString(PyExc_TypeError, "Expected int as r"); 32817db96d56Sopenharmony_ci goto error; 32827db96d56Sopenharmony_ci } 32837db96d56Sopenharmony_ci r = PyLong_AsSsize_t(robj); 32847db96d56Sopenharmony_ci if (r == -1 && PyErr_Occurred()) 32857db96d56Sopenharmony_ci goto error; 32867db96d56Sopenharmony_ci } 32877db96d56Sopenharmony_ci if (r < 0) { 32887db96d56Sopenharmony_ci PyErr_SetString(PyExc_ValueError, "r must be non-negative"); 32897db96d56Sopenharmony_ci goto error; 32907db96d56Sopenharmony_ci } 32917db96d56Sopenharmony_ci 32927db96d56Sopenharmony_ci indices = PyMem_New(Py_ssize_t, n); 32937db96d56Sopenharmony_ci cycles = PyMem_New(Py_ssize_t, r); 32947db96d56Sopenharmony_ci if (indices == NULL || cycles == NULL) { 32957db96d56Sopenharmony_ci PyErr_NoMemory(); 32967db96d56Sopenharmony_ci goto error; 32977db96d56Sopenharmony_ci } 32987db96d56Sopenharmony_ci 32997db96d56Sopenharmony_ci for (i=0 ; i<n ; i++) 33007db96d56Sopenharmony_ci indices[i] = i; 33017db96d56Sopenharmony_ci for (i=0 ; i<r ; i++) 33027db96d56Sopenharmony_ci cycles[i] = n - i; 33037db96d56Sopenharmony_ci 33047db96d56Sopenharmony_ci /* create permutationsobject structure */ 33057db96d56Sopenharmony_ci po = (permutationsobject *)type->tp_alloc(type, 0); 33067db96d56Sopenharmony_ci if (po == NULL) 33077db96d56Sopenharmony_ci goto error; 33087db96d56Sopenharmony_ci 33097db96d56Sopenharmony_ci po->pool = pool; 33107db96d56Sopenharmony_ci po->indices = indices; 33117db96d56Sopenharmony_ci po->cycles = cycles; 33127db96d56Sopenharmony_ci po->result = NULL; 33137db96d56Sopenharmony_ci po->r = r; 33147db96d56Sopenharmony_ci po->stopped = r > n ? 1 : 0; 33157db96d56Sopenharmony_ci 33167db96d56Sopenharmony_ci return (PyObject *)po; 33177db96d56Sopenharmony_ci 33187db96d56Sopenharmony_cierror: 33197db96d56Sopenharmony_ci if (indices != NULL) 33207db96d56Sopenharmony_ci PyMem_Free(indices); 33217db96d56Sopenharmony_ci if (cycles != NULL) 33227db96d56Sopenharmony_ci PyMem_Free(cycles); 33237db96d56Sopenharmony_ci Py_XDECREF(pool); 33247db96d56Sopenharmony_ci return NULL; 33257db96d56Sopenharmony_ci} 33267db96d56Sopenharmony_ci 33277db96d56Sopenharmony_cistatic void 33287db96d56Sopenharmony_cipermutations_dealloc(permutationsobject *po) 33297db96d56Sopenharmony_ci{ 33307db96d56Sopenharmony_ci PyObject_GC_UnTrack(po); 33317db96d56Sopenharmony_ci Py_XDECREF(po->pool); 33327db96d56Sopenharmony_ci Py_XDECREF(po->result); 33337db96d56Sopenharmony_ci PyMem_Free(po->indices); 33347db96d56Sopenharmony_ci PyMem_Free(po->cycles); 33357db96d56Sopenharmony_ci Py_TYPE(po)->tp_free(po); 33367db96d56Sopenharmony_ci} 33377db96d56Sopenharmony_ci 33387db96d56Sopenharmony_cistatic PyObject * 33397db96d56Sopenharmony_cipermutations_sizeof(permutationsobject *po, void *unused) 33407db96d56Sopenharmony_ci{ 33417db96d56Sopenharmony_ci Py_ssize_t res; 33427db96d56Sopenharmony_ci 33437db96d56Sopenharmony_ci res = _PyObject_SIZE(Py_TYPE(po)); 33447db96d56Sopenharmony_ci res += PyTuple_GET_SIZE(po->pool) * sizeof(Py_ssize_t); 33457db96d56Sopenharmony_ci res += po->r * sizeof(Py_ssize_t); 33467db96d56Sopenharmony_ci return PyLong_FromSsize_t(res); 33477db96d56Sopenharmony_ci} 33487db96d56Sopenharmony_ci 33497db96d56Sopenharmony_cistatic int 33507db96d56Sopenharmony_cipermutations_traverse(permutationsobject *po, visitproc visit, void *arg) 33517db96d56Sopenharmony_ci{ 33527db96d56Sopenharmony_ci Py_VISIT(po->pool); 33537db96d56Sopenharmony_ci Py_VISIT(po->result); 33547db96d56Sopenharmony_ci return 0; 33557db96d56Sopenharmony_ci} 33567db96d56Sopenharmony_ci 33577db96d56Sopenharmony_cistatic PyObject * 33587db96d56Sopenharmony_cipermutations_next(permutationsobject *po) 33597db96d56Sopenharmony_ci{ 33607db96d56Sopenharmony_ci PyObject *elem; 33617db96d56Sopenharmony_ci PyObject *oldelem; 33627db96d56Sopenharmony_ci PyObject *pool = po->pool; 33637db96d56Sopenharmony_ci Py_ssize_t *indices = po->indices; 33647db96d56Sopenharmony_ci Py_ssize_t *cycles = po->cycles; 33657db96d56Sopenharmony_ci PyObject *result = po->result; 33667db96d56Sopenharmony_ci Py_ssize_t n = PyTuple_GET_SIZE(pool); 33677db96d56Sopenharmony_ci Py_ssize_t r = po->r; 33687db96d56Sopenharmony_ci Py_ssize_t i, j, k, index; 33697db96d56Sopenharmony_ci 33707db96d56Sopenharmony_ci if (po->stopped) 33717db96d56Sopenharmony_ci return NULL; 33727db96d56Sopenharmony_ci 33737db96d56Sopenharmony_ci if (result == NULL) { 33747db96d56Sopenharmony_ci /* On the first pass, initialize result tuple using the indices */ 33757db96d56Sopenharmony_ci result = PyTuple_New(r); 33767db96d56Sopenharmony_ci if (result == NULL) 33777db96d56Sopenharmony_ci goto empty; 33787db96d56Sopenharmony_ci po->result = result; 33797db96d56Sopenharmony_ci for (i=0; i<r ; i++) { 33807db96d56Sopenharmony_ci index = indices[i]; 33817db96d56Sopenharmony_ci elem = PyTuple_GET_ITEM(pool, index); 33827db96d56Sopenharmony_ci Py_INCREF(elem); 33837db96d56Sopenharmony_ci PyTuple_SET_ITEM(result, i, elem); 33847db96d56Sopenharmony_ci } 33857db96d56Sopenharmony_ci } else { 33867db96d56Sopenharmony_ci if (n == 0) 33877db96d56Sopenharmony_ci goto empty; 33887db96d56Sopenharmony_ci 33897db96d56Sopenharmony_ci /* Copy the previous result tuple or re-use it if available */ 33907db96d56Sopenharmony_ci if (Py_REFCNT(result) > 1) { 33917db96d56Sopenharmony_ci PyObject *old_result = result; 33927db96d56Sopenharmony_ci result = _PyTuple_FromArray(_PyTuple_ITEMS(old_result), r); 33937db96d56Sopenharmony_ci if (result == NULL) 33947db96d56Sopenharmony_ci goto empty; 33957db96d56Sopenharmony_ci po->result = result; 33967db96d56Sopenharmony_ci Py_DECREF(old_result); 33977db96d56Sopenharmony_ci } 33987db96d56Sopenharmony_ci // bpo-42536: The GC may have untracked this result tuple. Since we're 33997db96d56Sopenharmony_ci // recycling it, make sure it's tracked again: 34007db96d56Sopenharmony_ci else if (!_PyObject_GC_IS_TRACKED(result)) { 34017db96d56Sopenharmony_ci _PyObject_GC_TRACK(result); 34027db96d56Sopenharmony_ci } 34037db96d56Sopenharmony_ci /* Now, we've got the only copy so we can update it in-place */ 34047db96d56Sopenharmony_ci assert(r == 0 || Py_REFCNT(result) == 1); 34057db96d56Sopenharmony_ci 34067db96d56Sopenharmony_ci /* Decrement rightmost cycle, moving leftward upon zero rollover */ 34077db96d56Sopenharmony_ci for (i=r-1 ; i>=0 ; i--) { 34087db96d56Sopenharmony_ci cycles[i] -= 1; 34097db96d56Sopenharmony_ci if (cycles[i] == 0) { 34107db96d56Sopenharmony_ci /* rotatation: indices[i:] = indices[i+1:] + indices[i:i+1] */ 34117db96d56Sopenharmony_ci index = indices[i]; 34127db96d56Sopenharmony_ci for (j=i ; j<n-1 ; j++) 34137db96d56Sopenharmony_ci indices[j] = indices[j+1]; 34147db96d56Sopenharmony_ci indices[n-1] = index; 34157db96d56Sopenharmony_ci cycles[i] = n - i; 34167db96d56Sopenharmony_ci } else { 34177db96d56Sopenharmony_ci j = cycles[i]; 34187db96d56Sopenharmony_ci index = indices[i]; 34197db96d56Sopenharmony_ci indices[i] = indices[n-j]; 34207db96d56Sopenharmony_ci indices[n-j] = index; 34217db96d56Sopenharmony_ci 34227db96d56Sopenharmony_ci for (k=i; k<r ; k++) { 34237db96d56Sopenharmony_ci /* start with i, the leftmost element that changed */ 34247db96d56Sopenharmony_ci /* yield tuple(pool[k] for k in indices[:r]) */ 34257db96d56Sopenharmony_ci index = indices[k]; 34267db96d56Sopenharmony_ci elem = PyTuple_GET_ITEM(pool, index); 34277db96d56Sopenharmony_ci Py_INCREF(elem); 34287db96d56Sopenharmony_ci oldelem = PyTuple_GET_ITEM(result, k); 34297db96d56Sopenharmony_ci PyTuple_SET_ITEM(result, k, elem); 34307db96d56Sopenharmony_ci Py_DECREF(oldelem); 34317db96d56Sopenharmony_ci } 34327db96d56Sopenharmony_ci break; 34337db96d56Sopenharmony_ci } 34347db96d56Sopenharmony_ci } 34357db96d56Sopenharmony_ci /* If i is negative, then the cycles have all 34367db96d56Sopenharmony_ci rolled-over and we're done. */ 34377db96d56Sopenharmony_ci if (i < 0) 34387db96d56Sopenharmony_ci goto empty; 34397db96d56Sopenharmony_ci } 34407db96d56Sopenharmony_ci Py_INCREF(result); 34417db96d56Sopenharmony_ci return result; 34427db96d56Sopenharmony_ci 34437db96d56Sopenharmony_ciempty: 34447db96d56Sopenharmony_ci po->stopped = 1; 34457db96d56Sopenharmony_ci return NULL; 34467db96d56Sopenharmony_ci} 34477db96d56Sopenharmony_ci 34487db96d56Sopenharmony_cistatic PyObject * 34497db96d56Sopenharmony_cipermutations_reduce(permutationsobject *po, PyObject *Py_UNUSED(ignored)) 34507db96d56Sopenharmony_ci{ 34517db96d56Sopenharmony_ci if (po->result == NULL) { 34527db96d56Sopenharmony_ci return Py_BuildValue("O(On)", Py_TYPE(po), po->pool, po->r); 34537db96d56Sopenharmony_ci } else if (po->stopped) { 34547db96d56Sopenharmony_ci return Py_BuildValue("O(()n)", Py_TYPE(po), po->r); 34557db96d56Sopenharmony_ci } else { 34567db96d56Sopenharmony_ci PyObject *indices=NULL, *cycles=NULL; 34577db96d56Sopenharmony_ci Py_ssize_t n, i; 34587db96d56Sopenharmony_ci 34597db96d56Sopenharmony_ci /* we must pickle the indices and cycles and use them for setstate */ 34607db96d56Sopenharmony_ci n = PyTuple_GET_SIZE(po->pool); 34617db96d56Sopenharmony_ci indices = PyTuple_New(n); 34627db96d56Sopenharmony_ci if (indices == NULL) 34637db96d56Sopenharmony_ci goto err; 34647db96d56Sopenharmony_ci for (i=0; i<n; i++) { 34657db96d56Sopenharmony_ci PyObject* index = PyLong_FromSsize_t(po->indices[i]); 34667db96d56Sopenharmony_ci if (!index) 34677db96d56Sopenharmony_ci goto err; 34687db96d56Sopenharmony_ci PyTuple_SET_ITEM(indices, i, index); 34697db96d56Sopenharmony_ci } 34707db96d56Sopenharmony_ci 34717db96d56Sopenharmony_ci cycles = PyTuple_New(po->r); 34727db96d56Sopenharmony_ci if (cycles == NULL) 34737db96d56Sopenharmony_ci goto err; 34747db96d56Sopenharmony_ci for (i=0 ; i<po->r ; i++) { 34757db96d56Sopenharmony_ci PyObject* index = PyLong_FromSsize_t(po->cycles[i]); 34767db96d56Sopenharmony_ci if (!index) 34777db96d56Sopenharmony_ci goto err; 34787db96d56Sopenharmony_ci PyTuple_SET_ITEM(cycles, i, index); 34797db96d56Sopenharmony_ci } 34807db96d56Sopenharmony_ci return Py_BuildValue("O(On)(NN)", Py_TYPE(po), 34817db96d56Sopenharmony_ci po->pool, po->r, 34827db96d56Sopenharmony_ci indices, cycles); 34837db96d56Sopenharmony_ci err: 34847db96d56Sopenharmony_ci Py_XDECREF(indices); 34857db96d56Sopenharmony_ci Py_XDECREF(cycles); 34867db96d56Sopenharmony_ci return NULL; 34877db96d56Sopenharmony_ci } 34887db96d56Sopenharmony_ci} 34897db96d56Sopenharmony_ci 34907db96d56Sopenharmony_cistatic PyObject * 34917db96d56Sopenharmony_cipermutations_setstate(permutationsobject *po, PyObject *state) 34927db96d56Sopenharmony_ci{ 34937db96d56Sopenharmony_ci PyObject *indices, *cycles, *result; 34947db96d56Sopenharmony_ci Py_ssize_t n, i; 34957db96d56Sopenharmony_ci 34967db96d56Sopenharmony_ci if (!PyTuple_Check(state)) { 34977db96d56Sopenharmony_ci PyErr_SetString(PyExc_TypeError, "state is not a tuple"); 34987db96d56Sopenharmony_ci return NULL; 34997db96d56Sopenharmony_ci } 35007db96d56Sopenharmony_ci if (!PyArg_ParseTuple(state, "O!O!", 35017db96d56Sopenharmony_ci &PyTuple_Type, &indices, 35027db96d56Sopenharmony_ci &PyTuple_Type, &cycles)) { 35037db96d56Sopenharmony_ci return NULL; 35047db96d56Sopenharmony_ci } 35057db96d56Sopenharmony_ci 35067db96d56Sopenharmony_ci n = PyTuple_GET_SIZE(po->pool); 35077db96d56Sopenharmony_ci if (PyTuple_GET_SIZE(indices) != n || PyTuple_GET_SIZE(cycles) != po->r) { 35087db96d56Sopenharmony_ci PyErr_SetString(PyExc_ValueError, "invalid arguments"); 35097db96d56Sopenharmony_ci return NULL; 35107db96d56Sopenharmony_ci } 35117db96d56Sopenharmony_ci 35127db96d56Sopenharmony_ci for (i=0; i<n; i++) { 35137db96d56Sopenharmony_ci PyObject* indexObject = PyTuple_GET_ITEM(indices, i); 35147db96d56Sopenharmony_ci Py_ssize_t index = PyLong_AsSsize_t(indexObject); 35157db96d56Sopenharmony_ci if (index < 0 && PyErr_Occurred()) 35167db96d56Sopenharmony_ci return NULL; /* not an integer */ 35177db96d56Sopenharmony_ci /* clamp the index */ 35187db96d56Sopenharmony_ci if (index < 0) 35197db96d56Sopenharmony_ci index = 0; 35207db96d56Sopenharmony_ci else if (index > n-1) 35217db96d56Sopenharmony_ci index = n-1; 35227db96d56Sopenharmony_ci po->indices[i] = index; 35237db96d56Sopenharmony_ci } 35247db96d56Sopenharmony_ci 35257db96d56Sopenharmony_ci for (i=0; i<po->r; i++) { 35267db96d56Sopenharmony_ci PyObject* indexObject = PyTuple_GET_ITEM(cycles, i); 35277db96d56Sopenharmony_ci Py_ssize_t index = PyLong_AsSsize_t(indexObject); 35287db96d56Sopenharmony_ci if (index < 0 && PyErr_Occurred()) 35297db96d56Sopenharmony_ci return NULL; /* not an integer */ 35307db96d56Sopenharmony_ci if (index < 1) 35317db96d56Sopenharmony_ci index = 1; 35327db96d56Sopenharmony_ci else if (index > n-i) 35337db96d56Sopenharmony_ci index = n-i; 35347db96d56Sopenharmony_ci po->cycles[i] = index; 35357db96d56Sopenharmony_ci } 35367db96d56Sopenharmony_ci result = PyTuple_New(po->r); 35377db96d56Sopenharmony_ci if (result == NULL) 35387db96d56Sopenharmony_ci return NULL; 35397db96d56Sopenharmony_ci for (i=0; i<po->r; i++) { 35407db96d56Sopenharmony_ci PyObject *element = PyTuple_GET_ITEM(po->pool, po->indices[i]); 35417db96d56Sopenharmony_ci Py_INCREF(element); 35427db96d56Sopenharmony_ci PyTuple_SET_ITEM(result, i, element); 35437db96d56Sopenharmony_ci } 35447db96d56Sopenharmony_ci Py_XSETREF(po->result, result); 35457db96d56Sopenharmony_ci Py_RETURN_NONE; 35467db96d56Sopenharmony_ci} 35477db96d56Sopenharmony_ci 35487db96d56Sopenharmony_cistatic PyMethodDef permuations_methods[] = { 35497db96d56Sopenharmony_ci {"__reduce__", (PyCFunction)permutations_reduce, METH_NOARGS, 35507db96d56Sopenharmony_ci reduce_doc}, 35517db96d56Sopenharmony_ci {"__setstate__", (PyCFunction)permutations_setstate, METH_O, 35527db96d56Sopenharmony_ci setstate_doc}, 35537db96d56Sopenharmony_ci {"__sizeof__", (PyCFunction)permutations_sizeof, METH_NOARGS, 35547db96d56Sopenharmony_ci sizeof_doc}, 35557db96d56Sopenharmony_ci {NULL, NULL} /* sentinel */ 35567db96d56Sopenharmony_ci}; 35577db96d56Sopenharmony_ci 35587db96d56Sopenharmony_cistatic PyTypeObject permutations_type = { 35597db96d56Sopenharmony_ci PyVarObject_HEAD_INIT(NULL, 0) 35607db96d56Sopenharmony_ci "itertools.permutations", /* tp_name */ 35617db96d56Sopenharmony_ci sizeof(permutationsobject), /* tp_basicsize */ 35627db96d56Sopenharmony_ci 0, /* tp_itemsize */ 35637db96d56Sopenharmony_ci /* methods */ 35647db96d56Sopenharmony_ci (destructor)permutations_dealloc, /* tp_dealloc */ 35657db96d56Sopenharmony_ci 0, /* tp_vectorcall_offset */ 35667db96d56Sopenharmony_ci 0, /* tp_getattr */ 35677db96d56Sopenharmony_ci 0, /* tp_setattr */ 35687db96d56Sopenharmony_ci 0, /* tp_as_async */ 35697db96d56Sopenharmony_ci 0, /* tp_repr */ 35707db96d56Sopenharmony_ci 0, /* tp_as_number */ 35717db96d56Sopenharmony_ci 0, /* tp_as_sequence */ 35727db96d56Sopenharmony_ci 0, /* tp_as_mapping */ 35737db96d56Sopenharmony_ci 0, /* tp_hash */ 35747db96d56Sopenharmony_ci 0, /* tp_call */ 35757db96d56Sopenharmony_ci 0, /* tp_str */ 35767db96d56Sopenharmony_ci PyObject_GenericGetAttr, /* tp_getattro */ 35777db96d56Sopenharmony_ci 0, /* tp_setattro */ 35787db96d56Sopenharmony_ci 0, /* tp_as_buffer */ 35797db96d56Sopenharmony_ci Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | 35807db96d56Sopenharmony_ci Py_TPFLAGS_BASETYPE, /* tp_flags */ 35817db96d56Sopenharmony_ci itertools_permutations__doc__, /* tp_doc */ 35827db96d56Sopenharmony_ci (traverseproc)permutations_traverse,/* tp_traverse */ 35837db96d56Sopenharmony_ci 0, /* tp_clear */ 35847db96d56Sopenharmony_ci 0, /* tp_richcompare */ 35857db96d56Sopenharmony_ci 0, /* tp_weaklistoffset */ 35867db96d56Sopenharmony_ci PyObject_SelfIter, /* tp_iter */ 35877db96d56Sopenharmony_ci (iternextfunc)permutations_next, /* tp_iternext */ 35887db96d56Sopenharmony_ci permuations_methods, /* tp_methods */ 35897db96d56Sopenharmony_ci 0, /* tp_members */ 35907db96d56Sopenharmony_ci 0, /* tp_getset */ 35917db96d56Sopenharmony_ci 0, /* tp_base */ 35927db96d56Sopenharmony_ci 0, /* tp_dict */ 35937db96d56Sopenharmony_ci 0, /* tp_descr_get */ 35947db96d56Sopenharmony_ci 0, /* tp_descr_set */ 35957db96d56Sopenharmony_ci 0, /* tp_dictoffset */ 35967db96d56Sopenharmony_ci 0, /* tp_init */ 35977db96d56Sopenharmony_ci 0, /* tp_alloc */ 35987db96d56Sopenharmony_ci itertools_permutations, /* tp_new */ 35997db96d56Sopenharmony_ci PyObject_GC_Del, /* tp_free */ 36007db96d56Sopenharmony_ci}; 36017db96d56Sopenharmony_ci 36027db96d56Sopenharmony_ci 36037db96d56Sopenharmony_ci/* accumulate object ********************************************************/ 36047db96d56Sopenharmony_ci 36057db96d56Sopenharmony_citypedef struct { 36067db96d56Sopenharmony_ci PyObject_HEAD 36077db96d56Sopenharmony_ci PyObject *total; 36087db96d56Sopenharmony_ci PyObject *it; 36097db96d56Sopenharmony_ci PyObject *binop; 36107db96d56Sopenharmony_ci PyObject *initial; 36117db96d56Sopenharmony_ci} accumulateobject; 36127db96d56Sopenharmony_ci 36137db96d56Sopenharmony_ci/*[clinic input] 36147db96d56Sopenharmony_ci@classmethod 36157db96d56Sopenharmony_ciitertools.accumulate.__new__ 36167db96d56Sopenharmony_ci iterable: object 36177db96d56Sopenharmony_ci func as binop: object = None 36187db96d56Sopenharmony_ci * 36197db96d56Sopenharmony_ci initial: object = None 36207db96d56Sopenharmony_ciReturn series of accumulated sums (or other binary function results). 36217db96d56Sopenharmony_ci[clinic start generated code]*/ 36227db96d56Sopenharmony_ci 36237db96d56Sopenharmony_cistatic PyObject * 36247db96d56Sopenharmony_ciitertools_accumulate_impl(PyTypeObject *type, PyObject *iterable, 36257db96d56Sopenharmony_ci PyObject *binop, PyObject *initial) 36267db96d56Sopenharmony_ci/*[clinic end generated code: output=66da2650627128f8 input=c4ce20ac59bf7ffd]*/ 36277db96d56Sopenharmony_ci{ 36287db96d56Sopenharmony_ci PyObject *it; 36297db96d56Sopenharmony_ci accumulateobject *lz; 36307db96d56Sopenharmony_ci 36317db96d56Sopenharmony_ci /* Get iterator. */ 36327db96d56Sopenharmony_ci it = PyObject_GetIter(iterable); 36337db96d56Sopenharmony_ci if (it == NULL) 36347db96d56Sopenharmony_ci return NULL; 36357db96d56Sopenharmony_ci 36367db96d56Sopenharmony_ci /* create accumulateobject structure */ 36377db96d56Sopenharmony_ci lz = (accumulateobject *)type->tp_alloc(type, 0); 36387db96d56Sopenharmony_ci if (lz == NULL) { 36397db96d56Sopenharmony_ci Py_DECREF(it); 36407db96d56Sopenharmony_ci return NULL; 36417db96d56Sopenharmony_ci } 36427db96d56Sopenharmony_ci 36437db96d56Sopenharmony_ci if (binop != Py_None) { 36447db96d56Sopenharmony_ci Py_XINCREF(binop); 36457db96d56Sopenharmony_ci lz->binop = binop; 36467db96d56Sopenharmony_ci } 36477db96d56Sopenharmony_ci lz->total = NULL; 36487db96d56Sopenharmony_ci lz->it = it; 36497db96d56Sopenharmony_ci Py_XINCREF(initial); 36507db96d56Sopenharmony_ci lz->initial = initial; 36517db96d56Sopenharmony_ci return (PyObject *)lz; 36527db96d56Sopenharmony_ci} 36537db96d56Sopenharmony_ci 36547db96d56Sopenharmony_cistatic void 36557db96d56Sopenharmony_ciaccumulate_dealloc(accumulateobject *lz) 36567db96d56Sopenharmony_ci{ 36577db96d56Sopenharmony_ci PyObject_GC_UnTrack(lz); 36587db96d56Sopenharmony_ci Py_XDECREF(lz->binop); 36597db96d56Sopenharmony_ci Py_XDECREF(lz->total); 36607db96d56Sopenharmony_ci Py_XDECREF(lz->it); 36617db96d56Sopenharmony_ci Py_XDECREF(lz->initial); 36627db96d56Sopenharmony_ci Py_TYPE(lz)->tp_free(lz); 36637db96d56Sopenharmony_ci} 36647db96d56Sopenharmony_ci 36657db96d56Sopenharmony_cistatic int 36667db96d56Sopenharmony_ciaccumulate_traverse(accumulateobject *lz, visitproc visit, void *arg) 36677db96d56Sopenharmony_ci{ 36687db96d56Sopenharmony_ci Py_VISIT(lz->binop); 36697db96d56Sopenharmony_ci Py_VISIT(lz->it); 36707db96d56Sopenharmony_ci Py_VISIT(lz->total); 36717db96d56Sopenharmony_ci Py_VISIT(lz->initial); 36727db96d56Sopenharmony_ci return 0; 36737db96d56Sopenharmony_ci} 36747db96d56Sopenharmony_ci 36757db96d56Sopenharmony_cistatic PyObject * 36767db96d56Sopenharmony_ciaccumulate_next(accumulateobject *lz) 36777db96d56Sopenharmony_ci{ 36787db96d56Sopenharmony_ci PyObject *val, *newtotal; 36797db96d56Sopenharmony_ci 36807db96d56Sopenharmony_ci if (lz->initial != Py_None) { 36817db96d56Sopenharmony_ci lz->total = lz->initial; 36827db96d56Sopenharmony_ci Py_INCREF(Py_None); 36837db96d56Sopenharmony_ci lz->initial = Py_None; 36847db96d56Sopenharmony_ci Py_INCREF(lz->total); 36857db96d56Sopenharmony_ci return lz->total; 36867db96d56Sopenharmony_ci } 36877db96d56Sopenharmony_ci val = (*Py_TYPE(lz->it)->tp_iternext)(lz->it); 36887db96d56Sopenharmony_ci if (val == NULL) 36897db96d56Sopenharmony_ci return NULL; 36907db96d56Sopenharmony_ci 36917db96d56Sopenharmony_ci if (lz->total == NULL) { 36927db96d56Sopenharmony_ci Py_INCREF(val); 36937db96d56Sopenharmony_ci lz->total = val; 36947db96d56Sopenharmony_ci return lz->total; 36957db96d56Sopenharmony_ci } 36967db96d56Sopenharmony_ci 36977db96d56Sopenharmony_ci if (lz->binop == NULL) 36987db96d56Sopenharmony_ci newtotal = PyNumber_Add(lz->total, val); 36997db96d56Sopenharmony_ci else 37007db96d56Sopenharmony_ci newtotal = PyObject_CallFunctionObjArgs(lz->binop, lz->total, val, NULL); 37017db96d56Sopenharmony_ci Py_DECREF(val); 37027db96d56Sopenharmony_ci if (newtotal == NULL) 37037db96d56Sopenharmony_ci return NULL; 37047db96d56Sopenharmony_ci 37057db96d56Sopenharmony_ci Py_INCREF(newtotal); 37067db96d56Sopenharmony_ci Py_SETREF(lz->total, newtotal); 37077db96d56Sopenharmony_ci return newtotal; 37087db96d56Sopenharmony_ci} 37097db96d56Sopenharmony_ci 37107db96d56Sopenharmony_cistatic PyObject * 37117db96d56Sopenharmony_ciaccumulate_reduce(accumulateobject *lz, PyObject *Py_UNUSED(ignored)) 37127db96d56Sopenharmony_ci{ 37137db96d56Sopenharmony_ci if (lz->initial != Py_None) { 37147db96d56Sopenharmony_ci PyObject *it; 37157db96d56Sopenharmony_ci 37167db96d56Sopenharmony_ci assert(lz->total == NULL); 37177db96d56Sopenharmony_ci if (PyType_Ready(&chain_type) < 0) 37187db96d56Sopenharmony_ci return NULL; 37197db96d56Sopenharmony_ci it = PyObject_CallFunction((PyObject *)&chain_type, "(O)O", 37207db96d56Sopenharmony_ci lz->initial, lz->it); 37217db96d56Sopenharmony_ci if (it == NULL) 37227db96d56Sopenharmony_ci return NULL; 37237db96d56Sopenharmony_ci return Py_BuildValue("O(NO)O", Py_TYPE(lz), 37247db96d56Sopenharmony_ci it, lz->binop?lz->binop:Py_None, Py_None); 37257db96d56Sopenharmony_ci } 37267db96d56Sopenharmony_ci if (lz->total == Py_None) { 37277db96d56Sopenharmony_ci PyObject *it; 37287db96d56Sopenharmony_ci 37297db96d56Sopenharmony_ci if (PyType_Ready(&chain_type) < 0) 37307db96d56Sopenharmony_ci return NULL; 37317db96d56Sopenharmony_ci if (PyType_Ready(&islice_type) < 0) 37327db96d56Sopenharmony_ci return NULL; 37337db96d56Sopenharmony_ci it = PyObject_CallFunction((PyObject *)&chain_type, "(O)O", 37347db96d56Sopenharmony_ci lz->total, lz->it); 37357db96d56Sopenharmony_ci if (it == NULL) 37367db96d56Sopenharmony_ci return NULL; 37377db96d56Sopenharmony_ci it = PyObject_CallFunction((PyObject *)Py_TYPE(lz), "NO", 37387db96d56Sopenharmony_ci it, lz->binop ? lz->binop : Py_None); 37397db96d56Sopenharmony_ci if (it == NULL) 37407db96d56Sopenharmony_ci return NULL; 37417db96d56Sopenharmony_ci return Py_BuildValue("O(NiO)", &islice_type, it, 1, Py_None); 37427db96d56Sopenharmony_ci } 37437db96d56Sopenharmony_ci return Py_BuildValue("O(OO)O", Py_TYPE(lz), 37447db96d56Sopenharmony_ci lz->it, lz->binop?lz->binop:Py_None, 37457db96d56Sopenharmony_ci lz->total?lz->total:Py_None); 37467db96d56Sopenharmony_ci} 37477db96d56Sopenharmony_ci 37487db96d56Sopenharmony_cistatic PyObject * 37497db96d56Sopenharmony_ciaccumulate_setstate(accumulateobject *lz, PyObject *state) 37507db96d56Sopenharmony_ci{ 37517db96d56Sopenharmony_ci Py_INCREF(state); 37527db96d56Sopenharmony_ci Py_XSETREF(lz->total, state); 37537db96d56Sopenharmony_ci Py_RETURN_NONE; 37547db96d56Sopenharmony_ci} 37557db96d56Sopenharmony_ci 37567db96d56Sopenharmony_cistatic PyMethodDef accumulate_methods[] = { 37577db96d56Sopenharmony_ci {"__reduce__", (PyCFunction)accumulate_reduce, METH_NOARGS, 37587db96d56Sopenharmony_ci reduce_doc}, 37597db96d56Sopenharmony_ci {"__setstate__", (PyCFunction)accumulate_setstate, METH_O, 37607db96d56Sopenharmony_ci setstate_doc}, 37617db96d56Sopenharmony_ci {NULL, NULL} /* sentinel */ 37627db96d56Sopenharmony_ci}; 37637db96d56Sopenharmony_ci 37647db96d56Sopenharmony_cistatic PyTypeObject accumulate_type = { 37657db96d56Sopenharmony_ci PyVarObject_HEAD_INIT(NULL, 0) 37667db96d56Sopenharmony_ci "itertools.accumulate", /* tp_name */ 37677db96d56Sopenharmony_ci sizeof(accumulateobject), /* tp_basicsize */ 37687db96d56Sopenharmony_ci 0, /* tp_itemsize */ 37697db96d56Sopenharmony_ci /* methods */ 37707db96d56Sopenharmony_ci (destructor)accumulate_dealloc, /* tp_dealloc */ 37717db96d56Sopenharmony_ci 0, /* tp_vectorcall_offset */ 37727db96d56Sopenharmony_ci 0, /* tp_getattr */ 37737db96d56Sopenharmony_ci 0, /* tp_setattr */ 37747db96d56Sopenharmony_ci 0, /* tp_as_async */ 37757db96d56Sopenharmony_ci 0, /* tp_repr */ 37767db96d56Sopenharmony_ci 0, /* tp_as_number */ 37777db96d56Sopenharmony_ci 0, /* tp_as_sequence */ 37787db96d56Sopenharmony_ci 0, /* tp_as_mapping */ 37797db96d56Sopenharmony_ci 0, /* tp_hash */ 37807db96d56Sopenharmony_ci 0, /* tp_call */ 37817db96d56Sopenharmony_ci 0, /* tp_str */ 37827db96d56Sopenharmony_ci PyObject_GenericGetAttr, /* tp_getattro */ 37837db96d56Sopenharmony_ci 0, /* tp_setattro */ 37847db96d56Sopenharmony_ci 0, /* tp_as_buffer */ 37857db96d56Sopenharmony_ci Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | 37867db96d56Sopenharmony_ci Py_TPFLAGS_BASETYPE, /* tp_flags */ 37877db96d56Sopenharmony_ci itertools_accumulate__doc__, /* tp_doc */ 37887db96d56Sopenharmony_ci (traverseproc)accumulate_traverse, /* tp_traverse */ 37897db96d56Sopenharmony_ci 0, /* tp_clear */ 37907db96d56Sopenharmony_ci 0, /* tp_richcompare */ 37917db96d56Sopenharmony_ci 0, /* tp_weaklistoffset */ 37927db96d56Sopenharmony_ci PyObject_SelfIter, /* tp_iter */ 37937db96d56Sopenharmony_ci (iternextfunc)accumulate_next, /* tp_iternext */ 37947db96d56Sopenharmony_ci accumulate_methods, /* tp_methods */ 37957db96d56Sopenharmony_ci 0, /* tp_members */ 37967db96d56Sopenharmony_ci 0, /* tp_getset */ 37977db96d56Sopenharmony_ci 0, /* tp_base */ 37987db96d56Sopenharmony_ci 0, /* tp_dict */ 37997db96d56Sopenharmony_ci 0, /* tp_descr_get */ 38007db96d56Sopenharmony_ci 0, /* tp_descr_set */ 38017db96d56Sopenharmony_ci 0, /* tp_dictoffset */ 38027db96d56Sopenharmony_ci 0, /* tp_init */ 38037db96d56Sopenharmony_ci 0, /* tp_alloc */ 38047db96d56Sopenharmony_ci itertools_accumulate, /* tp_new */ 38057db96d56Sopenharmony_ci PyObject_GC_Del, /* tp_free */ 38067db96d56Sopenharmony_ci}; 38077db96d56Sopenharmony_ci 38087db96d56Sopenharmony_ci 38097db96d56Sopenharmony_ci/* compress object ************************************************************/ 38107db96d56Sopenharmony_ci 38117db96d56Sopenharmony_ci/* Equivalent to: 38127db96d56Sopenharmony_ci 38137db96d56Sopenharmony_ci def compress(data, selectors): 38147db96d56Sopenharmony_ci "compress('ABCDEF', [1,0,1,0,1,1]) --> A C E F" 38157db96d56Sopenharmony_ci return (d for d, s in zip(data, selectors) if s) 38167db96d56Sopenharmony_ci*/ 38177db96d56Sopenharmony_ci 38187db96d56Sopenharmony_citypedef struct { 38197db96d56Sopenharmony_ci PyObject_HEAD 38207db96d56Sopenharmony_ci PyObject *data; 38217db96d56Sopenharmony_ci PyObject *selectors; 38227db96d56Sopenharmony_ci} compressobject; 38237db96d56Sopenharmony_ci 38247db96d56Sopenharmony_ci/*[clinic input] 38257db96d56Sopenharmony_ci@classmethod 38267db96d56Sopenharmony_ciitertools.compress.__new__ 38277db96d56Sopenharmony_ci data as seq1: object 38287db96d56Sopenharmony_ci selectors as seq2: object 38297db96d56Sopenharmony_ciReturn data elements corresponding to true selector elements. 38307db96d56Sopenharmony_ci 38317db96d56Sopenharmony_ciForms a shorter iterator from selected data elements using the selectors to 38327db96d56Sopenharmony_cichoose the data elements. 38337db96d56Sopenharmony_ci[clinic start generated code]*/ 38347db96d56Sopenharmony_ci 38357db96d56Sopenharmony_cistatic PyObject * 38367db96d56Sopenharmony_ciitertools_compress_impl(PyTypeObject *type, PyObject *seq1, PyObject *seq2) 38377db96d56Sopenharmony_ci/*[clinic end generated code: output=7e67157212ed09e0 input=79596d7cd20c77e5]*/ 38387db96d56Sopenharmony_ci{ 38397db96d56Sopenharmony_ci PyObject *data=NULL, *selectors=NULL; 38407db96d56Sopenharmony_ci compressobject *lz; 38417db96d56Sopenharmony_ci 38427db96d56Sopenharmony_ci data = PyObject_GetIter(seq1); 38437db96d56Sopenharmony_ci if (data == NULL) 38447db96d56Sopenharmony_ci goto fail; 38457db96d56Sopenharmony_ci selectors = PyObject_GetIter(seq2); 38467db96d56Sopenharmony_ci if (selectors == NULL) 38477db96d56Sopenharmony_ci goto fail; 38487db96d56Sopenharmony_ci 38497db96d56Sopenharmony_ci /* create compressobject structure */ 38507db96d56Sopenharmony_ci lz = (compressobject *)type->tp_alloc(type, 0); 38517db96d56Sopenharmony_ci if (lz == NULL) 38527db96d56Sopenharmony_ci goto fail; 38537db96d56Sopenharmony_ci lz->data = data; 38547db96d56Sopenharmony_ci lz->selectors = selectors; 38557db96d56Sopenharmony_ci return (PyObject *)lz; 38567db96d56Sopenharmony_ci 38577db96d56Sopenharmony_cifail: 38587db96d56Sopenharmony_ci Py_XDECREF(data); 38597db96d56Sopenharmony_ci Py_XDECREF(selectors); 38607db96d56Sopenharmony_ci return NULL; 38617db96d56Sopenharmony_ci} 38627db96d56Sopenharmony_ci 38637db96d56Sopenharmony_cistatic void 38647db96d56Sopenharmony_cicompress_dealloc(compressobject *lz) 38657db96d56Sopenharmony_ci{ 38667db96d56Sopenharmony_ci PyObject_GC_UnTrack(lz); 38677db96d56Sopenharmony_ci Py_XDECREF(lz->data); 38687db96d56Sopenharmony_ci Py_XDECREF(lz->selectors); 38697db96d56Sopenharmony_ci Py_TYPE(lz)->tp_free(lz); 38707db96d56Sopenharmony_ci} 38717db96d56Sopenharmony_ci 38727db96d56Sopenharmony_cistatic int 38737db96d56Sopenharmony_cicompress_traverse(compressobject *lz, visitproc visit, void *arg) 38747db96d56Sopenharmony_ci{ 38757db96d56Sopenharmony_ci Py_VISIT(lz->data); 38767db96d56Sopenharmony_ci Py_VISIT(lz->selectors); 38777db96d56Sopenharmony_ci return 0; 38787db96d56Sopenharmony_ci} 38797db96d56Sopenharmony_ci 38807db96d56Sopenharmony_cistatic PyObject * 38817db96d56Sopenharmony_cicompress_next(compressobject *lz) 38827db96d56Sopenharmony_ci{ 38837db96d56Sopenharmony_ci PyObject *data = lz->data, *selectors = lz->selectors; 38847db96d56Sopenharmony_ci PyObject *datum, *selector; 38857db96d56Sopenharmony_ci PyObject *(*datanext)(PyObject *) = *Py_TYPE(data)->tp_iternext; 38867db96d56Sopenharmony_ci PyObject *(*selectornext)(PyObject *) = *Py_TYPE(selectors)->tp_iternext; 38877db96d56Sopenharmony_ci int ok; 38887db96d56Sopenharmony_ci 38897db96d56Sopenharmony_ci while (1) { 38907db96d56Sopenharmony_ci /* Steps: get datum, get selector, evaluate selector. 38917db96d56Sopenharmony_ci Order is important (to match the pure python version 38927db96d56Sopenharmony_ci in terms of which input gets a chance to raise an 38937db96d56Sopenharmony_ci exception first). 38947db96d56Sopenharmony_ci */ 38957db96d56Sopenharmony_ci 38967db96d56Sopenharmony_ci datum = datanext(data); 38977db96d56Sopenharmony_ci if (datum == NULL) 38987db96d56Sopenharmony_ci return NULL; 38997db96d56Sopenharmony_ci 39007db96d56Sopenharmony_ci selector = selectornext(selectors); 39017db96d56Sopenharmony_ci if (selector == NULL) { 39027db96d56Sopenharmony_ci Py_DECREF(datum); 39037db96d56Sopenharmony_ci return NULL; 39047db96d56Sopenharmony_ci } 39057db96d56Sopenharmony_ci 39067db96d56Sopenharmony_ci ok = PyObject_IsTrue(selector); 39077db96d56Sopenharmony_ci Py_DECREF(selector); 39087db96d56Sopenharmony_ci if (ok > 0) 39097db96d56Sopenharmony_ci return datum; 39107db96d56Sopenharmony_ci Py_DECREF(datum); 39117db96d56Sopenharmony_ci if (ok < 0) 39127db96d56Sopenharmony_ci return NULL; 39137db96d56Sopenharmony_ci } 39147db96d56Sopenharmony_ci} 39157db96d56Sopenharmony_ci 39167db96d56Sopenharmony_cistatic PyObject * 39177db96d56Sopenharmony_cicompress_reduce(compressobject *lz, PyObject *Py_UNUSED(ignored)) 39187db96d56Sopenharmony_ci{ 39197db96d56Sopenharmony_ci return Py_BuildValue("O(OO)", Py_TYPE(lz), 39207db96d56Sopenharmony_ci lz->data, lz->selectors); 39217db96d56Sopenharmony_ci} 39227db96d56Sopenharmony_ci 39237db96d56Sopenharmony_cistatic PyMethodDef compress_methods[] = { 39247db96d56Sopenharmony_ci {"__reduce__", (PyCFunction)compress_reduce, METH_NOARGS, 39257db96d56Sopenharmony_ci reduce_doc}, 39267db96d56Sopenharmony_ci {NULL, NULL} /* sentinel */ 39277db96d56Sopenharmony_ci}; 39287db96d56Sopenharmony_ci 39297db96d56Sopenharmony_cistatic PyTypeObject compress_type = { 39307db96d56Sopenharmony_ci PyVarObject_HEAD_INIT(NULL, 0) 39317db96d56Sopenharmony_ci "itertools.compress", /* tp_name */ 39327db96d56Sopenharmony_ci sizeof(compressobject), /* tp_basicsize */ 39337db96d56Sopenharmony_ci 0, /* tp_itemsize */ 39347db96d56Sopenharmony_ci /* methods */ 39357db96d56Sopenharmony_ci (destructor)compress_dealloc, /* tp_dealloc */ 39367db96d56Sopenharmony_ci 0, /* tp_vectorcall_offset */ 39377db96d56Sopenharmony_ci 0, /* tp_getattr */ 39387db96d56Sopenharmony_ci 0, /* tp_setattr */ 39397db96d56Sopenharmony_ci 0, /* tp_as_async */ 39407db96d56Sopenharmony_ci 0, /* tp_repr */ 39417db96d56Sopenharmony_ci 0, /* tp_as_number */ 39427db96d56Sopenharmony_ci 0, /* tp_as_sequence */ 39437db96d56Sopenharmony_ci 0, /* tp_as_mapping */ 39447db96d56Sopenharmony_ci 0, /* tp_hash */ 39457db96d56Sopenharmony_ci 0, /* tp_call */ 39467db96d56Sopenharmony_ci 0, /* tp_str */ 39477db96d56Sopenharmony_ci PyObject_GenericGetAttr, /* tp_getattro */ 39487db96d56Sopenharmony_ci 0, /* tp_setattro */ 39497db96d56Sopenharmony_ci 0, /* tp_as_buffer */ 39507db96d56Sopenharmony_ci Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | 39517db96d56Sopenharmony_ci Py_TPFLAGS_BASETYPE, /* tp_flags */ 39527db96d56Sopenharmony_ci itertools_compress__doc__, /* tp_doc */ 39537db96d56Sopenharmony_ci (traverseproc)compress_traverse, /* tp_traverse */ 39547db96d56Sopenharmony_ci 0, /* tp_clear */ 39557db96d56Sopenharmony_ci 0, /* tp_richcompare */ 39567db96d56Sopenharmony_ci 0, /* tp_weaklistoffset */ 39577db96d56Sopenharmony_ci PyObject_SelfIter, /* tp_iter */ 39587db96d56Sopenharmony_ci (iternextfunc)compress_next, /* tp_iternext */ 39597db96d56Sopenharmony_ci compress_methods, /* tp_methods */ 39607db96d56Sopenharmony_ci 0, /* tp_members */ 39617db96d56Sopenharmony_ci 0, /* tp_getset */ 39627db96d56Sopenharmony_ci 0, /* tp_base */ 39637db96d56Sopenharmony_ci 0, /* tp_dict */ 39647db96d56Sopenharmony_ci 0, /* tp_descr_get */ 39657db96d56Sopenharmony_ci 0, /* tp_descr_set */ 39667db96d56Sopenharmony_ci 0, /* tp_dictoffset */ 39677db96d56Sopenharmony_ci 0, /* tp_init */ 39687db96d56Sopenharmony_ci 0, /* tp_alloc */ 39697db96d56Sopenharmony_ci itertools_compress, /* tp_new */ 39707db96d56Sopenharmony_ci PyObject_GC_Del, /* tp_free */ 39717db96d56Sopenharmony_ci}; 39727db96d56Sopenharmony_ci 39737db96d56Sopenharmony_ci 39747db96d56Sopenharmony_ci/* filterfalse object ************************************************************/ 39757db96d56Sopenharmony_ci 39767db96d56Sopenharmony_citypedef struct { 39777db96d56Sopenharmony_ci PyObject_HEAD 39787db96d56Sopenharmony_ci PyObject *func; 39797db96d56Sopenharmony_ci PyObject *it; 39807db96d56Sopenharmony_ci} filterfalseobject; 39817db96d56Sopenharmony_ci 39827db96d56Sopenharmony_ci/*[clinic input] 39837db96d56Sopenharmony_ci@classmethod 39847db96d56Sopenharmony_ciitertools.filterfalse.__new__ 39857db96d56Sopenharmony_ci function as func: object 39867db96d56Sopenharmony_ci iterable as seq: object 39877db96d56Sopenharmony_ci / 39887db96d56Sopenharmony_ciReturn those items of iterable for which function(item) is false. 39897db96d56Sopenharmony_ci 39907db96d56Sopenharmony_ciIf function is None, return the items that are false. 39917db96d56Sopenharmony_ci[clinic start generated code]*/ 39927db96d56Sopenharmony_ci 39937db96d56Sopenharmony_cistatic PyObject * 39947db96d56Sopenharmony_ciitertools_filterfalse_impl(PyTypeObject *type, PyObject *func, PyObject *seq) 39957db96d56Sopenharmony_ci/*[clinic end generated code: output=55f87eab9fc0484e input=2d684a2c66f99cde]*/ 39967db96d56Sopenharmony_ci{ 39977db96d56Sopenharmony_ci PyObject *it; 39987db96d56Sopenharmony_ci filterfalseobject *lz; 39997db96d56Sopenharmony_ci 40007db96d56Sopenharmony_ci /* Get iterator. */ 40017db96d56Sopenharmony_ci it = PyObject_GetIter(seq); 40027db96d56Sopenharmony_ci if (it == NULL) 40037db96d56Sopenharmony_ci return NULL; 40047db96d56Sopenharmony_ci 40057db96d56Sopenharmony_ci /* create filterfalseobject structure */ 40067db96d56Sopenharmony_ci lz = (filterfalseobject *)type->tp_alloc(type, 0); 40077db96d56Sopenharmony_ci if (lz == NULL) { 40087db96d56Sopenharmony_ci Py_DECREF(it); 40097db96d56Sopenharmony_ci return NULL; 40107db96d56Sopenharmony_ci } 40117db96d56Sopenharmony_ci Py_INCREF(func); 40127db96d56Sopenharmony_ci lz->func = func; 40137db96d56Sopenharmony_ci lz->it = it; 40147db96d56Sopenharmony_ci 40157db96d56Sopenharmony_ci return (PyObject *)lz; 40167db96d56Sopenharmony_ci} 40177db96d56Sopenharmony_ci 40187db96d56Sopenharmony_cistatic void 40197db96d56Sopenharmony_cifilterfalse_dealloc(filterfalseobject *lz) 40207db96d56Sopenharmony_ci{ 40217db96d56Sopenharmony_ci PyObject_GC_UnTrack(lz); 40227db96d56Sopenharmony_ci Py_XDECREF(lz->func); 40237db96d56Sopenharmony_ci Py_XDECREF(lz->it); 40247db96d56Sopenharmony_ci Py_TYPE(lz)->tp_free(lz); 40257db96d56Sopenharmony_ci} 40267db96d56Sopenharmony_ci 40277db96d56Sopenharmony_cistatic int 40287db96d56Sopenharmony_cifilterfalse_traverse(filterfalseobject *lz, visitproc visit, void *arg) 40297db96d56Sopenharmony_ci{ 40307db96d56Sopenharmony_ci Py_VISIT(lz->it); 40317db96d56Sopenharmony_ci Py_VISIT(lz->func); 40327db96d56Sopenharmony_ci return 0; 40337db96d56Sopenharmony_ci} 40347db96d56Sopenharmony_ci 40357db96d56Sopenharmony_cistatic PyObject * 40367db96d56Sopenharmony_cifilterfalse_next(filterfalseobject *lz) 40377db96d56Sopenharmony_ci{ 40387db96d56Sopenharmony_ci PyObject *item; 40397db96d56Sopenharmony_ci PyObject *it = lz->it; 40407db96d56Sopenharmony_ci long ok; 40417db96d56Sopenharmony_ci PyObject *(*iternext)(PyObject *); 40427db96d56Sopenharmony_ci 40437db96d56Sopenharmony_ci iternext = *Py_TYPE(it)->tp_iternext; 40447db96d56Sopenharmony_ci for (;;) { 40457db96d56Sopenharmony_ci item = iternext(it); 40467db96d56Sopenharmony_ci if (item == NULL) 40477db96d56Sopenharmony_ci return NULL; 40487db96d56Sopenharmony_ci 40497db96d56Sopenharmony_ci if (lz->func == Py_None || lz->func == (PyObject *)&PyBool_Type) { 40507db96d56Sopenharmony_ci ok = PyObject_IsTrue(item); 40517db96d56Sopenharmony_ci } else { 40527db96d56Sopenharmony_ci PyObject *good; 40537db96d56Sopenharmony_ci good = PyObject_CallOneArg(lz->func, item); 40547db96d56Sopenharmony_ci if (good == NULL) { 40557db96d56Sopenharmony_ci Py_DECREF(item); 40567db96d56Sopenharmony_ci return NULL; 40577db96d56Sopenharmony_ci } 40587db96d56Sopenharmony_ci ok = PyObject_IsTrue(good); 40597db96d56Sopenharmony_ci Py_DECREF(good); 40607db96d56Sopenharmony_ci } 40617db96d56Sopenharmony_ci if (ok == 0) 40627db96d56Sopenharmony_ci return item; 40637db96d56Sopenharmony_ci Py_DECREF(item); 40647db96d56Sopenharmony_ci if (ok < 0) 40657db96d56Sopenharmony_ci return NULL; 40667db96d56Sopenharmony_ci } 40677db96d56Sopenharmony_ci} 40687db96d56Sopenharmony_ci 40697db96d56Sopenharmony_cistatic PyObject * 40707db96d56Sopenharmony_cifilterfalse_reduce(filterfalseobject *lz, PyObject *Py_UNUSED(ignored)) 40717db96d56Sopenharmony_ci{ 40727db96d56Sopenharmony_ci return Py_BuildValue("O(OO)", Py_TYPE(lz), lz->func, lz->it); 40737db96d56Sopenharmony_ci} 40747db96d56Sopenharmony_ci 40757db96d56Sopenharmony_cistatic PyMethodDef filterfalse_methods[] = { 40767db96d56Sopenharmony_ci {"__reduce__", (PyCFunction)filterfalse_reduce, METH_NOARGS, 40777db96d56Sopenharmony_ci reduce_doc}, 40787db96d56Sopenharmony_ci {NULL, NULL} /* sentinel */ 40797db96d56Sopenharmony_ci}; 40807db96d56Sopenharmony_ci 40817db96d56Sopenharmony_cistatic PyTypeObject filterfalse_type = { 40827db96d56Sopenharmony_ci PyVarObject_HEAD_INIT(NULL, 0) 40837db96d56Sopenharmony_ci "itertools.filterfalse", /* tp_name */ 40847db96d56Sopenharmony_ci sizeof(filterfalseobject), /* tp_basicsize */ 40857db96d56Sopenharmony_ci 0, /* tp_itemsize */ 40867db96d56Sopenharmony_ci /* methods */ 40877db96d56Sopenharmony_ci (destructor)filterfalse_dealloc, /* tp_dealloc */ 40887db96d56Sopenharmony_ci 0, /* tp_vectorcall_offset */ 40897db96d56Sopenharmony_ci 0, /* tp_getattr */ 40907db96d56Sopenharmony_ci 0, /* tp_setattr */ 40917db96d56Sopenharmony_ci 0, /* tp_as_async */ 40927db96d56Sopenharmony_ci 0, /* tp_repr */ 40937db96d56Sopenharmony_ci 0, /* tp_as_number */ 40947db96d56Sopenharmony_ci 0, /* tp_as_sequence */ 40957db96d56Sopenharmony_ci 0, /* tp_as_mapping */ 40967db96d56Sopenharmony_ci 0, /* tp_hash */ 40977db96d56Sopenharmony_ci 0, /* tp_call */ 40987db96d56Sopenharmony_ci 0, /* tp_str */ 40997db96d56Sopenharmony_ci PyObject_GenericGetAttr, /* tp_getattro */ 41007db96d56Sopenharmony_ci 0, /* tp_setattro */ 41017db96d56Sopenharmony_ci 0, /* tp_as_buffer */ 41027db96d56Sopenharmony_ci Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | 41037db96d56Sopenharmony_ci Py_TPFLAGS_BASETYPE, /* tp_flags */ 41047db96d56Sopenharmony_ci itertools_filterfalse__doc__, /* tp_doc */ 41057db96d56Sopenharmony_ci (traverseproc)filterfalse_traverse, /* tp_traverse */ 41067db96d56Sopenharmony_ci 0, /* tp_clear */ 41077db96d56Sopenharmony_ci 0, /* tp_richcompare */ 41087db96d56Sopenharmony_ci 0, /* tp_weaklistoffset */ 41097db96d56Sopenharmony_ci PyObject_SelfIter, /* tp_iter */ 41107db96d56Sopenharmony_ci (iternextfunc)filterfalse_next, /* tp_iternext */ 41117db96d56Sopenharmony_ci filterfalse_methods, /* tp_methods */ 41127db96d56Sopenharmony_ci 0, /* tp_members */ 41137db96d56Sopenharmony_ci 0, /* tp_getset */ 41147db96d56Sopenharmony_ci 0, /* tp_base */ 41157db96d56Sopenharmony_ci 0, /* tp_dict */ 41167db96d56Sopenharmony_ci 0, /* tp_descr_get */ 41177db96d56Sopenharmony_ci 0, /* tp_descr_set */ 41187db96d56Sopenharmony_ci 0, /* tp_dictoffset */ 41197db96d56Sopenharmony_ci 0, /* tp_init */ 41207db96d56Sopenharmony_ci 0, /* tp_alloc */ 41217db96d56Sopenharmony_ci itertools_filterfalse, /* tp_new */ 41227db96d56Sopenharmony_ci PyObject_GC_Del, /* tp_free */ 41237db96d56Sopenharmony_ci}; 41247db96d56Sopenharmony_ci 41257db96d56Sopenharmony_ci 41267db96d56Sopenharmony_ci/* count object ************************************************************/ 41277db96d56Sopenharmony_ci 41287db96d56Sopenharmony_citypedef struct { 41297db96d56Sopenharmony_ci PyObject_HEAD 41307db96d56Sopenharmony_ci Py_ssize_t cnt; 41317db96d56Sopenharmony_ci PyObject *long_cnt; 41327db96d56Sopenharmony_ci PyObject *long_step; 41337db96d56Sopenharmony_ci} countobject; 41347db96d56Sopenharmony_ci 41357db96d56Sopenharmony_ci/* Counting logic and invariants: 41367db96d56Sopenharmony_ci 41377db96d56Sopenharmony_cifast_mode: when cnt an integer < PY_SSIZE_T_MAX and no step is specified. 41387db96d56Sopenharmony_ci 41397db96d56Sopenharmony_ci assert(cnt != PY_SSIZE_T_MAX && long_cnt == NULL && long_step==PyLong(1)); 41407db96d56Sopenharmony_ci Advances with: cnt += 1 41417db96d56Sopenharmony_ci When count hits Y_SSIZE_T_MAX, switch to slow_mode. 41427db96d56Sopenharmony_ci 41437db96d56Sopenharmony_cislow_mode: when cnt == PY_SSIZE_T_MAX, step is not int(1), or cnt is a float. 41447db96d56Sopenharmony_ci 41457db96d56Sopenharmony_ci assert(cnt == PY_SSIZE_T_MAX && long_cnt != NULL && long_step != NULL); 41467db96d56Sopenharmony_ci All counting is done with python objects (no overflows or underflows). 41477db96d56Sopenharmony_ci Advances with: long_cnt += long_step 41487db96d56Sopenharmony_ci Step may be zero -- effectively a slow version of repeat(cnt). 41497db96d56Sopenharmony_ci Either long_cnt or long_step may be a float, Fraction, or Decimal. 41507db96d56Sopenharmony_ci*/ 41517db96d56Sopenharmony_ci 41527db96d56Sopenharmony_ci/*[clinic input] 41537db96d56Sopenharmony_ci@classmethod 41547db96d56Sopenharmony_ciitertools.count.__new__ 41557db96d56Sopenharmony_ci start as long_cnt: object(c_default="NULL") = 0 41567db96d56Sopenharmony_ci step as long_step: object(c_default="NULL") = 1 41577db96d56Sopenharmony_ciReturn a count object whose .__next__() method returns consecutive values. 41587db96d56Sopenharmony_ci 41597db96d56Sopenharmony_ciEquivalent to: 41607db96d56Sopenharmony_ci def count(firstval=0, step=1): 41617db96d56Sopenharmony_ci x = firstval 41627db96d56Sopenharmony_ci while 1: 41637db96d56Sopenharmony_ci yield x 41647db96d56Sopenharmony_ci x += step 41657db96d56Sopenharmony_ci[clinic start generated code]*/ 41667db96d56Sopenharmony_ci 41677db96d56Sopenharmony_cistatic PyObject * 41687db96d56Sopenharmony_ciitertools_count_impl(PyTypeObject *type, PyObject *long_cnt, 41697db96d56Sopenharmony_ci PyObject *long_step) 41707db96d56Sopenharmony_ci/*[clinic end generated code: output=09a9250aebd00b1c input=d7a85eec18bfcd94]*/ 41717db96d56Sopenharmony_ci{ 41727db96d56Sopenharmony_ci countobject *lz; 41737db96d56Sopenharmony_ci int fast_mode; 41747db96d56Sopenharmony_ci Py_ssize_t cnt = 0; 41757db96d56Sopenharmony_ci long step; 41767db96d56Sopenharmony_ci 41777db96d56Sopenharmony_ci if ((long_cnt != NULL && !PyNumber_Check(long_cnt)) || 41787db96d56Sopenharmony_ci (long_step != NULL && !PyNumber_Check(long_step))) { 41797db96d56Sopenharmony_ci PyErr_SetString(PyExc_TypeError, "a number is required"); 41807db96d56Sopenharmony_ci return NULL; 41817db96d56Sopenharmony_ci } 41827db96d56Sopenharmony_ci 41837db96d56Sopenharmony_ci fast_mode = (long_cnt == NULL || PyLong_Check(long_cnt)) && 41847db96d56Sopenharmony_ci (long_step == NULL || PyLong_Check(long_step)); 41857db96d56Sopenharmony_ci 41867db96d56Sopenharmony_ci /* If not specified, start defaults to 0 */ 41877db96d56Sopenharmony_ci if (long_cnt != NULL) { 41887db96d56Sopenharmony_ci if (fast_mode) { 41897db96d56Sopenharmony_ci assert(PyLong_Check(long_cnt)); 41907db96d56Sopenharmony_ci cnt = PyLong_AsSsize_t(long_cnt); 41917db96d56Sopenharmony_ci if (cnt == -1 && PyErr_Occurred()) { 41927db96d56Sopenharmony_ci PyErr_Clear(); 41937db96d56Sopenharmony_ci fast_mode = 0; 41947db96d56Sopenharmony_ci } 41957db96d56Sopenharmony_ci } 41967db96d56Sopenharmony_ci } else { 41977db96d56Sopenharmony_ci cnt = 0; 41987db96d56Sopenharmony_ci long_cnt = _PyLong_GetZero(); 41997db96d56Sopenharmony_ci } 42007db96d56Sopenharmony_ci Py_INCREF(long_cnt); 42017db96d56Sopenharmony_ci 42027db96d56Sopenharmony_ci /* If not specified, step defaults to 1 */ 42037db96d56Sopenharmony_ci if (long_step == NULL) { 42047db96d56Sopenharmony_ci long_step = _PyLong_GetOne(); 42057db96d56Sopenharmony_ci } 42067db96d56Sopenharmony_ci Py_INCREF(long_step); 42077db96d56Sopenharmony_ci 42087db96d56Sopenharmony_ci assert(long_cnt != NULL && long_step != NULL); 42097db96d56Sopenharmony_ci 42107db96d56Sopenharmony_ci /* Fast mode only works when the step is 1 */ 42117db96d56Sopenharmony_ci if (fast_mode) { 42127db96d56Sopenharmony_ci assert(PyLong_Check(long_step)); 42137db96d56Sopenharmony_ci step = PyLong_AsLong(long_step); 42147db96d56Sopenharmony_ci if (step != 1) { 42157db96d56Sopenharmony_ci fast_mode = 0; 42167db96d56Sopenharmony_ci if (step == -1 && PyErr_Occurred()) 42177db96d56Sopenharmony_ci PyErr_Clear(); 42187db96d56Sopenharmony_ci } 42197db96d56Sopenharmony_ci } 42207db96d56Sopenharmony_ci 42217db96d56Sopenharmony_ci if (fast_mode) 42227db96d56Sopenharmony_ci Py_CLEAR(long_cnt); 42237db96d56Sopenharmony_ci else 42247db96d56Sopenharmony_ci cnt = PY_SSIZE_T_MAX; 42257db96d56Sopenharmony_ci 42267db96d56Sopenharmony_ci assert((cnt != PY_SSIZE_T_MAX && long_cnt == NULL && fast_mode) || 42277db96d56Sopenharmony_ci (cnt == PY_SSIZE_T_MAX && long_cnt != NULL && !fast_mode)); 42287db96d56Sopenharmony_ci assert(!fast_mode || 42297db96d56Sopenharmony_ci (PyLong_Check(long_step) && PyLong_AS_LONG(long_step) == 1)); 42307db96d56Sopenharmony_ci 42317db96d56Sopenharmony_ci /* create countobject structure */ 42327db96d56Sopenharmony_ci lz = (countobject *)type->tp_alloc(type, 0); 42337db96d56Sopenharmony_ci if (lz == NULL) { 42347db96d56Sopenharmony_ci Py_XDECREF(long_cnt); 42357db96d56Sopenharmony_ci Py_DECREF(long_step); 42367db96d56Sopenharmony_ci return NULL; 42377db96d56Sopenharmony_ci } 42387db96d56Sopenharmony_ci lz->cnt = cnt; 42397db96d56Sopenharmony_ci lz->long_cnt = long_cnt; 42407db96d56Sopenharmony_ci lz->long_step = long_step; 42417db96d56Sopenharmony_ci 42427db96d56Sopenharmony_ci return (PyObject *)lz; 42437db96d56Sopenharmony_ci} 42447db96d56Sopenharmony_ci 42457db96d56Sopenharmony_cistatic void 42467db96d56Sopenharmony_cicount_dealloc(countobject *lz) 42477db96d56Sopenharmony_ci{ 42487db96d56Sopenharmony_ci PyObject_GC_UnTrack(lz); 42497db96d56Sopenharmony_ci Py_XDECREF(lz->long_cnt); 42507db96d56Sopenharmony_ci Py_XDECREF(lz->long_step); 42517db96d56Sopenharmony_ci Py_TYPE(lz)->tp_free(lz); 42527db96d56Sopenharmony_ci} 42537db96d56Sopenharmony_ci 42547db96d56Sopenharmony_cistatic int 42557db96d56Sopenharmony_cicount_traverse(countobject *lz, visitproc visit, void *arg) 42567db96d56Sopenharmony_ci{ 42577db96d56Sopenharmony_ci Py_VISIT(lz->long_cnt); 42587db96d56Sopenharmony_ci Py_VISIT(lz->long_step); 42597db96d56Sopenharmony_ci return 0; 42607db96d56Sopenharmony_ci} 42617db96d56Sopenharmony_ci 42627db96d56Sopenharmony_cistatic PyObject * 42637db96d56Sopenharmony_cicount_nextlong(countobject *lz) 42647db96d56Sopenharmony_ci{ 42657db96d56Sopenharmony_ci PyObject *long_cnt; 42667db96d56Sopenharmony_ci PyObject *stepped_up; 42677db96d56Sopenharmony_ci 42687db96d56Sopenharmony_ci long_cnt = lz->long_cnt; 42697db96d56Sopenharmony_ci if (long_cnt == NULL) { 42707db96d56Sopenharmony_ci /* Switch to slow_mode */ 42717db96d56Sopenharmony_ci long_cnt = PyLong_FromSsize_t(PY_SSIZE_T_MAX); 42727db96d56Sopenharmony_ci if (long_cnt == NULL) 42737db96d56Sopenharmony_ci return NULL; 42747db96d56Sopenharmony_ci } 42757db96d56Sopenharmony_ci assert(lz->cnt == PY_SSIZE_T_MAX && long_cnt != NULL); 42767db96d56Sopenharmony_ci 42777db96d56Sopenharmony_ci stepped_up = PyNumber_Add(long_cnt, lz->long_step); 42787db96d56Sopenharmony_ci if (stepped_up == NULL) 42797db96d56Sopenharmony_ci return NULL; 42807db96d56Sopenharmony_ci lz->long_cnt = stepped_up; 42817db96d56Sopenharmony_ci return long_cnt; 42827db96d56Sopenharmony_ci} 42837db96d56Sopenharmony_ci 42847db96d56Sopenharmony_cistatic PyObject * 42857db96d56Sopenharmony_cicount_next(countobject *lz) 42867db96d56Sopenharmony_ci{ 42877db96d56Sopenharmony_ci if (lz->cnt == PY_SSIZE_T_MAX) 42887db96d56Sopenharmony_ci return count_nextlong(lz); 42897db96d56Sopenharmony_ci return PyLong_FromSsize_t(lz->cnt++); 42907db96d56Sopenharmony_ci} 42917db96d56Sopenharmony_ci 42927db96d56Sopenharmony_cistatic PyObject * 42937db96d56Sopenharmony_cicount_repr(countobject *lz) 42947db96d56Sopenharmony_ci{ 42957db96d56Sopenharmony_ci if (lz->cnt != PY_SSIZE_T_MAX) 42967db96d56Sopenharmony_ci return PyUnicode_FromFormat("%s(%zd)", 42977db96d56Sopenharmony_ci _PyType_Name(Py_TYPE(lz)), lz->cnt); 42987db96d56Sopenharmony_ci 42997db96d56Sopenharmony_ci if (PyLong_Check(lz->long_step)) { 43007db96d56Sopenharmony_ci long step = PyLong_AsLong(lz->long_step); 43017db96d56Sopenharmony_ci if (step == -1 && PyErr_Occurred()) { 43027db96d56Sopenharmony_ci PyErr_Clear(); 43037db96d56Sopenharmony_ci } 43047db96d56Sopenharmony_ci if (step == 1) { 43057db96d56Sopenharmony_ci /* Don't display step when it is an integer equal to 1 */ 43067db96d56Sopenharmony_ci return PyUnicode_FromFormat("%s(%R)", 43077db96d56Sopenharmony_ci _PyType_Name(Py_TYPE(lz)), 43087db96d56Sopenharmony_ci lz->long_cnt); 43097db96d56Sopenharmony_ci } 43107db96d56Sopenharmony_ci } 43117db96d56Sopenharmony_ci return PyUnicode_FromFormat("%s(%R, %R)", 43127db96d56Sopenharmony_ci _PyType_Name(Py_TYPE(lz)), 43137db96d56Sopenharmony_ci lz->long_cnt, lz->long_step); 43147db96d56Sopenharmony_ci} 43157db96d56Sopenharmony_ci 43167db96d56Sopenharmony_cistatic PyObject * 43177db96d56Sopenharmony_cicount_reduce(countobject *lz, PyObject *Py_UNUSED(ignored)) 43187db96d56Sopenharmony_ci{ 43197db96d56Sopenharmony_ci if (lz->cnt == PY_SSIZE_T_MAX) 43207db96d56Sopenharmony_ci return Py_BuildValue("O(OO)", Py_TYPE(lz), lz->long_cnt, lz->long_step); 43217db96d56Sopenharmony_ci return Py_BuildValue("O(n)", Py_TYPE(lz), lz->cnt); 43227db96d56Sopenharmony_ci} 43237db96d56Sopenharmony_ci 43247db96d56Sopenharmony_cistatic PyMethodDef count_methods[] = { 43257db96d56Sopenharmony_ci {"__reduce__", (PyCFunction)count_reduce, METH_NOARGS, 43267db96d56Sopenharmony_ci reduce_doc}, 43277db96d56Sopenharmony_ci {NULL, NULL} /* sentinel */ 43287db96d56Sopenharmony_ci}; 43297db96d56Sopenharmony_ci 43307db96d56Sopenharmony_cistatic PyTypeObject count_type = { 43317db96d56Sopenharmony_ci PyVarObject_HEAD_INIT(NULL, 0) 43327db96d56Sopenharmony_ci "itertools.count", /* tp_name */ 43337db96d56Sopenharmony_ci sizeof(countobject), /* tp_basicsize */ 43347db96d56Sopenharmony_ci 0, /* tp_itemsize */ 43357db96d56Sopenharmony_ci /* methods */ 43367db96d56Sopenharmony_ci (destructor)count_dealloc, /* tp_dealloc */ 43377db96d56Sopenharmony_ci 0, /* tp_vectorcall_offset */ 43387db96d56Sopenharmony_ci 0, /* tp_getattr */ 43397db96d56Sopenharmony_ci 0, /* tp_setattr */ 43407db96d56Sopenharmony_ci 0, /* tp_as_async */ 43417db96d56Sopenharmony_ci (reprfunc)count_repr, /* tp_repr */ 43427db96d56Sopenharmony_ci 0, /* tp_as_number */ 43437db96d56Sopenharmony_ci 0, /* tp_as_sequence */ 43447db96d56Sopenharmony_ci 0, /* tp_as_mapping */ 43457db96d56Sopenharmony_ci 0, /* tp_hash */ 43467db96d56Sopenharmony_ci 0, /* tp_call */ 43477db96d56Sopenharmony_ci 0, /* tp_str */ 43487db96d56Sopenharmony_ci PyObject_GenericGetAttr, /* tp_getattro */ 43497db96d56Sopenharmony_ci 0, /* tp_setattro */ 43507db96d56Sopenharmony_ci 0, /* tp_as_buffer */ 43517db96d56Sopenharmony_ci Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | 43527db96d56Sopenharmony_ci Py_TPFLAGS_BASETYPE, /* tp_flags */ 43537db96d56Sopenharmony_ci itertools_count__doc__, /* tp_doc */ 43547db96d56Sopenharmony_ci (traverseproc)count_traverse, /* tp_traverse */ 43557db96d56Sopenharmony_ci 0, /* tp_clear */ 43567db96d56Sopenharmony_ci 0, /* tp_richcompare */ 43577db96d56Sopenharmony_ci 0, /* tp_weaklistoffset */ 43587db96d56Sopenharmony_ci PyObject_SelfIter, /* tp_iter */ 43597db96d56Sopenharmony_ci (iternextfunc)count_next, /* tp_iternext */ 43607db96d56Sopenharmony_ci count_methods, /* tp_methods */ 43617db96d56Sopenharmony_ci 0, /* tp_members */ 43627db96d56Sopenharmony_ci 0, /* tp_getset */ 43637db96d56Sopenharmony_ci 0, /* tp_base */ 43647db96d56Sopenharmony_ci 0, /* tp_dict */ 43657db96d56Sopenharmony_ci 0, /* tp_descr_get */ 43667db96d56Sopenharmony_ci 0, /* tp_descr_set */ 43677db96d56Sopenharmony_ci 0, /* tp_dictoffset */ 43687db96d56Sopenharmony_ci 0, /* tp_init */ 43697db96d56Sopenharmony_ci 0, /* tp_alloc */ 43707db96d56Sopenharmony_ci itertools_count, /* tp_new */ 43717db96d56Sopenharmony_ci PyObject_GC_Del, /* tp_free */ 43727db96d56Sopenharmony_ci}; 43737db96d56Sopenharmony_ci 43747db96d56Sopenharmony_ci 43757db96d56Sopenharmony_ci/* repeat object ************************************************************/ 43767db96d56Sopenharmony_ci 43777db96d56Sopenharmony_citypedef struct { 43787db96d56Sopenharmony_ci PyObject_HEAD 43797db96d56Sopenharmony_ci PyObject *element; 43807db96d56Sopenharmony_ci Py_ssize_t cnt; 43817db96d56Sopenharmony_ci} repeatobject; 43827db96d56Sopenharmony_ci 43837db96d56Sopenharmony_cistatic PyTypeObject repeat_type; 43847db96d56Sopenharmony_ci 43857db96d56Sopenharmony_cistatic PyObject * 43867db96d56Sopenharmony_cirepeat_new(PyTypeObject *type, PyObject *args, PyObject *kwds) 43877db96d56Sopenharmony_ci{ 43887db96d56Sopenharmony_ci repeatobject *ro; 43897db96d56Sopenharmony_ci PyObject *element; 43907db96d56Sopenharmony_ci Py_ssize_t cnt = -1, n_args; 43917db96d56Sopenharmony_ci static char *kwargs[] = {"object", "times", NULL}; 43927db96d56Sopenharmony_ci 43937db96d56Sopenharmony_ci n_args = PyTuple_GET_SIZE(args); 43947db96d56Sopenharmony_ci if (kwds != NULL) 43957db96d56Sopenharmony_ci n_args += PyDict_GET_SIZE(kwds); 43967db96d56Sopenharmony_ci if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|n:repeat", kwargs, 43977db96d56Sopenharmony_ci &element, &cnt)) 43987db96d56Sopenharmony_ci return NULL; 43997db96d56Sopenharmony_ci /* Does user supply times argument? */ 44007db96d56Sopenharmony_ci if (n_args == 2 && cnt < 0) 44017db96d56Sopenharmony_ci cnt = 0; 44027db96d56Sopenharmony_ci 44037db96d56Sopenharmony_ci ro = (repeatobject *)type->tp_alloc(type, 0); 44047db96d56Sopenharmony_ci if (ro == NULL) 44057db96d56Sopenharmony_ci return NULL; 44067db96d56Sopenharmony_ci Py_INCREF(element); 44077db96d56Sopenharmony_ci ro->element = element; 44087db96d56Sopenharmony_ci ro->cnt = cnt; 44097db96d56Sopenharmony_ci return (PyObject *)ro; 44107db96d56Sopenharmony_ci} 44117db96d56Sopenharmony_ci 44127db96d56Sopenharmony_cistatic void 44137db96d56Sopenharmony_cirepeat_dealloc(repeatobject *ro) 44147db96d56Sopenharmony_ci{ 44157db96d56Sopenharmony_ci PyObject_GC_UnTrack(ro); 44167db96d56Sopenharmony_ci Py_XDECREF(ro->element); 44177db96d56Sopenharmony_ci Py_TYPE(ro)->tp_free(ro); 44187db96d56Sopenharmony_ci} 44197db96d56Sopenharmony_ci 44207db96d56Sopenharmony_cistatic int 44217db96d56Sopenharmony_cirepeat_traverse(repeatobject *ro, visitproc visit, void *arg) 44227db96d56Sopenharmony_ci{ 44237db96d56Sopenharmony_ci Py_VISIT(ro->element); 44247db96d56Sopenharmony_ci return 0; 44257db96d56Sopenharmony_ci} 44267db96d56Sopenharmony_ci 44277db96d56Sopenharmony_cistatic PyObject * 44287db96d56Sopenharmony_cirepeat_next(repeatobject *ro) 44297db96d56Sopenharmony_ci{ 44307db96d56Sopenharmony_ci if (ro->cnt == 0) 44317db96d56Sopenharmony_ci return NULL; 44327db96d56Sopenharmony_ci if (ro->cnt > 0) 44337db96d56Sopenharmony_ci ro->cnt--; 44347db96d56Sopenharmony_ci Py_INCREF(ro->element); 44357db96d56Sopenharmony_ci return ro->element; 44367db96d56Sopenharmony_ci} 44377db96d56Sopenharmony_ci 44387db96d56Sopenharmony_cistatic PyObject * 44397db96d56Sopenharmony_cirepeat_repr(repeatobject *ro) 44407db96d56Sopenharmony_ci{ 44417db96d56Sopenharmony_ci if (ro->cnt == -1) 44427db96d56Sopenharmony_ci return PyUnicode_FromFormat("%s(%R)", 44437db96d56Sopenharmony_ci _PyType_Name(Py_TYPE(ro)), ro->element); 44447db96d56Sopenharmony_ci else 44457db96d56Sopenharmony_ci return PyUnicode_FromFormat("%s(%R, %zd)", 44467db96d56Sopenharmony_ci _PyType_Name(Py_TYPE(ro)), ro->element, 44477db96d56Sopenharmony_ci ro->cnt); 44487db96d56Sopenharmony_ci} 44497db96d56Sopenharmony_ci 44507db96d56Sopenharmony_cistatic PyObject * 44517db96d56Sopenharmony_cirepeat_len(repeatobject *ro, PyObject *Py_UNUSED(ignored)) 44527db96d56Sopenharmony_ci{ 44537db96d56Sopenharmony_ci if (ro->cnt == -1) { 44547db96d56Sopenharmony_ci PyErr_SetString(PyExc_TypeError, "len() of unsized object"); 44557db96d56Sopenharmony_ci return NULL; 44567db96d56Sopenharmony_ci } 44577db96d56Sopenharmony_ci return PyLong_FromSize_t(ro->cnt); 44587db96d56Sopenharmony_ci} 44597db96d56Sopenharmony_ci 44607db96d56Sopenharmony_ciPyDoc_STRVAR(length_hint_doc, "Private method returning an estimate of len(list(it))."); 44617db96d56Sopenharmony_ci 44627db96d56Sopenharmony_cistatic PyObject * 44637db96d56Sopenharmony_cirepeat_reduce(repeatobject *ro, PyObject *Py_UNUSED(ignored)) 44647db96d56Sopenharmony_ci{ 44657db96d56Sopenharmony_ci /* unpickle this so that a new repeat iterator is constructed with an 44667db96d56Sopenharmony_ci * object, then call __setstate__ on it to set cnt 44677db96d56Sopenharmony_ci */ 44687db96d56Sopenharmony_ci if (ro->cnt >= 0) 44697db96d56Sopenharmony_ci return Py_BuildValue("O(On)", Py_TYPE(ro), ro->element, ro->cnt); 44707db96d56Sopenharmony_ci else 44717db96d56Sopenharmony_ci return Py_BuildValue("O(O)", Py_TYPE(ro), ro->element); 44727db96d56Sopenharmony_ci} 44737db96d56Sopenharmony_ci 44747db96d56Sopenharmony_cistatic PyMethodDef repeat_methods[] = { 44757db96d56Sopenharmony_ci {"__length_hint__", (PyCFunction)repeat_len, METH_NOARGS, length_hint_doc}, 44767db96d56Sopenharmony_ci {"__reduce__", (PyCFunction)repeat_reduce, METH_NOARGS, reduce_doc}, 44777db96d56Sopenharmony_ci {NULL, NULL} /* sentinel */ 44787db96d56Sopenharmony_ci}; 44797db96d56Sopenharmony_ci 44807db96d56Sopenharmony_ciPyDoc_STRVAR(repeat_doc, 44817db96d56Sopenharmony_ci"repeat(object [,times]) -> create an iterator which returns the object\n\ 44827db96d56Sopenharmony_cifor the specified number of times. If not specified, returns the object\n\ 44837db96d56Sopenharmony_ciendlessly."); 44847db96d56Sopenharmony_ci 44857db96d56Sopenharmony_cistatic PyTypeObject repeat_type = { 44867db96d56Sopenharmony_ci PyVarObject_HEAD_INIT(NULL, 0) 44877db96d56Sopenharmony_ci "itertools.repeat", /* tp_name */ 44887db96d56Sopenharmony_ci sizeof(repeatobject), /* tp_basicsize */ 44897db96d56Sopenharmony_ci 0, /* tp_itemsize */ 44907db96d56Sopenharmony_ci /* methods */ 44917db96d56Sopenharmony_ci (destructor)repeat_dealloc, /* tp_dealloc */ 44927db96d56Sopenharmony_ci 0, /* tp_vectorcall_offset */ 44937db96d56Sopenharmony_ci 0, /* tp_getattr */ 44947db96d56Sopenharmony_ci 0, /* tp_setattr */ 44957db96d56Sopenharmony_ci 0, /* tp_as_async */ 44967db96d56Sopenharmony_ci (reprfunc)repeat_repr, /* tp_repr */ 44977db96d56Sopenharmony_ci 0, /* tp_as_number */ 44987db96d56Sopenharmony_ci 0, /* tp_as_sequence */ 44997db96d56Sopenharmony_ci 0, /* tp_as_mapping */ 45007db96d56Sopenharmony_ci 0, /* tp_hash */ 45017db96d56Sopenharmony_ci 0, /* tp_call */ 45027db96d56Sopenharmony_ci 0, /* tp_str */ 45037db96d56Sopenharmony_ci PyObject_GenericGetAttr, /* tp_getattro */ 45047db96d56Sopenharmony_ci 0, /* tp_setattro */ 45057db96d56Sopenharmony_ci 0, /* tp_as_buffer */ 45067db96d56Sopenharmony_ci Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | 45077db96d56Sopenharmony_ci Py_TPFLAGS_BASETYPE, /* tp_flags */ 45087db96d56Sopenharmony_ci repeat_doc, /* tp_doc */ 45097db96d56Sopenharmony_ci (traverseproc)repeat_traverse, /* tp_traverse */ 45107db96d56Sopenharmony_ci 0, /* tp_clear */ 45117db96d56Sopenharmony_ci 0, /* tp_richcompare */ 45127db96d56Sopenharmony_ci 0, /* tp_weaklistoffset */ 45137db96d56Sopenharmony_ci PyObject_SelfIter, /* tp_iter */ 45147db96d56Sopenharmony_ci (iternextfunc)repeat_next, /* tp_iternext */ 45157db96d56Sopenharmony_ci repeat_methods, /* tp_methods */ 45167db96d56Sopenharmony_ci 0, /* tp_members */ 45177db96d56Sopenharmony_ci 0, /* tp_getset */ 45187db96d56Sopenharmony_ci 0, /* tp_base */ 45197db96d56Sopenharmony_ci 0, /* tp_dict */ 45207db96d56Sopenharmony_ci 0, /* tp_descr_get */ 45217db96d56Sopenharmony_ci 0, /* tp_descr_set */ 45227db96d56Sopenharmony_ci 0, /* tp_dictoffset */ 45237db96d56Sopenharmony_ci 0, /* tp_init */ 45247db96d56Sopenharmony_ci 0, /* tp_alloc */ 45257db96d56Sopenharmony_ci repeat_new, /* tp_new */ 45267db96d56Sopenharmony_ci PyObject_GC_Del, /* tp_free */ 45277db96d56Sopenharmony_ci}; 45287db96d56Sopenharmony_ci 45297db96d56Sopenharmony_ci 45307db96d56Sopenharmony_ci/* ziplongest object *********************************************************/ 45317db96d56Sopenharmony_ci 45327db96d56Sopenharmony_citypedef struct { 45337db96d56Sopenharmony_ci PyObject_HEAD 45347db96d56Sopenharmony_ci Py_ssize_t tuplesize; 45357db96d56Sopenharmony_ci Py_ssize_t numactive; 45367db96d56Sopenharmony_ci PyObject *ittuple; /* tuple of iterators */ 45377db96d56Sopenharmony_ci PyObject *result; 45387db96d56Sopenharmony_ci PyObject *fillvalue; 45397db96d56Sopenharmony_ci} ziplongestobject; 45407db96d56Sopenharmony_ci 45417db96d56Sopenharmony_cistatic PyTypeObject ziplongest_type; 45427db96d56Sopenharmony_ci 45437db96d56Sopenharmony_cistatic PyObject * 45447db96d56Sopenharmony_cizip_longest_new(PyTypeObject *type, PyObject *args, PyObject *kwds) 45457db96d56Sopenharmony_ci{ 45467db96d56Sopenharmony_ci ziplongestobject *lz; 45477db96d56Sopenharmony_ci Py_ssize_t i; 45487db96d56Sopenharmony_ci PyObject *ittuple; /* tuple of iterators */ 45497db96d56Sopenharmony_ci PyObject *result; 45507db96d56Sopenharmony_ci PyObject *fillvalue = Py_None; 45517db96d56Sopenharmony_ci Py_ssize_t tuplesize; 45527db96d56Sopenharmony_ci 45537db96d56Sopenharmony_ci if (kwds != NULL && PyDict_CheckExact(kwds) && PyDict_GET_SIZE(kwds) > 0) { 45547db96d56Sopenharmony_ci fillvalue = NULL; 45557db96d56Sopenharmony_ci if (PyDict_GET_SIZE(kwds) == 1) { 45567db96d56Sopenharmony_ci fillvalue = PyDict_GetItemWithError(kwds, &_Py_ID(fillvalue)); 45577db96d56Sopenharmony_ci } 45587db96d56Sopenharmony_ci if (fillvalue == NULL) { 45597db96d56Sopenharmony_ci if (!PyErr_Occurred()) { 45607db96d56Sopenharmony_ci PyErr_SetString(PyExc_TypeError, 45617db96d56Sopenharmony_ci "zip_longest() got an unexpected keyword argument"); 45627db96d56Sopenharmony_ci } 45637db96d56Sopenharmony_ci return NULL; 45647db96d56Sopenharmony_ci } 45657db96d56Sopenharmony_ci } 45667db96d56Sopenharmony_ci 45677db96d56Sopenharmony_ci /* args must be a tuple */ 45687db96d56Sopenharmony_ci assert(PyTuple_Check(args)); 45697db96d56Sopenharmony_ci tuplesize = PyTuple_GET_SIZE(args); 45707db96d56Sopenharmony_ci 45717db96d56Sopenharmony_ci /* obtain iterators */ 45727db96d56Sopenharmony_ci ittuple = PyTuple_New(tuplesize); 45737db96d56Sopenharmony_ci if (ittuple == NULL) 45747db96d56Sopenharmony_ci return NULL; 45757db96d56Sopenharmony_ci for (i=0; i < tuplesize; i++) { 45767db96d56Sopenharmony_ci PyObject *item = PyTuple_GET_ITEM(args, i); 45777db96d56Sopenharmony_ci PyObject *it = PyObject_GetIter(item); 45787db96d56Sopenharmony_ci if (it == NULL) { 45797db96d56Sopenharmony_ci Py_DECREF(ittuple); 45807db96d56Sopenharmony_ci return NULL; 45817db96d56Sopenharmony_ci } 45827db96d56Sopenharmony_ci PyTuple_SET_ITEM(ittuple, i, it); 45837db96d56Sopenharmony_ci } 45847db96d56Sopenharmony_ci 45857db96d56Sopenharmony_ci /* create a result holder */ 45867db96d56Sopenharmony_ci result = PyTuple_New(tuplesize); 45877db96d56Sopenharmony_ci if (result == NULL) { 45887db96d56Sopenharmony_ci Py_DECREF(ittuple); 45897db96d56Sopenharmony_ci return NULL; 45907db96d56Sopenharmony_ci } 45917db96d56Sopenharmony_ci for (i=0 ; i < tuplesize ; i++) { 45927db96d56Sopenharmony_ci Py_INCREF(Py_None); 45937db96d56Sopenharmony_ci PyTuple_SET_ITEM(result, i, Py_None); 45947db96d56Sopenharmony_ci } 45957db96d56Sopenharmony_ci 45967db96d56Sopenharmony_ci /* create ziplongestobject structure */ 45977db96d56Sopenharmony_ci lz = (ziplongestobject *)type->tp_alloc(type, 0); 45987db96d56Sopenharmony_ci if (lz == NULL) { 45997db96d56Sopenharmony_ci Py_DECREF(ittuple); 46007db96d56Sopenharmony_ci Py_DECREF(result); 46017db96d56Sopenharmony_ci return NULL; 46027db96d56Sopenharmony_ci } 46037db96d56Sopenharmony_ci lz->ittuple = ittuple; 46047db96d56Sopenharmony_ci lz->tuplesize = tuplesize; 46057db96d56Sopenharmony_ci lz->numactive = tuplesize; 46067db96d56Sopenharmony_ci lz->result = result; 46077db96d56Sopenharmony_ci Py_INCREF(fillvalue); 46087db96d56Sopenharmony_ci lz->fillvalue = fillvalue; 46097db96d56Sopenharmony_ci return (PyObject *)lz; 46107db96d56Sopenharmony_ci} 46117db96d56Sopenharmony_ci 46127db96d56Sopenharmony_cistatic void 46137db96d56Sopenharmony_cizip_longest_dealloc(ziplongestobject *lz) 46147db96d56Sopenharmony_ci{ 46157db96d56Sopenharmony_ci PyObject_GC_UnTrack(lz); 46167db96d56Sopenharmony_ci Py_XDECREF(lz->ittuple); 46177db96d56Sopenharmony_ci Py_XDECREF(lz->result); 46187db96d56Sopenharmony_ci Py_XDECREF(lz->fillvalue); 46197db96d56Sopenharmony_ci Py_TYPE(lz)->tp_free(lz); 46207db96d56Sopenharmony_ci} 46217db96d56Sopenharmony_ci 46227db96d56Sopenharmony_cistatic int 46237db96d56Sopenharmony_cizip_longest_traverse(ziplongestobject *lz, visitproc visit, void *arg) 46247db96d56Sopenharmony_ci{ 46257db96d56Sopenharmony_ci Py_VISIT(lz->ittuple); 46267db96d56Sopenharmony_ci Py_VISIT(lz->result); 46277db96d56Sopenharmony_ci Py_VISIT(lz->fillvalue); 46287db96d56Sopenharmony_ci return 0; 46297db96d56Sopenharmony_ci} 46307db96d56Sopenharmony_ci 46317db96d56Sopenharmony_cistatic PyObject * 46327db96d56Sopenharmony_cizip_longest_next(ziplongestobject *lz) 46337db96d56Sopenharmony_ci{ 46347db96d56Sopenharmony_ci Py_ssize_t i; 46357db96d56Sopenharmony_ci Py_ssize_t tuplesize = lz->tuplesize; 46367db96d56Sopenharmony_ci PyObject *result = lz->result; 46377db96d56Sopenharmony_ci PyObject *it; 46387db96d56Sopenharmony_ci PyObject *item; 46397db96d56Sopenharmony_ci PyObject *olditem; 46407db96d56Sopenharmony_ci 46417db96d56Sopenharmony_ci if (tuplesize == 0) 46427db96d56Sopenharmony_ci return NULL; 46437db96d56Sopenharmony_ci if (lz->numactive == 0) 46447db96d56Sopenharmony_ci return NULL; 46457db96d56Sopenharmony_ci if (Py_REFCNT(result) == 1) { 46467db96d56Sopenharmony_ci Py_INCREF(result); 46477db96d56Sopenharmony_ci for (i=0 ; i < tuplesize ; i++) { 46487db96d56Sopenharmony_ci it = PyTuple_GET_ITEM(lz->ittuple, i); 46497db96d56Sopenharmony_ci if (it == NULL) { 46507db96d56Sopenharmony_ci Py_INCREF(lz->fillvalue); 46517db96d56Sopenharmony_ci item = lz->fillvalue; 46527db96d56Sopenharmony_ci } else { 46537db96d56Sopenharmony_ci item = PyIter_Next(it); 46547db96d56Sopenharmony_ci if (item == NULL) { 46557db96d56Sopenharmony_ci lz->numactive -= 1; 46567db96d56Sopenharmony_ci if (lz->numactive == 0 || PyErr_Occurred()) { 46577db96d56Sopenharmony_ci lz->numactive = 0; 46587db96d56Sopenharmony_ci Py_DECREF(result); 46597db96d56Sopenharmony_ci return NULL; 46607db96d56Sopenharmony_ci } else { 46617db96d56Sopenharmony_ci Py_INCREF(lz->fillvalue); 46627db96d56Sopenharmony_ci item = lz->fillvalue; 46637db96d56Sopenharmony_ci PyTuple_SET_ITEM(lz->ittuple, i, NULL); 46647db96d56Sopenharmony_ci Py_DECREF(it); 46657db96d56Sopenharmony_ci } 46667db96d56Sopenharmony_ci } 46677db96d56Sopenharmony_ci } 46687db96d56Sopenharmony_ci olditem = PyTuple_GET_ITEM(result, i); 46697db96d56Sopenharmony_ci PyTuple_SET_ITEM(result, i, item); 46707db96d56Sopenharmony_ci Py_DECREF(olditem); 46717db96d56Sopenharmony_ci } 46727db96d56Sopenharmony_ci // bpo-42536: The GC may have untracked this result tuple. Since we're 46737db96d56Sopenharmony_ci // recycling it, make sure it's tracked again: 46747db96d56Sopenharmony_ci if (!_PyObject_GC_IS_TRACKED(result)) { 46757db96d56Sopenharmony_ci _PyObject_GC_TRACK(result); 46767db96d56Sopenharmony_ci } 46777db96d56Sopenharmony_ci } else { 46787db96d56Sopenharmony_ci result = PyTuple_New(tuplesize); 46797db96d56Sopenharmony_ci if (result == NULL) 46807db96d56Sopenharmony_ci return NULL; 46817db96d56Sopenharmony_ci for (i=0 ; i < tuplesize ; i++) { 46827db96d56Sopenharmony_ci it = PyTuple_GET_ITEM(lz->ittuple, i); 46837db96d56Sopenharmony_ci if (it == NULL) { 46847db96d56Sopenharmony_ci Py_INCREF(lz->fillvalue); 46857db96d56Sopenharmony_ci item = lz->fillvalue; 46867db96d56Sopenharmony_ci } else { 46877db96d56Sopenharmony_ci item = PyIter_Next(it); 46887db96d56Sopenharmony_ci if (item == NULL) { 46897db96d56Sopenharmony_ci lz->numactive -= 1; 46907db96d56Sopenharmony_ci if (lz->numactive == 0 || PyErr_Occurred()) { 46917db96d56Sopenharmony_ci lz->numactive = 0; 46927db96d56Sopenharmony_ci Py_DECREF(result); 46937db96d56Sopenharmony_ci return NULL; 46947db96d56Sopenharmony_ci } else { 46957db96d56Sopenharmony_ci Py_INCREF(lz->fillvalue); 46967db96d56Sopenharmony_ci item = lz->fillvalue; 46977db96d56Sopenharmony_ci PyTuple_SET_ITEM(lz->ittuple, i, NULL); 46987db96d56Sopenharmony_ci Py_DECREF(it); 46997db96d56Sopenharmony_ci } 47007db96d56Sopenharmony_ci } 47017db96d56Sopenharmony_ci } 47027db96d56Sopenharmony_ci PyTuple_SET_ITEM(result, i, item); 47037db96d56Sopenharmony_ci } 47047db96d56Sopenharmony_ci } 47057db96d56Sopenharmony_ci return result; 47067db96d56Sopenharmony_ci} 47077db96d56Sopenharmony_ci 47087db96d56Sopenharmony_cistatic PyObject * 47097db96d56Sopenharmony_cizip_longest_reduce(ziplongestobject *lz, PyObject *Py_UNUSED(ignored)) 47107db96d56Sopenharmony_ci{ 47117db96d56Sopenharmony_ci 47127db96d56Sopenharmony_ci /* Create a new tuple with empty sequences where appropriate to pickle. 47137db96d56Sopenharmony_ci * Then use setstate to set the fillvalue 47147db96d56Sopenharmony_ci */ 47157db96d56Sopenharmony_ci int i; 47167db96d56Sopenharmony_ci PyObject *args = PyTuple_New(PyTuple_GET_SIZE(lz->ittuple)); 47177db96d56Sopenharmony_ci 47187db96d56Sopenharmony_ci if (args == NULL) 47197db96d56Sopenharmony_ci return NULL; 47207db96d56Sopenharmony_ci for (i=0; i<PyTuple_GET_SIZE(lz->ittuple); i++) { 47217db96d56Sopenharmony_ci PyObject *elem = PyTuple_GET_ITEM(lz->ittuple, i); 47227db96d56Sopenharmony_ci if (elem == NULL) { 47237db96d56Sopenharmony_ci elem = PyTuple_New(0); 47247db96d56Sopenharmony_ci if (elem == NULL) { 47257db96d56Sopenharmony_ci Py_DECREF(args); 47267db96d56Sopenharmony_ci return NULL; 47277db96d56Sopenharmony_ci } 47287db96d56Sopenharmony_ci } else 47297db96d56Sopenharmony_ci Py_INCREF(elem); 47307db96d56Sopenharmony_ci PyTuple_SET_ITEM(args, i, elem); 47317db96d56Sopenharmony_ci } 47327db96d56Sopenharmony_ci return Py_BuildValue("ONO", Py_TYPE(lz), args, lz->fillvalue); 47337db96d56Sopenharmony_ci} 47347db96d56Sopenharmony_ci 47357db96d56Sopenharmony_cistatic PyObject * 47367db96d56Sopenharmony_cizip_longest_setstate(ziplongestobject *lz, PyObject *state) 47377db96d56Sopenharmony_ci{ 47387db96d56Sopenharmony_ci Py_INCREF(state); 47397db96d56Sopenharmony_ci Py_XSETREF(lz->fillvalue, state); 47407db96d56Sopenharmony_ci Py_RETURN_NONE; 47417db96d56Sopenharmony_ci} 47427db96d56Sopenharmony_ci 47437db96d56Sopenharmony_cistatic PyMethodDef zip_longest_methods[] = { 47447db96d56Sopenharmony_ci {"__reduce__", (PyCFunction)zip_longest_reduce, METH_NOARGS, 47457db96d56Sopenharmony_ci reduce_doc}, 47467db96d56Sopenharmony_ci {"__setstate__", (PyCFunction)zip_longest_setstate, METH_O, 47477db96d56Sopenharmony_ci setstate_doc}, 47487db96d56Sopenharmony_ci {NULL, NULL} /* sentinel */ 47497db96d56Sopenharmony_ci}; 47507db96d56Sopenharmony_ci 47517db96d56Sopenharmony_ciPyDoc_STRVAR(zip_longest_doc, 47527db96d56Sopenharmony_ci"zip_longest(iter1 [,iter2 [...]], [fillvalue=None]) --> zip_longest object\n\ 47537db96d56Sopenharmony_ci\n\ 47547db96d56Sopenharmony_ciReturn a zip_longest object whose .__next__() method returns a tuple where\n\ 47557db96d56Sopenharmony_cithe i-th element comes from the i-th iterable argument. The .__next__()\n\ 47567db96d56Sopenharmony_cimethod continues until the longest iterable in the argument sequence\n\ 47577db96d56Sopenharmony_ciis exhausted and then it raises StopIteration. When the shorter iterables\n\ 47587db96d56Sopenharmony_ciare exhausted, the fillvalue is substituted in their place. The fillvalue\n\ 47597db96d56Sopenharmony_cidefaults to None or can be specified by a keyword argument.\n\ 47607db96d56Sopenharmony_ci"); 47617db96d56Sopenharmony_ci 47627db96d56Sopenharmony_cistatic PyTypeObject ziplongest_type = { 47637db96d56Sopenharmony_ci PyVarObject_HEAD_INIT(NULL, 0) 47647db96d56Sopenharmony_ci "itertools.zip_longest", /* tp_name */ 47657db96d56Sopenharmony_ci sizeof(ziplongestobject), /* tp_basicsize */ 47667db96d56Sopenharmony_ci 0, /* tp_itemsize */ 47677db96d56Sopenharmony_ci /* methods */ 47687db96d56Sopenharmony_ci (destructor)zip_longest_dealloc, /* tp_dealloc */ 47697db96d56Sopenharmony_ci 0, /* tp_vectorcall_offset */ 47707db96d56Sopenharmony_ci 0, /* tp_getattr */ 47717db96d56Sopenharmony_ci 0, /* tp_setattr */ 47727db96d56Sopenharmony_ci 0, /* tp_as_async */ 47737db96d56Sopenharmony_ci 0, /* tp_repr */ 47747db96d56Sopenharmony_ci 0, /* tp_as_number */ 47757db96d56Sopenharmony_ci 0, /* tp_as_sequence */ 47767db96d56Sopenharmony_ci 0, /* tp_as_mapping */ 47777db96d56Sopenharmony_ci 0, /* tp_hash */ 47787db96d56Sopenharmony_ci 0, /* tp_call */ 47797db96d56Sopenharmony_ci 0, /* tp_str */ 47807db96d56Sopenharmony_ci PyObject_GenericGetAttr, /* tp_getattro */ 47817db96d56Sopenharmony_ci 0, /* tp_setattro */ 47827db96d56Sopenharmony_ci 0, /* tp_as_buffer */ 47837db96d56Sopenharmony_ci Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | 47847db96d56Sopenharmony_ci Py_TPFLAGS_BASETYPE, /* tp_flags */ 47857db96d56Sopenharmony_ci zip_longest_doc, /* tp_doc */ 47867db96d56Sopenharmony_ci (traverseproc)zip_longest_traverse, /* tp_traverse */ 47877db96d56Sopenharmony_ci 0, /* tp_clear */ 47887db96d56Sopenharmony_ci 0, /* tp_richcompare */ 47897db96d56Sopenharmony_ci 0, /* tp_weaklistoffset */ 47907db96d56Sopenharmony_ci PyObject_SelfIter, /* tp_iter */ 47917db96d56Sopenharmony_ci (iternextfunc)zip_longest_next, /* tp_iternext */ 47927db96d56Sopenharmony_ci zip_longest_methods, /* tp_methods */ 47937db96d56Sopenharmony_ci 0, /* tp_members */ 47947db96d56Sopenharmony_ci 0, /* tp_getset */ 47957db96d56Sopenharmony_ci 0, /* tp_base */ 47967db96d56Sopenharmony_ci 0, /* tp_dict */ 47977db96d56Sopenharmony_ci 0, /* tp_descr_get */ 47987db96d56Sopenharmony_ci 0, /* tp_descr_set */ 47997db96d56Sopenharmony_ci 0, /* tp_dictoffset */ 48007db96d56Sopenharmony_ci 0, /* tp_init */ 48017db96d56Sopenharmony_ci 0, /* tp_alloc */ 48027db96d56Sopenharmony_ci zip_longest_new, /* tp_new */ 48037db96d56Sopenharmony_ci PyObject_GC_Del, /* tp_free */ 48047db96d56Sopenharmony_ci}; 48057db96d56Sopenharmony_ci 48067db96d56Sopenharmony_ci 48077db96d56Sopenharmony_ci/* module level code ********************************************************/ 48087db96d56Sopenharmony_ci 48097db96d56Sopenharmony_ciPyDoc_STRVAR(module_doc, 48107db96d56Sopenharmony_ci"Functional tools for creating and using iterators.\n\ 48117db96d56Sopenharmony_ci\n\ 48127db96d56Sopenharmony_ciInfinite iterators:\n\ 48137db96d56Sopenharmony_cicount(start=0, step=1) --> start, start+step, start+2*step, ...\n\ 48147db96d56Sopenharmony_cicycle(p) --> p0, p1, ... plast, p0, p1, ...\n\ 48157db96d56Sopenharmony_cirepeat(elem [,n]) --> elem, elem, elem, ... endlessly or up to n times\n\ 48167db96d56Sopenharmony_ci\n\ 48177db96d56Sopenharmony_ciIterators terminating on the shortest input sequence:\n\ 48187db96d56Sopenharmony_ciaccumulate(p[, func]) --> p0, p0+p1, p0+p1+p2\n\ 48197db96d56Sopenharmony_cichain(p, q, ...) --> p0, p1, ... plast, q0, q1, ...\n\ 48207db96d56Sopenharmony_cichain.from_iterable([p, q, ...]) --> p0, p1, ... plast, q0, q1, ...\n\ 48217db96d56Sopenharmony_cicompress(data, selectors) --> (d[0] if s[0]), (d[1] if s[1]), ...\n\ 48227db96d56Sopenharmony_cidropwhile(pred, seq) --> seq[n], seq[n+1], starting when pred fails\n\ 48237db96d56Sopenharmony_cigroupby(iterable[, keyfunc]) --> sub-iterators grouped by value of keyfunc(v)\n\ 48247db96d56Sopenharmony_cifilterfalse(pred, seq) --> elements of seq where pred(elem) is False\n\ 48257db96d56Sopenharmony_ciislice(seq, [start,] stop [, step]) --> elements from\n\ 48267db96d56Sopenharmony_ci seq[start:stop:step]\n\ 48277db96d56Sopenharmony_cipairwise(s) --> (s[0],s[1]), (s[1],s[2]), (s[2], s[3]), ...\n\ 48287db96d56Sopenharmony_cistarmap(fun, seq) --> fun(*seq[0]), fun(*seq[1]), ...\n\ 48297db96d56Sopenharmony_citee(it, n=2) --> (it1, it2 , ... itn) splits one iterator into n\n\ 48307db96d56Sopenharmony_citakewhile(pred, seq) --> seq[0], seq[1], until pred fails\n\ 48317db96d56Sopenharmony_cizip_longest(p, q, ...) --> (p[0], q[0]), (p[1], q[1]), ...\n\ 48327db96d56Sopenharmony_ci\n\ 48337db96d56Sopenharmony_ciCombinatoric generators:\n\ 48347db96d56Sopenharmony_ciproduct(p, q, ... [repeat=1]) --> cartesian product\n\ 48357db96d56Sopenharmony_cipermutations(p[, r])\n\ 48367db96d56Sopenharmony_cicombinations(p, r)\n\ 48377db96d56Sopenharmony_cicombinations_with_replacement(p, r)\n\ 48387db96d56Sopenharmony_ci"); 48397db96d56Sopenharmony_ci 48407db96d56Sopenharmony_cistatic int 48417db96d56Sopenharmony_ciitertoolsmodule_exec(PyObject *m) 48427db96d56Sopenharmony_ci{ 48437db96d56Sopenharmony_ci PyTypeObject *typelist[] = { 48447db96d56Sopenharmony_ci &accumulate_type, 48457db96d56Sopenharmony_ci &combinations_type, 48467db96d56Sopenharmony_ci &cwr_type, 48477db96d56Sopenharmony_ci &cycle_type, 48487db96d56Sopenharmony_ci &dropwhile_type, 48497db96d56Sopenharmony_ci &takewhile_type, 48507db96d56Sopenharmony_ci &islice_type, 48517db96d56Sopenharmony_ci &starmap_type, 48527db96d56Sopenharmony_ci &chain_type, 48537db96d56Sopenharmony_ci &compress_type, 48547db96d56Sopenharmony_ci &filterfalse_type, 48557db96d56Sopenharmony_ci &count_type, 48567db96d56Sopenharmony_ci &ziplongest_type, 48577db96d56Sopenharmony_ci &pairwise_type, 48587db96d56Sopenharmony_ci &permutations_type, 48597db96d56Sopenharmony_ci &product_type, 48607db96d56Sopenharmony_ci &repeat_type, 48617db96d56Sopenharmony_ci &groupby_type, 48627db96d56Sopenharmony_ci &_grouper_type, 48637db96d56Sopenharmony_ci &tee_type, 48647db96d56Sopenharmony_ci &teedataobject_type 48657db96d56Sopenharmony_ci }; 48667db96d56Sopenharmony_ci 48677db96d56Sopenharmony_ci Py_SET_TYPE(&teedataobject_type, &PyType_Type); 48687db96d56Sopenharmony_ci 48697db96d56Sopenharmony_ci for (size_t i = 0; i < Py_ARRAY_LENGTH(typelist); i++) { 48707db96d56Sopenharmony_ci if (PyModule_AddType(m, typelist[i]) < 0) { 48717db96d56Sopenharmony_ci return -1; 48727db96d56Sopenharmony_ci } 48737db96d56Sopenharmony_ci } 48747db96d56Sopenharmony_ci 48757db96d56Sopenharmony_ci return 0; 48767db96d56Sopenharmony_ci} 48777db96d56Sopenharmony_ci 48787db96d56Sopenharmony_cistatic struct PyModuleDef_Slot itertoolsmodule_slots[] = { 48797db96d56Sopenharmony_ci {Py_mod_exec, itertoolsmodule_exec}, 48807db96d56Sopenharmony_ci {0, NULL} 48817db96d56Sopenharmony_ci}; 48827db96d56Sopenharmony_ci 48837db96d56Sopenharmony_cistatic PyMethodDef module_methods[] = { 48847db96d56Sopenharmony_ci ITERTOOLS_TEE_METHODDEF 48857db96d56Sopenharmony_ci {NULL, NULL} /* sentinel */ 48867db96d56Sopenharmony_ci}; 48877db96d56Sopenharmony_ci 48887db96d56Sopenharmony_ci 48897db96d56Sopenharmony_cistatic struct PyModuleDef itertoolsmodule = { 48907db96d56Sopenharmony_ci PyModuleDef_HEAD_INIT, 48917db96d56Sopenharmony_ci "itertools", 48927db96d56Sopenharmony_ci module_doc, 48937db96d56Sopenharmony_ci 0, 48947db96d56Sopenharmony_ci module_methods, 48957db96d56Sopenharmony_ci itertoolsmodule_slots, 48967db96d56Sopenharmony_ci NULL, 48977db96d56Sopenharmony_ci NULL, 48987db96d56Sopenharmony_ci NULL 48997db96d56Sopenharmony_ci}; 49007db96d56Sopenharmony_ci 49017db96d56Sopenharmony_ciPyMODINIT_FUNC 49027db96d56Sopenharmony_ciPyInit_itertools(void) 49037db96d56Sopenharmony_ci{ 49047db96d56Sopenharmony_ci return PyModuleDef_Init(&itertoolsmodule); 49057db96d56Sopenharmony_ci} 4906