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;
270 static void *convertible(PyObject *pyObj);
273 static void construct(PyObject *pyObj,
274 bp::converter::rvalue_from_python_stage1_data *memory);
276 static void registration();
279 template <
typename MatType>
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 #ifdef EIGENPY_MSVC_COMPILER 294 template <
typename EigenType>
296 typename
boost::remove_reference<EigenType>::type::Scalar>
298 template <typename EigenType, typename _Scalar>
304 template <
typename MatType>
309 PyArrayObject *pyArray =
reinterpret_cast<PyArrayObject *
>(pyObj);
311 if (!np_type_is_convertible_into_scalar<Scalar>(
315 if (MatType::IsVectorAtCompileTime) {
316 const Eigen::DenseIndex size_at_compile_time =
317 MatType::IsRowMajor ? MatType::ColsAtCompileTime
318 : MatType::RowsAtCompileTime;
320 switch (PyArray_NDIM(pyArray)) {
324 if (size_at_compile_time != Eigen::Dynamic) {
326 if (PyArray_DIMS(pyArray)[0] == size_at_compile_time)
335 if (PyArray_DIMS(pyArray)[0] == 1 && PyArray_DIMS(pyArray)[1] == 1) {
336 if (size_at_compile_time != Eigen::Dynamic) {
337 if (size_at_compile_time == 1)
345 if (PyArray_DIMS(pyArray)[0] > 1 && PyArray_DIMS(pyArray)[1] > 1) {
349 if (((PyArray_DIMS(pyArray)[0] == 1) &&
350 (MatType::ColsAtCompileTime == 1)) ||
351 ((PyArray_DIMS(pyArray)[1] == 1) &&
352 (MatType::RowsAtCompileTime == 1))) {
356 if (size_at_compile_time !=
358 const Eigen::DenseIndex pyArray_size =
359 PyArray_DIMS(pyArray)[0] > PyArray_DIMS(pyArray)[1]
360 ? PyArray_DIMS(pyArray)[0]
361 : PyArray_DIMS(pyArray)[1];
362 if (size_at_compile_time != pyArray_size)
return 0;
371 if (PyArray_NDIM(pyArray) ==
377 if (PyArray_NDIM(pyArray) != 2) {
381 if (PyArray_NDIM(pyArray) == 2) {
382 const int R = (int)PyArray_DIMS(pyArray)[0];
383 const int C = (int)PyArray_DIMS(pyArray)[1];
385 if ((MatType::RowsAtCompileTime != R) &&
386 (MatType::RowsAtCompileTime != Eigen::Dynamic))
388 if ((MatType::ColsAtCompileTime != C) &&
389 (MatType::ColsAtCompileTime != Eigen::Dynamic))
394 #ifdef NPY_1_8_API_VERSION 395 if (!(PyArray_FLAGS(pyArray)))
397 if (!(PyArray_FLAGS(pyArray) & NPY_ALIGNED))
406 template <
typename MatType>
408 PyObject *pyObj, bp::converter::rvalue_from_python_stage1_data *memory) {
409 eigen_from_py_construct<MatType>(pyObj, memory);
412 template <
typename MatType>
414 bp::converter::registry::push_back(
417 #ifndef BOOST_PYTHON_NO_PY_SIGNATURES
424 template <
typename EigenType,
428 template <
typename EigenType>
431 template <
typename MatType>
437 typedef Eigen::MatrixBase<MatType> MatrixBase;
441 typedef Eigen::EigenBase<MatType> EigenBase;
445 typedef Eigen::PlainObjectBase<MatType> PlainObjectBase;
448 #if EIGEN_VERSION_AT_LEAST(3, 2, 0) 450 typedef Eigen::Ref<MatType> RefType;
454 typedef const Eigen::Ref<const MatType> ConstRefType;
460 template <
typename MatType>
463 typedef Eigen::MatrixBase<MatType>
Base;
466 bp::converter::registry::push_back(
469 #ifndef BOOST_PYTHON_NO_PY_SIGNATURES
477 template <
typename MatType>
481 typedef Eigen::EigenBase<MatType>
Base;
484 bp::converter::registry::push_back(
487 #ifndef BOOST_PYTHON_NO_PY_SIGNATURES
495 template <
typename MatType>
498 typedef Eigen::PlainObjectBase<MatType>
Base;
501 bp::converter::registry::push_back(
504 #ifndef BOOST_PYTHON_NO_PY_SIGNATURES
512 #if EIGEN_VERSION_AT_LEAST(3, 2, 0) 514 template <
typename MatType,
int Options,
typename Str
ide>
515 struct EigenFromPy<Eigen::Ref<MatType, Options, Stride> > {
516 typedef Eigen::Ref<MatType, Options, Stride> RefType;
517 typedef typename MatType::Scalar
Scalar;
520 static void *convertible(PyObject *pyObj) {
522 PyArrayObject *pyArray =
reinterpret_cast<PyArrayObject *
>(pyObj);
523 if (!PyArray_ISWRITEABLE(pyArray))
return 0;
527 static void registration() {
528 bp::converter::registry::push_back(
530 &eigen_from_py_construct<RefType>, bp::type_id<RefType>()
531 #ifndef BOOST_PYTHON_NO_PY_SIGNATURES
539 template <
typename MatType,
int Options,
typename Str
ide>
540 struct EigenFromPy<const Eigen::Ref<const MatType, Options, Stride> > {
541 typedef const Eigen::Ref<const MatType, Options, Stride> ConstRefType;
542 typedef typename MatType::Scalar
Scalar;
545 static void *convertible(PyObject *pyObj) {
549 static void registration() {
550 bp::converter::registry::push_back(
552 &eigen_from_py_construct<ConstRefType>, bp::type_id<ConstRefType>()
553 #ifndef BOOST_PYTHON_NO_PY_SIGNATURES
564 #ifdef EIGENPY_WITH_TENSOR_SUPPORT 568 #endif // __eigenpy_eigen_from_python_hpp__ ReturnMatrix copy(const Eigen::MatrixBase< Matrix > &mat)
static void registration()
#define EIGENPY_RVALUE_FROM_PYTHON_DATA_INIT(type)
bool call_PyArray_Check(PyObject *py_obj)
EigenFromPy< MatType > EigenFromPyDerived
rvalue_from_python_data(rvalue_from_python_stage1_data const &_stage1)
Eigen::Ref< MatType, Options, Stride > RefType
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)
EigenFromPy< MatType > EigenFromPyDerived
~rvalue_from_python_data()
static PyTypeObject const * get_pytype()
Eigen::EigenBase< MatType > Base
static void registration()
Eigen::PlainObjectBase< MatType > Base
Eigen::Matrix< Scalar, Rows, Cols, Options, MaxRows, MaxCols > T
Eigen::Ref< const MatType, Options, Stride > RefType
~rvalue_from_python_data()
static void registration()
#define EIGENPY_GET_PY_ARRAY_TYPE(array)
static void construct(PyObject *pyObj, bp::converter::rvalue_from_python_stage1_data *memory)
Allocate memory and copy pyObj in the new storage.
static void * convertible(PyObject *pyObj)
Determine if pyObj can be converted into a MatType object.
Eigen::TensorRef< Tensor > ref(Eigen::TensorRef< Tensor > tensor)
static void run(const Eigen::MatrixBase< MatType > &input, PyArrayObject *pyArray)
Eigen::MatrixBase< MatType > Base
static void registration()
PyTypeObject * getPyArrayType()
static void registration()
rvalue_from_python_data(void *convertible)
rvalue_from_python_data(void *convertible)
boost::mpl::if_< boost::is_const< typename boost::remove_reference< EigenType >::type >, const _type, _type >::type type
EigenFromPy< MatType > EigenFromPyDerived
static void run(const Eigen::MatrixBase< MatType > &, PyArrayObject *)