factory.h
1 //*****************************************************************************
2 // Copyright 2017-2020 Intel Corporation
3 //
4 // Licensed under the Apache License, Version 2.0 (the "License");
5 // you may not use this file except in compliance with the License.
6 // You may obtain a copy of the License at
7 //
8 // http://www.apache.org/licenses/LICENSE-2.0
9 //
10 // Unless required by applicable law or agreed to in writing, software
11 // distributed under the License is distributed on an "AS IS" BASIS,
12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 // See the License for the specific language governing permissions and
14 // limitations under the License.
15 //*****************************************************************************
16 
17 #pragma once
18 #include "selective_build.h"
19 #include <string>
20 #include <functional>
21 #include <type_traits>
22 #include <unordered_map>
23 
24 namespace openvino {
25 namespace cc {
26 
27 template<typename Key, typename T>
28 class Factory;
29 
30 template<typename Key, typename T, typename ...Args>
31 class Factory<Key, T(Args...)> {
32  Factory(Factory const&) = delete;
33  Factory& operator=(Factory const&) = delete;
34 
35 public:
36  using builder_t = std::function<T(Args...)>;
37 
38  Factory(const std::string & name)
39  : name(name) {}
40 
41 #ifdef SELECTIVE_BUILD
42  #define registerNodeIfRequired(Module, Name, key, Impl) \
43  OV_PP_EXPAND(OV_PP_CAT(registerImpl, OV_CC_SCOPE_IS_ENABLED(OV_PP_CAT3(Module, _, Name)))<Impl>(key))
44  #define createNodeIfRegistered(Module, key, ...) createImpl(key, __VA_ARGS__)
45 
46  template<typename Impl>
47  void registerImpl0(const Key &) {
48  }
49 
50  template<typename Impl>
51  void registerImpl1(const Key & key) {
52  builders[key] = [](Args... args) -> T {
53  Impl *impl = new Impl(args...);
54  return static_cast<T>(impl);
55  };
56  }
57 
58  T createImpl(const Key & key, Args... args) {
59  auto builder = builders.find(key);
60  if (builder != builders.end()) {
61  return builder->second(args...);
62  }
63  return nullptr;
64  }
65 
66 #elif defined(SELECTIVE_BUILD_ANALYZER)
67  #define registerNodeIfRequired(Module, Name, key, Impl) registerImpl<OV_PP_CAT(FACTORY_, Module), Impl>(key, OV_PP_TOSTRING(Name))
68  #define createNodeIfRegistered(Module, key, ...) createImpl<OV_PP_CAT(FACTORY_, Module)>(key, __VA_ARGS__)
69 
70  template<openvino::itt::domain_t(*domain)(), typename Impl>
71  void registerImpl(const Key & key, const char *typeName) {
72  const std::string task_name = "REG$" + name + "$" + to_string(key) + "$" + typeName;
73  openvino::itt::ScopedTask<domain> task(openvino::itt::handle(task_name));
74  builders[key] = [](Args... args) -> T {
75  Impl *impl = new Impl(args...);
76  return static_cast<T>(impl);
77  };
78  }
79 
80  template<openvino::itt::domain_t(*domain)()>
81  T createImpl(const Key & key, Args... args) {
82  auto builder = builders.find(key);
83  if (builder != builders.end()) {
84  const std::string task_name = "CREATE$" + name + "$" + to_string(key);
85  openvino::itt::ScopedTask<domain> task(openvino::itt::handle(task_name));
86  return builder->second(args...);
87  }
88  return nullptr;
89  }
90 
91 #else
92 
93  #define registerNodeIfRequired(Module, Name, key, Impl) registerImpl<Impl>(key)
94  #define createNodeIfRegistered(Module, key, ...) createImpl(key, __VA_ARGS__)
95 
96  template<typename Impl>
97  void registerImpl(const Key & key) {
98  builders[key] = [](Args... args) -> T {
99  Impl *impl = new Impl(args...);
100  return static_cast<T>(impl);
101  };
102  }
103 
104  T createImpl(const Key & key, Args... args) {
105  auto builder = builders.find(key);
106  if (builder != builders.end()) {
107  return builder->second(args...);
108  }
109  return nullptr;
110  }
111 #endif
112 
113  template<typename Fn>
114  void foreach(Fn fn) const {
115  for (auto itm : builders)
116  fn(itm);
117  }
118 
119  size_t size() const noexcept {
120  return builders.size();
121  }
122 
123 private:
124  const std::string & to_string(const std::string & str) const noexcept {
125  return str;
126  }
127 
128  template<typename V,
129  typename std::enable_if<std::is_enum<V>::value, bool>::type = true>
130  std::string to_string(V val) const {
131  return std::to_string(static_cast<int>(val));
132  }
133 
134  template<typename V,
135  typename std::enable_if<!std::is_enum<V>::value, bool>::type = true>
136  std::string to_string(V val) const {
137  return std::to_string(val);
138  }
139 
140  template <typename K>
141  struct EnumClassHash {
142  std::size_t operator()(K t) const {
143  return static_cast<std::size_t>(t);
144  }
145  };
146 
147  using hash_t = typename std::conditional<std::is_enum<Key>::value, EnumClassHash<Key>, std::hash<Key>>::type;
148  using map_t = std::unordered_map<Key, builder_t, hash_t>;
149 
150  const std::string name;
151  map_t builders;
152 };
153 
154 } // namespace cc
155 } // namespace openvino
Definition: factory.h:28
Used to annotate section of code which would be named at runtime.
Definition: itt.hpp:121