Skip to content

Commit 87bd8ec

Browse files
committed
added state_base
1 parent 38efec7 commit 87bd8ec

File tree

5 files changed

+177
-5
lines changed

5 files changed

+177
-5
lines changed
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
// include/beman/execution/detail/as_tuple.hpp -*-C++-*-
2+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
3+
4+
#ifndef INCLUDED_INCLUDE_BEMAN_EXECUTION_DETAIL_AS_TUPLE
5+
#define INCLUDED_INCLUDE_BEMAN_EXECUTION_DETAIL_AS_TUPLE
6+
7+
#include <beman/execution/detail/decayed_tuple.hpp>
8+
9+
// ----------------------------------------------------------------------------
10+
11+
namespace beman::execution::detail {
12+
template <typename T> struct as_tuple;
13+
template <typename Rc, typename... A>
14+
struct as_tuple<Rc(A...)> { using type = ::beman::execution::detail::decayed_tuple<Rc, A...>; };
15+
16+
template <typename T> using as_tuple_t = typename ::beman::execution::detail::as_tuple<T>::type;
17+
}
18+
19+
// ----------------------------------------------------------------------------
20+
21+
#endif

include/beman/execution/detail/spawn_future.hpp

Lines changed: 51 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,62 @@
11
// include/beman/execution/detail/spawn_future.hpp -*-C++-*-
2-
// ----------------------------------------------------------------------------
32
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
4-
// ----------------------------------------------------------------------------
53

64
#ifndef INCLUDED_INCLUDE_BEMAN_EXECUTION_DETAIL_SPAWN_FUTURE
75
#define INCLUDED_INCLUDE_BEMAN_EXECUTION_DETAIL_SPAWN_FUTURE
86

7+
#include <beman/execution/detail/sender.hpp>
8+
#include <beman/execution/detail/async_scope_token.hpp>
9+
#include <beman/execution/detail/empty_env.hpp>
10+
#include <beman/execution/detail/queryable.hpp>
11+
#include <beman/execution/detail/as_tuple.hpp>
12+
#include <beman/execution/detail/meta_unique.hpp>
13+
#include <utility>
14+
#include <variant>
15+
#include <type_traits>
16+
#include <tuple>
17+
#include <exception>
18+
919
// ----------------------------------------------------------------------------
1020

