5#ifndef GKO_PUBLIC_CORE_BASE_UTILS_HELPER_HPP_
6#define GKO_PUBLIC_CORE_BASE_UTILS_HELPER_HPP_
13#include <ginkgo/core/base/exception.hpp>
14#include <ginkgo/core/base/name_demangling.hpp>
15#include <ginkgo/core/base/types.hpp>
48 std::enable_if_t<std::is_base_of<T, U>::value>* =
nullptr>
53 template <
typename U,
typename Deleter,
54 std::enable_if_t<std::is_base_of<T, U>::value>* =
nullptr>
60 std::enable_if_t<std::is_base_of<T, U>::value>* =
nullptr>
75 T*
get()
const {
return ptr_; }
78 explicit operator bool()
const {
return ptr_; }
94 std::remove_reference_t<
decltype(*std::declval<std::decay_t<T>>())>;
97template <
typename T,
typename =
void>
98struct is_cloneable_impl : std::false_type {};
101struct is_cloneable_impl<T,
std::
void_t<decltype(std::declval<T>().clone())>>
105constexpr bool is_cloneable()
107 return is_cloneable_impl<std::decay_t<T>>::value;
111template <
typename T,
typename =
void>
112struct is_cloneable_to_impl : std::false_type {};
115struct is_cloneable_to_impl<
116 T,
std::
void_t<decltype(std::declval<T>().clone(
117 std::declval<std::shared_ptr<const Executor>>()))>>
121constexpr bool is_cloneable_to()
123 return is_cloneable_to_impl<std::decay_t<T>>::value;
128struct have_ownership_impl : std::false_type {};
130template <
typename T,
typename Deleter>
131struct have_ownership_impl<
std::unique_ptr<T, Deleter>> : std::true_type {};
134struct have_ownership_impl<
std::shared_ptr<T>> : std::true_type {};
137using have_ownership_s = have_ownership_impl<std::decay_t<T>>;
140constexpr bool have_ownership()
142 return have_ownership_s<T>::value;
146template <
typename Po
inter>
148 std::unique_ptr<typename std::remove_cv<pointee<Pointer>>::type>;
151template <
typename Po
inter>
152using shared_type = std::shared_ptr<pointee<Pointer>>;
172template <
typename Po
inter>
173inline detail::cloned_type<Pointer>
clone(
const Pointer& p)
175 static_assert(detail::is_cloneable<detail::pointee<Pointer>>(),
176 "Object is not cloneable");
177 return detail::cloned_type<Pointer>(
178 static_cast<typename std::remove_cv<detail::pointee<Pointer>
>::type*>(
179 p->clone().release()));
198template <
typename Po
inter>
199inline detail::cloned_type<Pointer>
clone(std::shared_ptr<const Executor> exec,
202 static_assert(detail::is_cloneable_to<detail::pointee<Pointer>>(),
203 "Object is not cloneable");
204 return detail::cloned_type<Pointer>(
205 static_cast<typename std::remove_cv<detail::pointee<Pointer>
>::type*>(
206 p->clone(std::move(exec)).release()));
223template <
typename OwningPo
inter>
224inline detail::shared_type<OwningPointer>
share(OwningPointer&& p)
226 static_assert(detail::have_ownership<OwningPointer>(),
227 "OwningPointer does not have ownership of the object");
228 static_assert(std::is_rvalue_reference<
decltype(p)>::value,
229 "p must be an rvalue for this function to work");
230 return detail::shared_type<OwningPointer>(std::move(p));
246template <
typename OwningPo
inter>
247inline typename std::remove_reference<OwningPointer>::type&&
give(
250 static_assert(detail::have_ownership<OwningPointer>(),
251 "OwningPointer does not have ownership of the object");
266template <
typename Po
inter>
267GKO_DEPRECATED(
"no longer necessary, just pass the object without lend")
268inline typename
std::enable_if<detail::have_ownership_s<Pointer>::value,
269 detail::pointee<Pointer>*>::type
285template <
typename Po
inter>
286GKO_DEPRECATED(
"no longer necessary, just pass the object without lend")
287inline typename
std::enable_if<!detail::have_ownership_s<Pointer>::value,
288 detail::pointee<Pointer>*>::type
306template <
typename T,
typename U>
307inline std::decay_t<T>*
as(U* obj)
309 if (
auto p =
dynamic_cast<std::decay_t<T>*
>(obj)) {
313 std::string{
"gko::as<"} +
314 name_demangling::get_type_name(
typeid(T)) +
">",
315 name_demangling::get_type_name(
typeid(*obj)));
332template <
typename T,
typename U>
333inline const std::decay_t<T>*
as(
const U* obj)
335 if (
auto p =
dynamic_cast<const std::decay_t<T>*
>(obj)) {
339 std::string{
"gko::as<"} +
340 name_demangling::get_type_name(
typeid(T)) +
">",
341 name_demangling::get_type_name(
typeid(*obj)));
357template <
typename T,
typename U>
376template <
typename T,
typename U>
395template <
typename T,
typename U>
396inline std::unique_ptr<std::decay_t<T>>
as(std::unique_ptr<U>&& obj)
398 if (
auto p =
dynamic_cast<std::decay_t<T>*
>(obj.get())) {
400 return std::unique_ptr<std::decay_t<T>>{p};
403 name_demangling::get_type_name(
typeid(*obj)));
419template <
typename T,
typename U>
420inline std::shared_ptr<std::decay_t<T>>
as(std::shared_ptr<U> obj)
422 auto ptr = std::dynamic_pointer_cast<std::decay_t<T>>(obj);
427 name_demangling::get_type_name(
typeid(*obj)));
445template <
typename T,
typename U>
446inline std::shared_ptr<const std::decay_t<T>>
as(std::shared_ptr<const U> obj)
448 auto ptr = std::dynamic_pointer_cast<const std::decay_t<T>>(obj);
453 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:127
This is a deleter that does not delete the object.
Definition utils_helper.hpp:465
void operator()(pointer) const noexcept
Deletes the object.
Definition utils_helper.hpp:474
This class is used for function parameters in the place of raw pointers.
Definition utils_helper.hpp:41
T & operator*() const
Definition utils_helper.hpp:69
ptr_param(const std::unique_ptr< U, Deleter > &ptr)
Initializes the ptr_param from a unique_ptr.
Definition utils_helper.hpp:55
ptr_param(const std::shared_ptr< U > &ptr)
Initializes the ptr_param from a shared_ptr.
Definition utils_helper.hpp:49
ptr_param(T *ptr)
Initializes the ptr_param from a raw pointer.
Definition utils_helper.hpp:44
T * get() const
Definition utils_helper.hpp:75
T * operator->() const
Definition utils_helper.hpp:72
ptr_param(const ptr_param< U > &ptr)
Initializes the ptr_param from a ptr_param of a derived type.
Definition utils_helper.hpp:61
typename detail::make_void< Ts... >::type void_t
Use the custom implementation, since the std::void_t used in is_matrix_type_builder seems to trigger ...
Definition std_extensions.hpp:47
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:270
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::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:247
std::decay_t< T > * as(U *obj)
Performs polymorphic type conversion.
Definition utils_helper.hpp:307
detail::shared_type< OwningPointer > share(OwningPointer &&p)
Marks the object pointed to by p as shared.
Definition utils_helper.hpp:224