xref: /openbmc/sdbusplus/include/sdbusplus/async/stdexec/__detail/__type_traits.hpp (revision f083bc1a64e1f94c99fc270b7c0856810f4be638)
1 /*
2  * Copyright (c) 2022 NVIDIA Corporation
3  *
4  * Licensed under the Apache License Version 2.0 with LLVM Exceptions
5  * (the "License"); you may not use this file except in compliance with
6  * the License. You may obtain a copy of the License at
7  *
8  *   https://llvm.org/LICENSE.txt
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 #pragma once
17 
18 #include "__config.hpp"
19 
20 #include <type_traits>
21 
22 namespace stdexec
23 {
24 
25 //////////////////////////////////////////////////////////////////////////////////////////////////
26 // A very simple std::declval replacement that doesn't handle void
27 template <class _Tp>
28 extern auto (*__declval)() noexcept -> _Tp&&;
29 
30 //////////////////////////////////////////////////////////////////////////////////////////////////
31 // __decay_t: An efficient implementation for std::decay
32 #if STDEXEC_HAS_BUILTIN(__decay)
33 
34 namespace __tt
35 {
36 template <class>
37 struct __wrap;
38 
39 template <bool>
40 struct __decay_
41 {
42     template <class _Ty>
43     using __f = __decay(_Ty);
44 };
45 } // namespace __tt
46 template <class _Ty>
47 using __decay_t = typename __tt::__decay_<sizeof(__tt::__wrap<_Ty>*) ==
48                                           ~0ul>::template __f<_Ty>;
49 
50 #elif STDEXEC_EDG()
51 
52 template <class _Ty>
53 using __decay_t = std::decay_t<_Ty>;
54 
55 #else
56 
57 namespace __tt
58 {
59 struct __decay_object
60 {
61     template <class _Ty>
62     static _Ty __g(const _Ty&);
63     template <class _Ty>
64     using __f = decltype(__g(__declval<_Ty>()));
65 };
66 
67 struct __decay_default
68 {
69     template <class _Ty>
70     static _Ty __g(_Ty);
71     template <class _Ty>
72     using __f = decltype(__g(__declval<_Ty>()));
73 };
74 
75 struct __decay_abominable
76 {
77     template <class _Ty>
78     using __f = _Ty;
79 };
80 
81 struct __decay_void
82 {
83     template <class _Ty>
84     using __f = void;
85 };
86 
87 template <class _Ty>
88 extern __decay_object __mdecay;
89 
90 template <class _Ty, class... Us>
91 extern __decay_default __mdecay<_Ty(Us...)>;
92 
93 template <class _Ty, class... Us>
94 extern __decay_default __mdecay<_Ty(Us...) noexcept>;
95 
96 template <class _Ty, class... Us>
97 extern __decay_default __mdecay<_Ty (&)(Us...)>;
98 
99 template <class _Ty, class... Us>
100 extern __decay_default __mdecay<_Ty (&)(Us...) noexcept>;
101 
102 template <class _Ty, class... Us>
103 extern __decay_abominable __mdecay<_Ty(Us...) const>;
104 
105 template <class _Ty, class... Us>
106 extern __decay_abominable __mdecay<_Ty(Us...) const noexcept>;
107 
108 template <class _Ty, class... Us>
109 extern __decay_abominable __mdecay<_Ty(Us...) const&>;
110 
111 template <class _Ty, class... Us>
112 extern __decay_abominable __mdecay<_Ty(Us...) const & noexcept>;
113 
114 template <class _Ty, class... Us>
115 extern __decay_abominable __mdecay<_Ty(Us...) const&&>;
116 
117 template <class _Ty, class... Us>
118 extern __decay_abominable __mdecay<_Ty(Us...) const && noexcept>;
119 
120 template <class _Ty>
121 extern __decay_default __mdecay<_Ty[]>;
122 
123 template <class _Ty, std::size_t N>
124 extern __decay_default __mdecay<_Ty[N]>;
125 
126 template <class _Ty, std::size_t N>
127 extern __decay_default __mdecay<_Ty (&)[N]>;
128 
129 template <>
130 inline __decay_void __mdecay<void>;
131 
132 template <>
133 inline __decay_void __mdecay<const void>;
134 } // namespace __tt
135 
136 template <class _Ty>
137 using __decay_t = typename decltype(__tt::__mdecay<_Ty>)::template __f<_Ty>;
138 
139 #endif
140 
141 //////////////////////////////////////////////////////////////////////////////////////////////////
142 // __copy_cvref_t: For copying cvref from one type to another
143 struct __cp
144 {
145     template <class _Tp>
146     using __f = _Tp;
147 };
148 
149 struct __cpc
150 {
151     template <class _Tp>
152     using __f = const _Tp;
153 };
154 
155 struct __cplr
156 {
157     template <class _Tp>
158     using __f = _Tp&;
159 };
160 
161 struct __cprr
162 {
163     template <class _Tp>
164     using __f = _Tp&&;
165 };
166 
167 struct __cpclr
168 {
169     template <class _Tp>
170     using __f = const _Tp&;
171 };
172 
173 struct __cpcrr
174 {
175     template <class _Tp>
176     using __f = const _Tp&&;
177 };
178 
179 template <class>
180 extern __cp __cpcvr;
181 template <class _Tp>
182 extern __cpc __cpcvr<const _Tp>;
183 template <class _Tp>
184 extern __cplr __cpcvr<_Tp&>;
185 template <class _Tp>
186 extern __cprr __cpcvr<_Tp&&>;
187 template <class _Tp>
188 extern __cpclr __cpcvr<const _Tp&>;
189 template <class _Tp>
190 extern __cpcrr __cpcvr<const _Tp&&>;
191 template <class _Tp>
192 using __copy_cvref_fn = decltype(__cpcvr<_Tp>);
193 
194 template <class _From, class _To>
195 using __copy_cvref_t = typename __copy_cvref_fn<_From>::template __f<_To>;
196 
197 template <class>
198 inline constexpr bool __is_const_ = false;
199 template <class _Up>
200 inline constexpr bool __is_const_<const _Up> = true;
201 
202 namespace __tt
203 {
204 template <class _Ty>
205 auto __remove_rvalue_reference_fn(_Ty&&) -> _Ty;
206 } // namespace __tt
207 
208 template <class _Ty>
209 using __remove_rvalue_reference_t =
210     decltype(__tt::__remove_rvalue_reference_fn(__declval<_Ty>()));
211 
212 // Implemented as a class instead of a free function
213 // because of a bizarre nvc++ compiler bug:
214 struct __cref_fn
215 {
216     template <class _Ty>
217     auto operator()(const _Ty&) -> const _Ty&;
218 };
219 template <class _Ty>
220 using __cref_t = decltype(__cref_fn{}(__declval<_Ty>()));
221 } // namespace stdexec
222