core: change cv::Ptr DefaultDeleter
authorAlexander Alekhin <alexander.a.alekhin@gmail.com>
Wed, 12 Sep 2018 09:52:50 +0000 (09:52 +0000)
committerAlexander Alekhin <alexander.a.alekhin@gmail.com>
Wed, 12 Sep 2018 12:20:15 +0000 (12:20 +0000)
12 files changed:
apps/traincascade/old_ml.hpp
apps/traincascade/old_ml_tree.cpp
modules/core/include/opencv2/core/core_c.h
modules/core/include/opencv2/core/cvstd_wrapper.hpp
modules/core/include/opencv2/core/persistence.hpp
modules/core/src/array.cpp
modules/core/test/test_ptr.cpp
modules/objdetect/include/opencv2/objdetect.hpp
modules/objdetect/src/cascadedetect.cpp
modules/photo/src/inpaint.cpp
modules/videoio/include/opencv2/videoio.hpp
modules/videoio/src/cap.cpp

index 3ad739d..75a5d9f 100644 (file)
@@ -2033,7 +2033,8 @@ typedef CvANN_MLP NeuralNet_MLP;
 typedef CvGBTreesParams GradientBoostingTreeParams;
 typedef CvGBTrees GradientBoostingTrees;
 
-template<> void DefaultDeleter<CvDTreeSplit>::operator ()(CvDTreeSplit* obj) const;
+template<> struct DefaultDeleter<CvDTreeSplit>{ void operator ()(CvDTreeSplit* obj) const; };
+
 }
 
 #endif // __cplusplus