11-
namespace nstd {
12-
namespace xxx {
13-
}
21+
namespace beman::execution::detail {
22+
template <typename> struct non_throwing_args_copy;
23+
template <typename Rc, typename... A> struct non_throwing_args_copy<Rc(A...)> {
24+
static constexpr bool value = (true && ... && ::std::is_nothrow_constructible_v<::std::decay_t<A>, A> );
25+
};
26+
template <typename S> inline constexpr bool non_throwing_args_copy_v{non_throwing_args_copy<S>::value};
27+
28+
template <typename Completions> struct spawn_future_state_base;
29+
template <typename... Sigs>
30+
struct spawn_future_state_base<::beman::execution::completion_signatures<Sigs...>> {
31+
using variant_t = ::beman::execution::detail::meta::unique<
32+
::std::conditional_t<
33+
(true && ... && non_throwing_args_copy_v<Sigs>),
34+
::std::variant<::std::monostate, ::beman::execution::detail::as_tuple_t<Sigs>...>,
35+
::std::variant<::std::monostate, ::std::tuple<::beman::execution::set_error_t, ::std::exception_ptr>, ::beman::execution::detail::as_tuple_t<Sigs>...>
36+
>
37+
>;
38+
39+
variant_t result{};
40+
virtual ~spawn_future_state_base() = default;
41+
virtual auto complete() noexcept -> void = 0;
42+
};
43+
44+
class spawn_future_t {
45+
public:
46+
template <::beman::execution::sender Sndr, ::beman::execution::async_scope_token Tok, typename Env>
47+
requires ::beman::execution::detail::queryable<::std::remove_cvref_t<Env>>
48+
auto operator()(Sndr&&, Tok&&, Env&&) const {
49+
}
50+
template <::beman::execution::sender Sndr, ::beman::execution::async_scope_token Tok>
51+
auto operator()(Sndr&& sndr, Tok&& tok) const {
52+
return (*this)(::std::forward<Sndr>(sndr), ::std::forward<Tok>(tok), ::beman::execution::empty_env{});
53+
}
54+
};
55+
}
56+
57+
namespace beman::execution {
58+
using spawn_future_t = ::beman::execution::detail::spawn_future_t;
59+
inline constexpr spawn_future_t spawn_future{};
1460
}
1561

1662
// ----------------------------------------------------------------------------

src/beman/execution/CMakeLists.txt

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@ target_sources(
2727
${PROJECT_SOURCE_DIR}/include/beman/execution/execution.hpp
2828
${PROJECT_SOURCE_DIR}/include/beman/execution/functional.hpp
2929
${PROJECT_SOURCE_DIR}/include/beman/execution/stop_token.hpp
30+
${PROJECT_SOURCE_DIR}/include/beman/execution26/execution.hpp
31+
${PROJECT_SOURCE_DIR}/include/beman/execution26/stop_token.hpp
3032
PUBLIC FILE_SET
3133
${TARGET_NAME}_detail_headers
3234
TYPE
@@ -39,6 +41,8 @@ target_sources(
3941
${PROJECT_SOURCE_DIR}/include/beman/execution/detail/apply_sender.hpp
4042
${PROJECT_SOURCE_DIR}/include/beman/execution/detail/as_awaitable.hpp
4143
${PROJECT_SOURCE_DIR}/include/beman/execution/detail/as_except_ptr.hpp
44+
${PROJECT_SOURCE_DIR}/include/beman/execution/detail/as_tuple.hpp
45+
${PROJECT_SOURCE_DIR}/include/beman/execution/detail/async_scope_token.hpp
4246
${PROJECT_SOURCE_DIR}/include/beman/execution/detail/atomic_intrusive_stack.hpp
4347
${PROJECT_SOURCE_DIR}/include/beman/execution/detail/await_result_type.hpp
4448
${PROJECT_SOURCE_DIR}/include/beman/execution/detail/await_suspend_result.hpp
@@ -47,6 +51,7 @@ target_sources(
4751
${PROJECT_SOURCE_DIR}/include/beman/execution/detail/basic_receiver.hpp
4852
${PROJECT_SOURCE_DIR}/include/beman/execution/detail/basic_sender.hpp
4953
${PROJECT_SOURCE_DIR}/include/beman/execution/detail/basic_state.hpp
54+
${PROJECT_SOURCE_DIR}/include/beman/execution/detail/bulk.hpp
5055
${PROJECT_SOURCE_DIR}/include/beman/execution/detail/call_result_t.hpp
5156
${PROJECT_SOURCE_DIR}/include/beman/execution/detail/callable.hpp
5257
${PROJECT_SOURCE_DIR}/include/beman/execution/detail/check_type_alias_exist.hpp
@@ -65,6 +70,7 @@ target_sources(
6570
${PROJECT_SOURCE_DIR}/include/beman/execution/detail/connect_awaitable.hpp
6671
${PROJECT_SOURCE_DIR}/include/beman/execution/detail/connect_result_t.hpp
6772
${PROJECT_SOURCE_DIR}/include/beman/execution/detail/continues_on.hpp
73+
${PROJECT_SOURCE_DIR}/include/beman/execution/detail/counting_scope.hpp
6874
${PROJECT_SOURCE_DIR}/include/beman/execution/detail/decayed_same_as.hpp
6975
${PROJECT_SOURCE_DIR}/include/beman/execution/detail/decayed_tuple.hpp
7076
${PROJECT_SOURCE_DIR}/include/beman/execution/detail/decayed_type_list.hpp
@@ -119,6 +125,7 @@ target_sources(
119125
${PROJECT_SOURCE_DIR}/include/beman/execution/detail/meta_transform.hpp
120126
${PROJECT_SOURCE_DIR}/include/beman/execution/detail/meta_unique.hpp
121127
${PROJECT_SOURCE_DIR}/include/beman/execution/detail/movable_value.hpp
128+
${PROJECT_SOURCE_DIR}/include/beman/execution/detail/nest.hpp
122129
${PROJECT_SOURCE_DIR}/include/beman/execution/detail/never_stop_token.hpp
123130
${PROJECT_SOURCE_DIR}/include/beman/execution/detail/nostopstate.hpp
124131
${PROJECT_SOURCE_DIR}/include/beman/execution/detail/nothrow_callable.hpp
@@ -156,6 +163,8 @@ target_sources(
156163
${PROJECT_SOURCE_DIR}/include/beman/execution/detail/simple_counting_scope.hpp
157164
${PROJECT_SOURCE_DIR}/include/beman/execution/detail/single_sender.hpp
158165
${PROJECT_SOURCE_DIR}/include/beman/execution/detail/single_sender_value_type.hpp
166+
${PROJECT_SOURCE_DIR}/include/beman/execution/detail/spawn.hpp
167+
${PROJECT_SOURCE_DIR}/include/beman/execution/detail/spawn_future.hpp
159168
${PROJECT_SOURCE_DIR}/include/beman/execution/detail/split.hpp
160169
${PROJECT_SOURCE_DIR}/include/beman/execution/detail/start.hpp
161170
${PROJECT_SOURCE_DIR}/include/beman/execution/detail/starts_on.hpp

tests/beman/execution/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ list(
1212
APPEND
1313
execution_tests
1414
exec-scope-simple-counting.test
15+
exec-spawn-future.test
1516
exec-scope-concepts.test
1617
exec-nest.test
1718
issue-144.test
Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
// tests/beman/execution/exec-spawn-future.test.cpp -*-C++-*-
2+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
3+
4+
#include <beman/execution/detail/spawn_future.hpp>
5+
#include <beman/execution/detail/queryable.hpp>
6+
#include <beman/execution/detail/sender.hpp>
7+
#include <beman/execution/detail/async_scope_token.hpp>
8+
#include <test/execution.hpp>
9+
#include <concepts>
10+
11+
// ----------------------------------------------------------------------------
12+
13+
namespace
14+
{
15+
struct non_env { ~non_env() = delete; };
16+
static_assert(not test_detail::queryable<non_env>);
17+
18+
struct env {};
19+
static_assert(test_detail::queryable<env>);
20+
21+
struct non_sender {
22+
};
23+
static_assert(not test_std::sender<non_sender>);
24+
25+
struct sender {
26+
using sender_concept = test_std::sender_t;
27+
};
28+
static_assert(test_std::sender<sender>);
29+
30+
template <bool Noexcept>
31+
struct token {
32+
auto try_associate() -> bool { return {}; }
33+
auto disassociate() noexcept(Noexcept) -> void {}
34+
template <test_std::sender Sender>
35+
auto wrap(Sender&& sender) -> Sender { return std::forward<Sender>(sender); }
36+
};
37+
static_assert(test_std::async_scope_token<token<true>>);
38+
static_assert(not test_std::async_scope_token<token<false>>);
39+
40+
struct throws {
41+
throws() = default;
42+
throws(throws&&) noexcept(false) = default;
43+
};
44+
static_assert(!std::is_nothrow_constructible_v<std::decay_t<throws>, throws>);
45+
46+
template <bool Expect, typename Sender, typename Token, typename Env = ::env>
47+
auto test_spawn_future_interface(Sender&& sndr, Token&& tok, Env&& e = Env{}) -> void {
48+
if constexpr (!std::same_as<std::remove_cvref_t<Env>, non_env>){
49+
static_assert(Expect == requires{ test_std::spawn_future(std::forward<Sender>(sndr), std::forward<Token>(tok)); });
50+
}
51+
static_assert(Expect == requires{ test_std::spawn_future(std::forward<Sender>(sndr), std::forward<Token>(tok), std::forward<Env>(e)); });
52+
}
53+
54+
template <typename Completions>
55+
struct state_base: test_detail::spawn_future_state_base<Completions> {
56+
auto complete() noexcept -> void override {}
57+
};
58+
auto test_state_base() {
59+
static_assert(noexcept(std::declval<test_detail::spawn_future_state_base<test_std::completion_signatures<>>&>().complete()));
60+
using state0_t = state_base<test_std::completion_signatures<>>;
61+
[[maybe_unused]] state0_t b0;
62+
static_assert(std::same_as<std::variant<std::monostate>, state0_t::variant_t>);
63+
static_assert(std::same_as<state0_t::variant_t, decltype(b0.result)>);
64+
65+
using state1_t = state_base<test_std::completion_signatures<test_std::set_value_t(int)>>;
66+
[[maybe_unused]] state1_t b1;
67+
static_assert(std::same_as<std::variant<std::monostate, std::tuple<test_std::set_value_t, int>>, state1_t::variant_t>);
68+
static_assert(std::same_as<state1_t::variant_t, decltype(b1.result)>);
69+
70+
using state2_t = state_base<test_std::completion_signatures<test_std::set_value_t(throws)>>;
71+
[[maybe_unused]] state2_t b2;
72+
static_assert(std::same_as<std::variant<std::monostate, std::tuple<test_std::set_error_t, std::exception_ptr>, std::tuple<test_std::set_value_t, throws>>, typename state2_t::variant_t>);
73+
static_assert(std::same_as<state2_t::variant_t, decltype(b2.result)>);
74+
75+
using state3_t = state_base<test_std::completion_signatures<test_std::set_value_t(throws), test_std::set_error_t(std::exception_ptr)>>;
76+
[[maybe_unused]] state3_t b3;
77+
static_assert(std::same_as<std::variant<std::monostate, std::tuple<test_std::set_error_t, std::exception_ptr>, std::tuple<test_std::set_value_t, throws>>, typename state3_t::variant_t>);
78+
static_assert(std::same_as<state3_t::variant_t, decltype(b3.result)>);
79+
80+
using state4_t = state_base<test_std::completion_signatures<test_std::set_value_t(throws), test_std::set_value_t(throws const&)>>;
81+
[[maybe_unused]] state4_t b4;
82+
static_assert(std::same_as<std::variant<std::monostate, std::tuple<test_std::set_error_t, std::exception_ptr>, std::tuple<test_std::set_value_t, throws>>, typename state4_t::variant_t>);
83+
static_assert(std::same_as<state4_t::variant_t, decltype(b4.result)>);
84+
}
85+
}
86+
87+
TEST(exec_spawn_future) {
88+
static_assert(std::same_as<test_std::spawn_future_t const, decltype(test_std::spawn_future)>);
89+
test_spawn_future_interface<true>(sender{}, token<true>{});
90+
test_spawn_future_interface<false>(non_sender{}, token<true>{});
91+
test_spawn_future_interface<false>(sender{}, token<false>{});
92+
test_spawn_future_interface<false>(sender{}, token<true>{}, *new non_env{});
93+
94+
test_state_base();
95+
}

0 commit comments

Comments
 (0)