5 #ifndef __eigenpy_eigen_from_python_hpp__
6 #define __eigenpy_eigen_from_python_hpp__
15 template <
typename EigenType,
19 template <
typename MatType>
33 template <
typename Scalar,
int Rows,
int Cols,
int Options,
int MaxRows,
35 struct expected_pytype_for_arg<
36 Eigen::Matrix<Scalar, Rows, Cols, Options, MaxRows, MaxCols> >
38 Eigen::Matrix<Scalar, Rows, Cols, Options, MaxRows, MaxCols> > {};
48 static void run(
const Eigen::MatrixBase<MatType> &input,
49 PyArrayObject *pyArray) {
54 template <
typename MatType>
56 static void run(
const Eigen::MatrixBase<MatType> & ,
60 #if EIGEN_VERSION_AT_LEAST(3, 2, 0)
62 template <
typename _RefType>
63 struct referent_storage_eigen_ref {
64 typedef _RefType RefType;
66 typedef typename ::eigenpy::aligned_storage<
70 referent_storage_eigen_ref()
73 ref_ptr(reinterpret_cast<RefType *>(ref_storage.bytes)) {}
75 referent_storage_eigen_ref(
const RefType &
ref, PyArrayObject *pyArray,
76 PlainObjectType *plain_ptr = NULL)
79 ref_ptr(reinterpret_cast<RefType *>(ref_storage.bytes)) {
81 new (ref_storage.bytes) RefType(
ref);
84 ~referent_storage_eigen_ref() {
85 if (plain_ptr != NULL && PyArray_ISWRITEABLE(pyArray))
90 if (plain_ptr != NULL) plain_ptr->~PlainObjectType();
95 AlignedStorage ref_storage;
96 PyArrayObject *pyArray;
97 PlainObjectType *plain_ptr;
108 #if EIGEN_VERSION_AT_LEAST(3, 2, 0)
109 template <
typename MatType,
int Options,
typename Str
ide>
110 struct referent_storage<
Eigen::Ref<MatType, Options, Stride> &> {
111 typedef Eigen::Ref<MatType, Options, Stride> RefType;
112 typedef ::eigenpy::details::referent_storage_eigen_ref<RefType> StorageType;
113 typedef typename ::eigenpy::aligned_storage<
117 template <
typename MatType,
int Options,
typename Str
ide>
118 struct referent_storage<const
Eigen::Ref<const MatType, Options, Stride> &> {
119 typedef Eigen::Ref<const MatType, Options, Stride> RefType;
120 typedef ::eigenpy::details::referent_storage_eigen_ref<RefType> StorageType;
121 typedef typename ::eigenpy::aligned_storage<
131 namespace converter {
133 #define EIGENPY_RVALUE_FROM_PYTHON_DATA_INIT(type) \
134 typedef ::eigenpy::rvalue_from_python_data<type> Base; \
136 rvalue_from_python_data(rvalue_from_python_stage1_data const &_stage1) \
139 rvalue_from_python_data(void *convertible) : Base(convertible){};
141 template <
typename Scalar,
int Rows,
int Cols,
int Options,
int MaxRows,
143 struct rvalue_from_python_data<
144 Eigen::Matrix<Scalar, Rows, Cols, Options, MaxRows, MaxCols> const &>
146 Scalar, Rows, Cols, Options, MaxRows, MaxCols> const &> {
147 typedef Eigen::Matrix<Scalar, Rows, Cols, Options, MaxRows, MaxCols>
T;
151 template <
typename Derived>
152 struct rvalue_from_python_data<
Eigen::MatrixBase<Derived> const &>
157 template <
typename Derived>
158 struct rvalue_from_python_data<
Eigen::EigenBase<Derived> const &>
163 template <
typename Derived>
164 struct rvalue_from_python_data<
Eigen::PlainObjectBase<Derived> const &>
169 template <
typename MatType,
int Options,
typename Str
ide>
170 struct rvalue_from_python_data<
Eigen::Ref<MatType, Options, Stride> &>
171 : rvalue_from_python_storage<Eigen::Ref<MatType, Options, Stride> &> {
172 typedef Eigen::Ref<MatType, Options, Stride>
RefType;
174 #if (!defined(__MWERKS__) || __MWERKS__ >= 0x3000) && \
175 (!defined(__EDG_VERSION__) || __EDG_VERSION__ >= 245) && \
176 (!defined(__DECCXX_VER) || __DECCXX_VER > 60590014) && \
177 !defined(BOOST_PYTHON_SYNOPSIS)
180 BOOST_STATIC_ASSERT(BOOST_PYTHON_OFFSETOF(rvalue_from_python_storage<RefType>,
186 this->stage1 = _stage1;
193 this->stage1.convertible = convertible;
198 typedef ::eigenpy::details::referent_storage_eigen_ref<RefType> StorageType;
199 if (this->stage1.convertible == this->storage.bytes)
200 static_cast<StorageType *
>((
void *)this->storage.bytes)->~StorageType();
204 template <
typename MatType,
int Options,
typename Str
ide>
205 struct rvalue_from_python_data<
206 const
Eigen::Ref<const MatType, Options, Stride> &>
207 : rvalue_from_python_storage<
208 const Eigen::Ref<const MatType, Options, Stride> &> {
209 typedef Eigen::Ref<const MatType, Options, Stride>
RefType;
211 #if (!defined(__MWERKS__) || __MWERKS__ >= 0x3000) && \
212 (!defined(__EDG_VERSION__) || __EDG_VERSION__ >= 245) && \
213 (!defined(__DECCXX_VER) || __DECCXX_VER > 60590014) && \
214 !defined(BOOST_PYTHON_SYNOPSIS)
217 BOOST_STATIC_ASSERT(BOOST_PYTHON_OFFSETOF(rvalue_from_python_storage<RefType>,
223 this->stage1 = _stage1;
230 this->stage1.convertible = convertible;
235 typedef ::eigenpy::details::referent_storage_eigen_ref<RefType> StorageType;
236 if (this->stage1.convertible == this->storage.bytes)
237 static_cast<StorageType *
>((
void *)this->storage.bytes)->~StorageType();
247 template <
typename MatOrRefType>
249 PyObject *pyObj, bp::converter::rvalue_from_python_stage1_data *memory) {
250 PyArrayObject *pyArray =
reinterpret_cast<PyArrayObject *
>(pyObj);
251 assert((PyArray_DIMS(pyArray)[0] < INT_MAX) &&
252 (PyArray_DIMS(pyArray)[1] < INT_MAX));
254 bp::converter::rvalue_from_python_storage<MatOrRefType> *storage =
256 bp::converter::rvalue_from_python_storage<MatOrRefType> *
>(
257 reinterpret_cast<void *
>(memory));
261 memory->convertible = storage->storage.bytes;
264 template <
typename EigenType,
267 typedef typename EigenType::Scalar
Scalar;
274 bp::converter::rvalue_from_python_stage1_data *memory);
279 template <
typename MatType>
288 bp::converter::rvalue_from_python_stage1_data *memory);
293 template <
typename EigenType,
295 typename boost::remove_reference<EigenType>::type::Scalar>
298 template <
typename MatType>
303 PyArrayObject *pyArray =
reinterpret_cast<PyArrayObject *
>(pyObj);
305 if (!np_type_is_convertible_into_scalar<Scalar>(
309 if (MatType::IsVectorAtCompileTime) {
310 const Eigen::DenseIndex size_at_compile_time =
311 MatType::IsRowMajor ? MatType::ColsAtCompileTime
312 : MatType::RowsAtCompileTime;
314 switch (PyArray_NDIM(pyArray)) {
318 if (size_at_compile_time != Eigen::Dynamic) {
320 if (PyArray_DIMS(pyArray)[0] == size_at_compile_time)
329 if (PyArray_DIMS(pyArray)[0] == 1 && PyArray_DIMS(pyArray)[1] == 1) {
330 if (size_at_compile_time != Eigen::Dynamic) {
331 if (size_at_compile_time == 1)
339 if (PyArray_DIMS(pyArray)[0] > 1 && PyArray_DIMS(pyArray)[1] > 1) {
343 if (((PyArray_DIMS(pyArray)[0] == 1) &&
344 (MatType::ColsAtCompileTime == 1)) ||
345 ((PyArray_DIMS(pyArray)[1] == 1) &&
346 (MatType::RowsAtCompileTime == 1))) {
350 if (size_at_compile_time !=
352 const Eigen::DenseIndex pyArray_size =
353 PyArray_DIMS(pyArray)[0] > PyArray_DIMS(pyArray)[1]
354 ? PyArray_DIMS(pyArray)[0]
355 : PyArray_DIMS(pyArray)[1];
356 if (size_at_compile_time != pyArray_size)
return 0;
365 if (PyArray_NDIM(pyArray) ==
371 if (PyArray_NDIM(pyArray) != 2) {
375 if (PyArray_NDIM(pyArray) == 2) {
376 const int R = (int)PyArray_DIMS(pyArray)[0];
377 const int C = (int)PyArray_DIMS(pyArray)[1];
379 if ((MatType::RowsAtCompileTime !=
R) &&
380 (MatType::RowsAtCompileTime != Eigen::Dynamic))
382 if ((MatType::ColsAtCompileTime != C) &&
383 (MatType::ColsAtCompileTime != Eigen::Dynamic))
388 #ifdef NPY_1_8_API_VERSION
389 if (!(PyArray_FLAGS(pyArray)))
391 if (!(PyArray_FLAGS(pyArray) & NPY_ALIGNED))
400 template <
typename MatType>
402 PyObject *pyObj, bp::converter::rvalue_from_python_stage1_data *memory) {
403 eigen_from_py_construct<MatType>(pyObj, memory);
406 template <
typename MatType>
408 bp::converter::registry::push_back(
411 #ifndef BOOST_PYTHON_NO_PY_SIGNATURES
418 template <
typename EigenType,
422 template <
typename EigenType>
425 template <
typename MatType>
431 typedef Eigen::MatrixBase<MatType> MatrixBase;
435 typedef Eigen::EigenBase<MatType> EigenBase;
439 typedef Eigen::PlainObjectBase<MatType> PlainObjectBase;
442 #if EIGEN_VERSION_AT_LEAST(3, 2, 0)
444 typedef Eigen::Ref<MatType> RefType;
448 typedef const Eigen::Ref<const MatType> ConstRefType;
454 template <
typename MatType>
457 typedef Eigen::MatrixBase<MatType>
Base;
460 bp::converter::registry::push_back(
463 #ifndef BOOST_PYTHON_NO_PY_SIGNATURES
471 template <
typename MatType>
475 typedef Eigen::EigenBase<MatType>
Base;
478 bp::converter::registry::push_back(
481 #ifndef BOOST_PYTHON_NO_PY_SIGNATURES
489 template <
typename MatType>
492 typedef Eigen::PlainObjectBase<MatType>
Base;
495 bp::converter::registry::push_back(
498 #ifndef BOOST_PYTHON_NO_PY_SIGNATURES
506 #if EIGEN_VERSION_AT_LEAST(3, 2, 0)
508 template <
typename MatType,
int Options,
typename Str
ide>
509 struct EigenFromPy<
Eigen::Ref<MatType, Options, Stride> > {
510 typedef Eigen::Ref<MatType, Options, Stride> RefType;
511 typedef typename MatType::Scalar
Scalar;
516 PyArrayObject *pyArray =
reinterpret_cast<PyArrayObject *
>(pyObj);
517 if (!PyArray_ISWRITEABLE(pyArray))
return 0;
522 bp::converter::registry::push_back(
524 &eigen_from_py_construct<RefType>, bp::type_id<RefType>()
525 #ifndef BOOST_PYTHON_NO_PY_SIGNATURES
533 template <
typename MatType,
int Options,
typename Str
ide>
534 struct EigenFromPy<const
Eigen::Ref<const MatType, Options, Stride> > {
535 typedef const Eigen::Ref<const MatType, Options, Stride> ConstRefType;
536 typedef typename MatType::Scalar
Scalar;
544 bp::converter::registry::push_back(
546 &eigen_from_py_construct<ConstRefType>, bp::type_id<ConstRefType>()
547 #ifndef BOOST_PYTHON_NO_PY_SIGNATURES
558 #ifdef EIGENPY_WITH_TENSOR_SUPPORT
564 #endif // __eigenpy_eigen_from_python_hpp__