Merge pull request #278 from asuhov/2019-r3
[platform/upstream/dldt.git] / inference-engine / include / details / ie_so_pointer.hpp
1 // Copyright (C) 2018-2019 Intel Corporation
2 // SPDX-License-Identifier: Apache-2.0
3 //
4
5 /**
6 * @brief This is a wrapper class for handling plugin instantiation and releasing resources
7 * @file ie_so_pointer.hpp
8 */
9 #pragma once
10
11 #include <memory>
12 #include "ie_so_loader.h"
13 #include "ie_common.h"
14 #include "ie_plugin.hpp"
15 #include "details/ie_exception.hpp"
16 #include "details/ie_no_release.hpp"
17 #include <string>
18 #include <cassert>
19
20 namespace InferenceEngine {
21 namespace details {
22
23 /**
24 * @brief This class is a C++ helper to load a symbol from a library and create its instance
25 */
26 template<class Loader>
27 class SymbolLoader {
28 private:
29     std::shared_ptr<Loader> _so_loader;
30
31 public:
32     /**
33     * @brief The main constructor
34     * @param loader Library to load from
35     */
36     explicit SymbolLoader(std::shared_ptr<Loader> loader) : _so_loader(loader) {}
37
38     /**
39     * @brief Calls a function from the library that creates an object and returns StatusCode
40     * @param name Name of function to load object with
41     * @return If StatusCode provided by function is OK then returns the loaded object. Throws an exception otherwise
42     */
43     template<class T>
44     T* instantiateSymbol(const std::string& name) const {
45         T* instance = nullptr;
46         ResponseDesc desc;
47         StatusCode sts = bind_function<StatusCode(T*&, ResponseDesc*)>(name)(instance, &desc);
48         if (sts != OK) {
49             THROW_IE_EXCEPTION << desc.msg;
50         }
51         return instance;
52     }
53
54     /**
55     * @brief Loads function from the library and returns a pointer to it
56     * @param functionName Name of function to load
57     * @return The loaded function
58     */
59     template<class T>
60     std::function<T> bind_function(const std::string &functionName) const {
61         std::function<T> ptr(reinterpret_cast<T *>(_so_loader->get_symbol(functionName.c_str())));
62         return ptr;
63     }
64 };
65
66 /**
67 * @brief This class is a trait class that provides a creator with a function name corresponding to the templated class parameter
68 */
69 template<class T>
70 class SOCreatorTrait {};
71
72 /**
73 * @brief This class instantiate object using shared library
74 */
75 template <class T, class Loader = SharedObjectLoader>
76 class SOPointer {
77 IE_SUPPRESS_DEPRECATED_START
78     template <class U, class W> friend class SOPointer;
79 public:
80     /**
81     * @brief Default constructor
82     */
83     SOPointer() = default;
84
85     /**
86     * @brief The main constructor
87     * @param name Name of a shared library file
88     */
89     explicit SOPointer(const file_name_t &name)
90         : _so_loader(new Loader(name.c_str()))
91         , _pointedObj(details::shared_from_irelease(
92             SymbolLoader<Loader>(_so_loader).template instantiateSymbol<T>(SOCreatorTrait<T>::name))) {
93     }
94
95     /**
96     * @brief Constructs an object with existing reference
97     * @param _pointedObj_ Existing reference to wrap
98     */
99     explicit SOPointer(T * _pointedObj_)
100         : _so_loader()
101         , _pointedObj(_pointedObj_) {
102         if (_pointedObj == nullptr) {
103             THROW_IE_EXCEPTION << "Cannot create SOPointer<T, Loader> from nullptr";
104         }
105     }
106
107     /**
108     * @brief The copy-like constructor, can create So Pointer that dereferenced into child type if T is derived of U
109     * @param that copied SOPointer object
110     */
111     template<class U, class W>
112     SOPointer(const SOPointer<U, W> & that) :
113         _so_loader(std::dynamic_pointer_cast<Loader>(that._so_loader)),
114         _pointedObj(std::dynamic_pointer_cast<T>(that._pointedObj)) {
115         if (_pointedObj == nullptr) {
116             THROW_IE_EXCEPTION << "Cannot create object from SOPointer<U, W> reference";
117         }
118     }
119
120     /**
121     * @brief Standard pointer operator
122     * @return underlined interface with disabled Release method
123     */
124     details::NoReleaseOn<T>* operator->() const noexcept {
125         return reinterpret_cast<details::NoReleaseOn<T>*>(_pointedObj.get());
126     }
127
128     /**
129     * @brief Standard dereference operator
130     * @return underlined interface with disabled Release method
131     */
132     details::NoReleaseOn<T>* operator*() const noexcept {
133         return this->operator->();
134     }
135
136     explicit operator bool() const noexcept {
137         return (nullptr != _so_loader) && (nullptr != _pointedObj);
138     }
139
140     friend bool operator == (std::nullptr_t, const SOPointer& ptr) noexcept {
141         return !ptr;
142     }
143     friend bool operator == (const SOPointer& ptr, std::nullptr_t) noexcept {
144         return !ptr;
145     }
146     friend bool operator != (std::nullptr_t, const SOPointer& ptr) noexcept {
147         return static_cast<bool>(ptr);
148     }
149     friend bool operator != (const SOPointer& ptr, std::nullptr_t) noexcept {
150         return static_cast<bool>(ptr);
151     }
152
153     SOPointer& operator=(const SOPointer & pointer) noexcept {
154         _pointedObj =  pointer._pointedObj;
155         _so_loader = pointer._so_loader;
156         return *this;
157     }
158
159 protected:
160     /**
161      * @brief Gets a smart pointer to the DLL
162      */
163     std::shared_ptr<Loader> _so_loader;
164     /**
165      * @brief Gets a smart pointer to the custom object
166      */
167     std::shared_ptr<T> _pointedObj;
168 IE_SUPPRESS_DEPRECATED_END
169 };
170
171 }  // namespace details
172
173
174
175 /**
176  * @brief Creates a special shared_pointer wrapper for the given type from a specific shared module
177  * @param name Name of the shared library file
178  */
179 template <class T>
180 inline std::shared_ptr<T> make_so_pointer(const file_name_t & name) = delete;
181
182 }  // namespace InferenceEngine