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