GGS(GenericGEANT4Simulation)Software  2.6.0
 All Data Structures Namespaces Files Functions Variables Typedefs Macros
GGSFactory.h
Go to the documentation of this file.
1 /*
2  * GGSFactory.h
3  *
4  * Created on: 03 Jan 2018
5  * Author: Nicola Mori
6  */
7 
10 #ifndef GGSFACTORY_H_
11 #define GGSFACTORY_H_
12 
13 #include "utils/GGSSmartLog.h"
14 
15 #include <map>
16 #include <vector>
17 #include <typeinfo>
18 #include <cxxabi.h>
19 
29 template<class T, typename ... ConstructorArgs>
30 class GGSFactory {
31 
32 public:
33 
38  static GGSFactory &GetInstance();
39 
46  bool RegisterBuilder(const std::string &builderName, T *(*objectBuilder)(ConstructorArgs...));
47 
56  std::unique_ptr<T> CreateObject(const std::string &name, ConstructorArgs ... arguments);
57 
62  const std::vector<std::string> &GetListOfRegisteredBuilders();
63 
64 private:
65 
66  GGSFactory();
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 
74 template<class T, typename ... ConstructorArgs>
76  static GGSFactory<T, ConstructorArgs...> instance;
77  return instance;
78 }
79 
80 // Private default constructor
81 template<class T, typename ... ConstructorArgs>
83  _factoryName = std::string("GGSFactory<");
84  int result;
85  char *demangled = abi::__cxa_demangle(typeid(T).name(), NULL, NULL, &result);
86  if (result == 0) {
87  std::string demangledStr(demangled);
88  _factoryName.append(demangledStr);
89  }
90  else {
91  _factoryName.append("UNKNOWN_CLASS");
92  }
93  free(demangled);
94  _factoryName.append(">");
95 
96 }
97 
98 template<class T, typename ... ConstructorArgs>
99 bool GGSFactory<T, ConstructorArgs...>::RegisterBuilder(const std::string &builderName,
100  T *(*objectBuilder)(ConstructorArgs...)) {
101  const std::string &routineName(_factoryName + "::RegisterBuilder");
102 
103  std::pair<typename BuildersMap::iterator, bool> insertResult = _builders.insert(
104  std::pair<std::string, T *(*)(ConstructorArgs...)>(builderName, objectBuilder));
105  if (insertResult.second) {
106  _builderNames.push_back(builderName);
107  COUT(DEBUG) << "Registered builder " << builderName << ENDL;
108  return true;
109  }
110  else {
111  COUT(ERROR) << "Impossible to register class builder " << builderName
112  << ": a class builder with the same name is already registered." << ENDL;
113  return false;
114  }
115 }
116 
117 template<class T, typename ... ConstructorArgs>
119  return _builderNames;
120 }
121 
122 template<class T, typename ... ConstructorArgs>
123 std::unique_ptr<T> GGSFactory<T, ConstructorArgs...>::CreateObject(const std::string &builderName,
124  ConstructorArgs ... arguments) {
125  const std::string &routineName(_factoryName + "::CreateObject");
126 
127  // 1. Search for a suitable builder
128  typename BuildersMap::iterator builderIter = _builders.find(builderName);
129  if (builderIter == _builders.end()) {
130  COUT(ERROR) << "No available class builder with name " << builderName << "." << ENDL;
131  return std::unique_ptr<T>((T*)(NULL));
132  }
133 
134  // 2. Build the object and return it
135  return std::unique_ptr<T>((*(builderIter->second))(arguments...));
136 
137 }
138 
139 #endif /* GGSFACTORY_H_ */
#define ENDL
Definition: GGSSmartLog.h:93
std::unique_ptr< T > CreateObject(const std::string &name, ConstructorArgs...arguments)
Create an object.
Definition: GGSFactory.h:123
#define COUT(level)
Smart log macro. It writes on stdout only if the specified verbosity level is lesser than the maximum...
Definition: GGSSmartLog.h:66
const std::vector< std::string > & GetListOfRegisteredBuilders()
Gets a vector containing the names of available registered builders.
Definition: GGSFactory.h:118
Template factory class.
Definition: GGSFactory.h:30
static GGSFactory & GetInstance()
Getter method for singleton pointer.
Definition: GGSFactory.h:75
bool RegisterBuilder(const std::string &builderName, T *(*objectBuilder)(ConstructorArgs...))
Register a builder for a class.
Definition: GGSFactory.h:99