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