Patrick Williams | 5b5d15b | 2022-08-23 09:35:15 -0500 | [diff] [blame] | 1 | /* |
| 2 | * Copyright (c) 2021-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 | |
Patrick Williams | 5e7ef08 | 2023-01-05 11:08:53 -0600 | [diff] [blame] | 18 | #if __cpp_concepts < 201907L |
| 19 | #error This library requires support for C++20 concepts |
| 20 | #endif |
| 21 | |
Patrick Williams | 5b5d15b | 2022-08-23 09:35:15 -0500 | [diff] [blame] | 22 | #include <version> |
| 23 | |
Patrick Williams | 5e7ef08 | 2023-01-05 11:08:53 -0600 | [diff] [blame] | 24 | // Perhaps the stdlib lacks support for concepts though: |
Patrick Williams | abbdd6a | 2023-01-20 10:12:50 -0600 | [diff] [blame] | 25 | #if __has_include(<concepts>) && __cpp_lib_concepts >= 202002 |
| 26 | #define STDEXEC_HAS_STD_CONCEPTS_HEADER() 1 |
| 27 | #else |
| 28 | #define STDEXEC_HAS_STD_CONCEPTS_HEADER() 0 |
| 29 | #endif |
| 30 | |
| 31 | #if STDEXEC_HAS_STD_CONCEPTS_HEADER() |
Patrick Williams | 5b5d15b | 2022-08-23 09:35:15 -0500 | [diff] [blame] | 32 | #include <concepts> |
Patrick Williams | 5b5d15b | 2022-08-23 09:35:15 -0500 | [diff] [blame] | 33 | #else |
| 34 | #include <type_traits> |
Patrick Williams | abbdd6a | 2023-01-20 10:12:50 -0600 | [diff] [blame] | 35 | #endif |
Patrick Williams | 5b5d15b | 2022-08-23 09:35:15 -0500 | [diff] [blame] | 36 | |
Patrick Williams | e61c679 | 2023-03-29 10:28:22 -0500 | [diff] [blame] | 37 | #include "__detail/__meta.hpp" |
| 38 | |
Patrick Williams | abbdd6a | 2023-01-20 10:12:50 -0600 | [diff] [blame] | 39 | namespace stdexec::__std_concepts |
Patrick Williams | 5b5d15b | 2022-08-23 09:35:15 -0500 | [diff] [blame] | 40 | { |
Patrick Williams | 5b5d15b | 2022-08-23 09:35:15 -0500 | [diff] [blame] | 41 | #if defined(__clang__) |
Patrick Williams | e61c679 | 2023-03-29 10:28:22 -0500 | [diff] [blame] | 42 | template <class _Ap, class _Bp> |
| 43 | concept __same_as = __is_same(_Ap, _Bp); |
Patrick Williams | 5b5d15b | 2022-08-23 09:35:15 -0500 | [diff] [blame] | 44 | #elif defined(__GNUC__) |
Patrick Williams | e61c679 | 2023-03-29 10:28:22 -0500 | [diff] [blame] | 45 | template <class _Ap, class _Bp> |
| 46 | concept __same_as = __is_same_as(_Ap, _Bp); |
Patrick Williams | 5b5d15b | 2022-08-23 09:35:15 -0500 | [diff] [blame] | 47 | #else |
Patrick Williams | e61c679 | 2023-03-29 10:28:22 -0500 | [diff] [blame] | 48 | template <class _Ap, class _Bp> |
Patrick Williams | abbdd6a | 2023-01-20 10:12:50 -0600 | [diff] [blame] | 49 | inline constexpr bool __same_as = false; |
Patrick Williams | e61c679 | 2023-03-29 10:28:22 -0500 | [diff] [blame] | 50 | template <class _Ap> |
| 51 | inline constexpr bool __same_as<_Ap, _Ap> = true; |
Patrick Williams | 5b5d15b | 2022-08-23 09:35:15 -0500 | [diff] [blame] | 52 | #endif |
| 53 | |
Patrick Williams | abbdd6a | 2023-01-20 10:12:50 -0600 | [diff] [blame] | 54 | // Make sure we're using a same_as concept that doesn't instantiate std::is_same |
Patrick Williams | e61c679 | 2023-03-29 10:28:22 -0500 | [diff] [blame] | 55 | template <class _Ap, class _Bp> |
| 56 | concept same_as = __same_as<_Ap, _Bp> && __same_as<_Bp, _Ap>; |
Patrick Williams | abbdd6a | 2023-01-20 10:12:50 -0600 | [diff] [blame] | 57 | |
| 58 | #if STDEXEC_HAS_STD_CONCEPTS_HEADER() |
| 59 | |
| 60 | using std::convertible_to; |
| 61 | using std::derived_from; |
| 62 | using std::equality_comparable; |
| 63 | using std::integral; |
| 64 | |
| 65 | #else |
| 66 | |
Patrick Williams | 5b5d15b | 2022-08-23 09:35:15 -0500 | [diff] [blame] | 67 | template <class T> |
| 68 | concept integral = std::is_integral_v<T>; |
| 69 | |
Patrick Williams | e61c679 | 2023-03-29 10:28:22 -0500 | [diff] [blame] | 70 | template <class _Ap, class _Bp> |
| 71 | concept derived_from = // |
| 72 | std::is_base_of_v<_Bp, _Ap> && // |
| 73 | std::is_convertible_v<const volatile _Ap*, const volatile _Bp*>; |
Patrick Williams | 5b5d15b | 2022-08-23 09:35:15 -0500 | [diff] [blame] | 74 | |
| 75 | template <class _From, class _To> |
Patrick Williams | e61c679 | 2023-03-29 10:28:22 -0500 | [diff] [blame] | 76 | concept convertible_to = // |
| 77 | std::is_convertible_v<_From, _To> && // |
Patrick Williams | 5b5d15b | 2022-08-23 09:35:15 -0500 | [diff] [blame] | 78 | requires(_From (&__fun)()) { static_cast<_To>(__fun()); }; |
| 79 | |
Patrick Williams | e61c679 | 2023-03-29 10:28:22 -0500 | [diff] [blame] | 80 | template <class _Ty> |
| 81 | concept equality_comparable = // |
| 82 | requires(__cref_t<_Ty> __t) { |
| 83 | { |
| 84 | __t == __t |
Patrick Williams | d214904 | 2023-05-10 07:50:13 -0500 | [diff] [blame^] | 85 | } -> convertible_to<bool>; |
Patrick Williams | e61c679 | 2023-03-29 10:28:22 -0500 | [diff] [blame] | 86 | { |
| 87 | __t != __t |
Patrick Williams | d214904 | 2023-05-10 07:50:13 -0500 | [diff] [blame^] | 88 | } -> convertible_to<bool>; |
Patrick Williams | e61c679 | 2023-03-29 10:28:22 -0500 | [diff] [blame] | 89 | }; |
Patrick Williams | abbdd6a | 2023-01-20 10:12:50 -0600 | [diff] [blame] | 90 | #endif |
| 91 | } // namespace stdexec::__std_concepts |
Patrick Williams | 5b5d15b | 2022-08-23 09:35:15 -0500 | [diff] [blame] | 92 | |
Patrick Williams | abbdd6a | 2023-01-20 10:12:50 -0600 | [diff] [blame] | 93 | namespace stdexec |
| 94 | { |
| 95 | using namespace __std_concepts; |
Patrick Williams | abbdd6a | 2023-01-20 10:12:50 -0600 | [diff] [blame] | 96 | |
Patrick Williams | e61c679 | 2023-03-29 10:28:22 -0500 | [diff] [blame] | 97 | #if __has_builtin(__decay) |
| 98 | template <class _Ty> |
| 99 | using __decay_t = __decay(_Ty); |
| 100 | #elif STDEXEC_NVHPC() |
| 101 | template <class _Ty> |
| 102 | using __decay_t = std::decay_t<_Ty>; |
| 103 | #else |
| 104 | namespace __tt |
| 105 | { |
| 106 | struct __decay_object |
| 107 | { |
| 108 | template <class _Ty> |
| 109 | static _Ty __g(const _Ty&); |
| 110 | template <class _Ty> |
| 111 | using __f = decltype(__g(__declval<_Ty>())); |
| 112 | }; |
Patrick Williams | abbdd6a | 2023-01-20 10:12:50 -0600 | [diff] [blame] | 113 | |
Patrick Williams | e61c679 | 2023-03-29 10:28:22 -0500 | [diff] [blame] | 114 | struct __decay_default |
| 115 | { |
| 116 | template <class _Ty> |
| 117 | static _Ty __g(_Ty); |
| 118 | template <class _Ty> |
| 119 | using __f = decltype(__g(__declval<_Ty>())); |
| 120 | }; |
Patrick Williams | abbdd6a | 2023-01-20 10:12:50 -0600 | [diff] [blame] | 121 | |
Patrick Williams | e61c679 | 2023-03-29 10:28:22 -0500 | [diff] [blame] | 122 | struct __decay_abominable |
| 123 | { |
| 124 | template <class _Ty> |
| 125 | using __f = _Ty; |
| 126 | }; |
| 127 | |
| 128 | struct __decay_void |
| 129 | { |
| 130 | template <class _Ty> |
| 131 | using __f = void; |
| 132 | }; |
| 133 | |
| 134 | template <class _Ty> |
| 135 | extern __decay_object __mdecay; |
| 136 | |
| 137 | template <class _Ty, class... Us> |
| 138 | extern __decay_default __mdecay<_Ty(Us...)>; |
| 139 | |
| 140 | template <class _Ty, class... Us> |
| 141 | extern __decay_default __mdecay<_Ty(Us...) noexcept>; |
| 142 | |
| 143 | template <class _Ty, class... Us> |
| 144 | extern __decay_default __mdecay<_Ty (&)(Us...)>; |
| 145 | |
| 146 | template <class _Ty, class... Us> |
| 147 | extern __decay_default __mdecay<_Ty (&)(Us...) noexcept>; |
| 148 | |
| 149 | template <class _Ty, class... Us> |
| 150 | extern __decay_abominable __mdecay<_Ty(Us...) const>; |
| 151 | |
| 152 | template <class _Ty, class... Us> |
| 153 | extern __decay_abominable __mdecay<_Ty(Us...) const noexcept>; |
| 154 | |
| 155 | template <class _Ty, class... Us> |
| 156 | extern __decay_abominable __mdecay<_Ty(Us...) const&>; |
| 157 | |
| 158 | template <class _Ty, class... Us> |
| 159 | extern __decay_abominable __mdecay<_Ty(Us...) const & noexcept>; |
| 160 | |
| 161 | template <class _Ty, class... Us> |
| 162 | extern __decay_abominable __mdecay<_Ty(Us...) const&&>; |
| 163 | |
| 164 | template <class _Ty, class... Us> |
| 165 | extern __decay_abominable __mdecay<_Ty(Us...) const && noexcept>; |
| 166 | |
| 167 | template <class _Ty> |
| 168 | extern __decay_default __mdecay<_Ty[]>; |
| 169 | |
| 170 | template <class _Ty, std::size_t N> |
| 171 | extern __decay_default __mdecay<_Ty[N]>; |
| 172 | |
| 173 | template <class _Ty, std::size_t N> |
| 174 | extern __decay_default __mdecay<_Ty (&)[N]>; |
| 175 | |
| 176 | template <> |
| 177 | inline __decay_void __mdecay<void>; |
| 178 | |
| 179 | template <> |
| 180 | inline __decay_void __mdecay<const void>; |
| 181 | } // namespace __tt |
| 182 | |
| 183 | template <class _Ty> |
| 184 | using __decay_t = typename decltype(__tt::__mdecay<_Ty>)::template __f<_Ty>; |
| 185 | #endif |
Patrick Williams | abbdd6a | 2023-01-20 10:12:50 -0600 | [diff] [blame] | 186 | |
| 187 | // C++20 concepts |
Patrick Williams | e61c679 | 2023-03-29 10:28:22 -0500 | [diff] [blame] | 188 | template <class _Ty, class _Up> |
| 189 | concept __decays_to = __same_as<__decay_t<_Ty>, _Up>; |
| 190 | |
| 191 | template <class _Ty, class _Up> |
Patrick Williams | d214904 | 2023-05-10 07:50:13 -0500 | [diff] [blame^] | 192 | concept __not_decays_to = !__decays_to<_Ty, _Up>; |
Patrick Williams | e61c679 | 2023-03-29 10:28:22 -0500 | [diff] [blame] | 193 | |
| 194 | template <bool _TrueOrFalse> |
| 195 | concept __satisfies = _TrueOrFalse; |
Patrick Williams | abbdd6a | 2023-01-20 10:12:50 -0600 | [diff] [blame] | 196 | |
| 197 | template <class...> |
| 198 | concept __true = true; |
| 199 | |
Patrick Williams | e61c679 | 2023-03-29 10:28:22 -0500 | [diff] [blame] | 200 | template <class _Cp> |
| 201 | concept __class = __true<int _Cp::*> && (!__same_as<const _Cp, _Cp>); |
Patrick Williams | abbdd6a | 2023-01-20 10:12:50 -0600 | [diff] [blame] | 202 | |
Patrick Williams | e61c679 | 2023-03-29 10:28:22 -0500 | [diff] [blame] | 203 | template <class _Ty, class... _As> |
| 204 | concept __one_of = (__same_as<_Ty, _As> || ...); |
Patrick Williams | abbdd6a | 2023-01-20 10:12:50 -0600 | [diff] [blame] | 205 | |
Patrick Williams | e61c679 | 2023-03-29 10:28:22 -0500 | [diff] [blame] | 206 | template <class _Ty, class... _Us> |
| 207 | concept __all_of = (__same_as<_Ty, _Us> && ...); |
Patrick Williams | abbdd6a | 2023-01-20 10:12:50 -0600 | [diff] [blame] | 208 | |
Patrick Williams | e61c679 | 2023-03-29 10:28:22 -0500 | [diff] [blame] | 209 | template <class _Ty, class... _Us> |
Patrick Williams | d214904 | 2023-05-10 07:50:13 -0500 | [diff] [blame^] | 210 | concept __none_of = ((!__same_as<_Ty, _Us>)&&...); |
Patrick Williams | abbdd6a | 2023-01-20 10:12:50 -0600 | [diff] [blame] | 211 | |
| 212 | // Not exactly right, but close. |
Patrick Williams | e61c679 | 2023-03-29 10:28:22 -0500 | [diff] [blame] | 213 | template <class _Ty> |
| 214 | concept __boolean_testable_ = convertible_to<_Ty, bool>; |
| 215 | |
| 216 | template <class _Ty> |
| 217 | inline constexpr bool __is_lvalue_reference_ = false; |
| 218 | template <class _Ty> |
| 219 | inline constexpr bool __is_lvalue_reference_<_Ty&> = true; |
Patrick Williams | abbdd6a | 2023-01-20 10:12:50 -0600 | [diff] [blame] | 220 | |
| 221 | // Avoid using libstdc++'s object concepts because they instantiate a |
| 222 | // lot of templates. |
| 223 | template <class _Ty> |
Patrick Williams | e61c679 | 2023-03-29 10:28:22 -0500 | [diff] [blame] | 224 | inline constexpr bool __destructible_ = // |
Patrick Williams | abbdd6a | 2023-01-20 10:12:50 -0600 | [diff] [blame] | 225 | requires { |
| 226 | { |
| 227 | ((_Ty && (*)() noexcept) nullptr)().~_Ty() |
| 228 | } noexcept; |
| 229 | }; |
| 230 | template <class _Ty> |
| 231 | inline constexpr bool __destructible_<_Ty&> = true; |
| 232 | template <class _Ty> |
| 233 | inline constexpr bool __destructible_<_Ty&&> = true; |
Patrick Williams | e61c679 | 2023-03-29 10:28:22 -0500 | [diff] [blame] | 234 | template <class _Ty, std::size_t _Np> |
| 235 | inline constexpr bool __destructible_<_Ty[_Np]> = __destructible_<_Ty>; |
Patrick Williams | abbdd6a | 2023-01-20 10:12:50 -0600 | [diff] [blame] | 236 | |
| 237 | template <class T> |
| 238 | concept destructible = __destructible_<T>; |
Patrick Williams | 5b5d15b | 2022-08-23 09:35:15 -0500 | [diff] [blame] | 239 | |
| 240 | #if __has_builtin(__is_constructible) |
Patrick Williams | e61c679 | 2023-03-29 10:28:22 -0500 | [diff] [blame] | 241 | template <class _Ty, class... _As> |
| 242 | concept constructible_from = // |
| 243 | destructible<_Ty> && // |
| 244 | __is_constructible(_Ty, _As...); |
Patrick Williams | 5b5d15b | 2022-08-23 09:35:15 -0500 | [diff] [blame] | 245 | #else |
Patrick Williams | e61c679 | 2023-03-29 10:28:22 -0500 | [diff] [blame] | 246 | template <class _Ty, class... _As> |
| 247 | concept constructible_from = // |
| 248 | destructible<_Ty> && // |
| 249 | is_constructible_v<_Ty, _As...>; |
Patrick Williams | 5b5d15b | 2022-08-23 09:35:15 -0500 | [diff] [blame] | 250 | #endif |
| 251 | |
Patrick Williams | e61c679 | 2023-03-29 10:28:22 -0500 | [diff] [blame] | 252 | template <class _Ty> |
| 253 | concept default_initializable = // |
| 254 | constructible_from<_Ty> && // |
| 255 | requires { _Ty{}; } && // |
| 256 | requires { ::new _Ty; }; |
Patrick Williams | 5b5d15b | 2022-08-23 09:35:15 -0500 | [diff] [blame] | 257 | |
Patrick Williams | e61c679 | 2023-03-29 10:28:22 -0500 | [diff] [blame] | 258 | template <class _Ty> |
| 259 | concept move_constructible = // |
| 260 | constructible_from<_Ty, _Ty>; |
Patrick Williams | 5b5d15b | 2022-08-23 09:35:15 -0500 | [diff] [blame] | 261 | |
Patrick Williams | e61c679 | 2023-03-29 10:28:22 -0500 | [diff] [blame] | 262 | template <class _Ty> |
| 263 | concept copy_constructible = // |
| 264 | move_constructible<_Ty> // |
| 265 | && constructible_from<_Ty, const _Ty&>; |
| 266 | |
| 267 | template <class _LHS, class _RHS> |
| 268 | concept assignable_from = // |
| 269 | __is_lvalue_reference_<_LHS> && // |
| 270 | // std::common_reference_with< |
| 271 | // const std::remove_reference_t<_LHS>&, |
| 272 | // const std::remove_reference_t<_RHS>&> && |
| 273 | requires(_LHS __lhs, _RHS&& __rhs) { |
| 274 | { |
Patrick Williams | d214904 | 2023-05-10 07:50:13 -0500 | [diff] [blame^] | 275 | __lhs = ((_RHS&&)__rhs) |
| 276 | } -> same_as<_LHS>; |
Patrick Williams | e61c679 | 2023-03-29 10:28:22 -0500 | [diff] [blame] | 277 | }; |
| 278 | |
| 279 | namespace __swap |
| 280 | { |
| 281 | using std::swap; |
| 282 | |
| 283 | template <class _Ty, class _Uy> |
| 284 | concept swappable_with = // |
Patrick Williams | d214904 | 2023-05-10 07:50:13 -0500 | [diff] [blame^] | 285 | requires(_Ty&& __t, _Uy&& __u) { swap((_Ty&&)__t, (_Uy&&)__u); }; |
Patrick Williams | e61c679 | 2023-03-29 10:28:22 -0500 | [diff] [blame] | 286 | |
| 287 | inline constexpr const auto __fn = // |
| 288 | []<class _Ty, swappable_with<_Ty> _Uy>(_Ty&& __t, _Uy&& __u) noexcept( |
Patrick Williams | d214904 | 2023-05-10 07:50:13 -0500 | [diff] [blame^] | 289 | noexcept(swap((_Ty&&)__t, (_Uy&&)__u))) { |
| 290 | swap((_Ty&&)__t, (_Uy&&)__u); |
| 291 | }; |
Patrick Williams | e61c679 | 2023-03-29 10:28:22 -0500 | [diff] [blame] | 292 | } // namespace __swap |
| 293 | |
| 294 | using __swap::swappable_with; |
| 295 | inline constexpr const auto& swap = __swap::__fn; |
| 296 | |
| 297 | template <class _Ty> |
| 298 | concept swappable = // |
| 299 | swappable_with<_Ty, _Ty>; |
| 300 | |
| 301 | template <class _Ty> |
| 302 | concept movable = // |
| 303 | std::is_object_v<_Ty> && // |
| 304 | move_constructible<_Ty> && // |
| 305 | assignable_from<_Ty&, _Ty> && // |
| 306 | swappable<_Ty>; |
| 307 | |
| 308 | template <class _Ty> |
| 309 | concept copyable = // |
| 310 | copy_constructible<_Ty> && // |
| 311 | movable<_Ty> && // |
| 312 | assignable_from<_Ty&, _Ty&> && // |
| 313 | assignable_from<_Ty&, const _Ty&> && // |
| 314 | assignable_from<_Ty&, const _Ty>; |
| 315 | |
| 316 | template <class _Ty> |
| 317 | concept semiregular = // |
| 318 | copyable<_Ty> && // |
| 319 | default_initializable<_Ty>; |
| 320 | |
| 321 | template <class _Ty> |
| 322 | concept regular = // |
| 323 | semiregular<_Ty> && // |
| 324 | equality_comparable<_Ty>; |
| 325 | |
| 326 | template <class T, class U> |
| 327 | concept __partially_ordered_with = // |
| 328 | requires(__cref_t<T> t, __cref_t<U> u) { |
| 329 | { |
| 330 | t < u |
Patrick Williams | d214904 | 2023-05-10 07:50:13 -0500 | [diff] [blame^] | 331 | } -> __boolean_testable_; |
Patrick Williams | e61c679 | 2023-03-29 10:28:22 -0500 | [diff] [blame] | 332 | { |
| 333 | t > u |
Patrick Williams | d214904 | 2023-05-10 07:50:13 -0500 | [diff] [blame^] | 334 | } -> __boolean_testable_; |
Patrick Williams | e61c679 | 2023-03-29 10:28:22 -0500 | [diff] [blame] | 335 | { |
| 336 | t <= u |
Patrick Williams | d214904 | 2023-05-10 07:50:13 -0500 | [diff] [blame^] | 337 | } -> __boolean_testable_; |
Patrick Williams | e61c679 | 2023-03-29 10:28:22 -0500 | [diff] [blame] | 338 | { |
| 339 | t >= u |
Patrick Williams | d214904 | 2023-05-10 07:50:13 -0500 | [diff] [blame^] | 340 | } -> __boolean_testable_; |
Patrick Williams | e61c679 | 2023-03-29 10:28:22 -0500 | [diff] [blame] | 341 | { |
| 342 | u < t |
Patrick Williams | d214904 | 2023-05-10 07:50:13 -0500 | [diff] [blame^] | 343 | } -> __boolean_testable_; |
Patrick Williams | e61c679 | 2023-03-29 10:28:22 -0500 | [diff] [blame] | 344 | { |
| 345 | u > t |
Patrick Williams | d214904 | 2023-05-10 07:50:13 -0500 | [diff] [blame^] | 346 | } -> __boolean_testable_; |
Patrick Williams | e61c679 | 2023-03-29 10:28:22 -0500 | [diff] [blame] | 347 | { |
| 348 | u <= t |
Patrick Williams | d214904 | 2023-05-10 07:50:13 -0500 | [diff] [blame^] | 349 | } -> __boolean_testable_; |
Patrick Williams | e61c679 | 2023-03-29 10:28:22 -0500 | [diff] [blame] | 350 | { |
| 351 | u >= t |
Patrick Williams | d214904 | 2023-05-10 07:50:13 -0500 | [diff] [blame^] | 352 | } -> __boolean_testable_; |
Patrick Williams | e61c679 | 2023-03-29 10:28:22 -0500 | [diff] [blame] | 353 | }; |
| 354 | |
| 355 | template <class _Ty> |
| 356 | concept totally_ordered = // |
| 357 | equality_comparable<_Ty> && // |
| 358 | __partially_ordered_with<_Ty, _Ty>; |
| 359 | |
| 360 | template <class _Ty> |
| 361 | concept __movable_value = // |
| 362 | move_constructible<__decay_t<_Ty>> && // |
| 363 | constructible_from<__decay_t<_Ty>, _Ty>; |
Patrick Williams | 5b5d15b | 2022-08-23 09:35:15 -0500 | [diff] [blame] | 364 | |
| 365 | template <class _Trait> |
| 366 | concept __is_true = _Trait::value; |
| 367 | |
| 368 | template <class, template <class...> class> |
| 369 | constexpr bool __is_instance_of_ = false; |
Patrick Williams | e61c679 | 2023-03-29 10:28:22 -0500 | [diff] [blame] | 370 | template <class... _As, template <class...> class _Ty> |
| 371 | constexpr bool __is_instance_of_<_Ty<_As...>, _Ty> = true; |
Patrick Williams | 5b5d15b | 2022-08-23 09:35:15 -0500 | [diff] [blame] | 372 | |
Patrick Williams | e61c679 | 2023-03-29 10:28:22 -0500 | [diff] [blame] | 373 | template <class _Ay, template <class...> class _Ty> |
| 374 | concept __is_instance_of = __is_instance_of_<_Ay, _Ty>; |
Patrick Williams | 5b5d15b | 2022-08-23 09:35:15 -0500 | [diff] [blame] | 375 | |
Patrick Williams | e61c679 | 2023-03-29 10:28:22 -0500 | [diff] [blame] | 376 | template <class _Ay, template <class...> class _Ty> |
Patrick Williams | d214904 | 2023-05-10 07:50:13 -0500 | [diff] [blame^] | 377 | concept __is_not_instance_of = !__is_instance_of<_Ay, _Ty>; |
Patrick Williams | 5b5d15b | 2022-08-23 09:35:15 -0500 | [diff] [blame] | 378 | |
| 379 | #if __has_builtin(__is_nothrow_constructible) |
Patrick Williams | e61c679 | 2023-03-29 10:28:22 -0500 | [diff] [blame] | 380 | template <class _Ty, class... _As> |
| 381 | concept __nothrow_constructible_from = constructible_from<_Ty, _As...> && |
| 382 | __is_nothrow_constructible(_Ty, _As...); |
Patrick Williams | 5b5d15b | 2022-08-23 09:35:15 -0500 | [diff] [blame] | 383 | #else |
Patrick Williams | e61c679 | 2023-03-29 10:28:22 -0500 | [diff] [blame] | 384 | template <class _Ty, class... _As> |
Patrick Williams | 5b5d15b | 2022-08-23 09:35:15 -0500 | [diff] [blame] | 385 | concept __nothrow_constructible_from = |
Patrick Williams | e61c679 | 2023-03-29 10:28:22 -0500 | [diff] [blame] | 386 | constructible_from<_Ty, _As...> && |
| 387 | std::is_nothrow_constructible_v<_Ty, _As...>; |
Patrick Williams | 5b5d15b | 2022-08-23 09:35:15 -0500 | [diff] [blame] | 388 | #endif |
| 389 | |
| 390 | template <class _Ty> |
Patrick Williams | e61c679 | 2023-03-29 10:28:22 -0500 | [diff] [blame] | 391 | concept __decay_copyable = constructible_from<__decay_t<_Ty>, _Ty>; |
| 392 | |
| 393 | template <class _Ty> |
Patrick Williams | 5b5d15b | 2022-08-23 09:35:15 -0500 | [diff] [blame] | 394 | concept __nothrow_decay_copyable = |
Patrick Williams | e61c679 | 2023-03-29 10:28:22 -0500 | [diff] [blame] | 395 | __nothrow_constructible_from<__decay_t<_Ty>, _Ty>; |
Patrick Williams | 5b5d15b | 2022-08-23 09:35:15 -0500 | [diff] [blame] | 396 | } // namespace stdexec |
Patrick Williams | abbdd6a | 2023-01-20 10:12:50 -0600 | [diff] [blame] | 397 | |
| 398 | #if !STDEXEC_HAS_STD_CONCEPTS_HEADER() |
| 399 | namespace std |
| 400 | { |
| 401 | using namespace stdexec::__std_concepts; |
| 402 | } |
| 403 | #endif |