factory.hpp
1 /*---------------------------------------------------------------------------*\
2  *
3  * mimmo
4  *
5  * Copyright (C) 2015-2021 OPTIMAD engineering Srl
6  *
7  * -------------------------------------------------------------------------
8  * License
9  * This file is part of mimmo.
10  *
11  * mimmo is free software: you can redistribute it and/or modify it
12  * under the terms of the GNU Lesser General Public License v3 (LGPL)
13  * as published by the Free Software Foundation.
14  *
15  * mimmo is distributed in the hope that it will be useful, but WITHOUT
16  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
17  * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
18  * License for more details.
19  *
20  * You should have received a copy of the GNU Lesser General Public License
21  * along with mimmo. If not, see <http://www.gnu.org/licenses/>.
22  *
23  \ *---------------------------------------------------------------------------*/
24 
25 #ifndef BLOCK_FACTORY_HPP
26 #define BLOCK_FACTORY_HPP
27 
28 #include <unordered_map>
29 #include <vector>
30 #include <configuration.hpp>
31 #include <bitpit_common.hpp>
32 
33 
34 
35 namespace mimmo{
36 
46 template <class Base>
47 class Factory {
48 
49 private:
51  Factory() : defaultCreator(0) {};
53  Factory(const Factory&);
55  Factory& operator=(const Factory&);
57  ~Factory() {
58  deleteCreators();
59  };
60 
61 public:
68  public:
70  virtual ~AbstractCreator() {}
74  virtual Base* create(const bitpit::Config::Section & xml_root) const = 0;
75  };
76 
78  static Factory& instance(){
79  static Factory factory;
80  return factory;
81  }
87  static Base * create(const std::string name, const bitpit::Config::Section & xml_root){
88  Factory<Base>& factory = instance();
89  if (factory.creators.count(name) == 0) return 0;
90  return (factory.creators[name])->create(xml_root);
91  }
92 
96  void removeCreator(const std::string & name){
97  if (creators.count(name) > 0) {
98  delete creators[name];
99  creators.erase(name);
100  }
101  return;
102  }
103 
109  int addCreator(const std::string name, const AbstractCreator* creator){
110  removeCreator(name);
111  creators[name]= creator;
112  return (int) creators.size() + 1;
113  }
114 
119  bool containsCreator(const std::string & name){
120  return creators.count(name) > 0;
121  }
122 
127  int setDefaultCreator(const AbstractCreator* creator){
128  defaultCreator = creator;
129  return 0;
130  }
131 
134  std::vector<std::string> mapRegisteredBlocks(){
135  std::vector<std::string> result(creators.size());
136  int counter = 0;
137  for(auto &val : creators){
138  result[counter] = val.first;
139  ++counter;
140  }
141  return result;
142  }
143 
144 private:
145  const AbstractCreator* defaultCreator;
146  std::unordered_map<std::string, const AbstractCreator*> creators;
151  void deleteCreators(){
152  for(auto & val : creators){
153  delete val.second;
154  }
155  creators.clear();
156  };
157 };
158 
167 template <class Base, class Derived>
168 class Creator : public Factory<Base>::AbstractCreator {
169 
175 typedef Derived* (*CreateFn) (const bitpit::Config::Section & );
176 
177 public:
178  CreateFn createFn;
183  Creator(CreateFn fn = nullptr) : createFn(fn) {}
189  virtual Derived* create(const bitpit::Config::Section & xml_root) const {
190  return (createFn ? createFn(xml_root) : new Derived(xml_root));
191  };
192 };
193 
194 };
195 
196 
206 #define REGISTER(Base, Derived, name) \
207 /* register a Derived class with its xml default constructor that will be instantiate as Base*/ \
208 __attribute__((unused)) static int factory_##Base##_##Derived = mimmo::Factory<Base>::instance().addCreator(name, new mimmo::Creator<Base, Derived>());
209 
222 #define REGISTER_CUSTOM(Base, Derived, name, customCreator) \
223 /* register a Derived class a custom xml constructor/creator method that will be instantiate as Base*/ \
224 __attribute__((unused)) static int factory_##Base##_##Derived = mimmo::Factory<Base>::instance().addCreator(name, new Creator<Base, Derived>(&customCreator));
225 
232 template<class Base>
233 inline bool isREGISTERED(const std::string name){
235 }
236 
237 #endif
std::vector< std::string > mapRegisteredBlocks()
Definition: factory.hpp:134
Factory base template singleton for automatic factorization of executable classes.
Definition: factory.hpp:47
virtual Base * create(const bitpit::Config::Section &xml_root) const =0
static Factory & instance()
Definition: factory.hpp:78
void removeCreator(const std::string &name)
Definition: factory.hpp:96
int addCreator(const std::string name, const AbstractCreator *creator)
Definition: factory.hpp:109
static Base * create(const std::string name, const bitpit::Config::Section &xml_root)
Definition: factory.hpp:87
virtual Derived * create(const bitpit::Config::Section &xml_root) const
Definition: factory.hpp:189
int setDefaultCreator(const AbstractCreator *creator)
Definition: factory.hpp:127
bool isREGISTERED(const std::string name)
Definition: factory.hpp:233
bool containsCreator(const std::string &name)
Definition: factory.hpp:119
Abstract class embedded in Factory to link creators of type Base* <>(const bitpit::Config::Section & ...
Definition: factory.hpp:67
CreateFn createFn
Definition: factory.hpp:178
Creator(CreateFn fn=nullptr)
Definition: factory.hpp:183
Template class to create an object Base * = new Derived creator class, where Derived is a generic der...
Definition: factory.hpp:168