5#ifndef GKO_PUBLIC_CORE_BASE_POLYMORPHIC_OBJECT_HPP_
6#define GKO_PUBLIC_CORE_BASE_POLYMORPHIC_OBJECT_HPP_
12#include <ginkgo/core/base/executor.hpp>
13#include <ginkgo/core/base/utils.hpp>
14#include <ginkgo/core/log/logger.hpp>
47 this->
template log<log::Logger::polymorphic_object_deleted>(exec_.get(),
65 std::shared_ptr<const Executor> exec)
const
67 this->
template log<log::Logger::polymorphic_object_create_started>(
69 auto created = this->create_default_impl(std::move(exec));
70 this->
template log<log::Logger::polymorphic_object_create_completed>(
71 exec_.get(),
this, created.get());
98 std::unique_ptr<PolymorphicObject>
clone(
99 std::shared_ptr<const Executor> exec)
const
102 new_op->copy_from(
this);
114 std::unique_ptr<PolymorphicObject>
clone()
const
116 return this->
clone(exec_);
132 this->
template log<log::Logger::polymorphic_object_copy_started>(
133 exec_.get(), other,
this);
134 auto copied = this->copy_from_impl(other);
135 this->
template log<log::Logger::polymorphic_object_copy_completed>(
136 exec_.get(), other,
this);
155 template <
typename Derived,
typename Deleter>
157 "This function will be removed in a future release, the replacement "
158 "will copy instead of move. If a move is intended, use move_from "
164 this->
template log<log::Logger::polymorphic_object_move_started>(
165 exec_.get(), other.get(),
this);
166 auto copied = this->copy_from_impl(std::move(other));
167 this->
template log<log::Logger::polymorphic_object_move_completed>(
168 exec_.get(), other.get(),
this);
179 template <
typename Derived,
typename Deleter>
181 std::is_base_of<PolymorphicObject, std::decay_t<Derived>>::value,
183 copy_from(
const std::unique_ptr<Derived, Deleter>& other)
192 const std::shared_ptr<const PolymorphicObject>& other)
210 this->
template log<log::Logger::polymorphic_object_move_started>(
211 exec_.get(), other.
get(),
this);
212 auto moved = this->move_from_impl(other.
get());
213 this->
template log<log::Logger::polymorphic_object_move_completed>(
214 exec_.get(), other.
get(),
this);
250 : exec_{
std::move(exec)}
254 explicit PolymorphicObject(
const PolymorphicObject& other)
267 virtual std::unique_ptr<PolymorphicObject> create_default_impl(
268 std::shared_ptr<const Executor> exec)
const = 0;
278 virtual PolymorphicObject* copy_from_impl(
279 const PolymorphicObject* other) = 0;
289 virtual PolymorphicObject* copy_from_impl(
290 std::unique_ptr<PolymorphicObject> other) = 0;
300 virtual PolymorphicObject* move_from_impl(PolymorphicObject* other) = 0;
310 virtual PolymorphicObject* move_from_impl(
311 std::unique_ptr<PolymorphicObject> other) = 0;
319 virtual PolymorphicObject* clear_impl() = 0;
322 std::shared_ptr<const Executor> exec_;
344template <
typename AbstractObject,
typename PolymorphicBase = PolymorphicObject>
347 using PolymorphicBase::PolymorphicBase;
349 std::unique_ptr<AbstractObject> create_default(
350 std::shared_ptr<const Executor> exec)
const
352 return std::unique_ptr<AbstractObject>{
static_cast<AbstractObject*
>(
353 this->PolymorphicBase::create_default(std::move(exec)).release())};
356 std::unique_ptr<AbstractObject> create_default()
const
358 return std::unique_ptr<AbstractObject>{
static_cast<AbstractObject*
>(
359 this->PolymorphicBase::create_default().release())};
362 std::unique_ptr<AbstractObject>
clone(
363 std::shared_ptr<const Executor> exec)
const
365 return std::unique_ptr<AbstractObject>{
static_cast<AbstractObject*
>(
366 this->PolymorphicBase::clone(std::move(exec)).release())};
369 std::unique_ptr<AbstractObject>
clone()
const
371 return std::unique_ptr<AbstractObject>{
static_cast<AbstractObject*
>(
372 this->PolymorphicBase::clone().release())};
377 return static_cast<AbstractObject*
>(
378 this->PolymorphicBase::copy_from(other));
381 template <
typename Derived>
383 "This function will be removed in a future release, the replacement "
384 "will copy instead of move. If a move in intended, use move_to "
387 std::is_base_of<PolymorphicObject, std::decay_t<Derived>>::value,
388 AbstractObject>* copy_from(std::unique_ptr<Derived>&& other)
390 return static_cast<AbstractObject*
>(
391 this->PolymorphicBase::copy_from(std::move(other)));
394 template <
typename Derived>
396 std::is_base_of<PolymorphicObject, std::decay_t<Derived>>::value,
398 copy_from(
const std::unique_ptr<Derived>& other)
400 return copy_from(other.get());
403 AbstractObject* copy_from(
404 const std::shared_ptr<const PolymorphicObject>& other)
406 return copy_from(other.get());
411 return static_cast<AbstractObject*
>(
412 this->PolymorphicBase::move_from(other.
get()));
415 AbstractObject* clear()
417 return static_cast<AbstractObject*
>(this->PolymorphicBase::clear());
430#define GKO_ENABLE_SELF(_type) \
431 _type* self() noexcept { return static_cast<_type*>(this); } \
433 const _type* self() const noexcept \
435 return static_cast<const _type*>(this); \
469template <
typename ResultType>
472 using result_type = ResultType;
502 virtual void move_to(result_type* result) = 0;
511template <
typename R,
typename T>
512std::unique_ptr<R, std::function<void(R*)>> copy_and_convert_to_impl(
513 std::shared_ptr<const Executor> exec, T* obj)
515 auto obj_as_r =
dynamic_cast<R*
>(obj);
516 if (obj_as_r !=
nullptr && obj->get_executor() == exec) {
518 return {obj_as_r, [](R*) {}};
520 auto copy = R::create(exec);
522 return {copy.release(), std::default_delete<R>{}};
527template <
typename R,
typename T>
528std::shared_ptr<R> copy_and_convert_to_impl(
529 std::shared_ptr<const Executor> exec, std::shared_ptr<T> obj)
531 auto obj_as_r = std::dynamic_pointer_cast<R>(obj);
532 if (obj_as_r !=
nullptr && obj->get_executor() == exec) {
535 auto copy = R::create(exec);
537 return {std::move(copy)};
561template <
typename R,
typename T>
563 std::shared_ptr<const Executor> exec, T* obj)
565 return detail::copy_and_convert_to_impl<R>(std::move(exec), obj);
575template <
typename R,
typename T>
577 std::shared_ptr<const Executor> exec,
const T* obj)
579 return detail::copy_and_convert_to_impl<const R>(std::move(exec), obj);
600template <
typename R,
typename T>
602 std::shared_ptr<T> obj)
604 return detail::copy_and_convert_to_impl<R>(std::move(exec), obj);
615template <
typename R,
typename T>
617 std::shared_ptr<const Executor> exec, std::shared_ptr<const T> obj)
619 return detail::copy_and_convert_to_impl<const R>(std::move(exec), obj);
660template <
typename ConcreteObject,
typename PolymorphicBase = PolymorphicObject>
665 ConcreteObject, PolymorphicBase>::EnableAbstractPolymorphicObject;
667 std::unique_ptr<PolymorphicObject> create_default_impl(
668 std::shared_ptr<const Executor> exec)
const override
670 return std::unique_ptr<ConcreteObject>{
new ConcreteObject(exec)};
680 std::unique_ptr<PolymorphicObject> other)
override
693 std::unique_ptr<PolymorphicObject> other)
override
706 GKO_ENABLE_SELF(ConcreteObject);
722template <
typename ConcreteType,
typename ResultType = ConcreteType>
725 using result_type = ResultType;
729 void convert_to(result_type* result)
const override { *result = *self(); }
731 void move_to(result_type* result)
override { *result = std::move(*self()); }
734 GKO_ENABLE_SELF(ConcreteType);
746template <
typename ConcreteType>
749 template <
typename... Args>
750 static std::unique_ptr<ConcreteType> create(Args&&... args)
752 return std::unique_ptr<ConcreteType>(
753 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:470
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:345
This mixin implements a static create() method on ConcreteType that dynamically allocates the memory,...
Definition polymorphic_object.hpp:747
This mixin is used to enable a default PolymorphicObject::copy_from() implementation for objects that...
Definition polymorphic_object.hpp:723
This mixin inherits from (a subclass of) PolymorphicObject and provides a base implementation of a ne...
Definition polymorphic_object.hpp:662
A PolymorphicObject is the abstract base for all "heavy" objects in Ginkgo that behave polymorphicall...
Definition polymorphic_object.hpp:43
PolymorphicObject * copy_from(const PolymorphicObject *other)
Copies another object into this object.
Definition polymorphic_object.hpp:130
PolymorphicObject * copy_from(const std::shared_ptr< const PolymorphicObject > &other)
Copies another object into this object.
Definition polymorphic_object.hpp:191
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:183
PolymorphicObject * move_from(ptr_param< PolymorphicObject > other)
Moves another object into this object.
Definition polymorphic_object.hpp:208
std::unique_ptr< PolymorphicObject > create_default() const
Creates a new "default" object of the same dynamic type as this object.
Definition polymorphic_object.hpp:83
std::unique_ptr< PolymorphicObject > clone() const
Creates a clone of the object.
Definition polymorphic_object.hpp:114
std::shared_ptr< const Executor > get_executor() const noexcept
Returns the Executor of the object.
Definition polymorphic_object.hpp:234
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:64
std::unique_ptr< PolymorphicObject > clone(std::shared_ptr< const Executor > exec) const
Creates a clone of the object.
Definition polymorphic_object.hpp:98
PolymorphicObject * clear()
Transforms the object into its default state.
Definition polymorphic_object.hpp:227
EnableLogging is a mixin which should be inherited by any class which wants to enable logging.
Definition logger.hpp:760
This class is used for function parameters in the place of raw pointers.
Definition utils_helper.hpp:41
T * get() const
Definition utils_helper.hpp:75
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:173
std::decay_t< T > * as(U *obj)
Performs polymorphic type conversion.
Definition utils_helper.hpp:307
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:562