1 /*
2  * DON'T INCLUDE THIS DIRECTLY.
3  */
4 
5 #ifndef NPY_NDARRAYOBJECT_H
6 #define NPY_NDARRAYOBJECT_H
7 #ifdef __cplusplus
8 extern "C" {
9 #endif
10 
11 #include <Python.h>
12 #include "ndarraytypes.h"
13 
14 /* Includes the "function" C-API -- these are all stored in a
15    list of pointers --- one for each file
16    The two lists are concatenated into one in multiarray.
17 
18    They are available as import_array()
19 */
20 
21 #include "__multiarray_api.h"
22 
23 
24 /* C-API that requires previous API to be defined */
25 
26 #define PyArray_DescrCheck(op) PyObject_TypeCheck(op, &PyArrayDescr_Type)
27 
28 #define PyArray_Check(op) PyObject_TypeCheck(op, &PyArray_Type)
29 #define PyArray_CheckExact(op) (((PyObject*)(op))->ob_type == &PyArray_Type)
30 
31 #define PyArray_HasArrayInterfaceType(op, type, context, out)                 \
32         ((((out)=PyArray_FromStructInterface(op)) != Py_NotImplemented) ||    \
33          (((out)=PyArray_FromInterface(op)) != Py_NotImplemented) ||          \
34          (((out)=PyArray_FromArrayAttr(op, type, context)) !=                 \
35           Py_NotImplemented))
36 
37 #define PyArray_HasArrayInterface(op, out)                                    \
38         PyArray_HasArrayInterfaceType(op, NULL, NULL, out)
39 
40 #define PyArray_IsZeroDim(op) (PyArray_Check(op) && \
41                                (PyArray_NDIM((PyArrayObject *)op) == 0))
42 
43 #define PyArray_IsScalar(obj, cls)                                            \
44         (PyObject_TypeCheck(obj, &Py##cls##ArrType_Type))
45 
46 #define PyArray_CheckScalar(m) (PyArray_IsScalar(m, Generic) ||               \
47                                 PyArray_IsZeroDim(m))
48 #define PyArray_IsPythonNumber(obj)                                           \
49         (PyFloat_Check(obj) || PyComplex_Check(obj) ||                        \
50          PyLong_Check(obj) || PyBool_Check(obj))
51 #define PyArray_IsIntegerScalar(obj) (PyLong_Check(obj)                       \
52               || PyArray_IsScalar((obj), Integer))
53 #define PyArray_IsPythonScalar(obj)                                           \
54         (PyArray_IsPythonNumber(obj) || PyBytes_Check(obj) ||                 \
55          PyUnicode_Check(obj))
56 
57 #define PyArray_IsAnyScalar(obj)                                              \
58         (PyArray_IsScalar(obj, Generic) || PyArray_IsPythonScalar(obj))
59 
60 #define PyArray_CheckAnyScalar(obj) (PyArray_IsPythonScalar(obj) ||           \
61                                      PyArray_CheckScalar(obj))
62 
63 
64 #define PyArray_GETCONTIGUOUS(m) (PyArray_ISCONTIGUOUS(m) ?                   \
65                                   Py_INCREF(m), (m) :                         \
66                                   (PyArrayObject *)(PyArray_Copy(m)))
67 
68 #define PyArray_SAMESHAPE(a1,a2) ((PyArray_NDIM(a1) == PyArray_NDIM(a2)) &&   \
69                                   PyArray_CompareLists(PyArray_DIMS(a1),      \
70                                                        PyArray_DIMS(a2),      \
71                                                        PyArray_NDIM(a1)))
72 
73 #define PyArray_SIZE(m) PyArray_MultiplyList(PyArray_DIMS(m), PyArray_NDIM(m))
74 #define PyArray_NBYTES(m) (PyArray_ITEMSIZE(m) * PyArray_SIZE(m))
75 #define PyArray_FROM_O(m) PyArray_FromAny(m, NULL, 0, 0, 0, NULL)
76 
77 #define PyArray_FROM_OF(m,flags) PyArray_CheckFromAny(m, NULL, 0, 0, flags,   \
78                                                       NULL)
79 
80 #define PyArray_FROM_OT(m,type) PyArray_FromAny(m,                            \
81                                 PyArray_DescrFromType(type), 0, 0, 0, NULL)
82 
83 #define PyArray_FROM_OTF(m, type, flags) \
84         PyArray_FromAny(m, PyArray_DescrFromType(type), 0, 0, \
85                         (((flags) & NPY_ARRAY_ENSURECOPY) ? \
86                          ((flags) | NPY_ARRAY_DEFAULT) : (flags)), NULL)
87 
88 #define PyArray_FROMANY(m, type, min, max, flags) \
89         PyArray_FromAny(m, PyArray_DescrFromType(type), min, max, \
90                         (((flags) & NPY_ARRAY_ENSURECOPY) ? \
91                          (flags) | NPY_ARRAY_DEFAULT : (flags)), NULL)
92 
93 #define PyArray_ZEROS(m, dims, type, is_f_order) \
94         PyArray_Zeros(m, dims, PyArray_DescrFromType(type), is_f_order)
95 
96 #define PyArray_EMPTY(m, dims, type, is_f_order) \
97         PyArray_Empty(m, dims, PyArray_DescrFromType(type), is_f_order)
98 
99 #define PyArray_FILLWBYTE(obj, val) memset(PyArray_DATA(obj), val, \
100                                            PyArray_NBYTES(obj))
101 #ifndef PYPY_VERSION
102 #define PyArray_REFCOUNT(obj) (((PyObject *)(obj))->ob_refcnt)
103 #define NPY_REFCOUNT PyArray_REFCOUNT
104 #endif
105 #define NPY_MAX_ELSIZE (2 * NPY_SIZEOF_LONGDOUBLE)
106 
107 #define PyArray_ContiguousFromAny(op, type, min_depth, max_depth) \
108         PyArray_FromAny(op, PyArray_DescrFromType(type), min_depth, \
109                               max_depth, NPY_ARRAY_DEFAULT, NULL)
110 
111 #define PyArray_EquivArrTypes(a1, a2) \
112         PyArray_EquivTypes(PyArray_DESCR(a1), PyArray_DESCR(a2))
113 
114 #define PyArray_EquivByteorders(b1, b2) \
115         (((b1) == (b2)) || (PyArray_ISNBO(b1) == PyArray_ISNBO(b2)))
116 
117 #define PyArray_SimpleNew(nd, dims, typenum) \
118         PyArray_New(&PyArray_Type, nd, dims, typenum, NULL, NULL, 0, 0, NULL)
119 
120 #define PyArray_SimpleNewFromData(nd, dims, typenum, data) \
121         PyArray_New(&PyArray_Type, nd, dims, typenum, NULL, \
122                     data, 0, NPY_ARRAY_CARRAY, NULL)
123 
124 #define PyArray_SimpleNewFromDescr(nd, dims, descr) \
125         PyArray_NewFromDescr(&PyArray_Type, descr, nd, dims, \
126                              NULL, NULL, 0, NULL)
127 
128 #define PyArray_ToScalar(data, arr) \
129         PyArray_Scalar(data, PyArray_DESCR(arr), (PyObject *)arr)
130 
131 
132 /* These might be faster without the dereferencing of obj
133    going on inside -- of course an optimizing compiler should
134    inline the constants inside a for loop making it a moot point
135 */
136 
137 #define PyArray_GETPTR1(obj, i) ((void *)(PyArray_BYTES(obj) + \
138                                          (i)*PyArray_STRIDES(obj)[0]))
139 
140 #define PyArray_GETPTR2(obj, i, j) ((void *)(PyArray_BYTES(obj) + \
141                                             (i)*PyArray_STRIDES(obj)[0] + \
142                                             (j)*PyArray_STRIDES(obj)[1]))
143 
144 #define PyArray_GETPTR3(obj, i, j, k) ((void *)(PyArray_BYTES(obj) + \
145                                             (i)*PyArray_STRIDES(obj)[0] + \
146                                             (j)*PyArray_STRIDES(obj)[1] + \
147                                             (k)*PyArray_STRIDES(obj)[2]))
148 
149 #define PyArray_GETPTR4(obj, i, j, k, l) ((void *)(PyArray_BYTES(obj) + \
150                                             (i)*PyArray_STRIDES(obj)[0] + \
151                                             (j)*PyArray_STRIDES(obj)[1] + \
152                                             (k)*PyArray_STRIDES(obj)[2] + \
153                                             (l)*PyArray_STRIDES(obj)[3]))
154 
155 /* Move to arrayobject.c once PyArray_XDECREF_ERR is removed */
156 static NPY_INLINE void
PyArray_DiscardWritebackIfCopy(PyArrayObject * arr)157 PyArray_DiscardWritebackIfCopy(PyArrayObject *arr)
158 {
159     PyArrayObject_fields *fa = (PyArrayObject_fields *)arr;
160     if (fa && fa->base) {
161         if ((fa->flags & NPY_ARRAY_UPDATEIFCOPY) ||
162                 (fa->flags & NPY_ARRAY_WRITEBACKIFCOPY)) {
163             PyArray_ENABLEFLAGS((PyArrayObject*)fa->base, NPY_ARRAY_WRITEABLE);
164             Py_DECREF(fa->base);
165             fa->base = NULL;
166             PyArray_CLEARFLAGS(arr, NPY_ARRAY_WRITEBACKIFCOPY);
167             PyArray_CLEARFLAGS(arr, NPY_ARRAY_UPDATEIFCOPY);
168         }
169     }
170 }
171 
172 #define PyArray_DESCR_REPLACE(descr) do { \
173                 PyArray_Descr *_new_; \
174                 _new_ = PyArray_DescrNew(descr); \
175                 Py_XDECREF(descr); \
176                 descr = _new_; \
177         } while(0)
178 
179 /* Copy should always return contiguous array */
180 #define PyArray_Copy(obj) PyArray_NewCopy(obj, NPY_CORDER)
181 
182 #define PyArray_FromObject(op, type, min_depth, max_depth) \
183         PyArray_FromAny(op, PyArray_DescrFromType(type), min_depth, \
184                               max_depth, NPY_ARRAY_BEHAVED | \
185                                          NPY_ARRAY_ENSUREARRAY, NULL)
186 
187 #define PyArray_ContiguousFromObject(op, type, min_depth, max_depth) \
188         PyArray_FromAny(op, PyArray_DescrFromType(type), min_depth, \
189                               max_depth, NPY_ARRAY_DEFAULT | \
190                                          NPY_ARRAY_ENSUREARRAY, NULL)
191 
192 #define PyArray_CopyFromObject(op, type, min_depth, max_depth) \
193         PyArray_FromAny(op, PyArray_DescrFromType(type), min_depth, \
194                         max_depth, NPY_ARRAY_ENSURECOPY | \
195                                    NPY_ARRAY_DEFAULT | \
196                                    NPY_ARRAY_ENSUREARRAY, NULL)
197 
198 #define PyArray_Cast(mp, type_num)                                            \
199         PyArray_CastToType(mp, PyArray_DescrFromType(type_num), 0)
200 
201 #define PyArray_Take(ap, items, axis)                                         \
202         PyArray_TakeFrom(ap, items, axis, NULL, NPY_RAISE)
203 
204 #define PyArray_Put(ap, items, values)                                        \
205         PyArray_PutTo(ap, items, values, NPY_RAISE)
206 
207 /* Compatibility with old Numeric stuff -- don't use in new code */
208 
209 #define PyArray_FromDimsAndData(nd, d, type, data)                            \
210         PyArray_FromDimsAndDataAndDescr(nd, d, PyArray_DescrFromType(type),   \
211                                         data)
212 
213 
214 /*
215    Check to see if this key in the dictionary is the "title"
216    entry of the tuple (i.e. a duplicate dictionary entry in the fields
217    dict).
218 */
219 
220 static NPY_INLINE int
NPY_TITLE_KEY_check(PyObject * key,PyObject * value)221 NPY_TITLE_KEY_check(PyObject *key, PyObject *value)
222 {
223     PyObject *title;
224     if (PyTuple_Size(value) != 3) {
225         return 0;
226     }
227     title = PyTuple_GetItem(value, 2);
228     if (key == title) {
229         return 1;
230     }
231 #ifdef PYPY_VERSION
232     /*
233      * On PyPy, dictionary keys do not always preserve object identity.
234      * Fall back to comparison by value.
235      */
236     if (PyUnicode_Check(title) && PyUnicode_Check(key)) {
237         return PyUnicode_Compare(title, key) == 0 ? 1 : 0;
238     }
239 #endif
240     return 0;
241 }
242 
243 /* Macro, for backward compat with "if NPY_TITLE_KEY(key, value) { ..." */
244 #define NPY_TITLE_KEY(key, value) (NPY_TITLE_KEY_check((key), (value)))
245 
246 #define DEPRECATE(msg) PyErr_WarnEx(PyExc_DeprecationWarning,msg,1)
247 #define DEPRECATE_FUTUREWARNING(msg) PyErr_WarnEx(PyExc_FutureWarning,msg,1)
248 
249 #if !defined(NPY_NO_DEPRECATED_API) || \
250     (NPY_NO_DEPRECATED_API < NPY_1_14_API_VERSION)
251 static NPY_INLINE void
PyArray_XDECREF_ERR(PyArrayObject * arr)252 PyArray_XDECREF_ERR(PyArrayObject *arr)
253 {
254     /* 2017-Nov-10 1.14 */
255     DEPRECATE("PyArray_XDECREF_ERR is deprecated, call "
256         "PyArray_DiscardWritebackIfCopy then Py_XDECREF instead");
257     PyArray_DiscardWritebackIfCopy(arr);
258     Py_XDECREF(arr);
259 }
260 #endif
261 
262 
263 #ifdef __cplusplus
264 }
265 #endif
266 
267 
268 #endif /* NPY_NDARRAYOBJECT_H */
269