/home/runner/work/spades/spades/Source/Factory.H Source File

SPADES API: /home/runner/work/spades/spades/Source/Factory.H Source File
SPADES API
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 spades {
12
64template <class Base, class... Args>
65struct Factory
66{
72 static std::unique_ptr<Base> create(const std::string& key, Args... args)
73 {
75 auto ptr = table().at(key)(std::forward<Args>(args)...);
76 amrex::Print() << "Creating " << Base::base_identifier()
77 << " instance: " << key << std::endl;
78 return ptr;
79 }
80
85 static void print(std::ostream& os)
86 {
87 const auto& tbl = table();
88 os << Base::base_identifier() << " " << tbl.size() << std::endl;
89 for (const auto& it : tbl) {
90 os << " - " << it.first << std::endl;
91 }
92 }
93
95 template <class T>
96 struct Register : public Base
97 {
98 friend T;
99 static bool registered;
100
101 static bool add_sub_type()
102 {
103 // TODO: Add checks against multiple registration
104 Factory::table()[T::identifier()] =
105 [](Args... args) -> std::unique_ptr<Base> {
106 return std::unique_ptr<Base>(
107 new T(std::forward<Args>(args)...));
108 };
109 return true;
110 }
111
112 ~Register() override
113 {
114 if (registered) {
115 const auto& tbl = Factory::table();
116 const auto& it = tbl.find(T::identifier());
117 registered = (it != tbl.end());
118 }
119 }
120
121 private:
122 Register() { (void)registered; }
123 };
124
125 virtual ~Factory() = default;
126 friend Base;
127
128private:
129 using CreatorFunc = std::unique_ptr<Base> (*)(Args...);
130 using LookupTable = std::unordered_map<std::string, CreatorFunc>;
131
134 static void key_exists_or_error(const std::string& key)
135 {
136 const auto& tbl = table();
137 if (tbl.find(key) == tbl.end()) {
138 // Print valid options
139 if (amrex::ParallelDescriptor::IOProcessor()) {
140 print(std::cout);
141 }
142 // Quit with error
143 amrex::Abort(
144 "In " + Base::base_identifier() +
145 " cannot find instance: " + key);
146 }
147 }
148
151 {
152 static LookupTable tbl;
153 return tbl;
154 }
155
156 Factory() = default;
157};
158
159template <class Base, class... Args>
160template <class T>
161bool Factory<Base, Args...>::Register<T>::registered =
163
164} // namespace spades
165#endif /* FACTORY_H */
Solver for PArallel Discrete Event Simulation.
Definition ConsoleIO.cpp:14
Class to handle registration of subclass for runtime selection.
Definition Factory.H:97
static bool registered
Definition Factory.H:99
friend T
Definition Factory.H:98
~Register() override
Definition Factory.H:112
static bool add_sub_type()
Definition Factory.H:101
Register()
Definition Factory.H:122
Definition Factory.H:66
static void print(std::ostream &os)
Definition Factory.H:85
static void key_exists_or_error(const std::string &key)
Definition Factory.H:134
std::unordered_map< std::string, CreatorFunc > LookupTable
Definition Factory.H:130
virtual ~Factory()=default
static std::unique_ptr< Base > create(const std::string &key, Args... args)
Definition Factory.H:72
std::unique_ptr< Base >(*)(Args...) CreatorFunc
Definition Factory.H:129
Factory()=default
static LookupTable & table()
Lookup table containing all registered instances.
Definition Factory.H:150
friend Base
Definition Factory.H:126