xref: /openbmc/sdbusplus/include/sdbusplus/async/stdexec/__detail/__type_traits.hpp (revision 10d0b4b7d1498cfd5c3d37edea271a54d1984e41)
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> // IWYU pragma: keep
21 #include <utility>     // IWYU pragma: keep
22 
23 namespace stdexec {
24 
25   //////////////////////////////////////////////////////////////////////////////////////////////////
26   // A very simple std::declval replacement that doesn't handle void
27   template <class _Tp, bool _Noexcept = true>
28   using __declfn = auto (*)() noexcept(_Noexcept) -> _Tp;
29 
30   template <class _Tp>
31   extern __declfn<_Tp &&> __declval;
32 
33   //////////////////////////////////////////////////////////////////////////////////////////////////
34   // __decay_t: An efficient implementation for std::decay
35 #if STDEXEC_HAS_BUILTIN(__decay)
36 
37   namespace __tt {
38     template <class>
39     struct __wrap;
40 
41     template <bool>
42     struct __decay_ {
43       template <class _Ty>
44       using __f = __decay(_Ty);
45     };
46   } // namespace __tt
47   template <class _Ty>
48   using __decay_t = __tt::__decay_<sizeof(__tt::__wrap<_Ty> *) == ~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     struct __decay_object {
59       template <class _Ty>
60       static _Ty __g(_Ty const &);
61       template <class _Ty>
62       using __f = decltype(__g(__declval<_Ty>()));
63     };
64 
65     struct __decay_default {
66       template <class _Ty>
67       static _Ty __g(_Ty);
68       template <class _Ty>
69       using __f = decltype(__g(__declval<_Ty>()));
70     };
71 
72     struct __decay_abominable {
73       template <class _Ty>
74       using __f = _Ty;
75     };
76 
77     struct __decay_void {
78       template <class _Ty>
79       using __f = void;
80     };
81 
82     template <class _Ty>
83     extern __decay_object __mdecay;
84 
85     template <class _Ty, class... Us>
86     extern __decay_default __mdecay<_Ty(Us...)>;
87 
88     template <class _Ty, class... Us>
89     extern __decay_default __mdecay<_Ty(Us...) noexcept>;
90 
91     template <class _Ty, class... Us>
92     extern __decay_default __mdecay<_Ty (&)(Us...)>;
93 
94     template <class _Ty, class... Us>
95     extern __decay_default __mdecay<_Ty (&)(Us...) noexcept>;
96 
97     template <class _Ty, class... Us>
98     extern __decay_abominable __mdecay<_Ty(Us...) const>;
99 
100     template <class _Ty, class... Us>
101     extern __decay_abominable __mdecay<_Ty(Us...) const noexcept>;
102 
103     template <class _Ty, class... Us>
104     extern __decay_abominable __mdecay<_Ty(Us...) const &>;
105 
106     template <class _Ty, class... Us>
107     extern __decay_abominable __mdecay<_Ty(Us...) const & noexcept>;
108 
109     template <class _Ty, class... Us>
110     extern __decay_abominable __mdecay<_Ty(Us...) const &&>;
111 
112     template <class _Ty, class... Us>
113     extern __decay_abominable __mdecay<_Ty(Us...) const && noexcept>;
114 
115     template <class _Ty>
116     extern __decay_default __mdecay<_Ty[]>;
117 
118     template <class _Ty, std::size_t N>
119     extern __decay_default __mdecay<_Ty[N]>;
120 
121     template <class _Ty, std::size_t N>
122     extern __decay_default __mdecay<_Ty (&)[N]>;
123 
124     template <>
125     inline __decay_void __mdecay<void>;
126 
127     template <>
128     inline __decay_void __mdecay<void const>;
129   } // namespace __tt
130 
131   template <class _Ty>
132   using __decay_t = decltype(__tt::__mdecay<_Ty>)::template __f<_Ty>;
133 
134 #endif
135 
136   //////////////////////////////////////////////////////////////////////////////////////////////////
137   // __copy_cvref_t: For copying cvref from one type to another
138   struct __cp {
139     template <class _Tp>
140     using __f = _Tp;
141   };
142 
143   struct __cpc {
144     template <class _Tp>
145     using __f = const _Tp;
146   };
147 
148   struct __cplr {
149     template <class _Tp>
150     using __f = _Tp &;
151   };
152 
153   struct __cprr {
154     template <class _Tp>
155     using __f = _Tp &&;
156   };
157 
158   struct __cpclr {
159     template <class _Tp>
160     using __f = const _Tp &;
161   };
162 
163   struct __cpcrr {
164     template <class _Tp>
165     using __f = const _Tp &&;
166   };
167 
168   template <class>
169   extern __cp __cpcvr;
170   template <class _Tp>
171   extern __cpc __cpcvr<const _Tp>;
172   template <class _Tp>
173   extern __cplr __cpcvr<_Tp &>;
174   template <class _Tp>
175   extern __cprr __cpcvr<_Tp &&>;
176   template <class _Tp>
177   extern __cpclr __cpcvr<const _Tp &>;
178   template <class _Tp>
179   extern __cpcrr __cpcvr<const _Tp &&>;
180   template <class _Tp>
181   using __copy_cvref_fn = decltype(__cpcvr<_Tp>);
182 
183   template <class _From, class _To>
184   using __copy_cvref_t = __copy_cvref_fn<_From>::template __f<_To>;
185 
186   template <class>
187   inline constexpr bool __is_const_ = false;
188   template <class _Up>
189   inline constexpr bool __is_const_<_Up const> = true;
190 
191   namespace __tt {
192     template <class _Ty>
193     auto __remove_rvalue_reference_fn(_Ty &&) -> _Ty;
194   } // namespace __tt
195 
196   template <class _Ty>
197   using __remove_rvalue_reference_t = decltype(__tt::__remove_rvalue_reference_fn(
198     __declval<_Ty>()));
199 
200   // Implemented as a class instead of a free function
201   // because of a bizarre nvc++ compiler bug:
202   struct __cref_fn {
203     template <class _Ty>
204     auto operator()(const _Ty &) -> const _Ty &;
205   };
206   template <class _Ty>
207   using __cref_t = decltype(__cref_fn{}(__declval<_Ty>()));
208 
209   // Because of nvc++ nvbugs#4679848, we can't make __mbool a simple alias for __mconstant,
210   // and because of nvc++ nvbugs#4668709 it can't be a simple alias for std::bool_constant,
211   // either. :-(
212   // template <bool _Bp>
213   // using __mbool = __mconstant<_Bp>;
214 
215   template <bool _Bp>
216   struct __mbool : std::bool_constant<_Bp> { };
217 
218   using __mtrue = __mbool<true>;
219   using __mfalse = __mbool<false>;
220 
221 } // namespace stdexec
222