forked from Tencent/rapidjson
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
2 changed files
with
250 additions
and
9 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,249 @@ | ||
/* | ||
* This header file defines relevant features which: | ||
* - Require runtime inspection depending on the NumPy version. | ||
* - May be needed when compiling with an older version of NumPy to allow | ||
* a smooth transition. | ||
* | ||
* As such, it is shipped with NumPy 2.0, but designed to be vendored in full | ||
* or parts by downstream projects. | ||
* | ||
* It must be included after any other includes. `import_array()` must have | ||
* been called in the scope or version dependency will misbehave, even when | ||
* only `PyUFunc_` API is used. | ||
* | ||
* If required complicated defs (with inline functions) should be written as: | ||
* | ||
* #if NPY_FEATURE_VERSION >= NPY_2_0_API_VERSION | ||
* Simple definition when NumPy 2.0 API is guaranteed. | ||
* #else | ||
* static inline definition of a 1.x compatibility shim | ||
* #if NPY_ABI_VERSION < 0x02000000 | ||
* Make 1.x compatibility shim the public API (1.x only branch) | ||
* #else | ||
* Runtime dispatched version (1.x or 2.x) | ||
* #endif | ||
* #endif | ||
* | ||
* An internal build always passes NPY_FEATURE_VERSION >= NPY_2_0_API_VERSION | ||
*/ | ||
|
||
#ifndef NUMPY_CORE_INCLUDE_NUMPY_NPY_2_COMPAT_H_ | ||
#define NUMPY_CORE_INCLUDE_NUMPY_NPY_2_COMPAT_H_ | ||
|
||
/* | ||
* New macros for accessing real and complex part of a complex number can be | ||
* found in "npy_2_complexcompat.h". | ||
*/ | ||
|
||
|
||
/* | ||
* This header is meant to be included by downstream directly for 1.x compat. | ||
* In that case we need to ensure that users first included the full headers | ||
* and not just `ndarraytypes.h`. | ||
*/ | ||
|
||
#ifndef NPY_FEATURE_VERSION | ||
#error "The NumPy 2 compat header requires `import_array()` for which " \ | ||
"the `ndarraytypes.h` header include is not sufficient. Please " \ | ||
"include it after `numpy/ndarrayobject.h` or similar.\n" \ | ||
"To simplify inclusion, you may use `PyArray_ImportNumPy()` " \ | ||
"which is defined in the compat header and is lightweight (can be)." | ||
#endif | ||
|
||
#if NPY_ABI_VERSION < 0x02000000 | ||
/* | ||
* Define 2.0 feature version as it is needed below to decide whether we | ||
* compile for both 1.x and 2.x (defining it gaurantees 1.x only). | ||
*/ | ||
#define NPY_2_0_API_VERSION 0x00000012 | ||
/* | ||
* If we are compiling with NumPy 1.x, PyArray_RUNTIME_VERSION so we | ||
* pretend the `PyArray_RUNTIME_VERSION` is `NPY_FEATURE_VERSION`. | ||
* This allows downstream to use `PyArray_RUNTIME_VERSION` if they need to. | ||
*/ | ||
#define PyArray_RUNTIME_VERSION NPY_FEATURE_VERSION | ||
/* Compiling on NumPy 1.x where these are the same: */ | ||
#define PyArray_DescrProto PyArray_Descr | ||
#endif | ||
|
||
|
||
/* | ||
* Define a better way to call `_import_array()` to simplify backporting as | ||
* we now require imports more often (necessary to make ABI flexible). | ||
*/ | ||
#ifdef import_array1 | ||
|
||
static inline int | ||
PyArray_ImportNumPyAPI() | ||
{ | ||
if (NPY_UNLIKELY(PyArray_API == NULL)) { | ||
import_array1(-1); | ||
} | ||
return 0; | ||
} | ||
|
||
#endif /* import_array1 */ | ||
|
||
|
||
/* | ||
* NPY_DEFAULT_INT | ||
* | ||
* The default integer has changed, `NPY_DEFAULT_INT` is available at runtime | ||
* for use as type number, e.g. `PyArray_DescrFromType(NPY_DEFAULT_INT)`. | ||
* | ||
* NPY_RAVEL_AXIS | ||
* | ||
* This was introduced in NumPy 2.0 to allow indicating that an axis should be | ||
* raveled in an operation. Before NumPy 2.0, NPY_MAXDIMS was used for this purpose. | ||
* | ||
* NPY_MAXDIMS | ||
* | ||
* A constant indicating the maximum number dimensions allowed when creating | ||
* an ndarray. | ||
* | ||
* NPY_NTYPES_LEGACY | ||
* | ||
* The number of built-in NumPy dtypes. | ||
*/ | ||
#if NPY_FEATURE_VERSION >= NPY_2_0_API_VERSION | ||
#define NPY_DEFAULT_INT NPY_INTP | ||
#define NPY_RAVEL_AXIS NPY_MIN_INT | ||
#define NPY_MAXARGS 64 | ||
|
||
#elif NPY_ABI_VERSION < 0x02000000 | ||
#define NPY_DEFAULT_INT NPY_LONG | ||
#define NPY_RAVEL_AXIS 32 | ||
#define NPY_MAXARGS 32 | ||
|
||
/* Aliases of 2.x names to 1.x only equivalent names */ | ||
#define NPY_NTYPES NPY_NTYPES_LEGACY | ||
#define PyArray_DescrProto PyArray_Descr | ||
#define _PyArray_LegacyDescr PyArray_Descr | ||
/* NumPy 2 definition always works, but add it for 1.x only */ | ||
#define PyDataType_ISLEGACY(dtype) (1) | ||
#else | ||
#define NPY_DEFAULT_INT \ | ||
(PyArray_RUNTIME_VERSION >= NPY_2_0_API_VERSION ? NPY_INTP : NPY_LONG) | ||
#define NPY_RAVEL_AXIS \ | ||
(PyArray_RUNTIME_VERSION >= NPY_2_0_API_VERSION ? -1 : 32) | ||
#define NPY_MAXARGS \ | ||
(PyArray_RUNTIME_VERSION >= NPY_2_0_API_VERSION ? 64 : 32) | ||
#endif | ||
|
||
|
||
/* | ||
* Access inline functions for descriptor fields. Except for the first | ||
* few fields, these needed to be moved (elsize, alignment) for | ||
* additional space. Or they are descriptor specific and are not generally | ||
* available anymore (metadata, c_metadata, subarray, names, fields). | ||
* | ||
* Most of these are defined via the `DESCR_ACCESSOR` macro helper. | ||
*/ | ||
#if NPY_FEATURE_VERSION >= NPY_2_0_API_VERSION || NPY_ABI_VERSION < 0x02000000 | ||
/* Compiling for 1.x or 2.x only, direct field access is OK: */ | ||
|
||
static inline void | ||
PyDataType_SET_ELSIZE(PyArray_Descr *dtype, npy_intp size) | ||
{ | ||
dtype->elsize = size; | ||
} | ||
|
||
static inline npy_uint64 | ||
PyDataType_FLAGS(const PyArray_Descr *dtype) | ||
{ | ||
#if NPY_FEATURE_VERSION >= NPY_2_0_API_VERSION | ||
return dtype->flags; | ||
#else | ||
return (unsigned char)dtype->flags; /* Need unsigned cast on 1.x */ | ||
#endif | ||
} | ||
|
||
#define DESCR_ACCESSOR(FIELD, field, type, legacy_only) \ | ||
static inline type \ | ||
PyDataType_##FIELD(const PyArray_Descr *dtype) { \ | ||
if (legacy_only && !PyDataType_ISLEGACY(dtype)) { \ | ||
return (type)0; \ | ||
} \ | ||
return ((_PyArray_LegacyDescr *)dtype)->field; \ | ||
} | ||
#else /* compiling for both 1.x and 2.x */ | ||
|
||
static inline void | ||
PyDataType_SET_ELSIZE(PyArray_Descr *dtype, npy_intp size) | ||
{ | ||
if (PyArray_RUNTIME_VERSION >= NPY_2_0_API_VERSION) { | ||
((_PyArray_DescrNumPy2 *)dtype)->elsize = size; | ||
} | ||
else { | ||
((PyArray_DescrProto *)dtype)->elsize = (int)size; | ||
} | ||
} | ||
|
||
static inline npy_uint64 | ||
PyDataType_FLAGS(const PyArray_Descr *dtype) | ||
{ | ||
if (PyArray_RUNTIME_VERSION >= NPY_2_0_API_VERSION) { | ||
return ((_PyArray_DescrNumPy2 *)dtype)->flags; | ||
} | ||
else { | ||
return (unsigned char)((PyArray_DescrProto *)dtype)->flags; | ||
} | ||
} | ||
|
||
/* Cast to LegacyDescr always fine but needed when `legacy_only` */ | ||
#define DESCR_ACCESSOR(FIELD, field, type, legacy_only) \ | ||
static inline type \ | ||
PyDataType_##FIELD(const PyArray_Descr *dtype) { \ | ||
if (legacy_only && !PyDataType_ISLEGACY(dtype)) { \ | ||
return (type)0; \ | ||
} \ | ||
if (PyArray_RUNTIME_VERSION >= NPY_2_0_API_VERSION) { \ | ||
return ((_PyArray_LegacyDescr *)dtype)->field; \ | ||
} \ | ||
else { \ | ||
return ((PyArray_DescrProto *)dtype)->field; \ | ||
} \ | ||
} | ||
#endif | ||
|
||
DESCR_ACCESSOR(ELSIZE, elsize, npy_intp, 0) | ||
DESCR_ACCESSOR(ALIGNMENT, alignment, npy_intp, 0) | ||
DESCR_ACCESSOR(METADATA, metadata, PyObject *, 1) | ||
DESCR_ACCESSOR(SUBARRAY, subarray, PyArray_ArrayDescr *, 1) | ||
DESCR_ACCESSOR(NAMES, names, PyObject *, 1) | ||
DESCR_ACCESSOR(FIELDS, fields, PyObject *, 1) | ||
DESCR_ACCESSOR(C_METADATA, c_metadata, NpyAuxData *, 1) | ||
|
||
#undef DESCR_ACCESSOR | ||
|
||
|
||
#if !(defined(NPY_INTERNAL_BUILD) && NPY_INTERNAL_BUILD) | ||
#if NPY_FEATURE_VERSION >= NPY_2_0_API_VERSION | ||
static inline PyArray_ArrFuncs * | ||
PyDataType_GetArrFuncs(const PyArray_Descr *descr) | ||
{ | ||
return _PyDataType_GetArrFuncs(descr); | ||
} | ||
#elif NPY_ABI_VERSION < 0x02000000 | ||
static inline PyArray_ArrFuncs * | ||
PyDataType_GetArrFuncs(const PyArray_Descr *descr) | ||
{ | ||
return descr->f; | ||
} | ||
#else | ||
static inline PyArray_ArrFuncs * | ||
PyDataType_GetArrFuncs(const PyArray_Descr *descr) | ||
{ | ||
if (PyArray_RUNTIME_VERSION >= NPY_2_0_API_VERSION) { | ||
return _PyDataType_GetArrFuncs(descr); | ||
} | ||
else { | ||
return ((PyArray_DescrProto *)descr)->f; | ||
} | ||
} | ||
#endif | ||
|
||
|
||
#endif /* not internal build */ | ||
|
||
#endif /* NUMPY_CORE_INCLUDE_NUMPY_NPY_2_COMPAT_H_ */ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters