Thanks for using Compiler Explorer
Sponsors
Jakt
C++
Ada
Analysis
Android Java
Android Kotlin
Assembly
C
C3
Carbon
C++ (Circle)
CIRCT
Clean
CMake
CMakeScript
COBOL
C++ for OpenCL
MLIR
Cppx
Cppx-Blue
Cppx-Gold
Cpp2-cppfront
Crystal
C#
CUDA C++
D
Dart
Elixir
Erlang
Fortran
F#
Go
Haskell
HLSL
Hook
Hylo
ispc
Java
Julia
Kotlin
LLVM IR
LLVM MIR
Modula-2
Nim
Objective-C
Objective-C++
OCaml
OpenCL C
Pascal
Pony
Python
Racket
Ruby
Rust
Snowball
Scala
Solidity
Spice
Swift
LLVM TableGen
Toit
TypeScript Native
V
Vala
Visual Basic
WASM
Zig
Javascript
GIMPLE
c++ source #1
Output
Compile to binary object
Link to binary
Execute the code
Intel asm syntax
Demangle identifiers
Verbose demangling
Filters
Unused labels
Library functions
Directives
Comments
Horizontal whitespace
Debug intrinsics
Compiler
6502-c++ 11.1.0
ARM GCC 10.2.0
ARM GCC 10.3.0
ARM GCC 10.4.0
ARM GCC 10.5.0
ARM GCC 11.1.0
ARM GCC 11.2.0
ARM GCC 11.3.0
ARM GCC 11.4.0
ARM GCC 12.1.0
ARM GCC 12.2.0
ARM GCC 12.3.0
ARM GCC 12.4.0
ARM GCC 13.1.0
ARM GCC 13.2.0
ARM GCC 13.2.0 (unknown-eabi)
ARM GCC 13.3.0
ARM GCC 13.3.0 (unknown-eabi)
ARM GCC 14.1.0
ARM GCC 14.1.0 (unknown-eabi)
ARM GCC 14.2.0
ARM GCC 14.2.0 (unknown-eabi)
ARM GCC 4.5.4
ARM GCC 4.6.4
ARM GCC 5.4
ARM GCC 6.3.0
ARM GCC 6.4.0
ARM GCC 7.3.0
ARM GCC 7.5.0
ARM GCC 8.2.0
ARM GCC 8.5.0
ARM GCC 9.3.0
ARM GCC 9.4.0
ARM GCC 9.5.0
ARM GCC trunk
ARM gcc 10.2.1 (none)
ARM gcc 10.3.1 (2021.07 none)
ARM gcc 10.3.1 (2021.10 none)
ARM gcc 11.2.1 (none)
ARM gcc 5.4.1 (none)
ARM gcc 7.2.1 (none)
ARM gcc 8.2 (WinCE)
ARM gcc 8.3.1 (none)
ARM gcc 9.2.1 (none)
ARM msvc v19.0 (WINE)
ARM msvc v19.10 (WINE)
ARM msvc v19.14 (WINE)
ARM64 Morello gcc 10.1 Alpha 2
ARM64 gcc 10.2
ARM64 gcc 10.3
ARM64 gcc 10.4
ARM64 gcc 10.5.0
ARM64 gcc 11.1
ARM64 gcc 11.2
ARM64 gcc 11.3
ARM64 gcc 11.4.0
ARM64 gcc 12.1
ARM64 gcc 12.2.0
ARM64 gcc 12.3.0
ARM64 gcc 12.4.0
ARM64 gcc 13.1.0
ARM64 gcc 13.2.0
ARM64 gcc 13.3.0
ARM64 gcc 14.1.0
ARM64 gcc 14.2.0
ARM64 gcc 4.9.4
ARM64 gcc 5.4
ARM64 gcc 5.5.0
ARM64 gcc 6.3
ARM64 gcc 6.4
ARM64 gcc 7.3
ARM64 gcc 7.5
ARM64 gcc 8.2
ARM64 gcc 8.5
ARM64 gcc 9.3
ARM64 gcc 9.4
ARM64 gcc 9.5
ARM64 gcc trunk
ARM64 msvc v19.14 (WINE)
AVR gcc 10.3.0
AVR gcc 11.1.0
AVR gcc 12.1.0
AVR gcc 12.2.0
AVR gcc 12.3.0
AVR gcc 12.4.0
AVR gcc 13.1.0
AVR gcc 13.2.0
AVR gcc 13.3.0
AVR gcc 14.1.0
AVR gcc 14.2.0
AVR gcc 4.5.4
AVR gcc 4.6.4
AVR gcc 5.4.0
AVR gcc 9.2.0
AVR gcc 9.3.0
Arduino Mega (1.8.9)
Arduino Uno (1.8.9)
BPF clang (trunk)
BPF clang 13.0.0
BPF clang 14.0.0
BPF clang 15.0.0
BPF clang 16.0.0
BPF clang 17.0.1
BPF clang 18.1.0
BPF clang 19.1.0
BPF gcc 13.1.0
BPF gcc 13.2.0
BPF gcc 13.3.0
BPF gcc trunk
EDG (experimental reflection)
EDG 6.5
EDG 6.5 (GNU mode gcc 13)
EDG 6.6
EDG 6.6 (GNU mode gcc 13)
FRC 2019
FRC 2020
FRC 2023
HPPA gcc 14.2.0
KVX ACB 4.1.0 (GCC 7.5.0)
KVX ACB 4.1.0-cd1 (GCC 7.5.0)
KVX ACB 4.10.0 (GCC 10.3.1)
KVX ACB 4.11.1 (GCC 10.3.1)
KVX ACB 4.12.0 (GCC 11.3.0)
KVX ACB 4.2.0 (GCC 7.5.0)
KVX ACB 4.3.0 (GCC 7.5.0)
KVX ACB 4.4.0 (GCC 7.5.0)
KVX ACB 4.6.0 (GCC 9.4.1)
KVX ACB 4.8.0 (GCC 9.4.1)
KVX ACB 4.9.0 (GCC 9.4.1)
KVX ACB 5.0.0 (GCC 12.2.1)
LoongArch64 clang (trunk)
LoongArch64 clang 17.0.1
LoongArch64 clang 18.1.0
LoongArch64 clang 19.1.0
M68K gcc 13.1.0
M68K gcc 13.2.0
M68K gcc 13.3.0
M68K gcc 14.1.0
M68K gcc 14.2.0
M68k clang (trunk)
MRISC32 gcc (trunk)
MSP430 gcc 4.5.3
MSP430 gcc 5.3.0
MSP430 gcc 6.2.1
MinGW clang 14.0.3
MinGW clang 14.0.6
MinGW clang 15.0.7
MinGW clang 16.0.0
MinGW clang 16.0.2
MinGW gcc 11.3.0
MinGW gcc 12.1.0
MinGW gcc 12.2.0
MinGW gcc 13.1.0
RISC-V (32-bits) gcc (trunk)
RISC-V (32-bits) gcc 10.2.0
RISC-V (32-bits) gcc 10.3.0
RISC-V (32-bits) gcc 11.2.0
RISC-V (32-bits) gcc 11.3.0
RISC-V (32-bits) gcc 11.4.0
RISC-V (32-bits) gcc 12.1.0
RISC-V (32-bits) gcc 12.2.0
RISC-V (32-bits) gcc 12.3.0
RISC-V (32-bits) gcc 12.4.0
RISC-V (32-bits) gcc 13.1.0
RISC-V (32-bits) gcc 13.2.0
RISC-V (32-bits) gcc 13.3.0
RISC-V (32-bits) gcc 14.1.0
RISC-V (32-bits) gcc 14.2.0
RISC-V (32-bits) gcc 8.2.0
RISC-V (32-bits) gcc 8.5.0
RISC-V (32-bits) gcc 9.4.0
RISC-V (64-bits) gcc (trunk)
RISC-V (64-bits) gcc 10.2.0
RISC-V (64-bits) gcc 10.3.0
RISC-V (64-bits) gcc 11.2.0
RISC-V (64-bits) gcc 11.3.0
RISC-V (64-bits) gcc 11.4.0
RISC-V (64-bits) gcc 12.1.0
RISC-V (64-bits) gcc 12.2.0
RISC-V (64-bits) gcc 12.3.0
RISC-V (64-bits) gcc 12.4.0
RISC-V (64-bits) gcc 13.1.0
RISC-V (64-bits) gcc 13.2.0
RISC-V (64-bits) gcc 13.3.0
RISC-V (64-bits) gcc 14.1.0
RISC-V (64-bits) gcc 14.2.0
RISC-V (64-bits) gcc 8.2.0
RISC-V (64-bits) gcc 8.5.0
RISC-V (64-bits) gcc 9.4.0
RISC-V rv32gc clang (trunk)
RISC-V rv32gc clang 10.0.0
RISC-V rv32gc clang 10.0.1
RISC-V rv32gc clang 11.0.0
RISC-V rv32gc clang 11.0.1
RISC-V rv32gc clang 12.0.0
RISC-V rv32gc clang 12.0.1
RISC-V rv32gc clang 13.0.0
RISC-V rv32gc clang 13.0.1
RISC-V rv32gc clang 14.0.0
RISC-V rv32gc clang 15.0.0
RISC-V rv32gc clang 16.0.0
RISC-V rv32gc clang 17.0.1
RISC-V rv32gc clang 18.1.0
RISC-V rv32gc clang 19.1.0
RISC-V rv32gc clang 9.0.0
RISC-V rv32gc clang 9.0.1
RISC-V rv64gc clang (trunk)
RISC-V rv64gc clang 10.0.0
RISC-V rv64gc clang 10.0.1
RISC-V rv64gc clang 11.0.0
RISC-V rv64gc clang 11.0.1
RISC-V rv64gc clang 12.0.0
RISC-V rv64gc clang 12.0.1
RISC-V rv64gc clang 13.0.0
RISC-V rv64gc clang 13.0.1
RISC-V rv64gc clang 14.0.0
RISC-V rv64gc clang 15.0.0
RISC-V rv64gc clang 16.0.0
RISC-V rv64gc clang 17.0.1
RISC-V rv64gc clang 18.1.0
RISC-V rv64gc clang 19.1.0
RISC-V rv64gc clang 9.0.0
RISC-V rv64gc clang 9.0.1
Raspbian Buster
Raspbian Stretch
SPARC LEON gcc 12.2.0
SPARC LEON gcc 12.3.0
SPARC LEON gcc 12.4.0
SPARC LEON gcc 13.1.0
SPARC LEON gcc 13.2.0
SPARC LEON gcc 13.3.0
SPARC LEON gcc 14.1.0
SPARC LEON gcc 14.2.0
SPARC gcc 12.2.0
SPARC gcc 12.3.0
SPARC gcc 12.4.0
SPARC gcc 13.1.0
SPARC gcc 13.2.0
SPARC gcc 13.3.0
SPARC gcc 14.1.0
SPARC gcc 14.2.0
SPARC64 gcc 12.2.0
SPARC64 gcc 12.3.0
SPARC64 gcc 12.4.0
SPARC64 gcc 13.1.0
SPARC64 gcc 13.2.0
SPARC64 gcc 13.3.0
SPARC64 gcc 14.1.0
SPARC64 gcc 14.2.0
TI C6x gcc 12.2.0
TI C6x gcc 12.3.0
TI C6x gcc 12.4.0
TI C6x gcc 13.1.0
TI C6x gcc 13.2.0
TI C6x gcc 13.3.0
TI C6x gcc 14.1.0
TI C6x gcc 14.2.0
TI CL430 21.6.1
VAX gcc NetBSDELF 10.4.0
VAX gcc NetBSDELF 10.5.0 (Nov 15 03:50:22 2023)
WebAssembly clang (trunk)
Xtensa ESP32 gcc 11.2.0 (2022r1)
Xtensa ESP32 gcc 12.2.0 (20230208)
Xtensa ESP32 gcc 8.2.0 (2019r2)
Xtensa ESP32 gcc 8.2.0 (2020r1)
Xtensa ESP32 gcc 8.2.0 (2020r2)
Xtensa ESP32 gcc 8.4.0 (2020r3)
Xtensa ESP32 gcc 8.4.0 (2021r1)
Xtensa ESP32 gcc 8.4.0 (2021r2)
Xtensa ESP32-S2 gcc 11.2.0 (2022r1)
Xtensa ESP32-S2 gcc 12.2.0 (20230208)
Xtensa ESP32-S2 gcc 8.2.0 (2019r2)
Xtensa ESP32-S2 gcc 8.2.0 (2020r1)
Xtensa ESP32-S2 gcc 8.2.0 (2020r2)
Xtensa ESP32-S2 gcc 8.4.0 (2020r3)
Xtensa ESP32-S2 gcc 8.4.0 (2021r1)
Xtensa ESP32-S2 gcc 8.4.0 (2021r2)
Xtensa ESP32-S3 gcc 11.2.0 (2022r1)
Xtensa ESP32-S3 gcc 12.2.0 (20230208)
Xtensa ESP32-S3 gcc 8.4.0 (2020r3)
Xtensa ESP32-S3 gcc 8.4.0 (2021r1)
Xtensa ESP32-S3 gcc 8.4.0 (2021r2)
arm64 msvc v19.20 VS16.0
arm64 msvc v19.21 VS16.1
arm64 msvc v19.22 VS16.2
arm64 msvc v19.23 VS16.3
arm64 msvc v19.24 VS16.4
arm64 msvc v19.25 VS16.5
arm64 msvc v19.27 VS16.7
arm64 msvc v19.28 VS16.8
arm64 msvc v19.28 VS16.9
arm64 msvc v19.29 VS16.10
arm64 msvc v19.29 VS16.11
arm64 msvc v19.30 VS17.0
arm64 msvc v19.31 VS17.1
arm64 msvc v19.32 VS17.2
arm64 msvc v19.33 VS17.3
arm64 msvc v19.34 VS17.4
arm64 msvc v19.35 VS17.5
arm64 msvc v19.36 VS17.6
arm64 msvc v19.37 VS17.7
arm64 msvc v19.38 VS17.8
arm64 msvc v19.39 VS17.9
arm64 msvc v19.40 VS17.10
arm64 msvc v19.latest
armv7-a clang (trunk)
armv7-a clang 10.0.0
armv7-a clang 10.0.1
armv7-a clang 11.0.0
armv7-a clang 11.0.1
armv7-a clang 12.0.0
armv7-a clang 12.0.1
armv7-a clang 13.0.0
armv7-a clang 13.0.1
armv7-a clang 14.0.0
armv7-a clang 15.0.0
armv7-a clang 16.0.0
armv7-a clang 17.0.1
armv7-a clang 18.1.0
armv7-a clang 19.1.0
armv7-a clang 9.0.0
armv7-a clang 9.0.1
armv8-a clang (all architectural features, trunk)
armv8-a clang (trunk)
armv8-a clang 10.0.0
armv8-a clang 10.0.1
armv8-a clang 11.0.0
armv8-a clang 11.0.1
armv8-a clang 12.0.0
armv8-a clang 13.0.0
armv8-a clang 14.0.0
armv8-a clang 15.0.0
armv8-a clang 16.0.0
armv8-a clang 17.0.1
armv8-a clang 18.1.0
armv8-a clang 19.1.0
armv8-a clang 9.0.0
armv8-a clang 9.0.1
ellcc 0.1.33
ellcc 0.1.34
ellcc 2017-07-16
hexagon-clang 16.0.5
llvm-mos atari2600-3e
llvm-mos atari2600-4k
llvm-mos atari2600-common
llvm-mos atari5200-supercart
llvm-mos atari8-cart-megacart
llvm-mos atari8-cart-std
llvm-mos atari8-cart-xegs
llvm-mos atari8-common
llvm-mos atari8-dos
llvm-mos c128
llvm-mos c64
llvm-mos commodore
llvm-mos cpm65
llvm-mos cx16
llvm-mos dodo
llvm-mos eater
llvm-mos mega65
llvm-mos nes
llvm-mos nes-action53
llvm-mos nes-cnrom
llvm-mos nes-gtrom
llvm-mos nes-mmc1
llvm-mos nes-mmc3
llvm-mos nes-nrom
llvm-mos nes-unrom
llvm-mos nes-unrom-512
llvm-mos osi-c1p
llvm-mos pce
llvm-mos pce-cd
llvm-mos pce-common
llvm-mos pet
llvm-mos rp6502
llvm-mos rpc8e
llvm-mos supervision
llvm-mos vic20
loongarch64 gcc 12.2.0
loongarch64 gcc 12.3.0
loongarch64 gcc 12.4.0
loongarch64 gcc 13.1.0
loongarch64 gcc 13.2.0
loongarch64 gcc 13.3.0
loongarch64 gcc 14.1.0
loongarch64 gcc 14.2.0
mips clang 13.0.0
mips clang 14.0.0
mips clang 15.0.0
mips clang 16.0.0
mips clang 17.0.1
mips clang 18.1.0
mips clang 19.1.0
mips gcc 11.2.0
mips gcc 12.1.0
mips gcc 12.2.0
mips gcc 12.3.0
mips gcc 12.4.0
mips gcc 13.1.0
mips gcc 13.2.0
mips gcc 13.3.0
mips gcc 14.1.0
mips gcc 14.2.0
mips gcc 4.9.4
mips gcc 5.4
mips gcc 5.5.0
mips gcc 9.3.0 (codescape)
mips gcc 9.5.0
mips64 (el) gcc 12.1.0
mips64 (el) gcc 12.2.0
mips64 (el) gcc 12.3.0
mips64 (el) gcc 12.4.0
mips64 (el) gcc 13.1.0
mips64 (el) gcc 13.2.0
mips64 (el) gcc 13.3.0
mips64 (el) gcc 14.1.0
mips64 (el) gcc 14.2.0
mips64 (el) gcc 4.9.4
mips64 (el) gcc 5.4.0
mips64 (el) gcc 5.5.0
mips64 (el) gcc 9.5.0
mips64 clang 13.0.0
mips64 clang 14.0.0
mips64 clang 15.0.0
mips64 clang 16.0.0
mips64 clang 17.0.1
mips64 clang 18.1.0
mips64 clang 19.1.0
mips64 gcc 11.2.0
mips64 gcc 12.1.0
mips64 gcc 12.2.0
mips64 gcc 12.3.0
mips64 gcc 12.4.0
mips64 gcc 13.1.0
mips64 gcc 13.2.0
mips64 gcc 13.3.0
mips64 gcc 14.1.0
mips64 gcc 14.2.0
mips64 gcc 4.9.4
mips64 gcc 5.4.0
mips64 gcc 5.5.0
mips64 gcc 9.5.0
mips64el clang 13.0.0
mips64el clang 14.0.0
mips64el clang 15.0.0
mips64el clang 16.0.0
mips64el clang 17.0.1
mips64el clang 18.1.0
mips64el clang 19.1.0
mipsel clang 13.0.0
mipsel clang 14.0.0
mipsel clang 15.0.0
mipsel clang 16.0.0
mipsel clang 17.0.1
mipsel clang 18.1.0
mipsel clang 19.1.0
mipsel gcc 12.1.0
mipsel gcc 12.2.0
mipsel gcc 12.3.0
mipsel gcc 12.4.0
mipsel gcc 13.1.0
mipsel gcc 13.2.0
mipsel gcc 13.3.0
mipsel gcc 14.1.0
mipsel gcc 14.2.0
mipsel gcc 4.9.4
mipsel gcc 5.4.0
mipsel gcc 5.5.0
mipsel gcc 9.5.0
nanoMIPS gcc 6.3.0 (mtk)
power gcc 11.2.0
power gcc 12.1.0
power gcc 12.2.0
power gcc 12.3.0
power gcc 12.4.0
power gcc 13.1.0
power gcc 13.2.0
power gcc 13.3.0
power gcc 14.1.0
power gcc 14.2.0
power gcc 4.8.5
power64 AT12.0 (gcc8)
power64 AT13.0 (gcc9)
power64 gcc 11.2.0
power64 gcc 12.1.0
power64 gcc 12.2.0
power64 gcc 12.3.0
power64 gcc 12.4.0
power64 gcc 13.1.0
power64 gcc 13.2.0
power64 gcc 13.3.0
power64 gcc 14.1.0
power64 gcc 14.2.0
power64 gcc trunk
power64le AT12.0 (gcc8)
power64le AT13.0 (gcc9)
power64le clang (trunk)
power64le gcc 11.2.0
power64le gcc 12.1.0
power64le gcc 12.2.0
power64le gcc 12.3.0
power64le gcc 12.4.0
power64le gcc 13.1.0
power64le gcc 13.2.0
power64le gcc 13.3.0
power64le gcc 14.1.0
power64le gcc 14.2.0
power64le gcc 6.3.0
power64le gcc trunk
powerpc64 clang (trunk)
s390x gcc 11.2.0
s390x gcc 12.1.0
s390x gcc 12.2.0
s390x gcc 12.3.0
s390x gcc 12.4.0
s390x gcc 13.1.0
s390x gcc 13.2.0
s390x gcc 13.3.0
s390x gcc 14.1.0
s390x gcc 14.2.0
sh gcc 12.2.0
sh gcc 12.3.0
sh gcc 12.4.0
sh gcc 13.1.0
sh gcc 13.2.0
sh gcc 13.3.0
sh gcc 14.1.0
sh gcc 14.2.0
sh gcc 4.9.4
sh gcc 9.5.0
vast (trunk)
x64 msvc v19.0 (WINE)
x64 msvc v19.10 (WINE)
x64 msvc v19.14 (WINE)
x64 msvc v19.20 VS16.0
x64 msvc v19.21 VS16.1
x64 msvc v19.22 VS16.2
x64 msvc v19.23 VS16.3
x64 msvc v19.24 VS16.4
x64 msvc v19.25 VS16.5
x64 msvc v19.27 VS16.7
x64 msvc v19.28 VS16.8
x64 msvc v19.28 VS16.9
x64 msvc v19.29 VS16.10
x64 msvc v19.29 VS16.11
x64 msvc v19.30 VS17.0
x64 msvc v19.31 VS17.1
x64 msvc v19.32 VS17.2
x64 msvc v19.33 VS17.3
x64 msvc v19.34 VS17.4
x64 msvc v19.35 VS17.5
x64 msvc v19.36 VS17.6
x64 msvc v19.37 VS17.7
x64 msvc v19.38 VS17.8
x64 msvc v19.39 VS17.9
x64 msvc v19.40 VS17.10
x64 msvc v19.latest
x86 djgpp 4.9.4
x86 djgpp 5.5.0
x86 djgpp 6.4.0
x86 djgpp 7.2.0
x86 msvc v19.0 (WINE)
x86 msvc v19.10 (WINE)
x86 msvc v19.14 (WINE)
x86 msvc v19.20 VS16.0
x86 msvc v19.21 VS16.1
x86 msvc v19.22 VS16.2
x86 msvc v19.23 VS16.3
x86 msvc v19.24 VS16.4
x86 msvc v19.25 VS16.5
x86 msvc v19.27 VS16.7
x86 msvc v19.28 VS16.8
x86 msvc v19.28 VS16.9
x86 msvc v19.29 VS16.10
x86 msvc v19.29 VS16.11
x86 msvc v19.30 VS17.0
x86 msvc v19.31 VS17.1
x86 msvc v19.32 VS17.2
x86 msvc v19.33 VS17.3
x86 msvc v19.34 VS17.4
x86 msvc v19.35 VS17.5
x86 msvc v19.36 VS17.6
x86 msvc v19.37 VS17.7
x86 msvc v19.38 VS17.8
x86 msvc v19.39 VS17.9
x86 msvc v19.40 VS17.10
x86 msvc v19.latest
x86 nvc++ 22.11
x86 nvc++ 22.7
x86 nvc++ 22.9
x86 nvc++ 23.1
x86 nvc++ 23.11
x86 nvc++ 23.3
x86 nvc++ 23.5
x86 nvc++ 23.7
x86 nvc++ 23.9
x86 nvc++ 24.1
x86 nvc++ 24.3
x86 nvc++ 24.5
x86 nvc++ 24.7
x86-64 Zapcc 190308
x86-64 clang (EricWF contracts)
x86-64 clang (amd-staging)
x86-64 clang (assertions trunk)
x86-64 clang (clangir)
x86-64 clang (dascandy contracts)
x86-64 clang (experimental -Wlifetime)
x86-64 clang (experimental P1061)
x86-64 clang (experimental P1144)
x86-64 clang (experimental P1221)
x86-64 clang (experimental P2996)
x86-64 clang (experimental P3068)
x86-64 clang (experimental P3309)
x86-64 clang (experimental P3367)
x86-64 clang (experimental P3372)
x86-64 clang (experimental metaprogramming - P2632)
x86-64 clang (old concepts branch)
x86-64 clang (p1974)
x86-64 clang (pattern matching - P2688)
x86-64 clang (reflection)
x86-64 clang (resugar)
x86-64 clang (thephd.dev)
x86-64 clang (trunk)
x86-64 clang (variadic friends - P2893)
x86-64 clang (widberg)
x86-64 clang 10.0.0
x86-64 clang 10.0.0 (assertions)
x86-64 clang 10.0.1
x86-64 clang 11.0.0
x86-64 clang 11.0.0 (assertions)
x86-64 clang 11.0.1
x86-64 clang 12.0.0
x86-64 clang 12.0.0 (assertions)
x86-64 clang 12.0.1
x86-64 clang 13.0.0
x86-64 clang 13.0.0 (assertions)
x86-64 clang 13.0.1
x86-64 clang 14.0.0
x86-64 clang 14.0.0 (assertions)
x86-64 clang 15.0.0
x86-64 clang 15.0.0 (assertions)
x86-64 clang 16.0.0
x86-64 clang 16.0.0 (assertions)
x86-64 clang 17.0.1
x86-64 clang 17.0.1 (assertions)
x86-64 clang 18.1.0
x86-64 clang 18.1.0 (assertions)
x86-64 clang 19.1.0
x86-64 clang 19.1.0 (assertions)
x86-64 clang 2.6.0 (assertions)
x86-64 clang 2.7.0 (assertions)
x86-64 clang 2.8.0 (assertions)
x86-64 clang 2.9.0 (assertions)
x86-64 clang 3.0.0
x86-64 clang 3.0.0 (assertions)
x86-64 clang 3.1
x86-64 clang 3.1 (assertions)
x86-64 clang 3.2
x86-64 clang 3.2 (assertions)
x86-64 clang 3.3
x86-64 clang 3.3 (assertions)
x86-64 clang 3.4 (assertions)
x86-64 clang 3.4.1
x86-64 clang 3.5
x86-64 clang 3.5 (assertions)
x86-64 clang 3.5.1
x86-64 clang 3.5.2
x86-64 clang 3.6
x86-64 clang 3.6 (assertions)
x86-64 clang 3.7
x86-64 clang 3.7 (assertions)
x86-64 clang 3.7.1
x86-64 clang 3.8
x86-64 clang 3.8 (assertions)
x86-64 clang 3.8.1
x86-64 clang 3.9.0
x86-64 clang 3.9.0 (assertions)
x86-64 clang 3.9.1
x86-64 clang 4.0.0
x86-64 clang 4.0.0 (assertions)
x86-64 clang 4.0.1
x86-64 clang 5.0.0
x86-64 clang 5.0.0 (assertions)
x86-64 clang 5.0.1
x86-64 clang 5.0.2
x86-64 clang 6.0.0
x86-64 clang 6.0.0 (assertions)
x86-64 clang 6.0.1
x86-64 clang 7.0.0
x86-64 clang 7.0.0 (assertions)
x86-64 clang 7.0.1
x86-64 clang 7.1.0
x86-64 clang 8.0.0
x86-64 clang 8.0.0 (assertions)
x86-64 clang 8.0.1
x86-64 clang 9.0.0
x86-64 clang 9.0.0 (assertions)
x86-64 clang 9.0.1
x86-64 clang rocm-4.5.2
x86-64 clang rocm-5.0.2
x86-64 clang rocm-5.1.3
x86-64 clang rocm-5.2.3
x86-64 clang rocm-5.3.3
x86-64 clang rocm-5.7.0
x86-64 clang rocm-6.0.2
x86-64 clang rocm-6.1.2
x86-64 gcc (contract labels)
x86-64 gcc (contracts natural syntax)
x86-64 gcc (contracts)
x86-64 gcc (coroutines)
x86-64 gcc (modules)
x86-64 gcc (trunk)
x86-64 gcc 10.1
x86-64 gcc 10.2
x86-64 gcc 10.3
x86-64 gcc 10.4
x86-64 gcc 10.5
x86-64 gcc 11.1
x86-64 gcc 11.2
x86-64 gcc 11.3
x86-64 gcc 11.4
x86-64 gcc 12.1
x86-64 gcc 12.2
x86-64 gcc 12.3
x86-64 gcc 12.4
x86-64 gcc 13.1
x86-64 gcc 13.2
x86-64 gcc 13.3
x86-64 gcc 14.1
x86-64 gcc 14.2
x86-64 gcc 3.4.6
x86-64 gcc 4.0.4
x86-64 gcc 4.1.2
x86-64 gcc 4.4.7
x86-64 gcc 4.5.3
x86-64 gcc 4.6.4
x86-64 gcc 4.7.1
x86-64 gcc 4.7.2
x86-64 gcc 4.7.3
x86-64 gcc 4.7.4
x86-64 gcc 4.8.1
x86-64 gcc 4.8.2
x86-64 gcc 4.8.3
x86-64 gcc 4.8.4
x86-64 gcc 4.8.5
x86-64 gcc 4.9.0
x86-64 gcc 4.9.1
x86-64 gcc 4.9.2
x86-64 gcc 4.9.3
x86-64 gcc 4.9.4
x86-64 gcc 5.1
x86-64 gcc 5.2
x86-64 gcc 5.3
x86-64 gcc 5.4
x86-64 gcc 5.5
x86-64 gcc 6.1
x86-64 gcc 6.2
x86-64 gcc 6.3
x86-64 gcc 6.4
x86-64 gcc 6.5
x86-64 gcc 7.1
x86-64 gcc 7.2
x86-64 gcc 7.3
x86-64 gcc 7.4
x86-64 gcc 7.5
x86-64 gcc 8.1
x86-64 gcc 8.2
x86-64 gcc 8.3
x86-64 gcc 8.4
x86-64 gcc 8.5
x86-64 gcc 9.1
x86-64 gcc 9.2
x86-64 gcc 9.3
x86-64 gcc 9.4
x86-64 gcc 9.5
x86-64 icc 13.0.1
x86-64 icc 16.0.3
x86-64 icc 17.0.0
x86-64 icc 18.0.0
x86-64 icc 19.0.0
x86-64 icc 19.0.1
x86-64 icc 2021.1.2
x86-64 icc 2021.10.0
x86-64 icc 2021.2.0
x86-64 icc 2021.3.0
x86-64 icc 2021.4.0
x86-64 icc 2021.5.0
x86-64 icc 2021.6.0
x86-64 icc 2021.7.0
x86-64 icc 2021.7.1
x86-64 icc 2021.8.0
x86-64 icc 2021.9.0
x86-64 icx (latest)
x86-64 icx 2021.1.2
x86-64 icx 2021.2.0
x86-64 icx 2021.3.0
x86-64 icx 2021.4.0
x86-64 icx 2022.0.0
x86-64 icx 2022.1.0
x86-64 icx 2022.2.0
x86-64 icx 2022.2.1
x86-64 icx 2023.0.0
x86-64 icx 2023.1.0
x86-64 icx 2023.2.1
x86-64 icx 2024.0.0
x86-64 icx 2024.1.0
x86-64 icx 2024.2.0
zig c++ 0.10.0
zig c++ 0.11.0
zig c++ 0.12.0
zig c++ 0.12.1
zig c++ 0.13.0
zig c++ 0.6.0
zig c++ 0.7.0
zig c++ 0.7.1
zig c++ 0.8.0
zig c++ 0.9.0
zig c++ trunk
Options
Source code
#include <iostream> #include <atomic> #include <cassert> #include <concepts> #include <condition_variable> #include <stdexcept> #include <memory> #include <mutex> #include <optional> #include <system_error> #include <tuple> #include <type_traits> #include <variant> #include <cassert> #include <version> namespace stdexec { } #include <cassert> #include <exception> #include <type_traits> #include <utility> namespace stdexec { template <class _Tp> _Tp&& __declval() noexcept; namespace __tt { struct __decay_object { template <class _Ty> static _Ty __g(_Ty const &); template <class _Ty> using __f = decltype(__g(__declval<_Ty>())); }; struct __decay_default { template <class _Ty> static _Ty __g(_Ty); template <class _Ty> using __f = decltype(__g(__declval<_Ty>())); }; struct __decay_abominable { template <class _Ty> using __f = _Ty; }; struct __decay_void { template <class _Ty> using __f = void; }; template <class _Ty> extern __decay_object __mdecay; template <class _Ty, class... Us> extern __decay_default __mdecay<_Ty(Us...)>; template <class _Ty, class... Us> extern __decay_default __mdecay<_Ty(Us...) noexcept>; template <class _Ty, class... Us> extern __decay_default __mdecay<_Ty (&)(Us...)>; template <class _Ty, class... Us> extern __decay_default __mdecay<_Ty (&)(Us...) noexcept>; template <class _Ty, class... Us> extern __decay_abominable __mdecay<_Ty(Us...) const>; template <class _Ty, class... Us> extern __decay_abominable __mdecay<_Ty(Us...) const noexcept>; template <class _Ty, class... Us> extern __decay_abominable __mdecay<_Ty(Us...) const &>; template <class _Ty, class... Us> extern __decay_abominable __mdecay<_Ty(Us...) const & noexcept>; template <class _Ty, class... Us> extern __decay_abominable __mdecay<_Ty(Us...) const &&>; template <class _Ty, class... Us> extern __decay_abominable __mdecay<_Ty(Us...) const && noexcept>; template <class _Ty> extern __decay_default __mdecay<_Ty[]>; template <class _Ty, std::size_t N> extern __decay_default __mdecay<_Ty[N]>; template <class _Ty, std::size_t N> extern __decay_default __mdecay<_Ty (&)[N]>; template <> inline __decay_void __mdecay<void>; template <> inline __decay_void __mdecay<void const>; } template <class _Ty> using __decay_t = typename decltype(__tt::__mdecay<_Ty>)::template __f<_Ty>; struct __cp { template <class _Tp> using __f = _Tp; }; struct __cpc { template <class _Tp> using __f = const _Tp; }; struct __cplr { template <class _Tp> using __f = _Tp&; }; struct __cprr { template <class _Tp> using __f = _Tp&&; }; struct __cpclr { template <class _Tp> using __f = const _Tp&; }; struct __cpcrr { template <class _Tp> using __f = const _Tp&&; }; template <class> extern __cp __cpcvr; template <class _Tp> extern __cpc __cpcvr<const _Tp>; template <class _Tp> extern __cplr __cpcvr<_Tp&>; template <class _Tp> extern __cprr __cpcvr<_Tp&&>; template <class _Tp> extern __cpclr __cpcvr<const _Tp&>; template <class _Tp> extern __cpcrr __cpcvr<const _Tp&&>; template <class _Tp> using __copy_cvref_fn = decltype(__cpcvr<_Tp>); template <class _From, class _To> using __copy_cvref_t = typename __copy_cvref_fn<_From>::template __f<_To>; } namespace stdexec { template <class _Fun, class... _As> concept __callable = requires(_Fun&& __fun, _As&&... __as) { ((_Fun&&) __fun)((_As&&) __as...); }; template <class _Fun, class... _As> concept __nothrow_callable = __callable<_Fun, _As...> && requires(_Fun&& __fun, _As&&... __as) { { ((_Fun&&) __fun)((_As&&) __as...) } noexcept; }; template <class...> struct __types; template <class... _Ts> concept __typename = requires { typename __types<_Ts...>; }; template <class _Ap, class _Bp> concept __same_as = __is_same_as(_Ap, _Bp); template <class _Ty, class _Up> concept __decays_to = __same_as<__decay_t<_Ty>, _Up>; template <class _Ty, class _Up> concept __not_decays_to = !__decays_to<_Ty, _Up>; template <bool _TrueOrFalse> concept __satisfies = _TrueOrFalse; template <class...> concept __true = true; template <class _Cp> concept __class = __true<int _Cp::*> && (!__same_as<const _Cp, _Cp>); template <class _Ty, class... _As> concept __one_of = (__same_as<_Ty, _As> || ...); template <class _Ty, class... _Us> concept __all_of = (__same_as<_Ty, _Us> && ...); template <class _Ty, class... _Us> concept __none_of = ((!__same_as<_Ty, _Us>) &&...); template <class, template <class...> class> constexpr bool __is_instance_of_ = false; template <class... _As, template <class...> class _Ty> constexpr bool __is_instance_of_<_Ty<_As...>, _Ty> = true; template <class _Ay, template <class...> class _Ty> concept __is_instance_of = __is_instance_of_<_Ay, _Ty>; template <class _Ay, template <class...> class _Ty> concept __is_not_instance_of = !__is_instance_of<_Ay, _Ty>; } namespace stdexec { template <class...> struct __undefined; struct __ { }; struct __ignore { __ignore() = default; constexpr __ignore(auto&&...) noexcept { } }; struct __none_such { }; struct __immovable { __immovable() = default; private: __immovable(__immovable&&) = delete; }; struct __move_only { __move_only() = default; __move_only(__move_only&&) noexcept = default; __move_only& operator=(__move_only&&) noexcept = default; __move_only(const __move_only&) = delete; __move_only& operator=(const __move_only&) = delete; }; template <class _Tp> using __t = typename _Tp::__t; template <bool _Bp> using __mbool = std::bool_constant<_Bp>; template <class _Ty> struct __mtype { using __t = _Ty; }; template <auto _Value> using __mtypeof = decltype(_Value); template <class...> struct __types; template <class _Tp> using __midentity = _Tp; template <std::size_t _Np> using __msize_t = char[_Np + 1]; template <class _Tp, class _Up> using __mfirst = _Tp; template <class _Tp, class _Up> using __msecond = _Up; template <class _Tp> extern const __undefined<_Tp> __v; template <class _Tp> requires __typename<__mtypeof<_Tp::value>> inline constexpr auto __v<_Tp> = _Tp::value; template <class _Tp, class _Up> inline constexpr bool __v<std::is_same<_Tp, _Up>> = false; template <class _Tp> inline constexpr bool __v<std::is_same<_Tp, _Tp>> = true; template <class _Tp, _Tp _Ip> inline constexpr _Tp __v<std::integral_constant<_Tp, _Ip>> = _Ip; template <std::size_t _Ip> inline constexpr std::size_t __v<char[_Ip]> = _Ip - 1; template <std::size_t... _Is> using __indices = std::index_sequence<_Is...>*; template <std::size_t _Np> using __make_indices = std::make_index_sequence<_Np>*; template <class _Char> concept __mchar = __same_as<_Char, char>; template <std::size_t _Len> class __mstring { template <std::size_t... _Is> constexpr __mstring(const char (&__str)[_Len], __indices<_Is...>) noexcept : __what_{__str[_Is]...} { } public: constexpr __mstring(const char (&__str)[_Len]) noexcept : __mstring{__str, __make_indices<_Len>{}} { } template <__mchar... _Char> requires(sizeof...(_Char) == _Len) constexpr __mstring(_Char... __chars) noexcept : __what_{__chars...} { } static constexpr std::size_t __length() noexcept { return _Len; } char const __what_[_Len]; }; template <__mstring _Str> constexpr __mtypeof<_Str> operator""__csz() noexcept { return _Str; } using __msuccess = int; template <class _What, class... _With> struct _WARNING_ { }; template <class _What, class... _With> struct _ERROR_ { const _ERROR_& operator,(__msuccess) const noexcept; }; template <class _What, class... _With> using __mexception = const _ERROR_<_What, _With...>&; template <class> extern __msuccess __ok_v; template <class _What, class... _With> extern _ERROR_<_What, _With...> __ok_v<__mexception<_What, _With...>>; template <class _Ty> using __ok_t = decltype(__ok_v<_Ty>); template <class... _Ts> using __disp = const decltype((__msuccess(), ..., __ok_t<_Ts>()))&; template <bool _AllOK> struct __i { template <template <class...> class _Fn, class... _Args> using __g = _Fn<_Args...>; }; template <> struct __i<false> { template <template <class...> class, class... _Args> using __g = __disp<_Args...>; }; template <class _Arg> concept __ok = __same_as<__ok_t<_Arg>, __msuccess>; template <class _Arg> concept __merror = !__ok<_Arg>; template <class... _Args> concept _Ok = (__ok<_Args> && ...); template <template <class...> class _Fn, class... _Args> using __meval = typename __i<_Ok<_Args...>>::template __g<_Fn, _Args...>; template <class _Fn, class... _Args> using __minvoke = __meval<_Fn::template __f, _Args...>; template <template <class...> class _Fn> struct __q { template <class... _Args> using __f = __meval<_Fn, _Args...>; }; template <template <class...> class _Fn, class... _Front> struct __mbind_front_q { template <class... _Args> using __f = __meval<_Fn, _Front..., _Args...>; }; template <class _Fn, class... _Front> using __mbind_front = __mbind_front_q<_Fn::template __f, _Front...>; template <template <class...> class _Fn, class... _Back> struct __mbind_back_q { template <class... _Args> using __f = __meval<_Fn, _Args..., _Back...>; }; template <class _Fn, class... _Back> using __mbind_back = __mbind_back_q<_Fn::template __f, _Back...>; template <template <class...> class _Tp, class... _Args> concept __valid = requires { typename __meval<_Tp, _Args...>; }; template <class _Fn, class... _Args> concept __minvocable = __valid<_Fn::template __f, _Args...>; template <template <class...> class _Tp, class... _Args> concept __msucceeds = __valid<_Tp, _Args...> && __ok<__meval<_Tp, _Args...>>; template <class _Fn, class... _Args> concept __minvocable_succeeds = __minvocable<_Fn, _Args...> && __ok<__minvoke<_Fn, _Args...>>; template <class _Fn, class... _Args> struct __force_minvoke_ { using __t = __minvoke<_Fn, _Args...>; }; template <class _Fn, class... _Args> using __force_minvoke = __t<__force_minvoke_<_Fn, _Args...>>; template <class _Fn, class... _Args> struct __mdefer_ { }; template <class _Fn, class... _Args> requires __minvocable<_Fn, _Args...> struct __mdefer_<_Fn, _Args...> { using __t = __minvoke<_Fn, _Args...>; }; template <class _Fn, class... _Args> struct __mdefer : __mdefer_<_Fn, _Args...> { }; struct __if_ { template <bool> struct __ { template <class _True, class...> using __f = _True; }; template <class _Pred, class _True, class... _False> using __f = __minvoke<__<static_cast<bool>(__v<_Pred>)>, _True, _False...>; }; template <> struct __if_::__<false> { template <class, class _False> using __f = _False; }; template <class _Pred, class _True = void, class... _False> requires(sizeof...(_False) <= 1) using __if = __minvoke<__if_, _Pred, _True, _False...>; template <bool _Pred, class _True = void, class... _False> requires(sizeof...(_False) <= 1) using __if_c = __minvoke<__if_::__<_Pred>, _True, _False...>; template <class _Tp> struct __mconst { template <class...> using __f = _Tp; }; template <template <class...> class _Try, class _Catch> struct __mtry_catch_q { template <class... _Args> using __f = __minvoke< __if_c<__valid<_Try, _Args...>, __q<_Try>, _Catch>, _Args...>; }; template <class _Try, class _Catch> struct __mtry_catch { template <class... _Args> using __f = __minvoke< __if_c<__minvocable<_Try, _Args...>, _Try, _Catch>, _Args...>; }; template <class _Fn, class _Default> using __with_default = __mtry_catch<_Fn, __mconst<_Default>>; inline constexpr __mstring __mbad_substitution = "The specified meta-function could not be evaluated with the types provided."__csz; template <__mstring _Diagnostic = __mbad_substitution> struct _BAD_SUBSTITUTION_ { }; template <class... _Args> struct _WITH_TYPES_ { }; template <template <class...> class _Fun> struct _WITH_META_FUNCTION_T_ { template <class... _Args> using __f = __mexception<_BAD_SUBSTITUTION_<>, _WITH_META_FUNCTION_T_, _WITH_TYPES_<_Args...>>; }; template <class _Fun> struct _WITH_META_FUNCTION_ { template <class... _Args> using __f = __mexception<_BAD_SUBSTITUTION_<>, _WITH_META_FUNCTION_, _WITH_TYPES_<_Args...>>; }; template <template <class...> class _Fn> struct __mtry_eval_ { template <class... _Args> using __f = __meval<_Fn, _Args...>; }; template <template <class...> class _Fn, class... _Args> using __mtry_eval = __minvoke<__mtry_catch<__mtry_eval_<_Fn>, _WITH_META_FUNCTION_T_<_Fn>>, _Args...>; template <class _Fn, class... _Args> using __mtry_invoke = __minvoke<__mtry_catch<_Fn, _WITH_META_FUNCTION_<_Fn>>, _Args...>; template <class _Ty, class... _Default> using __msuccess_or_t = __if_c<__ok<_Ty>, _Ty, _Default...>; template <class _Fn, class _Continuation = __q<__types>> struct __transform { template <class... _Args> using __f = __minvoke<_Continuation, __minvoke<_Fn, _Args>...>; }; template <bool> struct __mfold_right_ { template <class _Fn, class _State, class _Head, class... _Tail> using __f = __minvoke< __mfold_right_<sizeof...(_Tail) == 0>, _Fn, __minvoke<_Fn, _State, _Head>, _Tail...>; }; template <> struct __mfold_right_<true> { template <class _Fn, class _State, class...> using __f = _State; }; template <class _Init, class _Fn> struct __mfold_right { template <class... _Args> using __f = __minvoke<__mfold_right_<sizeof...(_Args) == 0>, _Fn, _Init, _Args...>; }; template <class _Continuation, class... _As> struct __mconcat_ { }; template <class _Continuation, class... _As> requires(sizeof...(_As) == 0) && __minvocable<_Continuation, _As...> struct __mconcat_<_Continuation, _As...> { using __t = __minvoke<_Continuation, _As...>; }; template <class _Continuation, template <class...> class _Ap, class... _As> requires __minvocable<_Continuation, _As...> struct __mconcat_<_Continuation, _Ap<_As...>> { using __t = __minvoke<_Continuation, _As...>; }; template < class _Continuation, template <class...> class _Ap, class... _As, template <class...> class _Bp, class... _Bs> requires __minvocable<_Continuation, _As..., _Bs...> struct __mconcat_<_Continuation, _Ap<_As...>, _Bp<_Bs...>> { using __t = __minvoke<_Continuation, _As..., _Bs...>; }; template < class _Continuation, template <class...> class _Ap, class... _As, template <class...> class _Bp, class... _Bs, template <class...> class _Cp, class... _Cs> requires __minvocable<_Continuation, _As..., _Bs..., _Cs...> struct __mconcat_<_Continuation, _Ap<_As...>, _Bp<_Bs...>, _Cp<_Cs...>> { using __t = __minvoke<_Continuation, _As..., _Bs..., _Cs...>; }; template < class _Continuation, template <class...> class _Ap, class... _As, template <class...> class _Bp, class... _Bs, template <class...> class _Cp, class... _Cs, template <class...> class _Dp, class... _Ds, class... _Tail> struct __mconcat_<_Continuation, _Ap<_As...>, _Bp<_Bs...>, _Cp<_Cs...>, _Dp<_Ds...>, _Tail...> : __mconcat_<_Continuation, __types<_As..., _Bs..., _Cs..., _Ds...>, _Tail...> { }; template <class _Continuation = __q<__types>> struct __mconcat { template <class... _Args> using __f = __t<__mconcat_<_Continuation, _Args...>>; }; template <class _Fn> struct __curry { template <class... _Ts> using __f = __minvoke<_Fn, _Ts...>; }; template <class _Fn, class _Tp> struct __uncurry_; template <__merror _Fn, class _Tp> struct __uncurry_<_Fn, _Tp> { using __t = _Fn; }; template <class _Fn, template <class...> class _Ap, class... _As> requires __minvocable<_Fn, _As...> struct __uncurry_<_Fn, _Ap<_As...>> { using __t = __minvoke<_Fn, _As...>; }; template <class _Fn> struct __uncurry { template <class _Tp> using __f = __t<__uncurry_<_Fn, _Tp>>; }; template <class _Fn, class _List> using __mapply = __minvoke<__uncurry<_Fn>, _List>; struct __msize { template <class... _Ts> using __f = __msize_t<sizeof...(_Ts)>; }; template <class _Ty> struct __mcount { template <class... _Ts> using __f = __msize_t<(__same_as<_Ts, _Ty> + ... + 0)>; }; template <class _Fn> struct __mcount_if { template <class... _Ts> using __f = __msize_t<(bool(__v<__minvoke<_Fn, _Ts>>) + ... + 0)>; }; template <class _Tp> struct __contains { template <class... _Args> using __f = __mbool<(__same_as<_Tp, _Args> || ...)>; }; template <class _Continuation = __q<__types>> struct __push_back { template <class _List, class _Item> using __f = __mapply<__mbind_back<_Continuation, _Item>, _List>; }; template <class _Continuation = __q<__types>> struct __push_back_unique { template <class _List, class _Item> using __f = __mapply< __if< __mapply<__contains<_Item>, _List>, _Continuation, __mbind_back<_Continuation, _Item>>, _List>; }; template <class _Continuation = __q<__types>> struct __munique { template <class... _Ts> using __f = __mapply< _Continuation, __minvoke<__mfold_right<__types<>, __push_back_unique<>>, _Ts...>>; }; template <class...> struct __mcompose { }; template <class _First> struct __mcompose<_First> : _First { }; template <class _Second, class _First> struct __mcompose<_Second, _First> { template <class... _Args> using __f = __minvoke<_Second, __minvoke<_First, _Args...>>; }; template <class _Last, class _Penultimate, class... _Rest> struct __mcompose<_Last, _Penultimate, _Rest...> { template <class... _Args> using __f = __minvoke<_Last, __minvoke<__mcompose<_Penultimate, _Rest...>, _Args...>>; }; template <class _Old, class _New, class _Continuation = __q<__types>> struct __replace { template <class... _Args> using __f = __minvoke<_Continuation, __if_c<__same_as<_Args, _Old>, _New, _Args>...>; }; template <class _Old, class _Continuation = __q<__types>> struct __remove { template <class... _Args> using __f = __minvoke< __mconcat<_Continuation>, __if_c<__same_as<_Args, _Old>, __types<>, __types<_Args>>...>; }; template <class _Pred, class _Continuation = __q<__types>> struct __remove_if { template <class... _Args> using __f = __minvoke< __mconcat<_Continuation>, __if<__minvoke<_Pred, _Args>, __types<>, __types<_Args>>...>; }; template <class _Return> struct __qf { template <class... _Args> using __f = _Return(_Args...); }; template <class _Ty, class...> using __mfront_ = _Ty; template <class... _As> using __mfront = __meval<__mfront_, _As...>; template <class... _As> requires(sizeof...(_As) == 1) using __msingle = __mfront<_As...>; template <class _Ty> using __msingle_or = __mbind_back_q<__mfront_, _Ty>; template <class _Continuation = __q<__types>> struct __pop_front { template <class, class... _Ts> using __f = __minvoke<_Continuation, _Ts...>; }; template <class _Ty> struct _Xp { using __t = struct _Up { using __t = _Ty; }; }; template <class _Ty> using __x = __t<_Xp<_Ty>>; template <class _Ty> concept __has_id = requires { typename _Ty::__id; }; template <class _Ty> struct _Yp { using __t = _Ty; }; template <bool = true> struct __id_ { template <class _Ty> using __f = typename _Ty::__id; }; template <> struct __id_<false> { template <class _Ty> using __f = _Yp<_Ty>; }; template <class _Ty> using __id = __minvoke<__id_<__has_id<_Ty>>, _Ty>; template <class _Ty> using __cvref_t = __copy_cvref_t<_Ty, __t<std::remove_cvref_t<_Ty>>>; template <class _From, class _To = __decay_t<_From>> using __cvref_id = __copy_cvref_t<_From, __id<_To>>; template <class _Fun, class... _As> using __call_result_t = decltype(__declval<_Fun>()(__declval<_As>()...)); template <auto _FunPtr> struct __mimpl : __call_result_t<decltype(*_FunPtr)> { }; template <class _Ty> extern __mimpl<(decltype([] { return __mtype<_Ty>{}; })*) 0> __hide_; template <class _Ty> using __hide = __id<_Ty>; template <class _Ty> using __unhide = __t<_Ty>; struct __qcall_result { template <class _Fun, class... _As> using __f = __call_result_t<_Fun, _As...>; }; template <bool _Enable, class _Fun, class... _As> using __call_result_if_t = __minvoke<__if<__mbool<_Enable>, __qcall_result, __>, _Fun, _As...>; template <class _Fn> requires std::is_nothrow_move_constructible_v<_Fn> struct __conv { _Fn __fn_; using __t = __call_result_t<_Fn>; operator __t() && noexcept(__nothrow_callable<_Fn>) { return ((_Fn&&) __fn_)(); } __t operator()() && noexcept(__nothrow_callable<_Fn>) { return ((_Fn&&) __fn_)(); } }; template <class _Fn> __conv(_Fn) -> __conv<_Fn>; struct __cref_fn { template <class _Ty> const _Ty& operator()(const _Ty&); }; template <class _Ty> using __cref_t = decltype(__cref_fn{}(__declval<_Ty>())); template <class, class, class, class> struct __mzip_with2_; template < class _Fn, class _Continuation, template <class...> class _Cp, class... _Cs, template <class...> class _Dp, class... _Ds> requires requires { typename __minvoke<_Continuation, __minvoke<_Fn, _Cs, _Ds>...>; } struct __mzip_with2_<_Fn, _Continuation, _Cp<_Cs...>, _Dp<_Ds...>> { using __t = __minvoke<_Continuation, __minvoke<_Fn, _Cs, _Ds>...>; }; template <class _Fn, class _Continuation = __q<__types>> struct __mzip_with2 { template <class _Cp, class _Dp> using __f = __t<__mzip_with2_<_Fn, _Continuation, _Cp, _Dp>>; }; template <std::size_t... _Indices> __types<__msize_t<_Indices>...> __mconvert_indices(std::index_sequence<_Indices...>*); template <std::size_t _Np> using __mmake_index_sequence = decltype(stdexec::__mconvert_indices((std::make_index_sequence<_Np>*) nullptr)); template <class... _Ts> using __mindex_sequence_for = __mmake_index_sequence<sizeof...(_Ts)>; template <bool> struct __mfind_if_ { template <class _Fn, class _Continuation, class _Head, class... _Tail> using __f = __minvoke< __if_c< __v<__minvoke<_Fn, _Head>>, __mbind_front<_Continuation, _Head>, __mbind_front<__mfind_if_<(sizeof...(_Tail) != 0)>, _Fn, _Continuation>>, _Tail...>; }; template <> struct __mfind_if_<false> { template <class _Fn, class _Continuation> using __f = __minvoke<_Continuation>; }; template <class _Fn, class _Continuation = __q<__types>> struct __mfind_if { template <class... _Args> using __f = __minvoke<__mfind_if_<(sizeof...(_Args) != 0)>, _Fn, _Continuation, _Args...>; }; template <class _Fn> struct __mfind_if_i { template <class... _Args> using __f = __msize_t<(sizeof...(_Args) - __v<__minvoke<__mfind_if<_Fn, __msize>, _Args...>>)>; }; template <class... _Booleans> using __mand_ = __mbool<(__v<_Booleans> && ...)>; template <class... _Booleans> using __mand = __meval<__mand_, _Booleans...>; template <class... _Booleans> using __mor_ = __mbool<(__v<_Booleans> || ...)>; template <class... _Booleans> using __mor = __meval<__mor_, _Booleans...>; template <class _Boolean> using __mnot_ = __mbool<!__v<_Boolean>>; template <class _Boolean> using __mnot = __meval<__mnot_, _Boolean>; template <class _Fn> struct __mall_of { template <class... _Args> using __f = __mand<__minvoke<_Fn, _Args>...>; }; template <class _Fn> struct __mnone_of { template <class... _Args> using __f = __mand<__mnot<__minvoke<_Fn, _Args>>...>; }; template <class _Fn> struct __many_of { template <class... _Args> using __f = __mor<__minvoke<_Fn, _Args>...>; }; template <std::size_t> using __void_ptr = void*; template <class _Ty> using __mtype_ptr = __mtype<_Ty>*; template <class _Ty> struct __m_at_; template <std::size_t... _Is> struct __m_at_<std::index_sequence<_Is...>> { template <class _Up, class... _Us> static _Up __f_(__void_ptr<_Is>..., _Up*, _Us*...); template <class... _Ts> using __f = __t<decltype(__m_at_::__f_(__mtype_ptr<_Ts>()...))>; }; template <std::size_t _Np, class... _Ts> using __m_at = __minvoke<__m_at_<std::make_index_sequence<_Np>>, _Ts...>; template <std::size_t _Np> struct __placeholder_; template <std::size_t _Np> using __placeholder = __placeholder_<_Np>*; using __0 = __placeholder<0>; using __1 = __placeholder<1>; using __2 = __placeholder<2>; using __3 = __placeholder<3>; template <class _Ty, class _Noexcept = __mbool<true>> struct __mconstruct { template <class... _As> auto operator()(_As&&... __as) const noexcept(__v<_Noexcept>&& noexcept(_Ty((_As&&) __as...))) -> decltype(_Ty((_As&&) __as...)) { return _Ty((_As&&) __as...); } }; template <template <class...> class _Cp, class _Noexcept = __mbool<true>> using __mconstructor_for = __mcompose<__q<__mconstruct>, __q<_Cp>>; template <std::size_t> using __ignore_t = __ignore; template <std::size_t... _Is, class _Ty, class... _Us> _Ty&& __nth_pack_element_(__ignore_t<_Is>..., _Ty&& __t, _Us&&...) noexcept { return (_Ty&&) __t; } template <std::size_t _Np, class... _Ts> constexpr decltype(auto) __nth_pack_element(_Ts&&... __ts) noexcept { return [&]<std::size_t... _Is>(std::index_sequence<_Is...>*) noexcept -> decltype(auto) { return stdexec::__nth_pack_element_<_Is...>((_Ts&&) __ts...); }((std::make_index_sequence<_Np>*) nullptr); } template <class _Ty> struct __mdispatch_ { template <class... _Ts> _Ty operator()(_Ts&&...) const noexcept(noexcept(_Ty{})) { return _Ty{}; } }; template <std::size_t _Np> struct __mdispatch_<__placeholder<_Np>> { template <class... _Ts> decltype(auto) operator()(_Ts&&... __ts) const noexcept { return stdexec::__nth_pack_element<_Np>((_Ts&&) __ts...); } }; template <std::size_t _Np> struct __mdispatch_<__placeholder<_Np>&> { template <class... _Ts> decltype(auto) operator()(_Ts&&... __ts) const noexcept { return stdexec::__nth_pack_element<_Np>(__ts...); } }; template <std::size_t _Np> struct __mdispatch_<__placeholder<_Np>&&> { template <class... _Ts> decltype(auto) operator()(_Ts&&... __ts) const noexcept { return std::move(stdexec::__nth_pack_element<_Np>(__ts...)); } }; template <std::size_t _Np> struct __mdispatch_<const __placeholder<_Np>&> { template <class... _Ts> decltype(auto) operator()(_Ts&&... __ts) const noexcept { return std::as_const(stdexec::__nth_pack_element<_Np>(__ts...)); } }; template <class _Ret, class... _Args> struct __mdispatch_<_Ret (*)(_Args...)> { template <class... _Ts> requires(__callable<__mdispatch_<_Args>, _Ts...> && ...) && __callable<_Ret, __call_result_t<__mdispatch_<_Args>, _Ts...>...> auto operator()(_Ts&&... __ts) const noexcept(__nothrow_callable<_Ret, __call_result_t<__mdispatch_<_Args>, _Ts...>...>) -> __call_result_t<_Ret, __call_result_t<__mdispatch_<_Args>, _Ts...>...> { return _Ret{}(__mdispatch_<_Args>{}((_Ts&&) __ts...)...); } }; template <class _Ty> struct __mdispatch { }; template <class _Ret, class... _Args> struct __mdispatch<_Ret(_Args...)> { template <class... _Ts> requires(__callable<__mdispatch_<_Args>, _Ts...> && ...) && __callable<_Ret, __call_result_t<__mdispatch_<_Args>, _Ts...>...> auto operator()(_Ts&&... __ts) const noexcept(__nothrow_callable<_Ret, __call_result_t<__mdispatch_<_Args>, _Ts...>...>) -> __call_result_t<_Ret, __call_result_t<__mdispatch_<_Args>, _Ts...>...> { return _Ret{}(__mdispatch_<_Args>{}((_Ts&&) __ts...)...); } }; template <class _Ty, class... _Ts> concept __dispatchable = __callable<__mdispatch<_Ty>, _Ts...>; template <class _Ty, class... _Ts> concept __nothrow_dispatchable = __nothrow_callable<__mdispatch<_Ty>, _Ts...>; template <class _Ty, class... _Ts> using __dispatch_result_t = __call_result_t<__mdispatch<_Ty>, _Ts...>; template <class _Signature, class... _Args> using __try_dispatch_ = __mbool<__dispatchable<_Signature, _Args...>>; template <class _Signatures, class _Continuation = __q<__mfront>> struct __which { }; template <template <class...> class _Cp, class... _Signatures, class _Continuation> struct __which<_Cp<_Signatures...>, _Continuation> { template <class... _Args> using __f = __minvoke< __mfind_if<__mbind_back_q<__try_dispatch_, _Args...>, _Continuation>, _Signatures...>; }; template <class _Signatures, class _DefaultFn, class... _Args> using __make_dispatcher = __minvoke< __if_c< __minvocable<__which<_Signatures>, _Args...>, __mcompose<__q<__mdispatch>, __which<_Signatures>>, _DefaultFn>, _Args...>; } namespace stdexec { namespace __receivers { struct set_value_t; struct set_error_t; struct set_stopped_t; } using __receivers::set_value_t; using __receivers::set_error_t; using __receivers::set_stopped_t; extern const set_value_t set_value; extern const set_error_t set_error; extern const set_stopped_t set_stopped; template <class _Tag> concept __completion_tag = __one_of<_Tag, set_value_t, set_error_t, set_stopped_t>; template <class _Sender> extern const bool enable_receiver; namespace __env { struct get_env_t; struct empty_env; } using __env::empty_env; using __env::get_env_t; extern const get_env_t get_env; template <class _EnvProvider> using env_of_t = __call_result_t<get_env_t, _EnvProvider>; enum class forward_progress_guarantee { concurrent, parallel, weakly_parallel }; namespace __queries { struct forwarding_query_t; struct execute_may_block_caller_t; struct get_forward_progress_guarantee_t; struct __has_algorithm_customizations_t; struct get_scheduler_t; struct get_delegatee_scheduler_t; struct get_allocator_t; struct get_stop_token_t; template <__completion_tag _CPO> struct get_completion_scheduler_t; } using __queries::forwarding_query_t; using __queries::execute_may_block_caller_t; using __queries::__has_algorithm_customizations_t; using __queries::get_forward_progress_guarantee_t; using __queries::get_allocator_t; using __queries::get_scheduler_t; using __queries::get_delegatee_scheduler_t; using __queries::get_stop_token_t; using __queries::get_completion_scheduler_t; extern const forwarding_query_t forwarding_query; extern const execute_may_block_caller_t execute_may_block_caller; extern const __has_algorithm_customizations_t __has_algorithm_customizations; extern const get_forward_progress_guarantee_t get_forward_progress_guarantee; extern const get_scheduler_t get_scheduler; extern const get_delegatee_scheduler_t get_delegatee_scheduler; extern const get_allocator_t get_allocator; extern const get_stop_token_t get_stop_token; template <__completion_tag _CPO> extern const get_completion_scheduler_t<_CPO> get_completion_scheduler; template <class _Tp> using stop_token_of_t = __decay_t<__call_result_t<get_stop_token_t, _Tp>>; template <class _Sender, class _CPO> concept __has_completion_scheduler = __callable<get_completion_scheduler_t<_CPO>, env_of_t<const _Sender&>>; template <class _Sender, class _CPO> using __completion_scheduler_for = __call_result_t<get_completion_scheduler_t<_CPO>, env_of_t<const _Sender&>>; namespace __get_completion_signatures { struct get_completion_signatures_t; } using __get_completion_signatures::get_completion_signatures_t; extern const get_completion_signatures_t get_completion_signatures; template <class _Sender, class _Env> using __completion_signatures_of_t = __call_result_t< get_completion_signatures_t, _Sender, _Env>; namespace __connect { struct connect_t; } using __connect::connect_t; extern const connect_t connect; template <class _Sender, class _Receiver> using connect_result_t = __call_result_t<connect_t, _Sender, _Receiver>; template <class _Sender, class _Receiver> concept __nothrow_connectable = __nothrow_callable<connect_t, _Sender, _Receiver>; template <class _Sender> extern const bool enable_sender; namespace __start { struct start_t; } using __start::start_t; extern const start_t start; namespace __schedule { struct schedule_t; } using __schedule::schedule_t; extern const schedule_t schedule; namespace __as_awaitable { struct as_awaitable_t; } using __as_awaitable::as_awaitable_t; extern const as_awaitable_t as_awaitable; } #include <version> #include <type_traits> namespace stdexec::__std_concepts { template <class _Ap, class _Bp> concept same_as = __same_as<_Ap, _Bp> && __same_as<_Bp, _Ap>; template <class T> concept integral = std::is_integral_v<T>; template <class _Ap, class _Bp> concept derived_from = __is_base_of(_Bp, _Ap) && __is_convertible(const volatile _Ap*, const volatile _Bp*); template <class _From, class _To> concept convertible_to = __is_convertible(_From, _To) && requires(_From (&__fun)()) { static_cast<_To>(__fun()); }; template <class _Ty> concept equality_comparable = requires(__cref_t<_Ty> __t) { { __t == __t } -> convertible_to<bool>; { __t != __t } -> convertible_to<bool>; }; } namespace stdexec { using namespace __std_concepts; template <class _Ty> inline constexpr bool __destructible_ = requires { { ((_Ty && (*) () noexcept) nullptr)().~_Ty() } noexcept; }; template <class _Ty> inline constexpr bool __destructible_<_Ty&> = true; template <class _Ty> inline constexpr bool __destructible_<_Ty&&> = true; template <class _Ty, std::size_t _Np> inline constexpr bool __destructible_<_Ty[_Np]> = __destructible_<_Ty>; template <class T> concept destructible = __destructible_<T>; template <class _Ty, class... _As> concept constructible_from = destructible<_Ty> && __is_constructible(_Ty, _As...); template <class _Ty> concept default_initializable = constructible_from<_Ty> && requires { _Ty{}; } && requires { ::new _Ty; }; template <class _Ty> concept move_constructible = constructible_from<_Ty, _Ty>; template <class _Ty> concept copy_constructible = move_constructible<_Ty> && constructible_from<_Ty, _Ty const &>; template <class _LHS, class _RHS > concept assignable_from = same_as<_LHS, _LHS&> && requires(_LHS __lhs, _RHS&& __rhs) { { __lhs = ((_RHS&&) __rhs) } -> same_as<_LHS>; }; namespace __swap { using std::swap; template <class _Ty, class _Uy> concept swappable_with = requires(_Ty&& __t, _Uy&& __u) { swap((_Ty&&) __t, (_Uy&&) __u); }; inline constexpr auto const __fn = []<class _Ty, swappable_with<_Ty> _Uy>(_Ty&& __t, _Uy&& __u) noexcept( noexcept(swap((_Ty&&) __t, (_Uy&&) __u))) { swap((_Ty&&) __t, (_Uy&&) __u); }; } using __swap::swappable_with; inline constexpr auto const & swap = __swap::__fn; template <class _Ty> concept swappable = swappable_with<_Ty, _Ty>; template < class _Ty > concept movable = std::is_object_v<_Ty> && move_constructible<_Ty> && assignable_from<_Ty&, _Ty> && swappable<_Ty>; template <class _Ty> concept copyable = copy_constructible<_Ty> && movable<_Ty> && assignable_from<_Ty&, _Ty&> && assignable_from<_Ty&, const _Ty&> && assignable_from<_Ty&, const _Ty>; template <class _Ty> concept semiregular = copyable<_Ty> && default_initializable<_Ty>; template <class _Ty> concept regular = semiregular<_Ty> && equality_comparable<_Ty>; template <class _Ty> concept __boolean_testable_ = convertible_to<_Ty, bool>; template < class T, class U > concept __partially_ordered_with = requires(__cref_t<T> t, __cref_t<U> u) { { t < u } -> __boolean_testable_; { t > u } -> __boolean_testable_; { t <= u } -> __boolean_testable_; { t >= u } -> __boolean_testable_; { u < t } -> __boolean_testable_; { u > t } -> __boolean_testable_; { u <= t } -> __boolean_testable_; { u >= t } -> __boolean_testable_; }; template < class _Ty > concept totally_ordered = equality_comparable<_Ty> && __partially_ordered_with<_Ty, _Ty>; template <class _Ty> concept __movable_value = move_constructible<__decay_t<_Ty>> && constructible_from<__decay_t<_Ty>, _Ty>; template <class _Ty> concept __nothrow_movable_value = __movable_value<_Ty> && requires(_Ty&& __t) { { __decay_t<_Ty>{__decay_t<_Ty>{(_Ty&&) __t}} } noexcept; }; template <class _Ty, class... _As> concept __nothrow_constructible_from = constructible_from<_Ty, _As...> && __is_nothrow_constructible(_Ty, _As...); template <class _Ty> concept __nothrow_move_constructible = __nothrow_constructible_from<_Ty, _Ty>; template <class _Ty> concept __nothrow_copy_constructible = __nothrow_constructible_from<_Ty, const _Ty&>; template <class _Ty> concept __decay_copyable = constructible_from<__decay_t<_Ty>, _Ty>; template <class _Ty> concept __nothrow_decay_copyable = __nothrow_constructible_from<__decay_t<_Ty>, _Ty>; template <class _Range> using range_value_t = decltype(*begin(::std::declval<_Range>())); } #include <atomic> #include <memory> #include <new> namespace stdexec { namespace __ptr { template <class _Ty> struct __make_intrusive_t; template <class _Ty> struct __enable_intrusive_from_this; template <class _Ty> struct __control_block { alignas(_Ty) unsigned char __value_[sizeof(_Ty)]; std::atomic<unsigned long> __refcount_; template <class... _Us> explicit __control_block(_Us&&... __us) noexcept(noexcept(_Ty{__declval<_Us>()...})) : __refcount_(1u) { ::new ((void*) __value_) _Ty{(_Us&&) __us...}; } ~__control_block() { __value().~_Ty(); } _Ty& __value() const noexcept { return *(_Ty*) __value_; } }; template <class _Ty> class __intrusive_ptr { using _UncvTy = std::remove_cv_t<_Ty>; friend struct __make_intrusive_t<_Ty>; friend struct __enable_intrusive_from_this<_UncvTy>; __control_block<_UncvTy>* __data_{nullptr}; explicit __intrusive_ptr(__control_block<_UncvTy>* __data) noexcept : __data_(__data) { } void __addref_() noexcept { if (__data_) { __data_->__refcount_.fetch_add(1, std::memory_order_relaxed); } } void __release_() noexcept { if (__data_ && 1u == __data_->__refcount_.fetch_sub(1, std::memory_order_release)) { std::atomic_thread_fence(std::memory_order_acquire); delete __data_; } } public: __intrusive_ptr() = default; __intrusive_ptr(__intrusive_ptr&& __that) noexcept : __data_(std::exchange(__that.__data_, nullptr)) { } __intrusive_ptr(const __intrusive_ptr& __that) noexcept : __data_(__that.__data_) { __addref_(); } __intrusive_ptr& operator=(__intrusive_ptr&& __that) noexcept { [[maybe_unused]] __intrusive_ptr __old{ std::exchange(__data_, std::exchange(__that.__data_, nullptr))}; return *this; } __intrusive_ptr& operator=(const __intrusive_ptr& __that) noexcept { return operator=(__intrusive_ptr(__that)); } ~__intrusive_ptr() { __release_(); } void reset() noexcept { operator=({}); } void swap(__intrusive_ptr& __that) noexcept { std::swap(__data_, __that.__data_); } _Ty* get() const noexcept { return &__data_->__value(); } _Ty* operator->() const noexcept { return &__data_->__value(); } _Ty& operator*() const noexcept { return __data_->__value(); } explicit operator bool() const noexcept { return __data_ != nullptr; } bool operator!() const noexcept { return __data_ == nullptr; } bool operator==(const __intrusive_ptr&) const = default; bool operator==(std::nullptr_t) const noexcept { return __data_ == nullptr; } }; template <class _Ty> struct __enable_intrusive_from_this { __intrusive_ptr<_Ty> __intrusive_from_this() noexcept { static_assert(0 == offsetof(__control_block<_Ty>, __value_)); _Ty* __this = static_cast<_Ty*>(this); __intrusive_ptr<_Ty> __p{(__control_block<_Ty>*) __this}; __p.__addref_(); return __p; } __intrusive_ptr<const _Ty> __intrusive_from_this() const noexcept { static_assert(0 == offsetof(__control_block<_Ty>, __value_)); const _Ty* __this = static_cast<const _Ty*>(this); __intrusive_ptr<const _Ty> __p{(__control_block<_Ty>*) __this}; __p.__addref_(); return __p; } }; template <class _Ty> struct __make_intrusive_t { template <class... _Us> requires constructible_from<_Ty, _Us...> __intrusive_ptr<_Ty> operator()(_Us&&... __us) const { using _UncvTy = std::remove_cv_t<_Ty>; return __intrusive_ptr<_Ty>{::new __control_block<_UncvTy>{(_Us&&) __us...}}; } }; } using __ptr::__intrusive_ptr; using __ptr::__enable_intrusive_from_this; template <class _Ty> inline constexpr __ptr::__make_intrusive_t<_Ty> __make_intrusive{}; } namespace stdexec { template <class _Fn, class... _Ts> requires __nothrow_callable<_Fn, _Ts...> struct __scope_guard; template <class _Fn> struct __scope_guard<_Fn> { [[no_unique_address]] _Fn __fn_; [[no_unique_address]] __immovable __hidden_{}; bool __dismissed_{false}; ~__scope_guard() { if (!__dismissed_) ((_Fn&&) __fn_)(); } void __dismiss() noexcept { __dismissed_ = true; } }; template <class _Fn, class _T0> struct __scope_guard<_Fn, _T0> { [[no_unique_address]] _Fn __fn_; [[no_unique_address]] _T0 __t0_; [[no_unique_address]] __immovable __hidden_{}; bool __dismissed_{false}; void __dismiss() noexcept { __dismissed_ = true; } ~__scope_guard() { if (!__dismissed_) ((_Fn&&) __fn_)((_T0&&) __t0_); } }; template <class _Fn, class _T0, class _T1> struct __scope_guard<_Fn, _T0, _T1> { [[no_unique_address]] _Fn __fn_; [[no_unique_address]] _T0 __t0_; [[no_unique_address]] _T1 __t1_; [[no_unique_address]] __immovable __hidden_{}; bool __dismissed_{false}; void __dismiss() noexcept { __dismissed_ = true; } ~__scope_guard() { if (!__dismissed_) ((_Fn&&) __fn_)((_T0&&) __t0_, (_T1&&) __t1_); } }; template <class _Fn, class _T0, class _T1, class _T2> struct __scope_guard<_Fn, _T0, _T1, _T2> { [[no_unique_address]] _Fn __fn_; [[no_unique_address]] _T0 __t0_; [[no_unique_address]] _T1 __t1_; [[no_unique_address]] _T2 __t2_; [[no_unique_address]] __immovable __hidden_{}; bool __dismissed_{false}; void __dismiss() noexcept { __dismissed_ = true; } ~__scope_guard() { if (!__dismissed_) ((_Fn&&) __fn_)((_T0&&) __t0_, (_T1&&) __t1_, (_T2&&) __t2_); } }; template <class _Fn, class... _Ts> __scope_guard(_Fn, _Ts...) -> __scope_guard<_Fn, _Ts...>; } #include <cstddef> namespace stdexec { template <class _Fn, class... _Args> using __tuple_applicable = __mbool<__callable<_Fn, _Args...>>; template <class _Fn, class... _Args> using __tuple_nothrow_apply_ = __mbool<__nothrow_callable<_Fn, _Args...>>; template <class... _Ts> struct __tuple { std::tuple<_Ts...> __vals; template <class _Fn, __decays_to<__tuple> _Self> static constexpr auto __apply(_Fn __fn, _Self&& __self) noexcept( __nothrow_callable<_Fn, __copy_cvref_t<_Self, _Ts>...>) -> __call_result_t<_Fn, __copy_cvref_t<_Self, _Ts>...> { return std::apply((_Fn&&) __fn, ((_Self&&) __self).__vals); } }; template <class... _Ts> __tuple(_Ts...) -> __tuple<_Ts...>; template <> struct __tuple<> { template <class _Fn> static constexpr auto __apply(_Fn __fn, __tuple<>) noexcept(noexcept(((_Fn&&) __fn)()))->decltype(((_Fn&&) __fn)()) { return ((_Fn&&) __fn)(); } }; template <class _T0> struct __tuple<_T0> { _T0 __val0; template <class _Fn, __decays_to<__tuple> _Self> static constexpr auto __apply(_Fn __fn, _Self&& __self) noexcept(noexcept(((_Fn&&) __fn)(((_Self&&) __self).__val0)))->decltype(((_Fn&&) __fn)(((_Self&&) __self).__val0)) { return ((_Fn&&) __fn)(((_Self&&) __self).__val0); } }; template <class _T0, class _T1> struct __tuple<_T0, _T1> { _T0 __val0; _T1 __val1; template <class _Fn, __decays_to<__tuple> _Self> static constexpr auto __apply(_Fn __fn, _Self&& __self) noexcept(noexcept(((_Fn&&) __fn)(((_Self&&) __self).__val0, ((_Self&&) __self).__val1)))->decltype(((_Fn&&) __fn)(((_Self&&) __self).__val0, ((_Self&&) __self).__val1)) { return ((_Fn&&) __fn)(((_Self&&) __self).__val0, ((_Self&&) __self).__val1); } }; template <class _T0, class _T1, class _T2> struct __tuple<_T0, _T1, _T2> { _T0 __val0; _T1 __val1; _T2 __val2; template <class _Fn, __decays_to<__tuple> _Self> static constexpr auto __apply(_Fn __fn, _Self&& __self) noexcept(noexcept((( _Fn&&) __fn)(((_Self&&) __self).__val0, ((_Self&&) __self).__val1, ((_Self&&) __self).__val2)))->decltype((( _Fn&&) __fn)(((_Self&&) __self).__val0, ((_Self&&) __self).__val1, ((_Self&&) __self).__val2)) { return (( _Fn&&) __fn)(((_Self&&) __self).__val0, ((_Self&&) __self).__val1, ((_Self&&) __self).__val2); } }; template <class _T0, class _T1, class _T2, class _T3> struct __tuple<_T0, _T1, _T2, _T3> { _T0 __val0; _T1 __val1; _T2 __val2; _T3 __val3; template <class _Fn, __decays_to<__tuple> _Self> static constexpr auto __apply(_Fn __fn, _Self&& __self) noexcept(noexcept(((_Fn&&) __fn)( ((_Self&&) __self).__val0, ((_Self&&) __self).__val1, ((_Self&&) __self).__val2, ((_Self&&) __self).__val3)))->decltype(((_Fn&&) __fn)( ((_Self&&) __self).__val0, ((_Self&&) __self).__val1, ((_Self&&) __self).__val2, ((_Self&&) __self).__val3)) { return ((_Fn&&) __fn)( ((_Self&&) __self).__val0, ((_Self&&) __self).__val1, ((_Self&&) __self).__val2, ((_Self&&) __self).__val3); } }; template <class _Fn, class _Tuple> constexpr auto __tuple_apply(_Fn __fn, _Tuple&& __tup) noexcept(noexcept(__tup.__apply((_Fn&&) __fn, (_Tuple&&) __tup)))->decltype(__tup.__apply((_Fn&&) __fn, (_Tuple&&) __tup)) { return __tup.__apply((_Fn&&) __fn, (_Tuple&&) __tup); }; template <class _Tuple> extern const std::size_t __tuple_size; template <class... _Ts> inline constexpr std::size_t __tuple_size<__tuple<_Ts...>> = sizeof...(_Ts); template <std::size_t> struct __tuple_elem_fn_; template <> struct __tuple_elem_fn_<0u> { template <class _Tuple> using __f = decltype((__declval<_Tuple>().__val0)); }; template <> struct __tuple_elem_fn_<1u> { template <class _Tuple> using __f = decltype((__declval<_Tuple>().__val1)); }; template <> struct __tuple_elem_fn_<2u> { template <class _Tuple> using __f = decltype((__declval<_Tuple>().__val2)); }; template <> struct __tuple_elem_fn_<3u> { template <class _Tuple> using __f = decltype((__declval<_Tuple>().__val3)); }; template <std::size_t _Index, class _Tuple> using __tuple_elem = __minvoke<__tuple_elem_fn_<_Index>, _Tuple>; template <class _Tuple> using __tuple_elem0 = __tuple_elem<0u, _Tuple>; template <class _Tuple> using __tuple_elem1 = __tuple_elem<1u, _Tuple>; template <class _Tuple> using __tuple_elem2 = __tuple_elem<2u, _Tuple>; template <class _Tuple> using __tuple_elem3 = __tuple_elem<3u, _Tuple>; } #include <functional> namespace stdexec::__std_concepts { template <class _Fun, class... _As> concept invocable = requires(_Fun&& __f, _As&&... __as) { std::invoke((_Fun&&) __f, (_As&&) __as...); }; } namespace std { using namespace stdexec::__std_concepts; } namespace stdexec { template <class _Fun, class... _As> concept __nothrow_invocable = invocable<_Fun, _As...> && requires(_Fun&& __f, _As&&... __as) { { std::invoke((_Fun&&) __f, (_As&&) __as...) } noexcept; }; struct __first { template <class _First, class _Second> constexpr _First&& operator()(_First&& __first, _Second&&) const noexcept { return (_First&&) __first; } }; template <auto _Fun> struct __fun_c_t { using _FunT = decltype(_Fun); template <class... _Args> requires __callable<_FunT, _Args...> auto operator()(_Args&&... __args) const noexcept(noexcept(_Fun((_Args&&) __args...))) -> __call_result_t<_FunT, _Args...> { return _Fun((_Args&&) __args...); } }; template <auto _Fun> inline constexpr __fun_c_t<_Fun> __fun_c{}; template <class _Fun0, class _Fun1> struct __composed { [[no_unique_address]] _Fun0 __t0_; [[no_unique_address]] _Fun1 __t1_; template <class... _Ts> requires __callable<_Fun1, _Ts...> && __callable<_Fun0, __call_result_t<_Fun1, _Ts...>> __call_result_t<_Fun0, __call_result_t<_Fun1, _Ts...>> operator()(_Ts&&... __ts) && { return ((_Fun0&&) __t0_)(((_Fun1&&) __t1_)((_Ts&&) __ts...)); } template <class... _Ts> requires __callable<const _Fun1&, _Ts...> && __callable<const _Fun0&, __call_result_t<const _Fun1&, _Ts...>> __call_result_t<_Fun0, __call_result_t<_Fun1, _Ts...>> operator()(_Ts&&... __ts) const & { return __t0_(__t1_((_Ts&&) __ts...)); } }; inline constexpr struct __compose_t { template <class _Fun0, class _Fun1> __composed<_Fun0, _Fun1> operator()(_Fun0 __fun0, _Fun1 __fun1) const { return {(_Fun0&&) __fun0, (_Fun1&&) __fun1}; } } __compose{}; namespace __tag_invoke { void tag_invoke(); template <class _Tag, class... _Args> concept tag_invocable = requires(_Tag __tag, _Args&&... __args) { tag_invoke((_Tag&&) __tag, (_Args&&) __args...); }; template <class _Ret, class _Tag, class... _Args> concept __tag_invocable_r = requires(_Tag __tag, _Args&&... __args) { { static_cast<_Ret>(tag_invoke((_Tag&&) __tag, (_Args&&) __args...)) }; }; template <class _Tag, class... _Args> concept nothrow_tag_invocable = tag_invocable<_Tag, _Args...> && requires(_Tag __tag, _Args&&... __args) { { tag_invoke((_Tag&&) __tag, (_Args&&) __args...) } noexcept; }; template <class _Tag, class... _Args> using tag_invoke_result_t = decltype(tag_invoke(__declval<_Tag>(), __declval<_Args>()...)); template <class _Tag, class... _Args> struct tag_invoke_result { }; template <class _Tag, class... _Args> requires tag_invocable<_Tag, _Args...> struct tag_invoke_result<_Tag, _Args...> { using type = tag_invoke_result_t<_Tag, _Args...>; }; struct tag_invoke_t { template <class _Tag, class... _Args> requires tag_invocable<_Tag, _Args...> constexpr auto operator()(_Tag __tag, _Args&&... __args) const noexcept(nothrow_tag_invocable<_Tag, _Args...>) -> tag_invoke_result_t<_Tag, _Args...> { return tag_invoke((_Tag&&) __tag, (_Args&&) __args...); } }; } using __tag_invoke::tag_invoke_t; namespace __ti { inline constexpr tag_invoke_t tag_invoke{}; } using namespace __ti; template <auto& _Tag> using tag_t = __decay_t<decltype(_Tag)>; using __tag_invoke::tag_invocable; using __tag_invoke::__tag_invocable_r; using __tag_invoke::nothrow_tag_invocable; using __tag_invoke::tag_invoke_result_t; using __tag_invoke::tag_invoke_result; } #include <version> namespace stdexec { template <class _Awaitable, class _Promise = void> concept __awaitable = false; template <class _Awaitable, class _Promise = void> requires __awaitable<_Awaitable, _Promise> using __await_result_t = void; } #include <version> #include <cstdint> #include <utility> #include <type_traits> #include <atomic> #include <thread> namespace stdexec { class in_place_stop_token; class in_place_stop_source; template <class _Callback> class in_place_stop_callback; namespace __stok { struct __in_place_stop_callback_base { void __execute() noexcept { this->__execute_(this); } protected: using __execute_fn_t = void(__in_place_stop_callback_base*) noexcept; explicit __in_place_stop_callback_base( const in_place_stop_source* __source, __execute_fn_t* __execute) noexcept : __source_(__source) , __execute_(__execute) { } void __register_callback_() noexcept; friend in_place_stop_source; const in_place_stop_source* __source_; __execute_fn_t* __execute_; __in_place_stop_callback_base* __next_ = nullptr; __in_place_stop_callback_base** __prev_ptr_ = nullptr; bool* __removed_during_callback_ = nullptr; std::atomic<bool> __callback_completed_{false}; }; struct __spin_wait { __spin_wait() noexcept = default; void __wait() noexcept { if (__count_++ < __yield_threshold_) { } else { if (__count_ == 0) __count_ = __yield_threshold_; std::this_thread::yield(); } } private: static constexpr uint32_t __yield_threshold_ = 20; uint32_t __count_ = 0; }; template <template <class> class> struct __check_type_alias_exists; } struct never_stop_token { private: struct __callback_type { explicit __callback_type(never_stop_token, auto&&) noexcept { } }; public: template <class> using callback_type = __callback_type; static constexpr bool stop_requested() noexcept { return false; } static constexpr bool stop_possible() noexcept { return false; } bool operator==(const never_stop_token&) const noexcept = default; }; template <class _Callback> class in_place_stop_callback; class in_place_stop_source { public: in_place_stop_source() noexcept = default; ~in_place_stop_source(); in_place_stop_source(in_place_stop_source&&) = delete; in_place_stop_token get_token() const noexcept; bool request_stop() noexcept; bool stop_requested() const noexcept { return (__state_.load(std::memory_order_acquire) & __stop_requested_flag_) != 0; } private: friend in_place_stop_token; friend __stok::__in_place_stop_callback_base; template <class> friend class in_place_stop_callback; uint8_t __lock_() const noexcept; void __unlock_(uint8_t) const noexcept; bool __try_lock_unless_stop_requested_(bool) const noexcept; bool __try_add_callback_(__stok::__in_place_stop_callback_base*) const noexcept; void __remove_callback_(__stok::__in_place_stop_callback_base*) const noexcept; static constexpr uint8_t __stop_requested_flag_ = 1; static constexpr uint8_t __locked_flag_ = 2; mutable std::atomic<uint8_t> __state_{0}; mutable __stok::__in_place_stop_callback_base* __callbacks_ = nullptr; std::thread::id __notifying_thread_; }; class in_place_stop_token { public: template <class _Fun> using callback_type = in_place_stop_callback<_Fun>; in_place_stop_token() noexcept : __source_(nullptr) { } in_place_stop_token(const in_place_stop_token& __other) noexcept = default; in_place_stop_token(in_place_stop_token&& __other) noexcept : __source_(std::exchange(__other.__source_, {})) { } in_place_stop_token& operator=(const in_place_stop_token& __other) noexcept = default; in_place_stop_token& operator=(in_place_stop_token&& __other) noexcept { __source_ = std::exchange(__other.__source_, nullptr); return *this; } bool stop_requested() const noexcept { return __source_ != nullptr && __source_->stop_requested(); } bool stop_possible() const noexcept { return __source_ != nullptr; } void swap(in_place_stop_token& __other) noexcept { std::swap(__source_, __other.__source_); } bool operator==(const in_place_stop_token&) const noexcept = default; private: friend in_place_stop_source; template <class> friend class in_place_stop_callback; explicit in_place_stop_token(const in_place_stop_source* __source) noexcept : __source_(__source) { } const in_place_stop_source* __source_; }; inline in_place_stop_token in_place_stop_source::get_token() const noexcept { return in_place_stop_token{this}; } template <class _Fun> class in_place_stop_callback : __stok::__in_place_stop_callback_base { public: template <class _Fun2> requires constructible_from<_Fun, _Fun2> explicit in_place_stop_callback( in_place_stop_token __token, _Fun2&& __fun) noexcept(__nothrow_constructible_from<_Fun, _Fun2>) : __stok::__in_place_stop_callback_base( __token.__source_, &in_place_stop_callback::__execute_impl_) , __fun_((_Fun2&&) __fun) { __register_callback_(); } ~in_place_stop_callback() { if (__source_ != nullptr) __source_->__remove_callback_(this); } private: static void __execute_impl_(__stok::__in_place_stop_callback_base* cb) noexcept { std::move(static_cast<in_place_stop_callback*>(cb)->__fun_)(); } [[no_unique_address]] _Fun __fun_; }; namespace __stok { inline void __in_place_stop_callback_base::__register_callback_() noexcept { if (__source_ != nullptr) { if (!__source_->__try_add_callback_(this)) { __source_ = nullptr; __execute(); } } } } inline in_place_stop_source::~in_place_stop_source() { do { static_assert(noexcept((__state_.load(std::memory_order_relaxed) & __locked_flag_) == 0)); assert((__state_.load(std::memory_order_relaxed) & __locked_flag_) == 0); } while (false); do { static_assert(noexcept(__callbacks_ == nullptr)); assert(__callbacks_ == nullptr); } while (false); } inline bool in_place_stop_source::request_stop() noexcept { if (!__try_lock_unless_stop_requested_(true)) return true; __notifying_thread_ = std::this_thread::get_id(); while (__callbacks_ != nullptr) { auto* __callbk = __callbacks_; __callbk->__prev_ptr_ = nullptr; __callbacks_ = __callbk->__next_; if (__callbacks_ != nullptr) __callbacks_->__prev_ptr_ = &__callbacks_; __state_.store(__stop_requested_flag_, std::memory_order_release); bool __removed_during_callback = false; __callbk->__removed_during_callback_ = &__removed_during_callback; __callbk->__execute(); if (!__removed_during_callback) { __callbk->__removed_during_callback_ = nullptr; __callbk->__callback_completed_.store(true, std::memory_order_release); } __lock_(); } __state_.store(__stop_requested_flag_, std::memory_order_release); return false; } inline uint8_t in_place_stop_source::__lock_() const noexcept { __stok::__spin_wait __spin; auto __old_state = __state_.load(std::memory_order_relaxed); do { while ((__old_state & __locked_flag_) != 0) { __spin.__wait(); __old_state = __state_.load(std::memory_order_relaxed); } } while (!__state_.compare_exchange_weak( __old_state, __old_state | __locked_flag_, std::memory_order_acquire, std::memory_order_relaxed)); return __old_state; } inline void in_place_stop_source::__unlock_(uint8_t __old_state) const noexcept { (void) __state_.store(__old_state, std::memory_order_release); } inline bool in_place_stop_source::__try_lock_unless_stop_requested_( bool __set_stop_requested) const noexcept { __stok::__spin_wait __spin; auto __old_state = __state_.load(std::memory_order_relaxed); do { while (true) { if ((__old_state & __stop_requested_flag_) != 0) { return false; } else if (__old_state == 0) { break; } else { __spin.__wait(); __old_state = __state_.load(std::memory_order_relaxed); } } } while (!__state_.compare_exchange_weak( __old_state, __set_stop_requested ? (__locked_flag_ | __stop_requested_flag_) : __locked_flag_, std::memory_order_acq_rel, std::memory_order_relaxed)); return true; } inline bool in_place_stop_source::__try_add_callback_( __stok::__in_place_stop_callback_base* __callbk) const noexcept { if (!__try_lock_unless_stop_requested_(false)) { return false; } __callbk->__next_ = __callbacks_; __callbk->__prev_ptr_ = &__callbacks_; if (__callbacks_ != nullptr) { __callbacks_->__prev_ptr_ = &__callbk->__next_; } __callbacks_ = __callbk; __unlock_(0); return true; } inline void in_place_stop_source::__remove_callback_( __stok::__in_place_stop_callback_base* __callbk) const noexcept { auto __old_state = __lock_(); if (__callbk->__prev_ptr_ != nullptr) { *__callbk->__prev_ptr_ = __callbk->__next_; if (__callbk->__next_ != nullptr) { __callbk->__next_->__prev_ptr_ = __callbk->__prev_ptr_; } __unlock_(__old_state); } else { auto __notifying_thread = __notifying_thread_; __unlock_(__old_state); if (std::this_thread::get_id() == __notifying_thread) { if (__callbk->__removed_during_callback_ != nullptr) { *__callbk->__removed_during_callback_ = true; } } else { __stok::__spin_wait __spin; while (!__callbk->__callback_completed_.load(std::memory_order_acquire)) { __spin.__wait(); } } } } template <class _Token> concept stoppable_token = copy_constructible<_Token> && move_constructible<_Token> && std::is_nothrow_copy_constructible_v<_Token> && std::is_nothrow_move_constructible_v<_Token> && equality_comparable<_Token> && requires(const _Token& __token) { { __token.stop_requested() } noexcept -> __boolean_testable_; { __token.stop_possible() } noexcept -> __boolean_testable_; typename __stok::__check_type_alias_exists<_Token::template callback_type>; }; template <class _Token, typename _Callback, typename _Initializer = _Callback> concept stoppable_token_for = stoppable_token<_Token> && __callable<_Callback> && requires { typename _Token::template callback_type<_Callback>; } && constructible_from<_Callback, _Initializer> && constructible_from< typename _Token::template callback_type<_Callback>, _Token, _Initializer> && constructible_from< typename _Token::template callback_type<_Callback>, _Token&, _Initializer> && constructible_from< typename _Token::template callback_type<_Callback>, const _Token, _Initializer> && constructible_from< typename _Token::template callback_type<_Callback>, const _Token&, _Initializer>; template <class _Token> concept unstoppable_token = stoppable_token<_Token> && requires { { _Token::stop_possible() } -> __boolean_testable_; } && (!_Token::stop_possible()); } namespace stdexec { template <class T> concept queryable = destructible<T>; template <class Tag> struct __query { template <class Sig> static inline constexpr Tag (*signature)(Sig) = nullptr; }; namespace __queries { struct forwarding_query_t { template <class _Query> constexpr bool operator()(_Query __query) const noexcept { if constexpr (tag_invocable<forwarding_query_t, _Query>) { return tag_invoke(*this, (_Query&&) __query); } else if constexpr (std::derived_from<_Query, forwarding_query_t>) { return true; } else { return false; } } }; struct query_or_t { template <class _Query, class _Queryable, class _Default> constexpr auto operator()(_Query, _Queryable&&, _Default&& __default) const noexcept(__nothrow_constructible_from<_Default, _Default&&>) -> _Default { return (_Default&&) __default; } template <class _Query, class _Queryable, class _Default> requires __callable<_Query, _Queryable> constexpr auto operator()(_Query __query, _Queryable&& __queryable, _Default&&) const noexcept(__nothrow_callable<_Query, _Queryable>) -> __call_result_t<_Query, _Queryable> { return ((_Query&&) __query)((_Queryable&&) __queryable); } }; struct execute_may_block_caller_t : __query<execute_may_block_caller_t> { template <class _Tp> requires tag_invocable<execute_may_block_caller_t, __cref_t<_Tp>> constexpr bool operator()(_Tp&& __t) const noexcept { static_assert( same_as<bool, tag_invoke_result_t<execute_may_block_caller_t, __cref_t<_Tp>>>); static_assert(nothrow_tag_invocable<execute_may_block_caller_t, __cref_t<_Tp>>); return tag_invoke(execute_may_block_caller_t{}, std::as_const(__t)); } constexpr bool operator()(auto&&) const noexcept { return true; } }; struct get_forward_progress_guarantee_t : __query<get_forward_progress_guarantee_t> { template <class _Tp> requires tag_invocable<get_forward_progress_guarantee_t, __cref_t<_Tp>> constexpr auto operator()(_Tp&& __t) const noexcept(nothrow_tag_invocable<get_forward_progress_guarantee_t, __cref_t<_Tp>>) -> tag_invoke_result_t<get_forward_progress_guarantee_t, __cref_t<_Tp>> { return tag_invoke(get_forward_progress_guarantee_t{}, std::as_const(__t)); } constexpr stdexec::forward_progress_guarantee operator()(auto&&) const noexcept { return stdexec::forward_progress_guarantee::weakly_parallel; } }; struct __has_algorithm_customizations_t : __query<__has_algorithm_customizations_t> { template <class _Tp> using __result_t = tag_invoke_result_t<__has_algorithm_customizations_t, __cref_t<_Tp>>; template <class _Tp> requires tag_invocable<__has_algorithm_customizations_t, __cref_t<_Tp>> constexpr __result_t<_Tp> operator()(_Tp&&) const noexcept(noexcept(__result_t<_Tp>{})) { using _Boolean = tag_invoke_result_t<__has_algorithm_customizations_t, __cref_t<_Tp>>; static_assert(_Boolean{} ? true : true); return _Boolean{}; } constexpr std::false_type operator()(auto&&) const noexcept { return {}; } }; template <class _T0> concept __allocator = true; struct get_scheduler_t : __query<get_scheduler_t> { friend constexpr bool tag_invoke(forwarding_query_t, const get_scheduler_t&) noexcept { return true; } template <class _Env> requires tag_invocable<get_scheduler_t, const _Env&> auto operator()(const _Env& __env) const noexcept -> tag_invoke_result_t<get_scheduler_t, const _Env&>; auto operator()() const noexcept; }; struct get_delegatee_scheduler_t : __query<get_delegatee_scheduler_t> { friend constexpr bool tag_invoke(forwarding_query_t, const get_delegatee_scheduler_t&) noexcept { return true; } template <class _Env> requires tag_invocable<get_delegatee_scheduler_t, const _Env&> auto operator()(const _Env& __t) const noexcept -> tag_invoke_result_t<get_delegatee_scheduler_t, const _Env&>; auto operator()() const noexcept; }; struct get_allocator_t : __query<get_allocator_t> { friend constexpr bool tag_invoke(forwarding_query_t, const get_allocator_t&) noexcept { return true; } template <class _Env> requires tag_invocable<get_allocator_t, const _Env&> auto operator()(const _Env& __env) const noexcept -> tag_invoke_result_t<get_allocator_t, const _Env&> { static_assert(nothrow_tag_invocable<get_allocator_t, const _Env&>); static_assert(__allocator<tag_invoke_result_t<get_allocator_t, const _Env&>>); return tag_invoke(get_allocator_t{}, __env); } auto operator()() const noexcept; }; struct get_stop_token_t : __query<get_stop_token_t> { friend constexpr bool tag_invoke(forwarding_query_t, const get_stop_token_t&) noexcept { return true; } template <class _Env> never_stop_token operator()(const _Env&) const noexcept { return {}; } template <class _Env> requires tag_invocable<get_stop_token_t, const _Env&> auto operator()(const _Env& __env) const noexcept -> tag_invoke_result_t<get_stop_token_t, const _Env&> { static_assert(nothrow_tag_invocable<get_stop_token_t, const _Env&>); static_assert(stoppable_token<tag_invoke_result_t<get_stop_token_t, const _Env&>>); return tag_invoke(get_stop_token_t{}, __env); } auto operator()() const noexcept; }; template <class _Queryable, class _CPO> concept __has_completion_scheduler_for = queryable<_Queryable> && tag_invocable<get_completion_scheduler_t<_CPO>, const _Queryable&>; template <__completion_tag _CPO> struct get_completion_scheduler_t : __query<get_completion_scheduler_t<_CPO>> { friend constexpr bool tag_invoke(forwarding_query_t, const get_completion_scheduler_t<_CPO>&) noexcept { return true; } template <__has_completion_scheduler_for<_CPO> _Queryable> auto operator()(const _Queryable& __queryable) const noexcept -> tag_invoke_result_t<get_completion_scheduler_t<_CPO>, const _Queryable&>; }; template <class _Base = __none_such> struct __default_domain { template <class _Sender, class _Env = empty_env> static _Sender transform_sender(_Sender&& __sndr, const _Env& = {}) { return static_cast<_Sender&&>(__sndr); } operator _Base() const { return __base_; } [[no_unique_address]] _Base __base_; }; template <class _Base> __default_domain(_Base) -> __default_domain<_Base>; struct get_domain_t { template <class _Ty> requires tag_invocable<get_domain_t, const _Ty&> constexpr auto operator()(const _Ty& __ty) const noexcept -> tag_invoke_result_t<get_domain_t, const _Ty&> { static_assert( nothrow_tag_invocable<get_domain_t, const _Ty&>, "Customizations of get_domain must be noexcept."); static_assert( __class<tag_invoke_result_t<get_domain_t, const _Ty&>>, "Customizations of get_domain must return a class type."); return tag_invoke(get_domain_t{}, __ty); } friend constexpr bool tag_invoke(forwarding_query_t, get_domain_t) noexcept { return true; } }; } using __queries::forwarding_query_t; using __queries::query_or_t; using __queries::execute_may_block_caller_t; using __queries::__has_algorithm_customizations_t; using __queries::get_forward_progress_guarantee_t; using __queries::get_allocator_t; using __queries::get_scheduler_t; using __queries::get_delegatee_scheduler_t; using __queries::get_stop_token_t; using __queries::get_completion_scheduler_t; using __queries::__default_domain; using __queries::get_domain_t; inline constexpr forwarding_query_t forwarding_query{}; inline constexpr query_or_t query_or{}; inline constexpr execute_may_block_caller_t execute_may_block_caller{}; inline constexpr __has_algorithm_customizations_t __has_algorithm_customizations{}; inline constexpr get_forward_progress_guarantee_t get_forward_progress_guarantee{}; inline constexpr get_scheduler_t get_scheduler{}; inline constexpr get_delegatee_scheduler_t get_delegatee_scheduler{}; inline constexpr get_allocator_t get_allocator{}; inline constexpr get_stop_token_t get_stop_token{}; template <> inline constexpr get_completion_scheduler_t<set_value_t> get_completion_scheduler<set_value_t>{}; template <> inline constexpr get_completion_scheduler_t<set_error_t> get_completion_scheduler<set_error_t>{}; template <> inline constexpr get_completion_scheduler_t<set_stopped_t> get_completion_scheduler<set_stopped_t>{}; template <class _Tag> concept __forwarding_query = forwarding_query(_Tag{}); inline constexpr get_domain_t get_domain{}; template <class _Tag, class _Queryable, class _Default> using __query_result_or_t = __call_result_t<query_or_t, _Tag, _Queryable, _Default>; namespace __queries { struct get_scheduler_t; struct get_stop_token_t; } using __queries::get_scheduler_t; using __queries::get_stop_token_t; extern const get_scheduler_t get_scheduler; extern const get_stop_token_t get_stop_token; namespace __env { struct no_env { using __t = no_env; using __id = no_env; template <class _Tag, same_as<no_env> _Self, class... _Ts> friend void tag_invoke(_Tag, _Self, _Ts&&...) = delete; }; struct empty_env { using __t = empty_env; using __id = empty_env; }; template <class _Tag> struct __deleted { }; template <__nothrow_move_constructible _Fun> struct __env_fn { using __t = __env_fn; using __id = __env_fn; [[no_unique_address]] _Fun __fun_; template <class _Tag> requires __callable<const _Fun&, _Tag> friend auto tag_invoke(_Tag, const __env_fn& __self) noexcept(__nothrow_callable<const _Fun&, _Tag>) -> __call_result_t<const _Fun&, _Tag> { return __self.__fun_(_Tag()); } }; template <class _Fun> __env_fn(_Fun) -> __env_fn<_Fun>; template <class _Env> struct __env_fwd { static_assert(__nothrow_move_constructible<_Env>); using __t = __env_fwd; using __id = __env_fwd; [[no_unique_address]] _Env __env_; template <__forwarding_query _Tag> requires tag_invocable<_Tag, const _Env&> friend auto tag_invoke(_Tag, const __env_fwd& __self) noexcept(nothrow_tag_invocable<_Tag, const _Env&>) -> tag_invoke_result_t<_Tag, const _Env&> { return _Tag()(__self.__env_); } }; template <class _Env, class _Base = empty_env> struct __joined_env : __env_fwd<_Base> { static_assert(__nothrow_move_constructible<_Env>); using __t = __joined_env; using __id = __joined_env; [[no_unique_address]] _Env __env_; const _Base& base() const noexcept { return this->__env_fwd<_Base>::__env_; } template <class _Tag> requires tag_invocable<_Tag, const _Env&> friend auto tag_invoke(_Tag, const __joined_env& __self) noexcept(nothrow_tag_invocable<_Tag, const _Env&>) -> tag_invoke_result_t<_Tag, const _Env&> { return _Tag()(__self.__env_); } }; template <class _Tag, class _Base> struct __joined_env<__env_fn<__deleted<_Tag>>, _Base> : __env_fwd<_Base> { using __t = __joined_env; using __id = __joined_env; [[no_unique_address]] __env_fn<__deleted<_Tag>> __env_; friend void tag_invoke(_Tag, const __joined_env&) noexcept = delete; }; struct __join_env_t { template <class _Env> _Env operator()(_Env&& __env) const noexcept { return (_Env&&) __env; } template <class _Env, class _Base> decltype(auto) operator()(_Env&& __env, _Base&& __base) const noexcept { using __env_t = __decay_t<_Env>; using __base_t = __decay_t<_Base>; if constexpr (__one_of<no_env, __env_t, __base_t>) { return no_env(); } else if constexpr (__same_as<__env_t, empty_env>) { return _Base((_Base&&) __base); } else if constexpr (__same_as<__base_t, empty_env>) { return _Env((_Env&&) __env); } else { return __joined_env<_Env, _Base>{{(_Base&&) __base}, (_Env&&) __env}; } } template <class _Env0, class _Env1, class _Env2, class... _Envs> decltype(auto) operator()(_Env0&& __env0, _Env1&& __env1, _Env2&& __env2, _Envs&&... __envs) const noexcept { const auto& __join_env = *this; return __join_env( (_Env0&&) __env0, __join_env((_Env1&&) __env1, __join_env((_Env2&&) __env2, (_Envs&&) __envs...))); } }; template <class... _Envs> using __env_join_t = __call_result_t<__join_env_t, _Envs...>; template <class _Env> struct __env_promise { template <class _Ty> _Ty&& await_transform(_Ty&& __value) noexcept { return (_Ty&&) __value; } template <class _Ty> requires tag_invocable<as_awaitable_t, _Ty, __env_promise&> auto await_transform(_Ty&& __value) noexcept(nothrow_tag_invocable<as_awaitable_t, _Ty, __env_promise&>) -> tag_invoke_result_t<as_awaitable_t, _Ty, __env_promise&> { return tag_invoke(as_awaitable, (_Ty&&) __value, *this); } friend auto tag_invoke(get_env_t, const __env_promise&) noexcept -> const _Env&; }; template <class _Tag, __nothrow_move_constructible _Value> constexpr auto __with_(_Tag, _Value __val) noexcept { return __env_fn{ [__val = std::move(__val)](_Tag) noexcept(__nothrow_copy_constructible<_Value>) { return __val; }}; } template <class _Tag> __env_fn<__deleted<_Tag>> __with_(_Tag) noexcept { return {}; } template <class... _Ts> using __with = decltype(__env::__with_(__declval<_Ts>()...)); struct __make_env_t { template <__nothrow_move_constructible _Base, __nothrow_move_constructible _Env> auto operator()(_Base&& __base, _Env&& __env) const noexcept -> __env_join_t<_Env, _Base> { return __join_env_t()((_Env&&) __env, (_Base&&) __base); } template <__nothrow_move_constructible _Env> _Env operator()(_Env&& __env) const noexcept { return (_Env&&) __env; } }; struct get_env_t { template <class _EnvProvider> requires tag_invocable<get_env_t, const _EnvProvider&> constexpr auto operator()(const _EnvProvider& __with_env) const noexcept -> tag_invoke_result_t<get_env_t, const _EnvProvider&> { static_assert(queryable<tag_invoke_result_t<get_env_t, const _EnvProvider&> >); static_assert(nothrow_tag_invocable<get_env_t, const _EnvProvider&>); return tag_invoke(*this, __with_env); } template <class _EnvProvider> constexpr decltype(auto) operator()(const _EnvProvider& __with_env) const noexcept { if constexpr (!enable_sender<_EnvProvider>) { return __with_env; } else { return empty_env{}; } } }; } using __env::no_env; using __env::empty_env; using __empty_env [[deprecated("Please use stdexec::empty_env now.")]] = empty_env; using __env::__with; using __env::__with_; using __env::__env_promise; using no_env_promise = __env_promise<no_env>; inline constexpr __env::__make_env_t __make_env{}; inline constexpr __env::__join_env_t __join_env{}; inline constexpr __env::get_env_t get_env{}; template <class... _Ts> using __make_env_t = __call_result_t<__env::__make_env_t, _Ts...>; using __default_env = no_env; template <class _EnvProvider> concept environment_provider = requires(_EnvProvider& __ep) { { get_env(std::as_const(__ep)) } -> queryable; { get_env(std::as_const(__ep)) } -> __none_of<no_env, void>; }; inline constexpr struct __get_sender_domain_t { template <class _Sender, class _Tag = set_value_t> auto operator()(const _Sender& __sndr, _Tag = {}) const noexcept { auto __sched = query_or(get_completion_scheduler<_Tag>, get_env(__sndr), empty_env()); auto __env = __join_env(get_env(__sndr), __sched); return query_or(get_domain, __env, __default_domain{__sched}); } } __get_sender_domain{}; template <class _Sender, class _Tag = set_value_t> using __sender_domain_of_t = __call_result_t<__get_sender_domain_t, _Sender, _Tag>; inline constexpr struct __get_env_domain_t { template <class _Env, class _Sender> auto operator()(const _Env& __env, const _Sender& ) const noexcept { auto __sched = query_or(get_scheduler, __env, empty_env()); auto __env2 = __join_env(__env, __sched); return query_or(get_domain, __env2, __default_domain()); } } __get_env_domain{}; template <class _Env, class _Sender> using __env_domain_of_t = __call_result_t<__get_env_domain_t, _Env, _Sender>; namespace __receivers { struct set_value_t { template <class _Fn, class... _Args> using __f = __minvoke<_Fn, _Args...>; template <class _Receiver, class... _As> requires tag_invocable<set_value_t, _Receiver, _As...> void operator()(_Receiver&& __rcvr, _As&&... __as) const noexcept { static_assert(nothrow_tag_invocable<set_value_t, _Receiver, _As...>); (void) tag_invoke(set_value_t{}, (_Receiver&&) __rcvr, (_As&&) __as...); } }; struct set_error_t { template <class _Fn, class... _Args> requires(sizeof...(_Args) == 1) using __f = __minvoke<_Fn, _Args...>; template <class _Receiver, class _Error> requires tag_invocable<set_error_t, _Receiver, _Error> void operator()(_Receiver&& __rcvr, _Error&& __err) const noexcept { static_assert(nothrow_tag_invocable<set_error_t, _Receiver, _Error>); (void) tag_invoke(set_error_t{}, (_Receiver&&) __rcvr, (_Error&&) __err); } }; struct set_stopped_t { template <class _Fn, class... _Args> requires(sizeof...(_Args) == 0) using __f = __minvoke<_Fn, _Args...>; template <class _Receiver> requires tag_invocable<set_stopped_t, _Receiver> void operator()(_Receiver&& __rcvr) const noexcept { static_assert(nothrow_tag_invocable<set_stopped_t, _Receiver>); (void) tag_invoke(set_stopped_t{}, (_Receiver&&) __rcvr); } }; } using __receivers::set_value_t; using __receivers::set_error_t; using __receivers::set_stopped_t; inline constexpr set_value_t set_value{}; inline constexpr set_error_t set_error{}; inline constexpr set_stopped_t set_stopped{}; inline constexpr struct __try_call_t { template <class _Receiver, class _Fun, class... _Args> requires __callable<_Fun, _Args...> void operator()(_Receiver&& __rcvr, _Fun __fun, _Args&&... __args) const noexcept { if constexpr (__nothrow_callable<_Fun, _Args...>) { ((_Fun&&) __fun)((_Args&&) __args...); } else { try { ((_Fun&&) __fun)((_Args&&) __args...); } catch (...) { set_error((_Receiver&&) __rcvr, std::current_exception()); } } } } __try_call{}; namespace __compl_sigs { template <same_as<set_value_t> _Tag, class _Ty = __q<__types>, class... _Args> __types<__minvoke<_Ty, _Args...>> __test(_Tag (*)(_Args...)); template <same_as<set_error_t> _Tag, class _Ty = __q<__types>, class _Error> __types<__minvoke<_Ty, _Error>> __test(_Tag (*)(_Error)); template <same_as<set_stopped_t> _Tag, class _Ty = __q<__types>> __types<__minvoke<_Ty>> __test(_Tag (*)()); template <class, class = void> __types<> __test(...); template <class _Tag, class _Ty = void, class... _Args> void __test(_Tag (*)(_Args...) noexcept) = delete; struct __dependent { }; template <class _Sig> concept __completion_signature = __typename<decltype(__compl_sigs::__test((_Sig*) nullptr))>; template <class _Sig, class _Tag, class _Ty = __q<__types>> using __signal_args_t = decltype(__compl_sigs::__test<_Tag, _Ty>((_Sig*) nullptr)); } using __compl_sigs::__completion_signature; template <same_as<no_env>> using dependent_completion_signatures = __compl_sigs::__dependent; template <__compl_sigs::__completion_signature... _Sigs> struct completion_signatures { }; namespace __compl_sigs { template <class _TaggedTuple, __completion_tag _Tag, class... _Ts> auto __as_tagged_tuple_(_Tag (*)(_Ts...), _TaggedTuple*) -> __mconst<__minvoke<_TaggedTuple, _Tag, _Ts...>>; template <class _Sig, class _TaggedTuple> using __as_tagged_tuple = decltype(__compl_sigs::__as_tagged_tuple_((_Sig*) nullptr, (_TaggedTuple*) nullptr)); template <class _TaggedTuple, class _Variant, class... _Sigs> auto __for_all_sigs_(completion_signatures<_Sigs...>*, _TaggedTuple*, _Variant*) -> __mconst< __minvoke< _Variant, __minvoke<__as_tagged_tuple<_Sigs, _TaggedTuple>>...>>; template <class _Completions, class _TaggedTuple, class _Variant> using __for_all_sigs = __minvoke< decltype(__compl_sigs::__for_all_sigs_( (_Completions*) nullptr, (_TaggedTuple*) nullptr, (_Variant*) nullptr))>; template <class _Completions, class _TaggedTuple, class _Variant> using __maybe_for_all_sigs = __meval<__for_all_sigs, _Completions, _TaggedTuple, _Variant>; } template <class _Ty> concept __is_completion_signatures = __is_instance_of<_Ty, completion_signatures>; template <class...> auto __concat_completion_signatures_impl() -> dependent_completion_signatures<no_env>; template <__is_completion_signatures... _Completions> auto __concat_completion_signatures_impl() -> __minvoke< __mconcat<__munique<__q<completion_signatures>>>, _Completions...>; template <class... _Completions> using __concat_completion_signatures_impl_t = decltype(__concat_completion_signatures_impl<_Completions...>()); template <class... _Completions> struct __concat_completion_signatures_ { using __t = __meval<__concat_completion_signatures_impl_t, _Completions...>; }; template <class... _Completions> using __concat_completion_signatures_t = __t<__concat_completion_signatures_<_Completions...>>; template <class _Completions, class _Env> inline constexpr bool __expecting_completion_signatures = false; template <class... _Sigs, class _Env> inline constexpr bool __expecting_completion_signatures<completion_signatures<_Sigs...>, _Env> = true; template <> inline constexpr bool __expecting_completion_signatures<dependent_completion_signatures<no_env>, no_env> = true; template <class _Completions, class _Env> concept __valid_completion_signatures = __expecting_completion_signatures<_Completions, _Env>; template <class _Receiver> struct _WITH_RECEIVER_ { }; template <class _Sig> struct _MISSING_COMPLETION_SIGNAL_ { }; template <class _Receiver, class _Tag, class... _Args> auto __try_completion(_Tag (*)(_Args...)) -> __mexception<_MISSING_COMPLETION_SIGNAL_<_Tag(_Args...)>, _WITH_RECEIVER_<_Receiver>>; template <class _Receiver, class _Tag, class... _Args> requires nothrow_tag_invocable<_Tag, _Receiver, _Args...> __msuccess __try_completion(_Tag (*)(_Args...)); template <class _Receiver, class... _Sigs> auto __try_completions(completion_signatures<_Sigs...>*) -> decltype((__msuccess(), ..., stdexec::__try_completion<_Receiver>((_Sigs*) nullptr))); struct __receiver_base { }; template <class _Receiver> concept __enable_receiver = requires { typename _Receiver::is_receiver; } || __is_base_of(__receiver_base, _Receiver); template <class _Receiver> inline constexpr bool enable_receiver = __enable_receiver<_Receiver>; template <class _Receiver> concept __receiver_r5_or_r7 = enable_receiver<_Receiver> || tag_invocable<get_env_t, _Receiver>; template <class _Receiver> concept __receiver = requires { requires __receiver_r5_or_r7<__decay_t<_Receiver>>; }; template <class _Receiver> concept receiver = __receiver<_Receiver> && environment_provider<__cref_t<_Receiver>> && move_constructible<__decay_t<_Receiver>> && constructible_from<__decay_t<_Receiver>, _Receiver>; template <class _Receiver, class _Completions> concept receiver_of = receiver<_Receiver> && requires(_Completions* __completions) { { stdexec::__try_completions<__decay_t<_Receiver>>(__completions) } -> __ok; }; template <class _Receiver, class _Sender> concept __receiver_from = receiver_of< _Receiver, __completion_signatures_of_t<_Sender, env_of_t<_Receiver>>>; namespace __debug { struct __is_debug_env_t { friend constexpr bool tag_invoke(forwarding_query_t, const __is_debug_env_t&) noexcept { return true; } template <class _Env> requires tag_invocable<__is_debug_env_t, const _Env&> auto operator()(const _Env&) const noexcept -> tag_invoke_result_t<__is_debug_env_t, const _Env&>; }; template <class _Env> using __debug_env_t = __make_env_t<_Env, __with<__is_debug_env_t, bool>>; template <class _Env> concept __is_debug_env = tag_invocable<__debug::__is_debug_env_t, _Env>; struct __completion_signatures { }; template <class _Sig> extern int __normalize_sig; template <class _Tag, class... _Args> extern _Tag (*__normalize_sig<_Tag(_Args...)>)(_Args&&...); template <class _Sig> using __normalize_sig_t = decltype(__normalize_sig<_Sig>); template <class... _Sigs> struct __valid_completions { template <derived_from<__valid_completions> _Self, class _Tag, class... _Args> requires __one_of<_Tag (*)(_Args&&...), _Sigs...> friend void tag_invoke(_Tag, _Self&&, _Args&&...) noexcept { std::terminate(); } }; template <class _CvrefSenderId, class _Env, class _Completions> struct __debug_receiver { using __t = __debug_receiver; using __id = __debug_receiver; using is_receiver = void; }; template <class _CvrefSenderId, class _Env, class... _Sigs> struct __debug_receiver<_CvrefSenderId, _Env, completion_signatures<_Sigs...>> : __valid_completions<__normalize_sig_t<_Sigs>...> { using __t = __debug_receiver; using __id = __debug_receiver; using is_receiver = void; template <same_as<get_env_t> _Tag> friend __debug_env_t<_Env> tag_invoke(_Tag, __debug_receiver) noexcept { std::terminate(); } }; struct _COMPLETION_SIGNATURES_MISMATCH_ { }; template <class _Sig> struct _COMPLETION_SIGNATURE_ { }; template <class... _Sigs> struct _IS_NOT_ONE_OF_ { }; template <class _Sender> struct _SIGNAL_SENT_BY_SENDER_ { }; template <class _Warning> [[deprecated( "The sender claims to send a particular set of completions," " but in actual fact it completes with a result that is not" " one of the declared completion signatures.")]] void _ATTENTION_() noexcept { } template <class _Sig> struct __invalid_completion { struct __t { template <class _CvrefSenderId, class _Env, class... _Sigs> __t(__debug_receiver<_CvrefSenderId, _Env, completion_signatures<_Sigs...>>&&) noexcept { using _SenderId = __decay_t<_CvrefSenderId>; using _Sender = stdexec::__t<_SenderId>; using _What = _WARNING_< _COMPLETION_SIGNATURES_MISMATCH_, _COMPLETION_SIGNATURE_<_Sig>, _IS_NOT_ONE_OF_<_Sigs...>, _SIGNAL_SENT_BY_SENDER_<_Sender>>; __debug::_ATTENTION_<_What>(); } }; }; template <__completion_tag _Tag, class... _Args> void tag_invoke(_Tag, __t<__invalid_completion<_Tag(_Args...)>>, _Args&&...) noexcept { } struct __debug_operation { template <same_as<start_t> _Tag> friend void tag_invoke(_Tag, __debug_operation&) noexcept { } }; template <class _Sigs, class _Env = empty_env, class _Sender> void __debug_sender(_Sender&& __sndr, const _Env& = {}) { if constexpr (!__is_debug_env<_Env> && !same_as<_Env, no_env>) { if (sizeof(_Sender) == ~0) { using _Receiver = __debug_receiver<__cvref_id<_Sender>, _Env, _Sigs>; using _Operation = connect_result_t<_Sender, _Receiver>; if constexpr (!same_as<_Operation, __debug_operation>) { auto __op = connect((_Sender&&) __sndr, _Receiver{}); start(__op); } } } } template <class _Env = empty_env, class _Sender> void __debug_sender(_Sender&& __sndr, const _Env& = {}) { if constexpr (!__is_debug_env<_Env> && !same_as<_Env, no_env>) { if (sizeof(_Sender) == ~0) { using _Sigs = __completion_signatures_of_t<_Sender, __debug_env_t<_Env>>; if constexpr (!same_as<_Sigs, __debug::__completion_signatures>) { using _Receiver = __debug_receiver<__cvref_id<_Sender>, _Env, _Sigs>; using _Operation = connect_result_t<_Sender, _Receiver>; if constexpr (!same_as<_Operation, __debug_operation>) { auto __op = connect((_Sender&&) __sndr, _Receiver{}); start(__op); } } } } } } using __debug::__is_debug_env; using __debug::__debug_sender; namespace __queries { struct get_scheduler_t; } using __queries::get_scheduler_t; extern const get_scheduler_t get_scheduler; inline constexpr struct sender_transform_t { template <class _Value, class _Env = no_env> constexpr decltype(auto) operator()(_Value&& __val, const _Env& __env = {}) const { auto __domain = __get_env_domain(__env, __val); return __domain.transform_sender((_Value&&) __val, __env); } } sender_transform{}; template <class _Value, class _Env = no_env> using sender_transform_result_t = __call_result_t<sender_transform_t, _Value, _Env>; namespace __get_completion_signatures { template <class _Sender, class _Env> concept __r7_style_sender = same_as<_Env, no_env> && enable_sender<__decay_t<_Sender>>; template <class _Sender, class _Env> concept __with_tag_invoke = tag_invocable< get_completion_signatures_t, sender_transform_result_t<_Sender, _Env>, _Env>; template <class _Sender, class _Env> using __member_alias_t = typename __decay_t<sender_transform_result_t<_Sender, _Env>>::completion_signatures; template <class _Sender, class _Env = no_env> concept __with_member_alias = __valid<__member_alias_t, _Sender, _Env>; struct get_completion_signatures_t { template <class _Sender, class _Env> static auto __impl() { static_assert(1 || !same_as<_Env, no_env>); static_assert(sizeof(_Sender), "Incomplete type used with get_completion_signatures"); static_assert(sizeof(_Env), "Incomplete type used with get_completion_signatures"); if constexpr (__with_tag_invoke<_Sender, _Env>) { using _Result = tag_invoke_result_t<get_completion_signatures_t, _Sender, _Env>; if constexpr (same_as<_Env, no_env> && __merror<_Result>) { return (dependent_completion_signatures<no_env>(*)()) nullptr; } else { return (_Result(*)()) nullptr; } } else if constexpr (__with_member_alias<_Sender, _Env>) { return (__member_alias_t<_Sender, _Env>(*)()) nullptr; } else if constexpr (__awaitable<_Sender, __env_promise<_Env>>) { using _Result = __await_result_t<_Sender, __env_promise<_Env>>; if constexpr (same_as<_Result, dependent_completion_signatures<no_env>>) { return (dependent_completion_signatures<no_env>(*)()) nullptr; } else { return (completion_signatures< __minvoke<__remove<void, __qf<set_value_t>>, _Result>, set_error_t(std::exception_ptr), set_stopped_t()>(*)()) nullptr; } } else if constexpr (__r7_style_sender<_Sender, _Env>) { return (dependent_completion_signatures<no_env>(*)()) nullptr; } else if constexpr (__is_debug_env<_Env>) { using __tag_invoke::tag_invoke; using _Completions [[maybe_unused]] = tag_invoke_result_t<get_completion_signatures_t, _Sender, _Env>; return (__debug::__completion_signatures(*)()) nullptr; } else { return (void (*)()) nullptr; } } template <class _Sender, class _Env = __default_env> requires( __with_tag_invoke<_Sender, _Env> || __with_member_alias<_Sender, _Env> || __awaitable<_Sender, __env_promise<_Env>> || __r7_style_sender<_Sender, _Env> || __is_debug_env<_Env>) constexpr auto operator()(_Sender&&, const _Env&) const noexcept -> decltype(__impl<_Sender, _Env>()()) { return {}; } }; } using __get_completion_signatures::get_completion_signatures_t; inline constexpr get_completion_signatures_t get_completion_signatures{}; template <class _Sender> concept __enable_sender = requires { typename _Sender::is_sender; } || __awaitable<_Sender, __env_promise<empty_env>>; template <class _Sender> inline constexpr bool enable_sender = __enable_sender<_Sender>; template <class _Sender, class _Env = no_env> concept __sender_like = requires(_Sender&& __sndr, _Env&& __env) { get_completion_signatures((_Sender&&) __sndr, (_Env&&) __env); } && __valid_completion_signatures<__completion_signatures_of_t<_Sender, _Env>, _Env>; template <class _Sender, class _Env = no_env> concept sender = __sender_like<_Sender> && __sender_like<_Sender, _Env> && environment_provider<__cref_t<_Sender>> && move_constructible<__decay_t<_Sender>> && constructible_from<__decay_t<_Sender>, _Sender>; template <class _Sender, class _Env = empty_env> concept sender_in = __sender_like<_Sender, _Env> && sender<_Sender, _Env>; template <class _Sender, class _Env> auto __checked_completion_signatures(_Sender&& __sndr, const _Env& __env) noexcept { using _WithEnv = __completion_signatures_of_t<_Sender, _Env>; stdexec::__debug_sender<_WithEnv>((_Sender&&) __sndr, __env); return _WithEnv{}; } template <class _Sender, class _Env = no_env> requires sender_in<_Sender, _Env> using completion_signatures_of_t = decltype(stdexec::__checked_completion_signatures(__declval<_Sender>(), __declval<_Env>())); struct __not_a_variant { __not_a_variant() = delete; }; template <class... _Ts> using __variant = __minvoke< __if_c< sizeof...(_Ts) != 0, __transform<__q<__decay_t>, __munique<__q<std::variant>>>, __mconst<__not_a_variant>>, _Ts...>; using __nullable_variant_t = __munique<__mbind_front_q<std::variant, std::monostate>>; template <class... _Ts> using __decayed_tuple = __meval<std::tuple, __decay_t<_Ts>...>; template <class _Tag, class _Tuple> struct __select_completions_for { template <same_as<_Tag> _Tag2, class... _Args> using __f = __minvoke<_Tag2, _Tuple, _Args...>; }; template <class _Tuple> struct __invoke_completions { template <class _Tag, class... _Args> using __f = __minvoke<_Tag, _Tuple, _Args...>; }; template <class _Tag, class _Tuple> using __select_completions_for_or = __with_default< __select_completions_for<_Tag, _Tuple>, __>; template <class _Tag, class _Completions> using __only_gather_signal = __compl_sigs::__maybe_for_all_sigs< _Completions, __select_completions_for_or<_Tag, __qf<_Tag>>, __remove<__, __q<completion_signatures>>>; template <class _Tag, class _Completions, class _Tuple, class _Variant> using __gather_signal = __compl_sigs::__maybe_for_all_sigs< __only_gather_signal<_Tag, _Completions>, __invoke_completions<_Tuple>, _Variant>; template <class _Tag, class _Sender, class _Env, class _Tuple, class _Variant> using __gather_completions_for = __meval< __gather_signal, _Tag, __completion_signatures_of_t<_Sender, _Env>, _Tuple, _Variant>; template < class _Sender, class _Env = __default_env, class _Tuple = __q<__decayed_tuple>, class _Variant = __q<__variant>> using __try_value_types_of_t = __gather_completions_for<set_value_t, _Sender, _Env, _Tuple, _Variant>; template < class _Sender, class _Env = __default_env, class _Tuple = __q<__decayed_tuple>, class _Variant = __q<__variant>> requires sender_in<_Sender, _Env> using __value_types_of_t = __msuccess_or_t<__try_value_types_of_t<_Sender, _Env, _Tuple, _Variant>>; template <class _Sender, class _Env = __default_env, class _Variant = __q<__variant>> using __try_error_types_of_t = __gather_completions_for<set_error_t, _Sender, _Env, __q<__midentity>, _Variant>; template <class _Sender, class _Env = __default_env, class _Variant = __q<__variant>> requires sender_in<_Sender, _Env> using __error_types_of_t = __msuccess_or_t<__try_error_types_of_t<_Sender, _Env, _Variant>>; template < class _Sender, class _Env = __default_env, template <class...> class _Tuple = __decayed_tuple, template <class...> class _Variant = __variant> requires sender_in<_Sender, _Env> using value_types_of_t = __value_types_of_t<_Sender, _Env, __q<_Tuple>, __q<_Variant>>; template <class _Sender, class _Env = __default_env, template <class...> class _Variant = __variant> requires sender_in<_Sender, _Env> using error_types_of_t = __error_types_of_t<_Sender, _Env, __q<_Variant>>; template <class _Tag, class _Sender, class _Env = __default_env> using __try_count_of = __compl_sigs::__maybe_for_all_sigs< __completion_signatures_of_t<_Sender, _Env>, __q<__mfront>, __mcount<_Tag>>; template <class _Tag, class _Sender, class _Env = __default_env> requires sender_in<_Sender, _Env> using __count_of = __msuccess_or_t<__try_count_of<_Tag, _Sender, _Env>>; template <class _Tag, class _Sender, class _Env = __default_env> requires __valid<__count_of, _Tag, _Sender, _Env> inline constexpr bool __sends = (__v<__count_of<_Tag, _Sender, _Env>> != 0); template <class _Sender, class _Env = __default_env> requires __valid<__count_of, set_stopped_t, _Sender, _Env> inline constexpr bool sends_stopped = __sends<set_stopped_t, _Sender, _Env>; template <class _Sender, class _Env = __default_env> using __single_sender_value_t = __value_types_of_t<_Sender, _Env, __msingle_or<void>, __q<__msingle>>; template <class _Sender, class _Env = __default_env> using __single_value_variant_sender_t = value_types_of_t<_Sender, _Env, __types, __msingle>; template <class _Sender, class _Env = __default_env> concept __single_typed_sender = sender_in<_Sender, _Env> && __valid<__single_sender_value_t, _Sender, _Env>; template <class _Sender, class _Env = __default_env> concept __single_value_variant_sender = sender_in<_Sender, _Env> && __valid<__single_value_variant_sender_t, _Sender, _Env>; template <class... Errs> using __nofail = __mbool<sizeof...(Errs) == 0>; template <class _Sender, class _Env = __default_env> concept __nofail_sender = sender_in<_Sender, _Env> && (__v<error_types_of_t<_Sender, _Env, __nofail>>); namespace __compl_sigs { template <class... _Args> using __default_set_value = completion_signatures<set_value_t(_Args...)>; template <class _Error> using __default_set_error = completion_signatures<set_error_t(_Error)>; template <__is_completion_signatures... _Sigs> using __ensure_concat_ = __minvoke<__mconcat<__q<completion_signatures>>, _Sigs...>; template <class... _Sigs> using __ensure_concat = __mtry_eval<__ensure_concat_, _Sigs...>; template <class _Sender, class _Env, class _Sigs, class _SetVal, class _SetErr, class _SetStp> using __compl_sigs_impl = __concat_completion_signatures_t< _Sigs, __mtry_eval<__try_value_types_of_t, _Sender, _Env, _SetVal, __q<__ensure_concat>>, __mtry_eval<__try_error_types_of_t, _Sender, _Env, __transform<_SetErr, __q<__ensure_concat>>>, __if<__try_count_of<set_stopped_t, _Sender, _Env>, _SetStp, completion_signatures<>>>; template <class _Sender, class _Env, class _Sigs, class _SetVal, class _SetErr, class _SetStp> requires __valid<__compl_sigs_impl, _Sender, _Env, _Sigs, _SetVal, _SetErr, _SetStp> extern __compl_sigs_impl<_Sender, _Env, _Sigs, _SetVal, _SetErr, _SetStp> __compl_sigs_v; template <class _Sender, class _Env, class _Sigs, class _SetVal, class _SetErr, class _SetStp> using __compl_sigs_t = decltype(__compl_sigs_v<_Sender, _Env, _Sigs, _SetVal, _SetErr, _SetStp>); template <bool> struct __make_compl_sigs { template <class _Sender, class _Env, class _Sigs, class _SetVal, class _SetErr, class _SetStp> using __f = __compl_sigs_t<_Sender, _Env, _Sigs, _SetVal, _SetErr, _SetStp>; }; template <> struct __make_compl_sigs<true> { template <class _Sender, class _Env, class _Sigs, class _SetVal, class _SetErr, class _SetStp> using __f = __msuccess_or_t< __compl_sigs_t<_Sender, _Env, _Sigs, _SetVal, _SetErr, _SetStp>, dependent_completion_signatures<_Env>>; }; template < class _Sender, class _Env = __default_env, class _Sigs = completion_signatures<>, class _SetValue = __q<__default_set_value>, class _SetError = __q<__default_set_error>, class _SetStopped = completion_signatures<set_stopped_t()>> using __try_make_completion_signatures = __minvoke< __make_compl_sigs<same_as<_Env, no_env>>, _Sender, _Env, _Sigs, _SetValue, _SetError, _SetStopped>; } using __compl_sigs::__try_make_completion_signatures; template < class _Sender, class _Env = __default_env, __valid_completion_signatures<_Env> _Sigs = completion_signatures<>, template <class...> class _SetValue = __compl_sigs::__default_set_value, template <class> class _SetError = __compl_sigs::__default_set_error, __valid_completion_signatures<_Env> _SetStopped = completion_signatures<set_stopped_t()>> requires sender_in<_Sender, _Env> using make_completion_signatures = __msuccess_or_t< __try_make_completion_signatures< _Sender, _Env, _Sigs, __q<_SetValue>, __q<_SetError>, _SetStopped>>; using __with_exception_ptr = completion_signatures<set_error_t(std::exception_ptr)>; namespace __schedule { struct schedule_t { template <class _Scheduler> requires tag_invocable<schedule_t, _Scheduler> auto operator()(_Scheduler&& __sched) const noexcept(nothrow_tag_invocable<schedule_t, _Scheduler>) { static_assert(sender<tag_invoke_result_t<schedule_t, _Scheduler>>); return tag_invoke(schedule_t{}, (_Scheduler&&) __sched); } friend constexpr bool tag_invoke(forwarding_query_t, schedule_t) { return false; } }; } using __schedule::schedule_t; inline constexpr schedule_t schedule{}; template <class _Tag, const auto& _Predicate> concept tag_category = requires { typename __mbool<bool{_Predicate(_Tag{})}>; requires bool{_Predicate(_Tag{})}; }; template <class _Scheduler> concept __has_schedule = requires(_Scheduler&& __sched) { { schedule((_Scheduler&&) __sched) } -> sender; }; template <class _Scheduler> concept __sender_has_completion_scheduler = requires(_Scheduler&& __sched, get_completion_scheduler_t<set_value_t>&& __tag) { { tag_invoke(std::move(__tag), get_env(schedule((_Scheduler&&) __sched))) } -> same_as<__decay_t<_Scheduler>>; }; template <class _Scheduler> concept scheduler = __has_schedule<_Scheduler> && __sender_has_completion_scheduler<_Scheduler> && equality_comparable<__decay_t<_Scheduler>> && copy_constructible<__decay_t<_Scheduler>>; template <scheduler _Scheduler> using schedule_result_t = __call_result_t<schedule_t, _Scheduler>; template <receiver _Receiver> using __current_scheduler_t = __call_result_t<get_scheduler_t, env_of_t<_Receiver>>; template <class _SchedulerProvider> concept __scheduler_provider = requires(const _SchedulerProvider& __sp) { { get_scheduler(__sp) } -> scheduler; }; namespace __start { struct start_t { template <class _Op> requires tag_invocable<start_t, _Op&> void operator()(_Op& __op) const noexcept { static_assert(nothrow_tag_invocable<start_t, _Op&>); (void) tag_invoke(start_t{}, __op); } }; } using __start::start_t; inline constexpr start_t start{}; template <class _Op> concept operation_state = destructible<_Op> && std::is_object_v<_Op> && requires(_Op& __op) { start(__op); }; struct __connect_awaitable_t { }; inline constexpr __connect_awaitable_t __connect_awaitable{}; namespace __connect { struct connect_t; template <class _Tp> [[deprecated( "Deprecated sender type detected. " "Please give the type a nested `is_sender` type alias, or " "specialize stdexec::enable_sender<your-sender-type> to be `true`. " "To suppress this deprecation warning, define `STDEXEC_DISABLE_R5_DEPRECATIONS`.")]] void _PLEASE_UPDATE_YOUR_SENDER_TYPE() { } template <class _Tp> [[deprecated( "Deprecated receiver type detected. " "Please give the type a nested `is_receiver` type alias, or " "specialize stdexec::enable_receiver<your-receiver-type> to be `true`." "To suppress this deprecation warning, define `STDEXEC_DISABLE_R5_DEPRECATIONS`.")]] void _PLEASE_UPDATE_YOUR_RECEIVER_TYPE() { } template <class _Sender, class _Receiver> using __tfx_sender = sender_transform_result_t<_Sender, env_of_t<_Receiver&>>; template <class _Sender, class _Receiver> concept __connectable_with_tag_invoke_ = receiver<_Receiver> && sender_in<_Sender, env_of_t<_Receiver>> && __receiver_from<_Receiver, _Sender> && tag_invocable<connect_t, _Sender, _Receiver>; template <class _Sender, class _Receiver> concept __connectable_with_tag_invoke = __connectable_with_tag_invoke_<__tfx_sender<_Sender, _Receiver>, _Receiver>; template <class _Sender, class _Receiver> concept __connectable_with_co_await = __callable<__connect_awaitable_t, __tfx_sender<_Sender, _Receiver>, _Receiver>; struct connect_t { template <class _Sender, class _Receiver> static constexpr auto __select_impl() noexcept { if constexpr (!enable_sender<__decay_t<_Sender>>) _PLEASE_UPDATE_YOUR_SENDER_TYPE<__decay_t<_Sender>>(); if constexpr (!enable_receiver<__decay_t<_Receiver>>) _PLEASE_UPDATE_YOUR_RECEIVER_TYPE< __decay_t<_Receiver>>(); constexpr bool _NothrowTfxSender = __nothrow_callable<get_env_t, _Receiver&> && __nothrow_callable<sender_transform_t, _Sender, env_of_t<_Receiver&>>; using _TfxSender = __tfx_sender<_Sender, _Receiver&>; if constexpr (__connectable_with_tag_invoke<_Sender, _Receiver>) { using _Result = tag_invoke_result_t<connect_t, _TfxSender, _Receiver>; constexpr bool _Nothrow = _NothrowTfxSender && nothrow_tag_invocable<connect_t, _TfxSender, _Receiver>; return static_cast<_Result (*)() noexcept(_Nothrow)>(nullptr); } else if constexpr (__connectable_with_co_await<_Sender, _Receiver>) { using _Result = __call_result_t<__connect_awaitable_t, _TfxSender, _Receiver>; return static_cast<_Result (*)()>(nullptr); } else { using _Result = __debug::__debug_operation; return static_cast<_Result (*)() noexcept(_NothrowTfxSender)>(nullptr); } } template <class _Sender, class _Receiver> using __select_impl_t = decltype(__select_impl<_Sender, _Receiver>()); template <sender _Sender, receiver _Receiver> requires __connectable_with_tag_invoke<_Sender, _Receiver> || __connectable_with_co_await<_Sender, _Receiver> || __is_debug_env<env_of_t<_Receiver>> auto operator()(_Sender&& __sndr, _Receiver&& __rcvr) const noexcept(__nothrow_callable<__select_impl_t<_Sender, _Receiver>>) -> __call_result_t<__select_impl_t<_Sender, _Receiver>> { using _TfxSender = __tfx_sender<_Sender, _Receiver&>; auto&& __env = get_env(__rcvr); if constexpr (__connectable_with_tag_invoke<_Sender, _Receiver>) { static_assert( operation_state<tag_invoke_result_t<connect_t, _TfxSender, _Receiver>>, "stdexec::connect(sender, receiver) must return a type that " "satisfies the operation_state concept"); return tag_invoke( connect_t{}, sender_transform((_Sender&&) __sndr, __env), (_Receiver&&) __rcvr); } else if constexpr (__connectable_with_co_await<_Sender, _Receiver>) { return __connect_awaitable( sender_transform((_Sender&&) __sndr, __env), (_Receiver&&) __rcvr); } else { using __tag_invoke::tag_invoke; tag_invoke(*this, sender_transform((_Sender&&) __sndr, __env), (_Receiver&&) __rcvr); } } friend constexpr bool tag_invoke(forwarding_query_t, connect_t) noexcept { return false; } }; } using __connect::connect_t; inline constexpr __connect::connect_t connect{}; template <class _Sender, class _Receiver> concept sender_to = receiver<_Receiver> && __sender_like<_Sender, env_of_t<_Receiver>> && sender_in<_Sender, env_of_t<_Receiver>> && __receiver_from<_Receiver, _Sender> && requires(_Sender&& __sndr, _Receiver&& __rcvr) { connect((_Sender&&) __sndr, (_Receiver&&) __rcvr); }; template <class _Tag, class... _Args> _Tag __tag_of_sig_(_Tag (*)(_Args...)); template <class _Sig> using __tag_of_sig_t = decltype(stdexec::__tag_of_sig_((_Sig*) nullptr)); template <class _Sender, class _SetSig, class _Env = __default_env> concept sender_of = sender_in<_Sender, _Env> && same_as< __types<_SetSig>, __gather_completions_for< __tag_of_sig_t<_SetSig>, _Sender, _Env, __qf<__tag_of_sig_t<_SetSig>>, __q<__types>>>; template <class _Fun, class _CPO, class _Sender, class... _As> concept __tag_invocable_with_domain = tag_invocable<_Fun, __sender_domain_of_t<_Sender, _CPO>, _Sender, _As...>; namespace __submit_ { template <class _ReceiverId> struct __operation_base; template <class _ReceiverId> struct __operation_base { using _Receiver = __t<_ReceiverId>; _Receiver __rcvr_; using __delete_fn_t = void(__operation_base<_ReceiverId>*) noexcept; __delete_fn_t* __delete_; }; template <class _ReceiverId> struct __receiver { using _Receiver = stdexec::__t<_ReceiverId>; struct __t { using is_receiver = void; using __id = __receiver; __operation_base<_ReceiverId>* __op_state_; template <__completion_tag _Tag, class... _As> requires __callable<_Tag, _Receiver, _As...> friend void tag_invoke(_Tag __tag, __t&& __self, _As&&... __as) noexcept( __nothrow_callable<_Tag, _Receiver, _As...>) { auto __g = __scope_guard{__self.__op_state_->__delete_, __self.__op_state_}; return __tag((_Receiver&&) __self.__op_state_->__rcvr_, (_As&&) __as...); } friend auto tag_invoke(get_env_t, const __t& __self) noexcept -> env_of_t<_Receiver> { return get_env(__self.__op_state_->__rcvr_); } }; }; template <class _ReceiverId> using __receiver_t = __t<__receiver<_ReceiverId>>; template <class _SenderId, class _ReceiverId> struct __operation : __operation_base<_ReceiverId> { using _Sender = stdexec::__t<_SenderId>; using _Receiver = stdexec::__t<_ReceiverId>; connect_result_t<_Sender, __receiver_t<_ReceiverId>> __op_state_; template <__decays_to<_Receiver> _CvrefReceiver> __operation(_Sender&& __sndr, _CvrefReceiver&& __rcvr) : __operation_base<_ReceiverId>{ (_CvrefReceiver&&) __rcvr, [](__operation_base<_ReceiverId>* __self) noexcept { delete static_cast<__operation*>(__self); }} , __op_state_(connect((_Sender&&) __sndr, __receiver_t<_ReceiverId>{this})) { } }; struct __submit_t { template <receiver _Receiver, sender_to<_Receiver> _Sender> void operator()(_Sender&& __sndr, _Receiver __rcvr) const noexcept(false) { start((new __operation<__id<_Sender>, __id<_Receiver>>{ (_Sender&&) __sndr, (_Receiver&&) __rcvr}) ->__op_state_); } }; } using __submit_::__submit_t; inline constexpr __submit_t __submit{}; namespace __inln { struct __scheduler { using __t = __scheduler; using __id = __scheduler; template <class _Receiver> struct __op : __immovable { _Receiver __recv_; friend void tag_invoke(start_t, __op& __self) noexcept { set_value((_Receiver&&) __self.__recv_); } }; struct __sender { using __t = __sender; using __id = __sender; using is_sender = void; using completion_signatures = stdexec::completion_signatures<set_value_t()>; template <receiver_of<completion_signatures> _Receiver> friend __op<_Receiver> tag_invoke(connect_t, __sender, _Receiver __rcvr) { return {{}, (_Receiver&&) __rcvr}; } friend auto tag_invoke(get_env_t, __sender) noexcept { return __env::__env_fn{[](get_completion_scheduler_t<set_value_t>) noexcept { return __scheduler{}; }}; } }; friend __sender tag_invoke(schedule_t, __scheduler) { return {}; } bool operator==(const __scheduler&) const noexcept = default; }; } namespace __start_detached { template <class _EnvId> struct __detached_receiver { using _Env = stdexec::__t<_EnvId>; struct __t { using is_receiver = void; using __id = __detached_receiver; [[no_unique_address]] _Env __env_; template <same_as<set_value_t> _Tag, class... _As> friend void tag_invoke(_Tag, __t&&, _As&&...) noexcept { } template <same_as<set_error_t> _Tag, class _Error> [[noreturn]] friend void tag_invoke(_Tag, __t&&, _Error&&) noexcept { std::terminate(); } template <same_as<set_stopped_t> _Tag> friend void tag_invoke(_Tag, __t&&) noexcept { } friend const _Env& tag_invoke(get_env_t, const __t& __self) noexcept { return __self.__env_; } }; }; template <class _Env> using __detached_receiver_t = __t<__detached_receiver<__id<__decay_t<_Env>>>>; struct start_detached_t; using _Sender = __0; using _Env = __1; using __cust_sigs = __types< tag_invoke_t(start_detached_t, _Sender), tag_invoke_t(start_detached_t, _Sender, _Env), tag_invoke_t(start_detached_t, get_scheduler_t(_Env&), _Sender), tag_invoke_t(start_detached_t, get_scheduler_t(_Env&), _Sender, _Env)>; template <class _Sender, class _Env> inline constexpr bool __is_start_detached_customized = __minvocable<__which<__cust_sigs>, _Sender, _Env>; struct __submit_detached { template <class _Sender, class _Env> void operator()(_Sender&& __sndr, _Env&& __env) const { __submit((_Sender&&) __sndr, __detached_receiver_t<_Env>{(_Env&&) __env}); } }; template <class _Sender, class _Env> using __dispatcher_for = __make_dispatcher<__cust_sigs, __mconst<__submit_detached>, _Sender, _Env>; struct start_detached_t { template <sender _Sender, class _Env = empty_env> requires sender_to<_Sender, __detached_receiver_t<_Env>> || __is_start_detached_customized<_Sender, _Env> void operator()(_Sender&& __sndr, _Env&& __env = _Env{}) const noexcept(__nothrow_callable<__dispatcher_for<_Sender, _Env>, _Sender, _Env>) { using _Dispatcher = __dispatcher_for<_Sender, _Env>; static_assert(same_as<void, __call_result_t<_Dispatcher, _Sender, _Env>>); _Dispatcher{}((_Sender&&) __sndr, (_Env&&) __env); } }; } using __start_detached::start_detached_t; inline constexpr start_detached_t start_detached{}; namespace __just { template <class _Tag, class... _Ts> using __completion_signatures_ = completion_signatures<_Tag(_Ts...)>; template <class _ReceiverId, class _Tag, class... _Ts> struct __operation { using _Receiver = stdexec::__t<_ReceiverId>; struct __t : __immovable { using __id = __operation; std::tuple<_Ts...> __vals_; _Receiver __rcvr_; friend void tag_invoke(start_t, __t& __op_state) noexcept { std::apply( [&__op_state](_Ts&... __ts) { _Tag{}((_Receiver&&) __op_state.__rcvr_, (_Ts&&) __ts...); }, __op_state.__vals_); } }; }; template <class _Tag, class... _Ts> struct __basic_sender { template <class _Receiver> using __operation_t = stdexec::__t<__operation<stdexec::__id<_Receiver>, _Tag, _Ts...>>; struct __t { using __id = __basic_sender; using is_sender = void; using completion_signatures = __completion_signatures_<_Tag, _Ts...>; std::tuple<_Ts...> __vals_; template <receiver_of<completion_signatures> _Receiver> requires(copy_constructible<_Ts> && ...) friend auto tag_invoke(connect_t, const __t& __sndr, _Receiver __rcvr) noexcept((std::is_nothrow_copy_constructible_v<_Ts> && ...)) -> __operation_t<_Receiver> { return {{}, __sndr.__vals_, (_Receiver&&) __rcvr}; } template <receiver_of<completion_signatures> _Receiver> friend auto tag_invoke(connect_t, __t&& __sndr, _Receiver __rcvr) noexcept((std::is_nothrow_move_constructible_v<_Ts> && ...)) -> __operation_t<_Receiver> { return {{}, ((__t&&) __sndr).__vals_, (_Receiver&&) __rcvr}; } friend empty_env tag_invoke(get_env_t, const __t&) noexcept { return {}; } }; }; template <class... _Values> struct __sender { using __base = stdexec::__t<__basic_sender<set_value_t, _Values...>>; struct __t : __base { using __id = __sender; }; }; template <class _Error> struct __error_sender { using __base = stdexec::__t<__basic_sender<set_error_t, _Error>>; struct __t : __base { using __id = __error_sender; }; }; struct __stopped_sender : __t<__basic_sender<set_stopped_t>> { using __id = __stopped_sender; using __t = __stopped_sender; }; inline constexpr struct __just_t { template <__movable_value... _Ts> __t<__sender<__decay_t<_Ts>...>> operator()(_Ts&&... __ts) const noexcept((__nothrow_constructible_from<__decay_t<_Ts>, _Ts> && ...)) { return {{{(_Ts&&) __ts...}}}; } } just{}; inline constexpr struct __just_error_t { template <__movable_value _Error> __t<__error_sender<__decay_t<_Error>>> operator()(_Error&& __err) const noexcept(__nothrow_constructible_from<__decay_t<_Error>, _Error>) { return {{{(_Error&&) __err}}}; } } just_error{}; inline constexpr struct __just_stopped_t { __stopped_sender operator()() const noexcept { return {{}}; } } just_stopped{}; } using __just::just; using __just::just_error; using __just::just_stopped; namespace __execute_ { template <class _Fun> struct __as_receiver { using is_receiver = void; _Fun __fun_; template <same_as<set_value_t> _Tag> friend void tag_invoke(_Tag, __as_receiver&& __rcvr) noexcept { try { __rcvr.__fun_(); } catch (...) { set_error((__as_receiver&&) __rcvr, std::exception_ptr()); } } template <same_as<set_error_t> _Tag> [[noreturn]] friend void tag_invoke(_Tag, __as_receiver&&, std::exception_ptr) noexcept { std::terminate(); } template <same_as<set_stopped_t> _Tag> friend void tag_invoke(_Tag, __as_receiver&&) noexcept { } friend empty_env tag_invoke(get_env_t, const __as_receiver&) noexcept { return {}; } }; struct execute_t { template <scheduler _Scheduler, class _Fun> requires __callable<_Fun&> && move_constructible<_Fun> void operator()(_Scheduler&& __sched, _Fun __fun) const noexcept(noexcept( __submit(schedule((_Scheduler&&) __sched), __as_receiver<_Fun>{(_Fun&&) __fun}))) { (void) __submit(schedule((_Scheduler&&) __sched), __as_receiver<_Fun>{(_Fun&&) __fun}); } template <scheduler _Scheduler, class _Fun> requires __callable<_Fun&> && move_constructible<_Fun> && tag_invocable<execute_t, _Scheduler, _Fun> void operator()(_Scheduler&& __sched, _Fun __fun) const noexcept(nothrow_tag_invocable<execute_t, _Scheduler, _Fun>) { (void) tag_invoke(execute_t{}, (_Scheduler&&) __sched, (_Fun&&) __fun); } }; } using __execute_::execute_t; inline constexpr execute_t execute{}; namespace __closure { template <__class _Dp> struct sender_adaptor_closure; } using __closure::sender_adaptor_closure; template <class _Tp> concept __sender_adaptor_closure = derived_from<__decay_t<_Tp>, sender_adaptor_closure<__decay_t<_Tp>>> && move_constructible<__decay_t<_Tp>> && constructible_from<__decay_t<_Tp>, _Tp>; template <class _Tp, class _Sender> concept __sender_adaptor_closure_for = __sender_adaptor_closure<_Tp> && sender<__decay_t<_Sender>> && __callable<_Tp, __decay_t<_Sender>> && sender<__call_result_t<_Tp, __decay_t<_Sender>>>; namespace __closure { template <class _T0, class _T1> struct __compose : sender_adaptor_closure<__compose<_T0, _T1>> { [[no_unique_address]] _T0 __t0_; [[no_unique_address]] _T1 __t1_; template <sender _Sender> requires __callable<_T0, _Sender> && __callable<_T1, __call_result_t<_T0, _Sender>> __call_result_t<_T1, __call_result_t<_T0, _Sender>> operator()(_Sender&& __sndr) && { return ((_T1&&) __t1_)(((_T0&&) __t0_)((_Sender&&) __sndr)); } template <sender _Sender> requires __callable<const _T0&, _Sender> && __callable<const _T1&, __call_result_t<const _T0&, _Sender>> __call_result_t<_T1, __call_result_t<_T0, _Sender>> operator()(_Sender&& __sndr) const & { return __t1_(__t0_((_Sender&&) __sndr)); } }; template <__class _Dp> struct sender_adaptor_closure { }; template <sender _Sender, __sender_adaptor_closure_for<_Sender> _Closure> __call_result_t<_Closure, _Sender> operator|(_Sender&& __sndr, _Closure&& __clsur) { return ((_Closure&&) __clsur)((_Sender&&) __sndr); } template <__sender_adaptor_closure _T0, __sender_adaptor_closure _T1> __compose<__decay_t<_T0>, __decay_t<_T1>> operator|(_T0&& __t0, _T1&& __t1) { return {{}, (_T0&&) __t0, (_T1&&) __t1}; } template <class _Fun, class... _As> struct __binder_back : sender_adaptor_closure<__binder_back<_Fun, _As...>> { [[no_unique_address]] _Fun __fun_; std::tuple<_As...> __as_; template <sender _Sender> requires __callable<_Fun, _Sender, _As...> __call_result_t<_Fun, _Sender, _As...> operator()(_Sender&& __sndr) && noexcept(__nothrow_callable<_Fun, _Sender, _As...>) { return std::apply( [&__sndr, this](_As&... __as) { return ((_Fun&&) __fun_)((_Sender&&) __sndr, (_As&&) __as...); }, __as_); } template <sender _Sender> requires __callable<const _Fun&, _Sender, const _As&...> __call_result_t<const _Fun&, _Sender, const _As&...> operator()(_Sender&& __sndr) const & noexcept(__nothrow_callable<const _Fun&, _Sender, const _As&...>) { return std::apply( [&__sndr, this](const _As&... __as) { return __fun_((_Sender&&) __sndr, __as...); }, __as_); } }; } using __closure::__binder_back; namespace __adaptors { template <class _Tp, class _Up> __copy_cvref_t<_Up&&, _Tp> __c_cast(_Up&& u) noexcept requires __decays_to<_Tp, _Tp> { static_assert(std::is_reference_v<__copy_cvref_t<_Up&&, _Tp>>); static_assert(__is_base_of(_Tp, __decay_t<_Up>)); return (__copy_cvref_t<_Up&&, _Tp>) (_Up&&) u; } namespace __no { struct __nope { }; struct __receiver : __nope { }; template <same_as<set_error_t> _Tag> void tag_invoke(_Tag, __receiver, std::exception_ptr) noexcept; template <same_as<set_stopped_t> _Tag> void tag_invoke(_Tag, __receiver) noexcept; empty_env tag_invoke(get_env_t, __receiver) noexcept; } using __not_a_receiver = __no::__receiver; template <class _Base> struct __adaptor { struct __t { template <class _T1> requires constructible_from<_Base, _T1> explicit __t(_T1&& __base) : __base_((_T1&&) __base) { } private: [[no_unique_address]] _Base __base_; protected: _Base& base() & noexcept { return __base_; } const _Base& base() const & noexcept { return __base_; } _Base&& base() && noexcept { return (_Base&&) __base_; } }; }; template <derived_from<__no::__nope> _Base> struct __adaptor<_Base> { struct __t : __no::__nope { }; }; template <class _Base> using __adaptor_base = typename __adaptor<_Base>::__t; template <__class _Derived, class _Base> struct receiver_adaptor { class __t : __adaptor_base<_Base> , __receiver_base { friend _Derived; template <class _Dp> static constexpr bool __missing_set_value() noexcept { return requires { requires bool(int(_Dp::set_value)); }; } template <class _Self, class... _Ts> static auto __call_set_value( _Self&& __self, _Ts&&... __ts) noexcept -> decltype(((_Self&&) __self).set_value((_Ts&&) __ts...)) { static_assert(noexcept(((_Self&&) __self).set_value((_Ts&&) __ts...))); return ((_Self&&) __self).set_value((_Ts&&) __ts...); } static constexpr int set_value = 1; template <class _Dp> static constexpr bool __missing_set_error() noexcept { return requires { requires bool(int(_Dp::set_error)); }; } template <class _Self, class... _Ts> static auto __call_set_error( _Self&& __self, _Ts&&... __ts) noexcept -> decltype(((_Self&&) __self).set_error((_Ts&&) __ts...)) { static_assert(noexcept(((_Self&&) __self).set_error((_Ts&&) __ts...))); return ((_Self&&) __self).set_error((_Ts&&) __ts...); } static constexpr int set_error = 1; template <class _Dp> static constexpr bool __missing_set_stopped() noexcept { return requires { requires bool(int(_Dp::set_stopped)); }; } template <class _Self, class... _Ts> static auto __call_set_stopped( _Self&& __self, _Ts&&... __ts) noexcept -> decltype(((_Self&&) __self).set_stopped((_Ts&&) __ts...)) { static_assert(noexcept(((_Self&&) __self).set_stopped((_Ts&&) __ts...))); return ((_Self&&) __self).set_stopped((_Ts&&) __ts...); } static constexpr int set_stopped = 1; template <class _Dp> static constexpr bool __missing_get_env() noexcept { return requires { requires bool(int(_Dp::get_env)); }; } template <class _Self, class... _Ts> static auto __call_get_env( _Self&& __self, _Ts&&... __ts) noexcept -> decltype(((_Self&&) __self).get_env((_Ts&&) __ts...)) { static_assert(noexcept(((_Self&&) __self).get_env((_Ts&&) __ts...))); return ((_Self&&) __self).get_env((_Ts&&) __ts...); } static constexpr int get_env = 1; static constexpr bool __has_base = !derived_from<_Base, __no::__nope>; template <class _Dp> using __base_from_derived_t = decltype(__declval<_Dp>().base()); using __get_base_t = __if_c< __has_base, __mbind_back_q<__copy_cvref_t, _Base>, __q<__base_from_derived_t>>; template <class _Dp> using __base_t = __minvoke<__get_base_t, _Dp&&>; template <class _Dp> static __base_t<_Dp> __get_base(_Dp&& __self) noexcept { if constexpr (__has_base) { return __c_cast<__t>((_Dp&&) __self).base(); } else { return ((_Dp&&) __self).base(); } } template <same_as<set_value_t> _SetValue, class... _As> friend auto tag_invoke(_SetValue, _Derived&& __self, _As&&... __as) noexcept -> __msecond< __if_c<same_as<set_value_t, _SetValue>>, decltype(__call_set_value((_Derived&&) __self, (_As&&) __as...))> { static_assert(noexcept(__call_set_value((_Derived&&) __self, (_As&&) __as...))); __call_set_value((_Derived&&) __self, (_As&&) __as...); } template <same_as<set_value_t> _SetValue, class _Dp = _Derived, class... _As> requires (__missing_set_value<_Dp>()) && tag_invocable<_SetValue, __base_t<_Dp>, _As...> friend void tag_invoke(_SetValue, _Derived&& __self, _As&&... __as) noexcept { stdexec::set_value(__get_base((_Dp&&) __self), (_As&&) __as...); } template <same_as<set_error_t> _SetError, class _Error> friend auto tag_invoke(_SetError, _Derived&& __self, _Error&& __err) noexcept -> __msecond< __if_c<same_as<set_error_t, _SetError>>, decltype(__call_set_error((_Derived&&) __self, (_Error&&) __err))> { static_assert(noexcept(__call_set_error((_Derived&&) __self, (_Error&&) __err))); __call_set_error((_Derived&&) __self, (_Error&&) __err); } template <same_as<set_error_t> _SetError, class _Error, class _Dp = _Derived> requires (__missing_set_error<_Dp>()) && tag_invocable<_SetError, __base_t<_Dp>, _Error> friend void tag_invoke(_SetError, _Derived&& __self, _Error&& __err) noexcept { stdexec::set_error(__get_base((_Derived&&) __self), (_Error&&) __err); } template <same_as<set_stopped_t> _SetStopped, class _Dp = _Derived> friend auto tag_invoke(_SetStopped, _Derived&& __self) noexcept -> __msecond< __if_c<same_as<set_stopped_t, _SetStopped>>, decltype(__call_set_stopped((_Dp&&) __self))> { static_assert(noexcept(__call_set_stopped((_Derived&&) __self))); __call_set_stopped((_Derived&&) __self); } template <same_as<set_stopped_t> _SetStopped, class _Dp = _Derived> requires (__missing_set_stopped<_Dp>()) && tag_invocable<_SetStopped, __base_t<_Dp>> friend void tag_invoke(_SetStopped, _Derived&& __self) noexcept { stdexec::set_stopped(__get_base((_Derived&&) __self)); } template <same_as<get_env_t> _GetEnv, class _Dp = _Derived> friend auto tag_invoke(_GetEnv, const _Derived& __self) noexcept -> decltype(__call_get_env((const _Dp&) __self)) { static_assert(noexcept(__call_get_env(__self))); return __call_get_env(__self); } template <same_as<get_env_t> _GetEnv, class _Dp = _Derived> requires (__missing_get_env<_Dp>()) friend auto tag_invoke(_GetEnv, const _Derived& __self) noexcept -> env_of_t<__base_t<const _Dp&>> { return stdexec::get_env(__get_base(__self)); } public: __t() = default; using __adaptor_base<_Base>::__adaptor_base; using is_receiver = void; }; }; } template <__class _Derived, receiver _Base = __adaptors::__not_a_receiver> using receiver_adaptor = typename __adaptors::receiver_adaptor<_Derived, _Base>::__t; template <class _Receiver, class _Fun, class... _As> concept __receiver_of_invoke_result = receiver_of< _Receiver, completion_signatures< __minvoke<__remove<void, __qf<set_value_t>>, std::invoke_result_t<_Fun, _As...>>>>; template <bool _CanThrow = false, class _Receiver, class _Fun, class... _As> void __set_value_invoke(_Receiver&& __rcvr, _Fun&& __fun, _As&&... __as) noexcept(!_CanThrow) { if constexpr (_CanThrow || __nothrow_invocable<_Fun, _As...>) { if constexpr (same_as<void, std::invoke_result_t<_Fun, _As...>>) { std::invoke((_Fun&&) __fun, (_As&&) __as...); set_value((_Receiver&&) __rcvr); } else { set_value((_Receiver&&) __rcvr, std::invoke((_Fun&&) __fun, (_As&&) __as...)); } } else { try { stdexec::__set_value_invoke<true>((_Receiver&&) __rcvr, (_Fun&&) __fun, (_As&&) __as...); } catch (...) { set_error((_Receiver&&) __rcvr, std::current_exception()); } } } template <class _Fun> struct _WITH_FUNCTION_ { }; template <class... _Args> struct _WITH_ARGUMENTS_ { }; inline constexpr __mstring __not_callable_diag = "The specified function is not callable with the arguments provided."__csz; template <__mstring _Context, __mstring _Diagnostic = __not_callable_diag> struct _NOT_CALLABLE_ { }; template <__mstring _Context> struct __callable_error { template <class _Fun, class... _Args> using __f = __mexception< _NOT_CALLABLE_<_Context>, _WITH_FUNCTION_<_Fun>, _WITH_ARGUMENTS_<_Args...>>; }; template <class _Fun, class... _Args> requires invocable<_Fun, _Args...> using __non_throwing_ = __mbool<__nothrow_invocable<_Fun, _Args...>>; template <class _Tag, class _Fun, class _Sender, class _Env, class _Catch> using __with_error_invoke_t = __if< __gather_completions_for< _Tag, _Sender, _Env, __mbind_front<__mtry_catch_q<__non_throwing_, _Catch>, _Fun>, __q<__mand>>, completion_signatures<>, __with_exception_ptr>; template <class _Fun, class... _Args> requires invocable<_Fun, _Args...> using __set_value_invoke_t = completion_signatures< __minvoke< __remove<void, __qf<set_value_t>>, std::invoke_result_t<_Fun, _Args...>>>; template <class _Data, class _Children> struct __sender_types { using __data_t = _Data; using __children_t = _Children; }; template <class _Tag, class _Domain> struct __sender_impl; template <class _Tag, class _TypesId> struct __sender; template <class _Tag> struct __default_sender_impl; template <class _Tag, class _Domain> struct __sender_impl : __default_sender_impl<_Tag> { }; template <class _Ty> _Ty __remove_rref(_Ty&&); template <class _Sender> using __data = decltype(__remove_rref(__declval<_Sender>().__data_)); template <class _Sender> using __child0 = decltype(__remove_rref(__declval<_Sender>().__children_.__val0)); template <class _Sender> using __child1 = decltype(__remove_rref(__declval<_Sender>().__children_.__val1)); template <class _Sender> using __child2 = decltype(__remove_rref(__declval<_Sender>().__children_.__val2)); template <class _SenderTag, class _CvrefSender, class _Env> using __custom_get_completion_signatures_result_t = decltype(__sender_impl<_SenderTag, __env_domain_of_t<_Env, _CvrefSender>>:: get_completion_signatures(__declval<_CvrefSender>(), __declval<_Env>())); template <class _SenderTag, class _CvrefSender, class _Receiver> using __custom_connect_result_t = decltype(__sender_impl<_SenderTag, __env_domain_of_t<env_of_t<_Receiver>, _CvrefSender>>:: connect(__declval<_CvrefSender>(), __declval<_Receiver>())); template <class _MemberTag> struct __sender_tag_invoke_result_for; template <> struct __sender_tag_invoke_result_for<get_completion_signatures_t> { template <class _SenderTag, class _CvrefSender, class _Env> requires __valid<__custom_get_completion_signatures_result_t, _SenderTag, _CvrefSender, _Env> static auto (*__sig)() noexcept -> __custom_get_completion_signatures_result_t<_SenderTag, _CvrefSender, _Env>; }; template <> struct __sender_tag_invoke_result_for<connect_t> { template <class _SenderTag, class _CvrefSender, class _Receiver> requires __valid<__custom_connect_result_t, _SenderTag, _CvrefSender, _Receiver> static auto (*__sig)() noexcept(noexcept( __sender_impl<_SenderTag, __env_domain_of_t<env_of_t<_Receiver>, _CvrefSender>>().connect( __declval<_CvrefSender>(), __declval<_Receiver>()))) -> __custom_connect_result_t<_SenderTag, _CvrefSender, _Receiver>; }; template <class _SenderTag, class _MemberTag, class _Ty, class _Uy> requires __one_of<_MemberTag, connect_t, get_completion_signatures_t> decltype(__sender_tag_invoke_result_for<_MemberTag>::template __sig<_SenderTag, _Ty, _Uy>) __sender_tag_invoke_result(); template <class _Tag, class _TypesId> struct __sender { using __tag_t = _Tag; using __types_t = __unhide<_TypesId>; using __data_t = typename __types_t::__data_t; using __children_t = typename __types_t::__children_t; using is_sender = void; using __env_t = __minvoke< __if_c< __tuple_size<__children_t> == 1, __mcompose<__q<env_of_t>, __q<__tuple_elem0>>, __mconst<empty_env>>, __children_t>; [[no_unique_address]] __tag_t __tag_{}; [[no_unique_address]] __data_t __data_; [[no_unique_address]] __children_t __children_; template <same_as<get_env_t> _Tag2, same_as<__sender> _Self> friend __env_t tag_invoke(_Tag2, const _Self& __self) noexcept { if constexpr (__tuple_size<__children_t> == 1) { return get_env(__self.__children_.__val0); } else { return empty_env{}; } __builtin_unreachable(); } template < __one_of<connect_t, get_completion_signatures_t> _Tag2, __decays_to<__sender> _Self, class _Uy> requires requires { __sender_tag_invoke_result<_Tag, _Tag2, _Self, _Uy>()(); } friend auto tag_invoke(_Tag2, _Self&& __self, _Uy&& __uy) noexcept( noexcept(__sender_tag_invoke_result<_Tag, _Tag2, _Self, _Uy>()())) -> decltype(__sender_tag_invoke_result<_Tag, _Tag2, _Self, _Uy>()()) { if constexpr (same_as<_Tag2, get_completion_signatures_t>) { using _Impl = __sender_impl<_Tag, __env_domain_of_t<_Uy, _Self>>; return _Impl::get_completion_signatures((_Self&&) __self, (_Uy&&) __uy); } else { using _Impl = __sender_impl<_Tag, __env_domain_of_t<env_of_t<_Uy>, _Self>>; using _T2 = decltype(__sender_tag_invoke_result<_Tag, _Tag2, _Self, _Uy>()()); using _U2 = decltype(_Impl::connect((_Self&&) __self, (_Uy&&) __uy)); static_assert(same_as<_T2, _U2>); static_assert(same_as<_T2, __decay_t<_T2>>); return _Impl::connect((_Self&&) __self, (_Uy&&) __uy); } __builtin_unreachable(); } }; template <class _Tag, class _Data, class... _Children> using __sender_t = __sender<_Tag, __hide<__sender_types<_Data, __tuple<_Children...>>>>; template <class _Tag, class _Data, class... _Children> auto __make_sender(_Tag __tag, _Data __data, _Children... __children) -> __sender_t<_Tag, _Data, _Children...> { return {__tag, (_Data&&) __data, __tuple((_Children&&) __children...)}; } namespace __then { template <class _ReceiverId, class _Fun> struct __receiver { using _Receiver = stdexec::__t<_ReceiverId>; struct __data { _Receiver __rcvr_; [[no_unique_address]] _Fun __fun_; }; struct __t { using is_receiver = void; using __id = __receiver; __data* __op_; template <__same_as<set_value_t> _Tag, class... _As> requires invocable<_Fun, _As...> && __receiver_of_invoke_result<_Receiver, _Fun, _As...> friend void tag_invoke(_Tag, __t&& __self, _As&&... __as) noexcept { stdexec::__set_value_invoke( (_Receiver&&) __self.__op_->__rcvr_, (_Fun&&) __self.__op_->__fun_, (_As&&) __as...); } template <__one_of<set_error_t, set_stopped_t> _Tag, class... _As> requires __callable<_Tag, _Receiver, _As...> friend void tag_invoke(_Tag __tag, __t&& __self, _As&&... __as) noexcept { __tag((_Receiver&&) __self.__op_->__rcvr_, (_As&&) __as...); } friend auto tag_invoke(get_env_t, const __t& __self) noexcept -> env_of_t<const _Receiver&> { return get_env(__self.__op_->__rcvr_); } }; }; template <class _CvrefSender, class _ReceiverId, class _Fun> struct __operation { using _Receiver = stdexec::__t<_ReceiverId>; using __receiver_id = __receiver<_ReceiverId, _Fun>; using __receiver_t = stdexec::__t<__receiver_id>; struct __t : __immovable { using __id = __operation; typename __receiver_id::__data __data_; connect_result_t<_CvrefSender, __receiver_t> __op_; __t(_CvrefSender&& __sndr, _Receiver __rcvr, _Fun __fun) noexcept(__nothrow_decay_copyable<_Receiver> && __nothrow_decay_copyable<_Fun> && __nothrow_connectable<_CvrefSender, __receiver_t>) : __data_{(_Receiver&&) __rcvr, (_Fun&&) __fun} , __op_(connect((_CvrefSender&&) __sndr, __receiver_t{&__data_})) { } friend void tag_invoke(start_t, __t& __self) noexcept { start(__self.__op_); } }; }; inline constexpr __mstring __then_context = "In stdexec::then(Sender, Function)..."__csz; using __on_not_callable = __callable_error<__then_context>; template <class _Fun, class _CvrefSender, class _Env> using __completion_signatures_t = __try_make_completion_signatures< _CvrefSender, _Env, __with_error_invoke_t< set_value_t, _Fun, _CvrefSender, _Env, __on_not_callable>, __mbind_front<__mtry_catch_q<__set_value_invoke_t, __on_not_callable>, _Fun>>; struct __impl { template <class _Self> using __fun = __decay_t<__data<_Self>>; template <class _Self, class _Receiver> using __receiver = __t<__receiver<__id<_Receiver>, __fun<_Self>>>; template <class _Self, class _Receiver> using __operation = __t<__operation<__child0<_Self>, __id<_Receiver>, __fun<_Self>>>; template <class _Self, class _Env> static auto get_completion_signatures(_Self&&, _Env&&) -> dependent_completion_signatures<_Env>; template <__true _Self, class _Env> static auto get_completion_signatures(_Self&& __self, _Env&&) -> __completion_signatures_t<__fun<_Self>, __child0<_Self>, _Env>; template <class _Self, receiver _Receiver> requires sender_to<__child0<_Self>, __receiver<_Self, _Receiver>> static auto connect(_Self&& __self, _Receiver __rcvr) noexcept(__nothrow_constructible_from< __operation<_Self, _Receiver>, __child0<_Self>, _Receiver, __data<_Self>>) -> __operation<_Self, _Receiver> { return { ((_Self&&) __self).__children_.__val0, (_Receiver&&) __rcvr, ((_Self&&) __self).__data_}; } }; struct then_t { template <class _Sender, class _Fun> using __sender = stdexec::__sender_t<then_t, _Fun, __decay_t<_Sender>>; template <sender _Sender, __movable_value _Fun> requires(!__tag_invocable_with_domain<then_t, set_value_t, _Sender, _Fun>) && (!tag_invocable<then_t, _Sender, _Fun>) auto operator()(_Sender&& __sndr, _Fun __fun) const -> __sender<_Sender, _Fun> { return stdexec::__make_sender(then_t(), (_Fun&&) __fun, (_Sender&&) __sndr); } template <sender _Sender, __movable_value _Fun> requires __tag_invocable_with_domain<then_t, set_value_t, _Sender, _Fun> sender auto operator()(_Sender&& __sndr, _Fun __fun) const noexcept(nothrow_tag_invocable<then_t, __sender_domain_of_t<_Sender>, _Sender, _Fun>) { auto __domain = stdexec::__get_sender_domain(__sndr); return tag_invoke(then_t{}, __domain, (_Sender&&) __sndr, (_Fun&&) __fun); } template <sender _Sender, __movable_value _Fun> requires(!__tag_invocable_with_domain<then_t, set_value_t, _Sender, _Fun>) && tag_invocable<then_t, _Sender, _Fun> sender auto operator()(_Sender&& __sndr, _Fun __fun) const noexcept(nothrow_tag_invocable<then_t, _Sender, _Fun>) { return tag_invoke(then_t{}, (_Sender&&) __sndr, (_Fun&&) __fun); } template <class _Fun> __binder_back<then_t, _Fun> operator()(_Fun __fun) const { return {{}, {}, {(_Fun&&) __fun}}; } }; } template <> struct __default_sender_impl<__then::then_t> : __then::__impl { }; using __then::then_t; inline constexpr then_t then{}; namespace __upon_error { template <class _ReceiverId, class _Fun> struct __receiver { using _Receiver = stdexec::__t<_ReceiverId>; struct __t { using is_receiver = void; using __id = __receiver; _Receiver __rcvr_; [[no_unique_address]] _Fun __fun_; template <__one_of<set_value_t, set_stopped_t> _Tag, same_as<__t> _Self, class... _Args> requires __callable<_Tag, _Receiver, _Args...> friend void tag_invoke(_Tag, _Self&& __self, _Args&&... __args) noexcept { _Tag{}((_Receiver&&) __self.__rcvr_, (_Args&&) __args...); } template <same_as<set_error_t> _Tag, __decays_to<__t> _Self, class _Error> requires invocable<_Fun, _Error> && __receiver_of_invoke_result<_Receiver, _Fun, _Error> friend void tag_invoke(_Tag, _Self&& __self, _Error&& __error) noexcept { stdexec::__set_value_invoke( (_Receiver&&) __self.__rcvr_, (_Fun&&) __self.__fun_, (_Error&&) __error); } friend env_of_t<_Receiver> tag_invoke(get_env_t, const __t& __self) noexcept { return get_env(__self.__rcvr_); } }; }; inline constexpr __mstring __upon_error_context = "In stdexec::upon_error(Sender, Function)..."__csz; using __on_not_callable = __callable_error<__upon_error_context>; template <class _SenderId, class _Fun> struct __sender { using _Sender = stdexec::__t<_SenderId>; template <class _Receiver> using __receiver = stdexec::__t<__receiver<__id<_Receiver>, _Fun>>; struct __t { using __id = __sender; using is_sender = void; [[no_unique_address]] _Sender __sndr_; [[no_unique_address]] _Fun __fun_; template <class _Self, class _Env> using __completion_signatures = __try_make_completion_signatures< __copy_cvref_t<_Self, _Sender>, _Env, __with_error_invoke_t< set_error_t, _Fun, __copy_cvref_t<_Self, _Sender>, _Env, __on_not_callable>, __q<__compl_sigs::__default_set_value>, __mbind_front_q<__set_value_invoke_t, _Fun>>; template <__decays_to<__t> _Self, receiver _Receiver> requires sender_to<__copy_cvref_t<_Self, _Sender>, __receiver<_Receiver>> friend auto tag_invoke(connect_t, _Self&& __self, _Receiver __rcvr) noexcept(__nothrow_connectable<__copy_cvref_t<_Self, _Sender>, __receiver<_Receiver>>) -> connect_result_t<__copy_cvref_t<_Self, _Sender>, __receiver<_Receiver>> { return stdexec::connect( ((_Self&&) __self).__sndr_, __receiver<_Receiver>{(_Receiver&&) __rcvr, ((_Self&&) __self).__fun_}); } template <__decays_to<__t> _Self, class _Env> friend auto tag_invoke(get_completion_signatures_t, _Self&&, _Env&&) -> dependent_completion_signatures<_Env>; template <__decays_to<__t> _Self, class _Env> friend auto tag_invoke(get_completion_signatures_t, _Self&&, _Env&&) -> __completion_signatures<_Self, _Env> requires true; friend auto tag_invoke(get_env_t, const __t& __self) noexcept -> env_of_t<const _Sender&> { return get_env(__self.__sndr_); } }; }; struct upon_error_t { template <class _Sender, class _Fun> using __sender = __t<__sender<stdexec::__id<__decay_t<_Sender>>, _Fun>>; template <sender _Sender, __movable_value _Fun> requires __tag_invocable_with_domain<upon_error_t, set_error_t, _Sender, _Fun> sender auto operator()(_Sender&& __sndr, _Fun __fun) const noexcept(nothrow_tag_invocable< upon_error_t, __sender_domain_of_t<_Sender, set_error_t>, _Sender, _Fun>) { auto __domain = __get_sender_domain(__sndr, set_error); return tag_invoke(upon_error_t{}, __domain, (_Sender&&) __sndr, (_Fun&&) __fun); } template <sender _Sender, __movable_value _Fun> requires(!__tag_invocable_with_domain<upon_error_t, set_error_t, _Sender, _Fun>) && tag_invocable<upon_error_t, _Sender, _Fun> sender auto operator()(_Sender&& __sndr, _Fun __fun) const noexcept(nothrow_tag_invocable<upon_error_t, _Sender, _Fun>) { return tag_invoke(upon_error_t{}, (_Sender&&) __sndr, (_Fun&&) __fun); } template <sender _Sender, __movable_value _Fun> requires(!__tag_invocable_with_domain<upon_error_t, set_error_t, _Sender, _Fun>) && (!tag_invocable<upon_error_t, _Sender, _Fun>) && sender<__sender<_Sender, _Fun>> __sender<_Sender, _Fun> operator()(_Sender&& __sndr, _Fun __fun) const { return __sender<_Sender, _Fun>{(_Sender&&) __sndr, (_Fun&&) __fun}; } template <class _Fun> __binder_back<upon_error_t, _Fun> operator()(_Fun __fun) const { return {{}, {}, {(_Fun&&) __fun}}; } }; } using __upon_error::upon_error_t; inline constexpr upon_error_t upon_error{}; namespace __upon_stopped { template <class _ReceiverId, class _Fun> struct __receiver { using _Receiver = stdexec::__t<_ReceiverId>; struct __t { using is_receiver = void; using __id = __receiver; _Receiver __rcvr_; [[no_unique_address]] _Fun __fun_; template <__one_of<set_value_t, set_error_t> _Tag, same_as<__t> _Self, class... _Args> requires __callable<_Tag, _Receiver, _Args...> friend void tag_invoke(_Tag, _Self&& __self, _Args&&... __args) noexcept { _Tag{}((_Receiver&&) __self.__rcvr_, (_Args&&) __args...); } template <same_as<set_stopped_t> _Tag> friend void tag_invoke(_Tag, __t&& __self) noexcept { stdexec::__set_value_invoke((_Receiver&&) __self.__rcvr_, (_Fun&&) __self.__fun_); } friend env_of_t<_Receiver> tag_invoke(get_env_t, const __t& __self) noexcept { return get_env(__self.__rcvr_); } }; }; inline constexpr __mstring __upon_stopped_context = "In stdexec::upon_stopped(Sender, Function)..."__csz; using __on_not_callable = __callable_error<__upon_stopped_context>; template <class _SenderId, class _Fun> struct __sender { using _Sender = stdexec::__t<_SenderId>; template <class _Receiver> using __receiver = stdexec::__t<__receiver<__id<_Receiver>, _Fun>>; struct __t { using __id = __sender; using is_sender = void; [[no_unique_address]] _Sender __sndr_; [[no_unique_address]] _Fun __fun_; template <class _Self, class _Env> using __completion_signatures = __try_make_completion_signatures< __copy_cvref_t<_Self, _Sender>, _Env, __with_error_invoke_t< set_stopped_t, _Fun, __copy_cvref_t<_Self, _Sender>, _Env, __on_not_callable>, __q<__compl_sigs::__default_set_value>, __q<__compl_sigs::__default_set_error>, __set_value_invoke_t<_Fun>>; template <__decays_to<__t> _Self, receiver _Receiver> requires __receiver_of_invoke_result<_Receiver, _Fun> && sender_to<__copy_cvref_t<_Self, _Sender>, __receiver<_Receiver>> friend auto tag_invoke(connect_t, _Self&& __self, _Receiver __rcvr) noexcept(__nothrow_connectable<_Sender, __receiver<_Receiver>>) -> connect_result_t<__copy_cvref_t<_Self, _Sender>, __receiver<_Receiver>> { return stdexec::connect( ((_Self&&) __self).__sndr_, __receiver<_Receiver>{(_Receiver&&) __rcvr, ((_Self&&) __self).__fun_}); } template <__decays_to<__t> _Self, class _Env> friend auto tag_invoke(get_completion_signatures_t, _Self&&, _Env&&) -> dependent_completion_signatures<_Env>; template <__decays_to<__t> _Self, class _Env> friend auto tag_invoke(get_completion_signatures_t, _Self&&, _Env&&) -> __completion_signatures<_Self, _Env> requires true; friend auto tag_invoke(get_env_t, const __t& __self) noexcept -> env_of_t<const _Sender&> { return get_env(__self.__sndr_); } }; }; struct upon_stopped_t { template <class _Sender, class _Fun> using __sender = __t<__sender<__id<__decay_t<_Sender>>, _Fun>>; template <sender _Sender, __movable_value _Fun> requires __tag_invocable_with_domain<upon_stopped_t, set_stopped_t, _Sender, _Fun> && __callable<_Fun> sender auto operator()(_Sender&& __sndr, _Fun __fun) const noexcept(nothrow_tag_invocable< upon_stopped_t, __sender_domain_of_t<_Sender, set_stopped_t>, _Sender, _Fun>) { auto __domain = __get_sender_domain(__sndr, set_stopped); return tag_invoke(upon_stopped_t{}, __domain, (_Sender&&) __sndr, (_Fun&&) __fun); } template <sender _Sender, __movable_value _Fun> requires(!__tag_invocable_with_domain<upon_stopped_t, set_stopped_t, _Sender, _Fun>) && tag_invocable<upon_stopped_t, _Sender, _Fun> && __callable<_Fun> sender auto operator()(_Sender&& __sndr, _Fun __fun) const noexcept(nothrow_tag_invocable<upon_stopped_t, _Sender, _Fun>) { return tag_invoke(upon_stopped_t{}, (_Sender&&) __sndr, (_Fun&&) __fun); } template <sender _Sender, __movable_value _Fun> requires(!__tag_invocable_with_domain<upon_stopped_t, set_stopped_t, _Sender, _Fun>) && (!tag_invocable<upon_stopped_t, _Sender, _Fun>) && __callable<_Fun> && sender<__sender<_Sender, _Fun>> __sender<_Sender, _Fun> operator()(_Sender&& __sndr, _Fun __fun) const { return __sender<_Sender, _Fun>{(_Sender&&) __sndr, (_Fun&&) __fun}; } template <__callable _Fun> __binder_back<upon_stopped_t, _Fun> operator()(_Fun __fun) const { return {{}, {}, {(_Fun&&) __fun}}; } }; } using __upon_stopped::upon_stopped_t; inline constexpr upon_stopped_t upon_stopped{}; namespace __bulk { inline constexpr __mstring __bulk_context = "In stdexec::bulk(Sender, Shape, Function)..."__csz; using __on_not_callable = __callable_error<__bulk_context>; template <class _ReceiverId, integral _Shape, class _Fun> struct __receiver { using _Receiver = stdexec::__t<_ReceiverId>; class __t : receiver_adaptor<__t, _Receiver> { friend receiver_adaptor<__t, _Receiver>; [[no_unique_address]] _Shape __shape_; [[no_unique_address]] _Fun __f_; template <class... _As> void set_value(_As&&... __as) && noexcept requires __nothrow_callable<_Fun, _Shape, _As&...> { for (_Shape __i{}; __i != __shape_; ++__i) { __f_(__i, __as...); } stdexec::set_value(std::move(this->base()), (_As&&) __as...); } template <class... _As> void set_value(_As&&... __as) && noexcept requires __callable<_Fun, _Shape, _As&...> { try { for (_Shape __i{}; __i != __shape_; ++__i) { __f_(__i, __as...); } stdexec::set_value(std::move(this->base()), (_As&&) __as...); } catch (...) { stdexec::set_error(std::move(this->base()), std::current_exception()); } } public: using __id = __receiver; explicit __t(_Receiver __rcvr, _Shape __shape, _Fun __fun) : receiver_adaptor<__t, _Receiver>((_Receiver&&) __rcvr) , __shape_(__shape) , __f_((_Fun&&) __fun) { } }; }; template <class _Ty> using __decay_ref = __decay_t<_Ty>&; template <class _SenderId, integral _Shape, class _Fun> struct __sender { using _Sender = stdexec::__t<_SenderId>; template <receiver _Receiver> using __receiver = stdexec::__t<__receiver<stdexec::__id<_Receiver>, _Shape, _Fun>>; struct __t { using __id = __sender; using is_sender = void; [[no_unique_address]] _Sender __sndr_; [[no_unique_address]] _Shape __shape_; [[no_unique_address]] _Fun __fun_; template <class _Sender, class _Env, class _Catch> using __with_error_invoke_t = __if< __try_value_types_of_t< _Sender, _Env, __transform< __q<__decay_ref>, __mbind_front<__mtry_catch_q<__non_throwing_, _Catch>, _Fun, _Shape>>, __q<__mand>>, completion_signatures<>, __with_exception_ptr>; template <class _Self, class _Env> using __completion_signatures = __try_make_completion_signatures< __copy_cvref_t<_Self, _Sender>, _Env, __with_error_invoke_t<__copy_cvref_t<_Self, _Sender>, _Env, __on_not_callable>>; template <__decays_to<__t> _Self, receiver _Receiver> requires sender_to<__copy_cvref_t<_Self, _Sender>, __receiver<_Receiver>> friend auto tag_invoke(connect_t, _Self&& __self, _Receiver __rcvr) noexcept(__nothrow_connectable<__copy_cvref_t<_Self, _Sender>, __receiver<_Receiver>>) -> connect_result_t<__copy_cvref_t<_Self, _Sender>, __receiver<_Receiver>> { return stdexec::connect( ((_Self&&) __self).__sndr_, __receiver<_Receiver>{ (_Receiver&&) __rcvr, __self.__shape_, ((_Self&&) __self).__fun_}); } template <__decays_to<__t> _Self, class _Env> friend auto tag_invoke(get_completion_signatures_t, _Self&&, _Env&&) -> dependent_completion_signatures<_Env>; template <__decays_to<__t> _Self, class _Env> friend auto tag_invoke(get_completion_signatures_t, _Self&&, _Env&&) -> __completion_signatures<_Self, _Env> requires true; friend auto tag_invoke(get_env_t, const __t& __self) noexcept -> env_of_t<const _Sender&> { return get_env(__self.__sndr_); } }; }; struct bulk_t { template <sender _Sender, integral _Shape, class _Fun> using __sender = __t<__sender<stdexec::__id<__decay_t<_Sender>>, _Shape, _Fun>>; template <sender _Sender, integral _Shape, __movable_value _Fun> requires __tag_invocable_with_domain<bulk_t, set_value_t, _Sender, _Shape, _Fun> sender auto operator()(_Sender&& __sndr, _Shape __shape, _Fun __fun) const noexcept( nothrow_tag_invocable< bulk_t, __sender_domain_of_t<_Sender>, _Sender, _Shape, _Fun>) { auto __domain = __get_sender_domain(__sndr); return tag_invoke( bulk_t{}, __domain, (_Sender&&) __sndr, (_Shape&&) __shape, (_Fun&&) __fun); } template <sender _Sender, integral _Shape, __movable_value _Fun> requires(!__tag_invocable_with_domain<bulk_t, set_value_t, _Sender, _Shape, _Fun>) && tag_invocable<bulk_t, _Sender, _Shape, _Fun> sender auto operator()(_Sender&& __sndr, _Shape __shape, _Fun __fun) const noexcept(nothrow_tag_invocable<bulk_t, _Sender, _Shape, _Fun>) { return tag_invoke(bulk_t{}, (_Sender&&) __sndr, (_Shape&&) __shape, (_Fun&&) __fun); } template <sender _Sender, integral _Shape, __movable_value _Fun> requires(!__tag_invocable_with_domain<bulk_t, set_value_t, _Sender, _Shape, _Fun>) && (!tag_invocable<bulk_t, _Sender, _Shape, _Fun>) __sender<_Sender, _Shape, _Fun> operator()(_Sender&& __sndr, _Shape __shape, _Fun __fun) const { return __sender<_Sender, _Shape, _Fun>{(_Sender&&) __sndr, __shape, (_Fun&&) __fun}; } template <integral _Shape, class _Fun> __binder_back<bulk_t, _Shape, _Fun> operator()(_Shape __shape, _Fun __fun) const { return { {}, {}, {(_Shape&&) __shape, (_Fun&&) __fun} }; } }; } using __bulk::bulk_t; inline constexpr bulk_t bulk{}; namespace __split { template <class _BaseEnv> using __env_t = __make_env_t< _BaseEnv, __with<get_stop_token_t, in_place_stop_token>>; template <class _CvrefSenderId, class _EnvId> struct __sh_state; template <class _CvrefSenderId, class _EnvId> struct __receiver { using _CvrefSender = stdexec::__cvref_t<_CvrefSenderId>; using _Env = stdexec::__t<_EnvId>; class __t { stdexec::__t<__sh_state<_CvrefSenderId, _EnvId>>& __sh_state_; public: using is_receiver = void; using __id = __receiver; template <__completion_tag _Tag, class... _As> friend void tag_invoke(_Tag __tag, __t&& __self, _As&&... __as) noexcept { stdexec::__t<__sh_state<_CvrefSenderId, _EnvId>>& __state = __self.__sh_state_; try { using __tuple_t = __decayed_tuple<_Tag, _As...>; __state.__data_.template emplace<__tuple_t>(__tag, (_As&&) __as...); } catch (...) { using __tuple_t = __decayed_tuple<set_error_t, std::exception_ptr>; __state.__data_.template emplace<__tuple_t>(set_error, std::current_exception()); } __state.__notify(); } friend const __env_t<_Env>& tag_invoke(get_env_t, const __t& __self) noexcept { return __self.__sh_state_.__env_; } explicit __t(stdexec::__t<__sh_state<_CvrefSenderId, _EnvId>>& __sh_state) noexcept : __sh_state_(__sh_state) { } }; }; struct __operation_base { using __notify_fn = void(__operation_base*) noexcept; __operation_base* __next_{}; __notify_fn* __notify_{}; }; template <class _CvrefSenderId, class _EnvId> struct __sh_state { using _CvrefSender = stdexec::__cvref_t<_CvrefSenderId>; using _Env = stdexec::__t<_EnvId>; struct __t { using __id = __sh_state; template <class... _Ts> using __bind_tuples = __mbind_front_q< __variant, std::tuple<set_stopped_t>, std::tuple<set_error_t, std::exception_ptr>, _Ts...>; using __bound_values_t = __value_types_of_t< _CvrefSender, __env_t<_Env>, __mbind_front_q<__decayed_tuple, set_value_t>, __q<__bind_tuples>>; using __variant_t = __error_types_of_t< _CvrefSender, __env_t<_Env>, __transform< __mbind_front_q<__decayed_tuple, set_error_t>, __bound_values_t>>; using __receiver_ = stdexec::__t<__receiver<_CvrefSenderId, _EnvId>>; void* const __token_{(void*) 0xDEADBEEF}; in_place_stop_source __stop_source_{}; __variant_t __data_; std::atomic<void*> __head_{nullptr}; __env_t<_Env> __env_; connect_result_t<_CvrefSender, __receiver_> __op_state2_; explicit __t(_CvrefSender&& __sndr, _Env __env) : __env_(__make_env((_Env&&) __env, __with_(get_stop_token, __stop_source_.get_token()))) , __op_state2_(connect((_CvrefSender&&) __sndr, __receiver_{*this})) { } void __notify() noexcept { void* const __completion_state = static_cast<void*>(this); void* __old = __head_.exchange(__completion_state, std::memory_order_acq_rel); __operation_base* __op_state = static_cast<__operation_base*>(__old); while (__op_state != nullptr) { __operation_base* __next = __op_state->__next_; __op_state->__notify_(__op_state); __op_state = __next; } } }; }; template <class _CvrefSenderId, class _EnvId, class _ReceiverId> struct __operation { using _CvrefSender = stdexec::__cvref_t<_CvrefSenderId>; using _Env = stdexec::__t<_EnvId>; using _Receiver = stdexec::__t<_ReceiverId>; class __t : public __operation_base { struct __on_stop_requested { in_place_stop_source& __stop_source_; void operator()() noexcept { __stop_source_.request_stop(); } }; using __on_stop = std::optional<typename stop_token_of_t< env_of_t<_Receiver>&>::template callback_type< __on_stop_requested>>; _Receiver __rcvr_; __on_stop __on_stop_{}; std::shared_ptr<stdexec::__t<__sh_state<_CvrefSenderId, _EnvId>>> __shared_state_; public: using __id = __operation; __t( _Receiver&& __rcvr, std::shared_ptr<stdexec::__t<__sh_state<_CvrefSenderId, _EnvId>>> __shared_state) noexcept(std::is_nothrow_move_constructible_v<_Receiver>) : __operation_base{nullptr, __notify} , __rcvr_((_Receiver&&) __rcvr) , __shared_state_(std::move(__shared_state)) { } __t(__t&&) = delete; static void __notify(__operation_base* __self) noexcept { __t* __op = static_cast<__t*>(__self); __op->__on_stop_.reset(); std::visit( [&](const auto& __tupl) noexcept -> void { std::apply( [&](auto __tag, const auto&... __args) noexcept -> void { __tag((_Receiver&&) __op->__rcvr_, __args...); }, __tupl); }, __op->__shared_state_->__data_); } friend void tag_invoke(start_t, __t& __self) noexcept { stdexec::__t<__sh_state<_CvrefSenderId, _EnvId>>* __shared_state = __self.__shared_state_.get(); do { static_assert(noexcept(__shared_state->__token_ == (void*) 0xDEADBEEF)); assert(__shared_state->__token_ == (void*) 0xDEADBEEF); } while (false); std::atomic<void*>& __head = __shared_state->__head_; void* const __completion_state = static_cast<void*>(__shared_state); void* __old = __head.load(std::memory_order_acquire); if (__old != __completion_state) { __self.__on_stop_.emplace( get_stop_token(get_env(__self.__rcvr_)), __on_stop_requested{__shared_state->__stop_source_}); } do { if (__old == __completion_state) { __self.__notify(&__self); return; } __self.__next_ = static_cast<__operation_base*>(__old); } while (!__head.compare_exchange_weak( __old, static_cast<void*>(&__self), std::memory_order_release, std::memory_order_acquire)); if (__old == nullptr) { if (__shared_state->__stop_source_.stop_requested()) { __shared_state->__notify(); } else { start(__shared_state->__op_state2_); } } } }; }; template <class _CvrefSenderId, class _EnvId> struct __sender { using _CvrefSender = stdexec::__cvref_t<_CvrefSenderId>; using _Env = stdexec::__t<_EnvId>; template <class _Receiver> using __operation = stdexec::__t<__operation<_CvrefSenderId, _EnvId, stdexec::__id<_Receiver>>>; struct __t { using __id = __sender; using is_sender = void; explicit __t(_CvrefSender&& __sndr, _Env __env) : __shared_state_{ std::make_shared<__sh_state_>(static_cast<_CvrefSender&&>(__sndr), (_Env&&) __env)} { } private: using __sh_state_ = stdexec::__t<__sh_state<_CvrefSenderId, _EnvId>>; template <class... _Tys> using __set_value_t = completion_signatures<set_value_t(const __decay_t<_Tys>&...)>; template <class _Ty> using __set_error_t = completion_signatures<set_error_t(const __decay_t<_Ty>&)>; template <class _Self> using __completions_t = __try_make_completion_signatures< _CvrefSender, __env_t<__mfront<_Env, _Self>>, completion_signatures< set_error_t(const std::exception_ptr&), set_stopped_t()>, __q<__set_value_t>, __q<__set_error_t>>; std::shared_ptr<__sh_state_> __shared_state_; template <__decays_to<__t> _Self, receiver_of<__completions_t<_Self>> _Receiver> friend auto tag_invoke(connect_t, _Self&& __self, _Receiver __recvr) noexcept(std::is_nothrow_move_constructible_v<_Receiver>) -> __operation<_Receiver> { return __operation<_Receiver>{(_Receiver&&) __recvr, __self.__shared_state_}; } template <__decays_to<__t> _Self, class _OtherEnv> friend auto tag_invoke(get_completion_signatures_t, _Self&&, _OtherEnv&&) -> __completions_t<_Self>; }; }; struct split_t; using _Sender = __0; using _Env = __1; using __cust_sigs = __types< tag_invoke_t( split_t, get_completion_scheduler_t<set_value_t>(get_env_t(const _Sender&)), _Sender), tag_invoke_t( split_t, get_completion_scheduler_t<set_value_t>(get_env_t(const _Sender&)), _Sender, _Env), tag_invoke_t(split_t, get_scheduler_t(_Env&), _Sender), tag_invoke_t(split_t, get_scheduler_t(_Env&), _Sender, _Env), tag_invoke_t(split_t, _Sender), tag_invoke_t(split_t, _Sender, _Env)>; template <class _Sender, class _Env> inline constexpr bool __is_split_customized = __minvocable<__which<__cust_sigs>, _Sender, _Env>; template <class _Sender, class _Env> using __sender_t = __t<__sender<stdexec::__cvref_id<_Sender>, stdexec::__id<__decay_t<_Env>>>>; template <class _Sender, class _Env> using __dispatcher_for = __make_dispatcher<__cust_sigs, __mconstructor_for<__sender_t>, _Sender, _Env>; struct split_t { template <sender _Sender, class _Env = empty_env> requires(sender_in<_Sender, _Env> && __decay_copyable<env_of_t<_Sender>>) || __is_split_customized<_Sender, _Env> auto operator()(_Sender&& __sndr, _Env&& __env = _Env{}) const noexcept(__nothrow_callable<__dispatcher_for<_Sender, _Env>, _Sender, _Env>) -> __call_result_t<__dispatcher_for<_Sender, _Env>, _Sender, _Env> { return __dispatcher_for<_Sender, _Env>{}((_Sender&&) __sndr, (_Env&&) __env); } __binder_back<split_t> operator()() const { return {{}, {}, {}}; } }; } using __split::split_t; inline constexpr split_t split{}; namespace __ensure_started { template <class _BaseEnv> using __env_t = __make_env_t< _BaseEnv, __with<get_stop_token_t, in_place_stop_token>>; template <class _CvrefSenderId, class _EnvId> struct __sh_state; template <class _CvrefSenderId, class _EnvId> struct __receiver { using _CvrefSender = stdexec::__cvref_t<_CvrefSenderId>; using _Env = stdexec::__t<_EnvId>; class __t { __intrusive_ptr<stdexec::__t<__sh_state<_CvrefSenderId, _EnvId>>> __shared_state_; public: using is_receiver = void; using __id = __receiver; explicit __t(stdexec::__t<__sh_state<_CvrefSenderId, _EnvId>>& __shared_state) noexcept : __shared_state_(__shared_state.__intrusive_from_this()) { } template <__completion_tag _Tag, class... _As> friend void tag_invoke(_Tag __tag, __t&& __self, _As&&... __as) noexcept { stdexec::__t<__sh_state<_CvrefSenderId, _EnvId>>& __state = *__self.__shared_state_; try { using __tuple_t = __decayed_tuple<_Tag, _As...>; __state.__data_.template emplace<__tuple_t>(__tag, (_As&&) __as...); } catch (...) { using __tuple_t = __decayed_tuple<set_error_t, std::exception_ptr>; __state.__data_.template emplace<__tuple_t>(set_error, std::current_exception()); } __state.__notify(); __self.__shared_state_.reset(); } friend const __env_t<_Env>& tag_invoke(get_env_t, const __t& __self) noexcept { return __self.__shared_state_->__env_; } }; }; struct __operation_base { using __notify_fn = void(__operation_base*) noexcept; __notify_fn* __notify_{}; }; template <class _CvrefSenderId, class _EnvId> struct __sh_state { using _CvrefSender = stdexec::__cvref_t<_CvrefSenderId>; using _Env = stdexec::__t<_EnvId>; struct __t : __enable_intrusive_from_this<__t> { using __id = __sh_state; template <class... _Ts> using __bind_tuples = __mbind_front_q< __variant, std::tuple<set_stopped_t>, std::tuple<set_error_t, std::exception_ptr>, _Ts...>; using __bound_values_t = __value_types_of_t< _CvrefSender, __env_t<_Env>, __mbind_front_q<__decayed_tuple, set_value_t>, __q<__bind_tuples>>; using __variant_t = __error_types_of_t< _CvrefSender, __env_t<_Env>, __transform< __mbind_front_q<__decayed_tuple, set_error_t>, __bound_values_t>>; using __receiver_t = stdexec::__t<__receiver<_CvrefSenderId, _EnvId>>; __variant_t __data_; in_place_stop_source __stop_source_{}; std::atomic<void*> __op_state1_{nullptr}; __env_t<_Env> __env_; connect_result_t<_CvrefSender, __receiver_t> __op_state2_; explicit __t(_CvrefSender&& __sndr, _Env __env) : __env_(__make_env((_Env&&) __env, __with_(get_stop_token, __stop_source_.get_token()))) , __op_state2_(connect((_CvrefSender&&) __sndr, __receiver_t{*this})) { start(__op_state2_); } void __notify() noexcept { void* const __completion_state = static_cast<void*>(this); void* const __old = __op_state1_.exchange(__completion_state, std::memory_order_acq_rel); if (__old != nullptr) { auto* __op = static_cast<__operation_base*>(__old); __op->__notify_(__op); } } void __detach() noexcept { __stop_source_.request_stop(); } }; }; template <class _CvrefSenderId, class _EnvId, class _ReceiverId> struct __operation { using _CvrefSender = stdexec::__cvref_t<_CvrefSenderId>; using _Env = stdexec::__t<_EnvId>; using _Receiver = stdexec::__t<_ReceiverId>; class __t : public __operation_base { struct __on_stop_requested { in_place_stop_source& __stop_source_; void operator()() noexcept { __stop_source_.request_stop(); } }; using __on_stop = std::optional< typename stop_token_of_t< env_of_t<_Receiver>&>::template callback_type< __on_stop_requested>>; _Receiver __rcvr_; __on_stop __on_stop_{}; __intrusive_ptr<stdexec::__t<__sh_state<_CvrefSenderId, _EnvId>>> __shared_state_; public: using __id = __operation; __t( _Receiver __rcvr, __intrusive_ptr<stdexec::__t<__sh_state<_CvrefSenderId, _EnvId>>> __shared_state) noexcept(std::is_nothrow_move_constructible_v<_Receiver>) : __operation_base{__notify} , __rcvr_((_Receiver&&) __rcvr) , __shared_state_(std::move(__shared_state)) { } ~__t() { if (nullptr == __shared_state_->__op_state1_.load(std::memory_order_acquire)) { __shared_state_->__detach(); } } __t(__t&&) = delete; static void __notify(__operation_base* __self) noexcept { __t* __op = static_cast<__t*>(__self); __op->__on_stop_.reset(); std::visit( [&](auto& __tupl) noexcept -> void { std::apply( [&](auto __tag, auto&... __args) noexcept -> void { __tag((_Receiver&&) __op->__rcvr_, std::move(__args)...); }, __tupl); }, __op->__shared_state_->__data_); } friend void tag_invoke(start_t, __t& __self) noexcept { stdexec::__t<__sh_state<_CvrefSenderId, _EnvId>>* __shared_state = __self.__shared_state_.get(); std::atomic<void*>& __op_state1 = __shared_state->__op_state1_; void* const __completion_state = static_cast<void*>(__shared_state); void* const __old = __op_state1.load(std::memory_order_acquire); if (__old == __completion_state) { __self.__notify(&__self); } else { __self.__on_stop_.emplace( get_stop_token(get_env(__self.__rcvr_)), __on_stop_requested{__shared_state->__stop_source_}); if (__shared_state->__stop_source_.stop_requested()) { stdexec::set_stopped((_Receiver&&) __self.__rcvr_); } else { void* __old = nullptr; if (!__op_state1.compare_exchange_weak( __old, &__self, std::memory_order_release, std::memory_order_acquire)) { do { static_assert(noexcept(__old == __completion_state)); assert(__old == __completion_state); } while (false); __self.__notify(&__self); } } } } }; }; template <class _CvrefSenderId, class _EnvId> struct __sender { using _CvrefSender = stdexec::__cvref_t<_CvrefSenderId>; using _Env = stdexec::__t<_EnvId>; struct __t { using __id = __sender; using is_sender = void; explicit __t(_CvrefSender __sndr, _Env __env) : __shared_state_{ __make_intrusive<__sh_state_>((_CvrefSender&&) __sndr, (_Env&&) __env)} { } ~__t() { if (nullptr != __shared_state_) { __shared_state_->__detach(); } } __t(__t&&) = default; private: using __sh_state_ = stdexec::__t<__sh_state<_CvrefSenderId, _EnvId>>; template <class _Receiver> using __operation = stdexec::__t<__operation<_CvrefSenderId, _EnvId, stdexec::__id<_Receiver>>>; template <class... _Tys> using __set_value_t = completion_signatures<set_value_t(__decay_t<_Tys>&&...)>; template <class _Ty> using __set_error_t = completion_signatures<set_error_t(__decay_t<_Ty>&&)>; template <class _Self> using __completions_t = __try_make_completion_signatures< _CvrefSender, __env_t<__mfront<_Env, _Self>>, completion_signatures< set_error_t(std::exception_ptr&&), set_stopped_t()>, __q<__set_value_t>, __q<__set_error_t>>; __intrusive_ptr<__sh_state_> __shared_state_; template <same_as<__t> _Self, receiver_of<__completions_t<_Self>> _Receiver> friend auto tag_invoke(connect_t, _Self&& __self, _Receiver __rcvr) noexcept(std::is_nothrow_move_constructible_v<_Receiver>) -> __operation<_Receiver> { return __operation<_Receiver>{(_Receiver&&) __rcvr, std::move(__self).__shared_state_}; } template <same_as<__t> _Self, class _OtherEnv> friend auto tag_invoke(get_completion_signatures_t, _Self&&, _OtherEnv&&) -> __completions_t<_Self>; }; }; struct ensure_started_t; using _CvrefSender = __0; using _Env = __1; using __cust_sigs = __types< tag_invoke_t( ensure_started_t, get_completion_scheduler_t<set_value_t>(get_env_t(const _CvrefSender&)), _CvrefSender), tag_invoke_t( ensure_started_t, get_completion_scheduler_t<set_value_t>(get_env_t(const _CvrefSender&)), _CvrefSender, _Env), tag_invoke_t(ensure_started_t, get_scheduler_t(_Env&), _CvrefSender), tag_invoke_t(ensure_started_t, get_scheduler_t(_Env&), _CvrefSender, _Env), tag_invoke_t(ensure_started_t, _CvrefSender), tag_invoke_t(ensure_started_t, _CvrefSender, _Env)>; template <class _CvrefSender, class _Env> inline constexpr bool __is_ensure_started_customized = __minvocable<__which<__cust_sigs>, _CvrefSender, _Env>; template <class _Sender, class _Env> using __sender_t = __t<__sender<stdexec::__cvref_id<_Sender, _Sender>, stdexec::__id<__decay_t<_Env>>>>; template <class _Sender> concept __ensure_started_sender = __is_instance_of<__id<__decay_t<_Sender>>, __sender>; template <class _Sender> using __fallback = __if_c<__ensure_started_sender<_Sender>, __mconst<__first>, __mconstructor_for<__sender_t>>; template <class _Sender, class _Env> using __dispatcher_for = __make_dispatcher<__cust_sigs, __fallback<_Sender>, _Sender, _Env>; struct ensure_started_t { template <sender _Sender, class _Env = empty_env> requires(sender_in<_Sender, _Env> && __decay_copyable<env_of_t<_Sender>>) || __is_ensure_started_customized<_Sender, _Env> auto operator()(_Sender&& __sndr, _Env&& __env = _Env{}) const noexcept(__nothrow_callable<__dispatcher_for<_Sender, _Env>, _Sender, _Env>) -> __call_result_t<__dispatcher_for<_Sender, _Env>, _Sender, _Env> { return __dispatcher_for<_Sender, _Env>{}((_Sender&&) __sndr, (_Env&&) __env); } __binder_back<ensure_started_t> operator()() const { return {{}, {}, {}}; } }; } using __ensure_started::ensure_started_t; inline constexpr ensure_started_t ensure_started{}; namespace __let { template <class _Set> struct __on_not_callable_ { using __t = __callable_error<"In stdexec::let_value(Sender, Function)..."__csz>; }; template <> struct __on_not_callable_<set_error_t> { using __t = __callable_error<"In stdexec::let_error(Sender, Function)..."__csz>; }; template <> struct __on_not_callable_<set_stopped_t> { using __t = __callable_error<"In stdexec::let_stopped(Sender, Function)..."__csz>; }; template <class _Set> using __on_not_callable = __t<__on_not_callable_<_Set>>; template <class _Tp> using __decay_ref = __decay_t<_Tp>&; template <class _Fun, class _Set> using __result_sender = __transform< __q<__decay_ref>, __mbind_front<__mtry_catch_q<__call_result_t, __on_not_callable<_Set>>, _Fun>>; template <class _Receiver, class _Fun, class _Set> using __op_state_for = __mcompose< __mbind_back_q<connect_result_t, _Receiver>, __result_sender<_Fun, _Set>>; template <class _Set, class _Sig> struct __tfx_signal_ { template <class, class> using __f = completion_signatures<_Sig>; }; template <class _Set, class... _Args> struct __tfx_signal_<_Set, _Set(_Args...)> { template <class _Env, class _Fun> using __f = __try_make_completion_signatures< __minvoke<__result_sender<_Fun, _Set>, _Args...>, _Env, completion_signatures<set_error_t(std::exception_ptr)>>; }; template <class _Env, class _Fun, class _Set, class _Sig> using __tfx_signal_t = __minvoke<__tfx_signal_<_Set, _Sig>, _Env, _Fun>; template <class _ReceiverId, class _Fun, class _Set, class... _Tuples> struct __operation_base_ { using _Receiver = stdexec::__t<_ReceiverId>; struct __t : __immovable { using __id = __operation_base_; using __results_variant_t = std::variant<std::monostate, _Tuples...>; using __op_state_variant_t = __minvoke< __transform< __uncurry<__op_state_for<_Receiver, _Fun, _Set>>, __nullable_variant_t>, _Tuples...>; _Receiver __rcvr_; _Fun __fun_; __results_variant_t __args_; __op_state_variant_t __op_state3_; }; }; template <class _ReceiverId, class _Fun, class _Set, class... _Tuples> struct __receiver_ { using _Receiver = stdexec::__t<_ReceiverId>; using _Env = env_of_t<_Receiver>; struct __t { using is_receiver = void; using __id = __receiver_; template <__one_of<_Set> _Tag, class... _As> requires(1 == __v<__minvoke<__mcount<__decayed_tuple<_As...>>, _Tuples...>>) && __minvocable<__result_sender<_Fun, _Set>, _As...> && sender_to<__minvoke<__result_sender<_Fun, _Set>, _As...>, _Receiver> friend void tag_invoke(_Tag, __t&& __self, _As&&... __as) noexcept { try { using __tuple_t = __decayed_tuple<_As...>; using __op_state_t = __minvoke<__op_state_for<_Receiver, _Fun, _Set>, _As...>; auto& __args = __self.__op_state_->__args_.template emplace<__tuple_t>((_As&&) __as...); auto& __op = __self.__op_state_->__op_state3_.template emplace<__op_state_t>( __conv{[&] { return connect( std::apply(std::move(__self.__op_state_->__fun_), __args), std::move(__self.__op_state_->__rcvr_)); }}); start(__op); } catch (...) { set_error(std::move(__self.__op_state_->__rcvr_), std::current_exception()); } } template <__completion_tag _Tag, class... _As> requires __none_of<_Tag, _Set> && __callable<_Tag, _Receiver, _As...> friend void tag_invoke(_Tag __tag, __t&& __self, _As&&... __as) noexcept { __tag(std::move(__self.__op_state_->__rcvr_), (_As&&) __as...); } friend auto tag_invoke(get_env_t, const __t& __self) noexcept -> env_of_t<_Receiver> { return get_env(__self.__op_state_->__rcvr_); } using __operation_base_t = stdexec::__t<__operation_base_<_ReceiverId, _Fun, _Set, _Tuples...>>; __operation_base_t* __op_state_; }; }; template <class _CvrefSenderId, class _ReceiverId, class _Fun, class _Set> using __receiver = stdexec::__t< __gather_completions_for< _Set, __cvref_t<_CvrefSenderId>, env_of_t<__t<_ReceiverId>>, __q<__decayed_tuple>, __munique<__mbind_front_q<__receiver_, _ReceiverId, _Fun, _Set>>>>; template <class _CvrefSenderId, class _ReceiverId, class _Fun, class _Set> using __operation_base = typename __receiver<_CvrefSenderId, _ReceiverId, _Fun, _Set>::__operation_base_t; template <class _CvrefSenderId, class _ReceiverId, class _Fun, class _Set> struct __operation { using _Sender = stdexec::__cvref_t<_CvrefSenderId>; struct __t : __operation_base<_CvrefSenderId, _ReceiverId, _Fun, _Set> { using __id = __operation; using __op_base_t = __operation_base<_CvrefSenderId, _ReceiverId, _Fun, _Set>; using __receiver_t = __receiver<_CvrefSenderId, _ReceiverId, _Fun, _Set>; friend void tag_invoke(start_t, __t& __self) noexcept { start(__self.__op_state2_); } template <class _Receiver2> __t(_Sender&& __sndr, _Receiver2&& __rcvr, _Fun __fun) : __op_base_t{{}, (_Receiver2&&) __rcvr, (_Fun&&) __fun} , __op_state2_(connect((_Sender&&) __sndr, __receiver_t{this})) { } connect_result_t<_Sender, __receiver_t> __op_state2_; }; }; template <class _SenderId, class _Fun, class _SetId> struct __sender { using _Sender = stdexec::__t<_SenderId>; using _Set = stdexec::__t<_SetId>; struct __t { using __id = __sender; using is_sender = void; template <class _Self, class _Receiver> using __operation_t = stdexec::__t< __operation< stdexec::__cvref_id<_Self, _Sender>, stdexec::__id<_Receiver>, _Fun, _Set>>; template <class _Self, class _Receiver> using __receiver_t = __receiver< stdexec::__cvref_id<_Self, _Sender>, stdexec::__id<_Receiver>, _Fun, _Set>; template <class _Sender, class _Env> using __completions = __mapply< __transform< __mbind_front_q<__tfx_signal_t, _Env, _Fun, _Set>, __q<__concat_completion_signatures_t>>, __completion_signatures_of_t<_Sender, _Env>>; template <__decays_to<__t> _Self, receiver _Receiver> requires sender_to<__copy_cvref_t<_Self, _Sender>, __receiver_t<_Self, _Receiver>> friend auto tag_invoke(connect_t, _Self&& __self, _Receiver __rcvr) -> __operation_t<_Self, _Receiver> { return __operation_t<_Self, _Receiver>{ ((_Self&&) __self).__sndr_, (_Receiver&&) __rcvr, ((_Self&&) __self).__fun_}; } friend auto tag_invoke(get_env_t, const __t& __self) noexcept -> env_of_t<const _Sender&> { return get_env(__self.__sndr_); } template <__decays_to<__t> _Self, class _Env> friend auto tag_invoke(get_completion_signatures_t, _Self&&, _Env&&) -> dependent_completion_signatures<_Env>; template <__decays_to<__t> _Self, class _Env> friend auto tag_invoke(get_completion_signatures_t, _Self&&, _Env&&) -> __completions<__copy_cvref_t<_Self, _Sender>, _Env> requires true; _Sender __sndr_; _Fun __fun_; }; }; template <class _LetTag, class _SetTag> struct __let_xxx_t { using __t = _SetTag; template <class _Sender, class _Fun> using __sender = stdexec::__t<__let::__sender<stdexec::__id<__decay_t<_Sender>>, _Fun, _LetTag>>; template <sender _Sender, __movable_value _Fun> requires __tag_invocable_with_domain<_LetTag, set_value_t, _Sender, _Fun> sender auto operator()(_Sender&& __sndr, _Fun __fun) const noexcept(nothrow_tag_invocable<_LetTag, __sender_domain_of_t<_Sender>, _Sender, _Fun>) { auto __domain = __get_sender_domain(__sndr); return tag_invoke(_LetTag{}, __domain, (_Sender&&) __sndr, (_Fun&&) __fun); } template <sender _Sender, __movable_value _Fun> requires(!__tag_invocable_with_domain<_LetTag, set_value_t, _Sender, _Fun>) && tag_invocable<_LetTag, _Sender, _Fun> sender auto operator()(_Sender&& __sndr, _Fun __fun) const noexcept(nothrow_tag_invocable<_LetTag, _Sender, _Fun>) { return tag_invoke(_LetTag{}, (_Sender&&) __sndr, (_Fun&&) __fun); } template <sender _Sender, __movable_value _Fun> requires(!__tag_invocable_with_domain<_LetTag, set_value_t, _Sender, _Fun>) && (!tag_invocable<_LetTag, _Sender, _Fun>) && sender<__sender<_Sender, _Fun>> __sender<_Sender, _Fun> operator()(_Sender&& __sndr, _Fun __fun) const { return __sender<_Sender, _Fun>{(_Sender&&) __sndr, (_Fun&&) __fun}; } template <class _Fun> __binder_back<_LetTag, _Fun> operator()(_Fun __fun) const { return {{}, {}, {(_Fun&&) __fun}}; } }; struct let_value_t : __let::__let_xxx_t<let_value_t, set_value_t> { }; struct let_error_t : __let::__let_xxx_t<let_error_t, set_error_t> { }; struct let_stopped_t : __let::__let_xxx_t<let_stopped_t, set_stopped_t> { }; } using __let::let_value_t; inline constexpr let_value_t let_value{}; using __let::let_error_t; inline constexpr let_error_t let_error{}; using __let::let_stopped_t; inline constexpr let_stopped_t let_stopped{}; namespace __stopped_as_xxx { template <class _CvrefSenderId, class _ReceiverId> struct __operation; template <class _CvrefSenderId, class _ReceiverId> struct __receiver { using _Sender = stdexec::__t<_CvrefSenderId>; using _Receiver = stdexec::__t<_ReceiverId>; struct __t : receiver_adaptor<__t> { using __id = __receiver; _Receiver&& base() && noexcept { return (_Receiver&&) __op_->__rcvr_; } const _Receiver& base() const & noexcept { return __op_->__rcvr_; } template <class _Ty> void set_value(_Ty&& __a) && noexcept { try { using _Value = __decay_t<__single_sender_value_t<_Sender, env_of_t<_Receiver>>>; static_assert(constructible_from<_Value, _Ty>); stdexec::set_value(((__t&&) *this).base(), std::optional<_Value>{(_Ty&&) __a}); } catch (...) { stdexec::set_error(((__t&&) *this).base(), std::current_exception()); } } void set_stopped() && noexcept { using _Value = __decay_t<__single_sender_value_t<_Sender, env_of_t<_Receiver>>>; stdexec::set_value(((__t&&) *this).base(), std::optional<_Value>{std::nullopt}); } stdexec::__t<__operation<_CvrefSenderId, _ReceiverId>>* __op_; }; }; template <class _CvrefSenderId, class _ReceiverId> struct __operation { using _Sender = stdexec::__t<_CvrefSenderId>; using _Receiver = stdexec::__t<_ReceiverId>; using __receiver_t = stdexec::__t<__receiver<_CvrefSenderId, _ReceiverId>>; struct __t { using __id = __operation; __t(_Sender&& __sndr, _Receiver&& __rcvr) : __rcvr_((_Receiver&&) __rcvr) , __op_state_(connect((_Sender&&) __sndr, __receiver_t{{}, this})) { } __t(__t&&) = delete; friend void tag_invoke(start_t, __t& __self) noexcept { start(__self.__op_state_); } _Receiver __rcvr_; connect_result_t<_Sender, __receiver_t> __op_state_; }; }; template <class _SenderId> struct __sender { using _Sender = stdexec::__t<_SenderId>; struct __t { using __id = __sender; using is_sender = void; template <class _Self, class _Receiver> using __operation_t = stdexec::__t<__operation<stdexec::__cvref_id<_Self, _Sender>, stdexec::__id<_Receiver>>>; template <class _Self, class _Receiver> using __receiver_t = stdexec::__t<__receiver<stdexec::__cvref_id<_Self, _Sender>, stdexec::__id<_Receiver>>>; template <__decays_to<__t> _Self, receiver _Receiver> requires __single_typed_sender<__copy_cvref_t<_Self, _Sender>, env_of_t<_Receiver>> && sender_to<__copy_cvref_t<_Self, _Sender>, __receiver_t<_Self, _Receiver>> friend auto tag_invoke(connect_t, _Self&& __self, _Receiver __rcvr) -> __operation_t<_Self, _Receiver> { return {((_Self&&) __self).__sndr_, (_Receiver&&) __rcvr}; } friend auto tag_invoke(get_env_t, const __t& __self) noexcept -> env_of_t<const _Sender&> { return get_env(__self.__sndr_); } template <class... _Tys> requires(sizeof...(_Tys) == 1) using __set_value_t = completion_signatures<set_value_t(std::optional<__decay_t<_Tys>>...)>; template <class _Ty> using __set_error_t = completion_signatures<set_error_t(_Ty)>; template <__decays_to<__t> _Self, class _Env> friend auto tag_invoke(get_completion_signatures_t, _Self&&, _Env&&) -> make_completion_signatures< __copy_cvref_t<_Self, _Sender>, _Env, completion_signatures<set_error_t(std::exception_ptr)>, __set_value_t, __set_error_t, completion_signatures<>>; _Sender __sndr_; }; }; struct stopped_as_optional_t { template <sender _Sender> auto operator()(_Sender&& __sndr) const -> __t<__sender<stdexec::__id<__decay_t<_Sender>>>> { return {(_Sender&&) __sndr}; } __binder_back<stopped_as_optional_t> operator()() const noexcept { return {}; } }; struct stopped_as_error_t { template <sender _Sender, __movable_value _Error> auto operator()(_Sender&& __sndr, _Error __err) const { return (_Sender&&) __sndr | let_stopped([__err2 = (_Error&&) __err]() mutable noexcept(std::is_nothrow_move_constructible_v<_Error>) { return just_error((_Error&&) __err2); }); } template <__movable_value _Error> auto operator()(_Error __err) const -> __binder_back<stopped_as_error_t, _Error> { return {{}, {}, {(_Error&&) __err}}; } }; } using __stopped_as_xxx::stopped_as_optional_t; inline constexpr stopped_as_optional_t stopped_as_optional{}; using __stopped_as_xxx::stopped_as_error_t; inline constexpr stopped_as_error_t stopped_as_error{}; namespace __loop { class run_loop; struct __task : __immovable { __task* __next_ = this; union { void (*__execute_)(__task*) noexcept; __task* __tail_; }; void __execute() noexcept { (*__execute_)(this); } }; template <class _ReceiverId> struct __operation { using _Receiver = stdexec::__t<_ReceiverId>; struct __t : __task { using __id = __operation; run_loop* __loop_; [[no_unique_address]] _Receiver __rcvr_; static void __execute_impl(__task* __p) noexcept { auto& __rcvr = ((__t*) __p)->__rcvr_; try { if (get_stop_token(get_env(__rcvr)).stop_requested()) { set_stopped((_Receiver&&) __rcvr); } else { set_value((_Receiver&&) __rcvr); } } catch (...) { set_error((_Receiver&&) __rcvr, std::current_exception()); } } explicit __t(__task* __tail) noexcept : __task{.__tail_ = __tail} { } __t(__task* __next, run_loop* __loop, _Receiver __rcvr) : __task{{}, __next, {&__execute_impl}} , __loop_{__loop} , __rcvr_{(_Receiver&&) __rcvr} { } friend void tag_invoke(start_t, __t& __self) noexcept { __self.__start_(); } void __start_() noexcept; }; }; class run_loop { template <class... Ts> using __completion_signatures_ = completion_signatures<Ts...>; template <class> friend struct __operation; public: struct __scheduler { using __t = __scheduler; using __id = __scheduler; bool operator==(const __scheduler&) const noexcept = default; private: struct __schedule_task { using __t = __schedule_task; using __id = __schedule_task; using is_sender = void; using completion_signatures = __completion_signatures_< set_value_t(), set_error_t(std::exception_ptr), set_stopped_t()>; private: friend __scheduler; template <class _Receiver> using __operation = stdexec::__t<__operation<stdexec::__id<_Receiver>>>; template <class _Receiver> friend __operation<_Receiver> tag_invoke(connect_t, const __schedule_task& __self, _Receiver __rcvr) { return __self.__connect_((_Receiver&&) __rcvr); } template <class _Receiver> __operation<_Receiver> __connect_(_Receiver&& __rcvr) const { return {&__loop_->__head_, __loop_, (_Receiver&&) __rcvr}; } struct __env { run_loop* __loop_; template <class _CPO> friend __scheduler tag_invoke(get_completion_scheduler_t<_CPO>, const __env& __self) noexcept { return __self.__loop_->get_scheduler(); } }; friend __env tag_invoke(get_env_t, const __schedule_task& __self) noexcept { return __env{__self.__loop_}; } explicit __schedule_task(run_loop* __loop) noexcept : __loop_(__loop) { } run_loop* const __loop_; }; friend run_loop; explicit __scheduler(run_loop* __loop) noexcept : __loop_(__loop) { } friend __schedule_task tag_invoke(schedule_t, const __scheduler& __self) noexcept { return __self.__schedule(); } friend stdexec::forward_progress_guarantee tag_invoke(get_forward_progress_guarantee_t, const __scheduler&) noexcept { return stdexec::forward_progress_guarantee::parallel; } friend bool tag_invoke(execute_may_block_caller_t, const __scheduler&) noexcept { return false; } __schedule_task __schedule() const noexcept { return __schedule_task{__loop_}; } run_loop* __loop_; }; __scheduler get_scheduler() noexcept { return __scheduler{this}; } void run(); void finish(); private: void __push_back_(__task* __task); __task* __pop_front_(); std::mutex __mutex_; std::condition_variable __cv_; __task __head_{.__tail_ = &__head_}; bool __stop_ = false; }; template <class _ReceiverId> inline void __operation<_ReceiverId>::__t::__start_() noexcept { try { __loop_->__push_back_(this); } catch (...) { set_error((_Receiver&&) __rcvr_, std::current_exception()); } } inline void run_loop::run() { for (__task* __task; (__task = __pop_front_()) != &__head_;) { __task->__execute(); } } inline void run_loop::finish() { std::unique_lock __lock{__mutex_}; __stop_ = true; __cv_.notify_all(); } inline void run_loop::__push_back_(__task* __task) { std::unique_lock __lock{__mutex_}; __task->__next_ = &__head_; __head_.__tail_ = __head_.__tail_->__next_ = __task; __cv_.notify_one(); } inline __task* run_loop::__pop_front_() { std::unique_lock __lock{__mutex_}; __cv_.wait(__lock, [this] { return __head_.__next_ != &__head_ || __stop_; }); if (__head_.__tail_ == __head_.__next_) __head_.__tail_ = &__head_; return std::exchange(__head_.__next_, __head_.__next_->__next_); } } using run_loop = __loop::run_loop; namespace __schedule_from { template <class _State, class... _Tuples> using __make_bind_ = __mbind_back<_State, _Tuples...>; template <class _State> using __make_bind = __mbind_front_q<__make_bind_, _State>; template <class _Tag> using __tuple_t = __mbind_front_q<__decayed_tuple, _Tag>; template <class _Sender, class _Env, class _State, class _Tag> using __bind_completions_t = __gather_completions_for<_Tag, _Sender, _Env, __tuple_t<_Tag>, __make_bind<_State>>; template <class _Sender, class _Env> using __variant_for_t = __minvoke< __minvoke< __mfold_right< __nullable_variant_t, __mbind_front_q<__bind_completions_t, _Sender, _Env>>, set_value_t, set_error_t, set_stopped_t>>; template <class _SchedulerId, class _CvrefSenderId, class _ReceiverId> struct __operation1; template <class _SchedulerId, class _CvrefSenderId, class _ReceiverId> struct __receiver2 { using _Receiver = stdexec::__t<_ReceiverId>; struct __t { using is_receiver = void; using __id = __receiver2; stdexec::__t<__operation1<_SchedulerId, _CvrefSenderId, _ReceiverId>>* __op_state_; template <same_as<set_value_t> _Tag> friend void tag_invoke(_Tag, __t&& __self) noexcept { __self.__op_state_->__complete(); } template <__one_of<set_error_t, set_stopped_t> _Tag, class... _As> requires __callable<_Tag, _Receiver, _As...> friend void tag_invoke(_Tag, __t&& __self, _As&&... __as) noexcept { _Tag{}((_Receiver&&) __self.__op_state_->__rcvr_, (_As&&) __as...); } friend auto tag_invoke(get_env_t, const __t& __self) noexcept -> env_of_t<_Receiver> { return get_env(__self.__op_state_->__rcvr_); } }; }; template <class _SchedulerId, class _CvrefSenderId, class _ReceiverId> struct __receiver1 { using _Scheduler = stdexec::__t<_SchedulerId>; using _Receiver = stdexec::__t<_ReceiverId>; using __receiver2_t = stdexec::__t<__receiver2<_SchedulerId, _CvrefSenderId, _ReceiverId>>; struct __t { using is_receiver = void; stdexec::__t<__operation1<_SchedulerId, _CvrefSenderId, _ReceiverId>>* __op_state_; template <class... _Args> static constexpr bool __nothrow_complete_ = (__nothrow_decay_copyable<_Args> && ...); template <class _Tag, class... _Args> static void __complete_(_Tag, __t&& __self, _Args&&... __args) noexcept(__nothrow_complete_<_Args...>) { __self.__op_state_->__data_.template emplace<__decayed_tuple<_Tag, _Args...>>( _Tag{}, (_Args&&) __args...); start(__self.__op_state_->__state2_); } template <__completion_tag _Tag, class... _Args> requires __callable<_Tag, _Receiver, __decay_t<_Args>...> friend void tag_invoke(_Tag __tag, __t&& __self, _Args&&... __args) noexcept { __try_call( (_Receiver&&) __self.__op_state_->__rcvr_, __fun_c<__complete_<_Tag, _Args...>>, (_Tag&&) __tag, (__t&&) __self, (_Args&&) __args...); } friend auto tag_invoke(get_env_t, const __t& __self) noexcept -> env_of_t<_Receiver> { return get_env(__self.__op_state_->__rcvr_); } }; }; template <class _SchedulerId, class _CvrefSenderId, class _ReceiverId> struct __operation1 { using _Scheduler = stdexec::__t<_SchedulerId>; using _CvrefSender = stdexec::__cvref_t<_CvrefSenderId>; using _Receiver = stdexec::__t<_ReceiverId>; using __receiver1_t = stdexec::__t<__receiver1<_SchedulerId, _CvrefSenderId, _ReceiverId>>; using __receiver2_t = stdexec::__t<__receiver2<_SchedulerId, _CvrefSenderId, _ReceiverId>>; using __variant_t = __variant_for_t<_CvrefSender, env_of_t<_Receiver>>; struct __t { using __id = __operation1; _Scheduler __sched_; _Receiver __rcvr_; __variant_t __data_; connect_result_t<_CvrefSender, __receiver1_t> __state1_; connect_result_t<schedule_result_t<_Scheduler>, __receiver2_t> __state2_; __t(_Scheduler __sched, _CvrefSender&& __sndr, _Receiver&& __rcvr) : __sched_((_Scheduler&&) __sched) , __rcvr_((_Receiver&&) __rcvr) , __state1_(connect((_CvrefSender&&) __sndr, __receiver1_t{this})) , __state2_(connect(schedule(__sched_), __receiver2_t{this})) { } __t(__t&&) = delete; friend void tag_invoke(start_t, __t& __op_state) noexcept { start(__op_state.__state1_); } void __complete() noexcept { do { static_assert(noexcept(!__data_.valueless_by_exception())); assert(!__data_.valueless_by_exception()); } while (false); std::visit( [&]<class _Tup>(_Tup& __tupl) -> void { if constexpr (same_as<_Tup, std::monostate>) { std::terminate(); } else { std::apply( [&]<class... _Args>(auto __tag, _Args&... __args) -> void { __tag((_Receiver&&) __rcvr_, (_Args&&) __args...); }, __tupl); } }, __data_); } }; }; template <class _Tp> using __decay_rvalue_ref = __decay_t<_Tp>&&; template <class _Tag> using __decay_signature = __transform<__q<__decay_rvalue_ref>, __mcompose<__q<completion_signatures>, __qf<_Tag>>>; template <class _SchedulerId> struct __env { using _Scheduler = stdexec::__t<_SchedulerId>; struct __t { using __id = __env; _Scheduler __sched_; template <__one_of<set_value_t, set_stopped_t> _Tag> friend _Scheduler tag_invoke(get_completion_scheduler_t<_Tag>, const __t& __self) noexcept { return __self.__sched_; } }; }; template <class _SchedulerId, class _SenderId> struct __sender { using _Scheduler = stdexec::__t<_SchedulerId>; using _Sender = stdexec::__t<_SenderId>; using _Env = stdexec::__t<__env<_SchedulerId>>; struct __t { using __id = __sender; using is_sender = void; _Env __env_; _Sender __sndr_; template <class _Self, class _Receiver> using __receiver_t = stdexec::__t< __receiver1<_SchedulerId, stdexec::__cvref_id<_Self, _Sender>, stdexec::__id<_Receiver>>>; template <__decays_to<__t> _Self, receiver _Receiver> requires sender_to<__copy_cvref_t<_Self, _Sender>, __receiver_t<_Self, _Receiver>> friend auto tag_invoke(connect_t, _Self&& __self, _Receiver __rcvr) -> stdexec::__t< __operation1< _SchedulerId, stdexec::__cvref_id<_Self, _Sender>, stdexec::__id<_Receiver>>> { return {__self.__env_.__sched_, ((_Self&&) __self).__sndr_, (_Receiver&&) __rcvr}; } template <class... _Ts> using __all_nothrow_decay_copyable = __mbool<(__nothrow_decay_copyable<_Ts> && ...)>; template <class _Self, class _Env> using __all_values_and_errors_nothrow_decay_copyable = __mand< error_types_of_t<__copy_cvref_t<_Self, _Sender>, _Env, __all_nothrow_decay_copyable>, value_types_of_t< __copy_cvref_t<_Self, _Sender>, _Env, __all_nothrow_decay_copyable, __mand>>; template <class _Self, class _Env> using __with_error_t = __if< __all_values_and_errors_nothrow_decay_copyable<_Self, _Env>, completion_signatures<>, __with_exception_ptr>; template <class _Self, class _Env> using __completions_t = __try_make_completion_signatures< __copy_cvref_t<_Self, _Sender>, _Env, __try_make_completion_signatures< schedule_result_t<_Scheduler>, _Env, __with_error_t<_Self, _Env>, __mconst<completion_signatures<>>>, __decay_signature<set_value_t>, __decay_signature<set_error_t>>; template <__decays_to<__t> _Self, class _Env> friend auto tag_invoke(get_completion_signatures_t, _Self&&, _Env&&) -> dependent_completion_signatures<_Env>; template <__decays_to<__t> _Self, class _Env> friend auto tag_invoke(get_completion_signatures_t, _Self&&, _Env&&) -> __completions_t<_Self, _Env> requires true; friend const _Env& tag_invoke(get_env_t, const __t& __self) noexcept { return __self.__env_; } }; }; struct schedule_from_t { template <scheduler _Scheduler, sender _Sender> requires tag_invocable<schedule_from_t, _Scheduler, _Sender> auto operator()(_Scheduler&& __sched, _Sender&& __sndr) const noexcept(nothrow_tag_invocable<schedule_from_t, _Scheduler, _Sender>) -> tag_invoke_result_t<schedule_from_t, _Scheduler, _Sender> { return tag_invoke(*this, (_Scheduler&&) __sched, (_Sender&&) __sndr); } template <scheduler _Scheduler, sender _Sender> auto operator()(_Scheduler&& __sched, _Sender&& __sndr) const -> stdexec::__t< __sender<stdexec::__id<__decay_t<_Scheduler>>, stdexec::__id<__decay_t<_Sender>>>> { return {{(_Scheduler&&) __sched}, (_Sender&&) __sndr}; } }; } using __schedule_from::schedule_from_t; inline constexpr schedule_from_t schedule_from{}; namespace __transfer { struct transfer_t { template <sender _Sender, scheduler _Scheduler> requires __tag_invocable_with_domain<transfer_t, set_value_t, _Sender, _Scheduler> tag_invoke_result_t<transfer_t, __sender_domain_of_t<_Sender>, _Sender, _Scheduler> operator()(_Sender&& __sndr, _Scheduler&& __sched) const noexcept( nothrow_tag_invocable< transfer_t, __sender_domain_of_t<_Sender>, _Sender, _Scheduler>) { auto __domain = __get_sender_domain(__sndr); return tag_invoke(transfer_t{}, __domain, (_Sender&&) __sndr, (_Scheduler&&) __sched); } template <sender _Sender, scheduler _Scheduler> requires(!__tag_invocable_with_domain<transfer_t, set_value_t, _Sender, _Scheduler>) && tag_invocable<transfer_t, _Sender, _Scheduler> tag_invoke_result_t<transfer_t, _Sender, _Scheduler> operator()(_Sender&& __sndr, _Scheduler&& __sched) const noexcept(nothrow_tag_invocable<transfer_t, _Sender, _Scheduler>) { return tag_invoke(transfer_t{}, (_Sender&&) __sndr, (_Scheduler&&) __sched); } template <sender _Sender, scheduler _Scheduler> requires(!__tag_invocable_with_domain<transfer_t, set_value_t, _Sender, _Scheduler>) && (!tag_invocable<transfer_t, _Sender, _Scheduler>) auto operator()(_Sender&& __sndr, _Scheduler&& __sched) const { return schedule_from((_Scheduler&&) __sched, (_Sender&&) __sndr); } template <scheduler _Scheduler> __binder_back<transfer_t, __decay_t<_Scheduler>> operator()(_Scheduler&& __sched) const { return {{}, {}, {(_Scheduler&&) __sched}}; } }; } using __transfer::transfer_t; inline constexpr transfer_t transfer{}; namespace __on { template <class _SchedulerId, class _SenderId, class _ReceiverId> struct __operation; template <class _SchedulerId, class _SenderId, class _ReceiverId> struct __receiver_ref { using _Scheduler = stdexec::__t<_SchedulerId>; using _Sender = stdexec::__t<_SenderId>; using _Receiver = stdexec::__t<_ReceiverId>; struct __t : receiver_adaptor<__t> { using __id = __receiver_ref; stdexec::__t<__operation<_SchedulerId, _SenderId, _ReceiverId>>* __op_state_; _Receiver&& base() && noexcept { return (_Receiver&&) __op_state_->__rcvr_; } const _Receiver& base() const & noexcept { return __op_state_->__rcvr_; } auto get_env() const noexcept -> __make_env_t<env_of_t<_Receiver>, __with<get_scheduler_t, _Scheduler>> { return __make_env( stdexec::get_env(this->base()), __with_(get_scheduler, __op_state_->__scheduler_)); } }; }; template <class _SchedulerId, class _SenderId, class _ReceiverId> struct __receiver { using _Scheduler = stdexec::__t<_SchedulerId>; using _Sender = stdexec::__t<_SenderId>; using _Receiver = stdexec::__t<_ReceiverId>; struct __t : receiver_adaptor<__t> { using __id = __receiver; using __receiver_ref_t = stdexec::__t<__receiver_ref<_SchedulerId, _SenderId, _ReceiverId>>; stdexec::__t<__operation<_SchedulerId, _SenderId, _ReceiverId>>* __op_state_; _Receiver&& base() && noexcept { return (_Receiver&&) __op_state_->__rcvr_; } const _Receiver& base() const & noexcept { return __op_state_->__rcvr_; } void set_value() && noexcept { auto* __op_state = __op_state_; try { start(__op_state->__data_.template emplace<1>(__conv{[__op_state] { return connect((_Sender&&) __op_state->__sndr_, __receiver_ref_t{{}, __op_state}); }})); } catch (...) { set_error((_Receiver&&) __op_state->__rcvr_, std::current_exception()); } } }; }; template <class _SchedulerId, class _SenderId, class _ReceiverId> struct __operation { using _Scheduler = stdexec::__t<_SchedulerId>; using _Sender = stdexec::__t<_SenderId>; using _Receiver = stdexec::__t<_ReceiverId>; struct __t { using __id = __operation; using __receiver_t = stdexec::__t<__receiver<_SchedulerId, _SenderId, _ReceiverId>>; using __receiver_ref_t = stdexec::__t<__receiver_ref<_SchedulerId, _SenderId, _ReceiverId>>; friend void tag_invoke(start_t, __t& __self) noexcept { start(std::get<0>(__self.__data_)); } template <class _Sender2, class _Receiver2> __t(_Scheduler __sched, _Sender2&& __sndr, _Receiver2&& __rcvr) : __scheduler_((_Scheduler&&) __sched) , __sndr_((_Sender2&&) __sndr) , __rcvr_((_Receiver2&&) __rcvr) , __data_{std::in_place_index<0>, __conv{[this] { return connect(schedule(__scheduler_), __receiver_t{{}, this}); }}} { } __t(__t&&) = delete; _Scheduler __scheduler_; _Sender __sndr_; _Receiver __rcvr_; std::variant< connect_result_t<schedule_result_t<_Scheduler>, __receiver_t>, connect_result_t<_Sender, __receiver_ref_t>> __data_; }; }; template <class _SchedulerId, class _SenderId> struct __sender { using _Scheduler = stdexec::__t<_SchedulerId>; using _Sender = stdexec::__t<_SenderId>; struct __t { using __id = __sender; using is_sender = void; template <class _ReceiverId> using __receiver_ref_t = stdexec::__t<__receiver_ref<_SchedulerId, _SenderId, _ReceiverId>>; template <class _ReceiverId> using __receiver_t = stdexec::__t<__receiver<_SchedulerId, _SenderId, _ReceiverId>>; template <class _ReceiverId> using __operation_t = stdexec::__t<__operation<_SchedulerId, _SenderId, _ReceiverId>>; _Scheduler __scheduler_; _Sender __sndr_; template <__decays_to<__t> _Self, receiver _Receiver> requires constructible_from<_Sender, __copy_cvref_t<_Self, _Sender>> && sender_to<schedule_result_t<_Scheduler>, __receiver_t<stdexec::__id<_Receiver>>> && sender_to<_Sender, __receiver_ref_t<stdexec::__id<_Receiver>>> friend auto tag_invoke(connect_t, _Self&& __self, _Receiver __rcvr) -> __operation_t<stdexec::__id<_Receiver>> { return { ((_Self&&) __self).__scheduler_, ((_Self&&) __self).__sndr_, (_Receiver&&) __rcvr}; } friend auto tag_invoke(get_env_t, const __t& __self) noexcept -> env_of_t<const _Sender&> { return get_env(__self.__sndr_); } template <class...> using __value_t = completion_signatures<>; template <__decays_to<__t> _Self, class _Env> friend auto tag_invoke(get_completion_signatures_t, _Self&&, _Env&&) -> __try_make_completion_signatures< schedule_result_t<_Scheduler>, _Env, __try_make_completion_signatures< __copy_cvref_t<_Self, _Sender>, __make_env_t<_Env, __with<get_scheduler_t, _Scheduler>>, completion_signatures<set_error_t(std::exception_ptr)>>, __q<__value_t>>; }; }; struct on_t { template <scheduler _Scheduler, sender _Sender> requires tag_invocable<on_t, _Scheduler, _Sender> auto operator()(_Scheduler&& __sched, _Sender&& __sndr) const noexcept(nothrow_tag_invocable<on_t, _Scheduler, _Sender>) -> tag_invoke_result_t<on_t, _Scheduler, _Sender> { return tag_invoke(*this, (_Scheduler&&) __sched, (_Sender&&) __sndr); } template <scheduler _Scheduler, sender _Sender> auto operator()(_Scheduler&& __sched, _Sender&& __sndr) const -> __t<__sender<stdexec::__id<__decay_t<_Scheduler>>, stdexec::__id<__decay_t<_Sender>>>> { using __has_customizations = __call_result_t<__has_algorithm_customizations_t, _Scheduler>; static_assert( !__has_customizations{}, "For now the default stdexec::on implementation doesn't support scheduling " "onto schedulers that customize algorithms."); return {(_Scheduler&&) __sched, (_Sender&&) __sndr}; } }; } using __on::on_t; inline constexpr on_t on{}; namespace __transfer_just { struct transfer_just_t { template <scheduler _Scheduler, __movable_value... _Values> requires tag_invocable<transfer_just_t, _Scheduler, _Values...> && sender<tag_invoke_result_t<transfer_just_t, _Scheduler, _Values...>> auto operator()(_Scheduler&& __sched, _Values&&... __vals) const noexcept(nothrow_tag_invocable<transfer_just_t, _Scheduler, _Values...>) -> tag_invoke_result_t<transfer_just_t, _Scheduler, _Values...> { return tag_invoke(*this, (_Scheduler&&) __sched, (_Values&&) __vals...); } template <scheduler _Scheduler, __movable_value... _Values> requires( !tag_invocable<transfer_just_t, _Scheduler, _Values...> || !sender<tag_invoke_result_t<transfer_just_t, _Scheduler, _Values...>>) auto operator()(_Scheduler&& __sched, _Values&&... __vals) const -> decltype(transfer(just((_Values&&) __vals...), (_Scheduler&&) __sched)) { return transfer(just((_Values&&) __vals...), (_Scheduler&&) __sched); } }; } using __transfer_just::transfer_just_t; inline constexpr transfer_just_t transfer_just{}; namespace __into_variant { template <class _Sender, class _Env> requires sender_in<_Sender, _Env> using __into_variant_result_t = value_types_of_t<_Sender, _Env>; template <class _ReceiverId, class _Variant> struct __receiver { using _Receiver = stdexec::__t<_ReceiverId>; struct __t { using is_receiver = void; using __id = __receiver; using _Receiver = stdexec::__t<_ReceiverId>; _Receiver __rcvr_; template <same_as<set_value_t> _Tag, class... _As> requires constructible_from<_Variant, std::tuple<_As&&...>> friend void tag_invoke(_Tag, __t&& __self, _As&&... __as) noexcept { try { set_value( (_Receiver&&) __self.__rcvr_, _Variant{std::tuple<_As&&...>{(_As&&) __as...}}); } catch (...) { set_error((_Receiver&&) __self.__rcvr_, std::current_exception()); } } template <same_as<set_error_t> _Tag, class _Error> friend void tag_invoke(_Tag, __t&& __self, _Error&& __err) noexcept { set_error((_Receiver&&) __self.__rcvr_, (_Error&&) __err); } template <same_as<set_stopped_t> _Tag> friend void tag_invoke(_Tag, __t&& __self) noexcept { set_stopped((_Receiver&&) __self.__rcvr_); } friend env_of_t<_Receiver> tag_invoke(get_env_t, const __t& __self) noexcept { return get_env(__self.__rcvr_); } }; }; template <class _SenderId> struct __sender { using _Sender = stdexec::__t<_SenderId>; template <class _Env> using __variant_t = __into_variant_result_t<_Sender, _Env>; template <class _Receiver> using __receiver_t = stdexec::__t< __receiver<__id<_Receiver>, __variant_t<env_of_t<_Receiver>>>>; struct __t { using __id = __sender; using is_sender = void; template <__decays_to<_Sender> _CvrefSender> explicit __t(_CvrefSender&& __sndr) : __sndr_((_CvrefSender&&) __sndr) { } private: template <class...> using __value_t = completion_signatures<>; template <class _Env> using __compl_sigs = make_completion_signatures< _Sender, _Env, completion_signatures< set_value_t(__variant_t<_Env>), set_error_t(std::exception_ptr)>, __value_t>; _Sender __sndr_; template <receiver _Receiver> requires sender_to<_Sender, __receiver_t<_Receiver>> friend auto tag_invoke(connect_t, __t&& __self, _Receiver __rcvr) noexcept(__nothrow_connectable<_Sender, __receiver_t<_Receiver>>) -> connect_result_t<_Sender, __receiver_t<_Receiver>> { return stdexec::connect( (_Sender&&) __self.__sndr_, __receiver_t<_Receiver>{(_Receiver&&) __rcvr}); } friend auto tag_invoke(get_env_t, const __t& __self) noexcept -> env_of_t<const _Sender&> { return get_env(__self.__sndr_); } template <class _Env> friend auto tag_invoke(get_completion_signatures_t, __t&&, _Env&&) -> __compl_sigs<_Env>; }; }; struct into_variant_t { template <sender _Sender> auto operator()(_Sender&& __sndr) const -> __t<__sender<stdexec::__id<__decay_t<_Sender>>>> { return __t<__sender<stdexec::__id<__decay_t<_Sender>>>>{(_Sender&&) __sndr}; } auto operator()() const noexcept { return __binder_back<into_variant_t>{}; } }; } using __into_variant::into_variant_t; inline constexpr into_variant_t into_variant{}; namespace __when_all { enum __state_t { __started, __error, __stopped }; struct __on_stop_requested { in_place_stop_source& __stop_source_; void operator()() noexcept { __stop_source_.request_stop(); } }; template <class _Env> auto __make_env(_Env&& __env, in_place_stop_source& __stop_source) noexcept { return __join_env( __env::__env_fn{[&](get_stop_token_t) noexcept { return __stop_source.get_token(); }}, (_Env&&) __env); } template <class _Env> using __env_t = decltype(__when_all::__make_env(__declval<_Env>(), __declval<in_place_stop_source&>())); template <class _Tp> using __decay_rvalue_ref = __decay_t<_Tp>&&; template <class _Sender, class _Env> concept __max1_sender = sender_in<_Sender, _Env> && __valid<__value_types_of_t, _Sender, _Env, __mconst<int>, __msingle_or<void>>; template <class _Env, class _Sender> using __single_values_of_t = __try_value_types_of_t< _Sender, _Env, __transform<__q<__decay_rvalue_ref>, __q<__types>>, __q<__msingle>>; template <class _Env, class... _Senders> using __set_values_sig_t = __meval< completion_signatures, __minvoke< __mconcat<__qf<set_value_t>>, __single_values_of_t<_Env, _Senders>...>>; template <class... _Args> using __all_nothrow_decay_copyable = __mbool<(__nothrow_decay_copyable<_Args> && ...)>; template <class _Env, class... _SenderIds> using __all_value_and_error_args_nothrow_decay_copyable = __mand< __mand<__try_value_types_of_t< __t<_SenderIds>, _Env, __q<__all_nothrow_decay_copyable>, __q<__mand>>...>, __mand<__try_error_types_of_t<__t<_SenderIds>, _Env, __q<__all_nothrow_decay_copyable>>...>>; template <class _Env, class... _Senders> using __completions_t = __concat_completion_signatures_t< __if< __all_value_and_error_args_nothrow_decay_copyable<_Env, __id<_Senders>...>, completion_signatures<set_stopped_t()>, completion_signatures<set_stopped_t(), set_error_t(std::exception_ptr&&)>>, __minvoke< __with_default< __mbind_front_q<__set_values_sig_t, _Env>, completion_signatures<>>, _Senders...>, __try_make_completion_signatures< _Senders, _Env, completion_signatures<>, __mconst<completion_signatures<>>, __mcompose<__q<completion_signatures>, __qf<set_error_t>, __q<__decay_rvalue_ref>>>...>; struct __not_an_error { }; struct __tie_fn { template <class... _Ty> std::tuple<_Ty&...> operator()(_Ty&... __vals) noexcept { return std::tuple<_Ty&...>{__vals...}; } }; template <class _Tag, class _Receiver> struct __complete_fn { _Receiver& __rcvr_; __complete_fn(_Tag, _Receiver& __rcvr) noexcept : __rcvr_(__rcvr) { } template <class _Ty, class... _Ts> void operator()(_Ty& __t, _Ts&... __ts) const noexcept { if constexpr (!same_as<_Ty, __not_an_error>) { _Tag{}((_Receiver&&) __rcvr_, (_Ty&&) __t, (_Ts&&) __ts...); } } void operator()() const noexcept { _Tag{}((_Receiver&&) __rcvr_); } }; template <class _Receiver, class _ValuesTuple> void __set_values(_Receiver& __rcvr, _ValuesTuple& __values) noexcept { std::apply( [&](auto&... __opt_vals) noexcept -> void { std::apply( __complete_fn{set_value, __rcvr}, std::tuple_cat(std::apply(__tie_fn{}, *__opt_vals)...)); }, __values); } template <class _ReceiverId, class _ValuesTuple, class _ErrorsVariant> struct __operation_base : __immovable { using _Receiver = stdexec::__t<_ReceiverId>; void __arrive() noexcept { if (0 == --__count_) { __complete(); } } void __complete() noexcept { __on_stop_.reset(); switch (__state_.load(std::memory_order_relaxed)) { case __started: if constexpr (!same_as<_ValuesTuple, __ignore>) { __when_all::__set_values(__rcvr_, __values_); } break; case __error: if constexpr (!same_as<_ErrorsVariant, std::variant<std::monostate>>) { std::visit(__complete_fn{set_error, __rcvr_}, __errors_); } break; case __stopped: stdexec::set_stopped((_Receiver&&) __rcvr_); break; default:; } } _Receiver __rcvr_; std::atomic<std::size_t> __count_; in_place_stop_source __stop_source_{}; std::atomic<__state_t> __state_{__started}; _ErrorsVariant __errors_{}; [[no_unique_address]] _ValuesTuple __values_{}; std::optional< typename stop_token_of_t<env_of_t<_Receiver>&>::template callback_type<__on_stop_requested>> __on_stop_{}; }; template <std::size_t _Index, class _ReceiverId, class _ValuesTuple, class _ErrorsVariant> struct __receiver { using _Receiver = stdexec::__t<_ReceiverId>; template <class _Tuple> using __tuple_type = typename std::tuple_element_t<_Index, _Tuple>::value_type; using _TupleType = __minvoke< __with_default<__q<__tuple_type>, __ignore>, _ValuesTuple>; struct __t { using is_receiver = void; using __id = __receiver; template <class _Error> void __set_error(_Error&& __err) noexcept { if (__error != __op_state_->__state_.exchange(__error)) { __op_state_->__stop_source_.request_stop(); if constexpr (__nothrow_decay_copyable<_Error>) { __op_state_->__errors_.template emplace<__decay_t<_Error>>((_Error&&) __err); } else { try { __op_state_->__errors_.template emplace<__decay_t<_Error>>((_Error&&) __err); } catch (...) { __op_state_->__errors_.template emplace<std::exception_ptr>( std::current_exception()); } } } } template <same_as<set_value_t> _Tag, class... _Values> requires same_as<_ValuesTuple, __ignore> || constructible_from<_TupleType, _Values...> friend void tag_invoke(_Tag, __t&& __self, _Values&&... __vals) noexcept { if constexpr (!same_as<_ValuesTuple, __ignore>) { static_assert( same_as<_TupleType, std::tuple<__decay_t<_Values>...>>, "One of the senders in this when_all() is fibbing about what types it sends"); if (__self.__op_state_->__state_ == __started) { if constexpr ((__nothrow_decay_copyable<_Values> && ...)) { std::get<_Index>(__self.__op_state_->__values_).emplace((_Values&&) __vals...); } else { try { std::get<_Index>(__self.__op_state_->__values_).emplace((_Values&&) __vals...); } catch (...) { __self.__set_error(std::current_exception()); } } } } __self.__op_state_->__arrive(); } template <same_as<set_error_t> _Tag, class _Error> requires requires(_ErrorsVariant& __errors, _Error&& __err) { __errors.template emplace<__decay_t<_Error>>((_Error&&) __err); } friend void tag_invoke(_Tag, __t&& __self, _Error&& __err) noexcept { __self.__set_error((_Error&&) __err); __self.__op_state_->__arrive(); } template <same_as<set_stopped_t> _Tag> requires receiver_of<_Receiver, completion_signatures<_Tag()>> friend void tag_invoke(_Tag, __t&& __self) noexcept { __state_t __expected = __started; if (__self.__op_state_->__state_.compare_exchange_strong(__expected, __stopped)) { __self.__op_state_->__stop_source_.request_stop(); } __self.__op_state_->__arrive(); } friend __env_t<env_of_t<_Receiver>> tag_invoke(get_env_t, const __t& __self) noexcept { return __when_all::__make_env( get_env(__self.__op_state_->__rcvr_), __self.__op_state_->__stop_source_); } __operation_base<_ReceiverId, _ValuesTuple, _ErrorsVariant>* __op_state_; }; }; template <class _Env, class _Sender> using __values_opt_tuple_t = __value_types_of_t< _Sender, __env_t<_Env>, __mcompose<__q<std::optional>, __q<__decayed_tuple>>, __q<__msingle>>; template <class _Env, __max1_sender<__env_t<_Env>>... _Senders> struct __traits_ { using __completions = __completions_t<__env_t<_Env>, _Senders...>; using __values_tuple = __minvoke< __with_default< __transform< __mbind_front_q<__values_opt_tuple_t, _Env>, __q<std::tuple>>, __ignore>, _Senders...>; using __nullable_variant_t_ = __munique<__mbind_front_q<std::variant, __not_an_error>>; using __error_types = __minvoke< __mconcat<__transform<__q<__decay_t>, __nullable_variant_t_>>, error_types_of_t<_Senders, __env_t<_Env>, __types>... >; using __errors_variant = __if< __all_value_and_error_args_nothrow_decay_copyable<_Env, __id<_Senders>...>, __error_types, __minvoke<__push_back_unique<__q<std::variant>>, __error_types, std::exception_ptr>>; }; template <receiver _Receiver, __max1_sender<__env_t<env_of_t<_Receiver>>>... _Senders> struct __traits : __traits_<env_of_t<_Receiver>, _Senders...> { using _Traits = __traits_<env_of_t<_Receiver>, _Senders...>; using typename _Traits::__completions; using typename _Traits::__values_tuple; using typename _Traits::__errors_variant; template <std::size_t _Index> using __receiver = __t< __when_all::__receiver< _Index, __id<_Receiver>, __values_tuple, __errors_variant>>; using __operation_base = __when_all::__operation_base<__id<_Receiver>, __values_tuple, __errors_variant>; template <class _Sender, class _Index> using __op_state = connect_result_t<_Sender, __receiver<__v<_Index>>>; template <class _Tuple = __q<std::tuple>> using __op_states_tuple = __minvoke< __mzip_with2<__q<__op_state>, _Tuple>, __types<_Senders...>, __mindex_sequence_for<_Senders...>>; }; template <class _Cvref, class _ReceiverId, class... _SenderIds> using __traits_ex = __traits<__t<_ReceiverId>, __minvoke<_Cvref, __t<_SenderIds>>...>; template <class _Cvref, class _ReceiverId, class... _SenderIds> using __op_states_tuple_ex = typename __traits_ex<_Cvref, _ReceiverId, _SenderIds...>::template __op_states_tuple<>; template <class _Cvref, class _ReceiverId, class... _SenderIds> requires __valid<__op_states_tuple_ex, _Cvref, _ReceiverId, _SenderIds...> struct __operation { using _Receiver = stdexec::__t<_ReceiverId>; using _Traits = __traits_ex<_Cvref, _ReceiverId, _SenderIds...>; using _Indices = std::index_sequence_for<_SenderIds...>; using __operation_base_t = typename _Traits::__operation_base; using __op_states_tuple_t = __op_states_tuple_ex<_Cvref, _ReceiverId, _SenderIds...>; template <std::size_t _Index> using __receiver_t = typename _Traits::template __receiver<_Index>; struct __t : __operation_base_t { using __id = __operation; template <class _SendersTuple, std::size_t... _Is> __t(_SendersTuple&& __sndrs, _Receiver __rcvr, std::index_sequence<_Is...>) : __operation_base_t{{}, (_Receiver&&) __rcvr, {sizeof...(_Is)}} , __op_states_{__conv{[&__sndrs, this]() { return stdexec::connect( std::get<_Is>((_SendersTuple&&) __sndrs), __receiver_t<_Is>{this}); }}...} { } template <class _SendersTuple> __t(_SendersTuple&& __sndrs, _Receiver __rcvr) : __t((_SendersTuple&&) __sndrs, (_Receiver&&) __rcvr, _Indices{}) { } friend void tag_invoke(start_t, __t& __self) noexcept { __self.__on_stop_.emplace( get_stop_token(get_env(__self.__rcvr_)), __on_stop_requested{__self.__stop_source_}); if (__self.__stop_source_.stop_requested()) { stdexec::set_stopped((_Receiver&&) __self.__rcvr_); } else { std::apply( [](auto&... __child_ops) noexcept -> void { (stdexec::start(__child_ops), ...); }, __self.__op_states_); if constexpr (sizeof...(_SenderIds) == 0) { __self.__complete(); } } } __op_states_tuple_t __op_states_; }; }; template <class _From, class _ToId> using __cvref_id = __copy_cvref_t<_From, __t<_ToId>>; template <class _Indices, class... _SenderIds> struct __sender; template <std::size_t... _Indices, class... _SenderIds> struct __sender<std::index_sequence<_Indices...>, _SenderIds...> { template <class _Self, class _Env> using __completions_t = typename __traits_<_Env, __cvref_id<_Self, _SenderIds>...>::__completions; template <class _Self, class _Receiver, std::size_t _Index> using __receiver_t = typename __traits<_Receiver, __cvref_id<_Self, _SenderIds>...>::template __receiver<_Index>; template <class _Self, class _Receiver> using __operation_t = stdexec::__t<__operation< __copy_cvref_fn<_Self>, stdexec::__id<_Receiver>, _SenderIds...>>; struct __t { using __id = __sender; using is_sender = void; template <class... _Sndrs> explicit(sizeof...(_Sndrs) == 1) __t(_Sndrs&&... __sndrs) : __sndrs_((_Sndrs&&) __sndrs...) { } private: template <__decays_to<__t> _Self, receiver _Receiver> requires( sender_to< __cvref_id<_Self, _SenderIds>, __receiver_t<_Self, _Receiver, _Indices>> && ...) friend auto tag_invoke(connect_t, _Self&& __self, _Receiver __rcvr) -> __operation_t<_Self, _Receiver> { return {((_Self&&) __self).__sndrs_, (_Receiver&&) __rcvr}; } template <__decays_to<__t> _Self, class _Env> friend auto tag_invoke(get_completion_signatures_t, _Self&&, _Env&&) -> dependent_completion_signatures<_Env>; template <__decays_to<__t> _Self, class _Env> friend auto tag_invoke(get_completion_signatures_t, _Self&&, _Env&&) -> __completions_t<_Self, _Env> requires true; friend empty_env tag_invoke(get_env_t, const __t&) noexcept { return {}; } std::tuple<stdexec::__t<_SenderIds>...> __sndrs_; }; }; template <class _Sender> using __into_variant_result_t = decltype(into_variant(__declval<_Sender>())); struct when_all_t { template <class... _Senders> using __sender_t = __t<__sender< std::index_sequence_for<_Senders...>, __id<__decay_t<_Senders>>...>>; template <sender... _Senders> requires tag_invocable<when_all_t, _Senders...> && sender<tag_invoke_result_t<when_all_t, _Senders...>> auto operator()(_Senders&&... __sndrs) const noexcept(nothrow_tag_invocable<when_all_t, _Senders...>) -> tag_invoke_result_t<when_all_t, _Senders...> { return tag_invoke(*this, (_Senders&&) __sndrs...); } template <sender... _Senders> requires(!tag_invocable<when_all_t, _Senders...>) && sender<__sender_t<_Senders...>> __sender_t<_Senders...> operator()(_Senders&&... __sndrs) const { return __sender_t<_Senders...>{(_Senders&&) __sndrs...}; } }; struct when_all_with_variant_t { template <sender... _Senders> requires tag_invocable<when_all_with_variant_t, _Senders...> && sender<tag_invoke_result_t<when_all_with_variant_t, _Senders...>> auto operator()(_Senders&&... __sndrs) const noexcept(nothrow_tag_invocable<when_all_with_variant_t, _Senders...>) -> tag_invoke_result_t<when_all_with_variant_t, _Senders...> { return tag_invoke(*this, (_Senders&&) __sndrs...); } template <sender... _Senders> requires(!tag_invocable<when_all_with_variant_t, _Senders...>) && (__callable<into_variant_t, _Senders> && ...) auto operator()(_Senders&&... __sndrs) const { return when_all_t{}(into_variant((_Senders&&) __sndrs)...); } }; struct transfer_when_all_t { template <scheduler _Sched, sender... _Senders> requires tag_invocable<transfer_when_all_t, _Sched, _Senders...> && sender<tag_invoke_result_t<transfer_when_all_t, _Sched, _Senders...>> auto operator()(_Sched&& __sched, _Senders&&... __sndrs) const noexcept(nothrow_tag_invocable<transfer_when_all_t, _Sched, _Senders...>) -> tag_invoke_result_t<transfer_when_all_t, _Sched, _Senders...> { return tag_invoke(*this, (_Sched&&) __sched, (_Senders&&) __sndrs...); } template <scheduler _Sched, sender... _Senders> requires( (!tag_invocable<transfer_when_all_t, _Sched, _Senders...>) || (!sender<tag_invoke_result_t<transfer_when_all_t, _Sched, _Senders...>>) ) auto operator()(_Sched&& __sched, _Senders&&... __sndrs) const { return transfer(when_all_t{}((_Senders&&) __sndrs...), (_Sched&&) __sched); } }; struct transfer_when_all_with_variant_t { template <scheduler _Sched, sender... _Senders> requires tag_invocable<transfer_when_all_with_variant_t, _Sched, _Senders...> && sender<tag_invoke_result_t<transfer_when_all_with_variant_t, _Sched, _Senders...>> auto operator()(_Sched&& __sched, _Senders&&... __sndrs) const noexcept(nothrow_tag_invocable<transfer_when_all_with_variant_t, _Sched, _Senders...>) -> tag_invoke_result_t<transfer_when_all_with_variant_t, _Sched, _Senders...> { return tag_invoke(*this, (_Sched&&) __sched, (_Senders&&) __sndrs...); } template <scheduler _Sched, sender... _Senders> requires(!tag_invocable<transfer_when_all_with_variant_t, _Sched, _Senders...>) && (__callable<into_variant_t, _Senders> && ...) auto operator()(_Sched&& __sched, _Senders&&... __sndrs) const { return transfer_when_all_t{}((_Sched&&) __sched, into_variant((_Senders&&) __sndrs)...); } }; } using __when_all::when_all_t; inline constexpr when_all_t when_all{}; using __when_all::when_all_with_variant_t; inline constexpr when_all_with_variant_t when_all_with_variant{}; using __when_all::transfer_when_all_t; inline constexpr transfer_when_all_t transfer_when_all{}; using __when_all::transfer_when_all_with_variant_t; inline constexpr transfer_when_all_with_variant_t transfer_when_all_with_variant{}; namespace __read { template <class _Tag, class _ReceiverId> struct __operation { using _Receiver = stdexec::__t<_ReceiverId>; struct __t : __immovable { using __id = __operation; _Receiver __rcvr_; friend void tag_invoke(start_t, __t& __self) noexcept { try { auto __env = get_env(__self.__rcvr_); set_value(std::move(__self.__rcvr_), _Tag{}(__env)); } catch (...) { set_error(std::move(__self.__rcvr_), std::current_exception()); } } }; }; template <class _Tag> struct __sender { using __t = __sender; using __id = __sender; using is_sender = void; template <class _Env> requires __callable<_Tag, _Env> using __completions_t = completion_signatures< set_value_t(__call_result_t<_Tag, _Env>), set_error_t(std::exception_ptr)>; template <class _Receiver> requires receiver_of<_Receiver, __completions_t<env_of_t<_Receiver>>> friend auto tag_invoke(connect_t, __sender, _Receiver __rcvr) noexcept(std::is_nothrow_move_constructible_v<_Receiver>) -> stdexec::__t<__operation<_Tag, stdexec::__id<_Receiver>>> { return {{}, (_Receiver&&) __rcvr}; } template <class _Env> friend auto tag_invoke(get_completion_signatures_t, __sender, _Env&&) -> dependent_completion_signatures<_Env>; template <__none_of<no_env> _Env> friend auto tag_invoke(get_completion_signatures_t, __sender, _Env&&) -> __completions_t<_Env>; friend empty_env tag_invoke(get_env_t, const __t&) noexcept { return {}; } }; struct __read_t { template <class _Tag> constexpr __sender<_Tag> operator()(_Tag) const noexcept { return {}; } }; } inline constexpr __read::__read_t read{}; namespace __queries { inline auto get_scheduler_t::operator()() const noexcept { return read(get_scheduler); } template <class _Env> requires tag_invocable<get_scheduler_t, const _Env&> inline auto get_scheduler_t::operator()(const _Env& __env) const noexcept -> tag_invoke_result_t<get_scheduler_t, const _Env&> { static_assert(nothrow_tag_invocable<get_scheduler_t, const _Env&>); static_assert(scheduler<tag_invoke_result_t<get_scheduler_t, const _Env&>>); return tag_invoke(get_scheduler_t{}, __env); } inline auto get_delegatee_scheduler_t::operator()() const noexcept { return read(get_delegatee_scheduler); } template <class _Env> requires tag_invocable<get_delegatee_scheduler_t, const _Env&> inline auto get_delegatee_scheduler_t::operator()(const _Env& __t) const noexcept -> tag_invoke_result_t<get_delegatee_scheduler_t, const _Env&> { static_assert(nothrow_tag_invocable<get_delegatee_scheduler_t, const _Env&>); static_assert(scheduler<tag_invoke_result_t<get_delegatee_scheduler_t, const _Env&>>); return tag_invoke(get_delegatee_scheduler_t{}, std::as_const(__t)); } inline auto get_allocator_t::operator()() const noexcept { return read(get_allocator); } inline auto get_stop_token_t::operator()() const noexcept { return read(get_stop_token); } template <__completion_tag _CPO> template <__has_completion_scheduler_for<_CPO> _Queryable> auto get_completion_scheduler_t<_CPO>::operator()(const _Queryable& __queryable) const noexcept -> tag_invoke_result_t<get_completion_scheduler_t<_CPO>, const _Queryable&> { static_assert( nothrow_tag_invocable<get_completion_scheduler_t<_CPO>, const _Queryable&>, "get_completion_scheduler<_CPO> should be noexcept"); static_assert( scheduler<tag_invoke_result_t<get_completion_scheduler_t<_CPO>, const _Queryable&>>); return tag_invoke(*this, __queryable); } } namespace __sync_wait { template <class _Sender> using __into_variant_result_t = decltype(into_variant(__declval<_Sender>())); inline auto __make_env(run_loop& __loop) noexcept { return __env::__env_fn{ [&](__one_of<get_scheduler_t, get_delegatee_scheduler_t> auto) noexcept { return __loop.get_scheduler(); }}; } using __env = decltype(__sync_wait::__make_env(__declval<run_loop&>())); template <sender_in<__env> _Sender, class _Continuation> using __sync_wait_result_impl = __value_types_of_t< _Sender, __env, __transform<__q<__decay_t>, _Continuation>, __q<__msingle>>; template <class _Sender> using __sync_wait_result_t = __mtry_eval<__sync_wait_result_impl, _Sender, __q<std::tuple>>; template <class _Sender> using __sync_wait_with_variant_result_t = __sync_wait_result_t<__into_variant_result_t<_Sender>>; template <class... _Values> struct __state { using _Tuple = std::tuple<_Values...>; std::variant<std::monostate, _Tuple, std::exception_ptr, set_stopped_t> __data_{}; }; template <class... _Values> struct __receiver { struct __t { using is_receiver = void; using __id = __receiver; __state<_Values...>* __state_; run_loop* __loop_; template <class _Error> void __set_error(_Error __err) noexcept { if constexpr (__decays_to<_Error, std::exception_ptr>) __state_->__data_.template emplace<2>((_Error&&) __err); else if constexpr (__decays_to<_Error, std::error_code>) __state_->__data_.template emplace<2>( std::make_exception_ptr(std::system_error(__err))); else __state_->__data_.template emplace<2>(std::make_exception_ptr((_Error&&) __err)); __loop_->finish(); } template <same_as<set_value_t> _Tag, class... _As> requires constructible_from<std::tuple<_Values...>, _As...> friend void tag_invoke(_Tag, __t&& __rcvr, _As&&... __as) noexcept { try { __rcvr.__state_->__data_.template emplace<1>((_As&&) __as...); __rcvr.__loop_->finish(); } catch (...) { __rcvr.__set_error(std::current_exception()); } } template <same_as<set_error_t> _Tag, class _Error> friend void tag_invoke(_Tag, __t&& __rcvr, _Error __err) noexcept { __rcvr.__set_error((_Error&&) __err); } friend void tag_invoke(set_stopped_t __d, __t&& __rcvr) noexcept { __rcvr.__state_->__data_.template emplace<3>(__d); __rcvr.__loop_->finish(); } friend __env tag_invoke(get_env_t, const __t& __rcvr) noexcept { return __sync_wait::__make_env(*__rcvr.__loop_); } }; }; template <class _Sender> using __into_variant_result_t = decltype(into_variant(__declval<_Sender>())); struct sync_wait_t; using _Sender = __0; using __cust_sigs = __types< tag_invoke_t(sync_wait_t, __get_sender_domain_t(_Sender), _Sender), tag_invoke_t(sync_wait_t, _Sender)>; template <class _Sender> inline constexpr bool __is_sync_wait_customized = __minvocable<__which<__cust_sigs>, _Sender>; template <class _Sender> using __receiver_t = __t<__sync_wait_result_impl<_Sender, __q<__receiver>>>; struct __default_impl { template <class _Sender> auto operator()(_Sender&& __sndr) const -> std::optional<__sync_wait_result_t<_Sender>> { using state_t = __sync_wait_result_impl<_Sender, __q<__state>>; state_t __state{}; run_loop __loop; auto __op_state = connect((_Sender&&) __sndr, __receiver_t<_Sender>{&__state, &__loop}); start(__op_state); __loop.run(); if (__state.__data_.index() == 2) std::rethrow_exception(std::get<2>(__state.__data_)); if (__state.__data_.index() == 3) return std::nullopt; return std::move(std::get<1>(__state.__data_)); } }; template <class _Sender> using __dispatcher_for = __make_dispatcher<__cust_sigs, __mconst<__default_impl>, _Sender>; template <class _Sender> struct __sync_receiver_for { using __t = __receiver_t<_Sender>; }; template <class _Sender> using __sync_receiver_for_t = __t<__sync_receiver_for<_Sender>>; template <class _Sender> struct __value_tuple_for { using __t = __sync_wait_result_t<_Sender>; }; template <class _Sender> using __value_tuple_for_t = __t<__value_tuple_for<_Sender>>; struct sync_wait_t { template <sender_in<__env> _Sender> requires __satisfies<__single_value_variant_sender<_Sender, __env>> && (sender_to<_Sender, __sync_receiver_for_t<_Sender>> || __is_sync_wait_customized<_Sender>) auto operator()(_Sender&& __sndr) const -> std::optional<__value_tuple_for_t<_Sender>> { return __dispatcher_for<_Sender>{}((_Sender&&) __sndr); } }; struct sync_wait_with_variant_t { template <sender_in<__env> _Sender> requires __tag_invocable_with_domain< sync_wait_with_variant_t, set_value_t, _Sender> tag_invoke_result_t< sync_wait_with_variant_t, __sender_domain_of_t<_Sender>, _Sender> operator()(_Sender&& __sndr) const noexcept( nothrow_tag_invocable< sync_wait_with_variant_t, __sender_domain_of_t<_Sender>, _Sender>) { static_assert( std::is_same_v< tag_invoke_result_t< sync_wait_with_variant_t, __sender_domain_of_t<_Sender>, _Sender>, std::optional<__sync_wait_with_variant_result_t<_Sender>>>, "The type of tag_invoke(sync_wait_with_variant, get_completion_scheduler, S) " "must be sync-wait-with-variant-type<S, sync-wait-env>"); auto __domain = __get_sender_domain(__sndr); return tag_invoke(sync_wait_with_variant_t{}, __domain, (_Sender&&) __sndr); } template <sender_in<__env> _Sender> requires(!__tag_invocable_with_domain< sync_wait_with_variant_t, set_value_t, _Sender>) && tag_invocable<sync_wait_with_variant_t, _Sender> tag_invoke_result_t<sync_wait_with_variant_t, _Sender> operator()(_Sender&& __sndr) const noexcept(nothrow_tag_invocable<sync_wait_with_variant_t, _Sender>) { static_assert( std::is_same_v< tag_invoke_result_t<sync_wait_with_variant_t, _Sender>, std::optional<__sync_wait_with_variant_result_t<_Sender>>>, "The type of tag_invoke(sync_wait_with_variant, S) " "must be sync-wait-with-variant-type<S, sync-wait-env>"); return tag_invoke(sync_wait_with_variant_t{}, (_Sender&&) __sndr); } template <sender_in<__env> _Sender> requires(!__tag_invocable_with_domain< sync_wait_with_variant_t, set_value_t, _Sender>) && (!tag_invocable<sync_wait_with_variant_t, _Sender>) && invocable<sync_wait_t, __into_variant_result_t<_Sender>> std::optional<__sync_wait_with_variant_result_t<_Sender>> operator()(_Sender&& __sndr) const { return sync_wait_t{}(into_variant((_Sender&&) __sndr)); } }; } using __sync_wait::sync_wait_t; inline constexpr sync_wait_t sync_wait{}; using __sync_wait::sync_wait_with_variant_t; inline constexpr sync_wait_with_variant_t sync_wait_with_variant{}; struct __ignore_sender { using is_sender = void; template <sender _Sender> constexpr __ignore_sender(_Sender&&) noexcept { } }; template <auto _Reason = "You cannot pipe one sender into another."__csz> struct _CANNOT_PIPE_INTO_A_SENDER_ { }; template <class _Sender> struct _WITH_SENDER_ { }; template <class _Sender> using __bad_pipe_sink_t = __mexception<_CANNOT_PIPE_INTO_A_SENDER_<>, _WITH_SENDER_<_Sender>>; } template <stdexec::sender _Sender> requires stdexec::__ok<stdexec::__bad_pipe_sink_t<_Sender>> auto operator|(stdexec::__ignore_sender, _Sender&&) noexcept -> stdexec::__ignore_sender; namespace std { [[deprecated( "Please access this entity in the ::stdexec:: namespace. Define " "STDEXEC_DISABLE_STD_DEPRECATIONS to silence this " "warning.")]] inline constexpr stdexec::tag_invoke_t tag_invoke{}; template <class _Tag, class... _Ts> using tag_invoke_result [[deprecated( "Please access this entity in the ::stdexec:: namespace. Define " "STDEXEC_DISABLE_STD_DEPRECATIONS to silence this " "warning.")]] = stdexec::tag_invoke_result<_Tag, _Ts...>; template <class _Tag, class... _Ts> using tag_invoke_result_t [[deprecated( "Please access this entity in the ::stdexec:: namespace. Define " "STDEXEC_DISABLE_STD_DEPRECATIONS to silence this " "warning.")]] = stdexec::tag_invoke_result_t<_Tag, _Ts...>; template <class _Tag, class... _Ts> concept tag_invocable = stdexec::tag_invocable<_Tag, _Ts...>; template <class _Tag, class... _Ts> concept nothrow_tag_invocable = stdexec::nothrow_tag_invocable<_Tag, _Ts...>; template <auto& _Tag> using tag_t [[deprecated( "Please access this entity in the ::stdexec:: namespace. Define " "STDEXEC_DISABLE_STD_DEPRECATIONS to silence this " "warning.")]] = stdexec::tag_t<_Tag>; template <class _Token> concept stoppable_token = stdexec::stoppable_token<_Token>; template <class _Token, typename _Callback, typename _Initializer = _Callback> concept stoppable_token_for = stdexec::stoppable_token_for<_Token, _Callback, _Initializer>; template <class _Token> concept unstoppable_token = stdexec::unstoppable_token<_Token>; using never_stop_token [[deprecated( "Please access this entity in the ::stdexec:: namespace. Define " "STDEXEC_DISABLE_STD_DEPRECATIONS to silence this " "warning.")]] = stdexec::never_stop_token; using in_place_stop_token [[deprecated( "Please access this entity in the ::stdexec:: namespace. Define " "STDEXEC_DISABLE_STD_DEPRECATIONS to silence this " "warning.")]] = stdexec::in_place_stop_token; using in_place_stop_source [[deprecated( "Please access this entity in the ::stdexec:: namespace. Define " "STDEXEC_DISABLE_STD_DEPRECATIONS to silence this " "warning.")]] = stdexec::in_place_stop_source; template <class _Callback> using in_place_stop_callback [[deprecated( "Please access this entity in the ::stdexec:: namespace. Define " "STDEXEC_DISABLE_STD_DEPRECATIONS to silence this " "warning.")]] = stdexec::in_place_stop_callback<_Callback>; namespace execution { using get_scheduler_t [[deprecated( "Please access this entity in the ::stdexec:: namespace. Define " "STDEXEC_DISABLE_STD_DEPRECATIONS to silence this " "warning.")]] = stdexec::get_scheduler_t; using get_delegatee_scheduler_t [[deprecated( "Please access this entity in the ::stdexec:: namespace. Define " "STDEXEC_DISABLE_STD_DEPRECATIONS to silence this " "warning.")]] = stdexec::get_delegatee_scheduler_t; using get_allocator_t [[deprecated( "Please access this entity in the ::stdexec:: namespace. Define " "STDEXEC_DISABLE_STD_DEPRECATIONS to silence this " "warning.")]] = stdexec::get_allocator_t; using get_stop_token_t [[deprecated( "Please access this entity in the ::stdexec:: namespace. Define " "STDEXEC_DISABLE_STD_DEPRECATIONS to silence this " "warning.")]] = stdexec::get_stop_token_t; [[deprecated( "Please access this entity in the ::stdexec:: namespace. Define " "STDEXEC_DISABLE_STD_DEPRECATIONS to silence this " "warning.")]] inline constexpr stdexec::get_scheduler_t get_scheduler{}; [[deprecated( "Please access this entity in the ::stdexec:: namespace. Define " "STDEXEC_DISABLE_STD_DEPRECATIONS to silence this " "warning.")]] inline constexpr stdexec::get_delegatee_scheduler_t get_delegatee_scheduler{}; [[deprecated( "Please access this entity in the ::stdexec:: namespace. Define " "STDEXEC_DISABLE_STD_DEPRECATIONS to silence this " "warning.")]] inline constexpr stdexec::get_allocator_t get_allocator{}; [[deprecated( "Please access this entity in the ::stdexec:: namespace. Define " "STDEXEC_DISABLE_STD_DEPRECATIONS to silence this " "warning.")]] inline constexpr stdexec::get_stop_token_t get_stop_token{}; template <class _StopTokenProvider> using stop_token_of_t [[deprecated( "Please access this entity in the ::stdexec:: namespace. Define " "STDEXEC_DISABLE_STD_DEPRECATIONS to silence this " "warning.")]] = stdexec::stop_token_of_t<_StopTokenProvider>; using no_env [[deprecated( "Please access this entity in the ::stdexec:: namespace. Define " "STDEXEC_DISABLE_STD_DEPRECATIONS to silence this " "warning.")]] = stdexec::no_env; using get_env_t [[deprecated( "Please access this entity in the ::stdexec:: namespace. Define " "STDEXEC_DISABLE_STD_DEPRECATIONS to silence this " "warning.")]] = stdexec::get_env_t; [[deprecated( "Please access this entity in the ::stdexec:: namespace. Define " "STDEXEC_DISABLE_STD_DEPRECATIONS to silence this " "warning.")]] inline constexpr stdexec::get_env_t get_env{}; template <class _EnvProvider> using env_of_t [[deprecated( "Please access this entity in the ::stdexec:: namespace. Define " "STDEXEC_DISABLE_STD_DEPRECATIONS to silence this " "warning.")]] = stdexec::env_of_t<_EnvProvider>; template <class _Scheduler> concept scheduler = stdexec::scheduler<_Scheduler>; using forward_progress_guarantee [[deprecated( "Please access this entity in the ::stdexec:: namespace. Define " "STDEXEC_DISABLE_STD_DEPRECATIONS to silence this " "warning.")]] = stdexec::forward_progress_guarantee; [[deprecated( "Please access this entity in the ::stdexec:: namespace. Define " "STDEXEC_DISABLE_STD_DEPRECATIONS to silence this " "warning.")]] inline constexpr stdexec::get_forward_progress_guarantee_t get_forward_progress_guarantee{}; template <class _Receiver> concept receiver = stdexec::receiver<_Receiver>; template <class _Receiver, class _Completions> concept receiver_of = stdexec::receiver_of<_Receiver, _Completions>; using set_value_t [[deprecated( "Please access this entity in the ::stdexec:: namespace. Define " "STDEXEC_DISABLE_STD_DEPRECATIONS to silence this " "warning.")]] = stdexec::set_value_t; using set_error_t [[deprecated( "Please access this entity in the ::stdexec:: namespace. Define " "STDEXEC_DISABLE_STD_DEPRECATIONS to silence this " "warning.")]] = stdexec::set_error_t; using set_stopped_t [[deprecated( "Please access this entity in the ::stdexec:: namespace. Define " "STDEXEC_DISABLE_STD_DEPRECATIONS to silence this " "warning.")]] = stdexec::set_stopped_t; [[deprecated( "Please access this entity in the ::stdexec:: namespace. Define " "STDEXEC_DISABLE_STD_DEPRECATIONS to silence this " "warning.")]] inline constexpr stdexec::set_value_t set_value{}; [[deprecated( "Please access this entity in the ::stdexec:: namespace. Define " "STDEXEC_DISABLE_STD_DEPRECATIONS to silence this " "warning.")]] inline constexpr stdexec::set_error_t set_error{}; [[deprecated( "Please access this entity in the ::stdexec:: namespace. Define " "STDEXEC_DISABLE_STD_DEPRECATIONS to silence this " "warning.")]] inline constexpr stdexec::set_stopped_t set_stopped{}; template <class _OpState> concept operation_state = stdexec::operation_state<_OpState>; using start_t [[deprecated( "Please access this entity in the ::stdexec:: namespace. Define " "STDEXEC_DISABLE_STD_DEPRECATIONS to silence this " "warning.")]] = stdexec::start_t; [[deprecated( "Please access this entity in the ::stdexec:: namespace. Define " "STDEXEC_DISABLE_STD_DEPRECATIONS to silence this " "warning.")]] inline constexpr stdexec::start_t start{}; template <class _Sender, class _Env = stdexec::no_env> concept sender = stdexec::sender_in<_Sender, _Env>; template <class _Sender, class _Receiver> concept sender_to = stdexec::sender_to<_Sender, _Receiver>; template <class _Sender, class _SetSig, class _Env = stdexec::no_env> concept sender_of = stdexec::sender_of<_Sender, _SetSig, _Env>; using get_completion_signatures_t [[deprecated( "Please access this entity in the ::stdexec:: namespace. Define " "STDEXEC_DISABLE_STD_DEPRECATIONS to silence this " "warning.")]] = stdexec::get_completion_signatures_t; [[deprecated( "Please access this entity in the ::stdexec:: namespace. Define " "STDEXEC_DISABLE_STD_DEPRECATIONS to silence this " "warning.")]] inline constexpr stdexec::get_completion_signatures_t get_completion_signatures{}; template <class _Sender, class _Env = stdexec::no_env> using completion_signatures_of_t [[deprecated( "Please access this entity in the ::stdexec:: namespace. Define " "STDEXEC_DISABLE_STD_DEPRECATIONS to silence this " "warning.")]] = stdexec::completion_signatures_of_t<_Sender, _Env>; template <class _Env> using dependent_completion_signatures [[deprecated( "Please access this entity in the ::stdexec:: namespace. Define " "STDEXEC_DISABLE_STD_DEPRECATIONS to silence this " "warning.")]] = stdexec::dependent_completion_signatures<_Env>; template < class _Sender, class _Env = stdexec::no_env, template <class...> class _Tuple = stdexec::__decayed_tuple, template <class...> class _Variant = stdexec::__variant> using value_types_of_t [[deprecated( "Please access this entity in the ::stdexec:: namespace. Define " "STDEXEC_DISABLE_STD_DEPRECATIONS to silence this " "warning.")]] = stdexec::value_types_of_t<_Sender, _Env, _Tuple, _Variant>; template < class _Sender, class _Env = stdexec::no_env, template <class...> class _Variant = stdexec::__variant> using error_types_of_t [[deprecated( "Please access this entity in the ::stdexec:: namespace. Define " "STDEXEC_DISABLE_STD_DEPRECATIONS to silence this " "warning.")]] = stdexec::error_types_of_t<_Sender, _Env, _Variant>; template <class _Sender, class _Env = stdexec::no_env> [[deprecated( "Please access this entity in the ::stdexec:: namespace. Define " "STDEXEC_DISABLE_STD_DEPRECATIONS to silence this " "warning.")]] inline constexpr bool sends_stopped = stdexec::sends_stopped<_Sender, _Env>; using connect_t [[deprecated( "Please access this entity in the ::stdexec:: namespace. Define " "STDEXEC_DISABLE_STD_DEPRECATIONS to silence this " "warning.")]] = stdexec::connect_t; [[deprecated( "Please access this entity in the ::stdexec:: namespace. Define " "STDEXEC_DISABLE_STD_DEPRECATIONS to silence this " "warning.")]] inline constexpr stdexec::connect_t connect{}; template <class _Sender, class _Receiver> using connect_result_t [[deprecated( "Please access this entity in the ::stdexec:: namespace. Define " "STDEXEC_DISABLE_STD_DEPRECATIONS to silence this " "warning.")]] = stdexec::connect_result_t<_Sender, _Receiver>; template <class _Tag> using get_completion_scheduler_t [[deprecated( "Please access this entity in the ::stdexec:: namespace. Define " "STDEXEC_DISABLE_STD_DEPRECATIONS to silence this " "warning.")]] = stdexec::get_completion_scheduler_t<_Tag>; template <class _Tag> [[deprecated( "Please access this entity in the ::stdexec:: namespace. Define " "STDEXEC_DISABLE_STD_DEPRECATIONS to silence this " "warning.")]] inline constexpr stdexec::get_completion_scheduler_t<_Tag> get_completion_scheduler{}; using schedule_t [[deprecated( "Please access this entity in the ::stdexec:: namespace. Define " "STDEXEC_DISABLE_STD_DEPRECATIONS to silence this " "warning.")]] = stdexec::schedule_t; using transfer_just_t [[deprecated( "Please access this entity in the ::stdexec:: namespace. Define " "STDEXEC_DISABLE_STD_DEPRECATIONS to silence this " "warning.")]] = stdexec::transfer_just_t; [[deprecated( "Please access this entity in the ::stdexec:: namespace. Define " "STDEXEC_DISABLE_STD_DEPRECATIONS to silence this " "warning.")]] inline constexpr auto just = stdexec::just; [[deprecated( "Please access this entity in the ::stdexec:: namespace. Define " "STDEXEC_DISABLE_STD_DEPRECATIONS to silence this " "warning.")]] inline constexpr auto just_error = stdexec::just_error; [[deprecated( "Please access this entity in the ::stdexec:: namespace. Define " "STDEXEC_DISABLE_STD_DEPRECATIONS to silence this " "warning.")]] inline constexpr auto just_stopped = stdexec::just_stopped; [[deprecated( "Please access this entity in the ::stdexec:: namespace. Define " "STDEXEC_DISABLE_STD_DEPRECATIONS to silence this " "warning.")]] inline constexpr auto schedule = stdexec::schedule; [[deprecated( "Please access this entity in the ::stdexec:: namespace. Define " "STDEXEC_DISABLE_STD_DEPRECATIONS to silence this " "warning.")]] inline constexpr auto transfer_just = stdexec::transfer_just; [[deprecated( "Please access this entity in the ::stdexec:: namespace. Define " "STDEXEC_DISABLE_STD_DEPRECATIONS to silence this " "warning.")]] inline constexpr auto read = stdexec::read; template <class _Scheduler> using schedule_result_t [[deprecated( "Please access this entity in the ::stdexec:: namespace. Define " "STDEXEC_DISABLE_STD_DEPRECATIONS to silence this " "warning.")]] = stdexec::schedule_result_t<_Scheduler>; template <class _Closure> using sender_adaptor_closure [[deprecated( "Please access this entity in the ::stdexec:: namespace. Define " "STDEXEC_DISABLE_STD_DEPRECATIONS to silence this " "warning.")]] = stdexec::sender_adaptor_closure<_Closure>; using on_t [[deprecated( "Please access this entity in the ::stdexec:: namespace. Define " "STDEXEC_DISABLE_STD_DEPRECATIONS to silence this " "warning.")]] = stdexec::on_t; using transfer_t [[deprecated( "Please access this entity in the ::stdexec:: namespace. Define " "STDEXEC_DISABLE_STD_DEPRECATIONS to silence this " "warning.")]] = stdexec::transfer_t; using schedule_from_t [[deprecated( "Please access this entity in the ::stdexec:: namespace. Define " "STDEXEC_DISABLE_STD_DEPRECATIONS to silence this " "warning.")]] = stdexec::schedule_from_t; using then_t [[deprecated( "Please access this entity in the ::stdexec:: namespace. Define " "STDEXEC_DISABLE_STD_DEPRECATIONS to silence this " "warning.")]] = stdexec::then_t; using upon_error_t [[deprecated( "Please access this entity in the ::stdexec:: namespace. Define " "STDEXEC_DISABLE_STD_DEPRECATIONS to silence this " "warning.")]] = stdexec::upon_error_t; using upon_stopped_t [[deprecated( "Please access this entity in the ::stdexec:: namespace. Define " "STDEXEC_DISABLE_STD_DEPRECATIONS to silence this " "warning.")]] = stdexec::upon_stopped_t; using let_value_t [[deprecated( "Please access this entity in the ::stdexec:: namespace. Define " "STDEXEC_DISABLE_STD_DEPRECATIONS to silence this " "warning.")]] = stdexec::let_value_t; using let_error_t [[deprecated( "Please access this entity in the ::stdexec:: namespace. Define " "STDEXEC_DISABLE_STD_DEPRECATIONS to silence this " "warning.")]] = stdexec::let_error_t; using let_stopped_t [[deprecated( "Please access this entity in the ::stdexec:: namespace. Define " "STDEXEC_DISABLE_STD_DEPRECATIONS to silence this " "warning.")]] = stdexec::let_stopped_t; using bulk_t [[deprecated( "Please access this entity in the ::stdexec:: namespace. Define " "STDEXEC_DISABLE_STD_DEPRECATIONS to silence this " "warning.")]] = stdexec::bulk_t; using split_t [[deprecated( "Please access this entity in the ::stdexec:: namespace. Define " "STDEXEC_DISABLE_STD_DEPRECATIONS to silence this " "warning.")]] = stdexec::split_t; using when_all_t [[deprecated( "Please access this entity in the ::stdexec:: namespace. Define " "STDEXEC_DISABLE_STD_DEPRECATIONS to silence this " "warning.")]] = stdexec::when_all_t; using when_all_with_variant_t [[deprecated( "Please access this entity in the ::stdexec:: namespace. Define " "STDEXEC_DISABLE_STD_DEPRECATIONS to silence this " "warning.")]] = stdexec::when_all_with_variant_t; using transfer_when_all_t [[deprecated( "Please access this entity in the ::stdexec:: namespace. Define " "STDEXEC_DISABLE_STD_DEPRECATIONS to silence this " "warning.")]] = stdexec::transfer_when_all_t; using transfer_when_all_with_variant_t [[deprecated( "Please access this entity in the ::stdexec:: namespace. Define " "STDEXEC_DISABLE_STD_DEPRECATIONS to silence this " "warning.")]] = stdexec::transfer_when_all_with_variant_t; using into_variant_t [[deprecated( "Please access this entity in the ::stdexec:: namespace. Define " "STDEXEC_DISABLE_STD_DEPRECATIONS to silence this " "warning.")]] = stdexec::into_variant_t; using stopped_as_optional_t [[deprecated( "Please access this entity in the ::stdexec:: namespace. Define " "STDEXEC_DISABLE_STD_DEPRECATIONS to silence this " "warning.")]] = stdexec::stopped_as_optional_t; using stopped_as_error_t [[deprecated( "Please access this entity in the ::stdexec:: namespace. Define " "STDEXEC_DISABLE_STD_DEPRECATIONS to silence this " "warning.")]] = stdexec::stopped_as_error_t; using ensure_started_t [[deprecated( "Please access this entity in the ::stdexec:: namespace. Define " "STDEXEC_DISABLE_STD_DEPRECATIONS to silence this " "warning.")]] = stdexec::ensure_started_t; [[deprecated( "Please access this entity in the ::stdexec:: namespace. Define " "STDEXEC_DISABLE_STD_DEPRECATIONS to silence this " "warning.")]] inline constexpr auto on = stdexec::on; [[deprecated( "Please access this entity in the ::stdexec:: namespace. Define " "STDEXEC_DISABLE_STD_DEPRECATIONS to silence this " "warning.")]] inline constexpr auto transfer = stdexec::transfer; [[deprecated( "Please access this entity in the ::stdexec:: namespace. Define " "STDEXEC_DISABLE_STD_DEPRECATIONS to silence this " "warning.")]] inline constexpr auto schedule_from = stdexec::schedule_from; [[deprecated( "Please access this entity in the ::stdexec:: namespace. Define " "STDEXEC_DISABLE_STD_DEPRECATIONS to silence this " "warning.")]] inline constexpr auto then = stdexec::then; [[deprecated( "Please access this entity in the ::stdexec:: namespace. Define " "STDEXEC_DISABLE_STD_DEPRECATIONS to silence this " "warning.")]] inline constexpr auto upon_error = stdexec::upon_error; [[deprecated( "Please access this entity in the ::stdexec:: namespace. Define " "STDEXEC_DISABLE_STD_DEPRECATIONS to silence this " "warning.")]] inline constexpr auto upon_stopped = stdexec::upon_stopped; [[deprecated( "Please access this entity in the ::stdexec:: namespace. Define " "STDEXEC_DISABLE_STD_DEPRECATIONS to silence this " "warning.")]] inline constexpr auto let_value = stdexec::let_value; [[deprecated( "Please access this entity in the ::stdexec:: namespace. Define " "STDEXEC_DISABLE_STD_DEPRECATIONS to silence this " "warning.")]] inline constexpr auto let_error = stdexec::let_error; [[deprecated( "Please access this entity in the ::stdexec:: namespace. Define " "STDEXEC_DISABLE_STD_DEPRECATIONS to silence this " "warning.")]] inline constexpr auto let_stopped = stdexec::let_stopped; [[deprecated( "Please access this entity in the ::stdexec:: namespace. Define " "STDEXEC_DISABLE_STD_DEPRECATIONS to silence this " "warning.")]] inline constexpr auto bulk = stdexec::bulk; [[deprecated( "Please access this entity in the ::stdexec:: namespace. Define " "STDEXEC_DISABLE_STD_DEPRECATIONS to silence this " "warning.")]] inline constexpr auto split = stdexec::split; [[deprecated( "Please access this entity in the ::stdexec:: namespace. Define " "STDEXEC_DISABLE_STD_DEPRECATIONS to silence this " "warning.")]] inline constexpr auto when_all = stdexec::when_all; [[deprecated( "Please access this entity in the ::stdexec:: namespace. Define " "STDEXEC_DISABLE_STD_DEPRECATIONS to silence this " "warning.")]] inline constexpr auto when_all_with_variant = stdexec::when_all_with_variant; [[deprecated( "Please access this entity in the ::stdexec:: namespace. Define " "STDEXEC_DISABLE_STD_DEPRECATIONS to silence this " "warning.")]] inline constexpr auto transfer_when_all = stdexec::transfer_when_all; [[deprecated( "Please access this entity in the ::stdexec:: namespace. Define " "STDEXEC_DISABLE_STD_DEPRECATIONS to silence this " "warning.")]] inline constexpr auto transfer_when_all_with_variant = stdexec::transfer_when_all_with_variant; [[deprecated( "Please access this entity in the ::stdexec:: namespace. Define " "STDEXEC_DISABLE_STD_DEPRECATIONS to silence this " "warning.")]] inline constexpr auto into_variant = stdexec::into_variant; [[deprecated( "Please access this entity in the ::stdexec:: namespace. Define " "STDEXEC_DISABLE_STD_DEPRECATIONS to silence this " "warning.")]] inline constexpr auto stopped_as_optional = stdexec::stopped_as_optional; [[deprecated( "Please access this entity in the ::stdexec:: namespace. Define " "STDEXEC_DISABLE_STD_DEPRECATIONS to silence this " "warning.")]] inline constexpr auto stopped_as_error = stdexec::stopped_as_error; [[deprecated( "Please access this entity in the ::stdexec:: namespace. Define " "STDEXEC_DISABLE_STD_DEPRECATIONS to silence this " "warning.")]] inline constexpr auto ensure_started = stdexec::ensure_started; using start_detached_t [[deprecated( "Please access this entity in the ::stdexec:: namespace. Define " "STDEXEC_DISABLE_STD_DEPRECATIONS to silence this " "warning.")]] = stdexec::start_detached_t; [[deprecated( "Please access this entity in the ::stdexec:: namespace. Define " "STDEXEC_DISABLE_STD_DEPRECATIONS to silence this " "warning.")]] inline constexpr auto start_detached = stdexec::start_detached; template <class _Derived, class _Base = stdexec::__adaptors::__not_a_receiver> using receiver_adaptor [[deprecated( "Please access this entity in the ::stdexec:: namespace. Define " "STDEXEC_DISABLE_STD_DEPRECATIONS to silence this " "warning.")]] = stdexec::receiver_adaptor<_Derived, _Base>; template <class... _Sigs> using completion_signatures [[deprecated( "Please access this entity in the ::stdexec:: namespace. Define " "STDEXEC_DISABLE_STD_DEPRECATIONS to silence this " "warning.")]] = stdexec::completion_signatures<_Sigs...>; template < class _Sender, class _Env = stdexec::no_env, class _Sigs = stdexec::completion_signatures<>, template <class...> class _SetValue = stdexec::__compl_sigs::__default_set_value, template <class> class _SetError = stdexec::__compl_sigs::__default_set_error, class _SetStopped = stdexec::completion_signatures<stdexec::set_stopped_t()>> using make_completion_signatures [[deprecated( "Please access this entity in the ::stdexec:: namespace. Define " "STDEXEC_DISABLE_STD_DEPRECATIONS to silence this " "warning.")]] = stdexec::make_completion_signatures<_Sender, _Env, _Sigs, _SetValue, _SetError, _SetStopped>; using run_loop [[deprecated( "Please access this entity in the ::stdexec:: namespace. Define " "STDEXEC_DISABLE_STD_DEPRECATIONS to silence this " "warning.")]] = stdexec::run_loop; using execute_t [[deprecated( "Please access this entity in the ::stdexec:: namespace. Define " "STDEXEC_DISABLE_STD_DEPRECATIONS to silence this " "warning.")]] = stdexec::execute_t; [[deprecated( "Please access this entity in the ::stdexec:: namespace. Define " "STDEXEC_DISABLE_STD_DEPRECATIONS to silence this " "warning.")]] inline constexpr auto execute = stdexec::execute; } namespace this_thread { using execute_may_block_caller_t [[deprecated( "Please access this entity in the ::stdexec:: namespace. Define " "STDEXEC_DISABLE_STD_DEPRECATIONS to silence this " "warning.")]] = stdexec::execute_may_block_caller_t; using sync_wait_t [[deprecated( "Please access this entity in the ::stdexec:: namespace. Define " "STDEXEC_DISABLE_STD_DEPRECATIONS to silence this " "warning.")]] = stdexec::sync_wait_t; using sync_wait_with_variant_t [[deprecated( "Please access this entity in the ::stdexec:: namespace. Define " "STDEXEC_DISABLE_STD_DEPRECATIONS to silence this " "warning.")]] = stdexec::sync_wait_with_variant_t; [[deprecated( "Please access this entity in the ::stdexec:: namespace. Define " "STDEXEC_DISABLE_STD_DEPRECATIONS to silence this " "warning.")]] inline constexpr auto execute_may_block_caller = stdexec::execute_may_block_caller; [[deprecated( "Please access this entity in the ::stdexec:: namespace. Define " "STDEXEC_DISABLE_STD_DEPRECATIONS to silence this " "warning.")]] inline constexpr auto sync_wait = stdexec::sync_wait; [[deprecated( "Please access this entity in the ::stdexec:: namespace. Define " "STDEXEC_DISABLE_STD_DEPRECATIONS to silence this " "warning.")]] inline constexpr auto sync_wait_with_variant = stdexec::sync_wait_with_variant; } } #include <cassert> #include <tuple> #include <utility> namespace stdexec { namespace __queue { template <auto _Next> class __intrusive_queue; template <class _Item, _Item* _Item::*_Next> class __intrusive_queue<_Next> { public: __intrusive_queue() noexcept = default; __intrusive_queue(__intrusive_queue&& __other) noexcept : __head_(std::exchange(__other.__head_, nullptr)) , __tail_(std::exchange(__other.__tail_, nullptr)) { } __intrusive_queue& operator=(__intrusive_queue __other) noexcept { std::swap(__head_, __other.__head_); std::swap(__tail_, __other.__tail_); return *this; } ~__intrusive_queue() { do { static_assert(noexcept(empty())); assert(empty()); } while (false); } static __intrusive_queue make_reversed(_Item* __list) noexcept { _Item* __new_head = nullptr; _Item* __new_tail = __list; while (__list != nullptr) { _Item* __next = __list->*_Next; __list->*_Next = __new_head; __new_head = __list; __list = __next; } __intrusive_queue __result; __result.__head_ = __new_head; __result.__tail_ = __new_tail; return __result; } [[nodiscard]] bool empty() const noexcept { return __head_ == nullptr; } [[nodiscard]] _Item* pop_front() noexcept { do { static_assert(noexcept(!empty())); assert(!empty()); } while (false); _Item* __item = std::exchange(__head_, __head_->*_Next); if (__item->*_Next == nullptr) { __tail_ = nullptr; } return __item; } void push_front(_Item* __item) noexcept { do { static_assert(noexcept(__item != nullptr)); assert(__item != nullptr); } while (false); __item->*_Next = __head_; __head_ = __item; if (__tail_ == nullptr) { __tail_ = __item; } } void push_back(_Item* __item) noexcept { do { static_assert(noexcept(__item != nullptr)); assert(__item != nullptr); } while (false); __item->*_Next = nullptr; if (__tail_ == nullptr) { __head_ = __item; } else { __tail_->*_Next = __item; } __tail_ = __item; } void append(__intrusive_queue __other) noexcept { if (__other.empty()) return; auto* __other_head = std::exchange(__other.__head_, nullptr); if (empty()) { __head_ = __other_head; } else { __tail_->*_Next = __other_head; } __tail_ = std::exchange(__other.__tail_, nullptr); } void prepend(__intrusive_queue __other) noexcept { if (__other.empty()) return; __other.__tail_->*_Next = __head_; __head_ = __other.__head_; if (__tail_ == nullptr) { __tail_ = __other.__tail_; } __other.__tail_ = nullptr; __other.__head_ = nullptr; } private: _Item* __head_ = nullptr; _Item* __tail_ = nullptr; }; } using __queue::__intrusive_queue; } #include <atomic> #include <condition_variable> #include <exception> #include <mutex> #include <thread> #include <type_traits> #include <vector> namespace exec { using stdexec::__intrusive_queue; struct task_base { task_base* next; void (*__execute)(task_base*, std::uint32_t tid) noexcept; }; template <typename ReceiverID> class operation; class static_thread_pool { template <typename ReceiverId> friend class operation; public: static_thread_pool(); static_thread_pool(std::uint32_t threadCount); ~static_thread_pool(); struct scheduler { using __t = scheduler; using __id = scheduler; bool operator==(const scheduler&) const = default; private: template <typename ReceiverId> friend class operation; class sender { public: using __t = sender; using __id = sender; using is_sender = void; using completion_signatures = stdexec::completion_signatures< stdexec::set_value_t(), stdexec::set_stopped_t()>; private: template <typename Receiver> auto make_operation_(Receiver r) const -> operation<stdexec::__id<Receiver>> { return operation<stdexec::__id<Receiver>>{pool_, (Receiver&&) r}; } template <stdexec::receiver Receiver> friend auto tag_invoke(stdexec::connect_t, sender s, Receiver r) -> operation<stdexec::__id<Receiver>> { return s.make_operation_((Receiver&&) r); } struct env { static_thread_pool& pool_; template <class CPO> friend static_thread_pool::scheduler tag_invoke(stdexec::get_completion_scheduler_t<CPO>, const env& self) noexcept { return self.make_scheduler_(); } static_thread_pool::scheduler make_scheduler_() const { return static_thread_pool::scheduler{pool_}; } }; friend env tag_invoke(stdexec::get_env_t, const sender& self) noexcept { return env{self.pool_}; } friend struct static_thread_pool::scheduler; explicit sender(static_thread_pool& pool) noexcept : pool_(pool) { } static_thread_pool& pool_; }; sender make_sender_() const { return sender{*pool_}; } template <class Fun, class Shape, class... Args> requires stdexec::__callable<Fun, Shape, Args&...> using bulk_non_throwing = stdexec::__mbool< stdexec::__nothrow_callable<Fun, Shape, Args&...> && noexcept(stdexec::__decayed_tuple<Args...>(std::declval<Args>()...)) >; template <class SenderId, class ReceiverId, class Shape, class Fun, bool MayThrow> struct bulk_shared_state { using Sender = stdexec::__t<SenderId>; using Receiver = stdexec::__t<ReceiverId>; struct bulk_task : task_base { bulk_shared_state* sh_state_; bulk_task(bulk_shared_state* sh_state) : sh_state_(sh_state) { this->__execute = [](task_base* t, const std::uint32_t tid) noexcept { auto& sh_state = *static_cast<bulk_task*>(t)->sh_state_; auto total_threads = sh_state.num_agents_required(); auto computation = [&](auto&... args) { auto [begin, end] = even_share(sh_state.shape_, tid, total_threads); for (Shape i = begin; i < end; ++i) { sh_state.fn_(i, args...); } }; auto completion = [&](auto&... args) { stdexec::set_value((Receiver&&) sh_state.receiver_, std::move(args)...); }; if constexpr (MayThrow) { try { sh_state.apply(computation); } catch (...) { std::uint32_t expected = total_threads; if (sh_state.thread_with_exception_.compare_exchange_strong( expected, tid, std::memory_order_relaxed, std::memory_order_relaxed)) { sh_state.exception_ = std::current_exception(); } } const bool is_last_thread = sh_state.finished_threads_.fetch_add(1) == (total_threads - 1); if (is_last_thread) { if (sh_state.exception_) { stdexec::set_error( (Receiver&&) sh_state.receiver_, std::move(sh_state.exception_)); } else { sh_state.apply(completion); } } } else { sh_state.apply(computation); const bool is_last_thread = sh_state.finished_threads_.fetch_add(1) == (total_threads - 1); if (is_last_thread) { sh_state.apply(completion); } } }; } }; using variant_t = stdexec::__value_types_of_t< Sender, stdexec::env_of_t<Receiver>, stdexec::__q<stdexec::__decayed_tuple>, stdexec::__q<stdexec::__variant>>; variant_t data_; static_thread_pool& pool_; Receiver receiver_; Shape shape_; Fun fn_; std::atomic<std::uint32_t> finished_threads_{0}; std::atomic<std::uint32_t> thread_with_exception_{0}; std::exception_ptr exception_; std::vector<bulk_task> tasks_; static std::pair<Shape, Shape> even_share(Shape n, std::uint32_t rank, std::uint32_t size) noexcept { const auto avg_per_thread = n / size; const auto n_big_share = avg_per_thread + 1; const auto big_shares = n % size; const auto is_big_share = rank < big_shares; const auto begin = is_big_share ? n_big_share * rank : n_big_share * big_shares + (rank - big_shares) * avg_per_thread; const auto end = begin + (is_big_share ? n_big_share : avg_per_thread); return std::make_pair(begin, end); } std::uint32_t num_agents_required() const { return std::min(shape_, static_cast<Shape>(pool_.available_parallelism())); } template <class F> void apply(F f) { std::visit( [&](auto& tupl) -> void { std::apply([&](auto&... args) -> void { f(args...); }, tupl); }, data_); } bulk_shared_state(static_thread_pool& pool, Receiver receiver, Shape shape, Fun fn) : pool_{pool} , receiver_{(Receiver&&) receiver} , shape_{shape} , fn_{fn} , thread_with_exception_{num_agents_required()} , tasks_{num_agents_required(), {this}} { } }; template <class SenderId, class ReceiverId, class Shape, class Fn, bool MayThrow> struct bulk_receiver { using is_receiver = void; using Sender = stdexec::__t<SenderId>; using Receiver = stdexec::__t<ReceiverId>; using shared_state = bulk_shared_state<SenderId, ReceiverId, Shape, Fn, MayThrow>; shared_state& shared_state_; void enqueue() noexcept { shared_state_.pool_.bulk_enqueue( shared_state_.tasks_.data(), shared_state_.num_agents_required()); } template <class... As> friend void tag_invoke( stdexec::same_as<stdexec::set_value_t> auto, bulk_receiver&& self, As&&... as) noexcept { using tuple_t = stdexec::__decayed_tuple<As...>; shared_state& state = self.shared_state_; if constexpr (MayThrow) { try { state.data_.template emplace<tuple_t>((As&&) as...); } catch (...) { stdexec::set_error(std::move(state.receiver_), std::current_exception()); } } else { state.data_.template emplace<tuple_t>((As&&) as...); } if (state.shape_) { self.enqueue(); } else { state.apply([&](auto&... args) { stdexec::set_value(std::move(state.receiver_), std::move(args)...); }); } } template <stdexec::__one_of<stdexec::set_error_t, stdexec::set_stopped_t> Tag, class... As> friend void tag_invoke(Tag tag, bulk_receiver&& self, As&&... as) noexcept { shared_state& state = self.shared_state_; tag((Receiver&&) state.receiver_, (As&&) as...); } friend auto tag_invoke(stdexec::get_env_t, const bulk_receiver& self) noexcept -> stdexec::env_of_t<Receiver> { return stdexec::get_env(self.shared_state_.receiver_); } }; template <class SenderId, class ReceiverId, std::integral Shape, class Fun> struct bulk_op_state { using Sender = stdexec::__t<SenderId>; using Receiver = stdexec::__t<ReceiverId>; static constexpr bool may_throw = !stdexec::__v<stdexec::__value_types_of_t< Sender, stdexec::env_of_t<Receiver>, stdexec::__mbind_front_q<bulk_non_throwing, Fun, Shape>, stdexec::__q<stdexec::__mand>>>; using bulk_rcvr = bulk_receiver<SenderId, ReceiverId, Shape, Fun, may_throw>; using shared_state = bulk_shared_state<SenderId, ReceiverId, Shape, Fun, may_throw>; using inner_op_state = stdexec::connect_result_t<Sender, bulk_rcvr>; shared_state shared_state_; inner_op_state inner_op_; friend void tag_invoke(stdexec::start_t, bulk_op_state& op) noexcept { stdexec::start(op.inner_op_); } bulk_op_state( static_thread_pool& pool, Shape shape, Fun fn, Sender&& sender, Receiver receiver) : shared_state_(pool, (Receiver&&) receiver, shape, fn) , inner_op_{stdexec::connect((Sender&&) sender, bulk_rcvr{shared_state_})} { } }; template <class SenderId, std::integral Shape, class FunId> struct bulk_sender { using Sender = stdexec::__t<SenderId>; using Fun = stdexec::__t<FunId>; using is_sender = void; static_thread_pool& pool_; Sender sndr_; Shape shape_; Fun fun_; template <class Fun, class Sender, class Env> using with_error_invoke_t = stdexec::__if_c< stdexec::__v<stdexec::__value_types_of_t< Sender, Env, stdexec::__mbind_front_q<bulk_non_throwing, Fun, Shape>, stdexec::__q<stdexec::__mand>>>, stdexec::completion_signatures<>, stdexec::__with_exception_ptr>; template <class... Tys> using set_value_t = stdexec::completion_signatures< stdexec::set_value_t(stdexec::__decay_t<Tys>...)>; template <class Self, class Env> using completion_signatures = stdexec::__try_make_completion_signatures< stdexec::__copy_cvref_t<Self, Sender>, Env, with_error_invoke_t<Fun, stdexec::__copy_cvref_t<Self, Sender>, Env>, stdexec::__q<set_value_t>>; template <class Self, class Receiver> using bulk_op_state_t = bulk_op_state< stdexec::__x<stdexec::__copy_cvref_t<Self, Sender>>, stdexec::__x<stdexec::__decay_t<Receiver>>, Shape, Fun>; template <stdexec::__decays_to<bulk_sender> Self, stdexec::receiver Receiver> requires stdexec:: receiver_of<Receiver, completion_signatures<Self, stdexec::env_of_t<Receiver>>> friend bulk_op_state_t<Self, Receiver> tag_invoke(stdexec::connect_t, Self&& self, Receiver&& rcvr) noexcept(stdexec::__nothrow_constructible_from< bulk_op_state_t<Self, Receiver>, static_thread_pool&, Shape, Fun, Sender, Receiver>) { return bulk_op_state_t<Self, Receiver>{ self.pool_, self.shape_, self.fun_, ((Self&&) self).sndr_, (Receiver&&) rcvr}; } template <stdexec::__decays_to<bulk_sender> Self, class Env> friend auto tag_invoke(stdexec::get_completion_signatures_t, Self&&, Env&&) -> stdexec::dependent_completion_signatures<Env>; template <stdexec::__decays_to<bulk_sender> Self, class Env> friend auto tag_invoke(stdexec::get_completion_signatures_t, Self&&, Env&&) -> completion_signatures<Self, Env> requires true; friend auto tag_invoke(stdexec::get_env_t, const bulk_sender& self) noexcept -> stdexec::env_of_t<const Sender&> { return stdexec::get_env(self.sndr_); } }; friend sender tag_invoke(stdexec::schedule_t, const scheduler& s) noexcept { return s.make_sender_(); } template <stdexec::sender Sender, std::integral Shape, class Fun> using bulk_sender_t = bulk_sender< stdexec::__x<stdexec::__decay_t<Sender>>, Shape, stdexec::__x<stdexec::__decay_t<Fun>>>; template <stdexec::sender S, std::integral Shape, class Fn> friend bulk_sender_t<S, Shape, Fn> tag_invoke(stdexec::bulk_t, const scheduler& sch, S&& sndr, Shape shape, Fn fun) noexcept { return bulk_sender_t<S, Shape, Fn>{*sch.pool_, (S&&) sndr, shape, (Fn&&) fun}; } friend stdexec::forward_progress_guarantee tag_invoke(stdexec::get_forward_progress_guarantee_t, const static_thread_pool&) noexcept { return stdexec::forward_progress_guarantee::parallel; } friend class static_thread_pool; explicit scheduler(static_thread_pool& pool) noexcept : pool_(&pool) { } static_thread_pool* pool_; }; scheduler get_scheduler() noexcept { return scheduler{*this}; } void request_stop() noexcept; std::uint32_t available_parallelism() const { return threadCount_; } private: class thread_state { public: task_base* try_pop(); task_base* pop(); bool try_push(task_base* task); void push(task_base* task); void request_stop(); private: std::mutex mut_; std::condition_variable cv_; __intrusive_queue<&task_base::next> queue_; bool stopRequested_ = false; }; void run(std::uint32_t index) noexcept; void join() noexcept; void enqueue(task_base* task) noexcept; template <std::derived_from<task_base> TaskT> void bulk_enqueue(TaskT* task, std::uint32_t n_threads) noexcept; std::uint32_t threadCount_; std::vector<std::thread> threads_; std::vector<thread_state> threadStates_; std::atomic<std::uint32_t> nextThread_; }; template <typename ReceiverId> class operation : task_base { using Receiver = stdexec::__t<ReceiverId>; friend static_thread_pool::scheduler::sender; static_thread_pool& pool_; Receiver receiver_; explicit operation(static_thread_pool& pool, Receiver&& r) : pool_(pool) , receiver_((Receiver&&) r) { this->__execute = [](task_base* t, const std::uint32_t ) noexcept { auto& op = *static_cast<operation*>(t); auto stoken = stdexec::get_stop_token(stdexec::get_env(op.receiver_)); if constexpr (std::unstoppable_token<decltype(stoken)>) { stdexec::set_value((Receiver&&) op.receiver_); } else if (stoken.stop_requested()) { stdexec::set_stopped((Receiver&&) op.receiver_); } else { stdexec::set_value((Receiver&&) op.receiver_); } }; } void enqueue_(task_base* op) const { pool_.enqueue(op); } friend void tag_invoke(stdexec::start_t, operation& op) noexcept { op.enqueue_(&op); } }; inline static_thread_pool::static_thread_pool() : static_thread_pool(std::thread::hardware_concurrency()) { } inline static_thread_pool::static_thread_pool(std::uint32_t threadCount) : threadCount_(threadCount) , threadStates_(threadCount) , nextThread_(0) { do { static_assert(noexcept(threadCount > 0)); assert(threadCount > 0); } while (false); threads_.reserve(threadCount); try { for (std::uint32_t i = 0; i < threadCount; ++i) { threads_.emplace_back([this, i] { run(i); }); } } catch (...) { request_stop(); join(); throw; } } inline static_thread_pool::~static_thread_pool() { request_stop(); join(); } inline void static_thread_pool::request_stop() noexcept { for (auto& state: threadStates_) { state.request_stop(); } } inline void static_thread_pool::run(const std::uint32_t threadIndex) noexcept { do { static_assert(noexcept(threadIndex < threadCount_)); assert(threadIndex < threadCount_); } while (false); while (true) { task_base* task = nullptr; std::uint32_t queueIndex = threadIndex; do { task = threadStates_[queueIndex].try_pop(); } while (!task && (++queueIndex %= threadCount_) != threadIndex); do { static_assert(noexcept(task || queueIndex == threadIndex)); assert(task || queueIndex == threadIndex); } while (false); if (!task && !(task = threadStates_[queueIndex].pop())) return; task->__execute(task, queueIndex); } } inline void static_thread_pool::join() noexcept { for (auto& t: threads_) { t.join(); } threads_.clear(); } inline void static_thread_pool::enqueue(task_base* task) noexcept { const std::uint32_t threadCount = static_cast<std::uint32_t>(threads_.size()); const std::uint32_t startIndex = nextThread_.fetch_add(1, std::memory_order_relaxed) % threadCount; for (std::uint32_t i = 0; i < threadCount; ++i) { const auto index = (startIndex + i) < threadCount ? (startIndex + i) : (startIndex + i - threadCount); if (threadStates_[index].try_push(task)) { return; } } threadStates_[startIndex].push(task); } template <std::derived_from<task_base> TaskT> inline void static_thread_pool::bulk_enqueue(TaskT* task, std::uint32_t n_threads) noexcept { for (std::size_t i = 0; i < n_threads; ++i) { threadStates_[i % available_parallelism()].push(task + i); } } inline task_base* static_thread_pool::thread_state::try_pop() { std::unique_lock lk{mut_, std::try_to_lock}; if (!lk || queue_.empty()) { return nullptr; } return queue_.pop_front(); } inline task_base* static_thread_pool::thread_state::pop() { std::unique_lock lk{mut_}; while (queue_.empty()) { if (stopRequested_) { return nullptr; } cv_.wait(lk); } return queue_.pop_front(); } inline bool static_thread_pool::thread_state::try_push(task_base* task) { std::unique_lock lk{mut_, std::try_to_lock}; if (!lk) { return false; } const bool wasEmpty = queue_.empty(); queue_.push_back(task); if (wasEmpty) { cv_.notify_one(); } return true; } inline void static_thread_pool::thread_state::push(task_base* task) { std::lock_guard lk{mut_}; const bool wasEmpty = queue_.empty(); queue_.push_back(task); if (wasEmpty) { cv_.notify_one(); } } inline void static_thread_pool::thread_state::request_stop() { std::lock_guard lk{mut_}; stopRequested_ = true; cv_.notify_one(); } } namespace stdexec { template <class _Ty> auto __unconst_(const _Ty&&) -> _Ty; template <class _Ty> auto __unconst_(const _Ty&) -> _Ty&; template <class _Ty> using __unconst_t = decltype(stdexec::__unconst_(__declval<_Ty>())); inline constexpr struct __apply_fn { template <class _ImplFn, class _ApplyFn> auto operator()(_ImplFn&& __impl, _ApplyFn&& __fun) const noexcept(noexcept(const_cast<__unconst_t<_ImplFn>&&>(__impl)( __copy_cvref_fn<_ImplFn>(), (_ApplyFn&&) __fun)))->decltype(const_cast<__unconst_t<_ImplFn>&&>(__impl)( __copy_cvref_fn<_ImplFn>(), (_ApplyFn&&) __fun)) { return const_cast<__unconst_t<_ImplFn>&&>(__impl)( __copy_cvref_fn<_ImplFn>(), (_ApplyFn&&) __fun); } } __apply{}; template <class _ImplFn> using __tag_from = decltype(__apply(__declval<_ImplFn>(), [](auto __tag, auto&&...) { return __tag; })); template <class _ImplFn> struct __basic_sender { using is_sender = void; using __tag_t = __tag_from<_ImplFn>; _ImplFn __impl_; explicit __basic_sender(_ImplFn __impl_) : __impl_((_ImplFn&&) __impl_) { } template <same_as<get_env_t> _Tag, same_as<__basic_sender> _Self> friend auto tag_invoke(_Tag, const _Self& __self) noexcept(noexcept(__tag_t().get_env(__self)))->decltype(__tag_t().get_env(__self)) { return __tag_t().get_env(__self); } template <same_as<get_completion_signatures_t> _Tag, __decays_to<__basic_sender> _Self, class _Env> friend auto tag_invoke(_Tag, _Self&& __self, _Env&& __env) -> decltype(__tag_t().get_completion_signatures((_Self&&) __self, (_Env&&) __env)); template <same_as<connect_t> _Tag, __decays_to<__basic_sender> _Self, receiver _Receiver> friend auto tag_invoke(_Tag, _Self&& __self, _Receiver&& __rcvr) noexcept(noexcept(__tag_t().connect((_Self&&) __self, (_Receiver&&) __rcvr)))->decltype(__tag_t().connect((_Self&&) __self, (_Receiver&&) __rcvr)) { return __tag_t().connect((_Self&&) __self, (_Receiver&&) __rcvr); } }; template <class _ImplFn> __basic_sender(_ImplFn) -> __basic_sender<_ImplFn>; template <class _Sender> using __tag_of = decltype(__apply(__declval<_Sender>().__impl_, [](auto __tag, auto&&...) { return __tag; })); template <class _Tag> inline constexpr auto __make_basic_sender = []<class _Data, class... _Children>(_Data __data, _Children... __children) { return __basic_sender{ [__data = (_Data&&) __data, ... __children = (_Children&&) __children] <class _Cvref, class _Fun>(_Cvref, _Fun && __fun) mutable noexcept(noexcept(static_cast<_Fun&&>(__fun)( _Tag(), const_cast<__minvoke<_Cvref, _Data>&&>(__data), const_cast<__minvoke<_Cvref, _Children>&&>(__children)...)))->decltype(static_cast<_Fun&&>(__fun)( _Tag(), const_cast<__minvoke<_Cvref, _Data>&&>(__data), const_cast<__minvoke<_Cvref, _Children>&&>(__children)...)) { return static_cast<_Fun&&>(__fun)( _Tag(), const_cast<__minvoke<_Cvref, _Data>&&>(__data), const_cast<__minvoke<_Cvref, _Children>&&>(__children)...); }}; }; template <class _Sender, class _Tag> concept __basic_sender_for = requires (_Sender& __sndr) { []<class _ImplFn>(const __basic_sender<_ImplFn>&) {}(__sndr); }; } inline constexpr struct then_t { template <class _Sender, class _Fun> auto operator()(_Sender&& __sender, _Fun __fun) const { return stdexec::__make_basic_sender<then_t>((_Fun&&) __fun, (_Sender&&) __sender); } template <class> friend struct stdexec::__basic_sender; template <stdexec::__basic_sender_for<then_t> _Sender> static auto get_env(const _Sender& __sndr) noexcept { return stdexec::__apply( __sndr.__impl_, [&](auto, auto&&, const auto& __child) { return stdexec::get_env(__child); } ); } template <stdexec::__basic_sender_for<then_t> _Sender, class _Env> static auto get_completion_signatures(_Sender&& __sndr, _Env&& __env) { return stdexec::__apply( ((_Sender&&) __sndr).__impl_, [&](auto, auto&& __fun, auto&& __child) { return stdexec::get_completion_signatures(stdexec::then(__child, __fun), __env); } ); } template <stdexec::__basic_sender_for<then_t> _Sender, stdexec::receiver _Receiver> static auto connect(_Sender&& __sndr, _Receiver __rcvr) { return stdexec::__apply( ((_Sender&&) __sndr).__impl_, [&](auto, auto&& __fun, auto&& __child) { return stdexec::connect(stdexec::then(__child, __fun), __rcvr); } ); } } then {}; int main() { auto s = ::then(stdexec::just(), [] { std::cout << "Hello world!\n"; }); stdexec::__apply(s.__impl_, [](then_t&& tag, auto fn, auto just) { fn(); }); using S = decltype(s); using T = stdexec::__tag_of<S>; T t = then_t(); (void) t; static_assert(stdexec::__basic_sender_for<S, then_t>); static_assert(stdexec::sender<S>); static_assert(stdexec::sender_in<S, stdexec::empty_env>); static_assert(stdexec::sender_of<S, stdexec::set_value_t()>); }
Become a Patron
Sponsor on GitHub
Donate via PayPal
Source on GitHub
Mailing list
Installed libraries
Wiki
Report an issue
How it works
Contact the author
CE on Mastodon
About the author
Statistics
Changelog
Version tree