Commit a24ddcd8 authored by Raymond Hettinger's avatar Raymond Hettinger

SF 564601 adding rangeiterobject to make xrange() iterate like range().

parent a9eb41b6
...@@ -8,8 +8,6 @@ typedef struct { ...@@ -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) ...@@ -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,31 +86,86 @@ range_repr(rangeobject *r) ...@@ -90,31 +86,86 @@ range_repr(rangeobject *r)
return rtn; return rtn;
} }
static PyObject * static PySequenceMethods range_as_sequence = {
range_getiter(rangeobject *r) (inquiry)range_length, /* sq_length */
0, /* sq_concat */
0, /* sq_repeat */
(intargfunc)range_item, /* sq_item */
0, /* sq_slice */
};
staticforward PyObject * range_iter(PyObject *seq);
PyTypeObject PyRange_Type = {
PyObject_HEAD_INIT(&PyType_Type)
0, /* Number of items for varobject */
"xrange", /* Name of this type */
sizeof(rangeobject), /* Basic object size */
0, /* Item size for varobject */
(destructor)PyObject_Del, /* tp_dealloc */
0, /* tp_print */
0, /* tp_getattr */
0, /* tp_setattr */
0, /* tp_compare */
(reprfunc)range_repr, /* tp_repr */
0, /* tp_as_number */
&range_as_sequence, /* tp_as_sequence */
0, /* tp_as_mapping */
0, /* tp_hash */
0, /* tp_call */
0, /* tp_str */
0, /* 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)range_iter, /* tp_iter */
};
/*********************** Xrange Iterator **************************/
typedef struct {
PyObject_HEAD
long index;
long start;
long step;
long len;
} rangeiterobject;
PyTypeObject Pyrangeiter_Type;
PyObject *
range_iter(PyObject *seq)
{ {
rangeobject *obj; rangeiterobject *it;
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 (!PyRange_Check(seq)) {
if (obj == NULL) PyErr_BadInternalCall();
return NULL; 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;
}
obj->start = r->start; static PyObject *
obj->len = r->len; rangeiter_getiter(PyObject *it)
obj->step = r->step; {
obj->index = 0; Py_INCREF(it);
obj->used = 1; return it;
return (PyObject *) obj;
} }
static PyObject * static PyObject *
range_next(rangeobject *r) rangeiter_next(rangeiterobject *r)
{ {
if (r->index < r->len) if (r->index < r->len)
return PyInt_FromLong(r->start + (r->index++) * r->step); return PyInt_FromLong(r->start + (r->index++) * r->step);
...@@ -122,34 +173,27 @@ range_next(rangeobject *r) ...@@ -122,34 +173,27 @@ range_next(rangeobject *r)
return NULL; return NULL;
} }
static PyMethodDef range_methods[] = { static PyMethodDef rangeiter_methods[] = {
{"next", (PyCFunction)range_next, METH_NOARGS, {"next", (PyCFunction)rangeiter_next, METH_NOARGS,
"it.next() -- get the next value, or raise StopIteration"}, "it.next() -- get the next value, or raise StopIteration"},
{NULL, NULL} /* sentinel */ {NULL, NULL} /* sentinel */
}; };
static PySequenceMethods range_as_sequence = { PyTypeObject Pyrangeiter_Type = {
(inquiry)range_length, /* sq_length */
0, /* sq_concat */
0, /* sq_repeat */
(intargfunc)range_item, /* sq_item */
0, /* sq_slice */
};
PyTypeObject PyRange_Type = {
PyObject_HEAD_INIT(&PyType_Type) PyObject_HEAD_INIT(&PyType_Type)
0, /* Number of items for varobject */ 0, /* ob_size */
"xrange", /* Name of this type */ "rangeiterator", /* tp_name */
sizeof(rangeobject), /* Basic object size */ sizeof(rangeiterobject), /* tp_basicsize */
0, /* Item size for varobject */ 0, /* tp_itemsize */
/* methods */
(destructor)PyObject_Del, /* tp_dealloc */ (destructor)PyObject_Del, /* tp_dealloc */
0, /* tp_print */ 0, /* tp_print */
0, /* tp_getattr */ 0, /* tp_getattr */
0, /* tp_setattr */ 0, /* tp_setattr */
0, /* tp_compare */ 0, /* tp_compare */
(reprfunc)range_repr, /* tp_repr */ 0, /* tp_repr */
0, /* tp_as_number */ 0, /* tp_as_number */
&range_as_sequence, /* tp_as_sequence */ 0, /* tp_as_sequence */
0, /* tp_as_mapping */ 0, /* tp_as_mapping */
0, /* tp_hash */ 0, /* tp_hash */
0, /* tp_call */ 0, /* tp_call */
...@@ -163,7 +207,8 @@ PyTypeObject PyRange_Type = { ...@@ -163,7 +207,8 @@ 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)rangeiter_getiter, /* tp_iter */
(iternextfunc)range_next, /* tp_iternext */ (iternextfunc)rangeiter_next, /* tp_iternext */
range_methods, /* tp_methods */ rangeiter_methods, /* tp_methods */
}; };
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment