summaryrefslogtreecommitdiffstats
path: root/Objects/rangeobject.c
diff options
context:
space:
mode:
Diffstat (limited to 'Objects/rangeobject.c')
-rw-r--r--Objects/rangeobject.c237
1 files changed, 15 insertions, 222 deletions
diff --git a/Objects/rangeobject.c b/Objects/rangeobject.c
index cec38f0..0b0966f 100644
--- a/Objects/rangeobject.c
+++ b/Objects/rangeobject.c
@@ -10,58 +10,20 @@ typedef struct {
long start;
long step;
long len;
- int reps;
- long totlen;
} rangeobject;
-static int
-long_mul(long i, long j, long *kk)
-{
- PyObject *a;
- PyObject *b;
- PyObject *c;
-
- if ((a = PyInt_FromLong(i)) == NULL)
- return 0;
-
- if ((b = PyInt_FromLong(j)) == NULL)
- return 0;
-
- c = PyNumber_Multiply(a, b);
-
- Py_DECREF(a);
- Py_DECREF(b);
-
- if (c == NULL)
- return 0;
-
- *kk = PyInt_AS_LONG(c);
- Py_DECREF(c);
-
- if (*kk > INT_MAX) {
- PyErr_SetString(PyExc_OverflowError,
- "integer multiplication");
- return 0;
- }
- else
- return 1;
-}
-
PyObject *
-PyRange_New(long start, long len, long step, int reps)
+PyRange_New(long start, long len, long step)
{
- long totlen = -1;
rangeobject *obj = PyObject_NEW(rangeobject, &PyRange_Type);
if (obj == NULL)
return NULL;
- if (len == 0 || reps <= 0) {
+ if (len == 0) {
start = 0;
len = 0;
step = 1;
- reps = 1;
- totlen = 0;
}
else {
long last = start + (len - 1) * step;
@@ -71,20 +33,12 @@ PyRange_New(long start, long len, long step, int reps)
PyErr_SetString(PyExc_OverflowError,
"integer addition");
return NULL;
- }
- if (! long_mul(len, (long) reps, &totlen)) {
- if(!PyErr_ExceptionMatches(PyExc_OverflowError))
- return NULL;
- PyErr_Clear();
- totlen = -1;
}
}
obj->start = start;
obj->len = len;
obj->step = step;
- obj->reps = reps;
- obj->totlen = totlen;
return (PyObject *) obj;
}
@@ -98,12 +52,11 @@ range_dealloc(rangeobject *r)
static PyObject *
range_item(rangeobject *r, int i)
{
- if (i < 0 || i >= r->totlen)
- if (r->totlen!=-1) {
- PyErr_SetString(PyExc_IndexError,
+ if (i < 0 || i >= r->len) {
+ PyErr_SetString(PyExc_IndexError,
"xrange object index out of range");
- return NULL;
- }
+ return NULL;
+ }
return PyInt_FromLong(r->start + (i % r->len) * r->step);
}
@@ -111,10 +64,7 @@ range_item(rangeobject *r, int i)
static int
range_length(rangeobject *r)
{
- if (r->totlen == -1)
- PyErr_SetString(PyExc_OverflowError,
- "xrange object has too many items");
- return r->totlen;
+ return r->len;
}
static PyObject *
@@ -124,7 +74,6 @@ range_repr(rangeobject *r)
* a bit of "(xrange(...) * ...)" text.
*/
char buf1[250];
- char buf2[250];
if (r->start == 0 && r->step == 1)
sprintf(buf1, "xrange(%ld)", r->start + r->len * r->step);
@@ -140,174 +89,18 @@ range_repr(rangeobject *r)
r->start + r->len * r->step,
r->step);
- if (r->reps != 1)
- sprintf(buf2, "(%s * %d)", buf1, r->reps);
-
- return PyString_FromString(r->reps == 1 ? buf1 : buf2);
-}
-
-static PyObject *
-range_concat(rangeobject *r, PyObject *obj)
-{
- PyErr_SetString(PyExc_TypeError, "cannot concatenate xrange objects");
- return NULL;
-}
-
-static PyObject *
-range_repeat(rangeobject *r, int n)
-{
- long lreps = 0;
-
- if (n <= 0)
- return (PyObject *) PyRange_New(0, 0, 1, 1);
-
- else if (n == 1) {
- Py_INCREF(r);
- return (PyObject *) r;
- }
-
- else if (! long_mul((long) r->reps, (long) n, &lreps))
- return NULL;
-
- else
- return (PyObject *) PyRange_New(
- r->start,
- r->len,
- r->step,
- (int) lreps);
-}
-
-static int
-range_compare(rangeobject *r1, rangeobject *r2)
-{
- if (r1->start != r2->start)
- return r1->start - r2->start;
-
- else if (r1->step != r2->step)
- return r1->step - r2->step;
-
- else if (r1->len != r2->len)
- return r1->len - r2->len;
-
- else
- return r1->reps - r2->reps;
-}
-
-static PyObject *
-range_slice(rangeobject *r, int low, int high)
-{
- if (r->reps != 1) {
- PyErr_SetString(PyExc_TypeError,
- "cannot slice a replicated xrange");
- return NULL;
- }
- if (low < 0)
- low = 0;
- else if (low > r->len)
- low = r->len;
- if (high < 0)
- high = 0;
- if (high < low)
- high = low;
- else if (high > r->len)
- high = r->len;
-
- if (low == 0 && high == r->len) {
- Py_INCREF(r);
- return (PyObject *) r;
- }
-
- return (PyObject *) PyRange_New(
- low * r->step + r->start,
- high - low,
- r->step,
- 1);
-}
-
-static PyObject *
-range_tolist(rangeobject *self, PyObject *args)
-{
- PyObject *thelist;
- int j;
-
- if (! PyArg_ParseTuple(args, ":tolist"))
- return NULL;
-
- if (self->totlen == -1)
- return PyErr_NoMemory();
-
- if ((thelist = PyList_New(self->totlen)) == NULL)
- return NULL;
-
- for (j = 0; j < self->totlen; ++j)
- if ((PyList_SetItem(thelist, j, (PyObject *) PyInt_FromLong(
- self->start + (j % self->len) * self->step))) < 0)
- return NULL;
-
- return thelist;
-}
-
-static PyObject *
-range_getattr(rangeobject *r, char *name)
-{
- PyObject *result;
-
- static PyMethodDef range_methods[] = {
- {"tolist", (PyCFunction)range_tolist, METH_VARARGS,
- "tolist() -> list\n"
- "Return a list object with the same values."},
- {NULL, NULL}
- };
- static struct memberlist range_members[] = {
- {"step", T_LONG, offsetof(rangeobject, step), RO},
- {"start", T_LONG, offsetof(rangeobject, start), RO},
- {"stop", T_LONG, 0, RO},
- {NULL, 0, 0, 0}
- };
-
- result = Py_FindMethod(range_methods, (PyObject *) r, name);
- if (result == NULL) {
- PyErr_Clear();
- if (strcmp("stop", name) == 0)
- result = PyInt_FromLong(r->start + (r->len * r->step));
- else
- result = PyMember_Get((char *)r, range_members, name);
- }
- return result;
-}
-
-static int
-range_contains(rangeobject *r, PyObject *obj)
-{
- long num = PyInt_AsLong(obj);
-
- if (num < 0 && PyErr_Occurred())
- return -1;
-
- if (r->step > 0) {
- if ((num < r->start) || ((num - r->start) % r->step))
- return 0;
- if (num >= (r->start + (r->len * r->step)))
- return 0;
- }
- else {
- if ((num > r->start) || ((num - r->start) % r->step))
- return 0;
- if (num <= (r->start + (r->len * r->step)))
- return 0;
- }
- return 1;
+ return PyString_FromString(buf1);
}
static PySequenceMethods range_as_sequence = {
(inquiry)range_length, /*sq_length*/
- (binaryfunc)range_concat, /*sq_concat*/
- (intargfunc)range_repeat, /*sq_repeat*/
- (intargfunc)range_item, /*sq_item*/
- (intintargfunc)range_slice, /*sq_slice*/
+ 0, /*sq_concat*/
+ 0, /*sq_repeat*/
+ (intargfunc)range_item, /*sq_item*/
+ 0, /*sq_slice*/
0, /*sq_ass_item*/
0, /*sq_ass_slice*/
- (objobjproc)range_contains, /*sq_contains*/
+ 0, /*sq_contains*/
};
PyTypeObject PyRange_Type = {
@@ -318,9 +111,9 @@ PyTypeObject PyRange_Type = {
0, /* Item size for varobject */
(destructor)range_dealloc, /*tp_dealloc*/
0, /*tp_print*/
- (getattrfunc)range_getattr, /*tp_getattr*/
+ 0, /*tp_getattr*/
0, /*tp_setattr*/
- (cmpfunc)range_compare, /*tp_compare*/
+ 0, /*tp_compare*/
(reprfunc)range_repr, /*tp_repr*/
0, /*tp_as_number*/
&range_as_sequence, /*tp_as_sequence*/