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 template <class _Ty> 35 using __decay_t = __decay(_Ty); 36 37 #elif STDEXEC_NVHPC() 38 39 template <class _Ty> 40 using __decay_t = std::decay_t<_Ty>; 41 42 #else 43 44 namespace __tt 45 { 46 struct __decay_object 47 { 48 template <class _Ty> 49 static _Ty __g(const _Ty&); 50 template <class _Ty> 51 using __f = decltype(__g(__declval<_Ty>())); 52 }; 53 54 struct __decay_default 55 { 56 template <class _Ty> 57 static _Ty __g(_Ty); 58 template <class _Ty> 59 using __f = decltype(__g(__declval<_Ty>())); 60 }; 61 62 struct __decay_abominable 63 { 64 template <class _Ty> 65 using __f = _Ty; 66 }; 67 68 struct __decay_void 69 { 70 template <class _Ty> 71 using __f = void; 72 }; 73 74 template <class _Ty> 75 extern __decay_object __mdecay; 76 77 template <class _Ty, class... Us> 78 extern __decay_default __mdecay<_Ty(Us...)>; 79 80 template <class _Ty, class... Us> 81 extern __decay_default __mdecay<_Ty(Us...) noexcept>; 82 83 template <class _Ty, class... Us> 84 extern __decay_default __mdecay<_Ty (&)(Us...)>; 85 86 template <class _Ty, class... Us> 87 extern __decay_default __mdecay<_Ty (&)(Us...) noexcept>; 88 89 template <class _Ty, class... Us> 90 extern __decay_abominable __mdecay<_Ty(Us...) const>; 91 92 template <class _Ty, class... Us> 93 extern __decay_abominable __mdecay<_Ty(Us...) const noexcept>; 94 95 template <class _Ty, class... Us> 96 extern __decay_abominable __mdecay<_Ty(Us...) const&>; 97 98 template <class _Ty, class... Us> 99 extern __decay_abominable __mdecay<_Ty(Us...) const & noexcept>; 100 101 template <class _Ty, class... Us> 102 extern __decay_abominable __mdecay<_Ty(Us...) const&&>; 103 104 template <class _Ty, class... Us> 105 extern __decay_abominable __mdecay<_Ty(Us...) const && noexcept>; 106 107 template <class _Ty> 108 extern __decay_default __mdecay<_Ty[]>; 109 110 template <class _Ty, std::size_t N> 111 extern __decay_default __mdecay<_Ty[N]>; 112 113 template <class _Ty, std::size_t N> 114 extern __decay_default __mdecay<_Ty (&)[N]>; 115 116 template <> 117 inline __decay_void __mdecay<void>; 118 119 template <> 120 inline __decay_void __mdecay<const void>; 121 } // namespace __tt 122 123 template <class _Ty> 124 using __decay_t = typename decltype(__tt::__mdecay<_Ty>)::template __f<_Ty>; 125 126 #endif 127 128 ////////////////////////////////////////////////////////////////////////////////////////////////// 129 // __copy_cvref_t: For copying cvref from one type to another 130 struct __cp 131 { 132 template <class _Tp> 133 using __f = _Tp; 134 }; 135 136 struct __cpc 137 { 138 template <class _Tp> 139 using __f = const _Tp; 140 }; 141 142 struct __cplr 143 { 144 template <class _Tp> 145 using __f = _Tp&; 146 }; 147 148 struct __cprr 149 { 150 template <class _Tp> 151 using __f = _Tp&&; 152 }; 153 154 struct __cpclr 155 { 156 template <class _Tp> 157 using __f = const _Tp&; 158 }; 159 160 struct __cpcrr 161 { 162 template <class _Tp> 163 using __f = const _Tp&&; 164 }; 165 166 template <class> 167 extern __cp __cpcvr; 168 template <class _Tp> 169 extern __cpc __cpcvr<const _Tp>; 170 template <class _Tp> 171 extern __cplr __cpcvr<_Tp&>; 172 template <class _Tp> 173 extern __cprr __cpcvr<_Tp&&>; 174 template <class _Tp> 175 extern __cpclr __cpcvr<const _Tp&>; 176 template <class _Tp> 177 extern __cpcrr __cpcvr<const _Tp&&>; 178 template <class _Tp> 179 using __copy_cvref_fn = decltype(__cpcvr<_Tp>); 180 181 template <class _From, class _To> 182 using __copy_cvref_t = typename __copy_cvref_fn<_From>::template __f<_To>; 183 184 template <class> 185 inline constexpr bool __is_const_ = false; 186 template <class _Up> 187 inline constexpr bool __is_const_<const _Up> = true; 188 189 namespace __tt 190 { 191 template <class _Ty> 192 auto __remove_rvalue_reference_fn(_Ty&&) -> _Ty; 193 } // namespace __tt 194 195 template <class _Ty> 196 using __remove_rvalue_reference_t = 197 decltype(__tt::__remove_rvalue_reference_fn(__declval<_Ty>())); 198 199 // Implemented as a class instead of a free function 200 // because of a bizarre nvc++ compiler bug: 201 struct __cref_fn 202 { 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 } // namespace stdexec 209