]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
Make long a new style number type. Sequence repeat is now done here
authorNeil Schemenauer <nascheme@enme.ucalgary.ca>
Thu, 4 Jan 2001 01:46:03 +0000 (01:46 +0000)
committerNeil Schemenauer <nascheme@enme.ucalgary.ca>
Thu, 4 Jan 2001 01:46:03 +0000 (01:46 +0000)
now as well.

Objects/longobject.c

index 615d1d833709c5d077fd5f66cfb3eb072d8e3ded..fb6d78e54483e08c3e08e420d304b2b500a1e26e 100644 (file)
@@ -457,6 +457,40 @@ PyLong_AsUnsignedLongLong(PyObject *vv)
 }
 #endif /* HAVE_LONG_LONG */
 
+
+static int
+convert_binop(PyObject *v, PyObject *w, PyLongObject **a, PyLongObject **b) {
+       if (PyLong_Check(v)) { 
+               *a = (PyLongObject *) v;
+               Py_INCREF(v);
+       }
+       else if (PyInt_Check(v)) {
+               *a = (PyLongObject *) PyLong_FromLong(PyInt_AS_LONG(v));
+       }
+       else {
+               return 0;
+       }
+       if (PyLong_Check(w)) { 
+               *b = (PyLongObject *) w;
+               Py_INCREF(w);
+       }
+       else if (PyInt_Check(w)) {
+               *b = (PyLongObject *) PyLong_FromLong(PyInt_AS_LONG(w));
+       }
+       else {
+               Py_DECREF(*a);
+               return 0;
+       }
+       return 1;
+}
+
+#define CONVERT_BINOP(v, w, a, b) \
+       if (!convert_binop(v, w, a, b)) { \
+               Py_INCREF(Py_NotImplemented); \
+               return Py_NotImplemented; \
+       }
+
+
 /* Multiply by a single digit, ignoring the sign. */
 
 static PyLongObject *
@@ -932,6 +966,19 @@ long_compare(PyLongObject *a, PyLongObject *b)
        return sign < 0 ? -1 : sign > 0 ? 1 : 0;
 }
 
+/* Needed for the new style number compare slots */
+static PyObject *
+long_cmp(PyObject *v, PyObject *w)
+{
+       PyLongObject *a, *b;
+       int c;
+       CONVERT_BINOP(v, w, &a, &b);
+       c = long_compare(a, b);
+       Py_DECREF(a);
+       Py_DECREF(b);
+       return PyInt_FromLong(c);
+}
+
 static long
 long_hash(PyLongObject *v)
 {
@@ -1050,10 +1097,12 @@ x_sub(PyLongObject *a, PyLongObject *b)
 }
 
 static PyObject *
