Publishing 2019 R1 content
[platform/upstream/dldt.git] / inference-engine / thirdparty / fluid / modules / gapi / include / opencv2 / gapi / util / any.hpp
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.
4 //
5 // Copyright (C) 2018-2019 Intel Corporation
6
7
8 #ifndef OPENCV_GAPI_UTIL_ANY_HPP
9 #define OPENCV_GAPI_UTIL_ANY_HPP
10
11 #include <memory>
12 #include <type_traits>
13 #include <typeinfo>
14 #include <utility>
15
16 #include "opencv2/gapi/util/throw.hpp"
17
18 #if defined(_MSC_VER)
19    // disable MSVC warning on "multiple copy constructors specified"
20 #  pragma warning(disable: 4521)
21 #endif
22
23 namespace cv
24 {
25
26 namespace internal
27 {
28     template <class T, class Source>
29     T down_cast(Source operand)
30     {
31 #if defined(__GXX_RTTI) || defined(_CPPRTTI)
32        return dynamic_cast<T>(operand);
33 #else
34     #warning used static cast instead of dynamic because RTTI is disabled
35        return static_cast<T>(operand);
36 #endif
37     }
38 }
39
40 namespace util
41 {
42    class bad_any_cast : public std::bad_cast
43    {
44    public:
45        virtual const char* what() const noexcept override
46        {
47            return "Bad any cast";
48        }
49    };
50
51    //modeled against C++17 std::any
52
53    class any
54    {
55    private:
56       struct holder;
57       using holder_ptr = std::unique_ptr<holder>;
58       struct holder
59       {
60          virtual holder_ptr clone() = 0;
61          virtual ~holder() = default;
62       };
63
64       template <typename value_t>
65       struct holder_impl : holder
66       {
67          value_t v;
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));}
71       };
72
73       holder_ptr hldr;
74    public:
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))) {}
77
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)) {}
81
82       any()       = default;
83       any(any&& ) = default;
84
85       any& operator=(any&&) = default;
86
87       any& operator=(any const& src)
88       {
89          any copy(src);
90          swap(*this, copy);
91          return *this;
92       }
93
94       template<class value_t>
95       friend value_t* any_cast(any* operand);
96
97       template<class value_t>
98       friend const value_t* any_cast(const any* operand);
99
100       template<class value_t>
101       friend value_t& unsafe_any_cast(any& operand);
102
103       template<class value_t>
104       friend const value_t& unsafe_any_cast(const any& operand);
105
106       friend void swap(any & lhs, any& rhs)
107       {
108          swap(lhs.hldr, rhs.hldr);
109       }
110
111    };
112
113    template<class value_t>
114    value_t* any_cast(any* operand)
115    {
116       auto casted = internal::down_cast<any::holder_impl<typename std::decay<value_t>::type> *>(operand->hldr.get());
117       if (casted){
118          return & (casted->v);
119       }
120       return nullptr;
121    }
122
123    template<class value_t>
124    const value_t* any_cast(const any* operand)
125    {
126       auto casted = internal::down_cast<any::holder_impl<typename std::decay<value_t>::type> *>(operand->hldr.get());
127       if (casted){
128          return & (casted->v);
129       }
130       return nullptr;
131    }
132
133    template<class value_t>
134    value_t& any_cast(any& operand)
135    {
136       auto ptr = any_cast<value_t>(&operand);
137       if (ptr)
138       {
139          return *ptr;
140       }
141
142       throw_error(bad_any_cast());
143    }
144
145
146    template<class value_t>
147    const value_t& any_cast(const any& operand)
148    {
149       auto ptr = any_cast<value_t>(&operand);
150       if (ptr)
151       {
152          return *ptr;
153       }
154
155       throw_error(bad_any_cast());
156    }
157
158    template<class value_t>
159    inline value_t& unsafe_any_cast(any& operand)
160    {
161 #ifdef DEBUG
162       return any_cast<value_t>(operand);
163 #else
164       return static_cast<any::holder_impl<typename std::decay<value_t>::type> *>(operand.hldr.get())->v;
165 #endif
166    }
167
168    template<class value_t>
169    inline const value_t& unsafe_any_cast(const any& operand)
170    {
171 #ifdef DEBUG
172       return any_cast<value_t>(operand);
173 #else
174       return static_cast<any::holder_impl<typename std::decay<value_t>::type> *>(operand.hldr.get())->v;
175 #endif
176    }
177
178 } // namespace util
179 } // namespace cv
180
181 #if defined(_MSC_VER)
182    // Enable "multiple copy constructors specified" back
183 #  pragma warning(default: 4521)
184 #endif
185
186 #endif // OPENCV_GAPI_UTIL_ANY_HPP