Publishing R3
[platform/upstream/dldt.git] / inference-engine / thirdparty / ade / common / include / util / any.hpp
1 // Copyright (C) 2018 Intel Corporation
2 //
3 // SPDX-License-Identifier: Apache-2.0
4 //
5
6 #ifndef UTIL_ANY_HPP
7 #define UTIL_ANY_HPP
8
9 #include <memory>
10 #include <type_traits>
11 #include <utility>
12 #include <typeinfo>
13
14 #include "assert.hpp"
15
16 //TODO - drop any from ADE metadata, using only typed graph
17 //and to introduce bind() instead
18
19 namespace internal
20 {
21     template <class T, class Source>
22     T down_cast(Source operand)
23     {
24 #if defined(__GXX_RTTI) || defined(_CPPRTTI)
25        return dynamic_cast<T>(operand);
26 #else
27     #warning used static cast instead of dynamic because RTTI is disabled
28        return static_cast<T>(operand);
29 #endif
30     }
31 }
32
33 namespace util
34 {
35    class bad_any_cast : public std::bad_cast
36    {
37    public:
38        virtual const char* what() const noexcept override
39        {
40            return "Bad any cast";
41        }
42    };
43
44    //modeled against C++17 std::any
45    class any
46    {
47    private:
48       struct holder;
49       using holder_ptr = std::unique_ptr<holder>;
50       struct holder
51       {
52          virtual holder_ptr clone() = 0;
53          virtual ~holder() = default;
54       };
55
56       template <typename value_t>
57       struct holder_impl : holder
58       {
59          value_t v;
60          template<typename arg_t>
61          holder_impl(arg_t&& a) : v(std::forward<arg_t>(a)) {}
62          holder_ptr clone() override { return holder_ptr(new holder_impl (v));}
63       };
64
65       holder_ptr hldr;
66    public:
67       template<class value_t>
68       any(value_t&& arg) :  hldr(new holder_impl<typename std::decay<value_t>::type>( std::forward<value_t>(arg))) {}
69
70       any(any const& src) : hldr( src.hldr ? src.hldr->clone() : nullptr) {}
71       //simple hack in order not to write enable_if<not any> for the template constructor
72       any(any & src) : any (const_cast<any const&>(src)) {}
73
74       any()       = default;
75       any(any&& ) = default;
76
77       any& operator=(any&&) = default;
78
79       any& operator=(any const& src)
80       {
81          any copy(src);
82          swap(*this, copy);
83          return *this;
84       }
85
86       template<class value_t>
87       friend value_t* any_cast(any* operand);
88
89       template<class value_t>
90       friend const value_t* any_cast(const any* operand);
91
92       friend void swap(any & lhs, any& rhs)
93       {
94          swap(lhs.hldr, rhs.hldr);
95       }
96
97    };
98
99    template<class value_t>
100    value_t* any_cast(any* operand)
101    {
102       auto casted = internal::down_cast<any::holder_impl<typename std::decay<value_t>::type> *>(operand->hldr.get());
103       if (casted){
104          return & (casted->v);
105       }
106       return nullptr;
107    }
108
109    template<class value_t>
110    const value_t* any_cast(const any* operand)
111    {
112       auto casted = internal::down_cast<any::holder_impl<typename std::decay<value_t>::type> *>(operand->hldr.get());
113       if (casted){
114          return & (casted->v);
115       }
116       return nullptr;
117    }
118
119    template<class value_t>
120    value_t& any_cast(any& operand)
121    {
122       auto ptr = any_cast<value_t>(&operand);
123       if (ptr)
124       {
125          return *ptr;
126       }
127
128       throw_error(bad_any_cast());
129    }
130
131
132    template<class value_t>
133    const value_t& any_cast(const any& operand)
134    {
135       auto ptr = any_cast<value_t>(&operand);
136       if (ptr)
137       {
138          return *ptr;
139       }
140
141       throw_error(bad_any_cast());
142    }
143 }
144
145 #endif // UTIL_ANY_HPP