1 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 2 * gmpy2_macros.h * 3 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 4 * Python interface to the GMP or MPIR, MPFR, and MPC multiple precision * 5 * libraries. * 6 * * 7 * Copyright 2000 - 2009 Alex Martelli * 8 * * 9 * Copyright 2008 - 2021 Case Van Horsen * 10 * * 11 * This file is part of GMPY2. * 12 * * 13 * GMPY2 is free software: you can redistribute it and/or modify it under * 14 * the terms of the GNU Lesser General Public License as published by the * 15 * Free Software Foundation, either version 3 of the License, or (at your * 16 * option) any later version. * 17 * * 18 * GMPY2 is distributed in the hope that it will be useful, but WITHOUT * 19 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * 20 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public * 21 * License for more details. * 22 * * 23 * You should have received a copy of the GNU Lesser General Public * 24 * License along with GMPY2; if not, see <http://www.gnu.org/licenses/> * 25 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ 26 27 /* This file contains a collection of macros that can be used to reduce 28 * repetitive code. As new macros are written to support of refactoring, 29 * they should be placed here. 30 */ 31 32 /* NAME is used as part of the GMPy function name. It usually uses an upper- 33 * case first character. 34 * FUNC is the component of the actual name used by MPFR and MPC. 35 * 36 * Note: the following macro can release the GIL. 37 * GMPY_MPFR_MPC_UNIOP_EXWT(NAME, FUNC) creates the following functions: 38 * GMPy_RealWithType_NAME(x, xtype, context) 39 * GMPy_ComplexWithType_NAME(x, xtype, context) 40 * GMPy_Number_NAME(x, context) 41 * GMPy_Context_NAME(self, other) 42 * - called with METH_O 43 * 44 * Note: the following macro is only used for is_xxx tests so it does 45 * not release the GIL. 46 * GMPY_MPFR_MPC_UNIOP_TEMPLATEWT(NAME, FUNC) creates the following functions: 47 * GMPy_Number_NAME(x, context) 48 * - assumes GMPy_RealWithType_NAME & GMPy_ComplexWithType_NAME exist 49 * GMPy_Context_NAME(self, other) 50 * - called with METH_O 51 * 52 * GMPY_MPFR_MPC_TRIOP_EX(NAME, FUNC) creates the following functions: 53 * GMPy_Real_NAME(x, y, Z, context) 54 * GMPy_Complex_NAME(x, y, Z, context) 55 * GMPy_Number_NAME(x, y, Z, context) 56 * - assumes GMPy_Integer_NAME & GMPy_Rational_NAME also exist 57 * GMPy_Context_NAME(self, args) 58 * - called with METH_VARARGS 59 * 60 * GMPY_MPFR_MPC_UNIOP_TEMPLATE(NAME, FUNC) creates the following functions: 61 * GMPy_Number_NAME(x, context) 62 * - assumes GMPy_Real_NAME & GMPy_Complex_NAME exist 63 * GMPy_Context_NAME(self, other) 64 * - called with METH_O 65 * 66 * GMPY_MPFR_UNIOP(NAME, FUNC) creates the following functions: 67 * GMPy_Real_NAME(x, context) 68 * GMPy_Number_NAME(x, context) 69 * GMPy_Context_NAME(self, other) 70 * - called with METH_O 71 * 72 * GMPY_MPFR_UNIOP_TEMPLATE(NAME, FUNC) creates the following functions: 73 * GMPy_Number_NAME(x, context) 74 * - assumes GMPy_Real_NAME exists 75 * GMPy_Context_NAME(self, other) 76 * - called with METH_O 77 * 78 * GMPY_MPFR_BINOP(NAME, FUNC) creates the following functions: 79 * GMPy_Real_NAME(x, y, context) 80 * GMPy_Number_NAME(x, y, context) 81 * GMPy_Context_NAME(self, args) 82 * - called with METH_VARARGS 83 * 84 */ 85 86 #define GMPY_MPFR_MPC_UNIOP_EXWT(NAME, FUNC) \ 87 static PyObject * \ 88 GMPy_RealWithType_##NAME(PyObject *x, int xtype, CTXT_Object *context) \ 89 { \ 90 MPFR_Object *result = NULL, *tempx = NULL; \ 91 if (IS_TYPE_MPFR(xtype)) { \ 92 if (!(result = GMPy_MPFR_New(0, context))) return NULL; \ 93 mpfr_clear_flags(); \ 94 result->rc = mpfr_##FUNC(result->f, MPFR(x), GET_MPFR_ROUND(context)); \ 95 _GMPy_MPFR_Cleanup(&result, context); \ 96 return (PyObject*)result; \ 97 } \ 98 if (IS_TYPE_REAL(xtype)) { \ 99 if (!(tempx = GMPy_MPFR_From_RealWithType(x, xtype, 1, context))) return NULL; \ 100 if (!(result = GMPy_MPFR_New(0, context))) { \ 101 Py_DECREF(tempx); \ 102 return NULL; \ 103 } \ 104 mpfr_clear_flags(); \ 105 result->rc = mpfr_##FUNC(result->f, MPFR(tempx), GET_MPFR_ROUND(context)); \ 106 _GMPy_MPFR_Cleanup(&result, context); \ 107 Py_DECREF(tempx); \ 108 return (PyObject*)result; \ 109 } \ 110 TYPE_ERROR(#FUNC"() argument type not supported"); \ 111 return NULL; \ 112 } \ 113 static PyObject * \ 114 GMPy_ComplexWithType_##NAME(PyObject *x, int xtype, CTXT_Object *context) \ 115 { \ 116 MPC_Object *result = NULL, *tempx = NULL; \ 117 if (IS_TYPE_MPC(xtype)) { \ 118 if (!(result = GMPy_MPC_New(0, 0, context))) return NULL; \ 119 result->rc = mpc_##FUNC(result->c, MPC(x), GET_MPC_ROUND(context)); \ 120 _GMPy_MPC_Cleanup(&result, context); \ 121 return (PyObject*)result; \ 122 } \ 123 if (IS_TYPE_COMPLEX(xtype)) { \ 124 if (!(tempx = GMPy_MPC_From_ComplexWithType(x, xtype, 1, 1, context))) return NULL; \ 125 if (!(result = GMPy_MPC_New(0, 0, context))) { \ 126 Py_DECREF(tempx); \ 127 return NULL; \ 128 } \ 129 result->rc = mpc_##FUNC(result->c, MPC(tempx), GET_MPC_ROUND(context)); \ 130 _GMPy_MPC_Cleanup(&result, context); \ 131 Py_DECREF(tempx); \ 132 return (PyObject*)result; \ 133 } \ 134 TYPE_ERROR(#FUNC"() argument type not supported"); \ 135 return NULL; \ 136 } \ 137 static PyObject * \ 138 GMPy_Number_##NAME(PyObject *x, CTXT_Object *context) \ 139 { \ 140 CHECK_CONTEXT(context); \ 141 int xtype = GMPy_ObjectType(x);\ 142 if (IS_TYPE_REAL(xtype)) \ 143 return GMPy_RealWithType_##NAME(x, xtype, context); \ 144 if (IS_TYPE_COMPLEX(xtype)) \ 145 return GMPy_ComplexWithType_##NAME(x, xtype, context); \ 146 TYPE_ERROR(#FUNC"() argument type not supported"); \ 147 return NULL; \ 148 } \ 149 static PyObject * \ 150 GMPy_Context_##NAME(PyObject *self, PyObject *other) \ 151 { \ 152 CTXT_Object *context = NULL; \ 153 if (self && CTXT_Check(self)) { \ 154 context = (CTXT_Object*)self; \ 155 } \ 156 else { \ 157 CHECK_CONTEXT(context); \ 158 } \ 159 return GMPy_Number_##NAME(other, context); \ 160 } 161 162 /*********************************************************************/ 163 164 #define GMPY_MPFR_MPC_UNIOP_TEMPLATEWT(NAME, FUNC) \ 165 static PyObject * \ 166 GMPy_Number_##NAME(PyObject *x, CTXT_Object *context) \ 167 { \ 168 CHECK_CONTEXT(context); \ 169 int xtype = GMPy_ObjectType(x); \ 170 if (IS_TYPE_REAL(xtype)) \ 171 return GMPy_RealWithType_##NAME(x, xtype, context); \ 172 if (IS_TYPE_COMPLEX(xtype)) \ 173 return GMPy_ComplexWithType_##NAME(x, xtype, context); \ 174 TYPE_ERROR(#FUNC"() argument type not supported"); \ 175 return NULL; \ 176 } \ 177 static PyObject * \ 178 GMPy_Context_##NAME(PyObject *self, PyObject *other) \ 179 { \ 180 CTXT_Object *context = NULL; \ 181 if (self && CTXT_Check(self)) { \ 182 context = (CTXT_Object*)self; \ 183 } \ 184 else { \ 185 CHECK_CONTEXT(context); \ 186 } \ 187 return GMPy_Number_##NAME(other, context); \ 188 } \ 189 static PyObject * \ 190 GMPy_Number_Method_##NAME(PyObject *self, PyObject *args) \ 191 { \ 192 return GMPy_Number_##NAME(self, NULL); \ 193 } \ 194 195 /*********************************************************************/ 196 197 #define GMPY_MPFR_MPC_UNIOP_TEMPLATE_EXWT(NAME, FUNC) \ 198 static PyObject * \ 199 GMPy_Number_##NAME(PyObject *x, CTXT_Object *context) \ 200 { \ 201 CHECK_CONTEXT(context); \ 202 int xtype = GMPy_ObjectType(x); \ 203 if (IS_TYPE_REAL(xtype)) \ 204 return GMPy_RealWithType_##NAME(x, xtype, context); \ 205 if (IS_TYPE_COMPLEX(xtype)) \ 206 return GMPy_ComplexWithType_##NAME(x, xtype, context); \ 207 TYPE_ERROR(#FUNC"() argument type not supported"); \ 208 return NULL; \ 209 } \ 210 static PyObject * \ 211 GMPy_Context_##NAME(PyObject *self, PyObject *other) \ 212 { \ 213 CTXT_Object *context = NULL; \ 214 if (self && CTXT_Check(self)) { \ 215 context = (CTXT_Object*)self; \ 216 } \ 217 else { \ 218 CHECK_CONTEXT(context); \ 219 } \ 220 return GMPy_Number_##NAME(other, context); \ 221 } \ 222 223 /*********************************************************************/ 224 225 #define GMPY_MPFR_MPC_TRIOP_TEMPLATEWT(NAME, FUNC) \ 226 static PyObject * \ 227 GMPy_Number_##NAME(PyObject *x, PyObject *y, PyObject *z, CTXT_Object *context) \ 228 { \ 229 CHECK_CONTEXT(context); \ 230 int xtype = GMPy_ObjectType(x); \ 231 int ytype = GMPy_ObjectType(y); \ 232 int ztype = GMPy_ObjectType(z); \ 233 if (IS_TYPE_MPZ(xtype) && IS_TYPE_MPZ(ytype) && IS_TYPE_MPZ(ztype)) \ 234 return _GMPy_MPZ_##NAME(x, y, z, context); \ 235 if (IS_TYPE_MPQ(xtype) && IS_TYPE_MPQ(ytype) && IS_TYPE_MPQ(ztype)) \ 236 return _GMPy_MPQ_##NAME(x, y, z, context); \ 237 if (IS_TYPE_MPFR(xtype) && IS_TYPE_MPFR(ytype) && IS_TYPE_MPFR(ztype)) \ 238 return _GMPy_MPFR_##NAME(x, y, z, context); \ 239 if (IS_TYPE_MPC(xtype) && IS_TYPE_MPC(ytype) && IS_TYPE_MPC(ztype)) \ 240 return _GMPy_MPC_##NAME(x, y, z, context); \ 241 if (IS_TYPE_INTEGER(xtype) && IS_TYPE_INTEGER(ytype) && IS_TYPE_INTEGER(ztype)) \ 242 return GMPy_IntegerWithType_##NAME(x, xtype, y, ytype, z, ztype, context); \ 243 if (IS_TYPE_RATIONAL(xtype) && IS_TYPE_RATIONAL(ytype) && IS_TYPE_RATIONAL(ztype)) \ 244 return GMPy_RationalWithType_##NAME(x, xtype, y, ytype, z, ztype, context); \ 245 if (IS_TYPE_REAL(xtype) && IS_TYPE_REAL(ytype) && IS_TYPE_REAL(ztype)) \ 246 return GMPy_RealWithType_##NAME(x, xtype, y, ytype, z, ztype, context); \ 247 if (IS_TYPE_COMPLEX(xtype) && IS_TYPE_COMPLEX(ytype) && IS_TYPE_COMPLEX(ztype)) \ 248 return GMPy_ComplexWithType_##NAME(x, xtype, y, ytype, z, ztype, context); \ 249 TYPE_ERROR(#FUNC"() argument type not supported"); \ 250 return NULL; \ 251 } \ 252 static PyObject * \ 253 GMPy_Context_##NAME(PyObject *self, PyObject *args) \ 254 { \ 255 CTXT_Object *context = NULL; \ 256 if (PyTuple_GET_SIZE(args) != 3) { \ 257 TYPE_ERROR(#FUNC"() requires 3 arguments"); \ 258 return NULL; \ 259 } \ 260 if (self && CTXT_Check(self)) { \ 261 context = (CTXT_Object*)self; \ 262 } \ 263 else { \ 264 CHECK_CONTEXT(context); \ 265 } \ 266 return GMPy_Number_##NAME(PyTuple_GET_ITEM(args, 0), \ 267 PyTuple_GET_ITEM(args, 1), \ 268 PyTuple_GET_ITEM(args, 2), context); \ 269 } 270 271 /*********************************************************************/ 272 273 #define GMPY_MPFR_QUADOP_TEMPLATEWT(NAME, FUNC) \ 274 static PyObject * \ 275 GMPy_Number_##NAME(PyObject *x, PyObject *y, PyObject *z, PyObject *t, CTXT_Object *context) \ 276 { \ 277 CHECK_CONTEXT(context); \ 278 int xtype = GMPy_ObjectType(x); \ 279 int ytype = GMPy_ObjectType(y); \ 280 int ztype = GMPy_ObjectType(z); \ 281 int ttype = GMPy_ObjectType(t); \ 282 if (IS_TYPE_MPZ(xtype) && IS_TYPE_MPZ(ytype) && IS_TYPE_MPZ(ztype) && IS_TYPE_MPZ(ttype)) \ 283 return _GMPy_MPZ_##NAME(x, y, z, t, context); \ 284 if (IS_TYPE_MPQ(xtype) && IS_TYPE_MPQ(ytype) && IS_TYPE_MPQ(ztype) && IS_TYPE_MPQ(ttype)) \ 285 return _GMPy_MPQ_##NAME(x, y, z, t, context); \ 286 if (IS_TYPE_MPFR(xtype) && IS_TYPE_MPFR(ytype) && IS_TYPE_MPFR(ztype) && IS_TYPE_MPFR(ttype)) \ 287 return _GMPy_MPFR_##NAME(x, y, z, t, context); \ 288 if (IS_TYPE_INTEGER(xtype) && IS_TYPE_INTEGER(ytype) && IS_TYPE_INTEGER(ztype) && IS_TYPE_INTEGER(ttype)) \ 289 return GMPy_IntegerWithType_##NAME(x, xtype, y, ytype, z, ztype, t, ttype, context); \ 290 if (IS_TYPE_RATIONAL(xtype) && IS_TYPE_RATIONAL(ytype) && IS_TYPE_RATIONAL(ztype) && IS_TYPE_RATIONAL(ttype)) \ 291 return GMPy_RationalWithType_##NAME(x, xtype, y, ytype, z, ztype, t, ttype, context); \ 292 if (IS_TYPE_REAL(xtype) && IS_TYPE_REAL(ytype) && IS_TYPE_REAL(ztype) && IS_TYPE_REAL(ttype)) \ 293 return GMPy_RealWithType_##NAME(x, xtype, y, ytype, z, ztype, t, ttype, context); \ 294 TYPE_ERROR(#FUNC"() argument type not supported"); \ 295 return NULL; \ 296 } \ 297 static PyObject * \ 298 GMPy_Context_##NAME(PyObject *self, PyObject *args) \ 299 { \ 300 CTXT_Object *context = NULL; \ 301 if (PyTuple_GET_SIZE(args) != 4) { \ 302 TYPE_ERROR(#FUNC"() requires 4 arguments"); \ 303 return NULL; \ 304 } \ 305 if (self && CTXT_Check(self)) { \ 306 context = (CTXT_Object*)self; \ 307 } \ 308 else { \ 309 CHECK_CONTEXT(context); \ 310 } \ 311 return GMPy_Number_##NAME(PyTuple_GET_ITEM(args, 0), \ 312 PyTuple_GET_ITEM(args, 1), \ 313 PyTuple_GET_ITEM(args, 2), \ 314 PyTuple_GET_ITEM(args, 3), context); \ 315 } 316 317 /*********************************************************************/ 318 319 #define GMPY_MPFR_UNIOP_NOROUNDWT(NAME, FUNC) \ 320 static PyObject * \ 321 GMPy_RealWithType_##NAME(PyObject *x, int xtype, CTXT_Object *context) \ 322 { \ 323 MPFR_Object *result = NULL, *tempx = NULL; \ 324 result = GMPy_MPFR_New(0, context); \ 325 tempx = GMPy_MPFR_From_RealWithType(x, xtype, 1, context); \ 326 if (!result || !tempx) { \ 327 Py_XDECREF((PyObject*)result); \ 328 Py_XDECREF((PyObject*)tempx); \ 329 return NULL; \ 330 } \ 331 mpfr_clear_flags(); \ 332 result->rc = mpfr_##FUNC(result->f, tempx->f); \ 333 Py_DECREF((PyObject*)tempx); \ 334 _GMPy_MPFR_Cleanup(&result, context); \ 335 return (PyObject*)result; \ 336 } \ 337 static PyObject * \ 338 GMPy_Number_##NAME(PyObject *x, CTXT_Object *context) \ 339 { \ 340 int xtype = GMPy_ObjectType(x); \ 341 if (IS_TYPE_REAL(xtype)) \ 342 return GMPy_RealWithType_##NAME(x, xtype, context); \ 343 TYPE_ERROR(#FUNC"() argument type not supported"); \ 344 return NULL; \ 345 } \ 346 static PyObject * \ 347 GMPy_MPFR_Method_##NAME(PyObject *self, PyObject *other) \ 348 { \ 349 CTXT_Object *context = NULL; \ 350 CHECK_CONTEXT(context); \ 351 return GMPy_Number_##NAME(self, context); \ 352 }\ 353 static PyObject * \ 354 GMPy_Context_##NAME(PyObject *self, PyObject *other) \ 355 { \ 356 CTXT_Object *context = NULL; \ 357 if (self && CTXT_Check(self)) { \ 358 context = (CTXT_Object*)self; \ 359 } \ 360 else { \ 361 CHECK_CONTEXT(context); \ 362 } \ 363 return GMPy_Number_##NAME(other, context); \ 364 } 365 366 /*********************************************************************/ 367 368 #define GMPY_MPFR_UNIOP_NOROUND_NOMETHODWT(NAME, FUNC) \ 369 static PyObject * \ 370 GMPy_RealWithType_##NAME(PyObject *x, int xtype, CTXT_Object *context) \ 371 { \ 372 MPFR_Object *result = NULL, *tempx = NULL; \ 373 result = GMPy_MPFR_New(0, context); \ 374 tempx = GMPy_MPFR_From_RealWithType(x, xtype, 1, context); \ 375 if (!result || !tempx) { \ 376 Py_XDECREF((PyObject*)result); \ 377 Py_XDECREF((PyObject*)tempx); \ 378 return NULL; \ 379 } \ 380 mpfr_clear_flags(); \ 381 result->rc = mpfr_##FUNC(result->f, tempx->f); \ 382 Py_DECREF((PyObject*)tempx); \ 383 _GMPy_MPFR_Cleanup(&result, context); \ 384 return (PyObject*)result; \ 385 } \ 386 static PyObject * \ 387 GMPy_Number_##NAME(PyObject *x, CTXT_Object *context) \ 388 { \ 389 int xtype = GMPy_ObjectType(x); \ 390 if (IS_TYPE_REAL(xtype)) \ 391 return GMPy_RealWithType_##NAME(x, xtype, context); \ 392 TYPE_ERROR(#FUNC"() argument type not supported"); \ 393 return NULL; \ 394 } \ 395 static PyObject * \ 396 GMPy_Context_##NAME(PyObject *self, PyObject *other) \ 397 { \ 398 CTXT_Object *context = NULL; \ 399 if (self && CTXT_Check(self)) { \ 400 context = (CTXT_Object*)self; \ 401 } \ 402 else { \ 403 CHECK_CONTEXT(context); \ 404 } \ 405 return GMPy_Number_##NAME(other, context); \ 406 } 407 408 /*********************************************************************/ 409 410 #define GMPY_MPFR_UNIOP_EXWT(NAME, FUNC) \ 411 static PyObject * \ 412 GMPy_RealWithType_##NAME(PyObject *x, int xtype, CTXT_Object *context) \ 413 { \ 414 MPFR_Object *result = NULL, *tempx = NULL; \ 415 if (IS_TYPE_MPFR(xtype)) { \ 416 if (!(result = GMPy_MPFR_New(0, context))) return NULL; \ 417 mpfr_clear_flags(); \ 418 result->rc = mpfr_##FUNC(result->f, MPFR(x), GET_MPFR_ROUND(context)); \ 419 _GMPy_MPFR_Cleanup(&result, context); \ 420 return (PyObject*)result; \ 421 } \ 422 if (IS_TYPE_REAL(xtype)) { \ 423 if (!(tempx = GMPy_MPFR_From_RealWithType(x, xtype, 1, context))) return NULL; \ 424 if (!(result = GMPy_MPFR_New(0, context))) { \ 425 Py_DECREF(tempx); \ 426 return NULL; \ 427 } \ 428 mpfr_clear_flags(); \ 429 result->rc = mpfr_##FUNC(result->f, MPFR(tempx), GET_MPFR_ROUND(context)); \ 430 Py_DECREF(tempx); \ 431 _GMPy_MPFR_Cleanup(&result, context); \ 432 return (PyObject*)result; \ 433 } \ 434 TYPE_ERROR(#FUNC"() argument type not supported"); \ 435 return NULL; \ 436 } \ 437 static PyObject * \ 438 GMPy_Number_##NAME(PyObject *x, CTXT_Object *context) \ 439 { \ 440 CHECK_CONTEXT(context); \ 441 int xtype = GMPy_ObjectType(x);\ 442 if (IS_TYPE_REAL(xtype)) \ 443 return GMPy_RealWithType_##NAME(x, xtype, context); \ 444 TYPE_ERROR(#FUNC"() argument type not supported"); \ 445 return NULL; \ 446 } \ 447 static PyObject * \ 448 GMPy_Context_##NAME(PyObject *self, PyObject *other) \ 449 { \ 450 CTXT_Object *context = NULL; \ 451 if (self && CTXT_Check(self)) { \ 452 context = (CTXT_Object*)self; \ 453 } \ 454 else { \ 455 CHECK_CONTEXT(context); \ 456 } \ 457 return GMPy_Number_##NAME(other, context); \ 458 } 459 460 /*********************************************************************/ 461 462 #define GMPY_MPFR_UNIOP_TEMPLATEWT(NAME, FUNC) \ 463 static PyObject * \ 464 GMPy_Number_##NAME(PyObject *x, CTXT_Object *context) \ 465 { \ 466 CHECK_CONTEXT(context); \ 467 int xtype = GMPy_ObjectType(x);\ 468 if (IS_TYPE_REAL(xtype)) \ 469 return GMPy_RealWithType_##NAME(x, xtype, context); \ 470 TYPE_ERROR(#FUNC"() argument type not supported"); \ 471 return NULL; \ 472 } \ 473 static PyObject * \ 474 GMPy_Context_##NAME(PyObject *self, PyObject *other) \ 475 { \ 476 CTXT_Object *context = NULL; \ 477 if (self && CTXT_Check(self)) { \ 478 context = (CTXT_Object*)self; \ 479 } \ 480 else { \ 481 CHECK_CONTEXT(context); \ 482 } \ 483 return GMPy_Number_##NAME(other, context); \ 484 } 485 486 /*********************************************************************/ 487 488 #define GMPY_MPFR_UNIOP_TEMPLATE_EXWT(NAME, FUNC) \ 489 static PyObject * \ 490 GMPy_Number_##NAME(PyObject *x, CTXT_Object *context) \ 491 { \ 492 if (MPFR_Check(x)) \ 493 return _GMPy_MPFR_##NAME(x, context); \ 494 if (IS_REAL(x)) \ 495 return GMPy_Real_##NAME(x, context); \ 496 TYPE_ERROR(#FUNC"() argument type not supported"); \ 497 return NULL; \ 498 } \ 499 static PyObject * \ 500 GMPy_Context_##NAME(PyObject *self, PyObject *other) \ 501 { \ 502 CTXT_Object *context = NULL; \ 503 if (self && CTXT_Check(self)) { \ 504 context = (CTXT_Object*)self; \ 505 } \ 506 else { \ 507 CHECK_CONTEXT(context); \ 508 } \ 509 return GMPy_Number_##NAME(other, context); \ 510 } 511 512 /*********************************************************************/ 513 514 #define GMPY_MPFR_BINOPWT(NAME, FUNC) \ 515 static PyObject * \ 516 GMPy_RealWithType_##NAME(PyObject *x, int xtype, PyObject *y, int ytype, CTXT_Object *context) \ 517 { \ 518 MPFR_Object *result = NULL, *tempx = NULL, *tempy = NULL; \ 519 tempx = GMPy_MPFR_From_RealWithType(x, xtype, 1, context); \ 520 tempy = GMPy_MPFR_From_RealWithType(y, ytype, 1, context); \ 521 result = GMPy_MPFR_New(0, context); \ 522 if (!result || !tempx || !tempy) { \ 523 Py_XDECREF((PyObject*)tempx); \ 524 Py_XDECREF((PyObject*)tempy); \ 525 Py_XDECREF((PyObject*)result); \ 526 return NULL; \ 527 } \ 528 mpfr_clear_flags(); \ 529 result->rc = mpfr_##FUNC(result->f, tempx->f, tempy->f, GET_MPFR_ROUND(context)); \ 530 Py_DECREF((PyObject*)tempx); \ 531 Py_DECREF((PyObject*)tempy); \ 532 _GMPy_MPFR_Cleanup(&result, context); \ 533 return (PyObject*)result; \ 534 } \ 535 static PyObject * \ 536 GMPy_Number_##NAME(PyObject *x, PyObject *y, CTXT_Object *context) \ 537 { \ 538 int xtype = GMPy_ObjectType(x); \ 539 int ytype = GMPy_ObjectType(y); \ 540 CHECK_CONTEXT(context); \ 541 if (IS_TYPE_REAL(xtype) && IS_TYPE_REAL(ytype)) \ 542 return GMPy_RealWithType_##NAME(x, xtype, y, ytype, context); \ 543 TYPE_ERROR(#FUNC"() argument type not supported"); \ 544 return NULL; \ 545 } \ 546 static PyObject * \ 547 GMPy_Context_##NAME(PyObject *self, PyObject *args) \ 548 { \ 549 CTXT_Object *context = NULL; \ 550 if (PyTuple_GET_SIZE(args) != 2) { \ 551 TYPE_ERROR(#FUNC"() requires 2 arguments"); \ 552 return NULL; \ 553 } \ 554 if (self && CTXT_Check(self)) { \ 555 context = (CTXT_Object*)self; \ 556 } \ 557 else { \ 558 CHECK_CONTEXT(context); \ 559 } \ 560 return GMPy_Number_##NAME(PyTuple_GET_ITEM(args, 0), PyTuple_GET_ITEM(args, 1), context); \ 561 } \ 562 563 /* Macro to support functions that require ('mpfr', 'int'). 564 * More precisely, the first argument must pass IS_REAL() and the second 565 * argument must pass IS_INTEGER(). The calling sequence passes n first 566 * to the MPFR library.*/ 567 568 /*********************************************************************/ 569 570 #define GMPY_MPFR_BINOP_REAL_LONGWT(NAME, FUNC) \ 571 static PyObject * \ 572 GMPy_RealWithType_##NAME(PyObject *x, int xtype, PyObject *y, int ytype, CTXT_Object *context) \ 573 { \ 574 MPFR_Object *result = NULL, *tempx = NULL; \ 575 long n; \ 576 result = GMPy_MPFR_New(0, context); \ 577 tempx = GMPy_MPFR_From_RealWithType(x, xtype, 1, context); \ 578 n = GMPy_Integer_AsLongWithType(y, ytype); \ 579 if (!result || !tempx || (n == -1 && PyErr_Occurred())) { \ 580 Py_XDECREF((PyObject*)tempx); \ 581 Py_XDECREF((PyObject*)result); \ 582 return NULL; \ 583 } \ 584 mpfr_clear_flags(); \ 585 result->rc = mpfr_##FUNC(result->f, n, tempx->f, GET_MPFR_ROUND(context)); \ 586 Py_DECREF((PyObject*)tempx); \ 587 _GMPy_MPFR_Cleanup(&result, context); \ 588 return (PyObject*)result; \ 589 } \ 590 static PyObject * \ 591 GMPy_Number_##NAME(PyObject *x, PyObject *y, CTXT_Object *context) \ 592 { \ 593 int xtype = GMPy_ObjectType(x); \ 594 int ytype = GMPy_ObjectType(y); \ 595 CHECK_CONTEXT(context); \ 596 if (IS_TYPE_REAL(xtype) && IS_TYPE_INTEGER(ytype)) \ 597 return GMPy_RealWithType_##NAME(x, xtype, y, ytype, context); \ 598 TYPE_ERROR(#FUNC"() argument type not supported"); \ 599 return NULL; \ 600 } \ 601 static PyObject * \ 602 GMPy_Context_##NAME(PyObject *self, PyObject *args) \ 603 { \ 604 CTXT_Object *context = NULL; \ 605 if (PyTuple_GET_SIZE(args) != 2) { \ 606 TYPE_ERROR(#FUNC"() requires 2 arguments"); \ 607 return NULL; \ 608 } \ 609 if (self && CTXT_Check(self)) { \ 610 context = (CTXT_Object*)self; \ 611 } \ 612 else { \ 613 CHECK_CONTEXT(context); \ 614 } \ 615 return GMPy_Number_##NAME(PyTuple_GET_ITEM(args, 0), PyTuple_GET_ITEM(args, 1), context); \ 616 } \ 617 618 /*********************************************************************/ 619 620 #define GMPY_MPFR_BINOP_TEMPLATEWT(NAME, FUNC) \ 621 static PyObject * \ 622 GMPy_Number_##NAME(PyObject *x, PyObject *y, CTXT_Object *context) \ 623 { \ 624 int xtype = GMPy_ObjectType(x); \ 625 int ytype = GMPy_ObjectType(y); \ 626 CHECK_CONTEXT(context); \ 627 if (IS_TYPE_REAL(xtype) && IS_TYPE_REAL(ytype)) \ 628 return GMPy_RealWithType_##NAME(x, xtype, y, ytype, context); \ 629 TYPE_ERROR(#FUNC"() argument type not supported"); \ 630 return NULL; \ 631 } \ 632 static PyObject * \ 633 GMPy_Context_##NAME(PyObject *self, PyObject *args) \ 634 { \ 635 CTXT_Object *context = NULL; \ 636 if (PyTuple_GET_SIZE(args) != 2) { \ 637 TYPE_ERROR(#FUNC"() requires 2 arguments"); \ 638 return NULL; \ 639 } \ 640 if (self && CTXT_Check(self)) { \ 641 context = (CTXT_Object*)self; \ 642 } \ 643 else { \ 644 CHECK_CONTEXT(context); \ 645 } \ 646 return GMPy_Number_##NAME(PyTuple_GET_ITEM(args, 0), PyTuple_GET_ITEM(args, 1), context); \ 647 } \ 648 649 /*********************************************************************/ 650 651 #define GMPY_MPFR_BINOP_EXWT(NAME, FUNC) \ 652 static PyObject * \ 653 GMPy_RealWithType_##NAME(PyObject *x, int xtype, PyObject *y, int ytype, CTXT_Object *context) \ 654 { \ 655 MPFR_Object *result = NULL, *tempx = NULL, *tempy = NULL; \ 656 CHECK_CONTEXT(context); \ 657 tempx = GMPy_MPFR_From_RealWithType(x, xtype, 1, context); \ 658 tempy = GMPy_MPFR_From_RealWithType(y, ytype, 1, context); \ 659 result = GMPy_MPFR_New(0, context); \ 660 if (!tempx || !tempy || !result) { \ 661 Py_XDECREF(tempx); \ 662 Py_XDECREF(tempy); \ 663 Py_XDECREF(result); \ 664 return NULL; \ 665 } \ 666 mpfr_clear_flags(); \ 667 result->rc = mpfr_##FUNC(result->f, tempx->f, tempy->f, GET_MPFR_ROUND(context)); \ 668 Py_DECREF(tempx); \ 669 Py_DECREF(tempy); \ 670 _GMPy_MPFR_Cleanup(&result, context); \ 671 return (PyObject*)result; \ 672 } \ 673 static PyObject * \ 674 GMPy_Number_##NAME(PyObject *x, PyObject *y, CTXT_Object *context) \ 675 { \ 676 int xtype = GMPy_ObjectType(x); \ 677 int ytype = GMPy_ObjectType(y); \ 678 CHECK_CONTEXT(context); \ 679 if (IS_TYPE_REAL(xtype) && IS_TYPE_REAL(ytype)) \ 680 return GMPy_RealWithType_##NAME(x, xtype, y, ytype, context); \ 681 TYPE_ERROR(#FUNC"() argument type not supported"); \ 682 return NULL; \ 683 } \ 684 static PyObject * \ 685 GMPy_Context_##NAME(PyObject *self, PyObject *args) \ 686 { \ 687 CTXT_Object *context = NULL; \ 688 if (PyTuple_GET_SIZE(args) != 2) { \ 689 TYPE_ERROR(#FUNC"() requires 2 arguments"); \ 690 return NULL; \ 691 } \ 692 if (self && CTXT_Check(self)) { \ 693 context = (CTXT_Object*)self; \ 694 } \ 695 else { \ 696 CHECK_CONTEXT(context); \ 697 } \ 698 return GMPy_Number_##NAME(PyTuple_GET_ITEM(args, 0), PyTuple_GET_ITEM(args, 1), context); \ 699 } 700