JAPAn
Just Another Parity Analyzer
Loading...
Searching...
No Matches
QwFactory.h
Go to the documentation of this file.
1/*!
2 * \file QwFactory.h
3 * \brief Factory pattern implementation for creating analysis objects
4 */
5
6#pragma once
7
8// System headers
9#include <cxxabi.h>
10#include <cstdlib>
11#include <typeindex>
12
13// Qweak headers
14#include "QwLog.h"
15#include "QwConcepts.h"
16
17// Forward declarations
18class VQwSubsystem;
19class VQwDataElement;
20class VQwDataHandler;
21
22// Exceptions
26
27
28/**
29 * \class VQwFactory
30 * \ingroup QwAnalysis
31 * \brief Abstract factory base for runtime object creation
32 *
33 * Enables instantiation of derived types based on runtime string identifiers.
34 * Maintains a registry of concrete factory instances that can create objects
35 * of specified types. Used throughout the framework to support configuration-
36 * driven object creation for subsystems, data handlers, and data elements.
37 */
38template <class base_t>
40
41 public:
42
43 /// Default virtual destructor
44 virtual ~VQwFactory() { }
45
46 /// Create an object of type with name
47 static base_t* Create(const std::string& type, const std::string& name) {
48 return GetFactory(type)->Create(name);
49 }
50
51 /// Dynamic cast of object into type
52 static base_t* Cast(base_t* base, const std::string& type) {
53 return GetFactory(type)->Cast(base);
54 }
55
56 /// Test whether object inherits from type
57 static bool InheritsFrom(base_t* base, const std::string& type) {
58 return (Cast(base,type) != 0);
59 }
60
61 /// Creation of objects by type (pure virtual)
62 virtual base_t* Create(const std::string& name) const = 0;
63 /// Dynamic cast to type (pure virtual)
64 virtual base_t* Cast(base_t* base) const = 0;
65
66 protected:
67
68 /// Map from string to concrete type factories
69 static std::map<std::string,VQwFactory*>& GetRegisteredTypes() {
70 static std::map<std::string,VQwFactory<base_t>*> theMap;
71 return theMap;
72 }
73 /// List available type factories
74 static void ListRegisteredTypes() {
75 typename std::map<std::string,VQwFactory<base_t>*>::iterator type;
76 for (type = GetRegisteredTypes().begin();
77 type != GetRegisteredTypes().end(); type++ )
78 QwMessage << type->first << QwLog::endl;
79 }
80
81 /// Get a concrete type factory by string
82 static VQwFactory* GetFactory(const std::string& type) {
83 if (GetRegisteredTypes().find(type) != GetRegisteredTypes().end())
84 return GetRegisteredTypes()[type];
85 else {
86 QwError << "Type " << type << " is not registered!" << QwLog::endl;
87 QwMessage << "Available types:" << QwLog::endl;
89 QwWarning << "To register this type, add the following line to the top "
90 << "of the source file:" << QwLog::endl;
91 QwWarning << " REGISTER_SOMETHING_FACTORY(" << type << ");" << QwLog::endl;
92 QwWarning << "Ensure that the dynamic library contains the factory object."
93 << QwLog::endl;
95 }
96 }
97
98}; // class VQwFactory
99
100
101/**
102 * \class QwFactory
103 * \ingroup QwAnalysis
104 * \brief Concrete templated factory for creating specific object types
105 *
106 * Template specialization that provides concrete object creation for a
107 * specific derived type. Automatically registers itself in the factory
108 * registry during static initialization. Used by RegisterSomethingFactory
109 * macros to enable runtime type creation.
110 */
111template <class base_t, class type_t>
112class QwFactory: public VQwFactory<base_t> {
113
114 public:
115
116 /// Constructor which stores type name in list of registered types
117 QwFactory(const std::string& type) {
119 }
120
121 /// Concrete type creation
122 base_t* Create(const std::string& name) const override {
123 return new type_t(name);
124 }
125
126 /// Dynamic cast of type
127 type_t* Cast(base_t* base) const override {
128 return dynamic_cast<type_t*>(base);
129 }
130
131}; // class QwFactory
132
133
134/// Factory type with functionality for data handlers
136/// Factory type with functionality for subsystems
138/// Factory type with functionality for data elements
140
141
142// TODO It would be nice to be able to define something like
143// template <class type_t>
144// typedef class QwFactory<VQwSubsystem,type_t> QwSubsystemFactory;
145// to be able to write e.g.
146// QwSubsystemFactory<QwLumi>
147//
148// This seems to be functionality that is in C++0x...
149// typedef <class type_t> using QwSubsystemFactory = QwFactory<VQwSubsystem,type_t>;
150//
151// For now the following will do as well, but adds a layer of inheritance
152template <class handler_t>
153class QwHandlerFactory: public QwFactory<VQwDataHandler,handler_t> { };
154template <class subsystem_t>
155class QwSubsystemFactory: public QwFactory<VQwSubsystem,subsystem_t> { };
156template <class dataelement_t>
157class QwDataElementFactory: public QwFactory<VQwDataElement,dataelement_t> { };
158
159
160
161/**
162 * \class VQwCloneable
163 * \ingroup QwAnalysis
164 * \brief Virtual base providing polymorphic copy construction
165 *
166 * Template base class that enables runtime cloning of derived objects
167 * through a common interface. Part of the factory pattern implementation.
168 */
169template <class base_t>
171
172 public:
173
174 /// Virtual destructor
175 virtual ~VQwCloneable() { }
176
177 /// Get demangled name of this class
178 std::string GetClassName() const {
179 int status;
180 const std::type_index ti = typeid(*this);
181 char* name = abi::__cxa_demangle(ti.name(), 0, 0, &status);
182 std::string str(name);
183 free(name);
184 return str;
185 }
186
187 /// Abstract clone method when no derived method is defined
188 virtual base_t* Clone() const {
189 QwError << "Clone() is not implemented for class " << GetClassName() << "!" << QwLog::endl;
190 QwMessage << "Modify the class definition of " << GetClassName() << " to:" << QwLog::endl;
191 QwMessage << " class " << GetClassName() << ": "
192 << "public MQwSomethingCloneable<" << GetClassName() << ">" << QwLog::endl;
193 return 0;
194 }
195
196 /// Virtual factory getter
197 virtual const VQwFactory<base_t>* Factory() const { return 0; }
198
199}; // class VQwCloneable
200
201
202/**
203 * \class MQwCloneable
204 * \ingroup QwAnalysis
205 * \brief Mix-in template for concrete cloneable types
206 *
207 * Implements the curiously recurring template pattern to provide
208 * concrete clone functionality for specific derived types.
209 * Enables factory-based object creation and copying.
210 */
211template <class base_t, class type_t>
212class MQwCloneable: virtual public VQwCloneable<base_t> {
213
214 public:
215
216 /// Virtual destructor
217 ~MQwCloneable() override { };
218
219 /// Concrete clone method
220 base_t* Clone() const override {
221 return new type_t(static_cast<const type_t&>(*this));
222 }
223
224 /// Factory getter
225 const VQwFactory<base_t>* Factory() const override { return fFactory; }
226
227 /// Object creation
228 static base_t* Create(const std::string& name) {
229 if (fFactory) return fFactory->Create(name);
230 else return 0;
231 }
232
233 /// Object dynamic cast
234 static type_t* Cast(type_t* type) {
235 if (fFactory) return fFactory->Cast(type);
236 else return 0;
237 }
238
239 private:
240
241 /// Pointer to the factory of this type
243
244}; // class MQwCloneable
245
246/// Mix-in factory functionality for datahandlers
248template <class subsystem_t>
249class MQwDataHandlerCloneable: public MQwCloneable<VQwDataHandler,subsystem_t> { };
250/// Mix-in factory functionality for subsystems
252template <class subsystem_t>
253class MQwSubsystemCloneable: public MQwCloneable<VQwSubsystem,subsystem_t> { };
254/// Mix-in factory functionality for data elements
256template <class dataelement_t>
257class MQwDataElementCloneable: public MQwCloneable<VQwDataElement,dataelement_t> { };
258
259
260/// Macros to create and register the data handler factory of type A
261/// Note: a call to this macro should be followed by a semi-colon!
262/// Includes automatic architectural validation for VQwDataHandler derivatives
263#define REGISTER_DATA_HANDLER_FACTORY(A) \
264 VALIDATE_DATA_HANDLER_PATTERN(A); \
265 template<> const VQwDataHandlerFactory* MQwCloneable<VQwDataHandler,A>::fFactory = new QwFactory<VQwDataHandler,A>(#A)
266
267/// Macros to create and register the subsystem factory of type A
268/// Note: a call to this macro should be followed by a semi-colon!
269/// Includes automatic architectural validation for VQwSubsystem derivatives
270#define REGISTER_SUBSYSTEM_FACTORY(A) \
271 VALIDATE_SUBSYSTEM_PATTERN(A); \
272 template<> const VQwSubsystemFactory* MQwCloneable<VQwSubsystem,A>::fFactory = new QwFactory<VQwSubsystem,A>(#A)
273
274/// Macros to create and register the data element factory of type A
275/// Note: a call to this macro should be followed by a semi-colon!
276/// Includes automatic architectural validation for VQwDataElement derivatives
277#define REGISTER_DATA_ELEMENT_FACTORY(A) \
278 VALIDATE_DATA_ELEMENT_PATTERN(A); \
279 template<> const VQwDataElementFactory* MQwCloneable<VQwDataElement,A>::fFactory = new QwFactory<VQwDataElement,A>(#A)
280
A logfile class, based on an identical class in the Hermes analyzer.
#define QwError
Predefined log drain for errors.
Definition QwLog.h:39
#define QwWarning
Predefined log drain for warnings.
Definition QwLog.h:44
#define QwMessage
Predefined log drain for regular messages.
Definition QwLog.h:49
class VQwCloneable< VQwSubsystem > VQwSubsystemCloneable
Mix-in factory functionality for subsystems.
Definition QwFactory.h:251
class VQwCloneable< VQwDataHandler > VQwDataHandlerCloneable
Mix-in factory functionality for datahandlers.
Definition QwFactory.h:247
class VQwCloneable< VQwDataElement > VQwDataElementCloneable
Mix-in factory functionality for data elements.
Definition QwFactory.h:255
class VQwFactory< VQwDataHandler > VQwDataHandlerFactory
Factory type with functionality for data handlers.
Definition QwFactory.h:135
class VQwFactory< VQwDataElement > VQwDataElementFactory
Factory type with functionality for data elements.
Definition QwFactory.h:139
class VQwFactory< VQwSubsystem > VQwSubsystemFactory
Factory type with functionality for subsystems.
Definition QwFactory.h:137
Abstract factory base for runtime object creation.
Definition QwFactory.h:39
static void ListRegisteredTypes()
List available type factories.
Definition QwFactory.h:74
virtual base_t * Create(const std::string &name) const =0
Creation of objects by type (pure virtual)
virtual base_t * Cast(base_t *base) const =0
Dynamic cast to type (pure virtual)
virtual ~VQwFactory()
Default virtual destructor.
Definition QwFactory.h:44
static base_t * Cast(base_t *base, const std::string &type)
Dynamic cast of object into type.
Definition QwFactory.h:52
static std::map< std::string, VQwFactory * > & GetRegisteredTypes()
Map from string to concrete type factories.
Definition QwFactory.h:69
static VQwFactory * GetFactory(const std::string &type)
Get a concrete type factory by string.
Definition QwFactory.h:82
static bool InheritsFrom(base_t *base, const std::string &type)
Test whether object inherits from type.
Definition QwFactory.h:57
static base_t * Create(const std::string &type, const std::string &name)
Create an object of type with name.
Definition QwFactory.h:47
base_t * Create(const std::string &name) const override
Concrete type creation.
Definition QwFactory.h:122
type_t * Cast(base_t *base) const override
Dynamic cast of type.
Definition QwFactory.h:127
QwFactory(const std::string &type)
Constructor which stores type name in list of registered types.
Definition QwFactory.h:117
Virtual base providing polymorphic copy construction.
Definition QwFactory.h:170
virtual base_t * Clone() const
Abstract clone method when no derived method is defined.
Definition QwFactory.h:188
virtual const VQwFactory< base_t > * Factory() const
Virtual factory getter.
Definition QwFactory.h:197
virtual ~VQwCloneable()
Virtual destructor.
Definition QwFactory.h:175
std::string GetClassName() const
Get demangled name of this class.
Definition QwFactory.h:178
Mix-in template for concrete cloneable types.
Definition QwFactory.h:212
static type_t * Cast(type_t *type)
Object dynamic cast.
Definition QwFactory.h:234
const VQwFactory< base_t > * Factory() const override
Factory getter.
Definition QwFactory.h:225
static base_t * Create(const std::string &name)
Object creation.
Definition QwFactory.h:228
base_t * Clone() const override
Concrete clone method.
Definition QwFactory.h:220
static const VQwFactory< base_t > * fFactory
Pointer to the factory of this type.
Definition QwFactory.h:242
~MQwCloneable() override
Virtual destructor.
Definition QwFactory.h:217
static std::ostream & endl(std::ostream &)
End of the line.
Definition QwLog.cc:297
The pure virtual base class of all data elements.
Base class for subsystems implementing container-delegation pattern.
Abstract base for handlers that consume multiple subsystems and produce derived outputs.