12 PySeqIter_New(PyObject
*seq
)
15 it
= PyObject_NEW(seqiterobject
, &PySeqIter_Type
);
22 return (PyObject
*)it
;
25 iter_dealloc(seqiterobject
*it
)
28 Py_DECREF(it
->it_seq
);
29 it
= (seqiterobject
*) PyObject_AS_GC(it
);
34 iter_traverse(seqiterobject
*it
, visitproc visit
, void *arg
)
36 return visit(it
->it_seq
, arg
);
40 iter_next(seqiterobject
*it
)
42 PyObject
*seq
= it
->it_seq
;
43 PyObject
*result
= PySequence_GetItem(seq
, it
->it_index
++);
45 if (result
== NULL
&& PyErr_ExceptionMatches(PyExc_IndexError
))
46 PyErr_SetObject(PyExc_StopIteration
, Py_None
);
51 iter_getiter(PyObject
*it
)
58 iter_iternext(PyObject
*iterator
)
63 assert(PySeqIter_Check(iterator
));
64 it
= (seqiterobject
*)iterator
;
67 if (PyList_Check(seq
)) {
69 if (it
->it_index
>= PyList_GET_SIZE(seq
)) {
72 item
= PyList_GET_ITEM(seq
, it
->it_index
);
78 PyObject
*result
= PySequence_GetItem(seq
, it
->it_index
++);
82 if (PyErr_ExceptionMatches(PyExc_IndexError
) ||
83 PyErr_ExceptionMatches(PyExc_StopIteration
)) {
93 static PyMethodDef iter_methods
[] = {
94 {"next", (PyCFunction
)iter_next
, METH_NOARGS
,
95 "it.next() -- get the next value, or raise StopIteration"},
96 {NULL
, NULL
} /* sentinel */
99 PyTypeObject PySeqIter_Type
= {
100 PyObject_HEAD_INIT(&PyType_Type
)
102 "iterator", /* tp_name */
103 sizeof(seqiterobject
) + PyGC_HEAD_SIZE
, /* tp_basicsize */
106 (destructor
)iter_dealloc
, /* tp_dealloc */
112 0, /* tp_as_number */
113 0, /* tp_as_sequence */
114 0, /* tp_as_mapping */
118 PyObject_GenericGetAttr
, /* tp_getattro */
120 0, /* tp_as_buffer */
121 Py_TPFLAGS_DEFAULT
| Py_TPFLAGS_GC
, /* tp_flags */
123 (traverseproc
)iter_traverse
, /* tp_traverse */
125 0, /* tp_richcompare */
126 0, /* tp_weaklistoffset */
127 (getiterfunc
)iter_getiter
, /* tp_iter */
128 (iternextfunc
)iter_iternext
, /* tp_iternext */
129 iter_methods
, /* tp_methods */
134 0, /* tp_descr_get */
135 0, /* tp_descr_set */
138 /* -------------------------------------- */
142 PyObject
*it_callable
;
143 PyObject
*it_sentinel
;
147 PyCallIter_New(PyObject
*callable
, PyObject
*sentinel
)
150 it
= PyObject_NEW(calliterobject
, &PyCallIter_Type
);
154 it
->it_callable
= callable
;
156 it
->it_sentinel
= sentinel
;
157 PyObject_GC_Init(it
);
158 return (PyObject
*)it
;
161 calliter_dealloc(calliterobject
*it
)
163 PyObject_GC_Fini(it
);
164 Py_DECREF(it
->it_callable
);
165 Py_DECREF(it
->it_sentinel
);
166 it
= (calliterobject
*) PyObject_AS_GC(it
);
171 calliter_traverse(calliterobject
*it
, visitproc visit
, void *arg
)
174 if ((err
= visit(it
->it_callable
, arg
)))
176 if ((err
= visit(it
->it_sentinel
, arg
)))
182 calliter_next(calliterobject
*it
, PyObject
*args
)
184 PyObject
*result
= PyObject_CallObject(it
->it_callable
, NULL
);
185 if (result
!= NULL
) {
186 if (PyObject_RichCompareBool(result
, it
->it_sentinel
, Py_EQ
)) {
187 PyErr_SetObject(PyExc_StopIteration
, Py_None
);
195 static PyMethodDef calliter_methods
[] = {
196 {"next", (PyCFunction
)calliter_next
, METH_VARARGS
,
197 "it.next() -- get the next value, or raise StopIteration"},
198 {NULL
, NULL
} /* sentinel */
202 calliter_iternext(calliterobject
*it
)
204 PyObject
*result
= PyObject_CallObject(it
->it_callable
, NULL
);
205 if (result
!= NULL
) {
206 if (PyObject_RichCompareBool(result
, it
->it_sentinel
, Py_EQ
)) {
211 else if (PyErr_ExceptionMatches(PyExc_StopIteration
)) {
217 PyTypeObject PyCallIter_Type
= {
218 PyObject_HEAD_INIT(&PyType_Type
)
220 "callable-iterator", /* tp_name */
221 sizeof(calliterobject
) + PyGC_HEAD_SIZE
,/* tp_basicsize */
224 (destructor
)calliter_dealloc
, /* tp_dealloc */
230 0, /* tp_as_number */
231 0, /* tp_as_sequence */
232 0, /* tp_as_mapping */
236 PyObject_GenericGetAttr
, /* tp_getattro */
238 0, /* tp_as_buffer */
239 Py_TPFLAGS_DEFAULT
| Py_TPFLAGS_GC
, /* tp_flags */
241 (traverseproc
)calliter_traverse
, /* tp_traverse */
243 0, /* tp_richcompare */
244 0, /* tp_weaklistoffset */
245 (getiterfunc
)iter_getiter
, /* tp_iter */
246 (iternextfunc
)calliter_iternext
, /* tp_iternext */
247 calliter_methods
, /* tp_methods */
252 0, /* tp_descr_get */
253 0, /* tp_descr_set */