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
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