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 "__concepts.hpp" 22 #include "__tag_invoke.hpp" 23 24 #include <type_traits> 25 26 namespace stdexec 27 { 28 // operation state tag type 29 struct operation_state_t 30 {}; 31 32 ///////////////////////////////////////////////////////////////////////////// 33 // [execution.op_state] 34 namespace __start 35 { 36 struct start_t 37 { 38 template <__same_as<start_t> _Self, class _OpState> 39 STDEXEC_ATTRIBUTE((always_inline)) tag_invoke(_Self,_OpState & __op)40 friend auto tag_invoke(_Self, 41 _OpState& __op) noexcept -> decltype(__op.start()) 42 { 43 static_assert(noexcept(__op.start()), 44 "start() members must be noexcept"); 45 static_assert(__same_as<decltype(__op.start()), void>, 46 "start() members must return void"); 47 __op.start(); 48 } 49 50 template <class _Op> 51 requires tag_invocable<start_t, _Op&> 52 STDEXEC_ATTRIBUTE((always_inline)) operator ()stdexec::__start::start_t53 void operator()(_Op& __op) const noexcept 54 { 55 static_assert(nothrow_tag_invocable<start_t, _Op&>); 56 (void)tag_invoke(start_t{}, __op); 57 } 58 }; 59 } // namespace __start 60 61 using __start::start_t; 62 inline constexpr start_t start{}; 63 64 ///////////////////////////////////////////////////////////////////////////// 65 // [execution.op_state] 66 template <class _Op> 67 concept operation_state = // 68 destructible<_Op> && // 69 std::is_object_v<_Op> && // 70 requires(_Op& __op) { // 71 stdexec::start(__op); 72 }; 73 } // namespace stdexec 74