3aadaf514519263aa9ffc556acd5824717929e22
[platform/upstream/dldt.git] / inference-engine / src / vpu / graph_transformer / include / vpu / utils / any.hpp
1 // Copyright (C) 2018-2019 Intel Corporation
2 // SPDX-License-Identifier: Apache-2.0
3 //
4
5 #pragma once
6
7 #include <memory>
8 #include <iosfwd>
9 #include <string>
10 #include <type_traits>
11 #include <utility>
12
13 #include <vpu/utils/io.hpp>
14 #include <vpu/utils/dot_io.hpp>
15
16 namespace vpu {
17
18 class Any final {
19     struct Holder {
20         using Ptr = std::unique_ptr<Holder>;
21
22         virtual ~Holder() = default;
23
24         virtual Holder::Ptr clone() const = 0;
25
26         virtual void printImpl(std::ostream& os) const = 0;
27         virtual void printImpl(DotLabel& lbl) const = 0;
28     };
29
30     template <typename T>
31     struct HolderImpl final : Holder {
32         T _val;
33
34         explicit inline HolderImpl(const T& val) :
35                 _val(val) {
36         }
37         explicit inline HolderImpl(T&& val) :
38                 _val(std::move(val)) {
39         }
40
41         inline void set(const T& val) {
42             _val = val;
43         }
44         inline void set(T&& val) {
45             _val = std::move(val);
46         }
47
48         ~HolderImpl() override = default;
49
50         Holder::Ptr clone() const override {
51             return Holder::Ptr(new HolderImpl<T>(_val));
52         }
53
54         void printImpl(std::ostream& os) const override {
55             printTo(os, _val);
56         }
57         void printImpl(DotLabel& lbl) const override {
58             printTo(lbl, _val);
59         }
60     };
61
62 public:
63     inline Any() = default;
64
65     inline Any(Any&&) = default;
66     inline Any& operator=(Any&&) = default;
67
68     inline Any(const Any& other) :
69             _impl(other._impl != nullptr ? other._impl->clone() : nullptr) {
70     }
71     inline Any& operator=(const Any& other) {
72         if (&other != this) {
73             if (other._impl == nullptr) {
74                 _impl.reset();
75             } else {
76                 _impl = other._impl->clone();
77             }
78         }
79         return *this;
80     }
81
82     template <typename T>
83     explicit Any(const T& arg) :
84             _impl(new HolderImpl<T>(arg)) {
85     }
86     template <
87         typename T,
88         typename _Check = typename std::enable_if<!std::is_reference<T>::value, void>::type>
89     explicit inline Any(T&& arg) :
90             _impl(new HolderImpl<typename std::decay<T>::type>(std::move(arg))) {
91     }
92
93     inline bool empty() const {
94         return _impl == nullptr;
95     }
96
97     template <typename T>
98     inline void set(const T& arg) {
99         if (auto casted = dynamic_cast<HolderImpl<T>*>(_impl.get())) {
100             casted->set(arg);
101         } else {
102             _impl.reset(new HolderImpl<T>(arg));
103         }
104     }
105     template <
106         typename T,
107         typename _Check = typename std::enable_if<!std::is_reference<T>::value, void>::type>
108     inline void set(T&& arg) {
109         if (auto casted = dynamic_cast<HolderImpl<typename std::decay<T>::type>*>(_impl.get())) {
110             casted->set(std::move(arg));
111         } else {
112             _impl.reset(new HolderImpl<T>(std::move(arg)));
113         }
114     }
115
116     template <typename T>
117     inline const T& get() const {
118         auto casted = dynamic_cast<const HolderImpl<T>*>(_impl.get());
119         IE_ASSERT(casted != nullptr);
120         return casted->_val;
121     }
122     template <typename T>
123     inline T& get() {
124         auto casted = dynamic_cast<HolderImpl<T>*>(_impl.get());
125         IE_ASSERT(casted != nullptr);
126         return casted->_val;
127     }
128
129     inline void swap(Any& other) {
130         std::swap(_impl, other._impl);
131     }
132
133     inline void printImpl(std::ostream& os) const {
134         if (_impl != nullptr) {
135             _impl->printImpl(os);
136         }
137     }
138
139     inline void printImpl(DotLabel& lbl) const {
140         if (_impl != nullptr) {
141             _impl->printImpl(lbl);
142         }
143     }
144
145 private:
146     Holder::Ptr _impl;
147 };
148
149 }  // namespace vpu