1 /*
2  * Copyright (c) 2021-2024 NVIDIA Corporation
3  *
4  * Licensed under the Apache License Version 2.0 with LLVM Exceptions
5  * (the "License"); you may not use this file except in compliance with
6  * the License. You may obtain a copy of the License at
7  *
8  *   https://llvm.org/LICENSE.txt
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 #pragma once
17 
18 #include "__execution_fwd.hpp"
19 
20 // include these after __execution_fwd.hpp
21 #include "__awaitable.hpp"
22 #include "__completion_signatures.hpp"
23 #include "__concepts.hpp"
24 #include "__domain.hpp"
25 #include "__env.hpp"
26 #include "__receivers.hpp"
27 #include "__type_traits.hpp"
28 
29 namespace stdexec
30 {
31 /////////////////////////////////////////////////////////////////////////////
32 // [execution.senders]
33 struct sender_t
34 {
35     using sender_concept = sender_t;
36 };
37 
38 namespace __detail
39 {
40 template <class _Sender>
41 concept __enable_sender =                     //
42     derived_from<typename _Sender::sender_concept, sender_t> ||
43     requires { typename _Sender::is_sender; } // NOT TO SPEC back compat
44     || __awaitable<_Sender, __env::__promise<empty_env>>;
45 } // namespace __detail
46 
47 template <class _Sender>
48 inline constexpr bool enable_sender = __detail::__enable_sender<_Sender>;
49 
50 template <class _Sender>
51 concept sender =                                          //
52     enable_sender<__decay_t<_Sender>>                     //
53     && environment_provider<__cref_t<_Sender>>            //
54     && __detail::__consistent_completion_domains<_Sender> //
55     && move_constructible<__decay_t<_Sender>>             //
56     && constructible_from<__decay_t<_Sender>, _Sender>;
57 
58 template <class _Sender, class... _Env>
59 concept sender_in =
60     (sizeof...(_Env) <= 1) //
61     && sender<_Sender>     //
62     && requires(_Sender&& __sndr, _Env&&... __env) {
63            {
64                get_completion_signatures(static_cast<_Sender&&>(__sndr),
65                                          static_cast<_Env&&>(__env)...)
66            } -> __valid_completion_signatures;
67        };
68 } // namespace stdexec
69