Verified Commit c693c335 authored by Justin Carpentier's avatar Justin Carpentier
Browse files

types: add possibility to register cast functions

parent 62d3b683
// //
// Copyright (c) 2020 INRIA // Copyright (c) 2020-2021 INRIA
// //
#ifndef __eigenpy_user_type_hpp__ #ifndef __eigenpy_user_type_hpp__
...@@ -11,8 +11,32 @@ ...@@ -11,8 +11,32 @@
namespace eigenpy namespace eigenpy
{ {
/// \brief Default cast algo to cast a From to To. Can be specialized for any types.
template<typename From, typename To>
struct cast
{
static To run(const From & from)
{
return static_cast<To>(from);
}
};
namespace internal namespace internal
{ {
template<typename From, typename To>
static void cast(void * from_, void * to_, npy_intp n, void * /*fromarr*/, void * /*toarr*/)
{
// std::cout << "cast::run" << std::endl;
const From* from = static_cast<From*>(from_);
To* to = static_cast<To*>(to_);
for(npy_intp i = 0; i < n; i++)
{
to[i] = eigenpy::cast<From,To>::run(from[i]);
}
}
template<typename T, int type_code = NumpyEquivalentType<T>::type_code> template<typename T, int type_code = NumpyEquivalentType<T>::type_code>
struct SpecialMethods struct SpecialMethods
{ {
...@@ -27,7 +51,6 @@ namespace eigenpy ...@@ -27,7 +51,6 @@ namespace eigenpy
inline static int fill(void* data_, npy_intp length, void* arr); inline static int fill(void* data_, npy_intp length, void* arr);
inline static int fillwithscalar(void* buffer_, npy_intp length, inline static int fillwithscalar(void* buffer_, npy_intp length,
void* value, void* arr); void* value, void* arr);
// static void cast(void * /*from*/, void * /*to*/, npy_intp /*n*/, void * /*fromarr*/, void * /*toarr*/) {};
}; };
template<typename T> template<typename T>
...@@ -204,9 +227,6 @@ namespace eigenpy ...@@ -204,9 +227,6 @@ namespace eigenpy
return 0; return 0;
} }
// static void cast(void * from, void * to, npy_intp n, void * fromarr, void * toarr)
// {
// }
static int fill(void* data_, npy_intp length, void* /*arr*/) static int fill(void* data_, npy_intp length, void* /*arr*/)
{ {
...@@ -227,6 +247,49 @@ namespace eigenpy ...@@ -227,6 +247,49 @@ namespace eigenpy
} // namespace internal } // namespace internal
template<typename From, typename To>
bool registerCast(const bool safe)
{
PyArray_Descr* from_array_descr = Register::getPyArrayDescr<From>();
// int from_typenum = Register::getTypeCode<From>();
// PyTypeObject * to_py_type = Register::getPyType<To>();
int to_typenum = Register::getTypeCode<To>();
if(PyArray_RegisterCastFunc(from_array_descr,
to_typenum,
static_cast<PyArray_VectorUnaryFunc *>(&eigenpy::internal::cast<From,To>)) < 0)
{
std::stringstream ss;
ss
<< "PyArray_RegisterCastFunc of the cast from "
<< bp::type_info(typeid(From)).name()
<< " to "
<< bp::type_info(typeid(To)).name()
<< " has failed.";
eigenpy::Exception(ss.str());
return false;
}
if (safe && PyArray_RegisterCanCast(from_array_descr,
to_typenum,
NPY_NOSCALAR) < 0)
{
std::stringstream ss;
ss
<< "PyArray_RegisterCanCast of the cast from "
<< bp::type_info(typeid(From)).name()
<< " to "
<< bp::type_info(typeid(To)).name()
<< " has failed.";
eigenpy::Exception(ss.str());
return false;
}
return true;
}
template<typename Scalar> template<typename Scalar>
int registerNewType(PyTypeObject * py_type_ptr = NULL) int registerNewType(PyTypeObject * py_type_ptr = NULL)
{ {
...@@ -252,7 +315,6 @@ namespace eigenpy ...@@ -252,7 +315,6 @@ namespace eigenpy
PyArray_DotFunc * dotfunc = &internal::SpecialMethods<Scalar>::dotfunc; PyArray_DotFunc * dotfunc = &internal::SpecialMethods<Scalar>::dotfunc;
PyArray_FillFunc * fill = &internal::SpecialMethods<Scalar>::fill; PyArray_FillFunc * fill = &internal::SpecialMethods<Scalar>::fill;
PyArray_FillWithScalarFunc * fillwithscalar = &internal::SpecialMethods<Scalar>::fillwithscalar; PyArray_FillWithScalarFunc * fillwithscalar = &internal::SpecialMethods<Scalar>::fillwithscalar;
// PyArray_CastFunc * cast = &internal::SpecialMethods<Scalar>::cast;
int code = Register::registerNewType(py_type_ptr, int code = Register::registerNewType(py_type_ptr,
&typeid(Scalar), &typeid(Scalar),
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment