Ginkgo Generated from branch based on master. Ginkgo version 1.7.0
A numerical linear algebra library targeting many-core architectures
Loading...
Searching...
No Matches
utils_helper.hpp
1/*******************************<GINKGO LICENSE>******************************
2Copyright (c) 2017-2023, the Ginkgo authors
3All rights reserved.
4
5Redistribution and use in source and binary forms, with or without
6modification, are permitted provided that the following conditions
7are met:
8
91. Redistributions of source code must retain the above copyright
10notice, this list of conditions and the following disclaimer.
11
122. Redistributions in binary form must reproduce the above copyright
13notice, this list of conditions and the following disclaimer in the
14documentation and/or other materials provided with the distribution.
15
163. Neither the name of the copyright holder nor the names of its
17contributors may be used to endorse or promote products derived from
18this software without specific prior written permission.
19
20THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
21IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
22TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
23PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31******************************<GINKGO LICENSE>*******************************/
32
33#ifndef GKO_PUBLIC_CORE_BASE_UTILS_HELPER_HPP_
34#define GKO_PUBLIC_CORE_BASE_UTILS_HELPER_HPP_
35
36
37#include <functional>
38#include <memory>
39#include <type_traits>
40
41
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>
46
47
48#ifndef NDEBUG
49#include <cstdio>
50#endif // NDEBUG
51
52
53namespace gko {
54
55
56class Executor;
57
58
70template <typename T>
71class ptr_param {
72public:
74 ptr_param(T* ptr) : ptr_{ptr} {}
75
77 template <typename U,
78 std::enable_if_t<std::is_base_of<T, U>::value>* = nullptr>
79 ptr_param(const std::shared_ptr<U>& ptr) : ptr_param{ptr.get()}
80 {}
81
83 template <typename U, typename Deleter,
84 std::enable_if_t<std::is_base_of<T, U>::value>* = nullptr>
85 ptr_param(const std::unique_ptr<U, Deleter>& ptr) : ptr_param{ptr.get()}
86 {}
87
89 template <typename U,
90 std::enable_if_t<std::is_base_of<T, U>::value>* = nullptr>
91 ptr_param(const ptr_param<U>& ptr) : ptr_param{ptr.get()}
92 {}
93
94 ptr_param(const ptr_param&) = default;
95
96 ptr_param(ptr_param&&) = default;
97
99 T& operator*() const { return *ptr_; }
100
102 T* operator->() const { return ptr_; }
103
105 T* get() const { return ptr_; }
106
108 explicit operator bool() const { return ptr_; }
109
110 ptr_param& operator=(const ptr_param&) = delete;
111
112 ptr_param& operator=(ptr_param&&) = delete;
113
114private:
115 T* ptr_;
116};
117
118
119namespace detail {
120
121
122template <typename T>
123using pointee =
124 std::remove_reference_t<decltype(*std::declval<std::decay_t<T>>())>;
125
126
127template <typename T, typename = void>
128struct is_clonable_impl : std::false_type {};
129
130template <typename T>
131struct is_clonable_impl<T, xstd::void_t<decltype(std::declval<T>().clone())>>
132 : std::true_type {};
133
134template <typename T>
135constexpr bool is_clonable()
136{
138}
139
140
141template <typename T, typename = void>
142struct is_clonable_to_impl : std::false_type {};
143
144template <typename T>
145struct is_clonable_to_impl<
146 T, xstd::void_t<decltype(std::declval<T>().clone(
147 std::declval<std::shared_ptr<const Executor>>()))>>
148 : std::true_type {};
149
150template <typename T>
151constexpr bool is_clonable_to()
152{
154}
155
156
157template <typename T>
158struct have_ownership_impl : std::false_type {};
159
160template <typename T, typename Deleter>
161struct have_ownership_impl<std::unique_ptr<T, Deleter>> : std::true_type {};
162
163template <typename T>
164struct have_ownership_impl<std::shared_ptr<T>> : std::true_type {};
165
166template <typename T>
167using have_ownership_s = have_ownership_impl<std::decay_t<T>>;
168
169template <typename T>
170constexpr bool have_ownership()
171{
172 return have_ownership_s<T>::value;
173}
174
175
176template <typename Pointer>
177using cloned_type =
178 std::unique_ptr<typename std::remove_cv<pointee<Pointer>>::type>;
179
180
181template <typename Pointer>
182using shared_type = std::shared_ptr<pointee<Pointer>>;
183
184
185} // namespace detail
186
187
202template <typename Pointer>
203inline detail::cloned_type<Pointer> clone(const Pointer& p)
204{
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()));
210}
211
212
228template <typename Pointer>
229inline detail::cloned_type<Pointer> clone(std::shared_ptr<const Executor> exec,
230 const Pointer& p)
231{
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()));
237}
238
239
253template <typename OwningPointer>
254inline detail::shared_type<OwningPointer> share(OwningPointer&& p)
255{
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));
261}
262
263
276template <typename OwningPointer>
277inline typename std::remove_reference<OwningPointer>::type&& give(
278 OwningPointer&& p)
279{
280 static_assert(detail::have_ownership<OwningPointer>(),
281 "OwningPointer does not have ownership of the object");
282 return std::move(p);
283}
284
285
296template <typename Pointer>
297GKO_DEPRECATED("no longer necessary, just pass the object without lend")
298inline typename std::enable_if<detail::have_ownership_s<Pointer>::value,
299 detail::pointee<Pointer>*>::type
301{
302 return p.get();
303}
304
315template <typename Pointer>
316GKO_DEPRECATED("no longer necessary, just pass the object without lend")
317inline typename std::enable_if<!detail::have_ownership_s<Pointer>::value,
318 detail::pointee<Pointer>*>::type
320{
321 return p;
322}
323
324
336template <typename T, typename U>
337inline std::decay_t<T>* as(U* obj)
338{
339 if (auto p = dynamic_cast<std::decay_t<T>*>(obj)) {
340 return p;
341 } else {
343 std::string{"gko::as<"} +
344 name_demangling::get_type_name(typeid(T)) + ">",
345 name_demangling::get_type_name(typeid(*obj)));
346 }
347}
348
362template <typename T, typename U>
363inline const std::decay_t<T>* as(const U* obj)
364{
365 if (auto p = dynamic_cast<const std::decay_t<T>*>(obj)) {
366 return p;
367 } else {
369 std::string{"gko::as<"} +
370 name_demangling::get_type_name(typeid(T)) + ">",
371 name_demangling::get_type_name(typeid(*obj)));
372 }
373}
374
375
387template <typename T, typename U>
388inline std::decay_t<T>* as(ptr_param<U> obj)
389{
390 return as<T>(obj.get());
391}
392
406template <typename T, typename U>
407inline const std::decay_t<T>* as(ptr_param<const U> obj)
408{
409 return as<T>(obj.get());
410}
411
412
425template <typename T, typename U>
426inline std::unique_ptr<std::decay_t<T>> as(std::unique_ptr<U>&& obj)
427{
428 if (auto p = dynamic_cast<std::decay_t<T>*>(obj.get())) {
429 obj.release();
430 return std::unique_ptr<std::decay_t<T>>{p};
431 } else {
433 name_demangling::get_type_name(typeid(*obj)));
434 }
435}
436
437
449template <typename T, typename U>
450inline std::shared_ptr<std::decay_t<T>> as(std::shared_ptr<U> obj)
451{
452 auto ptr = std::dynamic_pointer_cast<std::decay_t<T>>(obj);
453 if (ptr) {
454 return ptr;
455 } else {
457 name_demangling::get_type_name(typeid(*obj)));
458 }
459}
460
461
475template <typename T, typename U>
476inline std::shared_ptr<const std::decay_t<T>> as(std::shared_ptr<const U> obj)
477{
478 auto ptr = std::dynamic_pointer_cast<const std::decay_t<T>>(obj);
479 if (ptr) {
480 return ptr;
481 } else {
483 name_demangling::get_type_name(typeid(*obj)));
484 }
485}
486
487
494template <typename T>
496public:
497 using pointer = T*;
498
504 void operator()(pointer) const noexcept {}
505};
506
507// a specialization for arrays
508template <typename T>
509class null_deleter<T[]> {
510public:
511 using pointer = T[];
512
513 void operator()(pointer) const noexcept {}
514};
515
516
517} // namespace gko
518
519
520#endif // GKO_PUBLIC_CORE_BASE_UTILS_HELPER_HPP_
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