5#ifndef GKO_PUBLIC_CORE_BASE_POLYMORPHIC_OBJECT_HPP_
6#define GKO_PUBLIC_CORE_BASE_POLYMORPHIC_OBJECT_HPP_
13#include <ginkgo/core/base/executor.hpp>
14#include <ginkgo/core/base/utils.hpp>
15#include <ginkgo/core/log/logger.hpp>
48 this->
template log<log::Logger::polymorphic_object_deleted>(exec_.get(),
66 std::shared_ptr<const Executor> exec)
const
68 this->
template log<log::Logger::polymorphic_object_create_started>(
70 auto created = this->create_default_impl(std::move(exec));
71 this->
template log<log::Logger::polymorphic_object_create_completed>(
72 exec_.get(),
this, created.get());
99 std::unique_ptr<PolymorphicObject>
clone(
100 std::shared_ptr<const Executor> exec)
const
103 new_op->copy_from(
this);
115 std::unique_ptr<PolymorphicObject>
clone()
const
117 return this->
clone(exec_);
133 this->
template log<log::Logger::polymorphic_object_copy_started>(
134 exec_.get(), other,
this);
135 auto copied = this->copy_from_impl(other);
136 this->
template log<log::Logger::polymorphic_object_copy_completed>(
137 exec_.get(), other,
this);
156 template <
typename Derived,
typename Deleter>
158 "This function will be removed in a future release, the replacement "
159 "will copy instead of move. If a move is intended, use move_from "
165 this->
template log<log::Logger::polymorphic_object_move_started>(
166 exec_.get(), other.get(),
this);
167 auto copied = this->copy_from_impl(std::move(other));
168 this->
template log<log::Logger::polymorphic_object_move_completed>(
169 exec_.get(), other.get(),
this);
180 template <
typename Derived,
typename Deleter>
182 std::is_base_of<PolymorphicObject, std::decay_t<Derived>>::value,
184 copy_from(
const std::unique_ptr<Derived, Deleter>& other)
193 const std::shared_ptr<const PolymorphicObject>& other)
211 this->
template log<log::Logger::polymorphic_object_move_started>(
212 exec_.get(), other.
get(),
this);
213 auto moved = this->move_from_impl(other.
get());
214 this->
template log<log::Logger::polymorphic_object_move_completed>(
215 exec_.get(), other.
get(),
this);
251 : exec_{std::move(exec)}
255 explicit PolymorphicObject(
const PolymorphicObject& other)
268 virtual std::unique_ptr<PolymorphicObject> create_default_impl(
269 std::shared_ptr<const Executor> exec)
const = 0;
279 virtual PolymorphicObject* copy_from_impl(
280 const PolymorphicObject* other) = 0;
290 virtual PolymorphicObject* copy_from_impl(
291 std::unique_ptr<PolymorphicObject> other) = 0;
301 virtual PolymorphicObject* move_from_impl(PolymorphicObject* other) = 0;
311 virtual PolymorphicObject* move_from_impl(
312 std::unique_ptr<PolymorphicObject> other) = 0;
320 virtual PolymorphicObject* clear_impl() = 0;
323 std::shared_ptr<const Executor> exec_;
345template <
typename AbstractObject,
typename PolymorphicBase = PolymorphicObject>
348 using PolymorphicBase::PolymorphicBase;
350 std::unique_ptr<AbstractObject> create_default(
351 std::shared_ptr<const Executor> exec)
const
353 return std::unique_ptr<AbstractObject>{
static_cast<AbstractObject*
>(
354 this->PolymorphicBase::create_default(std::move(exec)).release())};
357 std::unique_ptr<AbstractObject> create_default()
const
359 return std::unique_ptr<AbstractObject>{
static_cast<AbstractObject*
>(
360 this->PolymorphicBase::create_default().release())};
363 std::unique_ptr<AbstractObject>
clone(
364 std::shared_ptr<const Executor> exec)
const
366 return std::unique_ptr<AbstractObject>{
static_cast<AbstractObject*
>(
367 this->PolymorphicBase::clone(std::move(exec)).release())};
370 std::unique_ptr<AbstractObject>
clone()
const
372 return std::unique_ptr<AbstractObject>{
static_cast<AbstractObject*
>(
373 this->PolymorphicBase::clone().release())};
378 return static_cast<AbstractObject*
>(
379 this->PolymorphicBase::copy_from(other));
382 template <
typename Derived>
384 "This function will be removed in a future release, the replacement "
385 "will copy instead of move. If a move in intended, use move_to "
388 std::is_base_of<PolymorphicObject, std::decay_t<Derived>>::value,
389 AbstractObject>* copy_from(std::unique_ptr<Derived>&& other)
391 return static_cast<AbstractObject*
>(
392 this->PolymorphicBase::copy_from(std::move(other)));
395 template <
typename Derived>
397 std::is_base_of<PolymorphicObject, std::decay_t<Derived>>::value,
399 copy_from(
const std::unique_ptr<Derived>& other)
401 return copy_from(other.get());
404 AbstractObject* copy_from(
405 const std::shared_ptr<const PolymorphicObject>& other)
407 return copy_from(other.get());
412 return static_cast<AbstractObject*
>(
413 this->PolymorphicBase::move_from(other.
get()));
416 AbstractObject* clear()
418 return static_cast<AbstractObject*
>(this->PolymorphicBase::clear());
431#define GKO_ENABLE_SELF(_type) \
432 _type* self() noexcept { return static_cast<_type*>(this); } \
434 const _type* self() const noexcept \
436 return static_cast<const _type*>(this); \
470template <
typename ResultType>
473 using result_type = ResultType;
503 virtual void move_to(result_type* result) = 0;
512template <
typename R,
typename T>
513std::unique_ptr<R, std::function<void(R*)>> copy_and_convert_to_impl(
514 std::shared_ptr<const Executor> exec, T* obj)
516 auto obj_as_r =
dynamic_cast<R*
>(obj);
517 if (obj_as_r !=
nullptr && obj->get_executor() == exec) {
519 return {obj_as_r, [](R*) {}};
521 auto copy = R::create(exec);
523 return {copy.release(), std::default_delete<R>{}};
528template <
typename R,
typename T>
529std::shared_ptr<R> copy_and_convert_to_impl(
530 std::shared_ptr<const Executor> exec, std::shared_ptr<T> obj)
532 auto obj_as_r = std::dynamic_pointer_cast<R>(obj);
533 if (obj_as_r !=
nullptr && obj->get_executor() == exec) {
536 auto copy = R::create(exec);
538 return {std::move(copy)};
562template <
typename R,
typename T>
564 std::shared_ptr<const Executor> exec, T* obj)
566 return detail::copy_and_convert_to_impl<R>(std::move(exec), obj);
576template <
typename R,
typename T>
578 std::shared_ptr<const Executor> exec,
const T* obj)
580 return detail::copy_and_convert_to_impl<const R>(std::move(exec), obj);
601template <
typename R,
typename T>
603 std::shared_ptr<T> obj)
605 return detail::copy_and_convert_to_impl<R>(std::move(exec), obj);
616template <
typename R,
typename T>
618 std::shared_ptr<const Executor> exec, std::shared_ptr<const T> obj)
620 return detail::copy_and_convert_to_impl<const R>(std::move(exec), obj);
661template <
typename ConcreteObject,
typename PolymorphicBase = PolymorphicObject>
666 ConcreteObject, PolymorphicBase>::EnableAbstractPolymorphicObject;
668 std::unique_ptr<PolymorphicObject> create_default_impl(
669 std::shared_ptr<const Executor> exec)
const override
671 return std::unique_ptr<ConcreteObject>{
new ConcreteObject(exec)};
681 std::unique_ptr<PolymorphicObject> other)
override
694 std::unique_ptr<PolymorphicObject> other)
override
707 GKO_ENABLE_SELF(ConcreteObject);
723template <
typename ConcreteType,
typename ResultType = ConcreteType>
726 using result_type = ResultType;
730 void convert_to(result_type* result)
const override { *result = *self(); }
732 void move_to(result_type* result)
override { *result = std::move(*self()); }
735 GKO_ENABLE_SELF(ConcreteType);
747template <
typename ConcreteType>
750 template <
typename... Args>
751 static std::unique_ptr<ConcreteType> create(Args&&... args)
753 return std::unique_ptr<ConcreteType>(
754 new ConcreteType(std::forward<Args>(args)...));
ConvertibleTo interface is used to mark that the implementer can be converted to the object of Result...
Definition polymorphic_object.hpp:471
virtual void convert_to(result_type *result) const =0
Converts the implementer to an object of type result_type.
virtual void move_to(result_type *result)=0
Converts the implementer to an object of type result_type by moving data from this object.
This mixin inherits from (a subclass of) PolymorphicObject and provides a base implementation of a ne...
Definition polymorphic_object.hpp:346
This mixin implements a static create() method on ConcreteType that dynamically allocates the memory,...
Definition polymorphic_object.hpp:748
This mixin is used to enable a default PolymorphicObject::copy_from() implementation for objects that...
Definition polymorphic_object.hpp:724
This mixin inherits from (a subclass of) PolymorphicObject and provides a base implementation of a ne...
Definition polymorphic_object.hpp:663
A PolymorphicObject is the abstract base for all "heavy" objects in Ginkgo that behave polymorphicall...
Definition polymorphic_object.hpp:44
PolymorphicObject * copy_from(const PolymorphicObject *other)
Copies another object into this object.
Definition polymorphic_object.hpp:131
PolymorphicObject * copy_from(const std::shared_ptr< const PolymorphicObject > &other)
Copies another object into this object.
Definition polymorphic_object.hpp:192
std::enable_if_t< std::is_base_of< PolymorphicObject, std::decay_t< Derived > >::value, PolymorphicObject > * copy_from(const std::unique_ptr< Derived, Deleter > &other)
Copies another object into this object.
Definition polymorphic_object.hpp:184
PolymorphicObject * move_from(ptr_param< PolymorphicObject > other)
Moves another object into this object.
Definition polymorphic_object.hpp:209
std::unique_ptr< PolymorphicObject > create_default() const
Creates a new "default" object of the same dynamic type as this object.
Definition polymorphic_object.hpp:84
std::unique_ptr< PolymorphicObject > clone() const
Creates a clone of the object.
Definition polymorphic_object.hpp:115
std::shared_ptr< const Executor > get_executor() const noexcept
Returns the Executor of the object.
Definition polymorphic_object.hpp:235
std::unique_ptr< PolymorphicObject > create_default(std::shared_ptr< const Executor > exec) const
Creates a new "default" object of the same dynamic type as this object.
Definition polymorphic_object.hpp:65
std::unique_ptr< PolymorphicObject > clone(std::shared_ptr< const Executor > exec) const
Creates a clone of the object.
Definition polymorphic_object.hpp:99
PolymorphicObject * clear()
Transforms the object into its default state.
Definition polymorphic_object.hpp:228
EnableLogging is a mixin which should be inherited by any class which wants to enable logging.
Definition logger.hpp:749
This class is used for function parameters in the place of raw pointers.
Definition utils_helper.hpp:43
T * get() const
Definition utils_helper.hpp:77
The Ginkgo namespace.
Definition abstract_factory.hpp:20
detail::cloned_type< Pointer > clone(const Pointer &p)
Creates a unique clone of the object pointed to by p.
Definition utils_helper.hpp:175
std::decay_t< T > * as(U *obj)
Performs polymorphic type conversion.
Definition utils_helper.hpp:309
std::unique_ptr< R, std::function< void(R *)> > copy_and_convert_to(std::shared_ptr< const Executor > exec, T *obj)
Converts the object to R and places it on Executor exec.
Definition polymorphic_object.hpp:563