Publishing 2020.1 content
[platform/upstream/dldt.git] / inference-engine / include / ie_parameter.hpp
1 // Copyright (C) 2018-2020 Intel Corporation
2 // SPDX-License-Identifier: Apache-2.0
3 //
4
5 /**
6  * @brief A header file for the CNNNetworkIterator class
7  *
8  * @file ie_cnn_network_iterator.hpp
9  */
10 #pragma once
11
12 #include <algorithm>
13 #include <cctype>
14 #include <details/ie_exception.hpp>
15 #include <iterator>
16 #include <map>
17 #include <memory>
18 #include <string>
19 #include <tuple>
20 #include <typeinfo>
21 #include <utility>
22 #include <vector>
23
24 #include "ie_api.h"
25
26 namespace ngraph {
27
28 class Variant;
29
30 }  // namespace ngraph
31
32 namespace InferenceEngine {
33
34 /**
35  * @brief This class represents an object to work with different parameters
36  *
37  */
38 class INFERENCE_ENGINE_API_CLASS(Parameter) {
39 public:
40     /**
41      * @brief Default constructor
42      */
43     Parameter() = default;
44
45     /**
46      * @brief Move constructor
47      *
48      * @param parameter Parameter object
49      */
50     Parameter(Parameter&& parameter) noexcept {
51         std::swap(ptr, parameter.ptr);
52     }
53
54     /**
55      * @brief Creates parameter from variant.
56      * This method creates empty parameter if variant doesn't contain Parameter
57      *
58      * @param var ngraph variant
59      */
60     Parameter(const std::shared_ptr<ngraph::Variant>& var);
61
62     /**
63      * @brief Creates parameter from variant.
64      * This method creates empty parameter if variant doesn't contain Parameter
65      *
66      * @param var ngraph variant
67      */
68     Parameter(std::shared_ptr<ngraph::Variant>& var);
69
70     /**
71      * @brief Copy constructor
72      *
73      * @param parameter Parameter object
74      */
75     Parameter(const Parameter& parameter) {
76         *this = parameter;
77     }
78
79     /**
80      * @brief Constructor creates parameter with object
81      *
82      * @tparam T Parameter type
83      * @tparam U Identity type-transformation
84      * @param parameter object
85      */
86     template <class T,
87               typename = typename std::enable_if<!std::is_same<typename std::decay<T>::type, Parameter>::value>::type>
88     Parameter(T&& parameter) {  // NOLINT
89         static_assert(!std::is_same<typename std::decay<T>::type, Parameter>::value, "To prevent recursion");
90         ptr = new RealData<typename std::decay<T>::type>(std::forward<T>(parameter));
91     }
92
93     /**
94      * @brief Constructor creates string parameter from char *
95      *
96      * @param str char array
97      */
98     Parameter(const char* str): Parameter(std::string(str)) {}  // NOLINT
99
100     /**
101      * @brief Destructor
102      */
103     virtual ~Parameter();
104
105     /**
106      * Copy operator for Parameter
107      * @param parameter Parameter object
108      * @return Parameter
109      */
110     Parameter& operator=(const Parameter& parameter) {
111         if (this == &parameter) {
112             return *this;
113         }
114         clear();
115         if (!parameter.empty()) ptr = parameter.ptr->copy();
116         return *this;
117     }
118
119     /**
120      * Remove a value from parameter
121      */
122     void clear() {
123         delete ptr;
124         ptr = nullptr;
125     }
126
127     /**
128      * Checks that parameter contains a value
129      * @return false if parameter contains a value else false
130      */
131     bool empty() const noexcept {
132         return nullptr == ptr;
133     }
134
135     /**
136      * Checks the type of value
137      * @tparam T Type of value
138      * @return true if type of value is correct
139      */
140     template <class T>
141     bool is() const {
142         return empty() ? false : ptr->is(typeid(T));
143     }
144
145     /**
146      * Dynamic cast to specified type
147      * @tparam T type
148      * @return casted object
149      */
150     template <typename T>
151     T&& as() && {
152         return std::move(dyn_cast<T>(ptr));
153     }
154
155     /**
156      * Dynamic cast to specified type
157      * @tparam T type
158      * @return casted object
159      */
160     template <class T>
161     T& as() & {
162         return dyn_cast<T>(ptr);
163     }
164     /**
165      * Dynamic cast to specified type
166      * @tparam T type
167      * @return casted object
168      */
169     template <class T>
170     const T& as() const& {
171         return dyn_cast<T>(ptr);
172     }
173
174     /**
175      * Dynamic cast to specified type
176      * @tparam T type
177      * @return casted object
178      */
179     template <class T>
180     operator T &&() && {
181         return std::move(dyn_cast<typename std::remove_cv<T>::type>(ptr));
182     }
183
184     /**
185      * Dynamic cast to specified type
186      * @tparam T type
187      * @return casted object
188      */
189     template <class T>
190     operator T&() & {
191         return dyn_cast<typename std::remove_cv<T>::type>(ptr);
192     }
193
194     /**
195      * Dynamic cast to specified type
196      * @tparam T type
197      * @return casted object
198      */
199     template <class T>
200     operator const T&() const& {
201         return dyn_cast<typename std::remove_cv<T>::type>(ptr);
202     }
203
204     /**
205      * @brief Converts parameter to shared pointer on ngraph::Variant
206      *
207      * @return shared pointer on ngraph::Variant
208      */
209     std::shared_ptr<ngraph::Variant> asVariant() const;
210
211     /**
212      * @brief Casts to shared pointer on ngraph::Variant
213      *
214      * @return shared pointer on ngraph::Variant
215      */
216     operator std::shared_ptr<ngraph::Variant>() const {
217         return asVariant();
218     }
219
220     /**
221      * Dynamic cast to specified type
222      * @tparam T type
223      * @return casted object
224      */
225     template <class T>
226     operator T&() const& {
227         return dyn_cast<typename std::remove_cv<T>::type>(ptr);
228     }
229
230     /**
231      * @brief The comparison operator for the Parameter
232      *
233      * @param rhs object to compare
234      * @return true if objects are equal
235      */
236     bool operator==(const Parameter& rhs) const {
237         return *ptr == *(rhs.ptr);
238     }
239     /**
240      * @brief The comparison operator for the Parameter
241      *
242      * @param rhs object to compare
243      * @return true if objects aren't equal
244      */
245     bool operator!=(const Parameter& rhs) const {
246         return !(*this == rhs);
247     }
248
249 private:
250     template <class T, class EqualTo>
251     struct CheckOperatorEqual {
252         template <class U, class V>
253         static auto test(U*) -> decltype(std::declval<U>() == std::declval<V>()) {
254             return false;
255         }
256
257         template <typename, typename>
258         static auto test(...) -> std::false_type {
259             return {};
260         }
261
262         using type = typename std::is_same<bool, decltype(test<T, EqualTo>(nullptr))>::type;
263     };
264
265     template <class T, class EqualTo = T>
266     struct HasOperatorEqual : CheckOperatorEqual<T, EqualTo>::type {};
267
268     struct Any {
269 #ifdef __clang__
270         virtual ~Any();
271 #else
272         virtual ~Any() = default;
273 #endif
274         virtual bool is(const std::type_info&) const = 0;
275         virtual Any* copy() const = 0;
276         virtual bool operator==(const Any& rhs) const = 0;
277     };
278
279     template <class T>
280     struct RealData : Any, std::tuple<T> {
281         using std::tuple<T>::tuple;
282
283         bool is(const std::type_info& id) const override {
284             return id == typeid(T);
285         }
286         Any* copy() const override {
287             return new RealData {get()};
288         }
289
290         T& get() & {
291             return std::get<0>(*static_cast<std::tuple<T>*>(this));
292         }
293
294         const T& get() const& {
295             return std::get<0>(*static_cast<const std::tuple<T>*>(this));
296         }
297
298         template <class U>
299         typename std::enable_if<!HasOperatorEqual<U>::value, bool>::type equal(const Any& left, const Any& rhs) const {
300             THROW_IE_EXCEPTION << "Parameter doesn't contain equal operator";
301         }
302
303         template <class U>
304         typename std::enable_if<HasOperatorEqual<U>::value, bool>::type equal(const Any& left, const Any& rhs) const {
305             return dyn_cast<U>(&left) == dyn_cast<U>(&rhs);
306         }
307
308         bool operator==(const Any& rhs) const override {
309             return rhs.is(typeid(T)) && equal<T>(*this, rhs);
310         }
311     };
312
313     template <typename T>
314     static T& dyn_cast(Any* obj) {
315         if (obj == nullptr) THROW_IE_EXCEPTION << "Parameter is empty!";
316         return dynamic_cast<RealData<T>&>(*obj).get();
317     }
318
319     template <typename T>
320     static const T& dyn_cast(const Any* obj) {
321         if (obj == nullptr) THROW_IE_EXCEPTION << "Parameter is empty!";
322         return dynamic_cast<const RealData<T>&>(*obj).get();
323     }
324
325     Any* ptr = nullptr;
326 };
327
328 #ifdef __clang__
329 extern template struct INFERENCE_ENGINE_API_CLASS(InferenceEngine::Parameter::RealData<int>);
330 extern template struct INFERENCE_ENGINE_API_CLASS(InferenceEngine::Parameter::RealData<bool>);
331 extern template struct INFERENCE_ENGINE_API_CLASS(InferenceEngine::Parameter::RealData<float>);
332 extern template struct INFERENCE_ENGINE_API_CLASS(InferenceEngine::Parameter::RealData<uint32_t>);
333 extern template struct INFERENCE_ENGINE_API_CLASS(InferenceEngine::Parameter::RealData<std::string>);
334 extern template struct INFERENCE_ENGINE_API_CLASS(InferenceEngine::Parameter::RealData<unsigned long>);
335 extern template struct INFERENCE_ENGINE_API_CLASS(InferenceEngine::Parameter::RealData<std::vector<int>>);
336 extern template struct INFERENCE_ENGINE_API_CLASS(InferenceEngine::Parameter::RealData<std::vector<std::string>>);
337 extern template struct INFERENCE_ENGINE_API_CLASS(InferenceEngine::Parameter::RealData<std::vector<unsigned long>>);
338 extern template struct INFERENCE_ENGINE_API_CLASS(
339     InferenceEngine::Parameter::RealData<std::tuple<unsigned int, unsigned int>>);
340 extern template struct INFERENCE_ENGINE_API_CLASS(
341     InferenceEngine::Parameter::RealData<std::tuple<unsigned int, unsigned int, unsigned int>>);
342 #endif  // __clang__
343
344 }  // namespace InferenceEngine