Cantera 2.6.0

FactoryBase.h
Go to the documentation of this file.
1/**
2 * @file FactoryBase.h
3 * File contains the FactoryBase class declarations.
4 */
5
6// This file is part of Cantera. See License.txt in the top-level directory or
7// at https://cantera.org/license.txt for license and copyright information.
8
9#ifndef CT_FACTORY_BASE
10#define CT_FACTORY_BASE
11
12#include <mutex>
13#include <unordered_map>
14#include <functional>
15#include "cantera/base/ctexceptions.h"
16#include "cantera/base/global.h"
17
18 namespace Cantera
19{
20
21//! Base class for factories.
22/*!
23 * This class maintains a registry of all factories that derive from it, and
24 * deletes them all when its static method deleteFactories is invoked.
25 */
26 class FactoryBase
27{
28 public:
29
30 //! destructor
31 virtual ~FactoryBase() {
32 }
33
34 //! static function that deletes all factories in the internal registry
35 //! maintained in a static variable
36 static void deleteFactories() {
37 for (const auto& f : s_vFactoryRegistry) {
38 f->deleteFactory();
39 }
40 s_vFactoryRegistry.clear();
41 }
42
43 protected:
44
45 //! Constructor.
46 /*!
47 * Adds the current object to the current static list
48 */
49 FactoryBase() {
50 s_vFactoryRegistry.push_back(this);
51 }
52
53 //! Virtual abstract function that deletes the factory
54 /*!
55 * This must be properly defined in child objects.
56 */
57 virtual void deleteFactory() = 0;
58
59 private:
60 //! statically held list of Factories.
61 static std::vector<FactoryBase*> s_vFactoryRegistry;
62};
63
64//! Factory class that supports registering functions to create objects
65//!
66//! Template arguments for the class are the base type created by the factory,
67//! followed by the types of any arguments which need to be passed to the
68//! functions used to create objects, that is, arguments to the constructor.
69 template <class T, typename ... Args>
70 class Factory : public FactoryBase {
71 public:
72 virtual ~Factory() {}
73
74 //! Create an object using the object construction function corresponding to
75 //! "name" and the provided constructor arguments
76 T* create(const std::string& name, Args... args) {
77 return m_creators.at(canonicalize(name))(args...);
78 }
79
80 //! Register a new object construction function
81 void reg(const std::string& name, std::function<T*(Args...)> f) {
82 m_creators[name] = f;
83 }
84
85 //! Add an alias for an existing registered type
86 void addAlias(const std::string& original, const std::string& alias) {
87 if (!m_creators.count(original)) {
88 throw CanteraError("Factory::addAlias",
89 "Name '{}' not registered", original);
90 }
91 m_synonyms[alias] = original;
92 }
93
94 //! Get the canonical name registered for a type
95 std::string canonicalize(const std::string& name) {
96 if (m_creators.count(name)) {
97 return name;
98 } else if (m_synonyms.count(name)) {
99 return m_synonyms.at(name);
100 } else if (m_deprecated_names.count(name)) {
101 warn_deprecated(name,
102 fmt::format("Use '{}' instead.", m_deprecated_names.at(name)));
103 return m_deprecated_names.at(name);
104 } else {
105 throw CanteraError("Factory::canonicalize", "No such type: '{}'", name);
106 }
107 }
108
109 //! Returns true if `name` is registered with this factory
110 bool exists(const std::string& name) const {
111 return m_creators.count(name) || m_synonyms.count(name);
112 }
113
114 protected:
115 //! Add a deprecated alias for an existing registered type
116 void addDeprecatedAlias(const std::string& original,
117 const std::string& alias) {
118 if (!m_creators.count(original)) {
119 throw CanteraError("Factory::addDeprecatedAlias",
120 "Name '{}' not registered", original);
121 }
122 m_deprecated_names[alias] = original;
123 }
124
125 private:
126 std::unordered_map<std::string, std::function<T*(Args...)>> m_creators;
127
128 //! Map of synonyms to canonical names
129 std::unordered_map<std::string, std::string> m_synonyms;
130
131 //! Map of deprecated synonyms to canonical names. Use of these names will
132 //! show a deprecation warning.
133 std::unordered_map<std::string, std::string> m_deprecated_names;
134};
135
136}
137
138#endif
Cantera::CanteraError
Base class for exceptions thrown by Cantera classes.
Definition: ctexceptions.h:61
Cantera::FactoryBase
Base class for factories.
Definition: FactoryBase.h:27
Cantera::FactoryBase::deleteFactory
virtual void deleteFactory()=0
Virtual abstract function that deletes the factory.
Cantera::FactoryBase::s_vFactoryRegistry
static std::vector< FactoryBase * > s_vFactoryRegistry
statically held list of Factories.
Definition: FactoryBase.h:61
Cantera::FactoryBase::~FactoryBase
virtual ~FactoryBase()
destructor
Definition: FactoryBase.h:31
Cantera::FactoryBase::FactoryBase
FactoryBase()
Constructor.
Definition: FactoryBase.h:49
Cantera::FactoryBase::deleteFactories
static void deleteFactories()
static function that deletes all factories in the internal registry maintained in a static variable
Definition: FactoryBase.h:36
Cantera::Factory
Factory class that supports registering functions to create objects.
Definition: FactoryBase.h:70
Cantera::Factory::addDeprecatedAlias
void addDeprecatedAlias(const std::string &original, const std::string &alias)
Add a deprecated alias for an existing registered type.
Definition: FactoryBase.h:116
Cantera::Factory::exists
bool exists(const std::string &name) const
Returns true if name is registered with this factory.
Definition: FactoryBase.h:110
Cantera::Factory::canonicalize
std::string canonicalize(const std::string &name)
Get the canonical name registered for a type.
Definition: FactoryBase.h:95
Cantera::Factory::create
T * create(const std::string &name, Args... args)
Create an object using the object construction function corresponding to "name" and the provided cons...
Definition: FactoryBase.h:76
Cantera::Factory::addAlias
void addAlias(const std::string &original, const std::string &alias)
Add an alias for an existing registered type.
Definition: FactoryBase.h:86
Cantera::Factory::m_deprecated_names
std::unordered_map< std::string, std::string > m_deprecated_names
Map of deprecated synonyms to canonical names.
Definition: FactoryBase.h:133
Cantera::Factory::m_synonyms
std::unordered_map< std::string, std::string > m_synonyms
Map of synonyms to canonical names.
Definition: FactoryBase.h:129
Cantera::Factory::reg
void reg(const std::string &name, std::function< T *(Args...)> f)
Register a new object construction function.
Definition: FactoryBase.h:81
ctexceptions.h
Definitions for the classes that are thrown when Cantera experiences an error condition (also contain...
global.h
This file contains definitions for utility functions and text for modules, inputfiles,...
Cantera
Namespace for the Cantera kernel.
Definition: AnyMap.cpp:557
Cantera::warn_deprecated
void warn_deprecated(const std::string &source, const AnyBase &node, const std::string &message)
A deprecation warning for syntax in an input file.
Definition: AnyMap.cpp:1901