Geogram  Version 1.9.1
A programming library of geometric algorithms
factory.h
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2000-2022 Inria
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions are met:
7  *
8  * * Redistributions of source code must retain the above copyright notice,
9  * this list of conditions and the following disclaimer.
10  * * Redistributions in binary form must reproduce the above copyright notice,
11  * this list of conditions and the following disclaimer in the documentation
12  * and/or other materials provided with the distribution.
13  * * Neither the name of the ALICE Project-Team nor the names of its
14  * contributors may be used to endorse or promote products derived from this
15  * software without specific prior written permission.
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
21  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27  * POSSIBILITY OF SUCH DAMAGE.
28  *
29  * Contact: Bruno Levy
30  *
31  * https://www.inria.fr/fr/bruno-levy
32  *
33  * Inria,
34  * Domaine de Voluceau,
35  * 78150 Le Chesnay - Rocquencourt
36  * FRANCE
37  *
38  */
39 
40 #ifndef GEOGRAM_BASIC_FACTORY
41 #define GEOGRAM_BASIC_FACTORY
42 
43 #include <geogram/basic/memory.h>
44 #include <geogram/basic/counted.h>
45 #include <string>
46 #include <map>
47 #include <vector>
48 #include <typeinfo>
49 
55 namespace GEO {
56 
69  class GEOGRAM_API InstanceRepo {
70  public:
74  typedef Counted Instance;
75 
85  template <class InstanceType>
86  static InstanceType& instance() {
87  const std::string name = typeid(InstanceType).name();
88  Instance* instance = get(name);
89  if(instance == nullptr) {
90  instance = new InstanceType;
91  add(name, instance);
92  }
93  return *static_cast<InstanceType*>(instance);
94  }
95 
96  private:
102  static void add(const std::string& name, Instance* instance);
103 
110  static Instance* get(const std::string& name);
111  };
112 
113  /**************************************************************************/
114 
136  template <class FactoryCreator>
138  public:
139  typedef typename FactoryCreator::CreatorType CreatorType;
140 
157  template <class ConcreteType>
158  static void register_creator(const std::string& name) {
159  Factory& self = instance();
160  self.registry_[name] =
161  FactoryCreator::template create<ConcreteType>;
162  }
163 
171  static CreatorType find_creator(const std::string& name) {
172  Factory& self = instance();
173  auto i = self.registry_.find(name);
174  return i == self.registry_.end() ? nullptr : i->second;
175  }
176 
183  static void list_creators(std::vector<std::string>& names) {
184  Factory& self = instance();
185  for(auto& it : self.registry_) {
186  names.push_back(it.first);
187  }
188  }
189 
196  static bool has_creator(const std::string& name) {
197  Factory& self = instance();
198  for(auto& it : self.registry_) {
199  if(it.first == name) {
200  return true;
201  }
202  }
203  return false;
204  }
205 
224  template <class ConcreteType>
233  RegisterCreator(const std::string& name) {
234  Factory::template register_creator<ConcreteType>(name);
235  }
236  };
237 
238  protected:
242  ~Factory() override {
243  }
244 
245  private:
250  static inline Factory& instance() {
251  return InstanceRepo::instance<Factory>();
252  }
253 
257  typedef std::map<std::string, CreatorType> Registry;
258  Registry registry_;
259  };
260 
267  template <class Type>
272  typedef Type* (* CreatorType)();
273 
278  template <class ConcreteType>
279  static Type* create() {
280  return new ConcreteType;
281  }
282  };
283 
291  template <class Type>
292  class Factory0 : public Factory<FactoryCreator0<Type> > {
294 
295  public:
305  static Type* create_object(const std::string& name) {
306  typename BaseClass::CreatorType creator =
308  return creator == nullptr ? nullptr : (* creator)();
309  }
310  };
311 
319  template <class Type, class Param1>
324  typedef Type* (* CreatorType)(const Param1&);
325 
330  template <class ConcreteType>
331  static Type* create(const Param1& param1) {
332  return new ConcreteType(param1);
333  }
334  };
335 
344  template <class Type, class Param1>
345  class Factory1 : public Factory<FactoryCreator1<Type, Param1> > {
347 
348  public:
359  static Type* create_object(const std::string& name, const Param1& param1) {
360  typename BaseClass::CreatorType creator =
362  return creator == nullptr ? nullptr : (* creator)(param1);
363  }
364  };
365 
384 #define geo_register_creator(FactoryType, ConcreteType, name) \
385  static FactoryType::RegisterCreator<ConcreteType> \
386  CPP_CONCAT(Factory_register_creator_, __LINE__) (name); \
387  geo_argused(CPP_CONCAT(Factory_register_creator_, __LINE__))
388 }
389 
390 #endif
Base class for reference-counted objects.
Definition: counted.h:71
Factory for types without constructor arguments.
Definition: factory.h:292
static Type * create_object(const std::string &name)
Creates a new object.
Definition: factory.h:305
Factory for types with one constructor argument.
Definition: factory.h:345
static Type * create_object(const std::string &name, const Param1 &param1)
Creates a new object with parameter(s).
Definition: factory.h:359
Factory of typed objects.
Definition: factory.h:137
static bool has_creator(const std::string &name)
Tests whether the factory has a creator.
Definition: factory.h:196
static void list_creators(std::vector< std::string > &names)
Lists all registered creators.
Definition: factory.h:183
static void register_creator(const std::string &name)
Registers a creator.
Definition: factory.h:158
~Factory() override
Factory destructor.
Definition: factory.h:242
static CreatorType find_creator(const std::string &name)
Finds a creator by name.
Definition: factory.h:171
Repository of unique instances.
Definition: factory.h:69
Counted Instance
Type of the Instances stored in the repository.
Definition: factory.h:74
static InstanceType & instance()
Gets unique instance from the repository.
Definition: factory.h:86
Base class of reference-counted objects, to be used with smart pointers.
Types and functions for memory manipulation.
Global Vorpaline namespace.
Definition: basic.h:55
Factory creator without constructor arguments.
Definition: factory.h:268
static Type * create()
Creation function.
Definition: factory.h:279
Factory creator with one argument.
Definition: factory.h:320
static Type * create(const Param1 &param1)
Creation function.
Definition: factory.h:331
Helper class to register a creator.
Definition: factory.h:225
RegisterCreator(const std::string &name)
Constructs a registration object.
Definition: factory.h:233