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