123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154 |
- // This file is part of OpenCV project.
- // It is subject to the license terms in the LICENSE file found in the top-level directory
- // of this distribution and at http://opencv.org/license.html.
- #ifndef OPENCV_CORE_CVSTD_WRAPPER_HPP
- #define OPENCV_CORE_CVSTD_WRAPPER_HPP
- #include "opencv2/core/cvdef.h"
- #include <string>
- #include <memory> // std::shared_ptr
- #include <type_traits> // std::enable_if
- namespace cv {
- using std::nullptr_t;
- //! @addtogroup core_basic
- //! @{
- #ifdef CV_DOXYGEN
- template <typename _Tp> using Ptr = std::shared_ptr<_Tp>; // In ideal world it should look like this, but we need some compatibility workarounds below
- template<typename _Tp, typename ... A1> static inline
- Ptr<_Tp> makePtr(const A1&... a1) { return std::make_shared<_Tp>(a1...); }
- #else // cv::Ptr with compatibility workarounds
- // It should be defined for C-API types only.
- // C++ types should use regular "delete" operator.
- template<typename Y> struct DefaultDeleter;
- #if 0
- {
- void operator()(Y* p) const;
- };
- #endif
- namespace sfinae {
- template<typename C, typename Ret, typename... Args>
- struct has_parenthesis_operator
- {
- private:
- template<typename T>
- static CV_CONSTEXPR std::true_type check(typename std::is_same<typename std::decay<decltype(std::declval<T>().operator()(std::declval<Args>()...))>::type, Ret>::type*);
- template<typename> static CV_CONSTEXPR std::false_type check(...);
- typedef decltype(check<C>(0)) type;
- public:
- #if __cplusplus >= 201103L || (defined(_MSC_VER) && _MSC_VER >= 1900/*MSVS 2015*/)
- static CV_CONSTEXPR bool value = type::value;
- #else
- // support MSVS 2013
- static const int value = type::value;
- #endif
- };
- } // namespace sfinae
- template <typename T, typename = void>
- struct has_custom_delete
- : public std::false_type {};
- // Force has_custom_delete to std::false_type when NVCC is compiling CUDA source files
- #ifndef __CUDACC__
- 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 {};
- #endif
- template<typename T>
- struct Ptr : public std::shared_ptr<T>
- {
- #if 0
- using std::shared_ptr<T>::shared_ptr; // GCC 5.x can't handle this
- #else
- inline Ptr() CV_NOEXCEPT : std::shared_ptr<T>() {}
- inline Ptr(nullptr_t) CV_NOEXCEPT : std::shared_ptr<T>(nullptr) {}
- template<typename Y, typename D> inline Ptr(Y* p, D d) : std::shared_ptr<T>(p, d) {}
- template<typename D> inline Ptr(nullptr_t, D d) : std::shared_ptr<T>(nullptr, d) {}
- template<typename Y> inline Ptr(const Ptr<Y>& r, T* ptr) CV_NOEXCEPT : std::shared_ptr<T>(r, ptr) {}
- inline Ptr(const Ptr<T>& o) CV_NOEXCEPT : std::shared_ptr<T>(o) {}
- inline Ptr(Ptr<T>&& o) CV_NOEXCEPT : std::shared_ptr<T>(std::move(o)) {}
- template<typename Y> inline Ptr(const Ptr<Y>& o) CV_NOEXCEPT : std::shared_ptr<T>(o) {}
- template<typename Y> inline Ptr(Ptr<Y>&& o) CV_NOEXCEPT : std::shared_ptr<T>(std::move(o)) {}
- #endif
- 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)) {}
- // Overload with custom DefaultDeleter: Ptr<IplImage>(...)
- 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>
- 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>
- 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>
- inline void reset(const std::false_type&, Y* ptr) { std::shared_ptr<T>::reset(ptr); }
- template<typename Y>
- 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); }
- void reset() CV_NOEXCEPT { std::shared_ptr<T>::reset(); }
- Ptr& operator=(const Ptr& o) { std::shared_ptr<T>::operator =(o); return *this; }
- template<typename Y> inline Ptr& operator=(const Ptr<Y>& o) { std::shared_ptr<T>::operator =(o); return *this; }
- T* operator->() const CV_NOEXCEPT { return std::shared_ptr<T>::get();}
- typename std::add_lvalue_reference<T>::type operator*() const CV_NOEXCEPT { return *std::shared_ptr<T>::get(); }
- // OpenCV 3.x methods (not a part of standard C++ library)
- inline void release() { std::shared_ptr<T>::reset(); }
- inline operator T* () const { return std::shared_ptr<T>::get(); }
- inline bool empty() const { return std::shared_ptr<T>::get() == nullptr; }
- template<typename Y> inline
- Ptr<Y> staticCast() const CV_NOEXCEPT { return std::static_pointer_cast<Y>(*this); }
- template<typename Y> inline
- Ptr<Y> constCast() const CV_NOEXCEPT { return std::const_pointer_cast<Y>(*this); }
- template<typename Y> inline
- Ptr<Y> dynamicCast() const CV_NOEXCEPT { return std::dynamic_pointer_cast<Y>(*this); }
- };
- template<typename _Tp, typename ... A1> static inline
- Ptr<_Tp> makePtr(const A1&... a1)
- {
- static_assert( !has_custom_delete<_Tp>::value, "Can't use this makePtr with custom DefaultDeleter");
- return (Ptr<_Tp>)std::make_shared<_Tp>(a1...);
- }
- #endif // CV_DOXYGEN
- //! @} core_basic
- } // cv
- #endif //OPENCV_CORE_CVSTD_WRAPPER_HPP
|