5 #ifndef __eigenpy_eigen_from_python_hpp__ 6 #define __eigenpy_eigen_from_python_hpp__ 13 #include <boost/python/converter/rvalue_from_python_data.hpp> 22 static void run(
const Eigen::MatrixBase<MatType> & input,
23 PyArrayObject * pyArray)
29 template<
typename MatType>
32 static void run(
const Eigen::MatrixBase<MatType> & ,
37 #if EIGEN_VERSION_AT_LEAST(3,2,0) 38 template<
typename MatType,
int Options,
typename Str
ide>
struct referent_storage_eigen_ref;
40 template<
typename MatType,
int Options,
typename Str
ide>
41 struct referent_storage_eigen_ref
43 typedef Eigen::Ref<MatType,Options,Stride> RefType;
45 typedef ::boost::python::detail::aligned_storage<
49 referent_storage_eigen_ref()
52 , ref_ptr(reinterpret_cast<RefType*>(ref_storage.bytes))
56 referent_storage_eigen_ref(
const RefType & ref,
57 PyArrayObject * pyArray,
58 MatType * mat_ptr = NULL)
61 , ref_ptr(reinterpret_cast<RefType*>(ref_storage.bytes))
64 new (ref_storage.bytes) RefType(ref);
67 ~referent_storage_eigen_ref()
69 if(mat_ptr != NULL && PyArray_ISWRITEABLE(pyArray))
80 AlignedStorage ref_storage;
81 PyArrayObject * pyArray;
90 namespace boost {
namespace python {
namespace detail {
91 #if EIGEN_VERSION_AT_LEAST(3,2,0) 92 template<
typename MatType,
int Options,
typename Str
ide>
93 struct referent_storage<Eigen::Ref<MatType,Options,Stride> &>
95 typedef ::eigenpy::details::referent_storage_eigen_ref<MatType,Options,Stride> StorageType;
96 typedef aligned_storage<
101 template<
typename MatType,
int Options,
typename Str
ide>
102 struct referent_storage<const Eigen::Ref<const MatType,Options,Stride> &>
104 typedef ::eigenpy::details::referent_storage_eigen_ref<const MatType,Options,Stride> StorageType;
105 typedef aligned_storage<
114 template<
typename MatrixReference>
116 : rvalue_from_python_storage<MatrixReference>
118 typedef MatrixReference
T;
120 # if (!defined(__MWERKS__) || __MWERKS__ >= 0x3000) \ 121 && (!defined(__EDG_VERSION__) || __EDG_VERSION__ >= 245) \ 122 && (!defined(__DECCXX_VER) || __DECCXX_VER > 60590014) \ 123 && !defined(BOOST_PYTHON_SYNOPSIS) 125 BOOST_STATIC_ASSERT(BOOST_PYTHON_OFFSETOF(rvalue_from_python_storage<T>,stage1) == 0);
131 this->stage1 = _stage1;
139 this->stage1.convertible = convertible;
145 typedef typename boost::remove_const<typename boost::remove_reference<MatrixReference>::type>::type MatrixType;
146 if (this->stage1.convertible == this->storage.bytes)
147 static_cast<MatrixType *
>((
void *)this->storage.bytes)->~MatrixType();
151 #define EIGENPY_RVALUE_FROM_PYTHON_DATA_INIT(type) \ 152 typedef rvalue_from_python_data_eigen<type> Base; \ 154 rvalue_from_python_data(rvalue_from_python_stage1_data const & _stage1) \ 158 rvalue_from_python_data(void* convertible) : Base(convertible) {}; 161 template<
typename Derived>
162 struct rvalue_from_python_data<
Eigen::MatrixBase<Derived> const &>
169 template<
typename Derived>
170 struct rvalue_from_python_data<
Eigen::EigenBase<Derived> const &>
177 template<
typename Derived>
178 struct rvalue_from_python_data<
Eigen::PlainObjectBase<Derived> const &>
184 template<
typename MatType,
int Options,
typename Str
ide>
185 struct rvalue_from_python_data<
Eigen::Ref<MatType,Options,Stride> &>
186 : rvalue_from_python_storage<Eigen::Ref<MatType,Options,Stride> &>
188 typedef Eigen::Ref<MatType,Options,Stride>
T;
190 # if (!defined(__MWERKS__) || __MWERKS__ >= 0x3000) \ 191 && (!defined(__EDG_VERSION__) || __EDG_VERSION__ >= 245) \ 192 && (!defined(__DECCXX_VER) || __DECCXX_VER > 60590014) \ 193 && !defined(BOOST_PYTHON_SYNOPSIS) 195 BOOST_STATIC_ASSERT(BOOST_PYTHON_OFFSETOF(rvalue_from_python_storage<T>,stage1) == 0);
201 this->stage1 = _stage1;
209 this->stage1.convertible = convertible;
215 typedef ::eigenpy::details::referent_storage_eigen_ref<MatType, Options,Stride> StorageType;
216 if (this->stage1.convertible == this->storage.bytes)
217 static_cast<StorageType *
>((
void *)this->storage.bytes)->~StorageType();
221 template<
typename MatType,
int Options,
typename Str
ide>
222 struct rvalue_from_python_data<const
Eigen::Ref<const MatType,Options,Stride> &>
223 : rvalue_from_python_storage<const Eigen::Ref<const MatType,Options,Stride> &>
225 typedef const Eigen::Ref<const MatType,Options,Stride>
T;
227 # if (!defined(__MWERKS__) || __MWERKS__ >= 0x3000) \ 228 && (!defined(__EDG_VERSION__) || __EDG_VERSION__ >= 245) \ 229 && (!defined(__DECCXX_VER) || __DECCXX_VER > 60590014) \ 230 && !defined(BOOST_PYTHON_SYNOPSIS) 232 BOOST_STATIC_ASSERT(BOOST_PYTHON_OFFSETOF(rvalue_from_python_storage<T>,stage1) == 0);
238 this->stage1 = _stage1;
246 this->stage1.convertible = convertible;
252 typedef ::eigenpy::details::referent_storage_eigen_ref<const MatType, Options,Stride> StorageType;
253 if (this->stage1.convertible == this->storage.bytes)
254 static_cast<StorageType *
>((
void *)this->storage.bytes)->~StorageType();
263 template<
typename MatOrRefType>
265 bp::converter::rvalue_from_python_stage1_data* memory)
267 PyArrayObject * pyArray =
reinterpret_cast<PyArrayObject*
>(pyObj);
268 assert((PyArray_DIMS(pyArray)[0]<INT_MAX) && (PyArray_DIMS(pyArray)[1]<INT_MAX));
270 bp::converter::rvalue_from_python_storage<MatOrRefType>* storage =
reinterpret_cast<bp::converter::rvalue_from_python_storage<MatOrRefType>*
> 271 (
reinterpret_cast<void*
>(memory));
275 memory->convertible = storage->storage.bytes;
278 template<
typename MatType,
typename _Scalar>
284 static void* convertible(PyObject* pyObj);
287 static void construct(PyObject* pyObj,
288 bp::converter::rvalue_from_python_stage1_data* memory);
290 static void registration();
293 template<
typename MatType,
typename _Scalar>
299 PyArrayObject * pyArray =
reinterpret_cast<PyArrayObject*
>(pyObj);
304 if(MatType::IsVectorAtCompileTime)
306 const Eigen::DenseIndex size_at_compile_time
307 = MatType::IsRowMajor
308 ? MatType::ColsAtCompileTime
309 : MatType::RowsAtCompileTime;
311 switch(PyArray_NDIM(pyArray))
317 if(size_at_compile_time != Eigen::Dynamic)
320 if(PyArray_DIMS(pyArray)[0] == size_at_compile_time)
331 if(PyArray_DIMS(pyArray)[0] == 1 && PyArray_DIMS(pyArray)[1] == 1)
333 if(size_at_compile_time != Eigen::Dynamic)
335 if(size_at_compile_time == 1)
344 if(PyArray_DIMS(pyArray)[0] > 1 && PyArray_DIMS(pyArray)[1] > 1)
349 if(((PyArray_DIMS(pyArray)[0] == 1) && (MatType::ColsAtCompileTime == 1))
350 || ((PyArray_DIMS(pyArray)[1] == 1) && (MatType::RowsAtCompileTime == 1)))
355 if(size_at_compile_time != Eigen::Dynamic)
357 const Eigen::DenseIndex pyArray_size
358 = PyArray_DIMS(pyArray)[0] > PyArray_DIMS(pyArray)[1]
359 ? PyArray_DIMS(pyArray)[0]
360 : PyArray_DIMS(pyArray)[1];
361 if(size_at_compile_time != pyArray_size)
372 if(PyArray_NDIM(pyArray) == 1)
377 if(PyArray_NDIM(pyArray) != 2)
382 if(PyArray_NDIM(pyArray) == 2)
384 const int R = (int)PyArray_DIMS(pyArray)[0];
385 const int C = (int)PyArray_DIMS(pyArray)[1];
387 if( (MatType::RowsAtCompileTime!=R)
388 && (MatType::RowsAtCompileTime!=Eigen::Dynamic) )
390 if( (MatType::ColsAtCompileTime!=C)
391 && (MatType::ColsAtCompileTime!=Eigen::Dynamic) )
396 #ifdef NPY_1_8_API_VERSION 397 if(!(PyArray_FLAGS(pyArray)))
399 if(!(PyArray_FLAGS(pyArray) & NPY_ALIGNED))
408 template<
typename MatType,
typename _Scalar>
410 bp::converter::rvalue_from_python_stage1_data* memory)
412 eigen_from_py_construct<MatType>(pyObj,memory);
415 template<
typename MatType,
typename _Scalar>
418 bp::converter::registry::push_back
423 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>
458 typedef Eigen::MatrixBase<MatType>
Base;
462 bp::converter::registry::push_back
468 template<
typename MatType>
472 typedef Eigen::EigenBase<MatType>
Base;
476 bp::converter::registry::push_back
482 template<
typename MatType>
486 typedef Eigen::PlainObjectBase<MatType>
Base;
490 bp::converter::registry::push_back
496 #if EIGEN_VERSION_AT_LEAST(3,2,0) 498 template<
typename MatType,
int Options,
typename Str
ide>
499 struct EigenFromPy<Eigen::Ref<MatType,Options,Stride> >
501 typedef Eigen::Ref<MatType,Options,Stride> RefType;
502 typedef typename MatType::Scalar
Scalar;
505 static void* convertible(PyObject * pyObj)
509 PyArrayObject * pyArray =
reinterpret_cast<PyArrayObject*
>(pyObj);
510 if(!PyArray_ISWRITEABLE(pyArray))
515 static void registration()
517 bp::converter::registry::push_back
519 &eigen_from_py_construct<RefType>,bp::type_id<RefType>());
523 template<
typename MatType,
int Options,
typename Str
ide>
524 struct EigenFromPy<const Eigen::Ref<const MatType,Options,Stride> >
526 typedef const Eigen::Ref<const MatType,Options,Stride> ConstRefType;
527 typedef typename MatType::Scalar
Scalar;
530 static void* convertible(PyObject * pyObj)
535 static void registration()
537 bp::converter::registry::push_back
539 &eigen_from_py_construct<ConstRefType>,bp::type_id<ConstRefType>());
546 #endif // __eigenpy_eigen_from_python_hpp__
#define EIGENPY_RVALUE_FROM_PYTHON_DATA_INIT(type)
static void allocate(PyArrayObject *pyArray, bp::converter::rvalue_from_python_storage< MatType > *storage)
EigenFromPy< MatType > EigenFromPyDerived
rvalue_from_python_data(rvalue_from_python_stage1_data const &_stage1)
void eigen_from_py_construct(PyObject *pyObj, bp::converter::rvalue_from_python_stage1_data *memory)
rvalue_from_python_data(rvalue_from_python_stage1_data const &_stage1)
static void registration()
EigenFromPy< MatType > EigenFromPyDerived
~rvalue_from_python_data()
Eigen::Ref< MatType, Options, Stride > T
Eigen::EigenBase< MatType > Base
static void registration()
rvalue_from_python_data_eigen(void *convertible)
#define call_PyArray_Check(py_obj)
~rvalue_from_python_data_eigen()
static void * convertible(PyObject *pyObj)
Determine if pyObj can be converted into a MatType object.
Eigen::PlainObjectBase< MatType > Base
static void copy(const Eigen::MatrixBase< MatrixDerived > &mat_, PyArrayObject *pyArray)
Copy mat into the Python array using Eigen::Map.
rvalue_from_python_data_eigen(rvalue_from_python_stage1_data const &_stage1)
~rvalue_from_python_data()
const Eigen::Ref< const MatType, Options, Stride > T
#define EIGENPY_GET_PY_ARRAY_TYPE(array)
static void run(const Eigen::MatrixBase< MatType > &input, PyArrayObject *pyArray)
Eigen::MatrixBase< MatType > Base
static void registration()
static void construct(PyObject *pyObj, bp::converter::rvalue_from_python_stage1_data *memory)
Allocate memory and copy pyObj in the new storage.
static void registration()
rvalue_from_python_data(void *convertible)
rvalue_from_python_data(void *convertible)
EigenFromPy< MatType > EigenFromPyDerived
static void registration()
static void run(const Eigen::MatrixBase< MatType > &, PyArrayObject *)