5 #ifndef GKO_PUBLIC_CORE_BASE_UTILS_HELPER_HPP_
6 #define GKO_PUBLIC_CORE_BASE_UTILS_HELPER_HPP_
11 #include <type_traits>
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>>())>;
97 template <
typename T,
typename =
void>
98 struct is_cloneable_impl : std::false_type {};
100 template <
typename T>
101 struct is_cloneable_impl<T, std::
void_t<decltype(std::declval<T>().clone())>>
104 template <
typename T>
105 constexpr
bool is_cloneable()
107 return is_cloneable_impl<std::decay_t<T>>::value;
111 template <
typename T,
typename =
void>
112 struct is_cloneable_to_impl : std::false_type {};
114 template <
typename T>
115 struct is_cloneable_to_impl<
116 T, std::
void_t<decltype(std::declval<T>().clone(
117 std::declval<std::shared_ptr<const Executor>>()))>>
120 template <
typename T>
121 constexpr
bool is_cloneable_to()
123 return is_cloneable_to_impl<std::decay_t<T>>::value;
127 template <
typename T>
128 struct have_ownership_impl : std::false_type {};
130 template <
typename T,
typename Deleter>
131 struct have_ownership_impl<std::unique_ptr<T, Deleter>> : std::true_type {};
133 template <
typename T>
134 struct have_ownership_impl<std::shared_ptr<T>> : std::true_type {};
136 template <
typename T>
137 using have_ownership_s = have_ownership_impl<std::decay_t<T>>;
139 template <
typename T>
140 constexpr
bool have_ownership()
142 return have_ownership_s<T>::value;
146 template <
typename Po
inter>
148 std::unique_ptr<typename std::remove_cv<pointee<Pointer>>::type>;
151 template <
typename Po
inter>
152 using shared_type = std::shared_ptr<pointee<Pointer>>;
172 template <
typename Po
inter>
173 inline 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()));
198 template <
typename Po
inter>
199 inline 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()));
223 template <
typename OwningPo
inter>
224 inline 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));
246 template <
typename OwningPo
inter>
247 inline typename std::remove_reference<OwningPointer>::type&&
give(
250 static_assert(detail::have_ownership<OwningPointer>(),
251 "OwningPointer does not have ownership of the object");
266 template <
typename Po
inter>
267 GKO_DEPRECATED(
"no longer necessary, just pass the object without lend")
268 inline typename std::enable_if<detail::have_ownership_s<Pointer>::value,
269 detail::pointee<Pointer>*>::type
285 template <
typename Po
inter>
286 GKO_DEPRECATED(
"no longer necessary, just pass the object without lend")
287 inline typename std::enable_if<!detail::have_ownership_s<Pointer>::value,
288 detail::pointee<Pointer>*>::type
306 template <
typename T,
typename U>
307 inline 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)));
332 template <
typename T,
typename U>
333 inline 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)));
357 template <
typename T,
typename U>
360 return as<T>(obj.
get());
376 template <
typename T,
typename U>
379 return as<T>(obj.
get());
395 template <
typename T,
typename U>
396 inline 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)));
419 template <
typename T,
typename U>
420 inline 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)));
445 template <
typename T,
typename U>
446 inline 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)));
464 template <
typename T>
478 template <
typename T>
490 #endif // GKO_PUBLIC_CORE_BASE_UTILS_HELPER_HPP_