29template<
bool many,
typename Base,
typename... Args>
33 using OutputT = std::conditional_t<many, std::vector<std::unique_ptr<Base>>, std::unique_ptr<Base>>;
34 using GeneratorT = std::function<OutputT(Args...)>;
42 void add(
const std::string & tag, GeneratorT factory)
44 if (m_tags.contains(tag)) {
throw std::logic_error(
"Tag '" + tag +
"' already present"); }
45 m_tags[tag] = std::move(factory);
51 OutputT
create(
const std::string & tag,
auto &&... args)
53 if (
auto it = m_tags.find(tag); it != m_tags.end()) {
54 return std::invoke(it->second, std::forward<
decltype(args)>(args)...);
57 ss <<
"Could not find tag '" << tag <<
"'. ";
58 ss <<
"Available tags: [";
59 for (
auto i = 0u;
const auto & [tag_i, f] : m_tags) {
60 ss <<
"'" << tag_i <<
"'";
61 if (++i < m_tags.size()) { ss <<
", "; }
64 throw std::logic_error(ss.str());
69 std::map<std::string, GeneratorT> m_tags;
75template<
typename Base,
typename... Args>
81template<
typename Base,
typename... Args>
85template<
bool many,
typename Base,
typename... Args>
90template<
typename Base,
typename... Args>
91concept Constructible =
requires { has_factory<
false, Base, Args...>::value ==
true; };
94template<
typename Base,
typename... Args>
98#define EZ_GENERAL_FACTORY_DECLARE(many, Base, ...) \
99 EZ_GLOBAL_DECLARE(ezconfig::GeneralFactory<many, Base __VA_OPT__(, ) __VA_ARGS__>); \
101 struct ezconfig::has_factory<many, Base __VA_OPT__(, ) __VA_ARGS__> : public std::true_type \
105#define EZ_GENERAL_FACTORY_DEFINE(many, Base, ...) \
106 EZ_GLOBAL_DEFINE(ezconfig::GeneralFactory<many, Base __VA_OPT__(, ) __VA_ARGS__>)
109#define EZ_GENERAL_FACTORY_INSTANCE(many, Base, ...) \
110 EZ_GLOBAL_INSTANCE(ezconfig::GeneralFactory<many, Base __VA_OPT__(, ) __VA_ARGS__>)
113#define EZ_GENERAL_FACTORY_REGISTER(many, tag, creator, Base, ...) \
115 &ezconfig::GeneralFactory<many, Base __VA_OPT__(, ) __VA_ARGS__>::add, \
116 EZ_GENERAL_FACTORY_INSTANCE(many, Base, __VA_ARGS__), \
120#define EZ_FACTORY_DECLARE(Base, ...) EZ_GENERAL_FACTORY_DECLARE(false, Base, __VA_ARGS__)
121#define EZ_FACTORY_DEFINE(Base, ...) EZ_GENERAL_FACTORY_DEFINE(false, Base, __VA_ARGS__)
122#define EZ_FACTORY_INSTANCE(Base, ...) EZ_GENERAL_FACTORY_INSTANCE(false, Base, __VA_ARGS__)
123#define EZ_FACTORY_REGISTER(tag, creator, Base, ...) EZ_GENERAL_FACTORY_REGISTER(false, tag, creator, Base, __VA_ARGS__)
A Factory creates objects in a class hierarchy.
OutputT create(const std::string &tag, auto &&... args)
Create an object.
void add(const std::string &tag, GeneratorT factory)
Add a factory method to the factory.
Concept that identifies existing factories.
Concept that identifies existing factories.
Utilities to define and maintain a global instance.
Type trait that marks existing factories.