33#ifndef GKO_PUBLIC_CORE_BASE_UTILS_HELPER_HPP_
34#define GKO_PUBLIC_CORE_BASE_UTILS_HELPER_HPP_
42#include <ginkgo/core/base/exception.hpp>
43#include <ginkgo/core/base/name_demangling.hpp>
44#include <ginkgo/core/base/std_extensions.hpp>
45#include <ginkgo/core/base/types.hpp>
78 std::enable_if_t<std::is_base_of<T, U>::value>* =
nullptr>
83 template <
typename U,
typename Deleter,
84 std::enable_if_t<std::is_base_of<T, U>::value>* =
nullptr>
90 std::enable_if_t<std::is_base_of<T, U>::value>* =
nullptr>
105 T*
get()
const {
return ptr_; }
108 explicit operator bool()
const {
return ptr_; }
124 std::remove_reference_t<
decltype(*std::declval<std::decay_t<T>>())>;
127template <
typename T,
typename =
void>
128struct is_clonable_impl : std::false_type {};
131struct is_clonable_impl<
T, xstd::void_t<decltype(std::declval<T>().clone())>>
135constexpr bool is_clonable()
141template <
typename T,
typename =
void>
142struct is_clonable_to_impl : std::false_type {};
145struct is_clonable_to_impl<
146 T, xstd::void_t<decltype(std::declval<T>().clone(
147 std::declval<std::shared_ptr<const Executor>>()))>>
151constexpr bool is_clonable_to()
158struct have_ownership_impl : std::false_type {};
160template <
typename T,
typename Deleter>
161struct have_ownership_impl<std::unique_ptr<T, Deleter>> : std::true_type {};
164struct have_ownership_impl<std::shared_ptr<T>> : std::true_type {};
170constexpr bool have_ownership()
172 return have_ownership_s<T>::value;
176template <
typename Po
inter>
178 std::unique_ptr<typename std::remove_cv<pointee<Pointer>>::type>;
181template <
typename Po
inter>
182using shared_type = std::shared_ptr<pointee<Pointer>>;
202template <
typename Po
inter>
205 static_assert(detail::is_clonable<detail::pointee<Pointer>>(),
206 "Object is not clonable");
207 return detail::cloned_type<Pointer>(
208 static_cast<typename std::remove_cv<detail::pointee<Pointer>
>::type*>(
209 p->clone().release()));
228template <
typename Po
inter>
229inline detail::cloned_type<Pointer>
clone(std::shared_ptr<const Executor> exec,
232 static_assert(detail::is_clonable_to<detail::pointee<Pointer>>(),
233 "Object is not clonable");
234 return detail::cloned_type<Pointer>(
235 static_cast<typename std::remove_cv<detail::pointee<Pointer>
>::type*>(
236 p->clone(std::move(exec)).release()));
253template <
typename OwningPo
inter>
256 static_assert(detail::have_ownership<OwningPointer>(),
257 "OwningPointer does not have ownership of the object");
258 static_assert(std::is_rvalue_reference<
decltype(p)>::value,
259 "p must be an rvalue for this function to work");
260 return detail::shared_type<OwningPointer>(std::move(p));
276template <
typename OwningPo
inter>
277inline typename std::remove_reference<OwningPointer>::type&&
give(
280 static_assert(detail::have_ownership<OwningPointer>(),
281 "OwningPointer does not have ownership of the object");
296template <
typename Po
inter>
297GKO_DEPRECATED(
"no longer necessary, just pass the object without lend")
299 detail::pointee<
Pointer>*>::type
315template <
typename Po
inter>
316GKO_DEPRECATED(
"no longer necessary, just pass the object without lend")
318 detail::pointee<
Pointer>*>::type
336template <
typename T,
typename U>
337inline std::decay_t<T>*
as(
U* obj)
339 if (
auto p =
dynamic_cast<std::decay_t<T>*
>(obj)) {
343 std::string{
"gko::as<"} +
344 name_demangling::get_type_name(
typeid(
T)) +
">",
345 name_demangling::get_type_name(
typeid(*obj)));
362template <
typename T,
typename U>
363inline const std::decay_t<T>*
as(
const U* obj)
365 if (
auto p =
dynamic_cast<const std::decay_t<T>*
>(obj)) {
369 std::string{
"gko::as<"} +
370 name_demangling::get_type_name(
typeid(
T)) +
">",
371 name_demangling::get_type_name(
typeid(*obj)));
387template <
typename T,
typename U>
406template <
typename T,
typename U>
425template <
typename T,
typename U>
426inline std::unique_ptr<std::decay_t<T>>
as(std::unique_ptr<U>&& obj)
428 if (
auto p =
dynamic_cast<std::decay_t<T>*
>(obj.get())) {
430 return std::unique_ptr<std::decay_t<T>>{p};
433 name_demangling::get_type_name(
typeid(*obj)));
449template <
typename T,
typename U>
450inline std::shared_ptr<std::decay_t<T>>
as(std::shared_ptr<U> obj)
452 auto ptr = std::dynamic_pointer_cast<std::decay_t<T>>(obj);
457 name_demangling::get_type_name(
typeid(*obj)));
475template <
typename T,
typename U>
476inline std::shared_ptr<const std::decay_t<T>>
as(std::shared_ptr<const U> obj)
478 auto ptr = std::dynamic_pointer_cast<const std::decay_t<T>>(obj);
483 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:156
This is a deleter that does not delete the object.
Definition utils_helper.hpp:495
void operator()(pointer) const noexcept
Deletes the object.
Definition utils_helper.hpp:504
This class is used for function parameters in the place of raw pointers.
Definition utils_helper.hpp:71
T & operator*() const
Definition utils_helper.hpp:99
ptr_param(const std::unique_ptr< U, Deleter > &ptr)
Initializes the ptr_param from a unique_ptr.
Definition utils_helper.hpp:85
ptr_param(const std::shared_ptr< U > &ptr)
Initializes the ptr_param from a shared_ptr.
Definition utils_helper.hpp:79
ptr_param(T *ptr)
Initializes the ptr_param from a raw pointer.
Definition utils_helper.hpp:74
T * get() const
Definition utils_helper.hpp:105
T * operator->() const
Definition utils_helper.hpp:102
ptr_param(const ptr_param< U > &ptr)
Initializes the ptr_param from a ptr_param of a derived type.
Definition utils_helper.hpp:91
The Ginkgo namespace.
Definition abstract_factory.hpp:48
constexpr T one()
Returns the multiplicative identity for T.
Definition math.hpp:803
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:300
detail::cloned_type< Pointer > clone(const Pointer &p)
Creates a unique clone of the object pointed to by p.
Definition utils_helper.hpp:203
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:277
std::decay_t< T > * as(U *obj)
Performs polymorphic type conversion.
Definition utils_helper.hpp:337
detail::shared_type< OwningPointer > share(OwningPointer &&p)
Marks the object pointed to by p as shared.
Definition utils_helper.hpp:254