index d4826b8..cfba9ec 100644 (file)
@@ -1880,10 +1880,7 @@ double CvDTree::calc_node_dir( CvDTreeNode* node )
 namespace cv
 {
 
-template<> void DefaultDeleter<CvDTreeSplit>::operator ()(CvDTreeSplit* obj) const
-{
-    fastFree(obj);
-}
+void DefaultDeleter<CvDTreeSplit>::operator ()(CvDTreeSplit* obj) const { fastFree(obj); }
 
 DTreeBestSplitFinder::DTreeBestSplitFinder( CvDTree* _tree, CvDTreeNode* _node)
 {
index e5fe516..9151397 100644 (file)
@@ -2805,11 +2805,11 @@ CV_EXPORTS void insertImageCOI(InputArray coiimg, CvArr* arr, int coi=-1);
 
 ////// specialized implementations of DefaultDeleter::operator() for classic OpenCV types //////
 
-template<> CV_EXPORTS void DefaultDeleter<CvMat>::operator ()(CvMat* obj) const;
-template<> CV_EXPORTS void DefaultDeleter<IplImage>::operator ()(IplImage* obj) const;
-template<> CV_EXPORTS void DefaultDeleter<CvMatND>::operator ()(CvMatND* obj) const;
-template<> CV_EXPORTS void DefaultDeleter<CvSparseMat>::operator ()(CvSparseMat* obj) const;
-template<> CV_EXPORTS void DefaultDeleter<CvMemStorage>::operator ()(CvMemStorage* obj) const;
+template<> struct DefaultDeleter<CvMat>{ CV_EXPORTS void operator ()(CvMat* obj) const; };
+template<> struct DefaultDeleter<IplImage>{ CV_EXPORTS void operator ()(IplImage* obj) const; };
+template<> struct DefaultDeleter<CvMatND>{ CV_EXPORTS void operator ()(CvMatND* obj) const; };
+template<> struct DefaultDeleter<CvSparseMat>{ CV_EXPORTS void operator ()(CvSparseMat* obj) const; };
+template<> struct DefaultDeleter<CvMemStorage>{ CV_EXPORTS void operator ()(CvMemStorage* obj) const; };
 
 ////////////// convenient wrappers for operating old-style dynamic structures //////////////
 
index 0a30432..e950660 100644 (file)
@@ -27,15 +27,14 @@ Ptr<_Tp> makePtr(const A1&... a1) { return std::make_shared<_Tp>(a1...); }
 
 #else  // cv::Ptr with compatibility workarounds
 
-template<typename Y>
-struct DefaultDeleter
+// It should be defined for C-API types only.
+// C++ types should use regular "delete" operator.
+template<typename Y> struct DefaultDeleter;
+#if 0
 {
-#ifndef _MSC_VER
-    void operator()(Y* p) const = delete;  // not available by default; enabled for specializations only
-#else
-    void operator()(Y* p) const { delete p; }
-#endif
+    void operator()(Y* p) const;
 };
+#endif
 
 namespace sfinae {
 template<typename C, typename Ret, typename... Args>
@@ -54,7 +53,14 @@ public:
 };
 } // namespace sfinae
 
-template <typename Y> using has_custom_delete = sfinae::has_parenthesis_operator<DefaultDeleter<Y>, void, Y*>;
+template <typename T, typename = void>
+struct has_custom_delete
+        : public std::false_type {};
+
+template <typename T>
+struct has_custom_delete<T, typename std::enable_if< sfinae::has_parenthesis_operator<DefaultDeleter<T>, void, T*>::value >::type >
+        : public std::true_type {};
+
 
 template<typename T>
 struct Ptr : public std::shared_ptr<T>
@@ -78,29 +84,27 @@ struct Ptr : public std::shared_ptr<T>
     inline Ptr(const std::shared_ptr<T>& o) CV_NOEXCEPT : std::shared_ptr<T>(o) {}
     inline Ptr(std::shared_ptr<T>&& o) CV_NOEXCEPT : std::shared_ptr<T>(std::move(o)) {}
 
-#ifndef _MSC_VER
     // Overload with custom DefaultDeleter: Ptr<IplImage>(...)
-    template<typename Y = T, class = typename std::enable_if< has_custom_delete<Y>::value >::type>
-    inline Ptr(Y* ptr) : std::shared_ptr<T>(ptr, DefaultDeleter<Y>()) {}
+    template<typename Y>
+    inline Ptr(const std::true_type&, Y* ptr) : std::shared_ptr<T>(ptr, DefaultDeleter<Y>()) {}
 
     // Overload without custom deleter: Ptr<std::string>(...);
-    template<typename Y = T, int = sizeof(typename std::enable_if< !has_custom_delete<Y>::value, int >::type) >
-    inline Ptr(Y* ptr) : std::shared_ptr<T>(ptr) {}
+    template<typename Y>
+    inline Ptr(const std::false_type&, Y* ptr) : std::shared_ptr<T>(ptr) {}
+
+    template<typename Y = T>
+    inline Ptr(Y* ptr) : Ptr(has_custom_delete<Y>(), ptr) {}
 
     // Overload with custom DefaultDeleter: Ptr<IplImage>(...)
-    template<typename Y, class = typename std::enable_if< has_custom_delete<Y>::value >::type>
-    inline void reset(Y* ptr) { std::shared_ptr<T>::reset(ptr, DefaultDeleter<Y>()); }
+    template<typename Y>
+    inline void reset(const std::true_type&, Y* ptr) { std::shared_ptr<T>::reset(ptr, DefaultDeleter<Y>()); }
 
     // Overload without custom deleter: Ptr<std::string>(...);
-    template<typename Y, int = sizeof(typename std::enable_if< !has_custom_delete<Y>::value, int >::type) >
-    inline void reset(Y* ptr) { std::shared_ptr<T>::reset(ptr); }
-#else
     template<typename Y>
-    inline Ptr(Y* ptr) : std::shared_ptr<T>(ptr, DefaultDeleter<Y>()) {}
+    inline void reset(const std::false_type&, Y* ptr) { std::shared_ptr<T>::reset(ptr); }
 
     template<typename Y>
-    inline void reset(Y* ptr) { std::shared_ptr<T>::reset(ptr, DefaultDeleter<Y>()); }
-#endif
+    inline void reset(Y* ptr) { Ptr<T>::reset(has_custom_delete<Y>(), ptr); }
 
     template<class Y, class Deleter>
     void reset(Y* ptr, Deleter d) { std::shared_ptr<T>::reset(ptr, d); }
@@ -131,12 +135,8 @@ struct Ptr : public std::shared_ptr<T>
 template<typename _Tp, typename ... A1> static inline
 Ptr<_Tp> makePtr(const A1&... a1)
 {
-#ifndef _MSC_VER
     static_assert( !has_custom_delete<_Tp>::value, "Can't use this makePtr with custom DefaultDeleter");
     return (Ptr<_Tp>)std::make_shared<_Tp>(a1...);
-#else
-    return Ptr<_Tp>(new _Tp(a1...), DefaultDeleter<_Tp>());
-#endif
 }
 
 #endif // CV_DOXYGEN
index 790dde8..22e611e 100644 (file)
@@ -475,7 +475,7 @@ public:
     int state; //!< the writer state
 };
 
