| /* enumerate object */ |
| |
| #include "Python.h" |
| |
| typedef struct { |
| PyObject_HEAD |
| long en_index; /* current index of enumeration */ |
| PyObject* en_sit; /* secondary iterator of enumeration */ |
| } enumobject; |
| |
| PyTypeObject PyEnum_Type; |
| |
| static PyObject * |
| enum_new(PyTypeObject *type, PyObject *args, PyObject *kwds) |
| { |
| enumobject *en; |
| PyObject *seq = NULL; |
| static char *kwlist[] = {"sequence", 0}; |
| |
| if (!PyArg_ParseTupleAndKeywords(args, kwds, "O:enumerate", kwlist, |
| &seq)) |
| return NULL; |
| |
| en = (enumobject *)type->tp_alloc(type, 0); |
| if (en == NULL) |
| return NULL; |
| en->en_index = 0; |
| en->en_sit = PyObject_GetIter(seq); |
| if (en->en_sit == NULL) { |
| Py_DECREF(en); |
| return NULL; |
| } |
| return (PyObject *)en; |
| } |
| |
| static void |
| enum_dealloc(enumobject *en) |
| { |
| PyObject_GC_UnTrack(en); |
| Py_XDECREF(en->en_sit); |
| en->ob_type->tp_free(en); |
| } |
| |
| static int |
| enum_traverse(enumobject *en, visitproc visit, void *arg) |
| { |
| if (en->en_sit) |
| return visit(en->en_sit, arg); |
| return 0; |
| } |
| |
| static PyObject * |
| enum_next(enumobject *en) |
| { |
| PyObject *result; |
| PyObject *next_index; |
| PyObject *next_item; |
| |
| result = PyTuple_New(2); |
| if (result == NULL) |
| return NULL; |
| |
| next_index = PyInt_FromLong(en->en_index); |
| if (next_index == NULL) { |
| Py_DECREF(result); |
| return NULL; |
| } |
| PyTuple_SET_ITEM(result, 0, next_index); |
| |
| next_item = PyIter_Next(en->en_sit); |
| if (next_item == NULL) { |
| Py_DECREF(result); |
| return NULL; |
| } |
| |
| en->en_index++; |
| PyTuple_SET_ITEM(result, 1, next_item); |
| return result; |
| } |
| |
| static PyObject * |
| enum_getiter(PyObject *en) |
| { |
| Py_INCREF(en); |
| return en; |
| } |
| |
| PyDoc_STRVAR(enum_doc, |
| "enumerate(iterable) -> create an enumerating-iterator"); |
| |
| PyTypeObject PyEnum_Type = { |
| PyObject_HEAD_INIT(&PyType_Type) |
| 0, /* ob_size */ |
| "enumerate", /* tp_name */ |
| sizeof(enumobject), /* tp_basicsize */ |
| 0, /* tp_itemsize */ |
| /* methods */ |
| (destructor)enum_dealloc, /* tp_dealloc */ |
| 0, /* tp_print */ |
| 0, /* tp_getattr */ |
| 0, /* tp_setattr */ |
| 0, /* tp_compare */ |
| 0, /* tp_repr */ |
| 0, /* tp_as_number */ |
| 0, /* tp_as_sequence */ |
| 0, /* tp_as_mapping */ |
| 0, /* tp_hash */ |
| 0, /* tp_call */ |
| 0, /* tp_str */ |
| PyObject_GenericGetAttr, /* tp_getattro */ |
| 0, /* tp_setattro */ |
| 0, /* tp_as_buffer */ |
| Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | |
| Py_TPFLAGS_BASETYPE, /* tp_flags */ |
| enum_doc, /* tp_doc */ |
| (traverseproc)enum_traverse, /* tp_traverse */ |
| 0, /* tp_clear */ |
| 0, /* tp_richcompare */ |
| 0, /* tp_weaklistoffset */ |
| (getiterfunc)enum_getiter, /* tp_iter */ |
| (iternextfunc)enum_next, /* tp_iternext */ |
| 0, /* tp_methods */ |
| 0, /* tp_members */ |
| 0, /* tp_getset */ |
| 0, /* tp_base */ |
| 0, /* tp_dict */ |
| 0, /* tp_descr_get */ |
| 0, /* tp_descr_set */ |
| 0, /* tp_dictoffset */ |
| 0, /* tp_init */ |
| PyType_GenericAlloc, /* tp_alloc */ |
| enum_new, /* tp_new */ |
| PyObject_GC_Del, /* tp_free */ |
| }; |