blob: 66ee870d469fae980989f87eee34e46e8b988470 [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;
Guido van Rossumca5ed5b2002-07-16 21:02:42 +000057 PyObject *next_item;
Guido van Rossum7dab2422002-04-26 19:40:56 +000058
59 result = PyTuple_New(2);
Guido van Rossumca5ed5b2002-07-16 21:02:42 +000060 if (result == NULL)
61 return NULL;
62
63 next_index = PyInt_FromLong(en->en_index);
64 if (next_index == NULL) {
65 Py_DECREF(result);
Guido van Rossum7dab2422002-04-26 19:40:56 +000066 return NULL;
67 }
Guido van Rossumca5ed5b2002-07-16 21:02:42 +000068 PyTuple_SET_ITEM(result, 0, next_index);
Guido van Rossum7dab2422002-04-26 19:40:56 +000069
Guido van Rossumca5ed5b2002-07-16 21:02:42 +000070 next_item = PyIter_Next(en->en_sit);
71 if (next_item == NULL) {
Guido van Rossum7dab2422002-04-26 19:40:56 +000072 Py_DECREF(result);
73 return NULL;
74 }
75
Guido van Rossumca5ed5b2002-07-16 21:02:42 +000076 en->en_index++;
Guido van Rossum7dab2422002-04-26 19:40:56 +000077 PyTuple_SET_ITEM(result, 1, next_item);
78 return result;
79}
80
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000081PyDoc_STRVAR(enum_doc,
Jeremy Hyltonfbbe3472003-04-21 20:26:25 +000082"enumerate(iterable) -> iterator for index, value of iterable\n"
83"\n"
84"Return an enumerate object. iterable must be an other object that supports\n"
85"iteration. The enumerate object yields pairs containing a count (from\n"
86"zero) and a value yielded by the iterable argument. enumerate is useful\n"
87"for obtaining an indexed list: (0, seq[0]), (1, seq[1]), (2, seq[2]), ...");
Guido van Rossum7dab2422002-04-26 19:40:56 +000088
89PyTypeObject PyEnum_Type = {
90 PyObject_HEAD_INIT(&PyType_Type)
91 0, /* ob_size */
92 "enumerate", /* tp_name */
93 sizeof(enumobject), /* tp_basicsize */
94 0, /* tp_itemsize */
95 /* methods */
96 (destructor)enum_dealloc, /* tp_dealloc */
97 0, /* tp_print */
98 0, /* tp_getattr */
99 0, /* tp_setattr */
100 0, /* tp_compare */
101 0, /* tp_repr */
102 0, /* tp_as_number */
103 0, /* tp_as_sequence */
104 0, /* tp_as_mapping */
105 0, /* tp_hash */
106 0, /* tp_call */
107 0, /* tp_str */
108 PyObject_GenericGetAttr, /* tp_getattro */
109 0, /* tp_setattro */
110 0, /* tp_as_buffer */
111 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
112 Py_TPFLAGS_BASETYPE, /* tp_flags */
113 enum_doc, /* tp_doc */
114 (traverseproc)enum_traverse, /* tp_traverse */
115 0, /* tp_clear */
116 0, /* tp_richcompare */
117 0, /* tp_weaklistoffset */
Raymond Hettinger1da1dbf2003-03-17 19:46:11 +0000118 PyObject_SelfIter, /* tp_iter */
Guido van Rossum7dab2422002-04-26 19:40:56 +0000119 (iternextfunc)enum_next, /* tp_iternext */
Guido van Rossumca5ed5b2002-07-16 21:02:42 +0000120 0, /* tp_methods */
Guido van Rossum7dab2422002-04-26 19:40:56 +0000121 0, /* tp_members */
122 0, /* tp_getset */
123 0, /* tp_base */
124 0, /* tp_dict */
125 0, /* tp_descr_get */
126 0, /* tp_descr_set */
127 0, /* tp_dictoffset */
128 0, /* tp_init */
129 PyType_GenericAlloc, /* tp_alloc */
130 enum_new, /* tp_new */
131 PyObject_GC_Del, /* tp_free */
132};