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 namespace stdexec 21 { 22 23 ////////////////////////////////////////////////////////////////////////////////////////////////// 24 // A very simple std::declval replacement that doesn't handle void 25 template <class _Tp> 26 auto __declval() noexcept -> _Tp&&; 27 28 ////////////////////////////////////////////////////////////////////////////////////////////////// 29 // __decay_t: An efficient implementation for std::decay 30 #if STDEXEC_HAS_BUILTIN(__decay) 31 32 template <class _Ty> 33 using __decay_t = __decay(_Ty); 34 35 #elif STDEXEC_NVHPC() 36 37 template <class _Ty> 38 using __decay_t = std::decay_t<_Ty>; 39 40 #else 41 42 namespace __tt 43 { 44 struct __decay_object 45 { 46 template <class _Ty> 47 static _Ty __g(const _Ty&); 48 template <class _Ty> 49 using __f = decltype(__g(__declval<_Ty>())); 50 }; 51 52 struct __decay_default 53 { 54 template <class _Ty> 55 static _Ty __g(_Ty); 56 template <class _Ty> 57 using __f = decltype(__g(__declval<_Ty>())); 58 }; 59 60 struct __decay_abominable 61 { 62 template <class _Ty> 63 using __f = _Ty; 64 }; 65 66 struct __decay_void 67 { 68 template <class _Ty> 69 using __f = void; 70 }; 71 72 template <class _Ty> 73 extern __decay_object __mdecay; 74 75 template <class _Ty, class... Us> 76 extern __decay_default __mdecay<_Ty(Us...)>; 77 78 template <class _Ty, class... Us> 79 extern __decay_default __mdecay<_Ty(Us...) noexcept>; 80 81 template <class _Ty, class... Us> 82 extern __decay_default __mdecay<_Ty (&)(Us...)>; 83 84 template <class _Ty, class... Us> 85 extern __decay_default __mdecay<_Ty (&)(Us...) noexcept>; 86 87 template <class _Ty, class... Us> 88 extern __decay_abominable __mdecay<_Ty(Us...) const>; 89 90 template <class _Ty, class... Us> 91 extern __decay_abominable __mdecay<_Ty(Us...) const noexcept>; 92 93 template <class _Ty, class... Us> 94 extern __decay_abominable __mdecay<_Ty(Us...) const&>; 95 96 template <class _Ty, class... Us> 97 extern __decay_abominable __mdecay<_Ty(Us...) const & noexcept>; 98 99 template <class _Ty, class... Us> 100 extern __decay_abominable __mdecay<_Ty(Us...) const&&>; 101 102 template <class _Ty, class... Us> 103 extern __decay_abominable __mdecay<_Ty(Us...) const && noexcept>; 104 105 template <class _Ty> 106 extern __decay_default __mdecay<_Ty[]>; 107 108 template <class _Ty, std::size_t N> 109 extern __decay_default __mdecay<_Ty[N]>; 110 111 template <class _Ty, std::size_t N> 112 extern __decay_default __mdecay<_Ty (&)[N]>; 113 114 template <> 115 inline __decay_void __mdecay<void>; 116 117 template <> 118 inline __decay_void __mdecay<const void>; 119 } // namespace __tt 120 121 template <class _Ty> 122 using __decay_t = typename decltype(__tt::__mdecay<_Ty>)::template __f<_Ty>; 123 124 #endif 125 126 ////////////////////////////////////////////////////////////////////////////////////////////////// 127 // __copy_cvref_t: For copying cvref from one type to another 128 struct __cp 129 { 130 template <class _Tp> 131 using __f = _Tp; 132 }; 133 134 struct __cpc 135 { 136 template <class _Tp> 137 using __f = const _Tp; 138 }; 139 140 struct __cplr 141 { 142 template <class _Tp> 143 using __f = _Tp&; 144 }; 145 146 struct __cprr 147 { 148 template <class _Tp> 149 using __f = _Tp&&; 150 }; 151 152 struct __cpclr 153 { 154 template <class _Tp> 155 using __f = const _Tp&; 156 }; 157 158 struct __cpcrr 159 { 160 template <class _Tp> 161 using __f = const _Tp&&; 162 }; 163 164 template <class> 165 extern __cp __cpcvr; 166 template <class _Tp> 167 extern __cpc __cpcvr<const _Tp>; 168 template <class _Tp> 169 extern __cplr __cpcvr<_Tp&>; 170 template <class _Tp> 171 extern __cprr __cpcvr<_Tp&&>; 172 template <class _Tp> 173 extern __cpclr __cpcvr<const _Tp&>; 174 template <class _Tp> 175 extern __cpcrr __cpcvr<const _Tp&&>; 176 template <class _Tp> 177 using __copy_cvref_fn = decltype(__cpcvr<_Tp>); 178 179 template <class _From, class _To> 180 using __copy_cvref_t = typename __copy_cvref_fn<_From>::template __f<_To>; 181 182 #if !STDEXEC_HAS_BUILTIN(__is_const) 183 template <class> 184 inline constexpr bool __is_const = false; 185 template <class _Up> 186 inline constexpr bool __is_const<const _Up> = true; 187 #endif 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 } // namespace stdexec 200