| |
| |
| |
| |
| |
|
|
|
|
| #ifndef OPENCV_GAPI_UTIL_ANY_HPP |
| #define OPENCV_GAPI_UTIL_ANY_HPP |
|
|
| #include <memory> |
| #include <type_traits> |
| #include <typeinfo> |
| #include <utility> |
|
|
| #include "opencv2/gapi/util/throw.hpp" |
|
|
| #if defined(_MSC_VER) |
| |
| # pragma warning(disable: 4521) |
| #endif |
|
|
| namespace cv |
| { |
|
|
| namespace internal |
| { |
| template <class T, class Source> |
| T down_cast(Source operand) |
| { |
| #if defined(__GXX_RTTI) || defined(_CPPRTTI) |
| return dynamic_cast<T>(operand); |
| #else |
| #warning used static cast instead of dynamic because RTTI is disabled |
| return static_cast<T>(operand); |
| #endif |
| } |
| } |
|
|
| namespace util |
| { |
| class bad_any_cast : public std::bad_cast |
| { |
| public: |
| virtual const char* what() const noexcept override |
| { |
| return "Bad any cast"; |
| } |
| }; |
|
|
| |
|
|
| class any |
| { |
| private: |
| struct holder; |
| using holder_ptr = std::unique_ptr<holder>; |
| struct holder |
| { |
| virtual holder_ptr clone() = 0; |
| virtual ~holder() = default; |
| }; |
|
|
| template <typename value_t> |
| struct holder_impl : holder |
| { |
| value_t v; |
| template<typename arg_t> |
| holder_impl(arg_t&& a) : v(std::forward<arg_t>(a)) {} |
| holder_ptr clone() override { return holder_ptr(new holder_impl (v));} |
| }; |
|
|
| holder_ptr hldr; |
| public: |
| template<class value_t> |
| any(value_t&& arg) : hldr(new holder_impl<typename std::decay<value_t>::type>( std::forward<value_t>(arg))) {} |
|
|
| any(any const& src) : hldr( src.hldr ? src.hldr->clone() : nullptr) {} |
| |
| any(any & src) : any (const_cast<any const&>(src)) {} |
|
|
| any() = default; |
| any(any&& ) = default; |
|
|
| any& operator=(any&&) = default; |
|
|
| any& operator=(any const& src) |
| { |
| any copy(src); |
| swap(*this, copy); |
| return *this; |
| } |
|
|
| template<class value_t> |
| friend value_t* any_cast(any* operand); |
|
|
| template<class value_t> |
| friend const value_t* any_cast(const any* operand); |
|
|
| template<class value_t> |
| friend value_t& unsafe_any_cast(any& operand); |
|
|
| template<class value_t> |
| friend const value_t& unsafe_any_cast(const any& operand); |
|
|
| friend void swap(any & lhs, any& rhs) |
| { |
| swap(lhs.hldr, rhs.hldr); |
| } |
|
|
| }; |
|
|
| template<class value_t> |
| value_t* any_cast(any* operand) |
| { |
| auto casted = internal::down_cast<any::holder_impl<typename std::decay<value_t>::type> *>(operand->hldr.get()); |
| if (casted){ |
| return & (casted->v); |
| } |
| return nullptr; |
| } |
|
|
| template<class value_t> |
| const value_t* any_cast(const any* operand) |
| { |
| auto casted = internal::down_cast<any::holder_impl<typename std::decay<value_t>::type> *>(operand->hldr.get()); |
| if (casted){ |
| return & (casted->v); |
| } |
| return nullptr; |
| } |
|
|
| template<class value_t> |
| value_t& any_cast(any& operand) |
| { |
| auto ptr = any_cast<value_t>(&operand); |
| if (ptr) |
| { |
| return *ptr; |
| } |
|
|
| throw_error(bad_any_cast()); |
| } |
|
|
|
|
| template<class value_t> |
| const value_t& any_cast(const any& operand) |
| { |
| auto ptr = any_cast<value_t>(&operand); |
| if (ptr) |
| { |
| return *ptr; |
| } |
|
|
| throw_error(bad_any_cast()); |
| } |
|
|
| template<class value_t> |
| inline value_t& unsafe_any_cast(any& operand) |
| { |
| #ifdef DEBUG |
| return any_cast<value_t>(operand); |
| #else |
| return static_cast<any::holder_impl<typename std::decay<value_t>::type> *>(operand.hldr.get())->v; |
| #endif |
| } |
|
|
| template<class value_t> |
| inline const value_t& unsafe_any_cast(const any& operand) |
| { |
| #ifdef DEBUG |
| return any_cast<value_t>(operand); |
| #else |
| return static_cast<any::holder_impl<typename std::decay<value_t>::type> *>(operand.hldr.get())->v; |
| #endif |
| } |
|
|
| } |
| } |
|
|
| #if defined(_MSC_VER) |
| |
| # pragma warning(default: 4521) |
| #endif |
|
|
| #endif |
|
|