Graphite Version 3
An experimental 3D geometry processing program
Loading...
Searching...
No Matches
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
45#include <string>
46#include <map>
47#include <vector>
48#include <typeinfo>
49
56// Latest clang complains too often about empty \par statements in documentation
57#ifdef GEO_COMPILER_CLANG
58#pragma clang diagnostic push
59#pragma clang diagnostic ignored "-Wdocumentation"
60#endif
61
62namespace GEO {
63
76 class GEOGRAM_API InstanceRepo {
77 public:
82
92 template <class InstanceType>
93 static InstanceType& instance() {
94 const std::string name = typeid(InstanceType).name();
95 Instance* instance = get(name);
96 if(instance == nullptr) {
97 instance = new InstanceType;
98 add(name, instance);
99 }
100 return *static_cast<InstanceType*>(instance);
101 }
102
103 private:
109 static void add(const std::string& name, Instance* instance);
110
117 static Instance* get(const std::string& name);
118 };
119
120 /**************************************************************************/
121
143 template <class FactoryCreator>
145 public:
146 typedef typename FactoryCreator::CreatorType CreatorType;
147
164 template <class ConcreteType>
165 static void register_creator(const std::string& name) {
166 Factory& self = instance();
167 self.registry_[name] =
168 FactoryCreator::template create<ConcreteType>;
169 }
170
178 static CreatorType find_creator(const std::string& name) {
179 Factory& self = instance();
180 auto i = self.registry_.find(name);
181 return i == self.registry_.end() ? nullptr : i->second;
182 }
183
190 static void list_creators(std::vector<std::string>& names) {
191 Factory& self = instance();
192 for(auto& it : self.registry_) {
193 names.push_back(it.first);
194 }
195 }
196
203 static bool has_creator(const std::string& name) {
204 Factory& self = instance();
205 for(auto& it : self.registry_) {
206 if(it.first == name) {
207 return true;
208 }
209 }
210 return false;
211 }
212
231 template <class ConcreteType>
240 RegisterCreator(const std::string& name) {
241 Factory::template register_creator<ConcreteType>(name);
242 }
243 };
244
245 protected:
249 ~Factory() override {
250 }
251
252 private:
257 static inline Factory& instance() {
258 return InstanceRepo::instance<Factory>();
259 }
260
264 typedef std::map<std::string, CreatorType> Registry;
265 Registry registry_;
266 };
267
274 template <class Type>
279 typedef Type* (* CreatorType)();
280
285 template <class ConcreteType>
286 static Type* create() {
287 return new ConcreteType;
288 }
289 };
290
298 template <class Type>
299 class Factory0 : public Factory<FactoryCreator0<Type> > {
301
302 public:
312 static Type* create_object(const std::string& name) {
313 typename BaseClass::CreatorType creator =
315 return creator == nullptr ? nullptr : (* creator)();
316 }
317 };
318
326 template <class Type, class Param1>
331 typedef Type* (* CreatorType)(const Param1&);
332
337 template <class ConcreteType>
338 static Type* create(const Param1& param1) {
339 return new ConcreteType(param1);
340 }
341 };
342
351 template <class Type, class Param1>
352 class Factory1 : public Factory<FactoryCreator1<Type, Param1> > {
354
355 public:
366 static Type* create_object(
367 const std::string& name, const Param1& param1
368 ) {
369 typename BaseClass::CreatorType creator =
371 return creator == nullptr ? nullptr : (* creator)(param1);
372 }
373 };
374
393#define geo_register_creator(FactoryType, ConcreteType, name) \
394 static FactoryType::RegisterCreator<ConcreteType> \
395 CPP_CONCAT(Factory_register_creator_, __LINE__) (name); \
396 geo_argused(CPP_CONCAT(Factory_register_creator_, __LINE__))
397}
398
399
400#ifdef GEO_COMPILER_CLANG
401#pragma clang diagnostic pop
402#endif
403
404#endif
Base class for reference-counted objects.
Definition counted.h:71
Factory for types without constructor arguments.
Definition factory.h:299
static Type * create_object(const std::string &name)
Creates a new object.
Definition factory.h:312
Factory for types with one constructor argument.
Definition factory.h:352
static Type * create_object(const std::string &name, const Param1 &param1)
Creates a new object with parameter(s).
Definition factory.h:366
Factory of typed objects.
Definition factory.h:144
static bool has_creator(const std::string &name)
Tests whether the factory has a creator.
Definition factory.h:203
static void list_creators(std::vector< std::string > &names)
Lists all registered creators.
Definition factory.h:190
static void register_creator(const std::string &name)
Registers a creator.
Definition factory.h:165
~Factory() override
Factory destructor.
Definition factory.h:249
static CreatorType find_creator(const std::string &name)
Finds a creator by name.
Definition factory.h:178
Repository of unique instances.
Definition factory.h:76
Counted Instance
Type of the Instances stored in the repository.
Definition factory.h:81
static InstanceType & instance()
Gets unique instance from the repository.
Definition factory.h:93
Base class of reference-counted objects, to be used with smart pointers.
Types and functions for memory manipulation.
Global Vorpaline namespace.
Factory creator without constructor arguments.
Definition factory.h:275
static Type * create()
Creation function.
Definition factory.h:286
Factory creator with one argument.
Definition factory.h:327
static Type * create(const Param1 &param1)
Creation function.
Definition factory.h:338
Helper class to register a creator.
Definition factory.h:232
RegisterCreator(const std::string &name)
Constructs a registration object.
Definition factory.h:240