@@ -883,7 +883,129 @@ to_bool(PyObject *self)
883883        return res;                                      \
884884    }
885885
886- BINOP (add , PyNumber_Add )
886+ #define  CHECK_OPv2 (u , a , iu )    \
887+     if (MPZ_Check(a)) {         \
888+         u = (MPZ_Object *)a;    \
889+         Py_INCREF(u);           \
890+     }                           \
891+     else if (PyLong_Check(a)) { \
892+         iu = true;              \
893+     }                           \
894+     else if (Number_Check(a)) { \
895+         goto numbers;           \
896+     }                           \
897+     else {                      \
898+         goto fallback;          \
899+     }
900+ 
901+ #define  BINOPv2 (suff , slot )                                     \
902+     static PyObject *                                           \
903+     nb_##suff(PyObject *self, PyObject *other)                  \
904+     {                                                           \
905+         PyObject *res = NULL;                                   \
906+         MPZ_Object *u = NULL, *v = NULL;                        \
907+         bool iu = false, iv = false;                            \
908+                                                                 \
909+         CHECK_OPv2(u, self, iu);                                \
910+         CHECK_OPv2(v, other, iv);                               \
911+                                                                 \
912+         res = (PyObject *)MPZ_new(0);                           \
913+         if (!res) {                                             \
914+             goto end;                                           \
915+         }                                                       \
916+                                                                 \
917+         zz_err ret = ZZ_OK;                                     \
918+                                                                 \
919+         if (iu) {                                               \
920+             int32_t x;                                          \
921+                                                                 \
922+             if (PyLong_AsInt32(self, &x) == 0) {                \
923+                 ret = zz_i32_##suff(x, &v->z,                   \
924+                                     &((MPZ_Object *)res)->z);   \
925+                 goto done;                                      \
926+             }                                                   \
927+             else {                                              \
928+                 PyErr_Clear();                                  \
929+                 u = MPZ_from_int(self);                         \
930+                 if (!u) {                                       \
931+                     goto end;                                   \
932+                 }                                               \
933+             }                                                   \
934+         }                                                       \
935+         if (iv) {                                               \
936+             int32_t x;                                          \
937+                                                                 \
938+             if (PyLong_AsInt32(other, &x) == 0) {               \
939+                 ret = zz_##suff##_i32(&u->z, x,                 \
940+                                       &((MPZ_Object *)res)->z); \
941+                 goto done;                                      \
942+             }                                                   \
943+             else {                                              \
944+                 PyErr_Clear();                                  \
945+                 v = MPZ_from_int(other);                        \
946+                 if (!v) {                                       \
947+                     goto end;                                   \
948+                 }                                               \
949+             }                                                   \
950+         }                                                       \
951+         ret = zz_##suff(&u->z, &v->z, &((MPZ_Object *)res)->z); \
952+ done:                                                           \
953+         if (ret == ZZ_OK) {                                     \
954+             goto end;                                           \
955+         }                                                       \
956+         if (ret == ZZ_VAL) {                                    \
957+             Py_CLEAR(res);                                      \
958+             PyErr_SetString(PyExc_ZeroDivisionError,            \
959+                             "division by zero");                \
960+         }                                                       \
961+         else {                                                  \
962+             Py_CLEAR(res);                                      \
963+             PyErr_NoMemory();                                   \
964+         }                                                       \
965+     end:                                                        \
966+         Py_XDECREF(u);                                          \
967+         Py_XDECREF(v);                                          \
968+         return res;                                             \
969+     fallback:                                                   \
970+         Py_XDECREF(u);                                          \
971+         Py_XDECREF(v);                                          \
972+         Py_RETURN_NOTIMPLEMENTED;                               \
973+     numbers:                                                    \
974+         Py_XDECREF(u);                                          \
975+         Py_XDECREF(v);                                          \
976+                                                                 \
977+         PyObject *uf, *vf;                                      \
978+                                                                 \
979+         if (Number_Check(self)) {                               \
980+             uf = self;                                          \
981+             Py_INCREF(uf);                                      \
982+         }                                                       \
983+         else {                                                  \
984+             uf = to_float(self);                                \
985+             if (!uf) {                                          \
986+                 return NULL;                                    \
987+             }                                                   \
988+         }                                                       \
989+         if (Number_Check(other)) {                              \
990+             vf = other;                                         \
991+             Py_INCREF(vf);                                      \
992+         }                                                       \
993+         else {                                                  \
994+             vf = to_float(other);                               \
995+             if (!vf) {                                          \
996+                 Py_DECREF(uf);                                  \
997+                 return NULL;                                    \
998+             }                                                   \
999+         }                                                       \
1000+         res = slot(uf, vf);                                     \
1001+         Py_DECREF(uf);                                          \
1002+         Py_DECREF(vf);                                          \
1003+         return res;                                             \
1004+     }
1005+ 
1006+ #define  zz_i32_add (x , y , r ) zz_add_i32((y), (x), (r))
1007+ 
1008+ BINOPv2 (add , PyNumber_Add )
8871009BINOP (sub , PyNumber_Subtract )
8881010BINOP (mul , PyNumber_Multiply )
8891011
0 commit comments