5#ifndef __eigenpy_eigen_from_python_hpp__ 6#define __eigenpy_eigen_from_python_hpp__ 8#include "eigenpy/fwd.hpp" 9#include "eigenpy/eigen-allocator.hpp" 10#include "eigenpy/numpy-type.hpp" 11#include "eigenpy/scalar-conversion.hpp" 15template <
typename EigenType,
16 typename BaseType =
typename get_eigen_base_type<EigenType>::type>
19template <
typename MatType>
21 static PyTypeObject
const *get_pytype() {
22 PyTypeObject
const *py_type = eigenpy::getPyArrayType();
33template <
typename Scalar,
int Rows,
int Cols,
int Options,
int MaxRows,
35struct expected_pytype_for_arg<
36 Eigen::Matrix<Scalar, Rows, Cols, Options, MaxRows, MaxCols>>
38 Eigen::Matrix<Scalar, Rows, Cols, Options, MaxRows, MaxCols>> {};
46template <typename MatType, bool is_const = boost::is_const<MatType>::value>
48 static void run(
const Eigen::MatrixBase<MatType> &input,
49 PyArrayObject *pyArray) {
54template <
typename MatType>
56 static void run(
const Eigen::MatrixBase<MatType> & ,
60#if EIGEN_VERSION_AT_LEAST(3, 2, 0) 62template <
typename _RefType>
63struct referent_storage_eigen_ref {
64 typedef _RefType RefType;
66 typedef typename ::eigenpy::aligned_storage<
67 ::boost::python::detail::referent_size<RefType &>::value>
::type 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))
86 copy_if_non_const<PlainObjectType>::run(*plain_ptr, 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) 109template <
typename MatType,
int Options,
typename Str
ide>
110struct 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<
114 referent_size<StorageType &>::value>::type type;
117template <
typename MatType,
int Options,
typename Str
ide>
118struct 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<
122 referent_size<StorageType &>::value>::type type;
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){}; 141template <
typename Scalar,
int Rows,
int Cols,
int Options,
int MaxRows,
143struct 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;
148 EIGENPY_RVALUE_FROM_PYTHON_DATA_INIT(T
const &)
151template <
typename Derived>
152struct rvalue_from_python_data<Eigen::MatrixBase<Derived> const &>
154 EIGENPY_RVALUE_FROM_PYTHON_DATA_INIT(Derived
const &)
157template <
typename Derived>
158struct rvalue_from_python_data<Eigen::EigenBase<Derived> const &>
160 EIGENPY_RVALUE_FROM_PYTHON_DATA_INIT(Derived
const &)
163template <
typename Derived>
164struct rvalue_from_python_data<Eigen::PlainObjectBase<Derived> const &>
166 EIGENPY_RVALUE_FROM_PYTHON_DATA_INIT(Derived
const &)
169template <
typename MatType,
int Options,
typename Str
ide>
170struct 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>,
185 rvalue_from_python_data(rvalue_from_python_stage1_data
const &_stage1) {
186 this->stage1 = _stage1;
192 rvalue_from_python_data(
void *convertible) {
193 this->stage1.convertible = convertible;
197 ~rvalue_from_python_data() {
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();
204template <
typename MatType,
int Options,
typename Str
ide>
205struct 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>,
222 rvalue_from_python_data(rvalue_from_python_stage1_data
const &_stage1) {
223 this->stage1 = _stage1;
229 rvalue_from_python_data(
void *convertible) {
230 this->stage1.convertible = convertible;
234 ~rvalue_from_python_data() {
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();
247template <
typename MatOrRefType>
248void eigen_from_py_construct(
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));
259 EigenAllocator<MatOrRefType>::allocate(pyArray, storage);
261 memory->convertible = storage->storage.bytes;
264template <
typename EigenType,
265 typename BaseType =
typename get_eigen_base_type<EigenType>::type>
267 typedef typename EigenType::Scalar Scalar;
274 bp::converter::rvalue_from_python_stage1_data *memory);
276 static void registration();
279template <
typename MatType>
281 typedef typename MatType::Scalar Scalar;
288 bp::converter::rvalue_from_python_stage1_data *memory);
290 static void registration();
293template <
typename EigenType,
295 typename boost::remove_reference<EigenType>::type::Scalar>
298template <
typename MatType>
301 if (!call_PyArray_Check(
reinterpret_cast<PyObject *
>(pyObj)))
return 0;
303 PyArrayObject *pyArray =
reinterpret_cast<PyArrayObject *
>(pyObj);
305 if (!np_type_is_convertible_into_scalar<Scalar>(
306 EIGENPY_GET_PY_ARRAY_TYPE(pyArray)))
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))
400template <
typename MatType>
402 PyObject *pyObj, bp::converter::rvalue_from_python_stage1_data *memory) {
403 eigen_from_py_construct<MatType>(pyObj, memory);
406template <
typename MatType>
408 bp::converter::registry::push_back(
411#ifndef BOOST_PYTHON_NO_PY_SIGNATURES
418template <
typename EigenType,
419 typename BaseType =
typename get_eigen_base_type<EigenType>::type>
422template <
typename EigenType>
425template <
typename MatType>
427 static void registration() {
428 EigenFromPy<MatType>::registration();
431 typedef Eigen::MatrixBase<MatType> MatrixBase;
432 EigenFromPy<MatrixBase>::registration();
435 typedef Eigen::EigenBase<MatType> EigenBase;
436 EigenFromPy<EigenBase, typename MatType::Scalar>::registration();
439 typedef Eigen::PlainObjectBase<MatType> PlainObjectBase;
440 EigenFromPy<PlainObjectBase>::registration();
442#if EIGEN_VERSION_AT_LEAST(3, 2, 0) 444 typedef Eigen::Ref<MatType> RefType;
445 EigenFromPy<RefType>::registration();
448 typedef const Eigen::Ref<const MatType> ConstRefType;
449 EigenFromPy<ConstRefType>::registration();
454template <
typename MatType>
457 typedef Eigen::MatrixBase<MatType> Base;
459 static void registration() {
460 bp::converter::registry::push_back(
463#ifndef BOOST_PYTHON_NO_PY_SIGNATURES
471template <
typename MatType>
472struct EigenFromPy<Eigen::EigenBase<MatType>, typename MatType::Scalar>
475 typedef Eigen::EigenBase<MatType> Base;
477 static void registration() {
478 bp::converter::registry::push_back(
481#ifndef BOOST_PYTHON_NO_PY_SIGNATURES
489template <
typename MatType>
492 typedef Eigen::PlainObjectBase<MatType> Base;
494 static void registration() {
495 bp::converter::registry::push_back(
498#ifndef BOOST_PYTHON_NO_PY_SIGNATURES
506#if EIGEN_VERSION_AT_LEAST(3, 2, 0) 508template <
typename MatType,
int Options,
typename Str
ide>
509struct EigenFromPy<Eigen::Ref<MatType, Options, Stride>> {
510 typedef Eigen::Ref<MatType, Options, Stride> RefType;
511 typedef typename MatType::Scalar Scalar;
515 if (!call_PyArray_Check(pyObj))
return 0;
516 PyArrayObject *pyArray =
reinterpret_cast<PyArrayObject *
>(pyObj);
517 if (!PyArray_ISWRITEABLE(pyArray))
return 0;
521 static void registration() {
522 bp::converter::registry::push_back(
524 &eigen_from_py_construct<RefType>, bp::type_id<RefType>()
525#ifndef BOOST_PYTHON_NO_PY_SIGNATURES
533template <
typename MatType,
int Options,
typename Str
ide>
534struct EigenFromPy<const Eigen::Ref<const MatType, Options, Stride>> {
535 typedef const Eigen::Ref<const MatType, Options, Stride> ConstRefType;
536 typedef typename MatType::Scalar Scalar;
543 static void registration() {
544 bp::converter::registry::push_back(
546 &eigen_from_py_construct<ConstRefType>, bp::type_id<ConstRefType>()
547#ifndef BOOST_PYTHON_NO_PY_SIGNATURES
549 &eigenpy::expected_pytype_for_arg<MatType>::get_pytype
558#ifdef EIGENPY_WITH_TENSOR_SUPPORT 559#include "eigenpy/tensor/eigen-from-python.hpp" 562#include "eigenpy/sparse/eigen-from-python.hpp" static void * convertible(PyObject *pyObj)
Determine if pyObj can be converted into a MatType object.
static void construct(PyObject *pyObj, bp::converter::rvalue_from_python_stage1_data *memory)
Allocate memory and copy pyObj in the new storage.
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.