16#ifndef GMP_DP_OBJECT_FACTORY_HPP_
17#define GMP_DP_OBJECT_FACTORY_HPP_
28#if GMP_CPP_AT_LEAST(20)
71#if GMP_CPP_AT_LEAST(20)
72 requires std::derived_from<T, AbstractProduct>
82 this_type::instance().map_.emplace(
key,
96 this_type::instance().map_.erase(
key);
116 if (this_type::instance().map_.find(
key) == this_type::instance().map_.end())
117 throw std::invalid_argument(
"Unknown object type passed to factory!");
118 return this_type::instance().map_[
key](
args...);
132 return std::shared_ptr<AbstractProduct>(
create(
key,
args...));
146 return std::unique_ptr<AbstractProduct>(
create(
key,
args...));
153#define _GMP_GET_CONCRETE_PRODUCT_CLASS(ConcreteProduct) GMP_IF_THEN_ELSE(GMP_IS_TUPLE(ConcreteProduct), GMP_GET_TUPLE, ConcreteProduct)GMP_IF(GMP_IS_TUPLE(ConcreteProduct), (1, ConcreteProduct))
154#define _GMP_GET_CONSTRUCTOR_TYPES(ConstructorArgs) GMP_IF_THEN_ELSE(GMP_IS_TUPLE(ConstructorArgs), GMP_REMOVE_PARENS, ConstructorArgs)GMP_IF(GMP_IS_TUPLE(ConstructorArgs), (ConstructorArgs))
155#define GMP_FACTORY_REGISTER_WITH_ARGS(AbstractProduct, ConstructorArgs, ConcreteProduct) \
156 static gmp::object_factory<AbstractProduct, _GMP_GET_CONSTRUCTOR_TYPES(ConstructorArgs)>::register_type<_GMP_GET_CONCRETE_PRODUCT_CLASS(ConcreteProduct)> \
157 GMP_CONCATS(gmp_reg_, AbstractProduct, _, _GMP_GET_CONCRETE_PRODUCT_CLASS(ConcreteProduct))(GMP_IF_THEN_ELSE(GMP_IS_TUPLE(ConcreteProduct), GMP_STRINGIFY(GMP_GET_TUPLE(0, ConcreteProduct)), GMP_STRINGIFY(ConcreteProduct)));
158#define GMP_FACTORY_REGISTER_NO_ARGS(AbstractProduct, ConcreteProduct) \
159 static gmp::object_factory<AbstractProduct>::register_type<_GMP_GET_CONCRETE_PRODUCT_CLASS(ConcreteProduct)> \
160 GMP_CONCATS(gmp_reg_, AbstractProduct, _, _GMP_GET_CONCRETE_PRODUCT_CLASS(ConcreteProduct))(GMP_IF_THEN_ELSE(GMP_IS_TUPLE(ConcreteProduct), GMP_STRINGIFY(GMP_GET_TUPLE(0, ConcreteProduct)), GMP_STRINGIFY(ConcreteProduct)));
184#define GMP_FACTORY_REGISTER(AbstractProduct, ConstructorArgs, ...) \
185 _GMP_FACTORY_REGISTER_IMPL(AbstractProduct, ConstructorArgs, __VA_ARGS__)
186#define _GMP_FACTORY_REGISTER_IMPL(AbstractProduct, ConstructorArgs, ...) \
187 _GMP_FACTORY_REGISTER_IMPL_COMPAT_MSVC(AbstractProduct, ConstructorArgs, GMP_IS_EMPTY(__VA_ARGS__), GMP_TUPLE_EMPTY(ConstructorArgs), __VA_ARGS__)
188#define _GMP_FACTORY_REGISTER_IMPL_COMPAT_MSVC(AbstractProduct, ConstructorArgs, _0, _1, ...) \
189 GMP_EXPAND( GMP_OVERLOAD_INVOKE(_GMP_FACTORY_REGISTER_WHEN, _0, _1)(AbstractProduct, ConstructorArgs, __VA_ARGS__) )
190#define _GMP_FACTORY_REGISTER_WHEN_1(...)
191#define _GMP_FACTORY_REGISTER_WHEN_0_1(AbstractProduct, ConstructorArgs, ConcreteProduct, ...) \
192 GMP_FACTORY_REGISTER_NO_ARGS(AbstractProduct, ConcreteProduct) \
193 GMP_IF(GMP_BOOL(GMP_SIZE_OF_VAARGS(__VA_ARGS__)), _GMP_FACTORY_REGISTER_WHEN_1_CONTINUE) GMP_IF(GMP_BOOL(GMP_SIZE_OF_VAARGS(__VA_ARGS__)), (AbstractProduct, ConstructorArgs, __VA_ARGS__))
194#define _GMP_FACTORY_REGISTER_WHEN_0_0(AbstractProduct, ConstructorArgs, ConcreteProduct, ...) \
195 GMP_FACTORY_REGISTER_WITH_ARGS(AbstractProduct, ConstructorArgs, ConcreteProduct) \
196 GMP_IF(GMP_BOOL(GMP_SIZE_OF_VAARGS(__VA_ARGS__)), _GMP_FACTORY_REGISTER_WHEN_1_CONTINUE) GMP_IF(GMP_BOOL(GMP_SIZE_OF_VAARGS(__VA_ARGS__)), (AbstractProduct, ConstructorArgs, __VA_ARGS__))
197#define _GMP_FACTORY_REGISTER_WHEN_1_CONTINUE(AbstractProduct, ConstructorArgs, ...) \
198 GMP_DEFER(_GMP_FACTORY_REGISTER_INDIRECT)()(AbstractProduct, ConstructorArgs, __VA_ARGS__)
199#define _GMP_FACTORY_REGISTER_INDIRECT() _GMP_FACTORY_REGISTER_IMPL
A singleton-backed runtime factory that creates products by string key.
void unregister_type(const std::string &key)
Remove a previously registered product key from the factory.
AbstractProduct * create(const std::string &key, const ConstructorArgs &... args)
Create a concrete product with raw new semantics.
std::unique_ptr< AbstractProduct > create_unique(const std::string &key, const ConstructorArgs &... args)
Create a concrete product and return it as std::unique_ptr.
std::shared_ptr< AbstractProduct > create_shared(const std::string &key, const ConstructorArgs &... args)
Create a concrete product and return it as std::shared_ptr.
CRTP-based singleton helper with optional dead-reference recovery.
Register a concrete product type under a string key.
register_type(const std::string &key)
Register T with the specified lookup key.