8#include <ryujin/base/compile_time_options.h>
10#include <deal.II/base/exceptions.h>
11#include <deal.II/base/patterns.h>
47 template <
typename Base,
typename... Args>
56 using Creator = std::function<std::unique_ptr<Base>(Args...)>;
62 requires std::derived_from<T, Base> && std::constructible_from<T, Args...>
75 requires std::derived_from<T, Base> && std::constructible_from<T, Args...>
82 static std::vector<std::unique_ptr<Base>>
create(Args... args);
88 static std::vector<std::string>
names(Args... args);
95 static dealii::Patterns::Selection
96 selection(
const std::vector<std::unique_ptr<Base>> &objects);
102 static Base &
select(
const std::vector<std::unique_ptr<Base>> &objects,
103 const std::string &name);
111 static std::vector<Creator> &creators();
116 static std::vector<Creator> defaults();
123 template <
typename Base,
typename... Args>
124 template <
typename T>
125 requires std::derived_from<T, Base> && std::constructible_from<T, Args...>
128 return [](Args... args) -> std::unique_ptr<Base> {
129 return std::make_unique<T>(args...);
134 template <
typename Base,
typename... Args>
135 template <
typename T>
136 requires std::derived_from<T, Base> && std::constructible_from<T, Args...>
146 template <
typename Base,
typename... Args>
149 static std::vector<Creator> creators = defaults();
154 template <
typename Base,
typename... Args>
157 creators().push_back(std::move(creator));
161 template <
typename Base,
typename... Args>
162 std::vector<std::unique_ptr<Base>>
165 std::vector<std::unique_ptr<Base>> objects;
166 std::set<std::string> names;
168 for (
const auto &creator : creators()) {
169 auto object = creator(args...);
170 const auto [it, inserted] = names.insert(object->name());
173 dealii::ExcMessage(
"Two entries of a library share the name »" +
174 object->name() +
"«"));
175 objects.push_back(std::move(
object));
182 template <
typename Base,
typename... Args>
185 std::vector<std::string> names;
186 for (
const auto &
object : create(args...))
187 names.push_back(object->name());
192 template <
typename Base,
typename... Args>
194 const std::vector<std::unique_ptr<Base>> &objects)
197 for (
const auto &
object : objects)
198 names += (names.empty() ?
"" :
"|") + object->name();
199 return dealii::Patterns::Selection(names);
203 template <
typename Base,
typename... Args>
205 const std::vector<std::unique_ptr<Base>> &objects,
206 const std::string &name)
209 std::find_if(objects.begin(), objects.end(), [&](
const auto &
object) {
210 return object->name() == name;
213 AssertThrow(it != objects.end(),
214 dealii::ExcMessage(
"No entry of the library has the name »" +
static std::vector< std::string > names(Args... args)
static Base & select(const std::vector< std::unique_ptr< Base > > &objects, const std::string &name)
static std::vector< std::unique_ptr< Base > > create(Args... args)
std::function< std::unique_ptr< Base >(Args...)> Creator
static dealii::Patterns::Selection selection(const std::vector< std::unique_ptr< Base > > &objects)
DEAL_II_HOST_DEVICE_ALWAYS_INLINE FT add(const FT &flux_left_ij, const FT &flux_right_ij)