Skip to content

Commit 1a55414

Browse files
committed
added missing associate implementation (tests are still missing)
1 parent 65779de commit 1a55414

File tree

7 files changed

+335
-49
lines changed

7 files changed

+335
-49
lines changed

CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ option(
4040
include(GNUInstallDirs)
4141
set(INSTALL_CONFIGDIR ${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME})
4242

43+
if(FALSE)
4344
if(PROJECT_IS_TOP_LEVEL AND NOT BEMAN_EXECUTION_ENABLE_INSTALL OR CMAKE_SKIP_INSTALL_RULES)
4445
set(CMAKE_SKIP_INSTALL_RULES ON)
4546

@@ -90,6 +91,7 @@ if(PROJECT_IS_TOP_LEVEL AND NOT BEMAN_EXECUTION_ENABLE_INSTALL OR CMAKE_SKIP_INS
9091
# LINKER "lld"
9192
)
9293
endif()
94+
endif()
9395

9496
add_subdirectory(src/beman/execution)
9597

Lines changed: 178 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,178 @@
1+
// include/beman/execution/detail/associate.hpp -*-C++-*-
2+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
3+
4+
#ifndef INCLUDED_INCLUDE_BEMAN_EXECUTION_DETAIL_ASSOCIATE
5+
#define INCLUDED_INCLUDE_BEMAN_EXECUTION_DETAIL_ASSOCIATE
6+
7+
#include <beman/execution/detail/scope_token.hpp>
8+
#include <beman/execution/detail/sender.hpp>
9+
#include <beman/execution/detail/connect.hpp>
10+
#include <beman/execution/detail/transform_sender.hpp>
11+
#include <beman/execution/detail/get_domain_early.hpp>
12+
#include <beman/execution/detail/make_sender.hpp>
13+
#include <beman/execution/detail/default_impls.hpp>
14+
#include <beman/execution/detail/impls_for.hpp>
15+
#include <type_traits>
16+
#include <optional>
17+
#include <utility>
18+
#include <iostream> //-dk:TODO remove
19+
20+
// ----------------------------------------------------------------------------
21+
22+
namespace beman::execution::detail {
23+
template <::beman::execution::scope_token Token, ::beman::execution::sender Sender>
24+
struct associate_data {
25+
using wrap_sender = ::std::remove_cvref_t<decltype(::std::declval<Token&>().wrap(::std::declval<Sender>()))>;
26+
27+
explicit associate_data(Token t, Sender&& s)
28+
: token(t)
29+
, sender(this->token.wrap(::std::forward<Sender>(s)))
30+
{
31+
if (!token.try_associate()) {
32+
this->sender.reset();
33+
}
34+
}
35+
associate_data(associate_data const& other)
36+
noexcept(::std::is_nothrow_copy_constructible_v<wrap_sender> && noexcept(token.try_associate()))
37+
: token(other.token)
38+
, sender()
39+
{
40+
if (other.sender && this->token.try_associate()) {
41+
try { this->sender.emplace(*other.sender); }
42+
catch (...) { this->token.disassociate(); }
43+
}
44+
}
45+
associate_data(associate_data&& other) noexcept(::std::is_nothrow_move_constructible_v<wrap_sender>)
46+
: token(other.token)
47+
, sender(::std::move(other.sender))
48+
{
49+
other.sender.reset();
50+
}
51+
auto operator= (associate_data const&) -> associate_data& = delete;
52+
auto operator= (associate_data &&) -> associate_data& = delete;
53+
~associate_data() {
54+
if (this->sender) {
55+
this->sender.reset();
56+
this->token.disassociate();
57+
}
58+
}
59+
60+
auto release() -> ::std::optional<::std::pair<Token, wrap_sender>> {
61+
return this->sender
62+
? ( std::unique_ptr<std::optional<wrap_sender>, decltype([](auto* opt){ opt->reset(); })>(&this->sender),
63+
::std::optional{::std::pair{::std::move(this->token), ::std::move(*this->sender)}}
64+
)
65+
: ::std::optional<::std::pair<Token, wrap_sender>>{}
66+
;
67+
}
68+
69+
Token token;
70+
::std::optional<wrap_sender> sender;
71+
};
72+
template <::beman::execution::scope_token Token, ::beman::execution::sender Sender>
73+
associate_data(Token, Sender&&) -> associate_data<Token, Sender>;
74+
75+
struct associate_t {
76+
template <::beman::execution::sender Sender, ::beman::execution::scope_token Token>
77+
auto operator()(Sender&& sender, Token&& token) const {
78+
auto domain(::beman::execution::detail::get_domain_early(sender));
79+
return ::beman::execution::transform_sender(
80+
domain,
81+
::beman::execution::detail::make_sender(
82+
*this,
83+
::beman::execution::detail::associate_data(::std::forward<Token>(token), ::std::forward<Sender>(sender))
84+
)
85+
);
86+
}
87+
};
88+
89+
template <>
90+
struct impls_for<associate_t>
91+
: ::beman::execution::detail::default_impls {
92+
template <typename, typename>
93+
struct get_noexcept: ::std::false_type {};
94+
template <typename Tag, typename Data, typename Receiver>
95+
struct get_noexcept<::beman::execution::detail::basic_sender<Tag, Data>, Receiver>
96+
: ::std::bool_constant<
97+
::std::is_nothrow_move_constructible_v<typename ::std::remove_cvref_t<Data>::wrap_sender>
98+
&& ::beman::execution::detail::nothrow_callable<
99+
::beman::execution::connect_t, typename ::std::remove_cvref_t<Data>::wrap_sender, Receiver>
100+
> {};
101+
102+
static constexpr auto get_state = []<typename Sender, typename Receiver>(Sender&& sender, Receiver& receiver)
103+
noexcept(
104+
::std::is_nothrow_constructible_v<::std::remove_cvref_t<Sender>, Sender>
105+
&& get_noexcept<::std::remove_cvref_t<Sender>, Receiver>::value
106+
)
107+
{
108+
auto[_, data] = ::std::forward<Sender>(sender);
109+
auto dataParts{data.release()};
110+
111+
using scope_token = decltype(dataParts->first);
112+
using wrap_sender = decltype(dataParts->second);
113+
using op_t = decltype(::beman::execution::connect(::std::move(dataParts->second), ::std::forward<Receiver>(receiver)));
114+
115+
struct op_state {
116+
bool associated{false};
117+
union {
118+
Receiver* rcvr;
119+
struct {
120+
scope_token tok;
121+
op_t op;
122+
} assoc;
123+
};
124+
explicit op_state(Receiver& r) noexcept: rcvr(::std::addressof(r)) {}
125+
explicit op_state(scope_token tk, wrap_sender&& sndr, Receiver& r)
126+
try
127+
: associated(true)
128+
, assoc(tk, ::beman::execution::connect(::std::move(sndr), ::std::move(r))) {
129+
}
130+
catch (...) {
131+
tk.disassociate();
132+
throw;
133+
}
134+
op_state(op_state&&) = delete;
135+
~op_state() {
136+
if (this->associated) {
137+
this->assoc.op.~op_t();
138+
this->assoc.tok.disassociate();
139+
this->assoc.tok.~scope_token();
140+
}
141+
}
142+
auto run() noexcept -> void {
143+
if (this->associated) {
144+
::beman::execution::start(this->assoc.op);
145+
}
146+
else {
147+
::beman::execution::set_stopped(::std::move(*this->rcvr));
148+
}
149+
}
150+
};
151+
return dataParts
152+
? op_state(::std::move(dataParts->first), ::std::move(dataParts->second), receiver)
153+
: op_state(receiver)
154+
;
155+
};
156+
static constexpr auto start = [](auto& state, auto&&) noexcept -> void{
157+
state.run();
158+
};
159+
};
160+
161+
template <typename Data, typename Env>
162+
struct completion_signatures_for_impl<
163+
::beman::execution::detail::basic_sender<::beman::execution::detail::associate_t, Data>,
164+
Env> {
165+
using type = ::beman::execution::completion_signatures<
166+
::beman::execution::set_value_t()
167+
>;
168+
};
169+
}
170+
171+
namespace beman::execution {
172+
using associate_t = ::beman::execution::detail::associate_t;
173+
inline constexpr associate_t associate{};
174+
} // namespace beman::execution
175+
176+
// ----------------------------------------------------------------------------
177+
178+
#endif

include/beman/execution/detail/nest.hpp

Lines changed: 0 additions & 22 deletions
This file was deleted.

src/beman/execution/CMakeLists.txt

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,12 @@
66
add_library(${TARGET_NAME} STATIC)
77
add_library(${TARGET_ALIAS} ALIAS ${TARGET_NAME})
88

9+
if(FALSE)
910
if(NOT BEMAN_EXECUTION_ENABLE_INSTALL OR CMAKE_SKIP_INSTALL_RULES)
1011
target_link_libraries(${TARGET_NAME} PUBLIC $<BUILD_INTERFACE:${TARGET_NAME}_project_options>)
1112
target_link_libraries(${TARGET_NAME} PUBLIC $<BUILD_INTERFACE:${TARGET_NAME}_project_warnings>)
1213
endif()
14+
endif()
1315

1416
include(CMakePrintHelpers)
1517
cmake_print_variables(TARGET_ALIAS TARGET_NAME TARGET_PREFIX PROJECT_SOURCE_DIR)
@@ -42,6 +44,7 @@ target_sources(
4244
${PROJECT_SOURCE_DIR}/include/beman/execution/detail/as_awaitable.hpp
4345
${PROJECT_SOURCE_DIR}/include/beman/execution/detail/as_except_ptr.hpp
4446
${PROJECT_SOURCE_DIR}/include/beman/execution/detail/as_tuple.hpp
47+
${PROJECT_SOURCE_DIR}/include/beman/execution/detail/associate.hpp
4548
${PROJECT_SOURCE_DIR}/include/beman/execution/detail/atomic_intrusive_stack.hpp
4649
${PROJECT_SOURCE_DIR}/include/beman/execution/detail/await_result_type.hpp
4750
${PROJECT_SOURCE_DIR}/include/beman/execution/detail/await_suspend_result.hpp
@@ -125,7 +128,6 @@ target_sources(
125128
${PROJECT_SOURCE_DIR}/include/beman/execution/detail/meta_transform.hpp
126129
${PROJECT_SOURCE_DIR}/include/beman/execution/detail/meta_unique.hpp
127130
${PROJECT_SOURCE_DIR}/include/beman/execution/detail/movable_value.hpp
128-
${PROJECT_SOURCE_DIR}/include/beman/execution/detail/nest.hpp
129131
${PROJECT_SOURCE_DIR}/include/beman/execution/detail/never_stop_token.hpp
130132
${PROJECT_SOURCE_DIR}/include/beman/execution/detail/nostopstate.hpp
131133
${PROJECT_SOURCE_DIR}/include/beman/execution/detail/nothrow_callable.hpp

tests/beman/execution/CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,13 +11,13 @@ endif()
1111
list(
1212
APPEND
1313
execution_tests
14+
exec-associate.test
1415
exec-spawn.test
1516
exec-stop-when.test
1617
exec-prop.test
1718
exec-scope-simple-counting.test
1819
exec-spawn-future.test
1920
exec-scope-concepts.test
20-
exec-nest.test
2121
issue-144.test
2222
exec-on.test
2323
notify.test

0 commit comments

Comments
 (0)