+++ /dev/null
-/* Iterator objects */\r
-\r
-#include "Python.h"\r
-\r
-typedef struct {\r
- PyObject_HEAD\r
- long it_index;\r
- PyObject *it_seq; /* Set to NULL when iterator is exhausted */\r
-} seqiterobject;\r
-\r
-PyObject *\r
-PySeqIter_New(PyObject *seq)\r
-{\r
- seqiterobject *it;\r
-\r
- if (!PySequence_Check(seq)) {\r
- PyErr_BadInternalCall();\r
- return NULL;\r
- }\r
- it = PyObject_GC_New(seqiterobject, &PySeqIter_Type);\r
- if (it == NULL)\r
- return NULL;\r
- it->it_index = 0;\r
- Py_INCREF(seq);\r
- it->it_seq = seq;\r
- _PyObject_GC_TRACK(it);\r
- return (PyObject *)it;\r
-}\r
-\r
-static void\r
-iter_dealloc(seqiterobject *it)\r
-{\r
- _PyObject_GC_UNTRACK(it);\r
- Py_XDECREF(it->it_seq);\r
- PyObject_GC_Del(it);\r
-}\r
-\r
-static int\r
-iter_traverse(seqiterobject *it, visitproc visit, void *arg)\r
-{\r
- Py_VISIT(it->it_seq);\r
- return 0;\r
-}\r
-\r
-static PyObject *\r
-iter_iternext(PyObject *iterator)\r
-{\r
- seqiterobject *it;\r
- PyObject *seq;\r
- PyObject *result;\r
-\r
- assert(PySeqIter_Check(iterator));\r
- it = (seqiterobject *)iterator;\r
- seq = it->it_seq;\r
- if (seq == NULL)\r
- return NULL;\r
-\r
- result = PySequence_GetItem(seq, it->it_index);\r
- if (result != NULL) {\r
- it->it_index++;\r
- return result;\r
- }\r
- if (PyErr_ExceptionMatches(PyExc_IndexError) ||\r
- PyErr_ExceptionMatches(PyExc_StopIteration))\r
- {\r
- PyErr_Clear();\r
- Py_DECREF(seq);\r
- it->it_seq = NULL;\r
- }\r
- return NULL;\r
-}\r
-\r
-static PyObject *\r
-iter_len(seqiterobject *it)\r
-{\r
- Py_ssize_t seqsize, len;\r
-\r
- if (it->it_seq) {\r
- seqsize = PySequence_Size(it->it_seq);\r
- if (seqsize == -1)\r
- return NULL;\r
- len = seqsize - it->it_index;\r
- if (len >= 0)\r
- return PyInt_FromSsize_t(len);\r
- }\r
- return PyInt_FromLong(0);\r
-}\r
-\r
-PyDoc_STRVAR(length_hint_doc, "Private method returning an estimate of len(list(it)).");\r
-\r
-static PyMethodDef seqiter_methods[] = {\r
- {"__length_hint__", (PyCFunction)iter_len, METH_NOARGS, length_hint_doc},\r
- {NULL, NULL} /* sentinel */\r
-};\r
-\r
-PyTypeObject PySeqIter_Type = {\r
- PyVarObject_HEAD_INIT(&PyType_Type, 0)\r
- "iterator", /* tp_name */\r
- sizeof(seqiterobject), /* tp_basicsize */\r
- 0, /* tp_itemsize */\r
- /* methods */\r
- (destructor)iter_dealloc, /* tp_dealloc */\r
- 0, /* tp_print */\r
- 0, /* tp_getattr */\r
- 0, /* tp_setattr */\r
- 0, /* tp_compare */\r
- 0, /* tp_repr */\r
- 0, /* tp_as_number */\r
- 0, /* tp_as_sequence */\r
- 0, /* tp_as_mapping */\r
- 0, /* tp_hash */\r
- 0, /* tp_call */\r
- 0, /* tp_str */\r
- PyObject_GenericGetAttr, /* tp_getattro */\r
- 0, /* tp_setattro */\r
- 0, /* tp_as_buffer */\r
- Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,/* tp_flags */\r
- 0, /* tp_doc */\r
- (traverseproc)iter_traverse, /* tp_traverse */\r
- 0, /* tp_clear */\r
- 0, /* tp_richcompare */\r
- 0, /* tp_weaklistoffset */\r
- PyObject_SelfIter, /* tp_iter */\r
- iter_iternext, /* tp_iternext */\r
- seqiter_methods, /* tp_methods */\r
- 0, /* tp_members */\r
-};\r
-\r
-/* -------------------------------------- */\r
-\r
-typedef struct {\r
- PyObject_HEAD\r
- PyObject *it_callable; /* Set to NULL when iterator is exhausted */\r
- PyObject *it_sentinel; /* Set to NULL when iterator is exhausted */\r
-} calliterobject;\r
-\r
-PyObject *\r
-PyCallIter_New(PyObject *callable, PyObject *sentinel)\r
-{\r
- calliterobject *it;\r
- it = PyObject_GC_New(calliterobject, &PyCallIter_Type);\r
- if (it == NULL)\r
- return NULL;\r
- Py_INCREF(callable);\r
- it->it_callable = callable;\r
- Py_INCREF(sentinel);\r
- it->it_sentinel = sentinel;\r
- _PyObject_GC_TRACK(it);\r
- return (PyObject *)it;\r
-}\r
-static void\r
-calliter_dealloc(calliterobject *it)\r
-{\r
- _PyObject_GC_UNTRACK(it);\r
- Py_XDECREF(it->it_callable);\r
- Py_XDECREF(it->it_sentinel);\r
- PyObject_GC_Del(it);\r
-}\r
-\r
-static int\r
-calliter_traverse(calliterobject *it, visitproc visit, void *arg)\r
-{\r
- Py_VISIT(it->it_callable);\r
- Py_VISIT(it->it_sentinel);\r
- return 0;\r
-}\r
-\r
-static PyObject *\r
-calliter_iternext(calliterobject *it)\r
-{\r
- if (it->it_callable != NULL) {\r
- PyObject *args = PyTuple_New(0);\r
- PyObject *result;\r
- if (args == NULL)\r
- return NULL;\r
- result = PyObject_Call(it->it_callable, args, NULL);\r
- Py_DECREF(args);\r
- if (result != NULL) {\r
- int ok;\r
- ok = PyObject_RichCompareBool(result,\r
- it->it_sentinel,\r
- Py_EQ);\r
- if (ok == 0)\r
- return result; /* Common case, fast path */\r
- Py_DECREF(result);\r
- if (ok > 0) {\r
- Py_CLEAR(it->it_callable);\r
- Py_CLEAR(it->it_sentinel);\r
- }\r
- }\r
- else if (PyErr_ExceptionMatches(PyExc_StopIteration)) {\r
- PyErr_Clear();\r
- Py_CLEAR(it->it_callable);\r
- Py_CLEAR(it->it_sentinel);\r
- }\r
- }\r
- return NULL;\r
-}\r
-\r
-PyTypeObject PyCallIter_Type = {\r
- PyVarObject_HEAD_INIT(&PyType_Type, 0)\r
- "callable-iterator", /* tp_name */\r
- sizeof(calliterobject), /* tp_basicsize */\r
- 0, /* tp_itemsize */\r
- /* methods */\r
- (destructor)calliter_dealloc, /* tp_dealloc */\r
- 0, /* tp_print */\r
- 0, /* tp_getattr */\r
- 0, /* tp_setattr */\r
- 0, /* tp_compare */\r
- 0, /* tp_repr */\r
- 0, /* tp_as_number */\r
- 0, /* tp_as_sequence */\r
- 0, /* tp_as_mapping */\r
- 0, /* tp_hash */\r
- 0, /* tp_call */\r
- 0, /* tp_str */\r
- PyObject_GenericGetAttr, /* tp_getattro */\r
- 0, /* tp_setattro */\r
- 0, /* tp_as_buffer */\r
- Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,/* tp_flags */\r
- 0, /* tp_doc */\r
- (traverseproc)calliter_traverse, /* tp_traverse */\r
- 0, /* tp_clear */\r
- 0, /* tp_richcompare */\r
- 0, /* tp_weaklistoffset */\r
- PyObject_SelfIter, /* tp_iter */\r
- (iternextfunc)calliter_iternext, /* tp_iternext */\r
- 0, /* tp_methods */\r
-};\r