1 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
2  * gmpy_convert.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 #ifndef GMPY2_CONVERT_H
28 #define GMPY2_CONVERT_H
29 
30 #ifdef __cplusplus
31 extern "C" {
32 #endif
33 
34 /* The following macros classify the numeric types that are supported by
35  * gmpy2.
36  */
37 #define HAS_MPZ_CONVERSION(x) (PyObject_HasAttrString(x, "__mpz__"))
38 #define HAS_MPQ_CONVERSION(x) (PyObject_HasAttrString(x, "__mpq__"))
39 #define HAS_MPFR_CONVERSION(x) (PyObject_HasAttrString(x, "__mpfr__"))
40 #define HAS_MPC_CONVERSION(x) (PyObject_HasAttrString(x, "__mpc__"))
41 
42 #define HAS_STRICT_MPZ_CONVERSION(x) (HAS_MPZ_CONVERSION(x) && \
43                                      !HAS_MPQ_CONVERSION(x))
44 #define HAS_STRICT_MPFR_CONVERSION(x) (HAS_MPFR_CONVERSION(x) && \
45                                       !HAS_MPC_CONVERSION(x))
46 
47 #define IS_FRACTION(x) (!strcmp(Py_TYPE(x)->tp_name, "Fraction"))
48 
49 #define IS_RATIONAL_ONLY(x) (MPQ_Check(x) || IS_FRACTION(x) || \
50                              HAS_MPQ_CONVERSION(x))
51 
52 #ifdef PY2
53 #define IS_INTEGER(x) (MPZ_Check(x) || PyInt_Check(x) || \
54                        PyLong_Check(x) || XMPZ_Check(x) || \
55                        HAS_STRICT_MPZ_CONVERSION(x))
56 #define IS_RATIONAL(x) (MPQ_Check(x) || IS_FRACTION(x) || \
57                         MPZ_Check(x) || PyInt_Check(x) || \
58                         PyLong_Check(x)  || XMPZ_Check(x) || \
59                         HAS_MPQ_CONVERSION(x) || HAS_MPZ_CONVERSION(x))
60 #else
61 #define IS_INTEGER(x) (MPZ_Check(x) || PyLong_Check(x) || \
62                        XMPZ_Check(x) || HAS_STRICT_MPZ_CONVERSION(x))
63 #define IS_RATIONAL(x) (MPQ_Check(x) || IS_FRACTION(x) || \
64                         MPZ_Check(x) || PyLong_Check(x) || \
65                         XMPZ_Check(x) || HAS_MPQ_CONVERSION(x) || \
66                         HAS_MPZ_CONVERSION(x))
67 #endif
68 
69 #define IS_REAL_ONLY(x) (MPFR_Check(x) || PyFloat_Check(x) || \
70                          HAS_STRICT_MPFR_CONVERSION(x))
71 #define IS_REAL(x) (IS_RATIONAL(x) || IS_REAL_ONLY(x))
72 
73 #define IS_COMPLEX_ONLY(x) (MPC_Check(x) || PyComplex_Check(x) || \
74                             HAS_MPC_CONVERSION(x))
75 #define IS_COMPLEX(x) (IS_REAL(x) || IS_COMPLEX_ONLY(x))
76 
77 /* Define constants used in gmpy2_convert.c->GMPy_ObjectType. */
78 
79 #define OBJ_TYPE_UNKNOWN        0
80 #define OBJ_TYPE_MPZ            1
81 #define OBJ_TYPE_XMPZ           2
82 #define OBJ_TYPE_PyInteger      3
83 #define OBJ_TYPE_HAS_MPZ        4
84 /* 5 TO 14 reserved for additional integer types. */
85 #define OBJ_TYPE_INTEGER        15
86 
87 #define OBJ_TYPE_MPQ            16
88 #define OBJ_TYPE_PyFraction     17
89 #define OBJ_TYPE_HAS_MPQ        18
90 /* 19 to 30 reserved for additional rational types. */
91 #define OBJ_TYPE_RATIONAL       31
92 
93 #define OBJ_TYPE_MPFR           32
94 #define OBJ_TYPE_PyFloat        33
95 #define OBJ_TYPE_HAS_MPFR       34
96 /* 35 to 46 reserved for additional real types. */
97 #define OBJ_TYPE_REAL           47
98 
99 #define OBJ_TYPE_MPC            48
100 #define OBJ_TYPE_PyComplex      49
101 #define OBJ_TYPE_HAS_MPC        50
102 /* 50 to 62 reserved for additional complex types. */
103 #define OBJ_TYPE_COMPLEX        63
104 
105 #define OBJ_TYPE_MAX            64
106 
107 /* The following macros are the recommended method to check the result of the
108  * object type check.
109  */
110 
111 #define IS_TYPE_UNKNOWN(x)          (!OBJ_TYPE_UNKNOWN)
112 #define IS_TYPE_MPZ(x)              (x == OBJ_TYPE_MPZ)
113 #define IS_TYPE_XMPZ(x)             (x == OBJ_TYPE_XMPZ)
114 #define IS_TYPE_MPZANY(x)           ((x == OBJ_TYPE_MPZ) || \
115                                      (x == OBJ_TYPE_XMPZ))
116 #define IS_TYPE_PyInteger(x)        (x == OBJ_TYPE_PyInteger)
117 #define IS_TYPE_HAS_MPZ(x)          (x == OBJ_TYPE_HAS_MPZ)
118 #define IS_TYPE_INTEGER(x)          ((x > OBJ_TYPE_UNKNOWN) &&  \
119                                      (x < OBJ_TYPE_INTEGER))
120 
121 #define IS_TYPE_MPQ(x)              (x == OBJ_TYPE_MPQ)
122 #define IS_TYPE_PyFraction(x)       (x == OBJ_TYPE_PyFraction)
123 #define IS_TYPE_HAS_MPQ(x)          (x == OBJ_TYPE_HAS_MPQ)
124 #define IS_TYPE_RATIONAL(x)         ((x > OBJ_TYPE_UNKNOWN) && \
125                                      (x < OBJ_TYPE_RATIONAL))
126 #define IS_TYPE_RATIONAL_ONLY(x)    ((x > OBJ_TYPE_INTEGER) && \
127                                      (x < OBJ_TYPE_RATIONAL))
128 
129 #define IS_TYPE_MPFR(x)             (x == OBJ_TYPE_MPFR)
130 #define IS_TYPE_PyFloat(x)          (x == OBJ_TYPE_PyFloat)
131 #define IS_TYPE_HAS_MPFR(x)         (x == OBJ_TYPE_HAS_MPFR)
132 #define IS_TYPE_REAL(x)             ((x > OBJ_TYPE_UNKNOWN) && \
133                                      (x < OBJ_TYPE_REAL))
134 #define IS_TYPE_REAL_ONLY(x)        ((x > OBJ_TYPE_RATIONAL) && \
135                                      (x < OBJ_TYPE_REAL))
136 
137 #define IS_TYPE_MPC(x)              (x == OBJ_TYPE_MPC)
138 #define IS_TYPE_PyComplex(x)        (x == OBJ_TYPE_PyComplex)
139 #define IS_TYPE_HAS_MPC(x)          (x == OBJ_TYPE_HAS_MPC)
140 #define IS_TYPE_COMPLEX(x)          ((x > OBJ_TYPE_UNKNOWN) && \
141                                      (x < OBJ_TYPE_COMPLEX))
142 #define IS_TYPE_COMPLEX_ONLY(x)     ((x > OBJ_TYPE_REAL) && \
143                                      (x < OBJ_TYPE_COMPLEX))
144 
145 
146 /* Since the macros are used in gmpy2's codebase, these functions are skipped
147  * until they are needed for the C API in the future.
148  */
149 
150 #if 0
151 /* Checks for mpz, xmpz, and the integer types included with Python. */
152 static int GMPy_isInteger(PyObject *obj);
153 
154 /* Checks for the Fraction type included with Python. */
155 static int GMPy_isFraction(PyObject *obj);
156 
157 /* Combined mpq, isInteger() and isFraction() check. */
158 static int GMPy_isRational(PyObject *obj);
159 
160 /* Combined mpfr, PyFloat, and isRational() check. */
161 static int GMPy_isReal(PyObject *obj);
162 
163 /* Combined mpc, PyComplex, and isReal() check. */
164 static int GMPy_isComplex(PyObject *obj);
165 #endif
166 
167 /* ======== C helper routines ======== */
168 static int             mpz_set_PyStr(mpz_ptr z, PyObject *s, int base);
169 static PyObject *      mpz_ascii(mpz_t z, int base, int option, int which);
170 
171 #ifdef __cplusplus
172 }
173 #endif
174 #endif
175