]> git.proxmox.com Git - mirror_edk2.git/blame - AppPkg/Applications/Python/Python-2.7.10/Objects/iterobject.c
AppPkg/Applications/Python/Python-2.7.10: Initial Checkin part 3/5.
[mirror_edk2.git] / AppPkg / Applications / Python / Python-2.7.10 / Objects / iterobject.c
CommitLineData
53b2ba57
DM
1/* Iterator objects */\r
2\r
3#include "Python.h"\r
4\r
5typedef struct {\r
6 PyObject_HEAD\r
7 long it_index;\r
8 PyObject *it_seq; /* Set to NULL when iterator is exhausted */\r
9} seqiterobject;\r
10\r
11PyObject *\r
12PySeqIter_New(PyObject *seq)\r
13{\r
14 seqiterobject *it;\r
15\r
16 if (!PySequence_Check(seq)) {\r
17 PyErr_BadInternalCall();\r
18 return NULL;\r
19 }\r
20 it = PyObject_GC_New(seqiterobject, &PySeqIter_Type);\r
21 if (it == NULL)\r
22 return NULL;\r
23 it->it_index = 0;\r
24 Py_INCREF(seq);\r
25 it->it_seq = seq;\r
26 _PyObject_GC_TRACK(it);\r
27 return (PyObject *)it;\r
28}\r
29\r
30static void\r
31iter_dealloc(seqiterobject *it)\r
32{\r
33 _PyObject_GC_UNTRACK(it);\r
34 Py_XDECREF(it->it_seq);\r
35 PyObject_GC_Del(it);\r
36}\r
37\r
38static int\r
39iter_traverse(seqiterobject *it, visitproc visit, void *arg)\r
40{\r
41 Py_VISIT(it->it_seq);\r
42 return 0;\r
43}\r
44\r
45static PyObject *\r
46iter_iternext(PyObject *iterator)\r
47{\r
48 seqiterobject *it;\r
49 PyObject *seq;\r
50 PyObject *result;\r
51\r
52 assert(PySeqIter_Check(iterator));\r
53 it = (seqiterobject *)iterator;\r
54 seq = it->it_seq;\r
55 if (seq == NULL)\r
56 return NULL;\r
57\r
58 result = PySequence_GetItem(seq, it->it_index);\r
59 if (result != NULL) {\r
60 it->it_index++;\r
61 return result;\r
62 }\r
63 if (PyErr_ExceptionMatches(PyExc_IndexError) ||\r
64 PyErr_ExceptionMatches(PyExc_StopIteration))\r
65 {\r
66 PyErr_Clear();\r
67 Py_DECREF(seq);\r
68 it->it_seq = NULL;\r
69 }\r
70 return NULL;\r
71}\r
72\r
73static PyObject *\r
74iter_len(seqiterobject *it)\r
75{\r
76 Py_ssize_t seqsize, len;\r
77\r
78 if (it->it_seq) {\r
79 seqsize = PySequence_Size(it->it_seq);\r
80 if (seqsize == -1)\r
81 return NULL;\r
82 len = seqsize - it->it_index;\r
83 if (len >= 0)\r
84 return PyInt_FromSsize_t(len);\r
85 }\r
86 return PyInt_FromLong(0);\r
87}\r
88\r
89PyDoc_STRVAR(length_hint_doc, "Private method returning an estimate of len(list(it)).");\r
90\r
91static PyMethodDef seqiter_methods[] = {\r
92 {"__length_hint__", (PyCFunction)iter_len, METH_NOARGS, length_hint_doc},\r
93 {NULL, NULL} /* sentinel */\r
94};\r
95\r
96PyTypeObject PySeqIter_Type = {\r
97 PyVarObject_HEAD_INIT(&PyType_Type, 0)\r
98 "iterator", /* tp_name */\r
99 sizeof(seqiterobject), /* tp_basicsize */\r
100 0, /* tp_itemsize */\r
101 /* methods */\r
102 (destructor)iter_dealloc, /* tp_dealloc */\r
103 0, /* tp_print */\r
104 0, /* tp_getattr */\r
105 0, /* tp_setattr */\r
106 0, /* tp_compare */\r
107 0, /* tp_repr */\r
108 0, /* tp_as_number */\r
109 0, /* tp_as_sequence */\r
110 0, /* tp_as_mapping */\r
111 0, /* tp_hash */\r
112 0, /* tp_call */\r
113 0, /* tp_str */\r
114 PyObject_GenericGetAttr, /* tp_getattro */\r
115 0, /* tp_setattro */\r
116 0, /* tp_as_buffer */\r
117 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,/* tp_flags */\r
118 0, /* tp_doc */\r
119 (traverseproc)iter_traverse, /* tp_traverse */\r
120 0, /* tp_clear */\r
121 0, /* tp_richcompare */\r
122 0, /* tp_weaklistoffset */\r
123 PyObject_SelfIter, /* tp_iter */\r
124 iter_iternext, /* tp_iternext */\r
125 seqiter_methods, /* tp_methods */\r
126 0, /* tp_members */\r
127};\r
128\r
129/* -------------------------------------- */\r
130\r
131typedef struct {\r
132 PyObject_HEAD\r
133 PyObject *it_callable; /* Set to NULL when iterator is exhausted */\r
134 PyObject *it_sentinel; /* Set to NULL when iterator is exhausted */\r
135} calliterobject;\r
136\r
137PyObject *\r
138PyCallIter_New(PyObject *callable, PyObject *sentinel)\r
139{\r
140 calliterobject *it;\r
141 it = PyObject_GC_New(calliterobject, &PyCallIter_Type);\r
142 if (it == NULL)\r
143 return NULL;\r
144 Py_INCREF(callable);\r
145 it->it_callable = callable;\r
146 Py_INCREF(sentinel);\r
147 it->it_sentinel = sentinel;\r
148 _PyObject_GC_TRACK(it);\r
149 return (PyObject *)it;\r
150}\r
151static void\r
152calliter_dealloc(calliterobject *it)\r
153{\r
154 _PyObject_GC_UNTRACK(it);\r
155 Py_XDECREF(it->it_callable);\r
156 Py_XDECREF(it->it_sentinel);\r
157 PyObject_GC_Del(it);\r
158}\r
159\r
160static int\r
161calliter_traverse(calliterobject *it, visitproc visit, void *arg)\r
162{\r
163 Py_VISIT(it->it_callable);\r
164 Py_VISIT(it->it_sentinel);\r
165 return 0;\r
166}\r
167\r
168static PyObject *\r
169calliter_iternext(calliterobject *it)\r
170{\r
171 if (it->it_callable != NULL) {\r
172 PyObject *args = PyTuple_New(0);\r
173 PyObject *result;\r
174 if (args == NULL)\r
175 return NULL;\r
176 result = PyObject_Call(it->it_callable, args, NULL);\r
177 Py_DECREF(args);\r
178 if (result != NULL) {\r
179 int ok;\r
180 ok = PyObject_RichCompareBool(result,\r
181 it->it_sentinel,\r
182 Py_EQ);\r
183 if (ok == 0)\r
184 return result; /* Common case, fast path */\r
185 Py_DECREF(result);\r
186 if (ok > 0) {\r
187 Py_CLEAR(it->it_callable);\r
188 Py_CLEAR(it->it_sentinel);\r
189 }\r
190 }\r
191 else if (PyErr_ExceptionMatches(PyExc_StopIteration)) {\r
192 PyErr_Clear();\r
193 Py_CLEAR(it->it_callable);\r
194 Py_CLEAR(it->it_sentinel);\r
195 }\r
196 }\r
197 return NULL;\r
198}\r
199\r
200PyTypeObject PyCallIter_Type = {\r
201 PyVarObject_HEAD_INIT(&PyType_Type, 0)\r
202 "callable-iterator", /* tp_name */\r
203 sizeof(calliterobject), /* tp_basicsize */\r
204 0, /* tp_itemsize */\r
205 /* methods */\r
206 (destructor)calliter_dealloc, /* tp_dealloc */\r
207 0, /* tp_print */\r
208 0, /* tp_getattr */\r
209 0, /* tp_setattr */\r
210 0, /* tp_compare */\r
211 0, /* tp_repr */\r
212 0, /* tp_as_number */\r
213 0, /* tp_as_sequence */\r
214 0, /* tp_as_mapping */\r
215 0, /* tp_hash */\r
216 0, /* tp_call */\r
217 0, /* tp_str */\r
218 PyObject_GenericGetAttr, /* tp_getattro */\r
219 0, /* tp_setattro */\r
220 0, /* tp_as_buffer */\r
221 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,/* tp_flags */\r
222 0, /* tp_doc */\r
223 (traverseproc)calliter_traverse, /* tp_traverse */\r
224 0, /* tp_clear */\r
225 0, /* tp_richcompare */\r
226 0, /* tp_weaklistoffset */\r
227 PyObject_SelfIter, /* tp_iter */\r
228 (iternextfunc)calliter_iternext, /* tp_iternext */\r
229 0, /* tp_methods */\r
230};\r