From 89720ae24d818c32959a5cb88e6e7706993c6ed3 Mon Sep 17 00:00:00 2001 From: Alexander Alekhin Date: Sat, 8 Sep 2018 07:33:23 +0000 Subject: [PATCH] python: fix "unsigned int" / "size_t" overloading conflict --- modules/python/src2/cv2.cpp | 106 ++++++++++++++++++------------------ modules/python/src2/gen2.py | 72 +++++++++++++----------- 2 files changed, 94 insertions(+), 84 deletions(-) diff --git a/modules/python/src2/cv2.cpp b/modules/python/src2/cv2.cpp index 1d06d3074d..baafe7f2b7 100644 --- a/modules/python/src2/cv2.cpp +++ b/modules/python/src2/cv2.cpp @@ -10,6 +10,22 @@ #pragma warning(pop) #endif +#include // std::enable_if + +template // 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 static +bool pyopencv_to(PyObject* obj, T& p, const char* name = "") { return PyOpenCV_Converter::to(obj, p, name); } + +template static +PyObject* pyopencv_from(const T& src) { return PyOpenCV_Converter::from(src); } + + #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 @@ -28,8 +44,6 @@ #endif #define CV_PY_TO_CLASS(TYPE) \ -template<> bool pyopencv_to(PyObject* dst, Ptr& src, const char* name); \ - \ template<> \ 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) \ -template<> PyObject* pyopencv_from(const Ptr& src); \ - \ template<> \ PyObject* pyopencv_from(const TYPE& src) \ { \ @@ -55,8 +67,6 @@ PyObject* pyopencv_from(const TYPE& src) } #define CV_PY_TO_CLASS_PTR(TYPE) \ -template<> bool pyopencv_to(PyObject* dst, Ptr& src, const char* name); \ - \ template<> \ 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) \ -template<> PyObject* pyopencv_from(const Ptr& src); \ - \ static PyObject* pyopencv_from(TYPE*& src) \ { \ return pyopencv_from(Ptr(src)); \ } #define CV_PY_TO_ENUM(TYPE) \ -template<> bool pyopencv_to(PyObject* dst, std::underlying_type::type& src, const char* name); \ - \ template<> \ 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) \ -template<> PyObject* pyopencv_from(const std::underlying_type::type& src); \ - \ template<> \ PyObject* pyopencv_from(const TYPE& src) \ { \ @@ -302,12 +306,6 @@ public: NumpyAllocator g_numpyAllocator; -template static -bool pyopencv_to(PyObject* obj, T& p, const char* name = ""); - -template static -PyObject* pyopencv_from(const T& src); - enum { ARG_NONE = 0, ARG_MAT = 1, ARG_SCALAR = 2 }; // 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) return pyopencv_to(o, mx, ArgInfo(name, 0)); } -template -bool pyopencv_to(PyObject *o, Ptr& p, const char *name) -{ - if (!o || o == Py_None) - return true; - p = makePtr(); - return pyopencv_to(o, *p, name); -} - template<> PyObject* pyopencv_from(const Mat& m) { @@ -547,12 +536,22 @@ PyObject* pyopencv_from(const Matx<_Tp, m, n>& matx) } template -PyObject* pyopencv_from(const cv::Ptr& p) +struct PyOpenCV_Converter< cv::Ptr > { - if (!p) - Py_RETURN_NONE; - return pyopencv_from(*p); -} + static PyObject* from(const cv::Ptr& p) + { + if (!p) + Py_RETURN_NONE; + return pyopencv_from(*p); + } + static bool to(PyObject *o, Ptr& p, const char *name) + { + if (!o || o == Py_None) + return true; + p = makePtr(); + return pyopencv_to(o, *p, name); + } +}; template<> bool pyopencv_to(PyObject* obj, void*& ptr, const char* name) @@ -674,28 +673,31 @@ bool pyopencv_to(PyObject* obj, int& value, const char* name) return value != -1 || !PyErr_Occurred(); } -#if defined (_M_AMD64) || defined (__x86_64__) || defined (__PPC64__) -template<> -PyObject* pyopencv_from(const unsigned int& value) +// There is conflict between "size_t" and "unsigned int". +// They are the same type on some 32-bit platforms. +template +struct PyOpenCV_Converter + < T, typename std::enable_if< std::is_same::value && !std::is_same::value >::type > { - return PyLong_FromUnsignedLong(value); -} + static inline PyObject* from(const unsigned int& value) + { + return PyLong_FromUnsignedLong(value); + } -template<> -bool pyopencv_to(PyObject* obj, unsigned int& value, const char* name) -{ - CV_UNUSED(name); - if(!obj || obj == Py_None) - return true; - if(PyInt_Check(obj)) - value = (unsigned int)PyInt_AsLong(obj); - else if(PyLong_Check(obj)) - value = (unsigned int)PyLong_AsLong(obj); - else - return false; - return value != (unsigned int)-1 || !PyErr_Occurred(); -} -#endif + static inline bool to(PyObject* obj, unsigned int& value, const char* name) + { + CV_UNUSED(name); + if(!obj || obj == Py_None) + return true; + if(PyInt_Check(obj)) + value = (unsigned int)PyInt_AsLong(obj); + else if(PyLong_Check(obj)) + value = (unsigned int)PyLong_AsLong(obj); + else + return false; + return value != (unsigned int)-1 || !PyErr_Occurred(); + } +}; template<> PyObject* pyopencv_from(const uchar& value) diff --git a/modules/python/src2/gen2.py b/modules/python/src2/gen2.py index 8dcce91ed7..9830d9637c 100755 --- a/modules/python/src2/gen2.py +++ b/modules/python/src2/gen2.py @@ -70,25 +70,29 @@ static void pyopencv_${name}_dealloc(PyObject* 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); - new (&m->v) ${cname}(r); //Copy constructor - return (PyObject*)m; -} + static PyObject* from(const ${cname}& r) + { + 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) -{ - if(!src || src == Py_None) - return true; - if(PyObject_TypeCheck(src, &pyopencv_${name}_Type)) + static bool to(PyObject* src, ${cname}& dst, const char* name) { - dst = ((pyopencv_${name}_t*)src)->v; - return true; + if(!src || src == Py_None) + 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) gen_template_mappable = Template(""" @@ -121,27 +125,31 @@ static void pyopencv_${name}_dealloc(PyObject* 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); - new (&(m->v)) Ptr<$cname1>(); // init Ptr with placement new - m->v = r; - return (PyObject*)m; -} + static PyObject* from(const Ptr<${cname}>& r) + { + pyopencv_${name}_t *m = PyObject_NEW(pyopencv_${name}_t, &pyopencv_${name}_Type); + 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) -{ - if(!src || src == Py_None) - return true; - if(PyObject_TypeCheck(src, &pyopencv_${name}_Type)) + static bool to(PyObject* src, Ptr<${cname}>& dst, const char* name) { - dst = ((pyopencv_${name}_t*)src)->v.dynamicCast<${cname}>(); - return true; + if(!src || src == Py_None) + 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)