|
|
@ -212,6 +212,7 @@ constexpr int platform_lookup(int I, Ints... Is) { |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
struct npy_api { |
|
|
|
struct npy_api { |
|
|
|
|
|
|
|
// If you change this code, please review `normalized_dtype_num` below.
|
|
|
|
enum constants { |
|
|
|
enum constants { |
|
|
|
NPY_ARRAY_C_CONTIGUOUS_ = 0x0001, |
|
|
|
NPY_ARRAY_C_CONTIGUOUS_ = 0x0001, |
|
|
|
NPY_ARRAY_F_CONTIGUOUS_ = 0x0002, |
|
|
|
NPY_ARRAY_F_CONTIGUOUS_ = 0x0002, |
|
|
@ -384,6 +385,74 @@ private: |
|
|
|
} |
|
|
|
} |
|
|
|
}; |
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// This table normalizes typenums by mapping NPY_INT_, NPY_LONG, ... to NPY_INT32_, NPY_INT64, ...
|
|
|
|
|
|
|
|
// This is needed to correctly handle situations where multiple typenums map to the same type,
|
|
|
|
|
|
|
|
// e.g. NPY_LONG_ may be equivalent to NPY_INT_ or NPY_LONGLONG_ despite having a different
|
|
|
|
|
|
|
|
// typenum. The normalized typenum should always match the values used in npy_format_descriptor.
|
|
|
|
|
|
|
|
// If you change this code, please review `enum constants` above.
|
|
|
|
|
|
|
|
static constexpr int normalized_dtype_num[npy_api::NPY_VOID_ + 1] = { |
|
|
|
|
|
|
|
// NPY_BOOL_ =>
|
|
|
|
|
|
|
|
npy_api::NPY_BOOL_, |
|
|
|
|
|
|
|
// NPY_BYTE_ =>
|
|
|
|
|
|
|
|
npy_api::NPY_BYTE_, |
|
|
|
|
|
|
|
// NPY_UBYTE_ =>
|
|
|
|
|
|
|
|
npy_api::NPY_UBYTE_, |
|
|
|
|
|
|
|
// NPY_SHORT_ =>
|
|
|
|
|
|
|
|
npy_api::NPY_INT16_, |
|
|
|
|
|
|
|
// NPY_USHORT_ =>
|
|
|
|
|
|
|
|
npy_api::NPY_UINT16_, |
|
|
|
|
|
|
|
// NPY_INT_ =>
|
|
|
|
|
|
|
|
sizeof(int) == sizeof(std::int16_t) ? npy_api::NPY_INT16_ |
|
|
|
|
|
|
|
: sizeof(int) == sizeof(std::int32_t) ? npy_api::NPY_INT32_ |
|
|
|
|
|
|
|
: sizeof(int) == sizeof(std::int64_t) ? npy_api::NPY_INT64_ |
|
|
|
|
|
|
|
: npy_api::NPY_INT_, |
|
|
|
|
|
|
|
// NPY_UINT_ =>
|
|
|
|
|
|
|
|
sizeof(unsigned int) == sizeof(std::uint16_t) ? npy_api::NPY_UINT16_ |
|
|
|
|
|
|
|
: sizeof(unsigned int) == sizeof(std::uint32_t) ? npy_api::NPY_UINT32_ |
|
|
|
|
|
|
|
: sizeof(unsigned int) == sizeof(std::uint64_t) ? npy_api::NPY_UINT64_ |
|
|
|
|
|
|
|
: npy_api::NPY_UINT_, |
|
|
|
|
|
|
|
// NPY_LONG_ =>
|
|
|
|
|
|
|
|
sizeof(long) == sizeof(std::int16_t) ? npy_api::NPY_INT16_ |
|
|
|
|
|
|
|
: sizeof(long) == sizeof(std::int32_t) ? npy_api::NPY_INT32_ |
|
|
|
|
|
|
|
: sizeof(long) == sizeof(std::int64_t) ? npy_api::NPY_INT64_ |
|
|
|
|
|
|
|
: npy_api::NPY_LONG_, |
|
|
|
|
|
|
|
// NPY_ULONG_ =>
|
|
|
|
|
|
|
|
sizeof(unsigned long) == sizeof(std::uint16_t) ? npy_api::NPY_UINT16_ |
|
|
|
|
|
|
|
: sizeof(unsigned long) == sizeof(std::uint32_t) ? npy_api::NPY_UINT32_ |
|
|
|
|
|
|
|
: sizeof(unsigned long) == sizeof(std::uint64_t) ? npy_api::NPY_UINT64_ |
|
|
|
|
|
|
|
: npy_api::NPY_ULONG_, |
|
|
|
|
|
|
|
// NPY_LONGLONG_ =>
|
|
|
|
|
|
|
|
sizeof(long long) == sizeof(std::int16_t) ? npy_api::NPY_INT16_ |
|
|
|
|
|
|
|
: sizeof(long long) == sizeof(std::int32_t) ? npy_api::NPY_INT32_ |
|
|
|
|
|
|
|
: sizeof(long long) == sizeof(std::int64_t) ? npy_api::NPY_INT64_ |
|
|
|
|
|
|
|
: npy_api::NPY_LONGLONG_, |
|
|
|
|
|
|
|
// NPY_ULONGLONG_ =>
|
|
|
|
|
|
|
|
sizeof(unsigned long long) == sizeof(std::uint16_t) ? npy_api::NPY_UINT16_ |
|
|
|
|
|
|
|
: sizeof(unsigned long long) == sizeof(std::uint32_t) ? npy_api::NPY_UINT32_ |
|
|
|
|
|
|
|
: sizeof(unsigned long long) == sizeof(std::uint64_t) ? npy_api::NPY_UINT64_ |
|
|
|
|
|
|
|
: npy_api::NPY_ULONGLONG_, |
|
|
|
|
|
|
|
// NPY_FLOAT_ =>
|
|
|
|
|
|
|
|
npy_api::NPY_FLOAT_, |
|
|
|
|
|
|
|
// NPY_DOUBLE_ =>
|
|
|
|
|
|
|
|
npy_api::NPY_DOUBLE_, |
|
|
|
|
|
|
|
// NPY_LONGDOUBLE_ =>
|
|
|
|
|
|
|
|
npy_api::NPY_LONGDOUBLE_, |
|
|
|
|
|
|
|
// NPY_CFLOAT_ =>
|
|
|
|
|
|
|
|
npy_api::NPY_CFLOAT_, |
|
|
|
|
|
|
|
// NPY_CDOUBLE_ =>
|
|
|
|
|
|
|
|
npy_api::NPY_CDOUBLE_, |
|
|
|
|
|
|
|
// NPY_CLONGDOUBLE_ =>
|
|
|
|
|
|
|
|
npy_api::NPY_CLONGDOUBLE_, |
|
|
|
|
|
|
|
// NPY_OBJECT_ =>
|
|
|
|
|
|
|
|
npy_api::NPY_OBJECT_, |
|
|
|
|
|
|
|
// NPY_STRING_ =>
|
|
|
|
|
|
|
|
npy_api::NPY_STRING_, |
|
|
|
|
|
|
|
// NPY_UNICODE_ =>
|
|
|
|
|
|
|
|
npy_api::NPY_UNICODE_, |
|
|
|
|
|
|
|
// NPY_VOID_ =>
|
|
|
|
|
|
|
|
npy_api::NPY_VOID_, |
|
|
|
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
inline PyArray_Proxy *array_proxy(void *ptr) { return reinterpret_cast<PyArray_Proxy *>(ptr); } |
|
|
|
inline PyArray_Proxy *array_proxy(void *ptr) { return reinterpret_cast<PyArray_Proxy *>(ptr); } |
|
|
|
|
|
|
|
|
|
|
|
inline const PyArray_Proxy *array_proxy(const void *ptr) { |
|
|
|
inline const PyArray_Proxy *array_proxy(const void *ptr) { |
|
|
@ -684,6 +753,13 @@ public: |
|
|
|
return detail::npy_format_descriptor<typename std::remove_cv<T>::type>::dtype(); |
|
|
|
return detail::npy_format_descriptor<typename std::remove_cv<T>::type>::dtype(); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/// Return the type number associated with a C++ type.
|
|
|
|
|
|
|
|
/// This is the constexpr equivalent of `dtype::of<T>().num()`.
|
|
|
|
|
|
|
|
template <typename T> |
|
|
|
|
|
|
|
static constexpr int num_of() { |
|
|
|
|
|
|
|
return detail::npy_format_descriptor<typename std::remove_cv<T>::type>::value; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/// Size of the data type in bytes.
|
|
|
|
/// Size of the data type in bytes.
|
|
|
|
#ifdef PYBIND11_NUMPY_1_ONLY |
|
|
|
#ifdef PYBIND11_NUMPY_1_ONLY |
|
|
|
ssize_t itemsize() const { return detail::array_descriptor_proxy(m_ptr)->elsize; } |
|
|
|
ssize_t itemsize() const { return detail::array_descriptor_proxy(m_ptr)->elsize; } |
|
|
@ -725,7 +801,9 @@ public: |
|
|
|
return detail::array_descriptor_proxy(m_ptr)->type; |
|
|
|
return detail::array_descriptor_proxy(m_ptr)->type; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/// type number of dtype.
|
|
|
|
/// Type number of dtype. Note that different values may be returned for equivalent types,
|
|
|
|
|
|
|
|
/// e.g. even though ``long`` may be equivalent to ``int`` or ``long long``, they still have
|
|
|
|
|
|
|
|
/// different type numbers. Consider using `normalized_num` to avoid this.
|
|
|
|
int num() const { |
|
|
|
int num() const { |
|
|
|
// Note: The signature, `dtype::num` follows the naming of NumPy's public
|
|
|
|
// Note: The signature, `dtype::num` follows the naming of NumPy's public
|
|
|
|
// Python API (i.e., ``dtype.num``), rather than its internal
|
|
|
|
// Python API (i.e., ``dtype.num``), rather than its internal
|
|
|
@ -733,6 +811,17 @@ public: |
|
|
|
return detail::array_descriptor_proxy(m_ptr)->type_num; |
|
|
|
return detail::array_descriptor_proxy(m_ptr)->type_num; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/// Type number of dtype, normalized to match the return value of `num_of` for equivalent
|
|
|
|
|
|
|
|
/// types. This function can be used to write switch statements that correctly handle
|
|
|
|
|
|
|
|
/// equivalent types with different type numbers.
|
|
|
|
|
|
|
|
int normalized_num() const { |
|
|
|
|
|
|
|
int value = num(); |
|
|
|
|
|
|
|
if (value >= 0 && value <= detail::npy_api::NPY_VOID_) { |
|
|
|
|
|
|
|
return detail::normalized_dtype_num[value]; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
return value; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/// Single character for byteorder
|
|
|
|
/// Single character for byteorder
|
|
|
|
char byteorder() const { return detail::array_descriptor_proxy(m_ptr)->byteorder; } |
|
|
|
char byteorder() const { return detail::array_descriptor_proxy(m_ptr)->byteorder; } |
|
|
|
|
|
|
|
|
|
|
|