diff -r b0087e17cd5e Makefile.pre.in --- a/Makefile.pre.in Fri Jul 01 17:57:30 2016 +0300 +++ b/Makefile.pre.in Sat Jul 02 09:33:04 2016 +0300 @@ -844,6 +844,7 @@ Objects/unicodectype.o: $(srcdir)/Object $(srcdir)/Objects/unicodetype_db.h BYTESTR_DEPS = \ + $(srcdir)/Objects/iterlib.h \ $(srcdir)/Objects/stringlib/count.h \ $(srcdir)/Objects/stringlib/ctype.h \ $(srcdir)/Objects/stringlib/fastsearch.h \ @@ -855,6 +856,7 @@ BYTESTR_DEPS = \ $(srcdir)/Objects/stringlib/transmogrify.h UNICODE_DEPS = \ + $(srcdir)/Objects/iterlib.h \ $(srcdir)/Objects/stringlib/asciilib.h \ $(srcdir)/Objects/stringlib/codecs.h \ $(srcdir)/Objects/stringlib/count.h \ diff -r b0087e17cd5e Objects/bytearrayobject.c --- a/Objects/bytearrayobject.c Fri Jul 01 17:57:30 2016 +0300 +++ b/Objects/bytearrayobject.c Sat Jul 02 09:33:04 2016 +0300 @@ -2152,7 +2152,16 @@ Construct a mutable bytearray object fro - an integer"); -static PyObject *bytearray_iter(PyObject *seq); +/*********************** ByteArray Iterator ****************************/ + +#define ITERLIB_ITER_TYPE PyByteArrayIter_Type +#define ITERLIB_ITER_TYPE_NAME "bytearray_iterator" +#define ITERLIB_CHECK PyByteArray_Check +#define ITERLIB_LEN PyByteArray_GET_SIZE +#define ITERLIB_GET_ITEM(seq,i) \ + PyLong_FromLong((unsigned char)PyByteArray_AS_STRING(seq)[i]) +#define ITERLIB_CHECK_ITEM(item) ((item) != NULL) +#include "iterlib.h" PyTypeObject PyByteArray_Type = { PyVarObject_HEAD_INIT(&PyType_Type, 0) @@ -2180,7 +2189,7 @@ PyTypeObject PyByteArray_Type = { 0, /* tp_clear */ (richcmpfunc)bytearray_richcompare, /* tp_richcompare */ 0, /* tp_weaklistoffset */ - bytearray_iter, /* tp_iter */ + iterlib_new_iter, /* tp_iter */ 0, /* tp_iternext */ bytearray_methods, /* tp_methods */ 0, /* tp_members */ @@ -2195,157 +2204,3 @@ PyTypeObject PyByteArray_Type = { PyType_GenericNew, /* tp_new */ PyObject_Del, /* tp_free */ }; - -/*********************** Bytes Iterator ****************************/ - -typedef struct { - PyObject_HEAD - Py_ssize_t it_index; - PyByteArrayObject *it_seq; /* Set to NULL when iterator is exhausted */ -} bytesiterobject; - -static void -bytearrayiter_dealloc(bytesiterobject *it) -{ - _PyObject_GC_UNTRACK(it); - Py_XDECREF(it->it_seq); - PyObject_GC_Del(it); -} - -static int -bytearrayiter_traverse(bytesiterobject *it, visitproc visit, void *arg) -{ - Py_VISIT(it->it_seq); - return 0; -} - -static PyObject * -bytearrayiter_next(bytesiterobject *it) -{ - PyByteArrayObject *seq; - PyObject *item; - - assert(it != NULL); - seq = it->it_seq; - if (seq == NULL) - return NULL; - assert(PyByteArray_Check(seq)); - - if (it->it_index < PyByteArray_GET_SIZE(seq)) { - item = PyLong_FromLong( - (unsigned char)PyByteArray_AS_STRING(seq)[it->it_index]); - if (item != NULL) - ++it->it_index; - return item; - } - - it->it_seq = NULL; - Py_DECREF(seq); - return NULL; -} - -static PyObject * -bytearrayiter_length_hint(bytesiterobject *it) -{ - Py_ssize_t len = 0; - if (it->it_seq) - len = PyByteArray_GET_SIZE(it->it_seq) - it->it_index; - return PyLong_FromSsize_t(len); -} - -PyDoc_STRVAR(length_hint_doc, - "Private method returning an estimate of len(list(it))."); - -static PyObject * -bytearrayiter_reduce(bytesiterobject *it) -{ - if (it->it_seq != NULL) { - return Py_BuildValue("N(O)n", _PyObject_GetBuiltin("iter"), - it->it_seq, it->it_index); - } else { - PyObject *u = PyUnicode_FromUnicode(NULL, 0); - if (u == NULL) - return NULL; - return Py_BuildValue("N(N)", _PyObject_GetBuiltin("iter"), u); - } -} - -static PyObject * -bytearrayiter_setstate(bytesiterobject *it, PyObject *state) -{ - Py_ssize_t index = PyLong_AsSsize_t(state); - if (index == -1 && PyErr_Occurred()) - return NULL; - if (it->it_seq != NULL) { - if (index < 0) - index = 0; - else if (index > PyByteArray_GET_SIZE(it->it_seq)) - index = PyByteArray_GET_SIZE(it->it_seq); /* iterator exhausted */ - it->it_index = index; - } - Py_RETURN_NONE; -} - -PyDoc_STRVAR(setstate_doc, "Set state information for unpickling."); - -static PyMethodDef bytearrayiter_methods[] = { - {"__length_hint__", (PyCFunction)bytearrayiter_length_hint, METH_NOARGS, - length_hint_doc}, - {"__reduce__", (PyCFunction)bytearrayiter_reduce, METH_NOARGS, - bytearray_reduce__doc__}, - {"__setstate__", (PyCFunction)bytearrayiter_setstate, METH_O, - setstate_doc}, - {NULL, NULL} /* sentinel */ -}; - -PyTypeObject PyByteArrayIter_Type = { - PyVarObject_HEAD_INIT(&PyType_Type, 0) - "bytearray_iterator", /* tp_name */ - sizeof(bytesiterobject), /* tp_basicsize */ - 0, /* tp_itemsize */ - /* methods */ - (destructor)bytearrayiter_dealloc, /* tp_dealloc */ - 0, /* tp_print */ - 0, /* tp_getattr */ - 0, /* tp_setattr */ - 0, /* tp_reserved */ - 0, /* tp_repr */ - 0, /* tp_as_number */ - 0, /* tp_as_sequence */ - 0, /* tp_as_mapping */ - 0, /* tp_hash */ - 0, /* tp_call */ - 0, /* tp_str */ - PyObject_GenericGetAttr, /* tp_getattro */ - 0, /* tp_setattro */ - 0, /* tp_as_buffer */ - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */ - 0, /* tp_doc */ - (traverseproc)bytearrayiter_traverse, /* tp_traverse */ - 0, /* tp_clear */ - 0, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - PyObject_SelfIter, /* tp_iter */ - (iternextfunc)bytearrayiter_next, /* tp_iternext */ - bytearrayiter_methods, /* tp_methods */ - 0, -}; - -static PyObject * -bytearray_iter(PyObject *seq) -{ - bytesiterobject *it; - - if (!PyByteArray_Check(seq)) { - PyErr_BadInternalCall(); - return NULL; - } - it = PyObject_GC_New(bytesiterobject, &PyByteArrayIter_Type); - if (it == NULL) - return NULL; - it->it_index = 0; - Py_INCREF(seq); - it->it_seq = (PyByteArrayObject *)seq; - _PyObject_GC_TRACK(it); - return (PyObject *)it; -} diff -r b0087e17cd5e Objects/bytesobject.c --- a/Objects/bytesobject.c Fri Jul 01 17:57:30 2016 +0300 +++ b/Objects/bytesobject.c Sat Jul 02 09:33:04 2016 +0300 @@ -2732,7 +2732,16 @@ Construct an immutable array of bytes fr - any object implementing the buffer API.\n\ - an integer"); -static PyObject *bytes_iter(PyObject *seq); +/*********************** Bytes Iterator ****************************/ + +#define ITERLIB_ITER_TYPE PyBytesIter_Type +#define ITERLIB_ITER_TYPE_NAME "bytes_iterator" +#define ITERLIB_CHECK PyBytes_Check +#define ITERLIB_LEN PyBytes_GET_SIZE +#define ITERLIB_GET_ITEM(seq,i) \ + PyLong_FromLong((unsigned char)PyBytes_AS_STRING(seq)[i]) +#define ITERLIB_CHECK_ITEM(item) ((item) != NULL) +#include "iterlib.h" PyTypeObject PyBytes_Type = { PyVarObject_HEAD_INIT(&PyType_Type, 0) @@ -2761,7 +2770,7 @@ PyTypeObject PyBytes_Type = { 0, /* tp_clear */ (richcmpfunc)bytes_richcompare, /* tp_richcompare */ 0, /* tp_weaklistoffset */ - bytes_iter, /* tp_iter */ + iterlib_new_iter, /* tp_iter */ 0, /* tp_iternext */ bytes_methods, /* tp_methods */ 0, /* tp_members */ @@ -2888,162 +2897,6 @@ PyBytes_Fini(void) Py_CLEAR(nullstring); } -/*********************** Bytes Iterator ****************************/ - -typedef struct { - PyObject_HEAD - Py_ssize_t it_index; - PyBytesObject *it_seq; /* Set to NULL when iterator is exhausted */ -} striterobject; - -static void -striter_dealloc(striterobject *it) -{ - _PyObject_GC_UNTRACK(it); - Py_XDECREF(it->it_seq); - PyObject_GC_Del(it); -} - -static int -striter_traverse(striterobject *it, visitproc visit, void *arg) -{ - Py_VISIT(it->it_seq); - return 0; -} - -static PyObject * -striter_next(striterobject *it) -{ - PyBytesObject *seq; - PyObject *item; - - assert(it != NULL); - seq = it->it_seq; - if (seq == NULL) - return NULL; - assert(PyBytes_Check(seq)); - - if (it->it_index < PyBytes_GET_SIZE(seq)) { - item = PyLong_FromLong( - (unsigned char)seq->ob_sval[it->it_index]); - if (item != NULL) - ++it->it_index; - return item; - } - - it->it_seq = NULL; - Py_DECREF(seq); - return NULL; -} - -static PyObject * -striter_len(striterobject *it) -{ - Py_ssize_t len = 0; - if (it->it_seq) - len = PyBytes_GET_SIZE(it->it_seq) - it->it_index; - return PyLong_FromSsize_t(len); -} - -PyDoc_STRVAR(length_hint_doc, - "Private method returning an estimate of len(list(it))."); - -static PyObject * -striter_reduce(striterobject *it) -{ - if (it->it_seq != NULL) { - return Py_BuildValue("N(O)n", _PyObject_GetBuiltin("iter"), - it->it_seq, it->it_index); - } else { - PyObject *u = PyUnicode_FromUnicode(NULL, 0); - if (u == NULL) - return NULL; - return Py_BuildValue("N(N)", _PyObject_GetBuiltin("iter"), u); - } -} - -PyDoc_STRVAR(reduce_doc, "Return state information for pickling."); - -static PyObject * -striter_setstate(striterobject *it, PyObject *state) -{ - Py_ssize_t index = PyLong_AsSsize_t(state); - if (index == -1 && PyErr_Occurred()) - return NULL; - if (it->it_seq != NULL) { - if (index < 0) - index = 0; - else if (index > PyBytes_GET_SIZE(it->it_seq)) - index = PyBytes_GET_SIZE(it->it_seq); /* iterator exhausted */ - it->it_index = index; - } - Py_RETURN_NONE; -} - -PyDoc_STRVAR(setstate_doc, "Set state information for unpickling."); - -static PyMethodDef striter_methods[] = { - {"__length_hint__", (PyCFunction)striter_len, METH_NOARGS, - length_hint_doc}, - {"__reduce__", (PyCFunction)striter_reduce, METH_NOARGS, - reduce_doc}, - {"__setstate__", (PyCFunction)striter_setstate, METH_O, - setstate_doc}, - {NULL, NULL} /* sentinel */ -}; - -PyTypeObject PyBytesIter_Type = { - PyVarObject_HEAD_INIT(&PyType_Type, 0) - "bytes_iterator", /* tp_name */ - sizeof(striterobject), /* tp_basicsize */ - 0, /* tp_itemsize */ - /* methods */ - (destructor)striter_dealloc, /* tp_dealloc */ - 0, /* tp_print */ - 0, /* tp_getattr */ - 0, /* tp_setattr */ - 0, /* tp_reserved */ - 0, /* tp_repr */ - 0, /* tp_as_number */ - 0, /* tp_as_sequence */ - 0, /* tp_as_mapping */ - 0, /* tp_hash */ - 0, /* tp_call */ - 0, /* tp_str */ - PyObject_GenericGetAttr, /* tp_getattro */ - 0, /* tp_setattro */ - 0, /* tp_as_buffer */ - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,/* tp_flags */ - 0, /* tp_doc */ - (traverseproc)striter_traverse, /* tp_traverse */ - 0, /* tp_clear */ - 0, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - PyObject_SelfIter, /* tp_iter */ - (iternextfunc)striter_next, /* tp_iternext */ - striter_methods, /* tp_methods */ - 0, -}; - -static PyObject * -bytes_iter(PyObject *seq) -{ - striterobject *it; - - if (!PyBytes_Check(seq)) { - PyErr_BadInternalCall(); - return NULL; - } - it = PyObject_GC_New(striterobject, &PyBytesIter_Type); - if (it == NULL) - return NULL; - it->it_index = 0; - Py_INCREF(seq); - it->it_seq = (PyBytesObject *)seq; - _PyObject_GC_TRACK(it); - return (PyObject *)it; -} - /* _PyBytesWriter API */ diff -r b0087e17cd5e Objects/iterlib.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Objects/iterlib.h Sat Jul 02 09:33:04 2016 +0300 @@ -0,0 +1,168 @@ +typedef struct { + PyObject_HEAD + Py_ssize_t it_index; + PyObject *it_seq; /* Set to NULL when iterator is exhausted */ +} iterlib_object; + +static void +iterlib_dealloc(iterlib_object *it) +{ + _PyObject_GC_UNTRACK(it); + Py_XDECREF(it->it_seq); + PyObject_GC_Del(it); +} + +static int +iterlib_traverse(iterlib_object *it, visitproc visit, void *arg) +{ + Py_VISIT(it->it_seq); + return 0; +} + +static PyObject * +iterlib_next(iterlib_object *it) +{ + PyObject *seq; + PyObject *item; + + assert(it != NULL); + seq = it->it_seq; + if (seq == NULL) + return NULL; + assert(ITERLIB_CHECK(seq)); + + if (it->it_index < ITERLIB_LEN(seq)) { + item = ITERLIB_GET_ITEM(seq, it->it_index); + if (ITERLIB_CHECK_ITEM(item)) + ++it->it_index; + return item; + } + + it->it_seq = NULL; + Py_DECREF(seq); + return NULL; +} + +static PyObject * +iterlib_len(iterlib_object *it) +{ + Py_ssize_t len = 0; + if (it->it_seq) { + len = ITERLIB_LEN(it->it_seq) - it->it_index; + if (len < 0) { + len = 0; + } + } + return PyLong_FromSsize_t(len); +} + +PyDoc_STRVAR(length_hint_doc, + "Private method returning an estimate of len(list(it))."); + +static PyObject * +iterlib_reduce(iterlib_object *it) +{ + PyObject *iter = _PyObject_GetBuiltin("iter"); + if (it->it_seq == NULL) { + return Py_BuildValue("N(())", iter); + } + else if (it->it_index == 0) { + return Py_BuildValue("N(O)", iter, it->it_seq); + } + else { + return Py_BuildValue("N(O)n", iter, it->it_seq, it->it_index); + } +} + +PyDoc_STRVAR(reduce_doc, "Return state information for pickling."); + +static PyObject * +iterlib_setstate(iterlib_object *it, PyObject *state) +{ + Py_ssize_t index = PyLong_AsSsize_t(state); + if (index == -1 && PyErr_Occurred()) + return NULL; + if (it->it_seq != NULL) { + if (index < 0) + index = 0; + else if (index > ITERLIB_LEN(it->it_seq)) + index = ITERLIB_LEN(it->it_seq); /* iterator exhausted */ + it->it_index = index; + } + Py_RETURN_NONE; +} + +PyDoc_STRVAR(setstate_doc, "Set state information for unpickling."); + +static PyMethodDef iterlib_methods[] = { + {"__length_hint__", (PyCFunction)iterlib_len, METH_NOARGS, + length_hint_doc}, + {"__reduce__", (PyCFunction)iterlib_reduce, METH_NOARGS, + reduce_doc}, + {"__setstate__", (PyCFunction)iterlib_setstate, METH_O, + setstate_doc}, + {NULL, NULL} /* sentinel */ +}; + +PyTypeObject ITERLIB_ITER_TYPE = { + PyVarObject_HEAD_INIT(&PyType_Type, 0) + ITERLIB_ITER_TYPE_NAME, /* tp_name */ + sizeof(iterlib_object), /* tp_basicsize */ + 0, /* tp_itemsize */ + /* methods */ + (destructor)iterlib_dealloc, /* tp_dealloc */ + 0, /* tp_print */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_reserved */ + 0, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + PyObject_GenericGetAttr, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */ + 0, /* tp_doc */ + (traverseproc)iterlib_traverse, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + PyObject_SelfIter, /* tp_iter */ + (iternextfunc)iterlib_next, /* tp_iternext */ + iterlib_methods, /* tp_methods */ + 0, +}; + +static PyObject * +iterlib_new_iter(PyObject *seq) +{ + iterlib_object *it; + + if (!ITERLIB_CHECK(seq)) { + PyErr_BadInternalCall(); + return NULL; + } +#ifdef ITERLIB_READY + if (ITERLIB_READY(seq) == -1) + return NULL; +#endif + it = PyObject_GC_New(iterlib_object, &ITERLIB_ITER_TYPE); + if (it == NULL) + return NULL; + it->it_index = 0; + Py_INCREF(seq); + it->it_seq = seq; + _PyObject_GC_TRACK(it); + return (PyObject *)it; +} + +#undef ITERLIB_ITER_TYPE +#undef ITERLIB_ITER_TYPE_NAME +#undef ITERLIB_CHECK +#undef ITERLIB_READY +#undef ITERLIB_LEN +#undef ITERLIB_GET_ITEM diff -r b0087e17cd5e Objects/listobject.c --- a/Objects/listobject.c Fri Jul 01 17:57:30 2016 +0300 +++ b/Objects/listobject.c Sat Jul 02 09:33:04 2016 +0300 @@ -2322,8 +2322,7 @@ list_sizeof(PyListObject *self) return PyLong_FromSsize_t(res); } -static PyObject *list_iter(PyObject *seq); -static PyObject *list_reversed(PyListObject* seq, PyObject* unused); +static PyObject *list_reversed(PyObject* seq, PyObject* unused); PyDoc_STRVAR(getitem_doc, "x.__getitem__(y) <==> x[y]"); @@ -2617,6 +2616,145 @@ static PyMappingMethods list_as_mapping (objobjargproc)list_ass_subscript }; +/*********************** List Iterator **************************/ + +#define ITERLIB_ITER_TYPE PyListIter_Type +#define ITERLIB_ITER_TYPE_NAME "tuple_iterator" +#define ITERLIB_CHECK PyList_Check +#define ITERLIB_LEN PyList_GET_SIZE +#define ITERLIB_GET_ITEM PyList_GET_ITEM +#define ITERLIB_CHECK_ITEM(item) (Py_INCREF((item)), 1) +#include "iterlib.h" + +/*********************** List Reverse Iterator **************************/ + +static PyObject *list_reversed(PyObject *, PyObject *); +static PyObject *listreviter_next(iterlib_object *); +static PyObject *listreviter_len(iterlib_object *); +static PyObject *listreviter_reduce(iterlib_object *); +static PyObject *listreviter_setstate(iterlib_object *, PyObject *); + +static PyMethodDef listreviter_methods[] = { + {"__length_hint__", (PyCFunction)listreviter_len, METH_NOARGS, length_hint_doc}, + {"__reduce__", (PyCFunction)listreviter_reduce, METH_NOARGS, reduce_doc}, + {"__setstate__", (PyCFunction)listreviter_setstate, METH_O, setstate_doc}, + {NULL, NULL} /* sentinel */ +}; + +PyTypeObject PyListRevIter_Type = { + PyVarObject_HEAD_INIT(&PyType_Type, 0) + "list_reverseiterator", /* tp_name */ + sizeof(iterlib_object), /* tp_basicsize */ + 0, /* tp_itemsize */ + /* methods */ + (destructor)iterlib_dealloc, /* tp_dealloc */ + 0, /* tp_print */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_reserved */ + 0, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + PyObject_GenericGetAttr, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,/* tp_flags */ + 0, /* tp_doc */ + (traverseproc)iterlib_traverse, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + PyObject_SelfIter, /* tp_iter */ + (iternextfunc)listreviter_next, /* tp_iternext */ + listreviter_methods, /* tp_methods */ + 0, +}; + +static PyObject * +list_reversed(PyObject *seq, PyObject *unused) +{ + iterlib_object *it; + + it = PyObject_GC_New(iterlib_object, &PyListRevIter_Type); + if (it == NULL) + return NULL; + assert(PyList_Check(seq)); + it->it_index = PyList_GET_SIZE(seq) - 1; + Py_INCREF(seq); + it->it_seq = seq; + PyObject_GC_Track(it); + return (PyObject *)it; +} + +static PyObject * +listreviter_next(iterlib_object *it) +{ + PyObject *item; + Py_ssize_t index; + PyObject *seq; + + assert(it != NULL); + seq = it->it_seq; + if (seq == NULL) { + return NULL; + } + assert(PyList_Check(seq)); + + index = it->it_index; + if (index>=0 && index < PyList_GET_SIZE(seq)) { + item = PyList_GET_ITEM(seq, index); + it->it_index--; + Py_INCREF(item); + return item; + } + it->it_index = -1; + it->it_seq = NULL; + Py_DECREF(seq); + return NULL; +} + +static PyObject * +listreviter_len(iterlib_object *it) +{ + Py_ssize_t len = it->it_index + 1; + if (it->it_seq == NULL || PyList_GET_SIZE(it->it_seq) < len) + len = 0; + return PyLong_FromSsize_t(len); +} + +static PyObject * +listreviter_reduce(iterlib_object *it) +{ + if (it->it_seq == NULL) { + return Py_BuildValue("N(())", _PyObject_GetBuiltin("iter")); + } + else { + return Py_BuildValue("N(O)n", _PyObject_GetBuiltin("reversed"), + it->it_seq, it->it_index); + } +} + +static PyObject * +listreviter_setstate(iterlib_object *it, PyObject *state) +{ + Py_ssize_t index = PyLong_AsSsize_t(state); + if (index == -1 && PyErr_Occurred()) + return NULL; + if (it->it_seq != NULL) { + if (index < -1) + index = -1; + else if (index > PyList_GET_SIZE(it->it_seq) - 1) + index = PyList_GET_SIZE(it->it_seq) - 1; + it->it_index = index; + } + Py_RETURN_NONE; +} + + PyTypeObject PyList_Type = { PyVarObject_HEAD_INIT(&PyType_Type, 0) "list", @@ -2644,7 +2782,7 @@ PyTypeObject PyList_Type = { (inquiry)list_clear, /* tp_clear */ list_richcompare, /* tp_richcompare */ 0, /* tp_weaklistoffset */ - list_iter, /* tp_iter */ + iterlib_new_iter, /* tp_iter */ 0, /* tp_iternext */ list_methods, /* tp_methods */ 0, /* tp_members */ @@ -2659,329 +2797,3 @@ PyTypeObject PyList_Type = { PyType_GenericNew, /* tp_new */ PyObject_GC_Del, /* tp_free */ }; - - -/*********************** List Iterator **************************/ - -typedef struct { - PyObject_HEAD - Py_ssize_t it_index; - PyListObject *it_seq; /* Set to NULL when iterator is exhausted */ -} listiterobject; - -static PyObject *list_iter(PyObject *); -static void listiter_dealloc(listiterobject *); -static int listiter_traverse(listiterobject *, visitproc, void *); -static PyObject *listiter_next(listiterobject *); -static PyObject *listiter_len(listiterobject *); -static PyObject *listiter_reduce_general(void *_it, int forward); -static PyObject *listiter_reduce(listiterobject *); -static PyObject *listiter_setstate(listiterobject *, PyObject *state); - -PyDoc_STRVAR(length_hint_doc, "Private method returning an estimate of len(list(it))."); -PyDoc_STRVAR(reduce_doc, "Return state information for pickling."); -PyDoc_STRVAR(setstate_doc, "Set state information for unpickling."); - -static PyMethodDef listiter_methods[] = { - {"__length_hint__", (PyCFunction)listiter_len, METH_NOARGS, length_hint_doc}, - {"__reduce__", (PyCFunction)listiter_reduce, METH_NOARGS, reduce_doc}, - {"__setstate__", (PyCFunction)listiter_setstate, METH_O, setstate_doc}, - {NULL, NULL} /* sentinel */ -}; - -PyTypeObject PyListIter_Type = { - PyVarObject_HEAD_INIT(&PyType_Type, 0) - "list_iterator", /* tp_name */ - sizeof(listiterobject), /* tp_basicsize */ - 0, /* tp_itemsize */ - /* methods */ - (destructor)listiter_dealloc, /* tp_dealloc */ - 0, /* tp_print */ - 0, /* tp_getattr */ - 0, /* tp_setattr */ - 0, /* tp_reserved */ - 0, /* tp_repr */ - 0, /* tp_as_number */ - 0, /* tp_as_sequence */ - 0, /* tp_as_mapping */ - 0, /* tp_hash */ - 0, /* tp_call */ - 0, /* tp_str */ - PyObject_GenericGetAttr, /* tp_getattro */ - 0, /* tp_setattro */ - 0, /* tp_as_buffer */ - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,/* tp_flags */ - 0, /* tp_doc */ - (traverseproc)listiter_traverse, /* tp_traverse */ - 0, /* tp_clear */ - 0, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - PyObject_SelfIter, /* tp_iter */ - (iternextfunc)listiter_next, /* tp_iternext */ - listiter_methods, /* tp_methods */ - 0, /* tp_members */ -}; - - -static PyObject * -list_iter(PyObject *seq) -{ - listiterobject *it; - - if (!PyList_Check(seq)) { - PyErr_BadInternalCall(); - return NULL; - } - it = PyObject_GC_New(listiterobject, &PyListIter_Type); - if (it == NULL) - return NULL; - it->it_index = 0; - Py_INCREF(seq); - it->it_seq = (PyListObject *)seq; - _PyObject_GC_TRACK(it); - return (PyObject *)it; -} - -static void -listiter_dealloc(listiterobject *it) -{ - _PyObject_GC_UNTRACK(it); - Py_XDECREF(it->it_seq); - PyObject_GC_Del(it); -} - -static int -listiter_traverse(listiterobject *it, visitproc visit, void *arg) -{ - Py_VISIT(it->it_seq); - return 0; -} - -static PyObject * -listiter_next(listiterobject *it) -{ - PyListObject *seq; - PyObject *item; - - assert(it != NULL); - seq = it->it_seq; - if (seq == NULL) - return NULL; - assert(PyList_Check(seq)); - - if (it->it_index < PyList_GET_SIZE(seq)) { - item = PyList_GET_ITEM(seq, it->it_index); - ++it->it_index; - Py_INCREF(item); - return item; - } - - it->it_seq = NULL; - Py_DECREF(seq); - return NULL; -} - -static PyObject * -listiter_len(listiterobject *it) -{ - Py_ssize_t len; - if (it->it_seq) { - len = PyList_GET_SIZE(it->it_seq) - it->it_index; - if (len >= 0) - return PyLong_FromSsize_t(len); - } - return PyLong_FromLong(0); -} - -static PyObject * -listiter_reduce(listiterobject *it) -{ - return listiter_reduce_general(it, 1); -} - -static PyObject * -listiter_setstate(listiterobject *it, PyObject *state) -{ - Py_ssize_t index = PyLong_AsSsize_t(state); - if (index == -1 && PyErr_Occurred()) - return NULL; - if (it->it_seq != NULL) { - if (index < 0) - index = 0; - else if (index > PyList_GET_SIZE(it->it_seq)) - index = PyList_GET_SIZE(it->it_seq); /* iterator exhausted */ - it->it_index = index; - } - Py_RETURN_NONE; -} - -/*********************** List Reverse Iterator **************************/ - -typedef struct { - PyObject_HEAD - Py_ssize_t it_index; - PyListObject *it_seq; /* Set to NULL when iterator is exhausted */ -} listreviterobject; - -static PyObject *list_reversed(PyListObject *, PyObject *); -static void listreviter_dealloc(listreviterobject *); -static int listreviter_traverse(listreviterobject *, visitproc, void *); -static PyObject *listreviter_next(listreviterobject *); -static PyObject *listreviter_len(listreviterobject *); -static PyObject *listreviter_reduce(listreviterobject *); -static PyObject *listreviter_setstate(listreviterobject *, PyObject *); - -static PyMethodDef listreviter_methods[] = { - {"__length_hint__", (PyCFunction)listreviter_len, METH_NOARGS, length_hint_doc}, - {"__reduce__", (PyCFunction)listreviter_reduce, METH_NOARGS, reduce_doc}, - {"__setstate__", (PyCFunction)listreviter_setstate, METH_O, setstate_doc}, - {NULL, NULL} /* sentinel */ -}; - -PyTypeObject PyListRevIter_Type = { - PyVarObject_HEAD_INIT(&PyType_Type, 0) - "list_reverseiterator", /* tp_name */ - sizeof(listreviterobject), /* tp_basicsize */ - 0, /* tp_itemsize */ - /* methods */ - (destructor)listreviter_dealloc, /* tp_dealloc */ - 0, /* tp_print */ - 0, /* tp_getattr */ - 0, /* tp_setattr */ - 0, /* tp_reserved */ - 0, /* tp_repr */ - 0, /* tp_as_number */ - 0, /* tp_as_sequence */ - 0, /* tp_as_mapping */ - 0, /* tp_hash */ - 0, /* tp_call */ - 0, /* tp_str */ - PyObject_GenericGetAttr, /* tp_getattro */ - 0, /* tp_setattro */ - 0, /* tp_as_buffer */ - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,/* tp_flags */ - 0, /* tp_doc */ - (traverseproc)listreviter_traverse, /* tp_traverse */ - 0, /* tp_clear */ - 0, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - PyObject_SelfIter, /* tp_iter */ - (iternextfunc)listreviter_next, /* tp_iternext */ - listreviter_methods, /* tp_methods */ - 0, -}; - -static PyObject * -list_reversed(PyListObject *seq, PyObject *unused) -{ - listreviterobject *it; - - it = PyObject_GC_New(listreviterobject, &PyListRevIter_Type); - if (it == NULL) - return NULL; - assert(PyList_Check(seq)); - it->it_index = PyList_GET_SIZE(seq) - 1; - Py_INCREF(seq); - it->it_seq = seq; - PyObject_GC_Track(it); - return (PyObject *)it; -} - -static void -listreviter_dealloc(listreviterobject *it) -{ - PyObject_GC_UnTrack(it); - Py_XDECREF(it->it_seq); - PyObject_GC_Del(it); -} - -static int -listreviter_traverse(listreviterobject *it, visitproc visit, void *arg) -{ - Py_VISIT(it->it_seq); - return 0; -} - -static PyObject * -listreviter_next(listreviterobject *it) -{ - PyObject *item; - Py_ssize_t index; - PyListObject *seq; - - assert(it != NULL); - seq = it->it_seq; - if (seq == NULL) { - return NULL; - } - assert(PyList_Check(seq)); - - index = it->it_index; - if (index>=0 && index < PyList_GET_SIZE(seq)) { - item = PyList_GET_ITEM(seq, index); - it->it_index--; - Py_INCREF(item); - return item; - } - it->it_index = -1; - it->it_seq = NULL; - Py_DECREF(seq); - return NULL; -} - -static PyObject * -listreviter_len(listreviterobject *it) -{ - Py_ssize_t len = it->it_index + 1; - if (it->it_seq == NULL || PyList_GET_SIZE(it->it_seq) < len) - len = 0; - return PyLong_FromSsize_t(len); -} - -static PyObject * -listreviter_reduce(listreviterobject *it) -{ - return listiter_reduce_general(it, 0); -} - -static PyObject * -listreviter_setstate(listreviterobject *it, PyObject *state) -{ - Py_ssize_t index = PyLong_AsSsize_t(state); - if (index == -1 && PyErr_Occurred()) - return NULL; - if (it->it_seq != NULL) { - if (index < -1) - index = -1; - else if (index > PyList_GET_SIZE(it->it_seq) - 1) - index = PyList_GET_SIZE(it->it_seq) - 1; - it->it_index = index; - } - Py_RETURN_NONE; -} - -/* common pickling support */ - -static PyObject * -listiter_reduce_general(void *_it, int forward) -{ - PyObject *list; - - /* the objects are not the same, index is of different types! */ - if (forward) { - listiterobject *it = (listiterobject *)_it; - if (it->it_seq) - return Py_BuildValue("N(O)n", _PyObject_GetBuiltin("iter"), - it->it_seq, it->it_index); - } else { - listreviterobject *it = (listreviterobject *)_it; - if (it->it_seq) - return Py_BuildValue("N(O)n", _PyObject_GetBuiltin("reversed"), - it->it_seq, it->it_index); - } - /* empty iterator, create an empty list */ - list = PyList_New(0); - if (list == NULL) - return NULL; - return Py_BuildValue("N(N)", _PyObject_GetBuiltin("iter"), list); -} diff -r b0087e17cd5e Objects/tupleobject.c --- a/Objects/tupleobject.c Fri Jul 01 17:57:30 2016 +0300 +++ b/Objects/tupleobject.c Sat Jul 02 09:33:04 2016 +0300 @@ -776,7 +776,15 @@ static PyMappingMethods tuple_as_mapping 0 }; -static PyObject *tuple_iter(PyObject *seq); +/*********************** Tuple Iterator **************************/ + +#define ITERLIB_ITER_TYPE PyTupleIter_Type +#define ITERLIB_ITER_TYPE_NAME "tuple_iterator" +#define ITERLIB_CHECK PyTuple_Check +#define ITERLIB_LEN PyTuple_GET_SIZE +#define ITERLIB_GET_ITEM PyTuple_GET_ITEM +#define ITERLIB_CHECK_ITEM(item) (Py_INCREF((item)), 1) +#include "iterlib.h" PyTypeObject PyTuple_Type = { PyVarObject_HEAD_INIT(&PyType_Type, 0) @@ -805,7 +813,7 @@ PyTypeObject PyTuple_Type = { 0, /* tp_clear */ tuplerichcompare, /* tp_richcompare */ 0, /* tp_weaklistoffset */ - tuple_iter, /* tp_iter */ + iterlib_new_iter, /* tp_iter */ 0, /* tp_iternext */ tuple_methods, /* tp_methods */ 0, /* tp_members */ @@ -918,149 +926,3 @@ PyTuple_Fini(void) show_track(); #endif } - -/*********************** Tuple Iterator **************************/ - -typedef struct { - PyObject_HEAD - Py_ssize_t it_index; - PyTupleObject *it_seq; /* Set to NULL when iterator is exhausted */ -} tupleiterobject; - -static void -tupleiter_dealloc(tupleiterobject *it) -{ - _PyObject_GC_UNTRACK(it); - Py_XDECREF(it->it_seq); - PyObject_GC_Del(it); -} - -static int -tupleiter_traverse(tupleiterobject *it, visitproc visit, void *arg) -{ - Py_VISIT(it->it_seq); - return 0; -} - -static PyObject * -tupleiter_next(tupleiterobject *it) -{ - PyTupleObject *seq; - PyObject *item; - - assert(it != NULL); - seq = it->it_seq; - if (seq == NULL) - return NULL; - assert(PyTuple_Check(seq)); - - if (it->it_index < PyTuple_GET_SIZE(seq)) { - item = PyTuple_GET_ITEM(seq, it->it_index); - ++it->it_index; - Py_INCREF(item); - return item; - } - - it->it_seq = NULL; - Py_DECREF(seq); - return NULL; -} - -static PyObject * -tupleiter_len(tupleiterobject *it) -{ - Py_ssize_t len = 0; - if (it->it_seq) - len = PyTuple_GET_SIZE(it->it_seq) - it->it_index; - return PyLong_FromSsize_t(len); -} - -PyDoc_STRVAR(length_hint_doc, "Private method returning an estimate of len(list(it))."); - -static PyObject * -tupleiter_reduce(tupleiterobject *it) -{ - if (it->it_seq) - return Py_BuildValue("N(O)n", _PyObject_GetBuiltin("iter"), - it->it_seq, it->it_index); - else - return Py_BuildValue("N(())", _PyObject_GetBuiltin("iter")); -} - -static PyObject * -tupleiter_setstate(tupleiterobject *it, PyObject *state) -{ - Py_ssize_t index = PyLong_AsSsize_t(state); - if (index == -1 && PyErr_Occurred()) - return NULL; - if (it->it_seq != NULL) { - if (index < 0) - index = 0; - else if (index > PyTuple_GET_SIZE(it->it_seq)) - index = PyTuple_GET_SIZE(it->it_seq); /* exhausted iterator */ - it->it_index = index; - } - Py_RETURN_NONE; -} - -PyDoc_STRVAR(reduce_doc, "Return state information for pickling."); -PyDoc_STRVAR(setstate_doc, "Set state information for unpickling."); - -static PyMethodDef tupleiter_methods[] = { - {"__length_hint__", (PyCFunction)tupleiter_len, METH_NOARGS, length_hint_doc}, - {"__reduce__", (PyCFunction)tupleiter_reduce, METH_NOARGS, reduce_doc}, - {"__setstate__", (PyCFunction)tupleiter_setstate, METH_O, setstate_doc}, - {NULL, NULL} /* sentinel */ -}; - -PyTypeObject PyTupleIter_Type = { - PyVarObject_HEAD_INIT(&PyType_Type, 0) - "tuple_iterator", /* tp_name */ - sizeof(tupleiterobject), /* tp_basicsize */ - 0, /* tp_itemsize */ - /* methods */ - (destructor)tupleiter_dealloc, /* tp_dealloc */ - 0, /* tp_print */ - 0, /* tp_getattr */ - 0, /* tp_setattr */ - 0, /* tp_reserved */ - 0, /* tp_repr */ - 0, /* tp_as_number */ - 0, /* tp_as_sequence */ - 0, /* tp_as_mapping */ - 0, /* tp_hash */ - 0, /* tp_call */ - 0, /* tp_str */ - PyObject_GenericGetAttr, /* tp_getattro */ - 0, /* tp_setattro */ - 0, /* tp_as_buffer */ - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,/* tp_flags */ - 0, /* tp_doc */ - (traverseproc)tupleiter_traverse, /* tp_traverse */ - 0, /* tp_clear */ - 0, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - PyObject_SelfIter, /* tp_iter */ - (iternextfunc)tupleiter_next, /* tp_iternext */ - tupleiter_methods, /* tp_methods */ - 0, -}; - -static PyObject * -tuple_iter(PyObject *seq) -{ - tupleiterobject *it; - - if (!PyTuple_Check(seq)) { - PyErr_BadInternalCall(); - return NULL; - } - it = PyObject_GC_New(tupleiterobject, &PyTupleIter_Type); - if (it == NULL) - return NULL; - it->it_index = 0; - Py_INCREF(seq); - it->it_seq = (PyTupleObject *)seq; - _PyObject_GC_TRACK(it); - return (PyObject *)it; -} diff -r b0087e17cd5e Objects/unicodeobject.c --- a/Objects/unicodeobject.c Fri Jul 01 17:57:30 2016 +0300 +++ b/Objects/unicodeobject.c Sat Jul 02 09:33:04 2016 +0300 @@ -14905,7 +14905,17 @@ or repr(object).\n\ encoding defaults to sys.getdefaultencoding().\n\ errors defaults to 'strict'."); -static PyObject *unicode_iter(PyObject *seq); +/********************* Unicode Iterator **************************/ + +#define ITERLIB_ITER_TYPE PyUnicodeIter_Type +#define ITERLIB_ITER_TYPE_NAME "str_iterator" +#define ITERLIB_CHECK PyUnicode_Check +#define ITERLIB_READY PyUnicode_READY +#define ITERLIB_LEN PyUnicode_GET_LENGTH +#define ITERLIB_GET_ITEM(seq,i) \ + PyUnicode_FromOrdinal(PyUnicode_READ_CHAR((seq), (i))) +#define ITERLIB_CHECK_ITEM(item) ((item) != NULL) +#include "iterlib.h" PyTypeObject PyUnicode_Type = { PyVarObject_HEAD_INIT(&PyType_Type, 0) @@ -14935,7 +14945,7 @@ PyTypeObject PyUnicode_Type = { 0, /* tp_clear */ PyUnicode_RichCompare, /* tp_richcompare */ 0, /* tp_weaklistoffset */ - unicode_iter, /* tp_iter */ + iterlib_new_iter, /* tp_iter */ 0, /* tp_iternext */ unicode_methods, /* tp_methods */ 0, /* tp_members */ @@ -15141,165 +15151,6 @@ void } -/********************* Unicode Iterator **************************/ - -typedef struct { - PyObject_HEAD - Py_ssize_t it_index; - PyObject *it_seq; /* Set to NULL when iterator is exhausted */ -} unicodeiterobject; - -static void -unicodeiter_dealloc(unicodeiterobject *it) -{ - _PyObject_GC_UNTRACK(it); - Py_XDECREF(it->it_seq); - PyObject_GC_Del(it); -} - -static int -unicodeiter_traverse(unicodeiterobject *it, visitproc visit, void *arg) -{ - Py_VISIT(it->it_seq); - return 0; -} - -static PyObject * -unicodeiter_next(unicodeiterobject *it) -{ - PyObject *seq, *item; - - assert(it != NULL); - seq = it->it_seq; - if (seq == NULL) - return NULL; - assert(_PyUnicode_CHECK(seq)); - - if (it->it_index < PyUnicode_GET_LENGTH(seq)) { - int kind = PyUnicode_KIND(seq); - void *data = PyUnicode_DATA(seq); - Py_UCS4 chr = PyUnicode_READ(kind, data, it->it_index); - item = PyUnicode_FromOrdinal(chr); - if (item != NULL) - ++it->it_index; - return item; - } - - it->it_seq = NULL; - Py_DECREF(seq); - return NULL; -} - -static PyObject * -unicodeiter_len(unicodeiterobject *it) -{ - Py_ssize_t len = 0; - if (it->it_seq) - len = PyUnicode_GET_LENGTH(it->it_seq) - it->it_index; - return PyLong_FromSsize_t(len); -} - -PyDoc_STRVAR(length_hint_doc, "Private method returning an estimate of len(list(it))."); - -static PyObject * -unicodeiter_reduce(unicodeiterobject *it) -{ - if (it->it_seq != NULL) { - return Py_BuildValue("N(O)n", _PyObject_GetBuiltin("iter"), - it->it_seq, it->it_index); - } else { - PyObject *u = PyUnicode_FromUnicode(NULL, 0); - if (u == NULL) - return NULL; - return Py_BuildValue("N(N)", _PyObject_GetBuiltin("iter"), u); - } -} - -PyDoc_STRVAR(reduce_doc, "Return state information for pickling."); - -static PyObject * -unicodeiter_setstate(unicodeiterobject *it, PyObject *state) -{ - Py_ssize_t index = PyLong_AsSsize_t(state); - if (index == -1 && PyErr_Occurred()) - return NULL; - if (it->it_seq != NULL) { - if (index < 0) - index = 0; - else if (index > PyUnicode_GET_LENGTH(it->it_seq)) - index = PyUnicode_GET_LENGTH(it->it_seq); /* iterator truncated */ - it->it_index = index; - } - Py_RETURN_NONE; -} - -PyDoc_STRVAR(setstate_doc, "Set state information for unpickling."); - -static PyMethodDef unicodeiter_methods[] = { - {"__length_hint__", (PyCFunction)unicodeiter_len, METH_NOARGS, - length_hint_doc}, - {"__reduce__", (PyCFunction)unicodeiter_reduce, METH_NOARGS, - reduce_doc}, - {"__setstate__", (PyCFunction)unicodeiter_setstate, METH_O, - setstate_doc}, - {NULL, NULL} /* sentinel */ -}; - -PyTypeObject PyUnicodeIter_Type = { - PyVarObject_HEAD_INIT(&PyType_Type, 0) - "str_iterator", /* tp_name */ - sizeof(unicodeiterobject), /* tp_basicsize */ - 0, /* tp_itemsize */ - /* methods */ - (destructor)unicodeiter_dealloc, /* tp_dealloc */ - 0, /* tp_print */ - 0, /* tp_getattr */ - 0, /* tp_setattr */ - 0, /* tp_reserved */ - 0, /* tp_repr */ - 0, /* tp_as_number */ - 0, /* tp_as_sequence */ - 0, /* tp_as_mapping */ - 0, /* tp_hash */ - 0, /* tp_call */ - 0, /* tp_str */ - PyObject_GenericGetAttr, /* tp_getattro */ - 0, /* tp_setattro */ - 0, /* tp_as_buffer */ - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,/* tp_flags */ - 0, /* tp_doc */ - (traverseproc)unicodeiter_traverse, /* tp_traverse */ - 0, /* tp_clear */ - 0, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - PyObject_SelfIter, /* tp_iter */ - (iternextfunc)unicodeiter_next, /* tp_iternext */ - unicodeiter_methods, /* tp_methods */ - 0, -}; - -static PyObject * -unicode_iter(PyObject *seq) -{ - unicodeiterobject *it; - - if (!PyUnicode_Check(seq)) { - PyErr_BadInternalCall(); - return NULL; - } - if (PyUnicode_READY(seq) == -1) - return NULL; - it = PyObject_GC_New(unicodeiterobject, &PyUnicodeIter_Type); - if (it == NULL) - return NULL; - it->it_index = 0; - Py_INCREF(seq); - it->it_seq = seq; - _PyObject_GC_TRACK(it); - return (PyObject *)it; -} - - size_t Py_UNICODE_strlen(const Py_UNICODE *u) { diff -r b0087e17cd5e PCbuild/pythoncore.vcxproj --- a/PCbuild/pythoncore.vcxproj Fri Jul 01 17:57:30 2016 +0300 +++ b/PCbuild/pythoncore.vcxproj Sat Jul 02 09:33:04 2016 +0300 @@ -195,6 +195,7 @@ + diff -r b0087e17cd5e PCbuild/pythoncore.vcxproj.filters --- a/PCbuild/pythoncore.vcxproj.filters Fri Jul 01 17:57:30 2016 +0300 +++ b/PCbuild/pythoncore.vcxproj.filters Sat Jul 02 09:33:04 2016 +0300 @@ -384,6 +384,9 @@ Modules\cjkcodecs + + Objects + Objects