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