blob: 148ac3c74208db37b71b218432b98555a3da82f9 [file] [log] [blame]
Guido van Rossum7dab2422002-04-26 19:40:56 +00001/* enumerate object */
2
3#include "Python.h"
4
5typedef struct {
6 PyObject_HEAD
7 long en_index; /* current index of enumeration */
8 PyObject* en_sit; /* secondary iterator of enumeration */
9} enumobject;
10
11PyTypeObject PyEnum_Type;
12
13static PyObject *
14enum_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
15{
16 enumobject *en;
17 PyObject *seq = NULL;
18 static char *kwlist[] = {"sequence", 0};
19
20 if (!PyArg_ParseTupleAndKeywords(args, kwds, "O:enumerate", kwlist,
21 &seq))
22 return NULL;
23
24 en = (enumobject *)type->tp_alloc(type, 0);
25 if (en == NULL)
26 return NULL;
27 en->en_index = 0;
28 en->en_sit = PyObject_GetIter(seq);
29 if (en->en_sit == NULL) {
30 Py_DECREF(en);
31 return NULL;
32 }
33 return (PyObject *)en;
34}
35
36static void
37enum_dealloc(enumobject *en)
38{
39 PyObject_GC_UnTrack(en);
40 Py_XDECREF(en->en_sit);
41 en->ob_type->tp_free(en);
42}
43
44static int
45enum_traverse(enumobject *en, visitproc visit, void *arg)
46{
47 if (en->en_sit)
48 return visit(en->en_sit, arg);
49 return 0;
50}
51
52static PyObject *
53enum_next(enumobject *en)
54{
55 PyObject *result;
56 PyObject *next_index;
57
58 PyObject *next_item = PyIter_Next(en->en_sit);
59 if (next_item == NULL)
60 return NULL;
61
62 result = PyTuple_New(2);
63 if (result == NULL) {
64 Py_DECREF(next_item);
65 return NULL;
66 }
67
68 next_index = PyInt_FromLong(en->en_index++);
69 if (next_index == NULL) {
70 Py_DECREF(next_item);
71 Py_DECREF(result);
72 return NULL;
73 }
74
75 PyTuple_SET_ITEM(result, 0, next_index);
76 PyTuple_SET_ITEM(result, 1, next_item);
77 return result;
78}
79
80static PyObject *
81enum_getiter(PyObject *en)
82{
83 Py_INCREF(en);
84 return en;
85}
86
87static PyMethodDef enum_methods[] = {
88 {"next", (PyCFunction)enum_next, METH_NOARGS,
89 "return the next (index, value) pair, or raise StopIteration"},
90 {NULL, NULL} /* sentinel */
91};
92
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000093PyDoc_STRVAR(enum_doc,
94"enumerate(iterable) -> create an enumerating-iterator");
Guido van Rossum7dab2422002-04-26 19:40:56 +000095
96PyTypeObject PyEnum_Type = {
97 PyObject_HEAD_INIT(&PyType_Type)
98 0, /* ob_size */
99 "enumerate", /* tp_name */
100 sizeof(enumobject), /* tp_basicsize */
101 0, /* tp_itemsize */
102 /* methods */
103 (destructor)enum_dealloc, /* tp_dealloc */
104 0, /* tp_print */
105 0, /* tp_getattr */
106 0, /* tp_setattr */
107 0, /* tp_compare */
108 0, /* tp_repr */
109 0, /* tp_as_number */
110 0, /* tp_as_sequence */
111 0, /* tp_as_mapping */
112 0, /* tp_hash */
113 0, /* tp_call */
114 0, /* tp_str */
115 PyObject_GenericGetAttr, /* tp_getattro */
116 0, /* tp_setattro */
117 0, /* tp_as_buffer */
118 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
119 Py_TPFLAGS_BASETYPE, /* tp_flags */
120 enum_doc, /* tp_doc */
121 (traverseproc)enum_traverse, /* tp_traverse */
122 0, /* tp_clear */
123 0, /* tp_richcompare */
124 0, /* tp_weaklistoffset */
125 (getiterfunc)enum_getiter, /* tp_iter */
126 (iternextfunc)enum_next, /* tp_iternext */
127 enum_methods, /* tp_methods */
128 0, /* tp_members */
129 0, /* tp_getset */
130 0, /* tp_base */
131 0, /* tp_dict */
132 0, /* tp_descr_get */
133 0, /* tp_descr_set */
134 0, /* tp_dictoffset */
135 0, /* tp_init */
136 PyType_GenericAlloc, /* tp_alloc */
137 enum_new, /* tp_new */
138 PyObject_GC_Del, /* tp_free */
139};