@@ -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