Ginkgo  Generated from pipelines/150876808 branch based on develop. Ginkgo version 1.1.1
A numerical linear algebra library targeting many-core architectures
abstract_factory.hpp
1 /*******************************<GINKGO LICENSE>******************************
2 Copyright (c) 2017-2020, the Ginkgo authors
3 All rights reserved.
4 
5 Redistribution and use in source and binary forms, with or without
6 modification, are permitted provided that the following conditions
7 are met:
8 
9 1. Redistributions of source code must retain the above copyright
10 notice, this list of conditions and the following disclaimer.
11 
12 2. Redistributions in binary form must reproduce the above copyright
13 notice, this list of conditions and the following disclaimer in the
14 documentation and/or other materials provided with the distribution.
15 
16 3. Neither the name of the copyright holder nor the names of its
17 contributors may be used to endorse or promote products derived from
18 this software without specific prior written permission.
19 
20 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
21 IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
22 TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
23 PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24 HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25 SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26 LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 ******************************<GINKGO LICENSE>*******************************/
32 
33 #ifndef GKO_CORE_BASE_ABSTRACT_FACTORY_HPP_
34 #define GKO_CORE_BASE_ABSTRACT_FACTORY_HPP_
35 
36 
37 #include <ginkgo/core/base/polymorphic_object.hpp>
38 
39 
45 namespace gko {
46 
47 
69 template <typename AbstractProductType, typename ComponentsType>
72  AbstractFactory<AbstractProductType, ComponentsType>> {
73 public:
74  using abstract_product_type = AbstractProductType;
75  using components_type = ComponentsType;
76 
91  template <typename... Args>
92  std::unique_ptr<AbstractProductType> generate(Args &&... args) const
93  {
94  auto product = this->generate_impl({std::forward<Args>(args)...});
95  for (auto logger : this->loggers_) {
96  product->add_logger(logger);
97  }
98  return product;
99  }
100 
101 protected:
107  AbstractFactory(std::shared_ptr<const Executor> exec)
109  {}
110 
118  virtual std::unique_ptr<AbstractProductType> generate_impl(
119  ComponentsType args) const = 0;
120 };
121 
122 
146 template <typename ConcreteFactory, typename ProductType,
147  typename ParametersType, typename PolymorphicBase>
149  : public EnablePolymorphicObject<ConcreteFactory, PolymorphicBase>,
150  public EnablePolymorphicAssignment<ConcreteFactory> {
151 public:
152  friend class EnablePolymorphicObject<ConcreteFactory, PolymorphicBase>;
153 
154  using product_type = ProductType;
155  using parameters_type = ParametersType;
156  using polymorphic_base = PolymorphicBase;
157  using abstract_product_type =
158  typename PolymorphicBase::abstract_product_type;
159  using components_type = typename PolymorphicBase::components_type;
160 
161  template <typename... Args>
162  std::unique_ptr<ProductType> generate(Args &&... args) const
163  {
164  auto product = std::unique_ptr<ProductType>(static_cast<ProductType *>(
165  this->generate_impl({std::forward<Args>(args)...}).release()));
166  propagate_loggers<ConcreteFactory, ProductType>(product.get());
167  return product;
168  }
169 
175  const parameters_type &get_parameters() const noexcept
176  {
177  return parameters_;
178  };
179 
192  static parameters_type create() { return {}; }
193 
194 protected:
202  template <typename TheFactory, typename TheType>
203  typename std::enable_if<
204  std::is_base_of<log::Loggable, TheType>::value &&
205  std::is_base_of<log::Loggable, TheFactory>::value,
206  void>::type
207  propagate_loggers(TheType *product) const
208  {
209  for (auto logger : this->loggers_) {
210  product->add_logger(logger);
211  }
212  }
213 
221  template <typename TheFactory, typename TheType>
222  typename std::enable_if<
223  !std::is_base_of<log::Loggable, TheType>::value ||
224  !std::is_base_of<log::Loggable, TheFactory>::value,
225  void>::type
226  propagate_loggers(TheType *product) const
227  {}
228 
235  explicit EnableDefaultFactory(std::shared_ptr<const Executor> exec,
236  const parameters_type &parameters = {})
237  : EnablePolymorphicObject<ConcreteFactory, PolymorphicBase>(
238  std::move(exec)),
239  parameters_{parameters}
240  {}
241 
242  std::unique_ptr<abstract_product_type> generate_impl(
243  components_type args) const override
244  {
245  return std::unique_ptr<abstract_product_type>(
246  new ProductType(self(), args));
247  }
248 
249 private:
250  GKO_ENABLE_SELF(ConcreteFactory);
251 
252  ParametersType parameters_;
253 };
254 
255 
268 template <typename ConcreteParametersType, typename Factory>
270  using factory = Factory;
271 
279  std::unique_ptr<Factory> on(std::shared_ptr<const Executor> exec) const
280  {
281  return std::unique_ptr<Factory>(new Factory(exec, *self()));
282  }
283 
284 protected:
285  GKO_ENABLE_SELF(ConcreteParametersType);
286 };
287 
288 
289 } // namespace gko
290 
291 
292 #endif // GKO_CORE_BASE_ABSTRACT_FACTORY_HPP_
gko::AbstractFactory
The AbstractFactory is a generic interface template that enables easy implementation of the abstract ...
Definition: abstract_factory.hpp:70
gko::EnableAbstractPolymorphicObject
This mixin inherits from (a subclass of) PolymorphicObject and provides a base implementation of a ne...
Definition: polymorphic_object.hpp:294
gko::AbstractFactory::generate
std::unique_ptr< AbstractProductType > generate(Args &&... args) const
Creates a new product from the given components.
Definition: abstract_factory.hpp:92
gko::EnableDefaultFactory
This mixin provides a default implementation of a concrete factory.
Definition: abstract_factory.hpp:148
gko::EnableDefaultFactory::create
static parameters_type create()
Creates a new ParametersType object which can be used to instantiate a new ConcreteFactory.
Definition: abstract_factory.hpp:192
gko::EnableDefaultFactory::get_parameters
const parameters_type & get_parameters() const noexcept
Returns the parameters of the factory.
Definition: abstract_factory.hpp:175
gko::EnablePolymorphicAssignment
This mixin is used to enable a default PolymorphicObject::copy_from() implementation for objects that...
Definition: polymorphic_object.hpp:618
gko
The Ginkgo namespace.
Definition: abstract_factory.hpp:45
gko::enable_parameters_type::on
std::unique_ptr< Factory > on(std::shared_ptr< const Executor > exec) const
Creates a new factory on the specified executor.
Definition: abstract_factory.hpp:279
gko::enable_parameters_type
The enable_parameters_type mixin is used to create a base implementation of the factory parameters st...
Definition: abstract_factory.hpp:269
gko::EnablePolymorphicObject
This mixin inherits from (a subclass of) PolymorphicObject and provides a base implementation of a ne...
Definition: polymorphic_object.hpp:569