-long_add(PyLongObject *a, PyLongObject *b)
+long_add(PyLongObject *v, PyLongObject *w)
 {
-       PyLongObject *z;
+       PyLongObject *a, *b, *z;
        
+       CONVERT_BINOP((PyObject *)v, (PyObject *)w, &a, &b);
+
        if (a->ob_size < 0) {
                if (b->ob_size < 0) {
                        z = x_add(a, b);
@@ -1069,14 +1118,18 @@ long_add(PyLongObject *a, PyLongObject *b)
                else
                        z = x_add(a, b);
        }
+       Py_DECREF(a);
+       Py_DECREF(b);
        return (PyObject *)z;
 }
 
 static PyObject *
-long_sub(PyLongObject *a, PyLongObject *b)
+long_sub(PyLongObject *v, PyLongObject *w)
 {
-       PyLongObject *z;
+       PyLongObject *a, *b, *z;
        
+       CONVERT_BINOP((PyObject *)v, (PyObject *)w, &a, &b);
+
        if (a->ob_size < 0) {
                if (b->ob_size < 0)
                        z = x_sub(a, b);
@@ -1091,17 +1144,41 @@ long_sub(PyLongObject *a, PyLongObject *b)
                else
                        z = x_sub(a, b);
        }
+       Py_DECREF(a);
+       Py_DECREF(b);
        return (PyObject *)z;
 }
 
 static PyObject *
-long_mul(PyLongObject *a, PyLongObject *b)
+long_repeat(PyObject *v, PyLongObject *w)
 {
+       /* sequence * long */
+       long n = PyLong_AsLong((PyObject *) w);
+       if (n == -1 && PyErr_Occurred())
+               return NULL;
+       else
+               return (*v->ob_type->tp_as_sequence->sq_repeat)(v, n);
+}
+
+static PyObject *
+long_mul(PyLongObject *v, PyLongObject *w)
+{
+       PyLongObject *a, *b, *z;
        int size_a;
        int size_b;
-       PyLongObject *z;
        int i;
        
+       if (v->ob_type->tp_as_sequence &&
+                       v->ob_type->tp_as_sequence->sq_repeat) {
+               return long_repeat((PyObject *)v, w);
+       }
+       else if (w->ob_type->tp_as_sequence &&
+                       w->ob_type->tp_as_sequence->sq_repeat) {
+               return long_repeat((PyObject *)w, v);
+       }
+
+       CONVERT_BINOP((PyObject *)v, (PyObject *)w, &a, &b);
+
        size_a = ABS(a->ob_size);
        size_b = ABS(b->ob_size);
        if (size_a > size_b) {
@@ -1114,8 +1191,11 @@ long_mul(PyLongObject *a, PyLongObject *b)
                b = hold_a;
        }
        z = _PyLong_New(size_a + size_b);
-       if (z == NULL)
+       if (z == NULL) {
+               Py_DECREF(a);
+               Py_DECREF(b);
                return NULL;
+       }
        for (i = 0; i < z->ob_size; ++i)
                z->ob_digit[i] = 0;
        for (i = 0; i < size_a; ++i) {
@@ -1124,6 +1204,8 @@ long_mul(PyLongObject *a, PyLongObject *b)
                int j;
                
                SIGCHECK({
+                       Py_DECREF(a);
+                       Py_DECREF(b);
                        Py_DECREF(z);
                        return NULL;
                })
@@ -1143,6 +1225,8 @@ long_mul(PyLongObject *a, PyLongObject *b)
                z->ob_size = -(z->ob_size);
        if (b->ob_size < 0)
                z->ob_size = -(z->ob_size);
+       Py_DECREF(a);
+       Py_DECREF(b);
        return (PyObject *) long_normalize(z);
 }
 
@@ -1198,32 +1282,54 @@ l_divmod(PyLongObject *v, PyLongObject *w,
 }
 
 static PyObject *
-long_div(PyLongObject *v, PyLongObject *w)
+long_div(PyObject *v, PyObject *w)
 {
-       PyLongObject *div, *mod;
-       if (l_divmod(v, w, &div, &mod) < 0)
+       PyLongObject *a, *b, *div, *mod;
+
+       CONVERT_BINOP(v, w, &a, &b);
+
+       if (l_divmod(a, b, &div, &mod) < 0) {
+               Py_DECREF(a);
+               Py_DECREF(b);
                return NULL;
+       }
+       Py_DECREF(a);
+       Py_DECREF(b);
        Py_DECREF(mod);
        return (PyObject *)div;
 }
 
 static PyObject *
-long_mod(PyLongObject *v, PyLongObject *w)
+long_mod(PyObject *v, PyObject *w)
 {
-       PyLongObject *div, *mod;
-       if (l_divmod(v, w, &div, &mod) < 0)
+       PyLongObject *a, *b, *div, *mod;
+
+       CONVERT_BINOP(v, w, &a, &b);
+
+       if (l_divmod(a, b, &div, &mod) < 0) {
+               Py_DECREF(a);
+               Py_DECREF(b);
                return NULL;
+       }
+       Py_DECREF(a);
+       Py_DECREF(b);
        Py_DECREF(div);
        return (PyObject *)mod;
 }
 
 static PyObject *
-long_divmod(PyLongObject *v, PyLongObject *w)
+long_divmod(PyObject *v, PyObject *w)
 {
+       PyLongObject *a, *b, *div, *mod;
        PyObject *z;
-       PyLongObject *div, *mod;
-       if (l_divmod(v, w, &div, &mod) < 0)
+
+       CONVERT_BINOP(v, w, &a, &b);
+
+       if (l_divmod(a, b, &div, &mod) < 0) {
+               Py_DECREF(a);
+               Py_DECREF(b);
                return NULL;
+       }
        z = PyTuple_New(2);
        if (z != NULL) {
                PyTuple_SetItem(z, 0, (PyObject *) div);
@@ -1233,14 +1339,33 @@ long_divmod(PyLongObject *v, PyLongObject *w)
                Py_DECREF(div);
                Py_DECREF(mod);
        }
+       Py_DECREF(a);
+       Py_DECREF(b);
        return z;
 }
 
 static PyObject *
-long_pow(PyLongObject *a, PyLongObject *b, PyLongObject *c)
+long_pow(PyObject *v, PyObject *w, PyObject *x)
 {
+       PyLongObject *a, *b;
+       PyObject *c;
        PyLongObject *z, *div, *mod;
        int size_b, i;
+
+       CONVERT_BINOP(v, w, &a, &b);
+       if (PyLong_Check(x) || Py_None == x) { 
+               c = x;
+               Py_INCREF(x);
+       }
+       else if (PyInt_Check(x)) {
+               c = PyLong_FromLong(PyInt_AS_LONG(x));
+       }
+       else {
+               Py_DECREF(a);
+               Py_DECREF(b);
+               Py_INCREF(Py_NotImplemented);
+               return Py_NotImplemented;
+       }
        
        size_b = b->ob_size;
        if (size_b < 0) {
@@ -1250,10 +1375,10 @@ long_pow(PyLongObject *a, PyLongObject *b, PyLongObject *c)
                else
                        PyErr_SetString(PyExc_ZeroDivisionError,
                                        "zero to a negative power");
-               return NULL;
+               z = NULL;
+               goto error;
        }
        z = (PyLongObject *)PyLong_FromLong(1L);
-       Py_INCREF(a);
        for (i = 0; i < size_b; ++i) {
                digit bi = b->ob_digit[i];
                int j;
@@ -1264,8 +1389,9 @@ long_pow(PyLongObject *a, PyLongObject *b, PyLongObject *c)
                        if (bi & 1) {
                                temp = (PyLongObject *)long_mul(z, a);
                                Py_DECREF(z);
-                               if ((PyObject*)c!=Py_None && temp!=NULL) {
-                                       if (l_divmod(temp,c,&div,&mod) < 0) {
+                               if (c!=Py_None && temp!=NULL) {
+                                       if (l_divmod(temp,(PyLongObject *)c,
+                                                       &div,&mod) < 0) {
                                                Py_DECREF(temp);
                                                z = NULL;
                                                goto error;
@@ -1283,8 +1409,9 @@ long_pow(PyLongObject *a, PyLongObject *b, PyLongObject *c)
                                break;
                        temp = (PyLongObject *)long_mul(a, a);
                        Py_DECREF(a);
-                       if ((PyObject*)c!=Py_None && temp!=NULL) {
-                               if (l_divmod(temp, c, &div, &mod) < 0) {
+                       if (c!=Py_None && temp!=NULL) {
+                               if (l_divmod(temp, (PyLongObject *)c, &div,
+                                                       &mod) < 0) {
                                        Py_DECREF(temp);
                                        z = NULL;
                                        goto error;
@@ -1303,9 +1430,8 @@ long_pow(PyLongObject *a, PyLongObject *b, PyLongObject *c)
                if (a == NULL || z == NULL)
                        break;
        }
-       Py_XDECREF(a);
-       if ((PyObject*)c!=Py_None && z!=NULL) {
-               if (l_divmod(z, c, &div, &mod) < 0) {
+       if (c!=Py_None && z!=NULL) {
+               if (l_divmod(z, (PyLongObject *)c, &div, &mod) < 0) {
                        Py_DECREF(z);
                        z = NULL;
                }
@@ -1316,6 +1442,9 @@ long_pow(PyLongObject *a, PyLongObject *b, PyLongObject *c)
                }
        }
   error:
+       Py_XDECREF(a);
+       Py_DECREF(b);
+       Py_DECREF(c);
        return (PyObject *)z;
 }
 
@@ -1382,77 +1511,94 @@ long_nonzero(PyLongObject *v)
 }
 
 static PyObject *
-long_rshift(PyLongObject *a, PyLongObject *b)
+long_rshift(PyLongObject *v, PyLongObject *w)
 {
-       PyLongObject *z;
+       PyLongObject *a, *b;
+       PyLongObject *z = NULL;
        long shiftby;
        int newsize, wordshift, loshift, hishift, i, j;
        digit lomask, himask;
        
+       CONVERT_BINOP((PyObject *)v, (PyObject *)w, &a, &b);
+
        if (a->ob_size < 0) {
                /* Right shifting negative numbers is harder */
-               PyLongObject *a1, *a2, *a3;
+               PyLongObject *a1, *a2;
                a1 = (PyLongObject *) long_invert(a);
-               if (a1 == NULL) return NULL;
+               if (a1 == NULL)
+                       goto rshift_error;
                a2 = (PyLongObject *) long_rshift(a1, b);
                Py_DECREF(a1);
-               if (a2 == NULL) return NULL;
-               a3 = (PyLongObject *) long_invert(a2);
+               if (a2 == NULL)
+                       goto rshift_error;
+               z = (PyLongObject *) long_invert(a2);
                Py_DECREF(a2);
-               return (PyObject *) a3;
-       }
-       
-       shiftby = PyLong_AsLong((PyObject *)b);
-       if (shiftby == -1L && PyErr_Occurred())
-               return NULL;
-       if (shiftby < 0) {
-               PyErr_SetString(PyExc_ValueError, "negative shift count");
-               return NULL;
        }
-       wordshift = shiftby / SHIFT;
-       newsize = ABS(a->ob_size) - wordshift;
-       if (newsize <= 0) {
-               z = _PyLong_New(0);
-               return (PyObject *)z;
-       }
-       loshift = shiftby % SHIFT;
-       hishift = SHIFT - loshift;
-       lomask = ((digit)1 << hishift) - 1;
-       himask = MASK ^ lomask;
-       z = _PyLong_New(newsize);
-       if (z == NULL)
-               return NULL;
-       if (a->ob_size < 0)
-               z->ob_size = -(z->ob_size);
-       for (i = 0, j = wordshift; i < newsize; i++, j++) {
-               z->ob_digit[i] = (a->ob_digit[j] >> loshift) & lomask;
-               if (i+1 < newsize)
-                       z->ob_digit[i] |=
-                         (a->ob_digit[j+1] << hishift) & himask;
+       else {
+               
+               shiftby = PyLong_AsLong((PyObject *)b);
+               if (shiftby == -1L && PyErr_Occurred())
+                       goto rshift_error;
+               if (shiftby < 0) {
+                       PyErr_SetString(PyExc_ValueError,
+                                       "negative shift count");
+                       goto rshift_error;
+               }
+               wordshift = shiftby / SHIFT;
+               newsize = ABS(a->ob_size) - wordshift;
+               if (newsize <= 0) {
+                       z = _PyLong_New(0);
+                       Py_DECREF(a);
+                       Py_DECREF(b);
+                       return (PyObject *)z;
+               }
+               loshift = shiftby % SHIFT;
+               hishift = SHIFT - loshift;
+               lomask = ((digit)1 << hishift) - 1;
+               himask = MASK ^ lomask;
+               z = _PyLong_New(newsize);
+               if (z == NULL)
+                       goto rshift_error;
+               if (a->ob_size < 0)
+                       z->ob_size = -(z->ob_size);
+               for (i = 0, j = wordshift; i < newsize; i++, j++) {
+                       z->ob_digit[i] = (a->ob_digit[j] >> loshift) & lomask;
+                       if (i+1 < newsize)
+                               z->ob_digit[i] |=
+                                 (a->ob_digit[j+1] << hishift) & himask;
+               }
+               z = long_normalize(z);
        }
-       return (PyObject *) long_normalize(z);
+rshift_error:
+       Py_DECREF(a);
+       Py_DECREF(b);
+       return (PyObject *) z;
+
 }
 
 static PyObject *
-long_lshift(PyLongObject *a, PyLongObject *b)
+long_lshift(PyObject *v, PyObject *w)
 {
        /* This version due to Tim Peters */
-       PyLongObject *z;
+       PyLongObject *a, *b;
+       PyLongObject *z = NULL;
        long shiftby;
        int oldsize, newsize, wordshift, remshift, i, j;
        twodigits accum;
        
+       CONVERT_BINOP(v, w, &a, &b);
+
        shiftby = PyLong_AsLong((PyObject *)b);
        if (shiftby == -1L && PyErr_Occurred())
-               return NULL;
+               goto lshift_error;
        if (shiftby < 0) {
                PyErr_SetString(PyExc_ValueError, "negative shift count");
-               return NULL;
+               goto lshift_error;
        }
        if ((long)(int)shiftby != shiftby) {
                PyErr_SetString(PyExc_ValueError,
                                "outrageous left shift count");
-               return NULL;
+               goto lshift_error;
        }
        /* wordshift, remshift = divmod(shiftby, SHIFT) */
        wordshift = (int)shiftby / SHIFT;
@@ -1464,7 +1610,7 @@ long_lshift(PyLongObject *a, PyLongObject *b)
                ++newsize;
        z = _PyLong_New(newsize);
        if (z == NULL)
-               return NULL;
+               goto lshift_error;
        if (a->ob_size < 0)
                z->ob_size = -(z->ob_size);
        for (i = 0; i < wordshift; i++)
@@ -1479,7 +1625,11 @@ long_lshift(PyLongObject *a, PyLongObject *b)
                z->ob_digit[newsize-1] = (digit)accum;
        else    
                assert(!accum);
-       return (PyObject *) long_normalize(z);
+       z = long_normalize(z);
+lshift_error:
+       Py_DECREF(a);
+       Py_DECREF(b);
+       return (PyObject *) z;
 }
 
 
@@ -1590,28 +1740,46 @@ long_bitwise(PyLongObject *a,
 }
 
 static PyObject *
-long_and(PyLongObject *a, PyLongObject *b)
+long_and(PyObject *v, PyObject *w)
 {
-       return long_bitwise(a, '&', b);
+       PyLongObject *a, *b;
+       PyObject *c;
+       CONVERT_BINOP(v, w, &a, &b);
+       c = long_bitwise(a, '&', b);
+       Py_DECREF(a);
+       Py_DECREF(b);
+       return c;
 }
 
 static PyObject *
-long_xor(PyLongObject *a, PyLongObject *b)
+long_xor(PyObject *v, PyObject *w)
 {
-       return long_bitwise(a, '^', b);
+       PyLongObject *a, *b;
+       PyObject *c;
+       CONVERT_BINOP(v, w, &a, &b);
+       c = long_bitwise(a, '^', b);
+       Py_DECREF(a);
+       Py_DECREF(b);
+       return c;
 }
 
 static PyObject *
-long_or(PyLongObject *a, PyLongObject *b)
+long_or(PyObject *v, PyObject *w)
 {
-       return long_bitwise(a, '|', b);
+       PyLongObject *a, *b;
+       PyObject *c;
+       CONVERT_BINOP(v, w, &a, &b);
+       c = long_bitwise(a, '|', b);
+       Py_DECREF(a);
+       Py_DECREF(b);
+       return c;
 }
 
 static int
 long_coerce(PyObject **pv, PyObject **pw)
 {
        if (PyInt_Check(*pw)) {
-               *pw = PyLong_FromLong(PyInt_AsLong(*pw));
+               *pw = PyLong_FromLong(PyInt_AS_LONG(*pw));
                Py_INCREF(*pv);
                return 0;
        }
@@ -1681,6 +1849,20 @@ static PyNumberMethods long_as_number = {
        (unaryfunc)     long_float,     /*nb_float*/
        (unaryfunc)     long_oct,       /*nb_oct*/
        (unaryfunc)     long_hex,       /*nb_hex*/
+       0,                              /*nb_inplace_add*/
+       0,                              /*nb_inplace_subtract*/
+       0,                              /*nb_inplace_multiply*/
+       0,                              /*nb_inplace_divide*/
+       0,                              /*nb_inplace_remainder*/
+       0,                              /*nb_inplace_power*/
+       0,                              /*nb_inplace_lshift*/
+       0,                              /*nb_inplace_rshift*/
+       0,                              /*nb_inplace_and*/
+       0,                              /*nb_inplace_xor*/
+       0,                              /*nb_inplace_or*/
+
+       /* New style slots */
+       (binaryfunc)    long_cmp,       /*nb_cmp*/
 };
 
 PyTypeObject PyLong_Type = {
@@ -1701,4 +1883,8 @@ PyTypeObject PyLong_Type = {
        (hashfunc)long_hash,            /*tp_hash*/
         0,                             /*tp_call*/
         (reprfunc)long_str,            /*tp_str*/
+       0,                              /*tp_getattro*/
+       0,                              /*tp_setattro*/
+       0,                              /*tp_as_buffer*/
+       Py_TPFLAGS_NEWSTYLENUMBER       /*tp_flags*/
 };