retdec
factory.h
Go to the documentation of this file.
1 
11 #ifndef RETDEC_LLVMIR2HLL_SUPPORT_FACTORY_H
12 #define RETDEC_LLVMIR2HLL_SUPPORT_FACTORY_H
13 
14 #include <map>
15 #include <vector>
16 
18 
36 // Implementation notes:
37 //
38 // - The registration is done in a call to an anonymous lambda function. It
39 // returns objectId, which is used to initialize the objectIdVarName constant.
40 //
41 // - The created constant is static. We do not use an anonymous namespace for
42 // that because gcc with -pedantic reports a warning when a semicolon is used
43 // after the closing }. Thus, the user would have to use this macro without
44 // the ending semicolon, which would feel unnatural.
45 #define REGISTER_AT_FACTORY(objectId, objectIdVarName, factory, createFunc) \
46  static const std::string objectIdVarName = [] { \
47  factory::getInstance().registerObject(objectId, createFunc); \
48  return objectId; \
49  } ()
50 
51 namespace retdec {
52 namespace llvmir2hll {
53 
63 template<typename ObjectIDType, class AbstractObject>
65 public:
72  static ShPtr<AbstractObject> onUnknownType(ObjectIDType id) {
73  return ShPtr<AbstractObject>();
74  }
75 
76 protected:
80  DefaultFactoryError() = default;
81 
85  ~DefaultFactoryError() = default;
86 };
87 
117 template<
118  class AbstractObject,
119  typename ObjectIDType,
120  typename ObjectCreator = ShPtr<AbstractObject> (*)(),
121  template<typename, class>
122  class FactoryErrorPolicy = DefaultFactoryError
123 >
124 class Factory: public FactoryErrorPolicy<ObjectIDType, AbstractObject> {
125 private:
127  using IDToObjectMap = std::map<ObjectIDType, ObjectCreator>;
128 
129 public:
133  Factory(): associations() {}
134 
145  bool registerObject(ObjectIDType id, ObjectCreator creator) {
146  return associations.insert(typename IDToObjectMap::value_type(
147  id, creator)).second;
148  }
149 
156  bool unregisterObject(const ObjectIDType &id) const {
157  return associations.erase(id) == 1;
158  }
159 
167  template<typename... Args>
168  ShPtr<AbstractObject> createObject(const ObjectIDType &id,
169  Args &&... args) const {
170  auto i = associations.find(id);
171  if (i != associations.end()) {
172  // Instantiate the object via the registered function.
173  return (i->second)(std::forward<Args>(args)...);
174  }
175  return this->onUnknownType(id); // "this" is necessary here
176  }
177 
181  std::vector<ObjectIDType> getRegisteredObjects() const {
182  std::vector<ObjectIDType> regObjects;
183  for (const auto &item : associations) {
184  regObjects.push_back(item.first);
185  }
186  return regObjects;
187  }
188 
193  bool isRegistered(const ObjectIDType &id) const {
194  return associations.find(id) != associations.end();
195  }
196 
197 private:
200 };
201 
202 } // namespace llvmir2hll
203 } // namespace retdec
204 
205 #endif
Handles the "Unknown Type" error in an object factory.
Definition: factory.h:64
static ShPtr< AbstractObject > onUnknownType(ObjectIDType id)
Reaction to the "Unknown Type" error.
Definition: factory.h:72
DefaultFactoryError()=default
Default constructor.
~DefaultFactoryError()=default
Destructor.
Implementation of a generic object factory.
Definition: factory.h:124
IDToObjectMap associations
Container used to map an object ID to its creator function.
Definition: factory.h:199
bool registerObject(ObjectIDType id, ObjectCreator creator)
Registers the given object.
Definition: factory.h:145
bool unregisterObject(const ObjectIDType &id) const
Unregisters the given object.
Definition: factory.h:156
ShPtr< AbstractObject > createObject(const ObjectIDType &id, Args &&... args) const
Creates an instance of the given object with the given arguments.
Definition: factory.h:168
bool isRegistered(const ObjectIDType &id) const
Returns true if there is an object registered with the selected ID, false otherwise.
Definition: factory.h:193
std::map< ObjectIDType, ObjectCreator > IDToObjectMap
Type of a container used to map an object ID to its creator function.
Definition: factory.h:127
Factory()
Default constructor.
Definition: factory.h:133
std::vector< ObjectIDType > getRegisteredObjects() const
Returns a vector of all registered object IDs.
Definition: factory.h:181
A library providing API for working with back-end IR.
std::shared_ptr< T > ShPtr
An alias for a shared pointer.
Definition: smart_ptr.h:18
Definition: archive_wrapper.h:19
Declarations, aliases, macros, etc. for the use of smart pointers.