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>
18namespace experimental {
19namespace distributed {
56 this->
template log<log::Logger::polymorphic_object_deleted>(exec_.get(),
74 std::shared_ptr<const Executor> exec)
const
76 this->
template log<log::Logger::polymorphic_object_create_started>(
79 this->
template log<log::Logger::polymorphic_object_create_completed>(
80 exec_.get(),
this, created.get());
107 std::unique_ptr<PolymorphicObject>
clone(
108 std::shared_ptr<const Executor> exec)
const
111 new_op->copy_from(
this);
123 std::unique_ptr<PolymorphicObject>
clone()
const
125 return this->
clone(exec_);
141 this->
template log<log::Logger::polymorphic_object_copy_started>(
142 exec_.get(), other,
this);
144 this->
template log<log::Logger::polymorphic_object_copy_completed>(
145 exec_.get(), other,
this);
164 template <
typename Derived,
typename Deleter>
166 "This function will be removed in a future release, the replacement "
167 "will copy instead of move. If a move is intended, use move_from "
173 this->
template log<log::Logger::polymorphic_object_move_started>(
174 exec_.get(), other.get(),
this);
176 this->
template log<log::Logger::polymorphic_object_move_completed>(
177 exec_.get(), other.get(),
this);
188 template <
typename Derived,
typename Deleter>
190 std::is_base_of<PolymorphicObject, std::decay_t<Derived>>::value,
192 copy_from(
const std::unique_ptr<Derived, Deleter>& other)
201 const std::shared_ptr<const PolymorphicObject>& other)
219 this->
template log<log::Logger::polymorphic_object_move_started>(
220 exec_.get(), other.
get(),
this);
222 this->
template log<log::Logger::polymorphic_object_move_completed>(
223 exec_.get(), other.
get(),
this);
259 : exec_{
std::move(exec)}
277 std::shared_ptr<const Executor> exec)
const = 0;
299 std::unique_ptr<PolymorphicObject> other) = 0;
320 std::unique_ptr<PolymorphicObject> other) = 0;
331 std::shared_ptr<const Executor> exec_;
353template <
typename AbstractObject,
typename PolymorphicBase = PolymorphicObject>
356 using PolymorphicBase::PolymorphicBase;
358 std::unique_ptr<AbstractObject> create_default(
359 std::shared_ptr<const Executor> exec)
const
361 return std::unique_ptr<AbstractObject>{
static_cast<AbstractObject*
>(
362 this->PolymorphicBase::create_default(std::move(exec)).release())};
365 std::unique_ptr<AbstractObject> create_default()
const
367 return std::unique_ptr<AbstractObject>{
static_cast<AbstractObject*
>(
368 this->PolymorphicBase::create_default().release())};
371 std::unique_ptr<AbstractObject>
clone(
372 std::shared_ptr<const Executor> exec)
const
374 return std::unique_ptr<AbstractObject>{
static_cast<AbstractObject*
>(
375 this->PolymorphicBase::clone(std::move(exec)).release())};
378 std::unique_ptr<AbstractObject>
clone()
const
380 return std::unique_ptr<AbstractObject>{
static_cast<AbstractObject*
>(
381 this->PolymorphicBase::clone().release())};
386 return static_cast<AbstractObject*
>(
387 this->PolymorphicBase::copy_from(other));
390 template <
typename Derived>
392 "This function will be removed in a future release, the replacement "
393 "will copy instead of move. If a move in intended, use move_to "
396 std::is_base_of<PolymorphicObject, std::decay_t<Derived>>::value,
397 AbstractObject>* copy_from(std::unique_ptr<Derived>&& other)
399 return static_cast<AbstractObject*
>(
400 this->PolymorphicBase::copy_from(std::move(other)));
403 template <
typename Derived>
405 std::is_base_of<PolymorphicObject, std::decay_t<Derived>>::value,
407 copy_from(
const std::unique_ptr<Derived>& other)
409 return copy_from(other.get());
412 AbstractObject* copy_from(
413 const std::shared_ptr<const PolymorphicObject>& other)
415 return copy_from(other.get());
420 return static_cast<AbstractObject*
>(
421 this->PolymorphicBase::move_from(other.
get()));
424 AbstractObject* clear()
426 return static_cast<AbstractObject*
>(this->PolymorphicBase::clear());
439#define GKO_ENABLE_SELF(_type) \
440 _type* self() noexcept { return static_cast<_type*>(this); } \
442 const _type* self() const noexcept \
444 return static_cast<const _type*>(this); \
478template <
typename ResultType>
481 using result_type = ResultType;
511 virtual void move_to(result_type* result) = 0;
520template <
typename R,
typename T>
521std::unique_ptr<R, std::function<void(R*)>> copy_and_convert_to_impl(
522 std::shared_ptr<const Executor> exec, T* obj)
524 auto obj_as_r =
dynamic_cast<R*
>(obj);
525 if (obj_as_r !=
nullptr && obj->get_executor() == exec) {
527 return {obj_as_r, [](R*) {}};
529 auto copy = R::create(exec);
530 as<ConvertibleTo<std::decay_t<R>>>(obj)->convert_to(copy);
531 return {copy.release(), std::default_delete<R>{}};
536template <
typename R,
typename T>
537std::shared_ptr<R> copy_and_convert_to_impl(
538 std::shared_ptr<const Executor> exec, std::shared_ptr<T> obj)
540 auto obj_as_r = std::dynamic_pointer_cast<R>(obj);
541 if (obj_as_r !=
nullptr && obj->get_executor() == exec) {
544 auto copy = R::create(exec);
545 as<ConvertibleTo<std::decay_t<R>>>(obj.get())->convert_to(copy);
546 return {std::move(copy)};
570template <
typename R,
typename T>
572 std::shared_ptr<const Executor> exec, T* obj)
574 return detail::copy_and_convert_to_impl<R>(std::move(exec), obj);
584template <
typename R,
typename T>
586 std::shared_ptr<const Executor> exec,
const T* obj)
588 return detail::copy_and_convert_to_impl<const R>(std::move(exec), obj);
609template <
typename R,
typename T>
611 std::shared_ptr<T> obj)
613 return detail::copy_and_convert_to_impl<R>(std::move(exec), obj);
624template <
typename R,
typename T>
626 std::shared_ptr<const Executor> exec, std::shared_ptr<const T> obj)
628 return detail::copy_and_convert_to_impl<const R>(std::move(exec), obj);
666template <
typename ConcreteObject,
typename PolymorphicBase = PolymorphicObject>
671 ConcreteObject, PolymorphicBase>::EnableAbstractPolymorphicObject;
674 std::shared_ptr<const Executor> exec)
const override
676 if constexpr (std::is_base_of_v<
679 return std::unique_ptr<ConcreteObject>{
680 new ConcreteObject(exec, self()->get_communicator())};
682 return std::unique_ptr<ConcreteObject>{
new ConcreteObject(exec)};
688 as<ConvertibleTo<ConcreteObject>>(other)->convert_to(self());
693 std::unique_ptr<PolymorphicObject> other)
override
695 as<ConvertibleTo<ConcreteObject>>(other.get())->move_to(self());
701 as<ConvertibleTo<ConcreteObject>>(other)->move_to(self());
706 std::unique_ptr<PolymorphicObject> other)
override
708 as<ConvertibleTo<ConcreteObject>>(other.get())->move_to(self());
714 if constexpr (std::is_base_of_v<
718 self()->get_communicator()};
726 GKO_ENABLE_SELF(ConcreteObject);
742template <
typename ConcreteType,
typename ResultType = ConcreteType>
745 using result_type = ResultType;
749 void convert_to(result_type* result)
const override { *result = *self(); }
751 void move_to(result_type* result)
override { *result = std::move(*self()); }
754 GKO_ENABLE_SELF(ConcreteType);
766template <
typename ConcreteType>
769 template <
typename... Args>
770 static std::unique_ptr<ConcreteType> create(Args&&... args)
772 return std::unique_ptr<ConcreteType>(
773 new ConcreteType(std::forward<Args>(args)...));
Definition polymorphic_object.hpp:479
virtual void convert_to(result_type *result) const =0
virtual void move_to(result_type *result)=0
Definition polymorphic_object.hpp:354
Definition polymorphic_object.hpp:767
Definition polymorphic_object.hpp:743
void move_to(result_type *result) override
Definition polymorphic_object.hpp:751
void convert_to(result_type *result) const override
Definition polymorphic_object.hpp:749
Definition polymorphic_object.hpp:668
PolymorphicObject * move_from_impl(std::unique_ptr< PolymorphicObject > other) override
Definition polymorphic_object.hpp:705
std::unique_ptr< PolymorphicObject > create_default_impl(std::shared_ptr< const Executor > exec) const override
Definition polymorphic_object.hpp:673
PolymorphicObject * copy_from_impl(std::unique_ptr< PolymorphicObject > other) override
Definition polymorphic_object.hpp:692
PolymorphicObject * clear_impl() override
Definition polymorphic_object.hpp:712
PolymorphicObject * move_from_impl(PolymorphicObject *other) override
Definition polymorphic_object.hpp:699
PolymorphicObject * copy_from_impl(const PolymorphicObject *other) override
Definition polymorphic_object.hpp:686
Definition polymorphic_object.hpp:52
virtual PolymorphicObject * copy_from_impl(std::unique_ptr< PolymorphicObject > other)=0
PolymorphicObject * copy_from(const PolymorphicObject *other)
Definition polymorphic_object.hpp:139
PolymorphicObject * copy_from(const std::shared_ptr< const PolymorphicObject > &other)
Definition polymorphic_object.hpp:200
std::enable_if_t< std::is_base_of< PolymorphicObject, std::decay_t< Derived > >::value, PolymorphicObject > * copy_from(const std::unique_ptr< Derived, Deleter > &other)
Definition polymorphic_object.hpp:192
virtual PolymorphicObject * copy_from_impl(const PolymorphicObject *other)=0
PolymorphicObject * move_from(ptr_param< PolymorphicObject > other)
Definition polymorphic_object.hpp:217
std::unique_ptr< PolymorphicObject > create_default() const
Definition polymorphic_object.hpp:92
std::unique_ptr< PolymorphicObject > clone() const
Definition polymorphic_object.hpp:123
std::shared_ptr< const Executor > get_executor() const noexcept
Definition polymorphic_object.hpp:243
PolymorphicObject(std::shared_ptr< const Executor > exec)
Definition polymorphic_object.hpp:258
virtual PolymorphicObject * move_from_impl(std::unique_ptr< PolymorphicObject > other)=0
std::unique_ptr< PolymorphicObject > create_default(std::shared_ptr< const Executor > exec) const
Definition polymorphic_object.hpp:73
std::unique_ptr< PolymorphicObject > clone(std::shared_ptr< const Executor > exec) const
Definition polymorphic_object.hpp:107
PolymorphicObject * clear()
Definition polymorphic_object.hpp:236
virtual PolymorphicObject * move_from_impl(PolymorphicObject *other)=0
virtual std::unique_ptr< PolymorphicObject > create_default_impl(std::shared_ptr< const Executor > exec) const =0
virtual PolymorphicObject * clear_impl()=0
Definition logger.hpp:760
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)
Definition utils_helper.hpp:173
std::unique_ptr< R, std::function< void(R *)> > copy_and_convert_to(std::shared_ptr< const Executor > exec, T *obj)
Definition polymorphic_object.hpp:571