/home/runner/work/amr-wind/amr-wind/amr-wind/core/Factory.H Source File

AMR-Wind API: /home/runner/work/amr-wind/amr-wind/amr-wind/core/Factory.H Source File
AMR-Wind API v0.1.0
CFD solver for wind plant simulations
Loading...
Searching...
No Matches
Factory.H
Go to the documentation of this file.
1#ifndef FACTORY_H
2#define FACTORY_H
3
4#include <memory>
5#include <unordered_map>
6#include <iostream>
7
8#include "AMReX_Print.H"
9#include "AMReX.H"
10
11namespace amr_wind {
12
63template <class Base, class... Args>
64struct Factory
65{
71 static std::unique_ptr<Base> create(const std::string& key, Args... args)
72 {
74 auto ptr = table().at(key)(std::forward<Args>(args)...);
75 amrex::Print() << "Creating " << Base::base_identifier()
76 << " instance: " << key << std::endl;
77 return ptr;
78 }
79
84 static void print(std::ostream& os)
85 {
86 const auto& tbl = table();
87 os << Base::base_identifier() << " " << tbl.size() << std::endl;
88 for (const auto& it : tbl) {
89 os << " - " << it.first << std::endl;
90 }
91 }
92
94 template <class T>
95 struct Register : public Base
96 {
97 friend T;
98 static bool registered;
99
100 static bool add_sub_type()
101 {
102 // TODO: Add checks against multiple registration
103 Factory::table()[T::identifier()] =
104 [](Args... args) -> std::unique_ptr<Base> {
105 return std::unique_ptr<Base>(
106 new T(std::forward<Args>(args)...));
107 };
108 return true;
109 }
110
111 ~Register() override
112 {
113 if (registered) {
114 const auto& tbl = Factory::table();
115 const auto it = tbl.find(T::identifier());
116 registered = (it != tbl.end());
117 }
118 }
119
120 private:
121 Register() { (void)registered; }
122 };
123
124 virtual ~Factory() = default;
125 friend Base;
126
127private:
128 using CreatorFunc = std::unique_ptr<Base> (*)(Args...);
129 using LookupTable = std::unordered_map<std::string, CreatorFunc>;
130
133 static void key_exists_or_error(const std::string& key)
134 {
135 const auto& tbl = table();
136 if (tbl.find(key) == tbl.end()) {
137 // Print valid options
138 if (amrex::ParallelDescriptor::IOProcessor()) {
139 print(std::cout);
140 }
141 // Quit with error
142 amrex::Abort(
143 "In " + Base::base_identifier() +
144 " cannot find instance: " + key);
145 }
146 }
147
150 {
151 static LookupTable tbl;
152 return tbl;
153 }
154
155 Factory() = default;
156};
157
158template <class Base, class... Args>
159template <class T>
160bool Factory<Base, Args...>::Register<T>::registered =
162
163} // namespace amr_wind
164
165#endif /* FACTORY_H */
Definition BCInterface.cpp:7
Class to handle registration of subclass for runtime selection.
Definition Factory.H:96
Register()
Definition Factory.H:121
friend T
Definition Factory.H:97
~Register() override
Definition Factory.H:111
static bool registered
Definition Factory.H:98
static bool add_sub_type()
Definition Factory.H:100
Definition Factory.H:65
static std::unique_ptr< Base > create(const std::string &key, Args... args)
Definition Factory.H:71
std::unordered_map< std::string, CreatorFunc > LookupTable
Definition Factory.H:129
friend Base
Definition Factory.H:125
static void print(std::ostream &os)
Definition Factory.H:84
virtual ~Factory()=default
static void key_exists_or_error(const std::string &key)
Definition Factory.H:133
static LookupTable & table()
Lookup table containing all registered instances.
Definition Factory.H:149
std::unique_ptr< Base >(*)(Args...) CreatorFunc
Definition Factory.H:128