mirror of
https://github.com/python/cpython.git
synced 2025-09-26 18:29:57 +00:00
SF 564601 adding rangeiterobject to make xrange() iterate like range().
This commit is contained in:
parent
d842e07470
commit
48165d40cb
1 changed files with 91 additions and 46 deletions
|
@ -8,8 +8,6 @@ typedef struct {
|
||||||
long start;
|
long start;
|
||||||
long step;
|
long step;
|
||||||
long len;
|
long len;
|
||||||
long index;
|
|
||||||
int used; /* Set to 1 if called by range_getiter */
|
|
||||||
} rangeobject;
|
} rangeobject;
|
||||||
|
|
||||||
PyObject *
|
PyObject *
|
||||||
|
@ -45,8 +43,6 @@ PyRange_New(long start, long len, long step, int reps)
|
||||||
obj->start = start;
|
obj->start = start;
|
||||||
obj->len = len;
|
obj->len = len;
|
||||||
obj->step = step;
|
obj->step = step;
|
||||||
obj->index = 0;
|
|
||||||
obj->used = 0;
|
|
||||||
|
|
||||||
return (PyObject *) obj;
|
return (PyObject *) obj;
|
||||||
}
|
}
|
||||||
|
@ -90,44 +86,6 @@ range_repr(rangeobject *r)
|
||||||
return rtn;
|
return rtn;
|
||||||
}
|
}
|
||||||
|
|
||||||
static PyObject *
|
|
||||||
range_getiter(rangeobject *r)
|
|
||||||
{
|
|
||||||
rangeobject *obj;
|
|
||||||
if (r->used == 0 || r->index >= r->len) {
|
|
||||||
Py_INCREF(r);
|
|
||||||
r->used = 1;
|
|
||||||
r->index = 0;
|
|
||||||
return (PyObject *)r;
|
|
||||||
}
|
|
||||||
|
|
||||||
obj = PyObject_NEW(rangeobject, &PyRange_Type);
|
|
||||||
if (obj == NULL)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
obj->start = r->start;
|
|
||||||
obj->len = r->len;
|
|
||||||
obj->step = r->step;
|
|
||||||
obj->index = 0;
|
|
||||||
obj->used = 1;
|
|
||||||
return (PyObject *) obj;
|
|
||||||
}
|
|
||||||
|
|
||||||
static PyObject *
|
|
||||||
range_next(rangeobject *r)
|
|
||||||
{
|
|
||||||
if (r->index < r->len)
|
|
||||||
return PyInt_FromLong(r->start + (r->index++) * r->step);
|
|
||||||
PyErr_SetObject(PyExc_StopIteration, Py_None);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
static PyMethodDef range_methods[] = {
|
|
||||||
{"next", (PyCFunction)range_next, METH_NOARGS,
|
|
||||||
"it.next() -- get the next value, or raise StopIteration"},
|
|
||||||
{NULL, NULL} /* sentinel */
|
|
||||||
};
|
|
||||||
|
|
||||||
static PySequenceMethods range_as_sequence = {
|
static PySequenceMethods range_as_sequence = {
|
||||||
(inquiry)range_length, /* sq_length */
|
(inquiry)range_length, /* sq_length */
|
||||||
0, /* sq_concat */
|
0, /* sq_concat */
|
||||||
|
@ -136,6 +94,8 @@ static PySequenceMethods range_as_sequence = {
|
||||||
0, /* sq_slice */
|
0, /* sq_slice */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
staticforward PyObject * range_iter(PyObject *seq);
|
||||||
|
|
||||||
PyTypeObject PyRange_Type = {
|
PyTypeObject PyRange_Type = {
|
||||||
PyObject_HEAD_INIT(&PyType_Type)
|
PyObject_HEAD_INIT(&PyType_Type)
|
||||||
0, /* Number of items for varobject */
|
0, /* Number of items for varobject */
|
||||||
|
@ -154,7 +114,7 @@ PyTypeObject PyRange_Type = {
|
||||||
0, /* tp_hash */
|
0, /* tp_hash */
|
||||||
0, /* tp_call */
|
0, /* tp_call */
|
||||||
0, /* tp_str */
|
0, /* tp_str */
|
||||||
PyObject_GenericGetAttr, /* tp_getattro */
|
0, /* tp_getattro */
|
||||||
0, /* tp_setattro */
|
0, /* tp_setattro */
|
||||||
0, /* tp_as_buffer */
|
0, /* tp_as_buffer */
|
||||||
Py_TPFLAGS_DEFAULT, /* tp_flags */
|
Py_TPFLAGS_DEFAULT, /* tp_flags */
|
||||||
|
@ -163,7 +123,92 @@ PyTypeObject PyRange_Type = {
|
||||||
0, /* tp_clear */
|
0, /* tp_clear */
|
||||||
0, /* tp_richcompare */
|
0, /* tp_richcompare */
|
||||||
0, /* tp_weaklistoffset */
|
0, /* tp_weaklistoffset */
|
||||||
(getiterfunc)range_getiter, /* tp_iter */
|
(getiterfunc)range_iter, /* tp_iter */
|
||||||
(iternextfunc)range_next, /* tp_iternext */
|
|
||||||
range_methods, /* tp_methods */
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/*********************** Xrange Iterator **************************/
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
PyObject_HEAD
|
||||||
|
long index;
|
||||||
|
long start;
|
||||||
|
long step;
|
||||||
|
long len;
|
||||||
|
} rangeiterobject;
|
||||||
|
|
||||||
|
PyTypeObject Pyrangeiter_Type;
|
||||||
|
|
||||||
|
PyObject *
|
||||||
|
range_iter(PyObject *seq)
|
||||||
|
{
|
||||||
|
rangeiterobject *it;
|
||||||
|
|
||||||
|
if (!PyRange_Check(seq)) {
|
||||||
|
PyErr_BadInternalCall();
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
it = PyObject_New(rangeiterobject, &Pyrangeiter_Type);
|
||||||
|
if (it == NULL)
|
||||||
|
return NULL;
|
||||||
|
it->index = 0;
|
||||||
|
it->start = ((rangeobject *)seq)->start;
|
||||||
|
it->step = ((rangeobject *)seq)->step;
|
||||||
|
it->len = ((rangeobject *)seq)->len;
|
||||||
|
return (PyObject *)it;
|
||||||
|
}
|
||||||
|
|
||||||
|
static PyObject *
|
||||||
|
rangeiter_getiter(PyObject *it)
|
||||||
|
{
|
||||||
|
Py_INCREF(it);
|
||||||
|
return it;
|
||||||
|
}
|
||||||
|
|
||||||
|
static PyObject *
|
||||||
|
rangeiter_next(rangeiterobject *r)
|
||||||
|
{
|
||||||
|
if (r->index < r->len)
|
||||||
|
return PyInt_FromLong(r->start + (r->index++) * r->step);
|
||||||
|
PyErr_SetObject(PyExc_StopIteration, Py_None);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static PyMethodDef rangeiter_methods[] = {
|
||||||
|
{"next", (PyCFunction)rangeiter_next, METH_NOARGS,
|
||||||
|
"it.next() -- get the next value, or raise StopIteration"},
|
||||||
|
{NULL, NULL} /* sentinel */
|
||||||
|
};
|
||||||
|
|
||||||
|
PyTypeObject Pyrangeiter_Type = {
|
||||||
|
PyObject_HEAD_INIT(&PyType_Type)
|
||||||
|
0, /* ob_size */
|
||||||
|
"rangeiterator", /* tp_name */
|
||||||
|
sizeof(rangeiterobject), /* tp_basicsize */
|
||||||
|
0, /* tp_itemsize */
|
||||||
|
/* methods */
|
||||||
|
(destructor)PyObject_Del, /* tp_dealloc */
|
||||||
|
0, /* tp_print */
|
||||||
|
0, /* tp_getattr */
|
||||||
|
0, /* tp_setattr */
|
||||||
|
0, /* tp_compare */
|
||||||
|
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, /* tp_flags */
|
||||||
|
0, /* tp_doc */
|
||||||
|
0, /* tp_traverse */
|
||||||
|
0, /* tp_clear */
|
||||||
|
0, /* tp_richcompare */
|
||||||
|
0, /* tp_weaklistoffset */
|
||||||
|
(getiterfunc)rangeiter_getiter, /* tp_iter */
|
||||||
|
(iternextfunc)rangeiter_next, /* tp_iternext */
|
||||||
|
rangeiter_methods, /* tp_methods */
|
||||||
|
};
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue