EventAnalysis  1.0.0
Factory.h
Go to the documentation of this file.
1 /*
2  * Factory.h
3  *
4  * Created on: 07 May 2014
5  * Author: Nicola Mori
6  */
7 
10 #ifndef FACTORY_H_
11 #define FACTORY_H_
12 
13 #include "utils/Demangler.h"
14 #include "utils/SmartLog.h"
15 
16 #include <cxxabi.h>
17 #include <map>
18 #include <typeinfo>
19 #include <vector>
20 
21 namespace EA {
22 
32 template <class T, typename... ConstructorArgs> class Factory {
33 
34 public:
39  static Factory &GetInstance();
40 
47  bool RegisterBuilder(const std::string &builderName, T *(*objectBuilder)(ConstructorArgs...));
48 
57  std::unique_ptr<T> CreateObject(const std::string &name, ConstructorArgs... arguments);
58 
63  const std::vector<std::string> &GetListOfRegisteredBuilders();
64 
65 private:
66  Factory();
67  std::string _factoryName;
68  typedef std::map<std::string, T *(*)(ConstructorArgs...)> BuildersMap;
69  BuildersMap _builders;
70  std::vector<std::string> _builderNames;
71 };
72 
73 template <class T, typename... ConstructorArgs>
75  static Factory<T, ConstructorArgs...> instance;
76  return instance;
77 }
78 
79 // Private default constructor
80 template <class T, typename... ConstructorArgs>
81 Factory<T, ConstructorArgs...>::Factory() : _factoryName(std::string("Factory<").append(Demangler::ClassName<T>())) {
82  const std::string routineName(_factoryName + "::Factory");
83  COUT(DEEPDEB) << routineName << ENDL;
84 }
85 
86 template <class T, typename... ConstructorArgs>
87 bool Factory<T, ConstructorArgs...>::RegisterBuilder(const std::string &builderName,
88  T *(*objectBuilder)(ConstructorArgs...)) {
89  const std::string &routineName(_factoryName + "::RegisterBuilder");
90 
91  std::pair<typename BuildersMap::iterator, bool> insertResult =
92  _builders.insert(std::pair<std::string, T *(*)(ConstructorArgs...)>(builderName, objectBuilder));
93  if (insertResult.second) {
94  _builderNames.push_back(builderName);
95  return true;
96  } else {
97  COUT(ERROR) << "Impossible to register class builder " << builderName
98  << ": a class builder with the same name is already registered." << ENDL;
99  return false;
100  }
101 }
102 
103 template <class T, typename... ConstructorArgs>
105  return _builderNames;
106 }
107 
108 template <class T, typename... ConstructorArgs>
109 std::unique_ptr<T> Factory<T, ConstructorArgs...>::CreateObject(const std::string &builderName,
110  ConstructorArgs... arguments) {
111  const std::string &routineName(_factoryName + "::CreateObject");
112 
113  // 1. Search for a suitable builder
114  typename BuildersMap::iterator builderIter = _builders.find(builderName);
115  if (builderIter == _builders.end()) {
116  COUT(ERROR) << "No available class builder with name " << builderName << "." << ENDL;
117  return std::unique_ptr<T>((T *)(NULL));
118  }
119 
120  // 2. Build the object and return it
121  return std::unique_ptr<T>((*(builderIter->second))(arguments...));
122 }
123 
124 } // namespace EA
125 
126 #endif /* FACTORY_H_ */
bool RegisterBuilder(const std::string &builderName, T *(*objectBuilder)(ConstructorArgs...))
Register a builder for a class.
Definition: Factory.h:87
std::map< std::string, T *(*)(ConstructorArgs...)> BuildersMap
Definition: Factory.h:68
const std::vector< std::string > & GetListOfRegisteredBuilders()
Gets a vector containing the names of available registered builders.
Definition: Factory.h:104
#define COUT(level)
Definition: SmartLog.h:88
std::vector< std::string > _builderNames
Definition: Factory.h:70
IncludeFileExc.h IncludeFileExc class declaration.
Definition: Algorithm.h:21
std::unique_ptr< T > CreateObject(const std::string &name, ConstructorArgs... arguments)
Create an object.
Definition: Factory.h:109
static Factory & GetInstance()
Getter method for singleton pointer.
Definition: Factory.h:74
#define ENDL
Definition: SmartLog.h:117
Template factory class.
Definition: Factory.h:32
A simple name demangler.
Definition: Demangler.h:18
std::string _factoryName
Definition: Factory.h:67
BuildersMap _builders
Definition: Factory.h:69
Factory()
Definition: Factory.h:81
Aliased objet is an alias.