1#![allow(non_camel_case_types)]
5
6use libc::FILE;
7use pyo3::ffi::*;
8use std::ffi::*;
9
10use super::types::*;
11use crate::npyffi::*;
12
13pub const NPY_NTYPES_ABI_COMPATIBLE: usize = 21;
14pub const NPY_MAXDIMS_LEGACY_ITERS: usize = 32;
15
16#[repr(C)]
17pub struct PyArrayObject {
18 pub ob_base: PyObject,
19 pub data: *mut c_char,
20 pub nd: c_int,
21 pub dimensions: *mut npy_intp,
22 pub strides: *mut npy_intp,
23 pub base: *mut PyObject,
24 pub descr: *mut PyArray_Descr,
25 pub flags: c_int,
26 pub weakreflist: *mut PyObject,
27}
28
29#[repr(C)]
30pub struct PyArray_Descr {
31 pub ob_base: PyObject,
32 pub typeobj: *mut PyTypeObject,
33 pub kind: c_char,
34 pub type_: c_char,
35 pub byteorder: c_char,
36 pub _former_flags: c_char,
37 pub type_num: c_int,
38}
39
40#[repr(C)]
41pub struct PyArray_DescrProto {
42 pub ob_base: PyObject,
43 pub typeobj: *mut PyTypeObject,
44 pub kind: c_char,
45 pub type_: c_char,
46 pub byteorder: c_char,
47 pub flags: c_char,
48 pub type_num: c_int,
49 pub elsize: c_int,
50 pub alignment: c_int,
51 pub subarray: *mut PyArray_ArrayDescr,
52 pub fields: *mut PyObject,
53 pub names: *mut PyObject,
54 pub f: *mut PyArray_ArrFuncs,
55 pub metadata: *mut PyObject,
56 pub c_metadata: *mut NpyAuxData,
57 pub hash: npy_hash_t,
58}
59
60#[repr(C)]
61pub struct _PyArray_DescrNumPy2 {
62 pub ob_base: PyObject,
63 pub typeobj: *mut PyTypeObject,
64 pub kind: c_char,
65 pub type_: c_char,
66 pub byteorder: c_char,
67 pub _former_flags: c_char,
68 pub type_num: c_int,
69 pub flags: npy_uint64,
70 pub elsize: npy_intp,
71 pub alignment: npy_intp,
72 pub metadata: *mut PyObject,
73 pub hash: npy_hash_t,
74 pub reserved_null: [*mut std::ffi::c_void; 2],
75}
76
77#[repr(C)]
78struct _PyArray_LegacyDescr {
79 pub ob_base: PyObject,
80 pub typeobj: *mut PyTypeObject,
81 pub kind: c_char,
82 pub type_: c_char,
83 pub byteorder: c_char,
84 pub _former_flags: c_char,
85 pub type_num: c_int,
86 pub flags: npy_uint64,
87 pub elsize: npy_intp,
88 pub alignment: npy_intp,
89 pub metadata: *mut PyObject,
90 pub hash: npy_hash_t,
91 pub reserved_null: [*mut std::ffi::c_void; 2],
92 pub subarray: *mut PyArray_ArrayDescr,
93 pub fields: *mut PyObject,
94 pub names: *mut PyObject,
95 pub c_metadata: *mut NpyAuxData,
96}
97
98#[allow(non_snake_case)]
99#[inline(always)]
100pub unsafe fn PyDataType_ISLEGACY(dtype: *const PyArray_Descr) -> bool {
101 (*dtype).type_num < NPY_TYPES::NPY_VSTRING as _ && (*dtype).type_num >= 0
102}
103
104#[allow(non_snake_case)]
105#[inline(always)]
106pub unsafe fn PyDataType_SET_ELSIZE<'py>(
107 py: Python<'py>,
108 dtype: *mut PyArray_Descr,
109 size: npy_intp,
110) {
111 if is_numpy_2(py) {
112 unsafe {
113 (*(dtype as *mut _PyArray_DescrNumPy2)).elsize = size;
114 }
115 } else {
116 unsafe {
117 (*(dtype as *mut PyArray_DescrProto)).elsize = size as c_int;
118 }
119 }
120}
121
122#[allow(non_snake_case)]
123#[inline(always)]
124pub unsafe fn PyDataType_FLAGS<'py>(py: Python<'py>, dtype: *const PyArray_Descr) -> npy_uint64 {
125 if is_numpy_2(py) {
126 unsafe { (*(dtype as *mut _PyArray_DescrNumPy2)).flags }
127 } else {
128 unsafe { (*(dtype as *mut PyArray_DescrProto)).flags as c_uchar as npy_uint64 }
129 }
130}
131
132macro_rules! define_descr_accessor {
133 ($name:ident, $property:ident, $type:ty, $legacy_only:literal, $default:expr) => {
134 #[allow(non_snake_case)]
135 #[inline(always)]
136 pub unsafe fn $name<'py>(py: Python<'py>, dtype: *const PyArray_Descr) -> $type {
137 if $legacy_only && !PyDataType_ISLEGACY(dtype) {
138 $default
139 } else {
140 if is_numpy_2(py) {
141 unsafe { (*(dtype as *const _PyArray_LegacyDescr)).$property }
142 } else {
143 unsafe { (*(dtype as *mut PyArray_DescrProto)).$property as $type }
144 }
145 }
146 }
147 };
148}
149
150define_descr_accessor!(PyDataType_ELSIZE, elsize, npy_intp, false, 0);
151define_descr_accessor!(PyDataType_ALIGNMENT, alignment, npy_intp, false, 0);
152define_descr_accessor!(
153 PyDataType_METADATA,
154 metadata,
155 *mut PyObject,
156 true,
157 std::ptr::null_mut()
158);
159define_descr_accessor!(
160 PyDataType_SUBARRAY,
161 subarray,
162 *mut PyArray_ArrayDescr,
163 true,
164 std::ptr::null_mut()
165);
166define_descr_accessor!(
167 PyDataType_NAMES,
168 names,
169 *mut PyObject,
170 true,
171 std::ptr::null_mut()
172);
173define_descr_accessor!(
174 PyDataType_FIELDS,
175 fields,
176 *mut PyObject,
177 true,
178 std::ptr::null_mut()
179);
180define_descr_accessor!(
181 PyDataType_C_METADATA,
182 c_metadata,
183 *mut NpyAuxData,
184 true,
185 std::ptr::null_mut()
186);
187
188#[repr(C)]
189#[derive(Copy, Clone)]
190pub struct PyArray_ArrayDescr {
191 pub base: *mut PyArray_Descr,
192 pub shape: *mut PyObject,
193}
194
195#[repr(C)]
196#[derive(Copy, Clone)]
197pub struct PyArray_ArrFuncs {
198 pub cast: [PyArray_VectorUnaryFunc; NPY_NTYPES_ABI_COMPATIBLE],
199 pub getitem: PyArray_GetItemFunc,
200 pub setitem: PyArray_SetItemFunc,
201 pub copyswapn: PyArray_CopySwapNFunc,
202 pub copyswap: PyArray_CopySwapFunc,
203 pub compare: PyArray_CompareFunc,
204 pub argmax: PyArray_ArgFunc,
205 pub dotfunc: PyArray_DotFunc,
206 pub scanfunc: PyArray_ScanFunc,
207 pub fromstr: PyArray_FromStrFunc,
208 pub nonzero: PyArray_NonzeroFunc,
209 pub fill: PyArray_FillFunc,
210 pub fillwithscalar: PyArray_FillWithScalarFunc,
211 pub sort: [PyArray_SortFunc; NPY_NSORTS],
212 pub argsort: [PyArray_ArgSortFunc; NPY_NSORTS],
213 pub castdict: *mut PyObject,
214 pub scalarkind: PyArray_ScalarKindFunc,
215 pub cancastscalarkindto: *mut *mut c_int,
216 pub cancastto: *mut c_int,
217 pub _unused1: *mut c_void,
218 pub _unused2: *mut c_void,
219 pub _unused3: *mut c_void,
220 pub argmin: PyArray_ArgFunc,
221}
222
223pub type PyArray_GetItemFunc =
224 Option<unsafe extern "C" fn(*mut c_void, *mut c_void) -> *mut PyObject>;
225pub type PyArray_SetItemFunc =
226 Option<unsafe extern "C" fn(*mut PyObject, *mut c_void, *mut c_void) -> c_int>;
227pub type PyArray_CopySwapNFunc = Option<
228 unsafe extern "C" fn(
229 *mut c_void,
230 npy_intp,
231 *mut c_void,
232 npy_intp,
233 npy_intp,
234 c_int,
235 *mut c_void,
236 ),
237>;
238pub type PyArray_CopySwapFunc =
239 Option<unsafe extern "C" fn(*mut c_void, *mut c_void, c_int, *mut c_void)>;
240pub type PyArray_NonzeroFunc = Option<unsafe extern "C" fn(*mut c_void, *mut c_void) -> c_uchar>;
241pub type PyArray_CompareFunc =
242 Option<unsafe extern "C" fn(*const c_void, *const c_void, *mut c_void) -> c_int>;
243pub type PyArray_ArgFunc =
244 Option<unsafe extern "C" fn(*mut c_void, npy_intp, *mut npy_intp, *mut c_void) -> c_int>;
245pub type PyArray_DotFunc = Option<
246 unsafe extern "C" fn(
247 *mut c_void,
248 npy_intp,
249 *mut c_void,
250 npy_intp,
251 *mut c_void,
252 npy_intp,
253 *mut c_void,
254 ),
255>;
256pub type PyArray_VectorUnaryFunc =
257 Option<unsafe extern "C" fn(*mut c_void, *mut c_void, npy_intp, *mut c_void, *mut c_void)>;
258pub type PyArray_ScanFunc =
259 Option<unsafe extern "C" fn(*mut FILE, *mut c_void, *mut c_char, *mut PyArray_Descr) -> c_int>;
260pub type PyArray_FromStrFunc = Option<
261 unsafe extern "C" fn(*mut c_char, *mut c_void, *mut *mut c_char, *mut PyArray_Descr) -> c_int,
262>;
263pub type PyArray_FillFunc =
264 Option<unsafe extern "C" fn(*mut c_void, npy_intp, *mut c_void) -> c_int>;
265pub type PyArray_SortFunc =
266 Option<unsafe extern "C" fn(*mut c_void, npy_intp, *mut c_void) -> c_int>;
267pub type PyArray_ArgSortFunc =
268 Option<unsafe extern "C" fn(*mut c_void, *mut npy_intp, npy_intp, *mut c_void) -> c_int>;
269pub type PyArray_FillWithScalarFunc =
270 Option<unsafe extern "C" fn(*mut c_void, npy_intp, *mut c_void, *mut c_void) -> c_int>;
271pub type PyArray_ScalarKindFunc = Option<unsafe extern "C" fn(*mut c_void) -> c_int>;
272
273#[repr(C)]
274#[derive(Clone, Copy)]
275pub struct PyArray_Dims {
276 pub ptr: *mut npy_intp,
277 pub len: c_int,
278}
279
280#[repr(C)]
281pub struct PyArray_Chunk {
282 pub ob_base: PyObject,
283 pub base: *mut PyObject,
284 pub ptr: *mut c_void,
285 pub len: npy_intp,
286 pub flags: c_int,
287}
288
289#[repr(C)]
290#[derive(Clone, Copy)]
291pub struct PyArrayInterface {
292 pub two: c_int,
293 pub nd: c_int,
294 pub typekind: c_char,
295 pub itemsize: c_int,
296 pub flags: c_int,
297 pub shape: *mut npy_intp,
298 pub strides: *mut npy_intp,
299 pub data: *mut c_void,
300 pub descr: *mut PyObject,
301}
302
303#[repr(C)]
304pub struct PyUFuncObject {
305 pub ob_base: PyObject,
306 pub nin: c_int,
307 pub nout: c_int,
308 pub nargs: c_int,
309 pub identity: c_int,
310 pub functions: *mut PyUFuncGenericFunction,
311 pub data: *mut *mut c_void,
312 pub ntypes: c_int,
313 pub reserved1: c_int,
314 pub name: *const c_char,
315 pub types: *mut c_char,
316 pub doc: *const c_char,
317 pub ptr: *mut c_void,
318 pub obj: *mut PyObject,
319 pub userloops: *mut PyObject,
320 pub core_enabled: c_int,
321 pub core_num_dim_ix: c_int,
322 pub core_num_dims: *mut c_int,
323 pub core_dim_ixs: *mut c_int,
324 pub core_offsets: *mut c_int,
325 pub core_signature: *mut c_char,
326 pub type_resolver: PyUFunc_TypeResolutionFunc,
327 pub reserved2: *mut c_void, #[cfg(all(Py_3_8, not(Py_LIMITED_API)))]
329 pub vectorcall: Option<vectorcallfunc>,
330 #[cfg(not(all(Py_3_8, not(Py_LIMITED_API))))]
331 pub vectorcall: *mut c_void,
332 pub reserved3: *mut c_void, pub op_flags: *mut npy_uint32,
334 pub iter_flags: npy_uint32,
335}
336
337pub type PyUFuncGenericFunction =
338 Option<unsafe extern "C" fn(*mut *mut c_char, *mut npy_intp, *mut npy_intp, *mut c_void)>;
339pub type PyUFunc_MaskedStridedInnerLoopFunc = Option<
340 unsafe extern "C" fn(
341 *mut *mut c_char,
342 *mut npy_intp,
343 *mut c_char,
344 npy_intp,
345 npy_intp,
346 *mut NpyAuxData,
347 ),
348>;
349pub type PyUFunc_TypeResolutionFunc = Option<
350 unsafe extern "C" fn(
351 *mut PyUFuncObject,
352 NPY_CASTING,
353 *mut *mut PyArrayObject,
354 *mut PyObject,
355 *mut *mut PyArray_Descr,
356 ) -> c_int,
357>;
358
359#[repr(C)]
360#[derive(Debug, Copy, Clone)]
361pub struct NpyIter([u8; 0]);
362
363#[repr(C)]
364pub struct PyArrayIterObject {
365 pub ob_base: PyObject,
366 pub nd_m1: c_int,
367 pub index: npy_intp,
368 pub size: npy_intp,
369 pub coordinates: [npy_intp; NPY_MAXDIMS_LEGACY_ITERS],
370 pub dims_m1: [npy_intp; NPY_MAXDIMS_LEGACY_ITERS],
371 pub strides: [npy_intp; NPY_MAXDIMS_LEGACY_ITERS],
372 pub backstrides: [npy_intp; NPY_MAXDIMS_LEGACY_ITERS],
373 pub factors: [npy_intp; NPY_MAXDIMS_LEGACY_ITERS],
374 pub ao: *mut PyArrayObject,
375 pub dataptr: *mut c_char,
376 pub contiguous: npy_bool,
377 pub bounds: [[npy_intp; 2usize]; NPY_MAXDIMS_LEGACY_ITERS],
378 pub limits: [[npy_intp; 2usize]; NPY_MAXDIMS_LEGACY_ITERS],
379 pub limits_sizes: [npy_intp; NPY_MAXDIMS_LEGACY_ITERS],
380 pub translate: npy_iter_get_dataptr_t,
381}
382
383#[repr(C)]
384pub struct PyArrayMultiIterObject {
385 pub ob_base: PyObject,
386 pub numiter: c_int,
387 pub size: npy_intp,
388 pub index: npy_intp,
389 pub nd: c_int,
390 pub dimensions: [npy_intp; NPY_MAXDIMS_LEGACY_ITERS],
391 pub iters: [*mut PyArrayIterObject; 32usize],
392}
393
394#[repr(C)]
395pub struct PyArrayNeighborhoodIterObject {
396 pub ob_base: PyObject,
397 pub nd_m1: c_int,
398 pub index: npy_intp,
399 pub size: npy_intp,
400 pub coordinates: [npy_intp; NPY_MAXDIMS_LEGACY_ITERS],
401 pub dims_m1: [npy_intp; NPY_MAXDIMS_LEGACY_ITERS],
402 pub strides: [npy_intp; NPY_MAXDIMS_LEGACY_ITERS],
403 pub backstrides: [npy_intp; NPY_MAXDIMS_LEGACY_ITERS],
404 pub factors: [npy_intp; NPY_MAXDIMS_LEGACY_ITERS],
405 pub ao: *mut PyArrayObject,
406 pub dataptr: *mut c_char,
407 pub contiguous: npy_bool,
408 pub bounds: [[npy_intp; 2usize]; NPY_MAXDIMS_LEGACY_ITERS],
409 pub limits: [[npy_intp; 2usize]; NPY_MAXDIMS_LEGACY_ITERS],
410 pub limits_sizes: [npy_intp; NPY_MAXDIMS_LEGACY_ITERS],
411 pub translate: npy_iter_get_dataptr_t,
412 pub nd: npy_intp,
413 pub dimensions: [npy_intp; NPY_MAXDIMS_LEGACY_ITERS],
414 pub _internal_iter: *mut PyArrayIterObject,
415 pub constant: *mut c_char,
416 pub mode: c_int,
417}
418
419pub type NpyIter_IterNextFunc = Option<unsafe extern "C" fn(*mut NpyIter) -> c_int>;
420pub type NpyIter_GetMultiIndexFunc = Option<unsafe extern "C" fn(*mut NpyIter, *mut npy_intp)>;
421pub type PyDataMem_EventHookFunc =
422 Option<unsafe extern "C" fn(*mut c_void, *mut c_void, usize, *mut c_void)>;
423pub type npy_iter_get_dataptr_t =
424 Option<unsafe extern "C" fn(*mut PyArrayIterObject, *mut npy_intp) -> *mut c_char>;
425
426#[repr(C)]
427#[derive(Copy, Clone)]
428pub struct NpyAuxData {
429 pub free: NpyAuxData_FreeFunc,
430 pub clone: NpyAuxData_CloneFunc,
431 pub reserved: [*mut c_void; 2usize],
432}
433
434pub type NpyAuxData_FreeFunc = Option<unsafe extern "C" fn(*mut NpyAuxData)>;
435pub type NpyAuxData_CloneFunc = Option<unsafe extern "C" fn(*mut NpyAuxData) -> *mut NpyAuxData>;
436
437#[repr(C)]
438#[derive(Clone, Copy)]
439pub struct PyArray_DatetimeMetaData {
440 pub base: NPY_DATETIMEUNIT,
441 pub num: c_int,
442}
443
444#[repr(C)]
445#[derive(Clone, Copy)]
446pub struct PyArray_DatetimeDTypeMetaData {
447 pub base: NpyAuxData,
448 pub meta: PyArray_DatetimeMetaData,
449}
450
451#[repr(C)]
455pub struct npy_packed_static_string([u8; 0]);
456
457#[repr(C)]
458pub struct npy_string_allocator([u8; 0]);
459
460#[cfg(not(Py_LIMITED_API))]
461#[repr(C)]
462pub struct PyArray_DTypeMeta {
463 pub superclass: PyHeapTypeObject,
464 pub singleton: *mut PyArray_Descr,
465 pub type_num: c_int,
466 pub scalar_type: *mut PyTypeObject,
467 pub flags: npy_uint64,
468 pub dt_slots: *mut c_void,
469 pub reserved: [*mut c_void; 3],
470}
471
472#[cfg(Py_LIMITED_API)]
473pub type PyArray_DTypeMeta = PyTypeObject;
474
475#[repr(C)]
476#[derive(Clone, Copy)]
477pub struct npy_static_string {
478 pub size: usize,
479 pub buf: *const c_char,
480}
481
482#[repr(C)]
483pub struct PyArray_StringDTypeObject {
484 pub base: PyArray_Descr,
485 pub na_object: *mut PyObject,
486 pub coerce: c_char,
487 pub has_nan_na: c_char,
488 pub has_string_na: c_char,
489 pub array_owned: c_char,
490 pub default_string: npy_static_string,
491 pub na_name: npy_static_string,
492 pub allocator: *mut npy_string_allocator,
493}
494
495#[repr(C)]
496#[derive(Clone, Copy)]
497pub struct PyArrayMethod_Spec {
498 pub name: *const c_char,
499 pub nin: c_int,
500 pub nout: c_int,
501 pub casting: NPY_CASTING,
502 pub flags: NPY_ARRAYMETHOD_FLAGS,
503 pub dtypes: *mut *mut PyArray_DTypeMeta,
504 pub slots: *mut PyType_Slot,
505}
506
507#[repr(C)]
508#[derive(Clone, Copy)]
509pub struct PyArrayDTypeMeta_Spec {
510 pub typeobj: *mut PyTypeObject,
511 pub flags: c_int,
512 pub casts: *mut *mut PyArrayMethod_Spec,
513 pub slots: *mut PyType_Slot,
514 pub baseclass: *mut PyTypeObject,
515}