Merge pull request #335 from aldanor/bugfix/is_pod_struct

Decay types before passing to is_pod_struct<> / npy_format_descriptor<>
This commit is contained in:
Wenzel Jakob 2016-08-15 20:12:06 +02:00 committed by GitHub
commit 94f2052d08
2 changed files with 28 additions and 84 deletions

View File

@ -85,7 +85,7 @@ struct type_caster<Type, typename std::enable_if<is_eigen_dense<Type>::value &&
if (!buffer.check())
return false;
buffer_info info = buffer.request();
auto info = buffer.request();
if (info.ndim == 1) {
typedef Eigen::InnerStride<> Strides;
if (!isVector &&
@ -127,37 +127,19 @@ struct type_caster<Type, typename std::enable_if<is_eigen_dense<Type>::value &&
static handle cast(const Type &src, return_value_policy /* policy */, handle /* parent */) {
if (isVector) {
return array(buffer_info(
/* Pointer to buffer */
const_cast<Scalar *>(src.data()),
/* Size of one scalar */
sizeof(Scalar),
/* Python struct-style format descriptor */
format_descriptor<Scalar>::format(),
/* Number of dimensions */
1,
/* Buffer dimensions */
{ (size_t) src.size() },
/* Strides (in bytes) for each index */
{ sizeof(Scalar) * static_cast<size_t>(src.innerStride()) }
)).release();
return array(
{ (size_t) src.size() }, // shape
{ sizeof(Scalar) * static_cast<size_t>(src.innerStride()) }, // strides
src.data() // data
).release();
} else {
return array(buffer_info(
/* Pointer to buffer */
const_cast<Scalar *>(src.data()),
/* Size of one scalar */
sizeof(Scalar),
/* Python struct-style format descriptor */
format_descriptor<Scalar>::format(),
/* Number of dimensions */
isVector ? 1 : 2,
/* Buffer dimensions */
{ (size_t) src.rows(),
return array(
{ (size_t) src.rows(), // shape
(size_t) src.cols() },
/* Strides (in bytes) for each index */
{ sizeof(Scalar) * static_cast<size_t>(src.rowStride()),
sizeof(Scalar) * static_cast<size_t>(src.colStride()) }
)).release();
{ sizeof(Scalar) * static_cast<size_t>(src.rowStride()), // strides
sizeof(Scalar) * static_cast<size_t>(src.colStride()) },
src.data() // data
).release();
}
}
@ -248,9 +230,9 @@ struct type_caster<Type, typename std::enable_if<is_eigen_sparse<Type>::value>::
!outerIndicesArray.check())
return false;
buffer_info outerIndices = outerIndicesArray.request();
buffer_info innerIndices = innerIndicesArray.request();
buffer_info values = valuesArray.request();
auto outerIndices = outerIndicesArray.request();
auto innerIndices = innerIndicesArray.request();
auto values = valuesArray.request();
value = Eigen::MappedSparseMatrix<Scalar, Type::Flags, StorageIndex>(
shape[0].cast<Index>(),
@ -270,50 +252,9 @@ struct type_caster<Type, typename std::enable_if<is_eigen_sparse<Type>::value>::
object matrix_type = module::import("scipy.sparse").attr(
rowMajor ? "csr_matrix" : "csc_matrix");
array data(buffer_info(
// Pointer to buffer
const_cast<Scalar *>(src.valuePtr()),
// Size of one scalar
sizeof(Scalar),
// Python struct-style format descriptor
format_descriptor<Scalar>::format(),
// Number of dimensions
1,
// Buffer dimensions
{ (size_t) src.nonZeros() },
// Strides
{ sizeof(Scalar) }
));
array outerIndices(buffer_info(
// Pointer to buffer
const_cast<StorageIndex *>(src.outerIndexPtr()),
// Size of one scalar
sizeof(StorageIndex),
// Python struct-style format descriptor
format_descriptor<StorageIndex>::format(),
// Number of dimensions
1,
// Buffer dimensions
{ (size_t) (rowMajor ? src.rows() : src.cols()) + 1 },
// Strides
{ sizeof(StorageIndex) }
));
array innerIndices(buffer_info(
// Pointer to buffer
const_cast<StorageIndex *>(src.innerIndexPtr()),
// Size of one scalar
sizeof(StorageIndex),
// Python struct-style format descriptor
format_descriptor<StorageIndex>::format(),
// Number of dimensions
1,
// Buffer dimensions
{ (size_t) src.nonZeros() },
// Strides
{ sizeof(StorageIndex) }
));
array data((size_t) src.nonZeros(), src.valuePtr());
array outerIndices((size_t) (rowMajor ? src.rows() : src.cols()) + 1, src.outerIndexPtr());
array innerIndices((size_t) src.nonZeros(), src.innerIndexPtr());
return matrix_type(
std::make_tuple(data, innerIndices, outerIndices),

View File

@ -146,7 +146,7 @@ public:
}
template <typename T> static dtype of() {
return detail::npy_format_descriptor<T>::dtype();
return detail::npy_format_descriptor<typename std::remove_cv<T>::type>::dtype();
}
size_t itemsize() const {
@ -304,7 +304,9 @@ public:
template <typename T>
struct format_descriptor<T, typename std::enable_if<detail::is_pod_struct<T>::value>::type> {
static std::string format() { return detail::npy_format_descriptor<T>::format(); }
static std::string format() {
return detail::npy_format_descriptor<typename std::remove_cv<T>::type>::format();
}
};
template <size_t N> struct format_descriptor<char[N]> {
@ -321,14 +323,15 @@ template <typename T, size_t N> struct is_std_array<std::array<T, N>> : std::tru
template <typename T>
struct is_pod_struct {
enum { value = std::is_pod<T>::value && // offsetof only works correctly for POD types
!std::is_reference<T>::value &&
!std::is_array<T>::value &&
!is_std_array<T>::value &&
!std::is_integral<T>::value &&
!std::is_same<T, float>::value &&
!std::is_same<T, double>::value &&
!std::is_same<T, bool>::value &&
!std::is_same<T, std::complex<float>>::value &&
!std::is_same<T, std::complex<double>>::value };
!std::is_same<typename std::remove_cv<T>::type, float>::value &&
!std::is_same<typename std::remove_cv<T>::type, double>::value &&
!std::is_same<typename std::remove_cv<T>::type, bool>::value &&
!std::is_same<typename std::remove_cv<T>::type, std::complex<float>>::value &&
!std::is_same<typename std::remove_cv<T>::type, std::complex<double>>::value };
};
template <typename T> struct npy_format_descriptor<T, typename std::enable_if<std::is_integral<T>::value>::type> {