HIP: Heterogenous-computing Interface for Portability
Loading...
Searching...
No Matches
helpers.hpp
1/*
2Copyright (c) 2015 - 2021 Advanced Micro Devices, Inc. All rights reserved.
3
4Permission is hereby granted, free of charge, to any person obtaining a copy
5of this software and associated documentation files (the "Software"), to deal
6in the Software without restriction, including without limitation the rights
7to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8copies of the Software, and to permit persons to whom the Software is
9furnished to do so, subject to the following conditions:
10
11The above copyright notice and this permission notice shall be included in
12all copies or substantial portions of the Software.
13
14THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20THE SOFTWARE.
21*/
22
23#pragma once
24#include "concepts.hpp"
25
26#include <type_traits> // For std::conditional, std::decay, std::enable_if,
27 // std::false_type, std result_of and std::true_type.
28#include <utility> // For std::declval.
29
30#ifdef __has_include // Check if __has_include is present
31# if __has_include(<version>) // Check for version header
32# include <version>
33# if defined(__cpp_lib_is_invocable) && !defined(HIP_HAS_INVOCABLE)
34# define HIP_HAS_INVOCABLE __cpp_lib_is_invocable
35# endif
36# if defined(__cpp_lib_result_of_sfinae) && !defined(HIP_HAS_RESULT_OF_SFINAE)
37# define HIP_HAS_RESULT_OF_SFINAE __cpp_lib_result_of_sfinae
38# endif
39# endif
40#endif
41
42#ifndef HIP_HAS_INVOCABLE
43#define HIP_HAS_INVOCABLE 0
44#endif
45
46#ifndef HIP_HAS_RESULT_OF_SFINAE
47#define HIP_HAS_RESULT_OF_SFINAE 0
48#endif
49
50namespace std { // TODO: these should be removed as soon as possible.
51#if (__cplusplus < 201406L)
52#if (__cplusplus < 201402L)
53template <bool cond, typename T = void>
54using enable_if_t = typename enable_if<cond, T>::type;
55template <bool cond, typename T, typename U>
56using conditional_t = typename conditional<cond, T, U>::type;
57template <typename T>
58using decay_t = typename decay<T>::type;
59template <FunctionalProcedure F, typename... Ts>
60using result_of_t = typename result_of<F(Ts...)>::type;
61template <typename T>
62using remove_reference_t = typename remove_reference<T>::type;
63#endif
64#endif
65} // namespace std
66
67namespace hip_impl {
68template <typename...>
69using void_t_ = void;
70
71#if HIP_HAS_INVOCABLE
72template <typename, typename = void>
73struct is_callable_impl;
74
75template <FunctionalProcedure F, typename... Ts>
76struct is_callable_impl<F(Ts...)> : std::is_invocable<F, Ts...> {};
77#elif HIP_HAS_RESULT_OF_SFINAE
78template <typename, typename = void>
79struct is_callable_impl : std::false_type {};
80
81template <FunctionalProcedure F, typename... Ts>
82struct is_callable_impl<F(Ts...), void_t_<typename std::result_of<F(Ts...)>::type > > : std::true_type {};
83#else
84template <class Base, class T, class Derived>
85auto simple_invoke(T Base::*pmd, Derived&& ref)
86-> decltype(static_cast<Derived&&>(ref).*pmd);
87
88template <class PMD, class Pointer>
89auto simple_invoke(PMD&& pmd, Pointer&& ptr)
90-> decltype((*static_cast<Pointer&&>(ptr)).*static_cast<PMD&&>(pmd));
91
92template <class Base, class T, class Derived>
93auto simple_invoke(T Base::*pmd, const std::reference_wrapper<Derived>& ref)
94-> decltype(ref.get().*pmd);
95
96template <class Base, class T, class Derived, class... Args>
97auto simple_invoke(T Base::*pmf, Derived&& ref, Args&&... args)
98-> decltype((static_cast<Derived&&>(ref).*pmf)(static_cast<Args&&>(args)...));
99
100template <class PMF, class Pointer, class... Args>
101auto simple_invoke(PMF&& pmf, Pointer&& ptr, Args&&... args)
102-> decltype(((*static_cast<Pointer&&>(ptr)).*static_cast<PMF&&>(pmf))(static_cast<Args&&>(args)...));
103
104template <class Base, class T, class Derived, class... Args>
105auto simple_invoke(T Base::*pmf, const std::reference_wrapper<Derived>& ref, Args&&... args)
106-> decltype((ref.get().*pmf)(static_cast<Args&&>(args)...));
107
108template<class F, class... Ts>
109auto simple_invoke(F&& f, Ts&&... xs)
110-> decltype(f(static_cast<Ts&&>(xs)...));
111
112template <typename, typename = void>
113struct is_callable_impl : std::false_type {};
114
115template <FunctionalProcedure F, typename... Ts>
116struct is_callable_impl<F(Ts...), void_t_<decltype(simple_invoke(std::declval<F>(), std::declval<Ts>()...))> >
117 : std::true_type {};
118
119#endif
120
121template <typename Call>
123
124#define count_macro_args_impl_hip_(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, \
125 _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, \
126 _26, _27, _28, _29, _30, _31, _n, ...) \
127 _n
128#define count_macro_args_hip_(...) \
129 count_macro_args_impl_hip_(, ##__VA_ARGS__, 31, 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, 20, \
130 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, \
131 0)
132
133#define overloaded_macro_expand_hip_(macro, arg_cnt) macro##arg_cnt
134#define overload_macro_impl_hip_(macro, arg_cnt) overloaded_macro_expand_hip_(macro, arg_cnt)
135#define overload_macro_hip_(macro, ...) \
136 overload_macro_impl_hip_(macro, count_macro_args_hip_(__VA_ARGS__))(__VA_ARGS__)
137} // namespace hip_impl
Definition helpers.hpp:113
Definition helpers.hpp:122