GGS(GenericGEANT4Simulation)Software  2.7.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 <cxxabi.h>
16 #include <map>
17 #include <typeinfo>
18 #include <vector>
19 
29 template <class T, typename... ConstructorArgs> class GGSFactory {
30 
31 public:
36  static GGSFactory &GetInstance();
37 
44  bool RegisterBuilder(const std::string &builderName, T *(*objectBuilder)(ConstructorArgs...));
45 
54  std::unique_ptr<T> CreateObject(const std::string &name, ConstructorArgs... arguments);
55 
60  const std::vector<std::string> &GetListOfRegisteredBuilders();
61 
62 private:
63  GGSFactory();
64  std::string _factoryName;
65  typedef std::map<std::string, T *(*)(ConstructorArgs...)> BuildersMap;
66  BuildersMap _builders;
67  std::vector<std::string> _builderNames;
68 };
69 
70 template <class T, typename... ConstructorArgs>
72  static GGSFactory<T, ConstructorArgs...> instance;
73  return instance;
74 }
75 
76 // Private default constructor
77 template <class T, typename... ConstructorArgs> GGSFactory<T, ConstructorArgs...>::GGSFactory() {
78  _factoryName = std::string("GGSFactory<");
79  int result;
80  char *demangled = abi::__cxa_demangle(typeid(T).name(), NULL, NULL, &result);
81  if (result == 0) {
82  std::string demangledStr(demangled);
83  _factoryName.append(demangledStr);
84  } else {
85  _factoryName.append("UNKNOWN_CLASS");
86  }
87  free(demangled);
88  _factoryName.append(">");
89 }
90 
91 template <class T, typename... ConstructorArgs>
92 bool GGSFactory<T, ConstructorArgs...>::RegisterBuilder(const std::string &builderName,
93  T *(*objectBuilder)(ConstructorArgs...)) {
94  const std::string &routineName(_factoryName + "::RegisterBuilder");
95 
96  std::pair<typename BuildersMap::iterator, bool> insertResult =
97  _builders.insert(std::pair<std::string, T *(*)(ConstructorArgs...)>(builderName, objectBuilder));
98  if (insertResult.second) {
99  _builderNames.push_back(builderName);
100  COUT(DEBUG) << "Registered builder " << builderName << ENDL;
101  return true;
102  } else {
103  COUT(ERROR) << "Impossible to register class builder " << builderName
104  << ": a class builder with the same name is already registered." << ENDL;
105  return false;
106  }
107 }
108 
109 template <class T, typename... ConstructorArgs>
111  return _builderNames;
112 }
113 
114 template <class T, typename... ConstructorArgs>
115 std::unique_ptr<T> GGSFactory<T, ConstructorArgs...>::CreateObject(const std::string &builderName,
116  ConstructorArgs... arguments) {
117  const std::string &routineName(_factoryName + "::CreateObject");
118 
119  // 1. Search for a suitable builder
120  typename BuildersMap::iterator builderIter = _builders.find(builderName);
121  if (builderIter == _builders.end()) {
122  COUT(ERROR) << "No available class builder with name " << builderName << "." << ENDL;
123  return std::unique_ptr<T>((T *)(NULL));
124  }
125 
126  // 2. Build the object and return it
127  return std::unique_ptr<T>((*(builderIter->second))(arguments...));
128 }
129 
130 #endif /* GGSFACTORY_H_ */
#define ENDL
Definition: GGSSmartLog.h:105
std::unique_ptr< T > CreateObject(const std::string &name, ConstructorArgs...arguments)
Create an object.
Definition: GGSFactory.h:115
#define COUT(level)
Smart log macro. It writes on stdout only if the specified verbosity level is lesser than the maximum...
Definition: GGSSmartLog.h:76
const std::vector< std::string > & GetListOfRegisteredBuilders()
Gets a vector containing the names of available registered builders.
Definition: GGSFactory.h:110
Template factory class.
Definition: GGSFactory.h:29
static GGSFactory & GetInstance()
Getter method for singleton pointer.
Definition: GGSFactory.h:71
bool RegisterBuilder(const std::string &builderName, T *(*objectBuilder)(ConstructorArgs...))
Register a builder for a class.
Definition: GGSFactory.h:92