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 
18 #include "__concepts.hpp"
19 #include "__config.hpp"
20 #include "__type_traits.hpp"
21 
22 #include <cassert>
23 #include <cstddef>
24 #include <exception>
25 #include <type_traits>
26 #include <utility>
27 
28 namespace stdexec
29 {
30 
31 template <class...>
32 struct __undefined;
33 
34 struct __
35 {};
36 
37 struct __ignore
38 {
39     __ignore() = default;
40 
41     STDEXEC_ATTRIBUTE((always_inline))
__ignorestdexec::__ignore42     constexpr __ignore(auto&&...) noexcept {}
43 };
44 
45 struct __none_such
46 {};
47 
48 namespace
49 {
50 struct __anon
51 {};
52 } // namespace
53 
54 struct __immovable
55 {
56     __immovable() = default;
57 
58   private:
59     STDEXEC_IMMOVABLE(__immovable);
60 };
61 
62 struct __move_only
63 {
64     __move_only() = default;
65 
66     __move_only(__move_only&&) noexcept = default;
67     auto operator=(__move_only&&) noexcept -> __move_only& = default;
68 
69     __move_only(const __move_only&) = delete;
70     auto operator=(const __move_only&) -> __move_only& = delete;
71 };
72 
73 template <class _Tp>
74 using __t = typename _Tp::__t;
75 
76 template <bool _Bp>
77 using __mbool = std::bool_constant<_Bp>;
78 
79 template <class _Ty>
80 struct __mtype
81 {
82     using __t = _Ty;
83 };
84 
85 template <auto _Value>
86 using __mtypeof = decltype(_Value);
87 
88 template <class...>
89 struct __types;
90 
91 template <class _Tp>
92 using __midentity = _Tp;
93 
94 template <std::size_t _Np>
95 using __msize_t = char[_Np + 1];
96 
97 template <auto _Np>
98 struct __mconstant_;
99 
100 template <auto _Np>
101 using __mconstant = __mconstant_<_Np>*;
102 
103 template <class _Tp, class _Up>
104 using __mfirst = _Tp;
105 
106 template <class _Tp, class _Up>
107 using __msecond = _Up;
108 
109 template <class _Tp>
110 extern const __undefined<_Tp> __v;
111 
112 template <class _Tp>
113     requires __typename<__mtypeof<_Tp::value>>
114 inline constexpr auto __v<_Tp> = _Tp::value;
115 
116 template <class _Tp, class _Up>
117 inline constexpr bool __v<std::is_same<_Tp, _Up>> = false;
118 
119 template <class _Tp>
120 inline constexpr bool __v<std::is_same<_Tp, _Tp>> = true;
121 
122 template <class _Tp, _Tp _Ip>
123 inline constexpr _Tp __v<std::integral_constant<_Tp, _Ip>> = _Ip;
124 
125 template <auto _Np>
126 inline constexpr __mtypeof<_Np> __v<__mconstant<_Np>> = _Np;
127 
128 template <std::size_t _Ip>
129 inline constexpr std::size_t __v<char[_Ip]> = _Ip - 1;
130 
131 template <std::size_t... _Is>
132 using __indices = std::index_sequence<_Is...>*;
133 
134 template <std::size_t _Np>
135 using __make_indices = std::make_index_sequence<_Np>*;
136 
137 template <class... _Ts>
138 using __indices_for = __make_indices<sizeof...(_Ts)>;
139 
140 template <class _Char>
141 concept __mchar = __same_as<_Char, char>;
142 
143 template <std::size_t _Len>
144 class __mstring
145 {
146     template <std::size_t... _Is>
__mstring(const char (& __str)[_Len],__indices<_Is...>)147     constexpr __mstring(const char (&__str)[_Len], __indices<_Is...>) noexcept :
148         __what_{__str[_Is]...}
149     {}
150 
151   public:
__mstring(const char (& __str)[_Len])152     constexpr __mstring(const char (&__str)[_Len]) noexcept :
153         __mstring{__str, __make_indices<_Len>{}}
154     {}
155 
156     template <__mchar... _Char>
157         requires(sizeof...(_Char) == _Len)
__mstring(_Char...__chars)158     constexpr __mstring(_Char... __chars) noexcept : __what_{__chars...}
159     {}
160 
__length()161     static constexpr auto __length() noexcept -> std::size_t
162     {
163         return _Len;
164     }
165 
166     template <std::size_t... _Is>
__equal(__mstring __other,__indices<_Is...>) const167     constexpr auto __equal(__mstring __other, __indices<_Is...>) const noexcept
168         -> bool
169     {
170         return ((__what_[_Is] == __other.__what_[_Is]) && ...);
171     }
172 
operator ==(__mstring __other) const173     constexpr auto operator==(__mstring __other) const noexcept -> bool
174     {
175         return __equal(__other, __make_indices<_Len>());
176     }
177 
178     const char __what_[_Len];
179 };
180 
181 template <std::size_t _Len>
182 __mstring(const char (&__str)[_Len]) -> __mstring<_Len>;
183 
184 STDEXEC_PRAGMA_PUSH()
185 STDEXEC_PRAGMA_IGNORE_GNU("-Wuser-defined-literals")
186 
187 #if STDEXEC_NVHPC() && (__EDG_VERSION__ < 604)
188 // Use a non-standard extension for older nvc++ releases
189 template <__mchar _Char, _Char... _Str>
190 [[deprecated("Use _mstr instead")]] constexpr __mstring<sizeof...(_Str)>
operator ""__csz()191     operator""__csz() noexcept
192 {
193     return {_Str...};
194 }
195 
196 // Use a non-standard extension for older nvc++ releases
197 template <__mchar _Char, _Char... _Str>
operator ""_mstr()198 constexpr __mstring<sizeof...(_Str)> operator""_mstr() noexcept
199 {
200     return {_Str...};
201 }
202 #elif STDEXEC_NVHPC() && (__EDG_VERSION__ < 605)
203 // This is to work around an unfiled (by me) EDG bug that fixed in build 605
204 template <__mstring _Str>
205 [[deprecated("Use _mstr instead")]] constexpr const __mtypeof<_Str>
206     operator""__csz() noexcept
207 {
208     return _Str;
209 }
210 
211 // This is to work around an unfiled (by me) EDG bug that fixed in build 605
212 template <__mstring _Str>
213 constexpr const __mtypeof<_Str> operator""_mstr() noexcept
214 {
215     return _Str;
216 }
217 #else
218 // Use a standard user-defined string literal template
219 template <__mstring _Str>
220 [[deprecated("Use _mstr instead")]] constexpr auto operator""__csz() noexcept
221     -> __mtypeof<_Str>
222 {
223     return _Str;
224 }
225 
226 // Use a standard user-defined string literal template
227 template <__mstring _Str>
228 constexpr auto operator""_mstr() noexcept -> __mtypeof<_Str>
229 {
230     return _Str;
231 }
232 #endif
233 
234 STDEXEC_PRAGMA_POP()
235 
236 using __msuccess = int;
237 
238 template <class _What, class... _With>
239 struct _WARNING_
240 {};
241 
242 template <class _What, class... _With>
243 struct _ERROR_
244 {
245     auto operator,(__msuccess) const noexcept -> _ERROR_;
246 };
247 
248 template <__mstring _What>
249 struct _WHAT_
250 {};
251 
252 template <class _What, class... _With>
253 using __mexception = _ERROR_<_What, _With...>;
254 
255 template <class>
256 extern __msuccess __ok_v;
257 
258 template <class _What, class... _With>
259 extern _ERROR_<_What, _With...> __ok_v<__mexception<_What, _With...>>;
260 
261 template <class _Ty>
262 using __ok_t = decltype(__ok_v<_Ty>);
263 
264 template <class... _Ts>
265 using __disp = decltype((__msuccess(), ..., __ok_t<_Ts>()));
266 
267 template <class _Arg>
268 concept __ok = __same_as<__ok_t<_Arg>, __msuccess>;
269 
270 template <class _Arg>
271 concept __merror = !__ok<_Arg>;
272 
273 template <class... _Args>
274 concept _Ok = (__ok<_Args> && ...);
275 
276 template <bool _AllOK>
277 struct __i;
278 
279 #if STDEXEC_NVHPC()
280 // Most compilers memoize alias template specializations, but
281 // nvc++ does not. So we memoize the type computations by
282 // indirecting through a class template specialization.
283 template <template <class...> class _Fn, class... _Args>
284 using __meval__ = typename __i<_Ok<_Args...>>::template __g<_Fn, _Args...>;
285 
286 template <template <class...> class _Fn, class... _Args>
287 struct __meval_
288 {};
289 
290 template <template <class...> class _Fn, class... _Args>
291     requires __typename<__meval__<_Fn, _Args...>>
292 struct __meval_<_Fn, _Args...>
293 {
294     using __t = __meval__<_Fn, _Args...>;
295 };
296 
297 template <template <class...> class _Fn, class... _Args>
298 using __meval = __t<__meval_<_Fn, _Args...>>;
299 
300 template <class _Fn, class... _Args>
301 using __minvoke__ = typename __i<_Ok<_Fn>>::template __h<_Fn, _Args...>;
302 
303 template <class _Fn, class... _Args>
304 struct __minvoke_
305 {};
306 
307 template <class _Fn, class... _Args>
308     requires __typename<__minvoke__<_Fn, _Args...>>
309 struct __minvoke_<_Fn, _Args...>
310 {
311     using __t = __minvoke__<_Fn, _Args...>;
312 };
313 
314 template <class _Fn, class... _Args>
315 using __minvoke = __t<__minvoke_<_Fn, _Args...>>;
316 
317 #else
318 
319 template <template <class...> class _Fn, class... _Args>
320 using __meval = typename __i<_Ok<_Args...>>::template __g<_Fn, _Args...>;
321 
322 template <class _Fn, class... _Args>
323 using __minvoke = typename __i<_Ok<_Fn>>::template __h<_Fn, _Args...>;
324 
325 #endif
326 
327 template <bool _AllOK>
328 struct __i
329 {
330     template <template <class...> class _Fn, class... _Args>
331     using __g = _Fn<_Args...>;
332 
333     template <class _Fn, class... _Args>
334     using __h = __meval<_Fn::template __f, _Args...>;
335 };
336 
337 template <>
338 struct __i<false>
339 {
340     template <template <class...> class, class... _Args>
341     using __g = __disp<_Args...>;
342 
343     template <class _Fn, class...>
344     using __h = _Fn;
345 };
346 
347 template <template <class...> class _Fn>
348 struct __q
349 {
350     template <class... _Args>
351     using __f = __meval<_Fn, _Args...>;
352 };
353 
354 template <template <class...> class _Fn, class... _Front>
355 struct __mbind_front_q
356 {
357     template <class... _Args>
358     using __f = __meval<_Fn, _Front..., _Args...>;
359 };
360 
361 template <class _Fn, class... _Front>
362 using __mbind_front = __mbind_front_q<_Fn::template __f, _Front...>;
363 
364 template <template <class...> class _Fn, class... _Back>
365 struct __mbind_back_q
366 {
367     template <class... _Args>
368     using __f = __meval<_Fn, _Args..., _Back...>;
369 };
370 
371 template <class _Fn, class... _Back>
372 using __mbind_back = __mbind_back_q<_Fn::template __f, _Back...>;
373 
374 template <template <class...> class _Tp, class... _Args>
375 concept __mvalid = requires { typename __meval<_Tp, _Args...>; };
376 
377 template <class _Fn, class... _Args>
378 concept __minvocable = __mvalid<_Fn::template __f, _Args...>;
379 
380 template <template <class...> class _Tp, class... _Args>
381 concept __msucceeds = __mvalid<_Tp, _Args...> && __ok<__meval<_Tp, _Args...>>;
382 
383 template <class _Fn, class... _Args>
384 concept __minvocable_succeeds = __minvocable<_Fn, _Args...> &&
385                                 __ok<__minvoke<_Fn, _Args...>>;
386 
387 template <class _Fn, class... _Args>
388 struct __force_minvoke_
389 {
390     using __t = __minvoke<_Fn, _Args...>;
391 };
392 template <class _Fn, class... _Args>
393 using __force_minvoke = __t<__force_minvoke_<_Fn, _Args...>>;
394 
395 template <class _Fn, class... _Args>
396 struct __mdefer_
397 {};
398 
399 template <class _Fn, class... _Args>
400     requires __minvocable<_Fn, _Args...>
401 struct __mdefer_<_Fn, _Args...>
402 {
403     using __t = __minvoke<_Fn, _Args...>;
404 };
405 
406 template <class _Fn, class... _Args>
407 struct __mdefer : __mdefer_<_Fn, _Args...>
408 {};
409 
410 template <class _Fn, class... _Args>
411 using __mmemoize = __t<__mdefer<_Fn, _Args...>>;
412 
413 template <template <class...> class _Fn, class... _Args>
414 using __mmemoize_q = __mmemoize<__q<_Fn>, _Args...>;
415 
416 struct __if_
417 {
418     template <bool>
419     struct __
420     {
421         template <class _True, class...>
422         using __f = _True;
423     };
424 
425     template <class _Pred, class _True, class... _False>
426     using __f = __minvoke<__<static_cast<bool>(__v<_Pred>)>, _True, _False...>;
427 };
428 
429 template <>
430 struct __if_::__<false>
431 {
432     template <class, class _False>
433     using __f = _False;
434 };
435 
436 template <class _Pred, class _True = void, class... _False>
437     requires(sizeof...(_False) <= 1)
438 using __if = __minvoke<__if_, _Pred, _True, _False...>;
439 
440 template <bool _Pred, class _True = void, class... _False>
441     requires(sizeof...(_False) <= 1)
442 using __if_c = __minvoke<__if_::__<_Pred>, _True, _False...>;
443 
444 template <class _Pred, class _True, class _False, class... _Args>
445 using __minvoke_if = __minvoke<__if<_Pred, _True, _False>, _Args...>;
446 
447 template <bool _Pred, class _True, class _False, class... _Args>
448 using __minvoke_if_c = __minvoke<__if_c<_Pred, _True, _False>, _Args...>;
449 
450 template <class _Tp>
451 struct __mconst
452 {
453     template <class...>
454     using __f = _Tp;
455 };
456 
457 inline constexpr __mstring __mbad_substitution =
458     "The specified meta-function could not be evaluated with the types provided."_mstr;
459 
460 template <__mstring _Diagnostic = __mbad_substitution>
461 struct _BAD_SUBSTITUTION_
462 {};
463 
464 template <class... _Args>
465 struct _WITH_TYPES_;
466 
467 template <template <class...> class _Fun>
468 struct _WITH_META_FUNCTION_T_
469 {
470     template <class... _Args>
471     using __f = __mexception<_BAD_SUBSTITUTION_<>, _WITH_META_FUNCTION_T_,
472                              _WITH_TYPES_<_Args...>>;
473 };
474 
475 template <class _Fun>
476 struct _WITH_META_FUNCTION_
477 {
478     template <class... _Args>
479     using __f = __mexception<_BAD_SUBSTITUTION_<>, _WITH_META_FUNCTION_,
480                              _WITH_TYPES_<_Args...>>;
481 };
482 
483 template <template <class...> class _Try, class _Catch>
484 struct __mtry_catch_q
485 {
486     template <class... _Args>
487     using __f = __minvoke<__if_c<__mvalid<_Try, _Args...>, __q<_Try>, _Catch>,
488                           _Args...>;
489 };
490 
491 template <class _Try, class _Catch>
492 struct __mtry_catch
493 {
494     template <class... _Args>
495     using __f =
496         __minvoke<__if_c<__minvocable<_Try, _Args...>, _Try, _Catch>, _Args...>;
497 };
498 
499 template <class _Fn, class _Default>
500 using __with_default = __mtry_catch<_Fn, __mconst<_Default>>;
501 
502 template <template <class...> class _Fn, class _Default>
503 using __with_default_q = __mtry_catch_q<_Fn, __mconst<_Default>>;
504 
505 template <class _Fn, class _Default, class... _Args>
506 using __minvoke_or = __minvoke<__with_default<_Fn, _Default>, _Args...>;
507 
508 template <template <class...> class _Fn, class _Default, class... _Args>
509 using __meval_or = __minvoke<__with_default_q<_Fn, _Default>, _Args...>;
510 
511 template <template <class...> class _Fn>
512 struct __mtry_eval_
513 {
514     template <class... _Args>
515     using __f = __meval<_Fn, _Args...>;
516 };
517 
518 template <template <class...> class _Fn, class... _Args>
519 using __mtry_eval =
520     __minvoke<__mtry_catch<__mtry_eval_<_Fn>, _WITH_META_FUNCTION_T_<_Fn>>,
521               _Args...>;
522 
523 template <class _Fn, class... _Args>
524 using __mtry_invoke =
525     __minvoke<__mtry_catch<_Fn, _WITH_META_FUNCTION_<_Fn>>, _Args...>;
526 
527 template <class _Ty, class... _Default>
528 using __msuccess_or_t = __if_c<__ok<_Ty>, _Ty, _Default...>;
529 
530 template <class _Fn, class _Continuation = __q<__types>>
531 struct __transform
532 {
533     template <class... _Args>
534     using __f = __minvoke<_Continuation, __minvoke<_Fn, _Args>...>;
535 };
536 
537 template <bool>
538 struct __mfold_right_
539 {
540     template <class _Fn, class _State, class _Head, class... _Tail>
541     using __f = __minvoke<__mfold_right_<sizeof...(_Tail) == 0>, _Fn,
542                           __minvoke<_Fn, _State, _Head>, _Tail...>;
543 };
544 
545 template <>
546 struct __mfold_right_<true>
547 { // empty pack
548     template <class _Fn, class _State, class...>
549     using __f = _State;
550 };
551 
552 template <class _Init, class _Fn>
553 struct __mfold_right
554 {
555     template <class... _Args>
556     using __f =
557         __minvoke<__mfold_right_<sizeof...(_Args) == 0>, _Fn, _Init, _Args...>;
558 };
559 
560 template <class _Continuation, class... _As>
561 struct __mconcat_
562 {};
563 
564 template <class _Continuation, class... _As>
565     requires(sizeof...(_As) == 0) && __minvocable<_Continuation, _As...>
566 struct __mconcat_<_Continuation, _As...>
567 {
568     using __t = __minvoke<_Continuation, _As...>;
569 };
570 
571 template <class _Continuation, template <class...> class _Ap, class... _As>
572     requires __minvocable<_Continuation, _As...>
573 struct __mconcat_<_Continuation, _Ap<_As...>>
574 {
575     using __t = __minvoke<_Continuation, _As...>;
576 };
577 
578 template <               //
579     class _Continuation, //
580     template <class...> class _Ap,
581     class... _As,        //
582     template <class...> class _Bp, class... _Bs>
583     requires __minvocable<_Continuation, _As..., _Bs...>
584 struct __mconcat_<_Continuation, _Ap<_As...>, _Bp<_Bs...>>
585 {
586     using __t = __minvoke<_Continuation, _As..., _Bs...>;
587 };
588 
589 template <               //
590     class _Continuation, //
591     template <class...> class _Ap,
592     class... _As,        //
593     template <class...> class _Bp,
594     class... _Bs,        //
595     template <class...> class _Cp, class... _Cs>
596     requires __minvocable<_Continuation, _As..., _Bs..., _Cs...>
597 struct __mconcat_<_Continuation, _Ap<_As...>, _Bp<_Bs...>, _Cp<_Cs...>>
598 {
599     using __t = __minvoke<_Continuation, _As..., _Bs..., _Cs...>;
600 };
601 
602 template <               //
603     class _Continuation, //
604     template <class...> class _Ap,
605     class... _As,        //
606     template <class...> class _Bp,
607     class... _Bs,        //
608     template <class...> class _Cp,
609     class... _Cs,        //
610     template <class...> class _Dp,
611     class... _Ds,        //
612     class... _Tail>
613 struct __mconcat_<_Continuation, _Ap<_As...>, _Bp<_Bs...>, _Cp<_Cs...>,
614                   _Dp<_Ds...>, _Tail...> :
615     __mconcat_<_Continuation, __types<_As..., _Bs..., _Cs..., _Ds...>, _Tail...>
616 {};
617 
618 template <class _Continuation = __q<__types>>
619 struct __mconcat
620 {
621     template <class... _Args>
622     using __f = __t<__mconcat_<_Continuation, _Args...>>;
623 };
624 
625 template <class _Fn>
626 struct __curry
627 {
628     template <class... _Ts>
629     using __f = __minvoke<_Fn, _Ts...>;
630 };
631 
632 template <class _Fn, class _Tp>
633 struct __uncurry_;
634 
635 template <__merror _Fn, class _Tp>
636 struct __uncurry_<_Fn, _Tp>
637 {
638     using __t = _Fn;
639 };
640 
641 template <class _Fn, template <class...> class _Ap, class... _As>
642     requires __minvocable<_Fn, _As...>
643 struct __uncurry_<_Fn, _Ap<_As...>>
644 {
645     using __t = __minvoke<_Fn, _As...>;
646 };
647 
648 template <class _Fn>
649 struct __uncurry
650 {
651     template <class _Tp>
652     using __f = __t<__uncurry_<_Fn, _Tp>>;
653 };
654 template <class _Fn, class _List>
655 using __mapply = __minvoke<__uncurry<_Fn>, _List>;
656 
657 struct __msize
658 {
659     template <class... _Ts>
660     using __f = __msize_t<sizeof...(_Ts)>;
661 };
662 
663 template <class _Ty>
664 struct __mcount
665 {
666     template <class... _Ts>
667     using __f = __msize_t<(__same_as<_Ts, _Ty> + ... + 0)>;
668 };
669 
670 template <class _Fn>
671 struct __mcount_if
672 {
673     template <class... _Ts>
674     using __f = __msize_t<(bool(__v<__minvoke<_Fn, _Ts>>) + ... + 0)>;
675 };
676 
677 template <class _Tp>
678 struct __contains
679 {
680     template <class... _Args>
681     using __f = __mbool<(__same_as<_Tp, _Args> || ...)>;
682 };
683 
684 template <class _Continuation = __q<__types>>
685 struct __push_back
686 {
687     template <class _List, class _Item>
688     using __f = __mapply<__mbind_back<_Continuation, _Item>, _List>;
689 };
690 
691 template <class _Continuation = __q<__types>>
692 struct __push_back_unique
693 {
694     template <class _List, class _Item>
695     using __f = //
696         __mapply<__if<__mapply<__contains<_Item>, _List>, _Continuation,
697                       __mbind_back<_Continuation, _Item>>,
698                  _List>;
699 };
700 
701 template <class _Continuation = __q<__types>>
702 struct __munique
703 {
704     template <class... _Ts>
705     using __f = __mapply<
706         _Continuation,
707         __minvoke<__mfold_right<__types<>, __push_back_unique<>>, _Ts...>>;
708 };
709 
710 template <class...>
711 struct __mcompose
712 {};
713 
714 template <class _First>
715 struct __mcompose<_First> : _First
716 {};
717 
718 template <class _Second, class _First>
719 struct __mcompose<_Second, _First>
720 {
721     template <class... _Args>
722     using __f = __minvoke<_Second, __minvoke<_First, _Args...>>;
723 };
724 
725 template <class _Last, class _Penultimate, class... _Rest>
726 struct __mcompose<_Last, _Penultimate, _Rest...>
727 {
728     template <class... _Args>
729     using __f =
730         __minvoke<_Last,
731                   __minvoke<__mcompose<_Penultimate, _Rest...>, _Args...>>;
732 };
733 
734 template <class _Old, class _New, class _Continuation = __q<__types>>
735 struct __replace
736 {
737     template <class... _Args>
738     using __f = __minvoke<_Continuation,
739                           __if_c<__same_as<_Args, _Old>, _New, _Args>...>;
740 };
741 
742 template <class _Old, class _Continuation = __q<__types>>
743 struct __remove
744 {
745     template <class... _Args>
746     using __f = //
747         __minvoke<__mconcat<_Continuation>,
748                   __if_c<__same_as<_Args, _Old>, __types<>, __types<_Args>>...>;
749 };
750 
751 template <class _Pred, class _Continuation = __q<__types>>
752 struct __remove_if
753 {
754     template <class... _Args>
755     using __f = //
756         __minvoke<__mconcat<_Continuation>,
757                   __if<__minvoke<_Pred, _Args>, __types<>, __types<_Args>>...>;
758 };
759 
760 template <class _Return>
761 struct __qf
762 {
763     template <class... _Args>
764     using __f = _Return(_Args...);
765 };
766 
767 template <class _Ty, class...>
768 using __mfront_ = _Ty;
769 template <class... _As>
770 using __mfront = __meval<__mfront_, _As...>;
771 template <class... _As>
772     requires(sizeof...(_As) == 1)
773 using __msingle = __mfront<_As...>;
774 template <class _Default, class... _As>
775     requires(sizeof...(_As) <= 1)
776 using __msingle_or_ = __mfront<_As..., _Default>;
777 template <class _Default>
778 using __msingle_or = __mbind_front_q<__msingle_or_, _Default>;
779 
780 template <class _Continuation = __q<__types>>
781 struct __pop_front
782 {
783     template <class, class... _Ts>
784     using __f = __minvoke<_Continuation, _Ts...>;
785 };
786 
787 template <class _Ty>
788 concept __has_id = requires { typename _Ty::__id; };
789 
790 template <class _Ty>
791 struct _Id
792 {
793     using __t = _Ty;
794 
795     // Uncomment the line below to find any code that likely misuses the
796     // ADL isolation mechanism. In particular, '__id<T>' when T is a
797     // reference is a likely misuse. The static_assert below will trigger
798     // when the type passed to the __id alias template is a reference to
799     // a type that is setup to use ADL isolation.
800     // static_assert(!__has_id<std::remove_cvref_t<_Ty>>);
801 };
802 
803 template <bool = true>
804 struct __id_
805 {
806     template <class _Ty>
807     using __f = typename _Ty::__id;
808 };
809 
810 template <>
811 struct __id_<false>
812 {
813     template <class _Ty>
814     using __f = _Id<_Ty>;
815 };
816 template <class _Ty>
817 using __id = __minvoke<__id_<__has_id<_Ty>>, _Ty>;
818 
819 template <class _From, class _To = __decay_t<_From>>
820 using __cvref_t = __copy_cvref_t<_From, __t<_To>>;
821 
822 template <class _From, class _To = __decay_t<_From>>
823 using __cvref_id = __copy_cvref_t<_From, __id<_To>>;
824 
825 #if STDEXEC_NVHPC()
826 // nvc++ doesn't cache the results of alias template specializations.
827 // To avoid repeated computation of the same function return type,
828 // cache the result ourselves in a class template specialization.
829 template <class _Fun, class... _As>
830 using __call_result_ = decltype(__declval<_Fun>()(__declval<_As>()...));
831 template <class _Fun, class... _As>
832 using __call_result_t = __t<__mdefer<__q<__call_result_>, _Fun, _As...>>;
833 #else
834 template <class _Fun, class... _As>
835 using __call_result_t = decltype(__declval<_Fun>()(__declval<_As>()...));
836 #endif
837 
838 template <const auto& _Fun, class... _As>
839 using __result_of = __call_result_t<decltype(_Fun), _As...>;
840 
841 // For working around clang's lack of support for CWG#2369:
842 // http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#2369
843 struct __qcall_result
844 {
845     template <class _Fun, class... _As>
846     using __f = __call_result_t<_Fun, _As...>;
847 };
848 template <bool _Enable, class _Fun, class... _As>
849 using __call_result_if_t =
850     __minvoke<__if<__mbool<_Enable>, __qcall_result, __>, _Fun, _As...>;
851 
852 // For emplacing non-movable types into optionals:
853 template <class _Fn>
854     requires std::is_nothrow_move_constructible_v<_Fn>
855 struct __conv
856 {
857     _Fn __fn_;
858     using __t = __call_result_t<_Fn>;
859 
operator __tstdexec::__conv860     operator __t() && noexcept(__nothrow_callable<_Fn>)
861     {
862         return static_cast<_Fn&&>(__fn_)();
863     }
864 
operator ()stdexec::__conv865     auto operator()() && noexcept(__nothrow_callable<_Fn>) -> __t
866     {
867         return static_cast<_Fn&&>(__fn_)();
868     }
869 };
870 template <class _Fn>
871 __conv(_Fn) -> __conv<_Fn>;
872 
873 // Implemented as a class instead of a free function
874 // because of a bizarre nvc++ compiler bug:
875 struct __cref_fn
876 {
877     template <class _Ty>
878     auto operator()(const _Ty&) -> const _Ty&;
879 };
880 template <class _Ty>
881 using __cref_t = decltype(__cref_fn{}(__declval<_Ty>()));
882 
883 template <class, class, class, class>
884 struct __mzip_with2_;
885 
886 template <               //
887     class _Fn,           //
888     class _Continuation, //
889     template <class...> class _Cp,
890     class... _Cs,        //
891     template <class...> class _Dp, class... _Ds>
892     requires requires {
893                  typename __minvoke<_Continuation, __minvoke<_Fn, _Cs, _Ds>...>;
894              }
895 struct __mzip_with2_<_Fn, _Continuation, _Cp<_Cs...>, _Dp<_Ds...>>
896 {
897     using __t = __minvoke<_Continuation, __minvoke<_Fn, _Cs, _Ds>...>;
898 };
899 
900 template <class _Fn, class _Continuation = __q<__types>>
901 struct __mzip_with2
902 {
903     template <class _Cp, class _Dp>
904     using __f = __t<__mzip_with2_<_Fn, _Continuation, _Cp, _Dp>>;
905 };
906 
907 #if STDEXEC_GCC() && (__GNUC__ < 12)
908 template <class>
909 extern int __mconvert_indices;
910 template <std::size_t... _Indices>
911 extern __types<__msize_t<_Indices>...>
912     __mconvert_indices<std::index_sequence<_Indices...>>;
913 template <std::size_t _Np>
914 using __mmake_index_sequence =
915     decltype(stdexec::__mconvert_indices<std::make_index_sequence<_Np>>);
916 #else
917 template <std::size_t... _Indices>
918 auto __mconvert_indices(std::index_sequence<_Indices...>*)
919     -> __types<__msize_t<_Indices>...>;
920 template <std::size_t _Np>
921 using __mmake_index_sequence = decltype(stdexec::__mconvert_indices(
922     static_cast<std::make_index_sequence<_Np>*>(nullptr)));
923 #endif
924 
925 template <class... _Ts>
926 using __mindex_sequence_for = __mmake_index_sequence<sizeof...(_Ts)>;
927 
928 template <bool>
929 struct __mfind_if_
930 {
931     template <class _Fn, class _Continuation, class _Head, class... _Tail>
932     using __f = //
933         __minvoke<__if_c<__v<__minvoke<_Fn, _Head>>,
934                          __mbind_front<_Continuation, _Head>,
935                          __mbind_front<__mfind_if_<(sizeof...(_Tail) != 0)>,
936                                        _Fn, _Continuation>>,
937                   _Tail...>;
938 };
939 
940 template <>
941 struct __mfind_if_<false>
942 {
943     template <class _Fn, class _Continuation>
944     using __f = __minvoke<_Continuation>;
945 };
946 
947 template <class _Fn, class _Continuation = __q<__types>>
948 struct __mfind_if
949 {
950     template <class... _Args>
951     using __f = __minvoke<__mfind_if_<(sizeof...(_Args) != 0)>, _Fn,
952                           _Continuation, _Args...>;
953 };
954 
955 template <class _Fn>
956 struct __mfind_if_i
957 {
958     template <class... _Args>
959     using __f = __msize_t<(sizeof...(_Args) -
960                            __v<__minvoke<__mfind_if<_Fn, __msize>, _Args...>>)>;
961 };
962 
963 template <class... _Booleans>
964 using __mand_ = __mbool<(__v<_Booleans> && ...)>;
965 template <class... _Booleans>
966 using __mand = __meval<__mand_, _Booleans...>;
967 
968 template <class... _Booleans>
969 using __mor_ = __mbool<(__v<_Booleans> || ...)>;
970 template <class... _Booleans>
971 using __mor = __meval<__mor_, _Booleans...>;
972 
973 template <class _Boolean>
974 using __mnot_ = __mbool<!__v<_Boolean>>;
975 template <class _Boolean>
976 using __mnot = __meval<__mnot_, _Boolean>;
977 
978 template <class _Fn>
979 struct __mall_of
980 {
981     template <class... _Args>
982     using __f = __mand<__minvoke<_Fn, _Args>...>;
983 };
984 
985 template <class _Fn>
986 struct __mnone_of
987 {
988     template <class... _Args>
989     using __f = __mand<__mnot<__minvoke<_Fn, _Args>>...>;
990 };
991 
992 template <class _Fn>
993 struct __many_of
994 {
995     template <class... _Args>
996     using __f = __mor<__minvoke<_Fn, _Args>...>;
997 };
998 
999 #if STDEXEC_HAS_BUILTIN(__type_pack_element)
1000 template <std::size_t _Np, class... _Ts>
1001 struct __m_at_
1002 {
1003     using __t = __type_pack_element<_Np, _Ts...>;
1004 };
1005 
1006 template <std::size_t _Np, class... _Ts>
1007 using __m_at_c = __t<__m_at_<_Np, _Ts...>>;
1008 #else
1009 template <std::size_t>
1010 using __void_ptr = void*;
1011 
1012 template <class _Ty>
1013 using __mtype_ptr = __mtype<_Ty>*;
1014 
1015 template <class _Ty>
1016 struct __m_at_;
1017 
1018 template <std::size_t... _Is>
1019 struct __m_at_<std::index_sequence<_Is...>>
1020 {
1021     template <class _Up, class... _Us>
1022     static _Up __f_(__void_ptr<_Is>..., _Up*, _Us*...);
1023     template <class... _Ts>
1024     using __f = __t<decltype(__m_at_::__f_(__mtype_ptr<_Ts>()...))>;
1025 };
1026 
1027 template <std::size_t _Np, class... _Ts>
1028 using __m_at_c = __minvoke<__m_at_<std::make_index_sequence<_Np>>, _Ts...>;
1029 #endif
1030 
1031 template <class _Np, class... _Ts>
1032 using __m_at = __m_at_c<__v<_Np>, _Ts...>;
1033 
1034 template <class... _Ts>
1035 using __mback = __m_at_c<sizeof...(_Ts) - 1, _Ts...>;
1036 
1037 template <class _Continuation = __q<__types>>
1038 struct __mpop_back
1039 {
1040     template <class>
1041     struct __impl;
1042 
1043     template <std::size_t... _Idx>
1044     struct __impl<__indices<_Idx...>>
1045     {
1046         template <class... _Ts>
1047         using __f = __minvoke<_Continuation, __m_at_c<_Idx, _Ts...>...>;
1048     };
1049 
1050     template <class... _Ts>
1051         requires(sizeof...(_Ts) != 0)
1052     using __f = __minvoke<__impl<__make_indices<sizeof...(_Ts) - 1>>, _Ts...>;
1053 };
1054 
1055 template <std::size_t _Np>
1056 struct __placeholder
1057 {
1058     __placeholder() = default;
1059 
__placeholderstdexec::__placeholder1060     constexpr __placeholder(void*) noexcept {}
1061 
__get_placeholder_offset(__placeholder)1062     friend constexpr auto __get_placeholder_offset(__placeholder) noexcept
1063         -> std::size_t
1064     {
1065         return _Np;
1066     }
1067 };
1068 
1069 using __0 = __placeholder<0>;
1070 using __1 = __placeholder<1>;
1071 using __2 = __placeholder<2>;
1072 using __3 = __placeholder<3>;
1073 
1074 #if STDEXEC_MSVC()
1075 // MSVCBUG
1076 // https://developercommunity.visualstudio.com/t/Incorrect-function-template-argument-sub/10437827
1077 
1078 template <std::size_t>
1079 struct __ignore_t
1080 {
1081     __ignore_t() = default;
1082 
__ignore_tstdexec::__ignore_t1083     constexpr __ignore_t(auto&&...) noexcept {}
1084 };
1085 #else
1086 template <std::size_t>
1087 using __ignore_t = __ignore;
1088 #endif
1089 
1090 template <class... _Ignore>
1091 struct __nth_pack_element_impl
1092 {
1093     template <class _Ty, class... _Us>
1094     STDEXEC_ATTRIBUTE((always_inline))
operator ()stdexec::__nth_pack_element_impl1095     constexpr _Ty&& operator()(_Ignore..., _Ty&& __t, _Us&&...) const noexcept
1096     {
1097         return static_cast<decltype(__t)&&>(__t);
1098     }
1099 };
1100 
1101 template <std::size_t _Np>
1102 struct __nth_pack_element_t
1103 {
1104     template <std::size_t... _Is>
1105     STDEXEC_ATTRIBUTE((always_inline))
__implstdexec::__nth_pack_element_t1106     static constexpr auto __impl(__indices<_Is...>) noexcept
1107     {
1108         return __nth_pack_element_impl<__ignore_t<_Is>...>();
1109     }
1110 
1111     template <class... _Ts>
1112     STDEXEC_ATTRIBUTE((always_inline))
operator ()stdexec::__nth_pack_element_t1113     constexpr decltype(auto) operator()(_Ts&&... __ts) const noexcept
1114     {
1115         static_assert(_Np < sizeof...(_Ts));
1116         return __impl(__make_indices<_Np>())(static_cast<_Ts&&>(__ts)...);
1117     }
1118 };
1119 
1120 template <std::size_t _Np>
1121 inline constexpr __nth_pack_element_t<_Np> __nth_pack_element{};
1122 
1123 template <auto... _Vs>
1124 struct __mliterals
1125 {
1126     template <std::size_t _Np>
1127     STDEXEC_ATTRIBUTE((always_inline))
__nthstdexec::__mliterals1128     static constexpr auto __nth() noexcept
1129     {
1130         return stdexec::__nth_pack_element<_Np>(_Vs...);
1131     }
1132 };
1133 
1134 template <std::size_t _Np>
1135 struct __nth_member
1136 {
1137     template <class _Ty>
1138     STDEXEC_ATTRIBUTE((always_inline))
operator ()stdexec::__nth_member1139     constexpr decltype(auto) operator()(_Ty&& __ty) const noexcept
1140     {
1141         return static_cast<_Ty&&>(__ty).*(__ty.__mbrs_.template __nth<_Np>());
1142     }
1143 };
1144 
1145 template <class _Ty, std::size_t _Offset = 0>
1146 struct __mdispatch_
1147 {
1148     template <class... _Ts>
operator ()stdexec::__mdispatch_1149     auto operator()(_Ts&&...) const noexcept(noexcept(_Ty{})) -> _Ty
1150     {
1151         return _Ty{};
1152     }
1153 };
1154 
1155 template <std::size_t _Np, std::size_t _Offset>
1156 struct __mdispatch_<__placeholder<_Np>, _Offset>
1157 {
1158     template <class... _Ts>
operator ()stdexec::__mdispatch_1159     auto operator()(_Ts&&... __ts) const noexcept -> decltype(auto)
1160     {
1161         return stdexec::__nth_pack_element<_Np + _Offset>(
1162             static_cast<_Ts&&>(__ts)...);
1163     }
1164 };
1165 
1166 template <std::size_t _Np, std::size_t _Offset>
1167 struct __mdispatch_<__placeholder<_Np>&, _Offset>
1168 {
1169     template <class... _Ts>
operator ()stdexec::__mdispatch_1170     auto operator()(_Ts&&... __ts) const noexcept -> decltype(auto)
1171     {
1172         return stdexec::__nth_pack_element<_Np + _Offset>(__ts...);
1173     }
1174 };
1175 
1176 template <std::size_t _Np, std::size_t _Offset>
1177 struct __mdispatch_<__placeholder<_Np>&&, _Offset>
1178 {
1179     template <class... _Ts>
operator ()stdexec::__mdispatch_1180     auto operator()(_Ts&&... __ts) const noexcept -> decltype(auto)
1181     {
1182         return std::move(stdexec::__nth_pack_element<_Np + _Offset>(__ts...));
1183     }
1184 };
1185 
1186 template <std::size_t _Np, std::size_t _Offset>
1187 struct __mdispatch_<const __placeholder<_Np>&, _Offset>
1188 {
1189     template <class... _Ts>
operator ()stdexec::__mdispatch_1190     auto operator()(_Ts&&... __ts) const noexcept -> decltype(auto)
1191     {
1192         return std::as_const(
1193             stdexec::__nth_pack_element<_Np + _Offset>(__ts...));
1194     }
1195 };
1196 
1197 template <class _Ret, class... _Args, std::size_t _Offset>
1198 struct __mdispatch_<_Ret (*)(_Args...), _Offset>
1199 {
1200     template <class... _Ts>
1201         requires(__callable<__mdispatch_<_Args, _Offset>, _Ts...> && ...) &&
1202                 __callable<_Ret, __call_result_t<__mdispatch_<_Args, _Offset>,
1203                                                  _Ts...>...>
operator ()stdexec::__mdispatch_1204     auto operator()(_Ts&&... __ts) const noexcept(
1205         __nothrow_callable<
1206             _Ret, __call_result_t<__mdispatch_<_Args, _Offset>, _Ts...>...>)
1207         -> __call_result_t<
1208             _Ret, __call_result_t<__mdispatch_<_Args, _Offset>, _Ts...>...>
1209     {
1210         return _Ret{}(
1211             __mdispatch_<_Args, _Offset>{}(static_cast<_Ts&&>(__ts)...)...);
1212     }
1213 };
1214 
1215 template <class _Ret, class... _Args, std::size_t _Offset>
1216 struct __mdispatch_<_Ret (*)(_Args..., ...), _Offset>
1217 {
1218     static_assert(_Offset == 0, "nested pack expressions are not supported");
1219     using _Pattern = __mback<_Args...>;
1220     static constexpr std::size_t __offset =
1221         __get_placeholder_offset(static_cast<__mtype<_Pattern>*>(nullptr));
1222 
1223     struct __impl
1224     {
1225         template <std::size_t... _Idx, class... _Ts>
1226             requires(__callable<__mdispatch_<_Args>, _Ts...> && ...) &&
1227                     (__callable<__mdispatch_<_Pattern, _Idx + 1>, _Ts...> &&
1228                      ...) &&
1229                     __callable< //
1230                         _Ret, __call_result_t<__mdispatch_<_Args>, _Ts...>...,
1231                         __call_result_t<__mdispatch_<_Pattern, _Idx + 1>,
1232                                         _Ts...>...>
operator ()stdexec::__mdispatch_::__impl1233         auto operator()(__indices<_Idx...>, _Ts&&... __ts) const noexcept(
1234             __nothrow_callable<                                  //
1235                 _Ret,                                            //
1236                 __call_result_t<__mdispatch_<_Args>, _Ts...>..., //
1237                 __call_result_t<__mdispatch_<_Pattern, _Idx + 1>, _Ts...>...>)
1238             -> __call_result_t<                                  //
1239                 _Ret, __call_result_t<__mdispatch_<_Args>, _Ts...>...,
1240                 __call_result_t<__mdispatch_<_Pattern, _Idx + 1>, _Ts...>...>
1241         {
1242             return _Ret()(                                             //
1243                 __mdispatch_<_Args>()(static_cast<_Ts&&>(__ts)...)..., //
1244                 __mdispatch_<_Pattern, _Idx + 1>()(
1245                     static_cast<_Ts&&>(__ts)...)...);
1246         }
1247     };
1248 
1249     template <class... _Ts>
1250         requires(__offset < sizeof...(_Ts)) &&
1251                 __callable<__impl,
1252                            __make_indices<sizeof...(_Ts) - __offset - 1>,
1253                            _Ts...>
operator ()stdexec::__mdispatch_1254     auto operator()(_Ts&&... __ts) const noexcept(
1255         __nothrow_callable<
1256             __impl, __make_indices<sizeof...(_Ts) - __offset - 1>, _Ts...>)
1257         -> __msecond<
1258             __if_c<(__offset < sizeof...(_Ts))>,
1259             __call_result_t<
1260                 __impl, __make_indices<sizeof...(_Ts) - __offset - 1>, _Ts...>>
1261     {
1262         return __impl()(__make_indices<sizeof...(_Ts) - __offset - 1>(),
1263                         static_cast<_Ts&&>(__ts)...);
1264     }
1265 
1266     template <class... _Ts>
1267         requires(sizeof...(_Ts) == __offset) &&
1268                 __callable<
1269                     __mdispatch_<__minvoke<__mpop_back<__qf<_Ret>>, _Args...>*>,
1270                     _Ts...>
operator ()stdexec::__mdispatch_1271     auto operator()(_Ts&&... __ts) const
1272         noexcept(__nothrow_callable<
1273                  __mdispatch_<__minvoke<__mpop_back<__qf<_Ret>>, _Args...>*>,
1274                  _Ts...>)
1275             -> __msecond<
1276                 __if_c<(sizeof...(_Ts) == __offset)>,
1277                 __call_result_t<
1278                     __mdispatch_<__minvoke<__mpop_back<__qf<_Ret>>, _Args...>*>,
1279                     _Ts...>>
1280     {
1281         return __mdispatch_<__minvoke<__mpop_back<__qf<_Ret>>, _Args...>*>()(
1282             static_cast<_Ts&&>(__ts)...);
1283     }
1284 };
1285 
1286 template <class _Ty>
1287 struct __mdispatch
1288 {};
1289 
1290 template <class _Ret, class... _Args>
1291 struct __mdispatch<_Ret(_Args...)> : __mdispatch_<_Ret (*)(_Args...)>
1292 {};
1293 
1294 template <class _Ret, class... _Args>
1295 struct __mdispatch<_Ret(_Args..., ...)> : __mdispatch_<_Ret (*)(_Args..., ...)>
1296 {};
1297 
1298 template <class _Ty, class... _Ts>
1299 concept __dispatchable = __callable<__mdispatch<_Ty>, _Ts...>;
1300 
1301 template <class _Ty, class... _Ts>
1302 concept __nothrow_dispatchable = __nothrow_callable<__mdispatch<_Ty>, _Ts...>;
1303 
1304 template <class _Ty, class... _Ts>
1305 using __dispatch_result_t = __call_result_t<__mdispatch<_Ty>, _Ts...>;
1306 
1307 template <class _Signature, class... _Args>
1308 using __try_dispatch_ = __mbool<__dispatchable<_Signature, _Args...>>;
1309 
1310 template <class _Signatures, class _Continuation = __q<__mfront>>
1311 struct __which
1312 {};
1313 
1314 template <template <class...> class _Cp, class... _Signatures,
1315           class _Continuation>
1316 struct __which<_Cp<_Signatures...>, _Continuation>
1317 {
1318     template <class... _Args>
1319     using __f = //
1320         __minvoke<__mfind_if<__mbind_back_q<__try_dispatch_, _Args...>,
1321                              _Continuation>,
1322                   _Signatures...>;
1323 };
1324 
1325 template <class _Signatures, class _DefaultFn, class... _Args>
1326 using __make_dispatcher = //
1327     __minvoke<__mtry_catch<__mcompose<__q<__mdispatch>, __which<_Signatures>>,
1328                            _DefaultFn>,
1329               _Args...>;
1330 } // namespace stdexec
1331