Skip to content
Snippets Groups Projects
Unverified Commit d05963c0 authored by Justin Carpentier's avatar Justin Carpentier Committed by GitHub
Browse files

Merge pull request #218 from jcarpent/devel

Handle support of template specialization for exposing new types
parents ec232e76 c3e869da
No related branches found
No related tags found
No related merge requests found
Pipeline #12719 passed with warnings
Subproject commit 000a90190d1dca8b028f437095f2fddff0f9839b
Subproject commit 5cb34667bde62b5676e2b869dc6d13d598a4e2e3
......@@ -34,8 +34,6 @@ namespace eigenpy
}
};
BOOST_PYTHON_FUNCTION_OVERLOADS(isApproxAngleAxis_overload,call<Eigen::AngleAxisd>::isApprox,2,3)
template<typename AngleAxis>
class AngleAxisVisitor
: public bp::def_visitor< AngleAxisVisitor<AngleAxis> >
......@@ -48,6 +46,8 @@ namespace eigenpy
typedef typename Eigen::Quaternion<Scalar,0> Quaternion;
typedef Eigen::RotationBase<AngleAxis,3> RotationBase;
BOOST_PYTHON_FUNCTION_OVERLOADS(isApproxAngleAxis_overload,call<AngleAxis>::isApprox,2,3)
public:
template<class PyClass>
......
......@@ -19,50 +19,67 @@ namespace eigenpy
template<typename MatType, bool IsVectorAtCompileTime = MatType::IsVectorAtCompileTime>
struct init_matrix_or_array
{
static MatType * run(int rows, int cols, void * storage)
{
if(storage)
return new (storage) MatType(rows,cols);
else
return new MatType(rows,cols);
}
static MatType * run(PyArrayObject * pyArray, void * storage = NULL)
{
assert(PyArray_NDIM(pyArray) == 1 || PyArray_NDIM(pyArray) == 2);
int rows = -1, cols = -1;
if(PyArray_NDIM(pyArray) == 2)
const int ndim = PyArray_NDIM(pyArray);
if(ndim == 2)
{
rows = (int)PyArray_DIMS(pyArray)[0];
cols = (int)PyArray_DIMS(pyArray)[1];
}
else if(PyArray_NDIM(pyArray) == 1)
else if(ndim == 1)
{
rows = (int)PyArray_DIMS(pyArray)[0];
cols = 1;
}
if(storage)
return new (storage) MatType(rows,cols);
else
return new MatType(rows,cols);
return run(rows,cols,storage);
}
};
template<typename MatType>
struct init_matrix_or_array<MatType,true>
{
static MatType * run(int rows, int cols, void * storage)
{
if(storage)
return new (storage) MatType(rows,cols);
else
return new MatType(rows,cols);
}
static MatType * run(int size, void * storage)
{
if(storage)
return new (storage) MatType(size);
else
return new MatType(size);
}
static MatType * run(PyArrayObject * pyArray, void * storage = NULL)
{
if(PyArray_NDIM(pyArray) == 1)
const int ndim = PyArray_NDIM(pyArray);
if(ndim == 1)
{
const int rows_or_cols = (int)PyArray_DIMS(pyArray)[0];
if(storage)
return new (storage) MatType(rows_or_cols);
else
return new MatType(rows_or_cols);
const int size = (int)PyArray_DIMS(pyArray)[0];
return run(size,storage);
}
else
{
const int rows = (int)PyArray_DIMS(pyArray)[0];
const int cols = (int)PyArray_DIMS(pyArray)[1];
if(storage)
return new (storage) MatType(rows,cols);
else
return new MatType(rows,cols);
return run(rows,cols,storage);
}
}
};
......
......@@ -275,13 +275,13 @@ namespace eigenpy
memory->convertible = storage->storage.bytes;
}
template<typename MatType>
template<typename MatType, typename _Scalar>
struct EigenFromPy
{
typedef typename MatType::Scalar Scalar;
/// \brief Determine if pyObj can be converted into a MatType object
static void* convertible(PyArrayObject* pyArray);
static void* convertible(PyObject* pyObj);
/// \brief Allocate memory and copy pyObj in the new storage
static void construct(PyObject* pyObj,
......@@ -290,12 +290,14 @@ namespace eigenpy
static void registration();
};
template<typename MatType>
void* EigenFromPy<MatType>::convertible(PyArrayObject* pyArray)
template<typename MatType, typename _Scalar>
void* EigenFromPy<MatType,_Scalar>::convertible(PyObject* pyObj)
{
if(!call_PyArray_Check(reinterpret_cast<PyObject*>(pyArray)))
if(!call_PyArray_Check(reinterpret_cast<PyObject*>(pyObj)))
return 0;
PyArrayObject * pyArray = reinterpret_cast<PyArrayObject*>(pyObj);
if(!np_type_is_convertible_into_scalar<Scalar>(EIGENPY_GET_PY_ARRAY_TYPE(pyArray)))
return 0;
......@@ -403,15 +405,15 @@ namespace eigenpy
return pyArray;
}
template<typename MatType>
void EigenFromPy<MatType>::construct(PyObject* pyObj,
bp::converter::rvalue_from_python_stage1_data* memory)
template<typename MatType, typename _Scalar>
void EigenFromPy<MatType,_Scalar>::construct(PyObject* pyObj,
bp::converter::rvalue_from_python_stage1_data* memory)
{
eigen_from_py_construct<MatType>(pyObj,memory);
}
template<typename MatType>
void EigenFromPy<MatType>::registration()
template<typename MatType, typename _Scalar>
void EigenFromPy<MatType,_Scalar>::registration()
{
bp::converter::registry::push_back
(reinterpret_cast<void *(*)(_object *)>(&EigenFromPy::convertible),
......@@ -431,7 +433,7 @@ namespace eigenpy
// Add conversion to Eigen::EigenBase<MatType>
typedef Eigen::EigenBase<MatType> EigenBase;
EigenFromPy<EigenBase>::registration();
EigenFromPy<EigenBase,typename MatType::Scalar>::registration();
// Add conversion to Eigen::PlainObjectBase<MatType>
typedef Eigen::PlainObjectBase<MatType> PlainObjectBase;
......@@ -464,7 +466,7 @@ namespace eigenpy
};
template<typename MatType>
struct EigenFromPy< Eigen::EigenBase<MatType> > : EigenFromPy<MatType>
struct EigenFromPy< Eigen::EigenBase<MatType>, typename MatType::Scalar > : EigenFromPy<MatType>
{
typedef EigenFromPy<MatType> EigenFromPyDerived;
typedef Eigen::EigenBase<MatType> Base;
......@@ -500,13 +502,14 @@ namespace eigenpy
typedef typename MatType::Scalar Scalar;
/// \brief Determine if pyObj can be converted into a MatType object
static void* convertible(PyArrayObject * pyArray)
static void* convertible(PyObject * pyObj)
{
if(!call_PyArray_Check(reinterpret_cast<PyObject*>(pyArray)))
if(!call_PyArray_Check(pyObj))
return 0;
PyArrayObject * pyArray = reinterpret_cast<PyArrayObject*>(pyObj);
if(!PyArray_ISWRITEABLE(pyArray))
return 0;
return EigenFromPy<MatType>::convertible(pyArray);
return EigenFromPy<MatType>::convertible(pyObj);
}
static void registration()
......@@ -524,9 +527,9 @@ namespace eigenpy
typedef typename MatType::Scalar Scalar;
/// \brief Determine if pyObj can be converted into a MatType object
static void* convertible(PyArrayObject * pyArray)
static void* convertible(PyObject * pyObj)
{
return EigenFromPy<MatType>::convertible(pyArray);
return EigenFromPy<MatType>::convertible(pyObj);
}
static void registration()
......
......@@ -50,7 +50,7 @@ namespace eigenpy
{
namespace bp = boost::python;
template<typename MatType>
template<typename MatType, typename _Scalar>
struct EigenToPy
{
static PyObject* convert(typename boost::add_reference<typename boost::add_const<MatType>::type>::type mat)
......@@ -82,8 +82,8 @@ namespace eigenpy
}
};
template<typename MatType, int Options, typename Stride>
struct EigenToPy< Eigen::Ref<MatType,Options,Stride> >
template<typename MatType, int Options, typename Stride, typename _Scalar>
struct EigenToPy< Eigen::Ref<MatType,Options,Stride>,_Scalar >
{
static PyObject* convert(const Eigen::Ref<MatType,Options,Stride> & mat)
{
......
......@@ -28,8 +28,8 @@
namespace eigenpy
{
template<typename MatType> struct EigenToPy;
template<typename MatType> struct EigenFromPy;
template<typename MatType, typename Scalar = typename boost::remove_reference<MatType>::type::Scalar> struct EigenToPy;
template<typename MatType, typename Scalar = typename boost::remove_reference<MatType>::type::Scalar> struct EigenFromPy;
}
#endif // ifndef __eigenpy_fwd_hpp__
......@@ -88,8 +88,6 @@ namespace eigenpy
}
};
BOOST_PYTHON_FUNCTION_OVERLOADS(isApproxQuaternion_overload,call<Eigen::Quaterniond>::isApprox,2,3)
template<typename Quaternion>
class QuaternionVisitor
: public bp::def_visitor< QuaternionVisitor<Quaternion> >
......@@ -103,6 +101,8 @@ namespace eigenpy
typedef typename QuaternionBase::Matrix3 Matrix3;
typedef typename QuaternionBase::AngleAxisType AngleAxis;
BOOST_PYTHON_FUNCTION_OVERLOADS(isApproxQuaternion_overload,call<Quaternion>::isApprox,2,3)
public:
......
......@@ -16,13 +16,13 @@ namespace eigenpy
template<typename T, int type_code = NumpyEquivalentType<T>::type_code>
struct SpecialMethods
{
static void copyswap(void * /*dst*/, void * /*src*/, int /*swap*/, void * /*arr*/) {};
static PyObject * getitem(void * /*ip*/, void * /*ap*/) { return NULL; };
static int setitem(PyObject * /*op*/, void * /*ov*/, void * /*ap*/) { return -1; }
static void copyswapn(void * /*dest*/, long /*dstride*/, void * /*src*/,
long /*sstride*/, long /*n*/, int /*swap*/, void * /*arr*/) {};
static npy_bool nonzero(void * /*ip*/, void * /*array*/) { return (npy_bool)false; };
static void dotfunc(void * /*ip0_*/, npy_intp /*is0*/, void * /*ip1_*/, npy_intp /*is1*/,
inline static void copyswap(void * /*dst*/, void * /*src*/, int /*swap*/, void * /*arr*/) /*{}*/;
inline static PyObject * getitem(void * /*ip*/, void * /*ap*/) /*{ return NULL; }*/;
inline static int setitem(PyObject * /*op*/, void * /*ov*/, void * /*ap*/) /*{ return -1; }*/;
inline static void copyswapn(void * /*dest*/, long /*dstride*/, void * /*src*/,
long /*sstride*/, long /*n*/, int /*swap*/, void * /*arr*/) /*{}*/;
inline static npy_bool nonzero(void * /*ip*/, void * /*array*/) /*{ return (npy_bool)false; }*/;
inline static void dotfunc(void * /*ip0_*/, npy_intp /*is0*/, void * /*ip1_*/, npy_intp /*is1*/,
void * /*op*/, npy_intp /*n*/, void * /*arr*/);
// static void cast(void * /*from*/, void * /*to*/, npy_intp /*n*/, void * /*fromarr*/, void * /*toarr*/) {};
};
......@@ -30,7 +30,7 @@ namespace eigenpy
template<typename T>
struct SpecialMethods<T,NPY_USERDEF>
{
static void copyswap(void * dst, void * src, int swap, void * /*arr*/)
inline static void copyswap(void * dst, void * src, int swap, void * /*arr*/)
{
// std::cout << "copyswap" << std::endl;
if (src != NULL)
......@@ -48,7 +48,7 @@ namespace eigenpy
}
}
static PyObject * getitem(void * ip, void * ap)
inline static PyObject * getitem(void * ip, void * ap)
{
// std::cout << "getitem" << std::endl;
PyArrayObject * py_array = static_cast<PyArrayObject *>(ap);
......@@ -68,7 +68,7 @@ namespace eigenpy
}
}
static int setitem(PyObject * src_obj, void * dest_ptr, void * array)
inline static int setitem(PyObject * src_obj, void * dest_ptr, void * array)
{
// std::cout << "setitem" << std::endl;
if(array == NULL)
......@@ -103,8 +103,8 @@ namespace eigenpy
return 0;
}
static void copyswapn(void * dst, long dstride, void * src, long sstride,
long n, int swap, void * array)
inline static void copyswapn(void * dst, long dstride, void * src, long sstride,
long n, int swap, void * array)
{
// std::cout << "copyswapn" << std::endl;
......@@ -122,7 +122,7 @@ namespace eigenpy
}
}
static npy_bool nonzero(void * ip, void * array)
inline static npy_bool nonzero(void * ip, void * array)
{
// std::cout << "nonzero" << std::endl;
static const T ZeroValue = T(0);
......@@ -141,8 +141,8 @@ namespace eigenpy
}
}
static void dotfunc(void * ip0_, npy_intp is0, void * ip1_, npy_intp is1,
void * op, npy_intp n, void * /*arr*/)
inline static void dotfunc(void * ip0_, npy_intp is0, void * ip1_, npy_intp is1,
void * op, npy_intp n, void * /*arr*/)
{
T res = T(0);
char *ip0 = (char*)ip0_, *ip1 = (char*)ip1_;
......
<?xml version="1.0"?>
<package format="3">
<name>eigenpy</name>
<version>2.5.0</version>
<version>2.6.0</version>
<description>Bindings between Numpy and Eigen using Boost.Python</description>
<maintainer email="justin.carpentier@inria.fr">Justin Carpentier</maintainer>
<maintainer email="opensource@wolfgangmerkt.com">Wolfgang Merkt</maintainer>
......
......@@ -89,7 +89,8 @@ void expose_custom_type(const std::string & name)
.def("__repr__",&Type::print)
;
eigenpy::registerNewType<Type>();
int code = eigenpy::registerNewType<Type>();
std::cout << "code: " << code << std::endl;
eigenpy::registerCommonUfunc<Type>();
}
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment