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 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