123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190 |
- // 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 <memory>
- #include <type_traits>
- #include <typeinfo>
- #include <utility>
- #include <opencv2/gapi/util/throw.hpp>
- #if defined(_MSC_VER)
- // disable MSVC warning on "multiple copy constructors specified"
- # 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
- #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<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";
- }
- };
- //modeled against C++17 std::any
- 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) {}
- //simple hack in order not to write enable_if<not any> for the template constructor
- 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
- }
- } // 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
|