// 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. // // Copyright (C) 2018 Intel Corporation #ifndef OPENCV_GAPI_UTIL_ANY_HPP #define OPENCV_GAPI_UTIL_ANY_HPP #include #include #include #include #include #if defined(_MSC_VER) // disable MSVC warning on "multiple copy constructors specified" # pragma warning(disable: 4521) #endif namespace cv { namespace internal { template T down_cast(Source operand) { #if defined(__GXX_RTTI) || defined(_CPPRTTI) return dynamic_cast(operand); #else #ifdef __GNUC__ #warning used static cast instead of dynamic because RTTI is disabled #else #pragma message("WARNING: used static cast instead of dynamic because RTTI is disabled") #endif return static_cast(operand); #endif } } namespace util { class bad_any_cast : public std::bad_cast { public: virtual const char* what() const noexcept override { return "Bad any cast"; } }; //modeled against C++17 std::any class any { private: struct holder; using holder_ptr = std::unique_ptr; struct holder { virtual holder_ptr clone() = 0; virtual ~holder() = default; }; template struct holder_impl : holder { value_t v; template holder_impl(arg_t&& a) : v(std::forward(a)) {} holder_ptr clone() override { return holder_ptr(new holder_impl (v));} }; holder_ptr hldr; public: template any(value_t&& arg) : hldr(new holder_impl::type>( std::forward(arg))) {} any(any const& src) : hldr( src.hldr ? src.hldr->clone() : nullptr) {} //simple hack in order not to write enable_if for the template constructor any(any & src) : any (const_cast(src)) {} any() = default; any(any&& ) = default; any& operator=(any&&) = default; any& operator=(any const& src) { any copy(src); swap(*this, copy); return *this; } template friend value_t* any_cast(any* operand); template friend const value_t* any_cast(const any* operand); template friend value_t& unsafe_any_cast(any& operand); template friend const value_t& unsafe_any_cast(const any& operand); friend void swap(any & lhs, any& rhs) { swap(lhs.hldr, rhs.hldr); } }; template value_t* any_cast(any* operand) { auto casted = internal::down_cast::type> *>(operand->hldr.get()); if (casted){ return & (casted->v); } return nullptr; } template const value_t* any_cast(const any* operand) { auto casted = internal::down_cast::type> *>(operand->hldr.get()); if (casted){ return & (casted->v); } return nullptr; } template value_t& any_cast(any& operand) { auto ptr = any_cast(&operand); if (ptr) { return *ptr; } throw_error(bad_any_cast()); } template const value_t& any_cast(const any& operand) { auto ptr = any_cast(&operand); if (ptr) { return *ptr; } throw_error(bad_any_cast()); } template inline value_t& unsafe_any_cast(any& operand) { #ifdef DEBUG return any_cast(operand); #else return static_cast::type> *>(operand.hldr.get())->v; #endif } template inline const value_t& unsafe_any_cast(const any& operand) { #ifdef DEBUG return any_cast(operand); #else return static_cast::type> *>(operand.hldr.get())->v; #endif } } // namespace util } // namespace cv #if defined(_MSC_VER) // Enable "multiple copy constructors specified" back # pragma warning(default: 4521) #endif #endif // OPENCV_GAPI_UTIL_ANY_HPP