Skip to content

Commit 8552af3

Browse files
committed
added start and operation_state concept (#20)
1 parent 1de0f1d commit 8552af3

File tree

8 files changed

+235
-6
lines changed

8 files changed

+235
-6
lines changed

docs/TODO.json

+2-3
Original file line numberDiff line numberDiff line change
@@ -16,16 +16,15 @@
1616
"execution.receivers.set_value": { "code":true, "test":true, "doc":false },
1717
"execution.receivers.set_error": { "code":true, "test":true, "doc":false },
1818
"execution.receivers.set_stopped": { "code":true, "test":true, "doc":false },
19+
"execution.opstate.start": { "code":true, "test":true, "doc":false },
20+
"execution.opstate": { "code":true, "test":true, "doc":false },
1921
"execution.general": { "code":true, "test":true, "doc":false },
2022
"except": { "code":true, "test":true, "doc":true, "comment":"empty" },
2123
"except.special": { "code":true, "test":true, "doc":true, "comment":"empty" },
2224
"library": { "code":true, "test":true, "doc":true, "comment":"term definition only" },
2325
"support": { "code":true, "test":true, "doc":true, "comment":"empty" },
2426
"support.limits": { "code":true, "test":true, "doc":true, "comment":"empty" },
2527
"exec.get.env": { "code":true, "test":true, "doc":false },
26-
"exec.set.error": { "code":true, "test":true, "doc":false },
27-
"exec.set.stopped": { "code":true, "test":true, "doc":false },
28-
"exec.set.value": { "code":true, "test":true, "doc":false },
2928
"utilities": { "code":true, "test":true, "doc":true, "comment":"empty" },
3029
"function.objects": { "code":true, "test":true, "doc":true, "comment":"empty" },
3130
"functional.syn": { "code":true, "test":true, "doc":false },

docs/TODO.md

+3-3
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@
4343
| [[stopcallback.inplace.cons](https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2024/p2300r10.html#stopcallback.inplace.cons)] | ✅ | ✅ | 🔴 | |
4444
| [[execution](https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2024/p2300r10.html#execution)] | ✅ | ✅ | ✅ | empty |
4545
| [[execution.general](https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2024/p2300r10.html#execution.general)] | ✅ | ✅ | 🔴 | |
46-
| [[execution.queryable](https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2024/p2300r10.html#execution.queryable)] | 🔴 | 🔴 | 🔴 | |
46+
| [[execution.queryable](https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2024/p2300r10.html#execution.queryable)] | ✅ | ✅ | ✅ | empty |
4747
| [[execution.queryable.general](https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2024/p2300r10.html#execution.queryable.general)] | 🔴 | 🔴 | 🔴 | |
4848
| [[execution.queryable.concept](https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2024/p2300r10.html#execution.queryable.concept)] | 🔴 | 🔴 | 🔴 | |
4949
| [[execution-async.ops](https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2024/p2300r10.html#execution-async.ops)] | 🔴 | 🔴 | 🔴 | |
@@ -65,7 +65,7 @@
6565
| [[execution.receivers.set_error](https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2024/p2300r10.html#execution.receivers.set_error)] | ✅ | ✅ | 🔴 | |
6666
| [[execution.receivers.set_stopped](https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2024/p2300r10.html#execution.receivers.set_stopped)] | ✅ | ✅ | 🔴 | |
6767
| [[execution.opstate](https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2024/p2300r10.html#execution.opstate)] | 🔴 | 🔴 | 🔴 | |
68-
| [[execution.opstate.start](https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2024/p2300r10.html#execution.opstate.start)] | 🔴 | 🔴 | 🔴 | |
68+
| [[execution.opstate.start](https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2024/p2300r10.html#execution.opstate.start)] | ✅ | ✅ | 🔴 | |
6969
| [[execution.senders](https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2024/p2300r10.html#execution.senders)] | ✅ | ✅ | ✅ | empty |
7070
| [[execution.senders.general](https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2024/p2300r10.html#execution.senders.general)] | 🔴 | 🔴 | 🔴 | |
7171
| [[execution.snd.concepts](https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2024/p2300r10.html#execution.snd.concepts)] | 🔴 | 🔴 | 🔴 | |
@@ -108,5 +108,5 @@
108108
| [[execution.coro_utils](https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2024/p2300r10.html#execution.coro_utils)] | ✅ | ✅ | ✅ | empty |
109109
| [[execution.coro_utils.as_awaitable](https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2024/p2300r10.html#execution.coro_utils.as_awaitable)] | 🔴 | 🔴 | 🔴 | |
110110
| [[execution.coro_utils.with_awaitable_senders](https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2024/p2300r10.html#execution.coro_utils.with_awaitable_senders)] | 🔴 | 🔴 | 🔴 | |
111-
| [[allocator.requirements.general](https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2024/p2300r10.html#allocator.requirements.general)] | 🔴 | 🔴 | 🔴 | |
111+
| [[allocator.requirements.general](https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2024/p2300r10.html#allocator.requirements.general)] | ✅ | ✅ | 🔴 | |
112112
| [[exec.awaitables](https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2024/p2300r10.html#exec.awaitables)] | 🔴 | 🔴 | 🔴 | |
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
// include/Beman/Execution26/detail/operation_state.hpp -*-C++-*-
2+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
3+
4+
#ifndef INCLUDED_BEMAN_EXECUTION26_DETAIL_OPERATION_STATE
5+
#define INCLUDED_BEMAN_EXECUTION26_DETAIL_OPERATION_STATE
6+
7+
#include <concepts>
8+
#include <type_traits>
9+
10+
// ----------------------------------------------------------------------------
11+
12+
namespace Beman::Execution26
13+
{
14+
struct operation_state_t {};
15+
16+
template <typename State>
17+
concept operation_state
18+
= ::std::derived_from<typename State::operation_state_concept,
19+
::Beman::Execution26::operation_state_t>
20+
&& ::std::is_object_v<State>
21+
&& requires(State& state) { { state.start() } noexcept; }
22+
;
23+
}
24+
25+
// ----------------------------------------------------------------------------
26+
27+
#endif
+53
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
// include/Beman/Execution26/detail/start.hpp -*-C++-*-
2+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
3+
4+
#ifndef INCLUDED_BEMAN_EXECUTION26_DETAIL_START
5+
#define INCLUDED_BEMAN_EXECUTION26_DETAIL_START
6+
7+
#include <Beman/Execution26/detail/common.hpp>
8+
9+
// ----------------------------------------------------------------------------
10+
11+
namespace Beman::Execution26
12+
{
13+
struct start_t
14+
{
15+
template <typename State>
16+
auto operator()(State&&) const -> void
17+
= BEMAN_EXECUTION26_DELETE("start(obj) requires an lvalue argument");
18+
template <typename State>
19+
requires (not requires(State& state){ state.start(); })
20+
auto operator()(State&) const -> void
21+
= BEMAN_EXECUTION26_DELETE("state needs to have a start() member");
22+
template <typename State>
23+
requires (not requires(State const& state){ state.start(); })
24+
auto operator()(State const&) const -> void
25+
= BEMAN_EXECUTION26_DELETE("state needs to have a start() member");
26+
27+
template <typename State>
28+
requires (not requires(State& state){ { state.start() } noexcept; })
29+
auto operator()(State&) const -> void
30+
= BEMAN_EXECUTION26_DELETE("state start() member has to be noexcept");
31+
template <typename State>
32+
requires (not requires(State const& state){ { state.start()} noexcept; })
33+
auto operator()(State const&) const -> void
34+
= BEMAN_EXECUTION26_DELETE("state start() member has to be noexcept");
35+
36+
template <typename State>
37+
auto operator()(State const& state) const noexcept -> void
38+
{
39+
state.start();
40+
}
41+
template <typename State>
42+
auto operator()(State& state) const noexcept -> void
43+
{
44+
state.start();
45+
}
46+
};
47+
48+
inline constexpr start_t start{};
49+
}
50+
51+
// ----------------------------------------------------------------------------
52+
53+
#endif

include/Beman/Execution26/execution.hpp

+1
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
#include <Beman/Execution26/detail/set_value.hpp>
2222
#include <Beman/Execution26/detail/set_error.hpp>
2323
#include <Beman/Execution26/detail/set_stopped.hpp>
24+
#include <Beman/Execution26/detail/start.hpp>
2425

2526
// ----------------------------------------------------------------------------
2627

src/Beman/Execution26/tests/CMakeLists.txt

+2
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
33

44
list(APPEND execution_tests
5+
exec-opstate.pass
6+
exec-opstate-start.pass
57
allocator-requirements-general.pass
68
exec-general.pass
79
exec-utils-cmplsigs.pass
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
// src/Beman/Execution26/tests/exec-opstate-start.pass.cpp -*-C++-*-
2+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
3+
4+
#include <Beman/Execution26/execution.hpp>
5+
#include <test/execution.hpp>
6+
7+
#include <utility>
8+
9+
// ----------------------------------------------------------------------------
10+
11+
namespace
12+
{
13+
struct receiver
14+
{
15+
int value{};
16+
auto set_value(int value) noexcept -> void { this->value = value; }
17+
};
18+
19+
struct non_opstate
20+
{
21+
};
22+
23+
template <bool Noexcept>
24+
struct opstate
25+
{
26+
receiver* rcvr;
27+
auto start() const noexcept(Noexcept) -> void
28+
{
29+
test_std::set_value(std::move(*rcvr), 42);
30+
}
31+
};
32+
33+
template <typename State>
34+
auto test_start_argument_type()
35+
{
36+
receiver rcvr{};
37+
State state{&rcvr};
38+
receiver crcvr{};
39+
State const cstate{&crcvr};
40+
41+
static_assert(requires{ test_std::start(state); });
42+
static_assert(requires{ test_std::start(cstate); });
43+
44+
static_assert(not requires{ test_std::start(State(&rcvr)); });
45+
static_assert(not requires{ test_std::start(std::move(state)); });
46+
static_assert(not requires{ test_std::start(std::move(cstate)); });
47+
}
48+
49+
template <typename State>
50+
auto test_start_member()
51+
{
52+
State state;
53+
static_assert(not requires{ test_std::start(state); });
54+
State cstate;
55+
static_assert(not requires{ test_std::start(cstate); });
56+
}
57+
58+
template <typename State>
59+
auto test_start_noexcept()
60+
{
61+
State state;
62+
static_assert(not requires{ test_std::start(state); });
63+
State cstate;
64+
static_assert(not requires{ test_std::start(cstate); });
65+
}
66+
67+
template <typename State>
68+
auto test_start_call()
69+
{
70+
receiver rcvr{};
71+
State state{&rcvr};
72+
receiver crcvr{};
73+
State const cstate{&crcvr};
74+
75+
assert(rcvr.value == 0);
76+
test_std::start(state);
77+
assert(rcvr.value == 42);
78+
79+
assert(crcvr.value == 0);
80+
test_std::start(cstate);
81+
assert(crcvr.value == 42);
82+
}
83+
}
84+
85+
auto main() -> int
86+
{
87+
static_assert(std::same_as<test_std::start_t const, decltype(test_std::start)>);
88+
89+
test_start_argument_type<opstate<true>>();
90+
test_start_member<non_opstate>();
91+
test_start_noexcept<opstate<false>>();
92+
test_start_call<opstate<true>>();
93+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
// src/Beman/Execution26/tests/exec-opstate.pass.cpp -*-C++-*-
2+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
3+
4+
#include <Beman/Execution26/detail/operation_state.hpp>
5+
#include <test/execution.hpp>
6+
7+
// ----------------------------------------------------------------------------
8+
9+
namespace
10+
{
11+
struct base {};
12+
struct opstate_base: test_std::operation_state_t {};
13+
14+
struct non_operation_state {};
15+
struct no_tag
16+
{
17+
using operation_state_concept = test_std::operation_state_t;
18+
auto start() noexcept {}
19+
};
20+
struct no_start
21+
{
22+
using operation_state_concept = test_std::operation_state_t;
23+
auto start() noexcept {}
24+
};
25+
26+
template <bool Noexcept, typename Tag>
27+
struct operation_state
28+
{
29+
using operation_state_concept = Tag;
30+
auto start() noexcept(Noexcept) {}
31+
};
32+
33+
template <bool Expect, typename State>
34+
auto test_operation_state()
35+
{
36+
static_assert(Expect == test_std::operation_state<State>);
37+
}
38+
}
39+
40+
auto main() -> int
41+
{
42+
test_std::operation_state_t state_tag{};
43+
(void)state_tag;
44+
45+
test_operation_state<false, non_operation_state>();
46+
test_operation_state<true, no_tag>();
47+
test_operation_state<true, no_start>();
48+
49+
test_operation_state<true, operation_state<true, test_std::operation_state_t>>();
50+
test_operation_state<false, operation_state<false, test_std::operation_state_t>>();
51+
test_operation_state<false, operation_state<true, base>>();
52+
test_operation_state<true, operation_state<true, opstate_base>>();
53+
test_operation_state<false, operation_state<true, test_std::operation_state_t>&>();
54+
}

0 commit comments

Comments
 (0)