Cantera  3.1.0a1
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 
17 namespace 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 {
27 public:
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 
42 protected:
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 
58 private:
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.
68 template <class T, typename ... Args>
69 class Factory : public FactoryBase {
70 public:
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 
114 protected:
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 
125 private:
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.
Definition: ctexceptions.h:66
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.
Definition: FactoryBase.h:129
std::unordered_map< string, string > m_deprecated_names
Map of deprecated synonyms to canonical names.
Definition: FactoryBase.h:133
bool exists(const string &name) const
Returns true if name is registered with this factory.
Definition: FactoryBase.h:110
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.
Definition: FactoryBase.h:116
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