xref: /openbmc/sdbusplus/include/sdbusplus/async/stdexec/__detail/__operation_states.hpp (revision 10d0b4b7d1498cfd5c3d37edea271a54d1984e41)
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