5 #ifndef __eigenpy_user_type_hpp__
6 #define __eigenpy_user_type_hpp__
17 template <
typename From,
typename To>
19 static To
run(
const From& from) {
20 #pragma GCC diagnostic push
21 #pragma GCC diagnostic ignored "-Wconversion"
22 #pragma GCC diagnostic ignored "-Wfloat-conversion"
23 return static_cast<To
>(from);
24 #pragma GCC diagnostic pop
30 template <
typename From,
typename To>
31 static void cast(
void* from_,
void* to_, npy_intp n,
void* ,
34 const From* from =
static_cast<From*
>(from_);
35 To* to =
static_cast<To*
>(to_);
36 for (npy_intp i = 0; i < n; i++) {
53 static PyObject*
run(
void*
data,
void* ) {
55 T* elt_ptr =
static_cast<T*
>(
data);
62 template <typename T, int type_code = NumpyEquivalentType<T>::type_code>
64 inline static void copyswap(
void* ,
void* ,
int ,
66 inline static PyObject*
getitem(
void* ,
68 inline static int setitem(PyObject* ,
void* ,
70 inline static void copyswapn(
void* ,
long ,
void* ,
75 inline static void dotfunc(
void* , npy_intp ,
void* ,
76 npy_intp ,
void* , npy_intp ,
78 inline static int fill(
void* data_, npy_intp length,
void* arr);
95 static void copyswap(
void* dst,
void* src,
int swap,
void* ) {
98 T& t1 = *
static_cast<T*
>(dst);
99 T&
t2 = *
static_cast<T*
>(src);
104 T& t1 = *
static_cast<T*
>(dst);
105 T&
t2 = *
static_cast<T*
>(src);
110 static PyObject*
getitem(
void* ip,
void* ap) {
129 inline static int setitem(PyObject* src_obj,
void* dest_ptr,
void* array) {
135 PyArrayObject* py_array =
static_cast<PyArrayObject*
>(array);
136 PyArray_Descr* descr = PyArray_DTYPE(py_array);
137 PyTypeObject* array_scalar_type = descr->typeobj;
138 PyTypeObject* src_obj_type = Py_TYPE(src_obj);
140 if (array_scalar_type != src_obj_type) {
141 std::stringstream ss;
142 ss <<
"The input type is of wrong type. ";
143 ss <<
"The expected type is " <<
bp::type_info(
typeid(T)).name()
149 bp::extract<T&> extract_src_obj(src_obj);
150 if (!extract_src_obj.check()) {
151 std::stringstream ss;
152 ss <<
"The input type is of wrong type. ";
153 ss <<
"The expected type is " <<
bp::type_info(
typeid(T)).name()
159 const T& src = extract_src_obj();
160 T& dest = *
static_cast<T*
>(dest_ptr);
166 inline static void copyswapn(
void* dst,
long dstride,
void* src,
long sstride,
167 long n,
int swap,
void* array) {
170 char* dstptr =
static_cast<char*
>(dst);
171 char* srcptr =
static_cast<char*
>(src);
173 PyArrayObject* py_array =
static_cast<PyArrayObject*
>(array);
177 for (npy_intp i = 0; i < n; i++) {
178 copyswap(dstptr, srcptr, swap, array);
184 inline static npy_bool
nonzero(
void* ip,
void* array) {
186 static const T ZeroValue = T(0);
187 PyArrayObject* py_array =
static_cast<PyArrayObject*
>(array);
188 if (py_array == NULL || PyArray_ISBEHAVED_RO(py_array)) {
189 const T&
value = *
static_cast<T*
>(ip);
190 return (npy_bool)(
value != ZeroValue);
194 ->copyswap(&tmp_value, ip, PyArray_ISBYTESWAPPED(py_array), array);
195 return (npy_bool)(tmp_value != ZeroValue);
199 inline static void dotfunc(
void* ip0_, npy_intp is0,
void* ip1_, npy_intp is1,
200 void* op, npy_intp n,
void* ) {
202 typedef Eigen::Matrix<T, Eigen::Dynamic, 1> VectorT;
203 typedef Eigen::InnerStride<Eigen::Dynamic> InputStride;
204 typedef const Eigen::Map<const VectorT, 0, InputStride> ConstMapType;
206 ConstMapType v0(
static_cast<T*
>(ip0_), n,
207 InputStride(is0 / (Eigen::DenseIndex)
sizeof(T))),
208 v1(
static_cast<T*
>(ip1_), n,
209 InputStride(is1 / (Eigen::DenseIndex)
sizeof(T)));
211 *
static_cast<T*
>(op) = v0.dot(v1);
217 T
r = *
static_cast<T*
>(
value);
218 T* buffer =
static_cast<T*
>(buffer_);
220 for (i = 0; i < length; i++) {
226 static int fill(
void* data_, npy_intp length,
void* ) {
228 T*
data =
static_cast<T*
>(data_);
232 for (i = 2; i < length; i++) {
243 template <
typename From,
typename To>
245 PyArray_Descr* from_array_descr = Register::getPyArrayDescr<From>();
249 int to_typenum = Register::getTypeCode<To>();
250 assert(to_typenum >= 0 &&
"to_typenum is not valid");
251 assert(from_array_descr != NULL &&
"from_array_descr is not valid");
261 static_cast<PyArray_VectorUnaryFunc*
>(
262 &eigenpy::internal::cast<From, To>)) <
264 std::stringstream ss;
265 ss <<
"PyArray_RegisterCastFunc of the cast from "
274 std::stringstream ss;
275 ss <<
"PyArray_RegisterCanCast of the cast from "
287 template <
typename T>
291 const bp::converter::registration* registration =
292 bp::converter::registry::query(type);
300 bp::handle<PyTypeObject> handle(
301 bp::borrowed(registration->get_class_object()));
302 return bp::object(handle);
305 template <
typename Scalar>
309 if (isNumpyNativeType<Scalar>())
313 if (py_type_ptr == NULL) {
314 py_type_ptr = Register::getPyType<Scalar>();
325 PyArray_CopySwapNFunc* copyswapn =
reinterpret_cast<PyArray_CopySwapNFunc*
>(
329 PyArray_FillWithScalarFunc* fillwithscalar =
333 py_type_ptr, &
typeid(Scalar),
sizeof(Scalar),
335 copyswapn, dotfunc,
fill, fillwithscalar);
345 #endif // __eigenpy_user_type_hpp__