Commit 89720ae2 authored by Alexander Alekhin's avatar Alexander Alekhin

python: fix "unsigned int" / "size_t" overloading conflict

parent dca657a2
...@@ -10,6 +10,22 @@ ...@@ -10,6 +10,22 @@
#pragma warning(pop) #pragma warning(pop)
#endif #endif
#include <type_traits> // std::enable_if
template<typename T, class TEnable = void> // TEnable is used for SFINAE checks
struct PyOpenCV_Converter
{
//static inline bool to(PyObject* obj, T& p, const char* name);
//static inline PyObject* from(const T& src);
};
template<typename T> static
bool pyopencv_to(PyObject* obj, T& p, const char* name = "<unknown>") { return PyOpenCV_Converter<T>::to(obj, p, name); }
template<typename T> static
PyObject* pyopencv_from(const T& src) { return PyOpenCV_Converter<T>::from(src); }
#define CV_PY_FN_WITH_KW_(fn, flags) (PyCFunction)(void*)(PyCFunctionWithKeywords)(fn), (flags) | METH_VARARGS | METH_KEYWORDS #define CV_PY_FN_WITH_KW_(fn, flags) (PyCFunction)(void*)(PyCFunctionWithKeywords)(fn), (flags) | METH_VARARGS | METH_KEYWORDS
#define CV_PY_FN_NOARGS_(fn, flags) (PyCFunction)(fn), (flags) | METH_NOARGS #define CV_PY_FN_NOARGS_(fn, flags) (PyCFunction)(fn), (flags) | METH_NOARGS
...@@ -28,8 +44,6 @@ ...@@ -28,8 +44,6 @@
#endif #endif
#define CV_PY_TO_CLASS(TYPE) \ #define CV_PY_TO_CLASS(TYPE) \
template<> bool pyopencv_to(PyObject* dst, Ptr<TYPE>& src, const char* name); \
\
template<> \ template<> \
bool pyopencv_to(PyObject* dst, TYPE& src, const char* name) \ bool pyopencv_to(PyObject* dst, TYPE& src, const char* name) \
{ \ { \
...@@ -43,8 +57,6 @@ bool pyopencv_to(PyObject* dst, TYPE& src, const char* name) ...@@ -43,8 +57,6 @@ bool pyopencv_to(PyObject* dst, TYPE& src, const char* name)
} }
#define CV_PY_FROM_CLASS(TYPE) \ #define CV_PY_FROM_CLASS(TYPE) \
template<> PyObject* pyopencv_from(const Ptr<TYPE>& src); \
\
template<> \ template<> \
PyObject* pyopencv_from(const TYPE& src) \ PyObject* pyopencv_from(const TYPE& src) \
{ \ { \
...@@ -55,8 +67,6 @@ PyObject* pyopencv_from(const TYPE& src) ...@@ -55,8 +67,6 @@ PyObject* pyopencv_from(const TYPE& src)
} }
#define CV_PY_TO_CLASS_PTR(TYPE) \ #define CV_PY_TO_CLASS_PTR(TYPE) \
template<> bool pyopencv_to(PyObject* dst, Ptr<TYPE>& src, const char* name); \
\
template<> \ template<> \
bool pyopencv_to(PyObject* dst, TYPE*& src, const char* name) \ bool pyopencv_to(PyObject* dst, TYPE*& src, const char* name) \
{ \ { \
...@@ -70,16 +80,12 @@ bool pyopencv_to(PyObject* dst, TYPE*& src, const char* name) ...@@ -70,16 +80,12 @@ bool pyopencv_to(PyObject* dst, TYPE*& src, const char* name)
} }
#define CV_PY_FROM_CLASS_PTR(TYPE) \ #define CV_PY_FROM_CLASS_PTR(TYPE) \
template<> PyObject* pyopencv_from(const Ptr<TYPE>& src); \
\
static PyObject* pyopencv_from(TYPE*& src) \ static PyObject* pyopencv_from(TYPE*& src) \
{ \ { \
return pyopencv_from(Ptr<TYPE>(src)); \ return pyopencv_from(Ptr<TYPE>(src)); \
} }
#define CV_PY_TO_ENUM(TYPE) \ #define CV_PY_TO_ENUM(TYPE) \
template<> bool pyopencv_to(PyObject* dst, std::underlying_type<TYPE>::type& src, const char* name); \
\
template<> \ template<> \
bool pyopencv_to(PyObject* dst, TYPE& src, const char* name) \ bool pyopencv_to(PyObject* dst, TYPE& src, const char* name) \
{ \ { \
...@@ -93,8 +99,6 @@ bool pyopencv_to(PyObject* dst, TYPE& src, const char* name) ...@@ -93,8 +99,6 @@ bool pyopencv_to(PyObject* dst, TYPE& src, const char* name)
} }
#define CV_PY_FROM_ENUM(TYPE) \ #define CV_PY_FROM_ENUM(TYPE) \
template<> PyObject* pyopencv_from(const std::underlying_type<TYPE>::type& src); \
\
template<> \ template<> \
PyObject* pyopencv_from(const TYPE& src) \ PyObject* pyopencv_from(const TYPE& src) \
{ \ { \
...@@ -302,12 +306,6 @@ public: ...@@ -302,12 +306,6 @@ public:
NumpyAllocator g_numpyAllocator; NumpyAllocator g_numpyAllocator;
template<typename T> static
bool pyopencv_to(PyObject* obj, T& p, const char* name = "<unknown>");
template<typename T> static
PyObject* pyopencv_from(const T& src);
enum { ARG_NONE = 0, ARG_MAT = 1, ARG_SCALAR = 2 }; enum { ARG_NONE = 0, ARG_MAT = 1, ARG_SCALAR = 2 };
// special case, when the converter needs full ArgInfo structure // special case, when the converter needs full ArgInfo structure
...@@ -514,15 +512,6 @@ bool pyopencv_to(PyObject* o, Matx<_Tp, m, n>& mx, const char* name) ...@@ -514,15 +512,6 @@ bool pyopencv_to(PyObject* o, Matx<_Tp, m, n>& mx, const char* name)
return pyopencv_to(o, mx, ArgInfo(name, 0)); return pyopencv_to(o, mx, ArgInfo(name, 0));
} }
template <typename T>
bool pyopencv_to(PyObject *o, Ptr<T>& p, const char *name)
{
if (!o || o == Py_None)
return true;
p = makePtr<T>();
return pyopencv_to(o, *p, name);
}
template<> template<>
PyObject* pyopencv_from(const Mat& m) PyObject* pyopencv_from(const Mat& m)
{ {
...@@ -547,12 +536,22 @@ PyObject* pyopencv_from(const Matx<_Tp, m, n>& matx) ...@@ -547,12 +536,22 @@ PyObject* pyopencv_from(const Matx<_Tp, m, n>& matx)
} }
template<typename T> template<typename T>
PyObject* pyopencv_from(const cv::Ptr<T>& p) struct PyOpenCV_Converter< cv::Ptr<T> >
{ {
if (!p) static PyObject* from(const cv::Ptr<T>& p)
Py_RETURN_NONE; {
return pyopencv_from(*p); if (!p)
} Py_RETURN_NONE;
return pyopencv_from(*p);
}
static bool to(PyObject *o, Ptr<T>& p, const char *name)
{
if (!o || o == Py_None)
return true;
p = makePtr<T>();
return pyopencv_to(o, *p, name);
}
};
template<> template<>
bool pyopencv_to(PyObject* obj, void*& ptr, const char* name) bool pyopencv_to(PyObject* obj, void*& ptr, const char* name)
...@@ -674,28 +673,31 @@ bool pyopencv_to(PyObject* obj, int& value, const char* name) ...@@ -674,28 +673,31 @@ bool pyopencv_to(PyObject* obj, int& value, const char* name)
return value != -1 || !PyErr_Occurred(); return value != -1 || !PyErr_Occurred();
} }
#if defined (_M_AMD64) || defined (__x86_64__) || defined (__PPC64__) // There is conflict between "size_t" and "unsigned int".
template<> // They are the same type on some 32-bit platforms.
PyObject* pyopencv_from(const unsigned int& value) template<typename T>
struct PyOpenCV_Converter
< T, typename std::enable_if< std::is_same<unsigned int, T>::value && !std::is_same<unsigned int, size_t>::value >::type >
{ {
return PyLong_FromUnsignedLong(value); static inline PyObject* from(const unsigned int& value)
} {
return PyLong_FromUnsignedLong(value);
}
template<> static inline bool to(PyObject* obj, unsigned int& value, const char* name)
bool pyopencv_to(PyObject* obj, unsigned int& value, const char* name) {
{ CV_UNUSED(name);
CV_UNUSED(name); if(!obj || obj == Py_None)
if(!obj || obj == Py_None) return true;
return true; if(PyInt_Check(obj))
if(PyInt_Check(obj)) value = (unsigned int)PyInt_AsLong(obj);
value = (unsigned int)PyInt_AsLong(obj); else if(PyLong_Check(obj))
else if(PyLong_Check(obj)) value = (unsigned int)PyLong_AsLong(obj);
value = (unsigned int)PyLong_AsLong(obj); else
else return false;
return false; return value != (unsigned int)-1 || !PyErr_Occurred();
return value != (unsigned int)-1 || !PyErr_Occurred(); }
} };
#endif
template<> template<>
PyObject* pyopencv_from(const uchar& value) PyObject* pyopencv_from(const uchar& value)
......
...@@ -70,25 +70,29 @@ static void pyopencv_${name}_dealloc(PyObject* self) ...@@ -70,25 +70,29 @@ static void pyopencv_${name}_dealloc(PyObject* self)
PyObject_Del(self); PyObject_Del(self);
} }
template<> PyObject* pyopencv_from(const ${cname}& r) template<>
struct PyOpenCV_Converter< ${cname} >
{ {
pyopencv_${name}_t *m = PyObject_NEW(pyopencv_${name}_t, &pyopencv_${name}_Type); static PyObject* from(const ${cname}& r)
new (&m->v) ${cname}(r); //Copy constructor {
return (PyObject*)m; pyopencv_${name}_t *m = PyObject_NEW(pyopencv_${name}_t, &pyopencv_${name}_Type);
} new (&m->v) ${cname}(r); //Copy constructor
return (PyObject*)m;
}
template<> bool pyopencv_to(PyObject* src, ${cname}& dst, const char* name) static bool to(PyObject* src, ${cname}& dst, const char* name)
{
if(!src || src == Py_None)
return true;
if(PyObject_TypeCheck(src, &pyopencv_${name}_Type))
{ {
dst = ((pyopencv_${name}_t*)src)->v; if(!src || src == Py_None)
return true; return true;
if(PyObject_TypeCheck(src, &pyopencv_${name}_Type))
{
dst = ((pyopencv_${name}_t*)src)->v;
return true;
}
failmsg("Expected ${cname} for argument '%%s'", name);
return false;
} }
failmsg("Expected ${cname} for argument '%%s'", name); };
return false;
}
""" % head_init_str) """ % head_init_str)
gen_template_mappable = Template(""" gen_template_mappable = Template("""
...@@ -121,27 +125,31 @@ static void pyopencv_${name}_dealloc(PyObject* self) ...@@ -121,27 +125,31 @@ static void pyopencv_${name}_dealloc(PyObject* self)
PyObject_Del(self); PyObject_Del(self);
} }
template<> PyObject* pyopencv_from(const Ptr<${cname}>& r) template<>
struct PyOpenCV_Converter< Ptr<${cname}> >
{ {
pyopencv_${name}_t *m = PyObject_NEW(pyopencv_${name}_t, &pyopencv_${name}_Type); static PyObject* from(const Ptr<${cname}>& r)
new (&(m->v)) Ptr<$cname1>(); // init Ptr with placement new {
m->v = r; pyopencv_${name}_t *m = PyObject_NEW(pyopencv_${name}_t, &pyopencv_${name}_Type);
return (PyObject*)m; new (&(m->v)) Ptr<$cname1>(); // init Ptr with placement new
} m->v = r;
return (PyObject*)m;
}
template<> bool pyopencv_to(PyObject* src, Ptr<${cname}>& dst, const char* name) static bool to(PyObject* src, Ptr<${cname}>& dst, const char* name)
{
if(!src || src == Py_None)
return true;
if(PyObject_TypeCheck(src, &pyopencv_${name}_Type))
{ {
dst = ((pyopencv_${name}_t*)src)->v.dynamicCast<${cname}>(); if(!src || src == Py_None)
return true; return true;
if(PyObject_TypeCheck(src, &pyopencv_${name}_Type))
{
dst = ((pyopencv_${name}_t*)src)->v.dynamicCast<${cname}>();
return true;
}
${mappable_code}
failmsg("Expected ${cname} for argument '%%s'", name);
return false;
} }
${mappable_code} };
failmsg("Expected ${cname} for argument '%%s'", name);
return false;
}
""" % head_init_str) """ % head_init_str)
......
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