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 // operation state tag type 28 struct operation_state_t { }; 29 30 ///////////////////////////////////////////////////////////////////////////// 31 // [execution.op_state] 32 namespace __start { 33 template <class _Op> 34 concept __has_start = requires(_Op &__op) { __op.start(); }; 35 36 struct start_t { 37 template <class _Op> 38 requires __has_start<_Op> STDEXEC_ATTRIBUTEstdexec::__start::start_t39 STDEXEC_ATTRIBUTE(always_inline) 40 void operator()(_Op &__op) const noexcept { 41 static_assert(noexcept(__op.start()), "start() members must be noexcept"); 42 static_assert(__same_as<decltype(__op.start()), void>, "start() members must return void"); 43 __op.start(); 44 } 45 46 template <class _Op> 47 requires(!__has_start<_Op>) && tag_invocable<start_t, _Op &> STDEXEC_ATTRIBUTEstdexec::__start::start_t48 STDEXEC_ATTRIBUTE(always_inline) 49 void operator()(_Op &__op) const noexcept { 50 static_assert(nothrow_tag_invocable<start_t, _Op &>); 51 (void) tag_invoke(start_t{}, __op); 52 } 53 }; 54 } // namespace __start 55 56 using __start::start_t; 57 inline constexpr start_t start{}; 58 59 ///////////////////////////////////////////////////////////////////////////// 60 // [execution.op_state] 61 template <class _Op> 62 concept operation_state = destructible<_Op> && std::is_object_v<_Op> 63 && requires(_Op &__op) { stdexec::start(__op); }; 64 } // namespace stdexec 65