-template<> CV_EXPORTS void DefaultDeleter<CvFileStorage>::operator ()(CvFileStorage* obj) const;
+template<> struct DefaultDeleter<CvFileStorage>{ CV_EXPORTS void operator ()(CvFileStorage* obj) const; };
 
 /** @brief File Storage Node class.
 
index 49b533b..7c85ed9 100644 (file)
@@ -3205,23 +3205,12 @@ cvCheckTermCriteria( CvTermCriteria criteria, double default_eps,
 namespace cv
 {
 
-template<> void DefaultDeleter<CvMat>::operator ()(CvMat* obj) const
-{ cvReleaseMat(&obj); }
-
-template<> void DefaultDeleter<IplImage>::operator ()(IplImage* obj) const
-{ cvReleaseImage(&obj); }
-
-template<> void DefaultDeleter<CvMatND>::operator ()(CvMatND* obj) const
-{ cvReleaseMatND(&obj); }
-
-template<> void DefaultDeleter<CvSparseMat>::operator ()(CvSparseMat* obj) const
-{ cvReleaseSparseMat(&obj); }
-
-template<> void DefaultDeleter<CvMemStorage>::operator ()(CvMemStorage* obj) const
-{ cvReleaseMemStorage(&obj); }
-
-template<> void DefaultDeleter<CvFileStorage>::operator ()(CvFileStorage* obj) const
-{ cvReleaseFileStorage(&obj); }
+void DefaultDeleter<CvMat>::operator ()(CvMat* obj) const { cvReleaseMat(&obj); }
+void DefaultDeleter<IplImage>::operator ()(IplImage* obj) const { cvReleaseImage(&obj); }
+void DefaultDeleter<CvMatND>::operator ()(CvMatND* obj) const { cvReleaseMatND(&obj); }
+void DefaultDeleter<CvSparseMat>::operator ()(CvSparseMat* obj) const { cvReleaseSparseMat(&obj); }
+void DefaultDeleter<CvMemStorage>::operator ()(CvMemStorage* obj) const { cvReleaseMemStorage(&obj); }
+void DefaultDeleter<CvFileStorage>::operator ()(CvFileStorage* obj) const { cvReleaseFileStorage(&obj); }
 
 template <typename T> static inline
 void scalarToRawData_(const Scalar& s, T * const buf, const int cn, const int unroll_to)
index 24d947c..87fd559 100644 (file)
@@ -382,15 +382,14 @@ struct SpeciallyDeletable
     bool deleted;
 };
 
-}
+} // namespace
 
 namespace cv {
-
-template<>
-void DefaultDeleter<SpeciallyDeletable>::operator()(SpeciallyDeletable * obj) const
-{ obj->deleted = true; }
-
-}
+template<> struct DefaultDeleter<SpeciallyDeletable>
+{
+    void operator()(SpeciallyDeletable * obj) const { obj->deleted = true; }
+};
+} // namespace
 
 namespace opencv_test { namespace {
 
index 21eef23..f0396d9 100644 (file)
@@ -163,7 +163,7 @@ CV_EXPORTS   void groupRectangles_meanshift(std::vector<Rect>& rectList, std::ve
                                             std::vector<double>& foundScales,
                                             double detectThreshold = 0.0, Size winDetSize = Size(64, 128));
 
-template<> CV_EXPORTS void DefaultDeleter<CvHaarClassifierCascade>::operator ()(CvHaarClassifierCascade* obj) const;
+template<> struct DefaultDeleter<CvHaarClassifierCascade>{ CV_EXPORTS void operator ()(CvHaarClassifierCascade* obj) const; };
 
 enum { CASCADE_DO_CANNY_PRUNING    = 1,
        CASCADE_SCALE_IMAGE         = 2,
index d39d47d..f506341 100644 (file)
@@ -1603,8 +1603,7 @@ bool CascadeClassifierImpl::read_(const FileNode& root)
     return featureEvaluator->read(fn, data.origWinSize);
 }
 
-template<> void DefaultDeleter<CvHaarClassifierCascade>::operator ()(CvHaarClassifierCascade* obj) const
-{ cvReleaseHaarClassifierCascade(&obj); }
+void DefaultDeleter<CvHaarClassifierCascade>::operator ()(CvHaarClassifierCascade* obj) const { cvReleaseHaarClassifierCascade(&obj); }
 
 
 BaseCascadeClassifier::~BaseCascadeClassifier()
index adab6a3..b5472c5 100644 (file)
@@ -724,10 +724,7 @@ icvNSInpaintFMM(const CvMat *f, CvMat *t, CvMat *out, int range, CvPriorityQueue
    }
 
 namespace cv {
-template<> void cv::DefaultDeleter<IplConvKernel>::operator ()(IplConvKernel* obj) const
-{
-  cvReleaseStructuringElement(&obj);
-}
+template<> struct DefaultDeleter<IplConvKernel>{ void operator ()(IplConvKernel* obj) const { cvReleaseStructuringElement(&obj); } };
 }
 
 void
index bb4e398..968dd1f 100644 (file)
@@ -954,8 +954,8 @@ protected:
                                     Size frameSize, bool isColor = true);
 };
 
-template<> CV_EXPORTS void DefaultDeleter<CvCapture>::operator ()(CvCapture* obj) const;
-template<> CV_EXPORTS void DefaultDeleter<CvVideoWriter>::operator ()(CvVideoWriter* obj) const;
+template<> struct DefaultDeleter<CvCapture>{ CV_EXPORTS void operator ()(CvCapture* obj) const; };
+template<> struct DefaultDeleter<CvVideoWriter>{ CV_EXPORTS void operator ()(CvVideoWriter* obj) const; };
 
 //! @} videoio
 
index 9c14be0..b7cf851 100644 (file)
 
 namespace cv {
 
-template<> void DefaultDeleter<CvCapture>::operator ()(CvCapture* obj) const
-{ cvReleaseCapture(&obj); }
-
-template<> void DefaultDeleter<CvVideoWriter>::operator ()(CvVideoWriter* obj) const
-{ cvReleaseVideoWriter(&obj); }
-
+void DefaultDeleter<CvCapture>::operator ()(CvCapture* obj) const { cvReleaseCapture(&obj); }
+void DefaultDeleter<CvVideoWriter>::operator ()(CvVideoWriter* obj) const { cvReleaseVideoWriter(&obj); }
 
 
 VideoCapture::VideoCapture()