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.
5 // Copyright (C) 2018-2019 Intel Corporation
8 #ifndef OPENCV_GAPI_UTIL_ANY_HPP
9 #define OPENCV_GAPI_UTIL_ANY_HPP
12 #include <type_traits>
16 #include "opencv2/gapi/util/throw.hpp"
19 // disable MSVC warning on "multiple copy constructors specified"
20 # pragma warning(disable: 4521)
28 template <class T, class Source>
29 T down_cast(Source operand)
31 #if defined(__GXX_RTTI) || defined(_CPPRTTI)
32 return dynamic_cast<T>(operand);
34 #warning used static cast instead of dynamic because RTTI is disabled
35 return static_cast<T>(operand);
42 class bad_any_cast : public std::bad_cast
45 virtual const char* what() const noexcept override
47 return "Bad any cast";
51 //modeled against C++17 std::any
57 using holder_ptr = std::unique_ptr<holder>;
60 virtual holder_ptr clone() = 0;
61 virtual ~holder() = default;
64 template <typename value_t>
65 struct holder_impl : holder
68 template<typename arg_t>
69 holder_impl(arg_t&& a) : v(std::forward<arg_t>(a)) {}
70 holder_ptr clone() override { return holder_ptr(new holder_impl (v));}
75 template<class value_t>
76 any(value_t&& arg) : hldr(new holder_impl<typename std::decay<value_t>::type>( std::forward<value_t>(arg))) {}
78 any(any const& src) : hldr( src.hldr ? src.hldr->clone() : nullptr) {}
79 //simple hack in order not to write enable_if<not any> for the template constructor
80 any(any & src) : any (const_cast<any const&>(src)) {}
83 any(any&& ) = default;
85 any& operator=(any&&) = default;
87 any& operator=(any const& src)
94 template<class value_t>
95 friend value_t* any_cast(any* operand);
97 template<class value_t>
98 friend const value_t* any_cast(const any* operand);
100 template<class value_t>
101 friend value_t& unsafe_any_cast(any& operand);
103 template<class value_t>
104 friend const value_t& unsafe_any_cast(const any& operand);
106 friend void swap(any & lhs, any& rhs)
108 swap(lhs.hldr, rhs.hldr);
113 template<class value_t>
114 value_t* any_cast(any* operand)
116 auto casted = internal::down_cast<any::holder_impl<typename std::decay<value_t>::type> *>(operand->hldr.get());
118 return & (casted->v);
123 template<class value_t>
124 const value_t* any_cast(const any* operand)
126 auto casted = internal::down_cast<any::holder_impl<typename std::decay<value_t>::type> *>(operand->hldr.get());
128 return & (casted->v);
133 template<class value_t>
134 value_t& any_cast(any& operand)
136 auto ptr = any_cast<value_t>(&operand);
142 throw_error(bad_any_cast());
146 template<class value_t>
147 const value_t& any_cast(const any& operand)
149 auto ptr = any_cast<value_t>(&operand);
155 throw_error(bad_any_cast());
158 template<class value_t>
159 inline value_t& unsafe_any_cast(any& operand)
162 return any_cast<value_t>(operand);
164 return static_cast<any::holder_impl<typename std::decay<value_t>::type> *>(operand.hldr.get())->v;
168 template<class value_t>
169 inline const value_t& unsafe_any_cast(const any& operand)
172 return any_cast<value_t>(operand);
174 return static_cast<any::holder_impl<typename std::decay<value_t>::type> *>(operand.hldr.get())->v;
181 #if defined(_MSC_VER)
182 // Enable "multiple copy constructors specified" back
183 # pragma warning(default: 4521)
186 #endif // OPENCV_GAPI_UTIL_ANY_HPP