12 PySeqIter_New(PyObject
*seq
)
15 it
= PyObject_NEW(seqiterobject
, &PySeqIter_Type
);
21 return (PyObject
*)it
;
24 iter_dealloc(seqiterobject
*it
)
26 Py_DECREF(it
->it_seq
);
31 iter_traverse(seqiterobject
*it
, visitproc visit
, void *arg
)
33 return visit(it
->it_seq
, arg
);
37 iter_next(seqiterobject
*it
)
39 PyObject
*seq
= it
->it_seq
;
40 PyObject
*result
= PySequence_GetItem(seq
, it
->it_index
++);
42 if (result
== NULL
&& PyErr_ExceptionMatches(PyExc_IndexError
))
43 PyErr_SetObject(PyExc_StopIteration
, Py_None
);
48 iter_getiter(PyObject
*it
)
55 iter_iternext(PyObject
*iterator
)
60 assert(PySeqIter_Check(iterator
));
61 it
= (seqiterobject
*)iterator
;
64 if (PyList_Check(seq
)) {
66 if (it
->it_index
>= PyList_GET_SIZE(seq
)) {
69 item
= PyList_GET_ITEM(seq
, it
->it_index
);
75 PyObject
*result
= PySequence_GetItem(seq
, it
->it_index
++);
79 if (PyErr_ExceptionMatches(PyExc_IndexError
) ||
80 PyErr_ExceptionMatches(PyExc_StopIteration
)) {
90 static PyMethodDef iter_methods
[] = {
91 {"next", (PyCFunction
)iter_next
, METH_NOARGS
,
92 "it.next() -- get the next value, or raise StopIteration"},
93 {NULL
, NULL
} /* sentinel */
96 PyTypeObject PySeqIter_Type
= {
97 PyObject_HEAD_INIT(&PyType_Type
)
99 "iterator", /* tp_name */
100 sizeof(seqiterobject
), /* tp_basicsize */
103 (destructor
)iter_dealloc
, /* tp_dealloc */
109 0, /* tp_as_number */
110 0, /* tp_as_sequence */
111 0, /* tp_as_mapping */
115 PyObject_GenericGetAttr
, /* tp_getattro */
117 0, /* tp_as_buffer */
118 Py_TPFLAGS_DEFAULT
, /* tp_flags */
120 (traverseproc
)iter_traverse
, /* tp_traverse */
122 0, /* tp_richcompare */
123 0, /* tp_weaklistoffset */
124 (getiterfunc
)iter_getiter
, /* tp_iter */
125 (iternextfunc
)iter_iternext
, /* tp_iternext */
126 iter_methods
, /* tp_methods */
131 0, /* tp_descr_get */
132 0, /* tp_descr_set */
135 /* -------------------------------------- */
139 PyObject
*it_callable
;
140 PyObject
*it_sentinel
;
144 PyCallIter_New(PyObject
*callable
, PyObject
*sentinel
)
147 it
= PyObject_NEW(calliterobject
, &PyCallIter_Type
);
151 it
->it_callable
= callable
;
153 it
->it_sentinel
= sentinel
;
154 return (PyObject
*)it
;
157 calliter_dealloc(calliterobject
*it
)
159 Py_DECREF(it
->it_callable
);
160 Py_DECREF(it
->it_sentinel
);
165 calliter_traverse(calliterobject
*it
, visitproc visit
, void *arg
)
168 if ((err
= visit(it
->it_callable
, arg
)))
170 if ((err
= visit(it
->it_sentinel
, arg
)))
176 calliter_next(calliterobject
*it
, PyObject
*args
)
178 PyObject
*result
= PyObject_CallObject(it
->it_callable
, NULL
);
179 if (result
!= NULL
) {
180 if (PyObject_RichCompareBool(result
, it
->it_sentinel
, Py_EQ
)) {
181 PyErr_SetObject(PyExc_StopIteration
, Py_None
);
189 static PyMethodDef calliter_methods
[] = {
190 {"next", (PyCFunction
)calliter_next
, METH_VARARGS
,
191 "it.next() -- get the next value, or raise StopIteration"},
192 {NULL
, NULL
} /* sentinel */
196 calliter_iternext(calliterobject
*it
)
198 PyObject
*result
= PyObject_CallObject(it
->it_callable
, NULL
);
199 if (result
!= NULL
) {
200 if (PyObject_RichCompareBool(result
, it
->it_sentinel
, Py_EQ
)) {
205 else if (PyErr_ExceptionMatches(PyExc_StopIteration
)) {
211 PyTypeObject PyCallIter_Type
= {
212 PyObject_HEAD_INIT(&PyType_Type
)
214 "callable-iterator", /* tp_name */
215 sizeof(calliterobject
), /* tp_basicsize */
218 (destructor
)calliter_dealloc
, /* tp_dealloc */
224 0, /* tp_as_number */
225 0, /* tp_as_sequence */
226 0, /* tp_as_mapping */
230 PyObject_GenericGetAttr
, /* tp_getattro */
232 0, /* tp_as_buffer */
233 Py_TPFLAGS_DEFAULT
, /* tp_flags */
235 (traverseproc
)calliter_traverse
, /* tp_traverse */
237 0, /* tp_richcompare */
238 0, /* tp_weaklistoffset */
239 (getiterfunc
)iter_getiter
, /* tp_iter */
240 (iternextfunc
)calliter_iternext
, /* tp_iternext */
241 calliter_methods
, /* tp_methods */
246 0, /* tp_descr_get */
247 0, /* tp_descr_set */