5#ifndef GKO_PUBLIC_CORE_BASE_UTILS_HELPER_HPP_
6#define GKO_PUBLIC_CORE_BASE_UTILS_HELPER_HPP_
14#include <ginkgo/core/base/exception.hpp>
15#include <ginkgo/core/base/name_demangling.hpp>
16#include <ginkgo/core/base/std_extensions.hpp>
17#include <ginkgo/core/base/types.hpp>
50 std::enable_if_t<std::is_base_of<T, U>::value>* =
nullptr>
55 template <
typename U,
typename Deleter,
56 std::enable_if_t<std::is_base_of<T, U>::value>* =
nullptr>
62 std::enable_if_t<std::is_base_of<T, U>::value>* =
nullptr>
77 T*
get()
const {
return ptr_; }
80 explicit operator bool()
const {
return ptr_; }
96 std::remove_reference_t<
decltype(*std::declval<std::decay_t<T>>())>;
99template <
typename T,
typename =
void>
100struct is_clonable_impl : std::false_type {};
103struct is_clonable_impl<T, xstd::void_t<decltype(std::declval<T>().clone())>>
107constexpr bool is_clonable()
109 return is_clonable_impl<std::decay_t<T>>::value;
113template <
typename T,
typename =
void>
114struct is_clonable_to_impl : std::false_type {};
117struct is_clonable_to_impl<
118 T, xstd::void_t<decltype(std::declval<T>().clone(
119 std::declval<std::shared_ptr<const Executor>>()))>>
123constexpr bool is_clonable_to()
125 return is_clonable_to_impl<std::decay_t<T>>::value;
130struct have_ownership_impl : std::false_type {};
132template <
typename T,
typename Deleter>
133struct have_ownership_impl<std::unique_ptr<T, Deleter>> : std::true_type {};
136struct have_ownership_impl<std::shared_ptr<T>> : std::true_type {};
139using have_ownership_s = have_ownership_impl<std::decay_t<T>>;
142constexpr bool have_ownership()
144 return have_ownership_s<T>::value;
148template <
typename Po
inter>
150 std::unique_ptr<typename std::remove_cv<pointee<Pointer>>::type>;
153template <
typename Po
inter>
154using shared_type = std::shared_ptr<pointee<Pointer>>;
174template <
typename Po
inter>
175inline detail::cloned_type<Pointer>
clone(
const Pointer& p)
177 static_assert(detail::is_clonable<detail::pointee<Pointer>>(),
178 "Object is not clonable");
179 return detail::cloned_type<Pointer>(
180 static_cast<typename std::remove_cv<detail::pointee<Pointer>
>::type*>(
181 p->clone().release()));
200template <
typename Po
inter>
201inline detail::cloned_type<Pointer>
clone(std::shared_ptr<const Executor> exec,
204 static_assert(detail::is_clonable_to<detail::pointee<Pointer>>(),
205 "Object is not clonable");
206 return detail::cloned_type<Pointer>(
207 static_cast<typename std::remove_cv<detail::pointee<Pointer>
>::type*>(
208 p->clone(std::move(exec)).release()));
225template <
typename OwningPo
inter>
226inline detail::shared_type<OwningPointer>
share(OwningPointer&& p)
228 static_assert(detail::have_ownership<OwningPointer>(),
229 "OwningPointer does not have ownership of the object");
230 static_assert(std::is_rvalue_reference<
decltype(p)>::value,
231 "p must be an rvalue for this function to work");
232 return detail::shared_type<OwningPointer>(std::move(p));
248template <
typename OwningPo
inter>
249inline typename std::remove_reference<OwningPointer>::type&&
give(
252 static_assert(detail::have_ownership<OwningPointer>(),
253 "OwningPointer does not have ownership of the object");
268template <
typename Po
inter>
269GKO_DEPRECATED(
"no longer necessary, just pass the object without lend")
270inline typename std::enable_if<detail::have_ownership_s<Pointer>::value,
271 detail::pointee<Pointer>*>::type
287template <
typename Po
inter>
288GKO_DEPRECATED(
"no longer necessary, just pass the object without lend")
289inline typename std::enable_if<!detail::have_ownership_s<Pointer>::value,
290 detail::pointee<Pointer>*>::type
308template <
typename T,
typename U>
309inline std::decay_t<T>*
as(U* obj)
311 if (
auto p =
dynamic_cast<std::decay_t<T>*
>(obj)) {
315 std::string{
"gko::as<"} +
316 name_demangling::get_type_name(
typeid(T)) +
">",
317 name_demangling::get_type_name(
typeid(*obj)));
334template <
typename T,
typename U>
335inline const std::decay_t<T>*
as(
const U* obj)
337 if (
auto p =
dynamic_cast<const std::decay_t<T>*
>(obj)) {
341 std::string{
"gko::as<"} +
342 name_demangling::get_type_name(
typeid(T)) +
">",
343 name_demangling::get_type_name(
typeid(*obj)));
359template <
typename T,
typename U>
378template <
typename T,
typename U>
397template <
typename T,
typename U>
398inline std::unique_ptr<std::decay_t<T>>
as(std::unique_ptr<U>&& obj)
400 if (
auto p =
dynamic_cast<std::decay_t<T>*
>(obj.get())) {
402 return std::unique_ptr<std::decay_t<T>>{p};
405 name_demangling::get_type_name(
typeid(*obj)));
421template <
typename T,
typename U>
422inline std::shared_ptr<std::decay_t<T>>
as(std::shared_ptr<U> obj)
424 auto ptr = std::dynamic_pointer_cast<std::decay_t<T>>(obj);
429 name_demangling::get_type_name(
typeid(*obj)));
447template <
typename T,
typename U>
448inline std::shared_ptr<const std::decay_t<T>>
as(std::shared_ptr<const U> obj)
450 auto ptr = std::dynamic_pointer_cast<const std::decay_t<T>>(obj);
455 name_demangling::get_type_name(
typeid(*obj)));
NotSupported is thrown in case it is not possible to perform the requested operation on the given obj...
Definition exception.hpp:128
This is a deleter that does not delete the object.
Definition utils_helper.hpp:467
void operator()(pointer) const noexcept
Deletes the object.
Definition utils_helper.hpp:476
This class is used for function parameters in the place of raw pointers.
Definition utils_helper.hpp:43
T & operator*() const
Definition utils_helper.hpp:71
ptr_param(const std::unique_ptr< U, Deleter > &ptr)
Initializes the ptr_param from a unique_ptr.
Definition utils_helper.hpp:57
ptr_param(const std::shared_ptr< U > &ptr)
Initializes the ptr_param from a shared_ptr.
Definition utils_helper.hpp:51
ptr_param(T *ptr)
Initializes the ptr_param from a raw pointer.
Definition utils_helper.hpp:46
T * get() const
Definition utils_helper.hpp:77
T * operator->() const
Definition utils_helper.hpp:74
ptr_param(const ptr_param< U > &ptr)
Initializes the ptr_param from a ptr_param of a derived type.
Definition utils_helper.hpp:63
The Ginkgo namespace.
Definition abstract_factory.hpp:20
std::enable_if< detail::have_ownership_s< Pointer >::value, detail::pointee< Pointer > * >::type lend(const Pointer &p)
Returns a non-owning (plain) pointer to the object pointed to by p.
Definition utils_helper.hpp:272
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::remove_reference< OwningPointer >::type && give(OwningPointer &&p)
Marks that the object pointed to by p can be given to the callee.
Definition utils_helper.hpp:249
std::decay_t< T > * as(U *obj)
Performs polymorphic type conversion.
Definition utils_helper.hpp:309
detail::shared_type< OwningPointer > share(OwningPointer &&p)
Marks the object pointed to by p as shared.
Definition utils_helper.hpp:226