ObjectFactory.h
1 /*
2  * Medical Image Registration ToolKit (MIRTK)
3  *
4  * Copyright 2013-2015 Imperial College London
5  * Copyright 2013-2015 Andreas Schuh
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  * http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  */
19 
20 #ifndef MIRTK_ObjectFactory_H
21 #define MIRTK_ObjectFactory_H
22 
23 #include "mirtk/UnorderedMap.h"
24 #include "mirtk/Stream.h"
25 
26 #include "mirtk/CommonExport.h"
27 
28 
29 namespace mirtk {
30 
31 
32 // Global "debug" flag (cf. mirtk/Options.h)
33 MIRTK_Common_EXPORT extern int debug;
34 
35 
36 /**
37  * Constructs a new instance of a class derived from the template type
38  * given a type identification such as an enumeration value or string
39  */
40 template <typename TId, typename TInterface>
42 {
43  // ---------------------------------------------------------------------------
44  // Types
45 public:
46 
47  /// Type of object type identifier
48  typedef TId Id;
49 
50  /// Type of object base class
51  typedef TInterface Interface;
52 
53  /// Type of object creator
54  typedef Interface *(*Creator)();
55 
56  /// Type of object factory instance
58 
59  // ---------------------------------------------------------------------------
60  // Abstract base class for singleton
61 protected:
62 
63  /// Constructor
65 
66  /// Destructor
67  virtual ~ObjectFactory() {}
68 
69  /// Copy constructor. Intentionally not implemented.
71 
72  /// Assignment operator. Intentionally not implemented.
73  void operator =(const ObjectFactory &);
74 
75 public:
76 
77  // ---------------------------------------------------------------------------
78  // Object creation
79 private:
80 
81  /// Type of associative map
82  typedef UnorderedMap<Id, Creator> TypeIdAssociations;
83 
84  /// Type of associative map
85  typedef UnorderedMap<const char *, Creator> TypeNameAssociations;
86 
87  /// Registered object type creators
88  TypeIdAssociations _TypeIdAssociations;
89 
90  /// Registered object type creators
91  TypeNameAssociations _TypeNameAssociations;
92 
93 public:
94 
95  /// Register new object creator
96  ///
97  /// \param[in] type_id Object type identifier.
98  /// \param[in] type_name Object type name.
99  /// \param[in] creator Object creator function.
100  bool Register(Id type_id, const char *type_name, Creator creator)
101  {
102  _TypeIdAssociations [type_id ] = creator;
103  _TypeNameAssociations[type_name] = creator;
104  if (debug) {
105  cout << "Registered object type with name " << type_name << " and ID " << type_id << endl;
106  }
107  return true;
108  }
109 
110  /// Create new object
111  ///
112  /// \param[in] type_id Object type identifier.
113  ///
114  /// \returns Object of given type which must be deleted by caller or nullptr.
115  Interface *New(Id type_id) const
116  {
117  auto it = _TypeIdAssociations.find(type_id);
118  return (it == _TypeIdAssociations.end() ? nullptr : (it->second)());
119  }
120 
121  /// Create new object
122  ///
123  /// \param[in] type_name Object type name.
124  ///
125  /// \returns Object of given type which must be deleted by caller or nullptr.
126  Interface *New(const char *type_name) const
127  {
128  auto it = _TypeNameAssociations.find(type_name);
129  return (it == _TypeNameAssociations.end() ? nullptr : (it->second)());
130  }
131 
132 };
133 
134 // -----------------------------------------------------------------------------
135 /// Default object creation function
136 template <class BaseType, class ObjectType> BaseType *New()
137 {
138  return new ObjectType();
139 }
140 
141 // -----------------------------------------------------------------------------
142 /// Define singleton object factory class in .cc file of object base class
143 #define mirtkDefineObjectFactory(id_type, base) \
144  class base##Factory : public mirtk::ObjectFactory<id_type, base> \
145  { \
146  private: \
147  /** Constructor */ \
148  base##Factory() {} \
149  /** Destructor */ \
150  virtual ~base##Factory() {} \
151  /** Copy constructor. Intentionally not implemented. */ \
152  base##Factory(const base##Factory &); \
153  /** Assignment operator. Intentionally not implemented. */ \
154  void operator =(const base##Factory &); \
155  public: \
156  /** Get singleton instance */ \
157  static base##Factory &Instance() \
158  { \
159  static base##Factory instance; \
160  return instance; \
161  } \
162  }
163 
164 // -----------------------------------------------------------------------------
165 /// Register object type with factory at static initialization time
166 #ifdef MIRTK_AUTO_REGISTER
167  #define mirtkAutoRegisterObjectTypeMacro(factory, id_type, id, base, type) \
168  namespace { \
169  static auto _##type##Registered = \
170  (factory).Register(id, type::NameOfType(), mirtk::New<base, type>); \
171  }
172 #else // MIRTK_AUTO_REGISTER
173  #define mirtkAutoRegisterObjectTypeMacro(factory, id_type, id, base, type)
174 #endif // MIRTK_AUTO_REGISTER
175 
176 
177 } // namespace mirtk
178 
179 #endif // MIRTK_ObjectFactory_H
Interface * New(const char *type_name) const
TId Id
Type of object type identifier.
Definition: ObjectFactory.h:48
Interface * New(Id type_id) const
void operator=(const ObjectFactory &)
Assignment operator. Intentionally not implemented.
MIRTK_Common_EXPORT int debug
Definition: Options.h:105
Definition: IOConfig.h:41
ObjectFactory()
Constructor.
Definition: ObjectFactory.h:64
TInterface Interface
Type of object base class.
Definition: ObjectFactory.h:51
Interface *(* Creator)()
Type of object creator.
Definition: ObjectFactory.h:54
bool Register(Id type_id, const char *type_name, Creator creator)
ObjectFactory< Id, Interface > InstanceType
Type of object factory instance.
Definition: ObjectFactory.h:57
virtual ~ObjectFactory()
Destructor.
Definition: ObjectFactory.h:67