33#ifndef GKO_PUBLIC_CORE_BASE_ABSTRACT_FACTORY_HPP_
34#define GKO_PUBLIC_CORE_BASE_ABSTRACT_FACTORY_HPP_
37#include <unordered_map>
40#include <ginkgo/core/base/polymorphic_object.hpp>
72template <
typename AbstractProductType,
typename ComponentsType>
75 AbstractFactory<AbstractProductType, ComponentsType>> {
94 template <
typename...
Args>
98 this->generate_impl(components_type{std::forward<Args>(
args)...});
99 for (
auto logger : this->loggers_) {
122 virtual std::unique_ptr<abstract_product_type> generate_impl(
160 using polymorphic_base = PolymorphicBase;
161 using abstract_product_type =
162 typename PolymorphicBase::abstract_product_type;
163 using components_type =
typename PolymorphicBase::components_type;
165 template <
typename...
Args>
166 std::unique_ptr<product_type> generate(
Args&&...
args)
const
168 auto product = std::unique_ptr<product_type>(
static_cast<product_type*
>(
169 this->polymorphic_base::generate(std::forward<Args>(
args)...)
196 static parameters_type
create() {
return {}; }
212 std::unique_ptr<abstract_product_type> generate_impl(
213 components_type
args)
const override
215 return std::unique_ptr<abstract_product_type>(
216 new product_type(self(),
args));
238template <
typename ConcreteParametersType,
typename Factory>
241 using factory = Factory;
247 template <
typename...
Args>
250 this->loggers = {std::forward<Args>(
_value)...};
261 std::unique_ptr<Factory>
on(std::shared_ptr<const Executor> exec)
const
264 for (
const auto&
item : deferred_factories) {
265 item.second(exec, copy);
267 auto factory = std::unique_ptr<Factory>(
new Factory(exec, copy));
268 for (
auto&
logger : loggers) {
269 factory->add_logger(
logger);
280 std::vector<std::shared_ptr<const log::Logger>> loggers{};
288 std::unordered_map<std::string,
289 std::function<
void(std::shared_ptr<const Executor> exec,
308#define GKO_CREATE_FACTORY_PARAMETERS(_parameters_name, _factory_name) \
310 class _factory_name; \
311 struct _parameters_name##_type \
312 : public ::gko::enable_parameters_type<_parameters_name##_type, \
321template <
typename From,
typename To>
322struct is_pointer_convertible : std::is_convertible<From*, To*> {};
336template <
typename FactoryType>
345 generator_ = [](std::shared_ptr<const Executor>) {
return nullptr; };
353 std::enable_if_t<detail::is_pointer_convertible<
357 generator_ = [factory =
358 std::shared_ptr<FactoryType>(std::move(factory))](
359 std::shared_ptr<const Executor>) {
return factory; };
367 std::enable_if_t<detail::is_pointer_convertible<
370 std::unique_ptr<ConcreteFactoryType, Deleter> factory)
372 generator_ = [factory =
373 std::shared_ptr<FactoryType>(std::move(factory))](
374 std::shared_ptr<const Executor>) {
return factory; };
383 typename U =
decltype(std::declval<ParametersType>().on(
384 std::shared_ptr<const Executor>{})),
385 std::enable_if_t<detail::is_pointer_convertible<
386 typename U::element_type,
FactoryType>::value>* =
nullptr>
389 generator_ = [
parameters](std::shared_ptr<const Executor> exec)
390 -> std::shared_ptr<FactoryType> {
return parameters.on(exec); };
397 std::shared_ptr<FactoryType>
on(std::shared_ptr<const Executor> exec)
const
400 GKO_NOT_SUPPORTED(*
this);
402 return generator_(exec);
409 std::function<std::shared_ptr<FactoryType>(std::shared_ptr<const Executor>)>
422#define GKO_ENABLE_BUILD_METHOD(_factory_name) \
423 static auto build()->decltype(_factory_name::create()) \
425 return _factory_name::create(); \
427 static_assert(true, \
428 "This assert is used to counter the false positive extra " \
429 "semi-colon warnings")
432#if !(defined(__CUDACC__) || defined(__HIPCC__))
445#define GKO_FACTORY_PARAMETER(_name, ...) \
446 _name{__VA_ARGS__}; \
448 template <typename... Args> \
449 auto with_##_name(Args&&... _value) \
450 ->std::decay_t<decltype(*(this->self()))>& \
452 using type = decltype(this->_name); \
453 this->_name = type{std::forward<Args>(_value)...}; \
454 return *(this->self()); \
456 static_assert(true, \
457 "This assert is used to counter the false positive extra " \
458 "semi-colon warnings")
473#define GKO_FACTORY_PARAMETER_SCALAR(_name, _default) \
474 GKO_FACTORY_PARAMETER(_name, _default)
489#define GKO_FACTORY_PARAMETER_VECTOR(_name, ...) \
490 GKO_FACTORY_PARAMETER(_name, __VA_ARGS__)
496#define GKO_FACTORY_PARAMETER(_name, ...) \
497 _name{__VA_ARGS__}; \
499 template <typename... Args> \
500 auto with_##_name(Args&&... _value) \
501 ->std::decay_t<decltype(*(this->self()))>& \
503 GKO_NOT_IMPLEMENTED; \
504 return *(this->self()); \
506 static_assert(true, \
507 "This assert is used to counter the false positive extra " \
508 "semi-colon warnings")
510#define GKO_FACTORY_PARAMETER_SCALAR(_name, _default) \
513 template <typename Arg> \
514 auto with_##_name(Arg&& _value)->std::decay_t<decltype(*(this->self()))>& \
516 using type = decltype(this->_name); \
517 this->_name = type{std::forward<Arg>(_value)}; \
518 return *(this->self()); \
520 static_assert(true, \
521 "This assert is used to counter the false positive extra " \
522 "semi-colon warnings")
524#define GKO_FACTORY_PARAMETER_VECTOR(_name, ...) \
525 _name{__VA_ARGS__}; \
527 template <typename... Args> \
528 auto with_##_name(Args&&... _value) \
529 ->std::decay_t<decltype(*(this->self()))>& \
531 using type = decltype(this->_name); \
532 this->_name = type{std::forward<Args>(_value)...}; \
533 return *(this->self()); \
535 static_assert(true, \
536 "This assert is used to counter the false positive extra " \
537 "semi-colon warnings")
549#define GKO_DEFERRED_FACTORY_PARAMETER(_name) \
553 using _name##_type = typename decltype(_name)::element_type; \
556 auto with_##_name(::gko::deferred_factory_parameter<_name##_type> factory) \
557 ->std::decay_t<decltype(*(this->self()))>& \
559 this->_name##_generator_ = std::move(factory); \
560 this->deferred_factories[#_name] = [](const auto& exec, \
562 if (!params._name##_generator_.is_empty()) { \
563 params._name = params._name##_generator_.on(exec); \
566 return *(this->self()); \
570 ::gko::deferred_factory_parameter<_name##_type> _name##_generator_; \
573 static_assert(true, \
574 "This assert is used to counter the false positive extra " \
575 "semi-colon warnings")
587#define GKO_DEFERRED_FACTORY_VECTOR_PARAMETER(_name) \
591 using _name##_type = typename decltype(_name)::value_type::element_type; \
594 template <typename... Args, \
595 typename = std::enable_if_t<::gko::xstd::conjunction< \
596 std::is_convertible<Args, ::gko::deferred_factory_parameter< \
597 _name##_type>>...>::value>> \
598 auto with_##_name(Args&&... factories) \
599 ->std::decay_t<decltype(*(this->self()))>& \
601 this->_name##_generator_ = { \
602 ::gko::deferred_factory_parameter<_name##_type>{ \
603 std::forward<Args>(factories)}...}; \
604 this->deferred_factories[#_name] = [](const auto& exec, \
606 if (!params._name##_generator_.empty()) { \
607 params._name.clear(); \
608 for (auto& generator : params._name##_generator_) { \
609 params._name.push_back(generator.on(exec)); \
613 return *(this->self()); \
615 template <typename FactoryType, \
616 typename = std::enable_if_t<std::is_convertible< \
618 ::gko::deferred_factory_parameter<_name##_type>>::value>> \
619 auto with_##_name(const std::vector<FactoryType>& factories) \
620 ->std::decay_t<decltype(*(this->self()))>& \
622 this->_name##_generator_.clear(); \
623 for (const auto& factory : factories) { \
624 this->_name##_generator_.push_back(factory); \
626 this->deferred_factories[#_name] = [](const auto& exec, \
628 if (!params._name##_generator_.empty()) { \
629 params._name.clear(); \
630 for (auto& generator : params._name##_generator_) { \
631 params._name.push_back(generator.on(exec)); \
635 return *(this->self()); \
639 std::vector<::gko::deferred_factory_parameter<_name##_type>> \
640 _name##_generator_; \
643 static_assert(true, \
644 "This assert is used to counter the false positive extra " \
645 "semi-colon warnings")
The AbstractFactory is a generic interface template that enables easy implementation of the abstract ...
Definition abstract_factory.hpp:75
std::unique_ptr< abstract_product_type > generate(Args &&... args) const
Creates a new product from the given components.
Definition abstract_factory.hpp:95
This mixin inherits from (a subclass of) PolymorphicObject and provides a base implementation of a ne...
Definition polymorphic_object.hpp:374
This mixin provides a default implementation of a concrete factory.
Definition abstract_factory.hpp:154
static parameters_type create()
Creates a new ParametersType object which can be used to instantiate a new ConcreteFactory.
Definition abstract_factory.hpp:196
const parameters_type & get_parameters() const noexcept
Returns the parameters of the factory.
Definition abstract_factory.hpp:179
This mixin is used to enable a default PolymorphicObject::copy_from() implementation for objects that...
Definition polymorphic_object.hpp:752
This mixin inherits from (a subclass of) PolymorphicObject and provides a base implementation of a ne...
Definition polymorphic_object.hpp:691
Represents a factory parameter of factory type that can either initialized by a pre-existing factory ...
Definition abstract_factory.hpp:337
std::shared_ptr< FactoryType > on(std::shared_ptr< const Executor > exec) const
Instantiates the deferred parameter into an actual factory.
Definition abstract_factory.hpp:397
bool is_empty() const
Returns true iff the parameter is empty.
Definition abstract_factory.hpp:406
deferred_factory_parameter(std::shared_ptr< ConcreteFactoryType > factory)
Creates a deferred factory parameter from a preexisting factory with shared ownership.
Definition abstract_factory.hpp:355
deferred_factory_parameter()=default
Creates an empty deferred factory parameter.
deferred_factory_parameter(std::nullptr_t)
Creates a deferred factory parameter returning a nullptr.
Definition abstract_factory.hpp:343
deferred_factory_parameter(std::unique_ptr< ConcreteFactoryType, Deleter > factory)
Creates a deferred factory parameter by taking ownership of a preexisting factory with unique ownersh...
Definition abstract_factory.hpp:369
deferred_factory_parameter(ParametersType parameters)
Creates a deferred factory parameter object from a factory_parameters-like object.
Definition abstract_factory.hpp:387
The enable_parameters_type mixin is used to create a base implementation of the factory parameters st...
Definition abstract_factory.hpp:239
std::unique_ptr< Factory > on(std::shared_ptr< const Executor > exec) const
Creates a new factory on the specified executor.
Definition abstract_factory.hpp:261
ConcreteParametersType & with_loggers(Args &&... _value)
Provides the loggers to be added to the factory and its generated objects in a fluent interface.
Definition abstract_factory.hpp:248
The Ginkgo namespace.
Definition abstract_factory.hpp:48
constexpr T one()
Returns the multiplicative identity for T.
Definition math.hpp:803