1 | // This file is part of OpenCV project. |
2 | // It is subject to the license terms in the LICENSE file found in the top-level directory |
3 | // of this distribution and at http://opencv.org/license.html. |
4 | |
5 | #ifndef OPENCV_CORE_CVSTD_WRAPPER_HPP |
6 | #define OPENCV_CORE_CVSTD_WRAPPER_HPP |
7 | |
8 | #include "opencv2/core/cvdef.h" |
9 | |
10 | #include <string> |
11 | #include <memory> // std::shared_ptr |
12 | #include <type_traits> // std::enable_if |
13 | |
14 | namespace cv { |
15 | |
16 | using std::nullptr_t; |
17 | |
18 | //! @addtogroup core_basic |
19 | //! @{ |
20 | |
21 | #ifdef CV_DOXYGEN |
22 | |
23 | template <typename _Tp> using Ptr = std::shared_ptr<_Tp>; // In ideal world it should look like this, but we need some compatibility workarounds below |
24 | |
25 | template<typename _Tp, typename ... A1> static inline |
26 | Ptr<_Tp> makePtr(const A1&... a1) { return std::make_shared<_Tp>(a1...); } |
27 | |
28 | #else // cv::Ptr with compatibility workarounds |
29 | |
30 | // It should be defined for C-API types only. |
31 | // C++ types should use regular "delete" operator. |
32 | template<typename Y> struct DefaultDeleter; |
33 | #if 0 |
34 | { |
35 | void operator()(Y* p) const; |
36 | }; |
37 | #endif |
38 | |
39 | namespace sfinae { |
40 | template<typename C, typename Ret, typename... Args> |
41 | struct has_parenthesis_operator |
42 | { |
43 | private: |
44 | template<typename T> |
45 | static CV_CONSTEXPR std::true_type has_parenthesis_operator_check(typename std::is_same<typename std::decay<decltype(std::declval<T>().operator()(std::declval<Args>()...))>::type, Ret>::type*); |
46 | |
47 | template<typename> static CV_CONSTEXPR std::false_type has_parenthesis_operator_check(...); |
48 | |
49 | typedef decltype(has_parenthesis_operator_check<C>(0)) type; |
50 | |
51 | public: |
52 | #if __cplusplus >= 201103L || (defined(_MSC_VER) && _MSC_VER >= 1900/*MSVS 2015*/) |
53 | static CV_CONSTEXPR bool value = type::value; |
54 | #else |
55 | // support MSVS 2013 |
56 | static const int value = type::value; |
57 | #endif |
58 | }; |
59 | } // namespace sfinae |
60 | |
61 | template <typename T, typename = void> |
62 | struct has_custom_delete |
63 | : public std::false_type {}; |
64 | |
65 | // Force has_custom_delete to std::false_type when NVCC is compiling CUDA source files |
66 | #ifndef __CUDACC__ |
67 | template <typename T> |
68 | struct has_custom_delete<T, typename std::enable_if< sfinae::has_parenthesis_operator<DefaultDeleter<T>, void, T*>::value >::type > |
69 | : public std::true_type {}; |
70 | #endif |
71 | |
72 | template<typename T> |
73 | struct Ptr : public std::shared_ptr<T> |
74 | { |
75 | #if 0 |
76 | using std::shared_ptr<T>::shared_ptr; // GCC 5.x can't handle this |
77 | #else |
78 | inline Ptr() CV_NOEXCEPT : std::shared_ptr<T>() {} |
79 | inline Ptr(nullptr_t) CV_NOEXCEPT : std::shared_ptr<T>(nullptr) {} |
80 | template<typename Y, typename D> inline Ptr(Y* p, D d) : std::shared_ptr<T>(p, d) {} |
81 | template<typename D> inline Ptr(nullptr_t, D d) : std::shared_ptr<T>(nullptr, d) {} |
82 | |
83 | template<typename Y> inline Ptr(const Ptr<Y>& r, T* ptr) CV_NOEXCEPT : std::shared_ptr<T>(r, ptr) {} |
84 | |
85 | inline Ptr(const Ptr<T>& o) CV_NOEXCEPT : std::shared_ptr<T>(o) {} |
86 | inline Ptr(Ptr<T>&& o) CV_NOEXCEPT : std::shared_ptr<T>(std::move(o)) {} |
87 | |
88 | template<typename Y> inline Ptr(const Ptr<Y>& o) CV_NOEXCEPT : std::shared_ptr<T>(o) {} |
89 | template<typename Y> inline Ptr(Ptr<Y>&& o) CV_NOEXCEPT : std::shared_ptr<T>(std::move(o)) {} |
90 | #endif |
91 | inline Ptr(const std::shared_ptr<T>& o) CV_NOEXCEPT : std::shared_ptr<T>(o) {} |
92 | inline Ptr(std::shared_ptr<T>&& o) CV_NOEXCEPT : std::shared_ptr<T>(std::move(o)) {} |
93 | |
94 | // Overload with custom DefaultDeleter: Ptr<IplImage>(...) |
95 | template<typename Y> |
96 | inline Ptr(const std::true_type&, Y* ptr) : std::shared_ptr<T>(ptr, DefaultDeleter<Y>()) {} |
97 | |
98 | // Overload without custom deleter: Ptr<std::string>(...); |
99 | template<typename Y> |
100 | inline Ptr(const std::false_type&, Y* ptr) : std::shared_ptr<T>(ptr) {} |
101 | |
102 | template<typename Y = T> |
103 | inline Ptr(Y* ptr) : Ptr(has_custom_delete<Y>(), ptr) {} |
104 | |
105 | // Overload with custom DefaultDeleter: Ptr<IplImage>(...) |
106 | template<typename Y> |
107 | inline void reset(const std::true_type&, Y* ptr) { std::shared_ptr<T>::reset(ptr, DefaultDeleter<Y>()); } |
108 | |
109 | // Overload without custom deleter: Ptr<std::string>(...); |
110 | template<typename Y> |
111 | inline void reset(const std::false_type&, Y* ptr) { std::shared_ptr<T>::reset(ptr); } |
112 | |
113 | template<typename Y> |
114 | inline void reset(Y* ptr) { Ptr<T>::reset(has_custom_delete<Y>(), ptr); } |
115 | |
116 | template<class Y, class Deleter> |
117 | void reset(Y* ptr, Deleter d) { std::shared_ptr<T>::reset(ptr, d); } |
118 | |
119 | void reset() CV_NOEXCEPT { std::shared_ptr<T>::reset(); } |
120 | |
121 | Ptr& operator=(const Ptr& o) { std::shared_ptr<T>::operator =(o); return *this; } |
122 | template<typename Y> inline Ptr& operator=(const Ptr<Y>& o) { std::shared_ptr<T>::operator =(o); return *this; } |
123 | |
124 | T* operator->() const CV_NOEXCEPT { return std::shared_ptr<T>::get();} |
125 | typename std::add_lvalue_reference<T>::type operator*() const CV_NOEXCEPT { return *std::shared_ptr<T>::get(); } |
126 | |
127 | // OpenCV 3.x methods (not a part of standard C++ library) |
128 | inline void release() { std::shared_ptr<T>::reset(); } |
129 | inline operator T* () const { return std::shared_ptr<T>::get(); } |
130 | inline bool empty() const { return std::shared_ptr<T>::get() == nullptr; } |
131 | |
132 | template<typename Y> inline |
133 | Ptr<Y> staticCast() const CV_NOEXCEPT { return std::static_pointer_cast<Y>(*this); } |
134 | |
135 | template<typename Y> inline |
136 | Ptr<Y> constCast() const CV_NOEXCEPT { return std::const_pointer_cast<Y>(*this); } |
137 | |
138 | template<typename Y> inline |
139 | Ptr<Y> dynamicCast() const CV_NOEXCEPT { return std::dynamic_pointer_cast<Y>(*this); } |
140 | }; |
141 | |
142 | template<typename _Tp, typename ... A1> static inline |
143 | Ptr<_Tp> makePtr(const A1&... a1) |
144 | { |
145 | static_assert( !has_custom_delete<_Tp>::value, "Can't use this makePtr with custom DefaultDeleter" ); |
146 | return (Ptr<_Tp>)std::make_shared<_Tp>(a1...); |
147 | } |
148 | |
149 | #endif // CV_DOXYGEN |
150 | |
151 | //! @} core_basic |
152 | } // cv |
153 | |
154 | #endif //OPENCV_CORE_CVSTD_WRAPPER_HPP |
155 | |