Skip to content

Commit 476f66a

Browse files
authored
Merge pull request #48 from bemanproject/issues
Issues
2 parents 0495d7f + 999eaf4 commit 476f66a

File tree

15 files changed

+752
-138
lines changed

15 files changed

+752
-138
lines changed

CMakeLists.txt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,9 +34,9 @@ set(TARGETS_EXPORT_NAME ${CMAKE_PROJECT_NAME}Targets)
3434

3535
FetchContent_Declare(
3636
execution
37-
# SOURCE_DIR <path-to>/execution
37+
# SOURCE_DIR ${CMAKE_SOURCE_DIR}/../execution
3838
GIT_REPOSITORY https://github.com/bemanproject/execution
39-
GIT_TAG 330be95
39+
GIT_TAG a5843eb
4040
)
4141
FetchContent_MakeAvailable(execution)
4242

Makefile

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
#-dk: note to self: PATH=/opt/llvm-19.1.6/bin:$PATH LDFLAGS=-fuse-ld=lld
22

3-
.PHONY: config test default compile clean distclean doc html pdf format tidy
3+
.PHONY: config test default compile clean distclean doc html pdf format clang-format tidy
44

55
BUILDDIR = build
66
PRESET = gcc-release
@@ -26,7 +26,7 @@ compile:
2626
list:
2727
cmake --workflow --list-presets
2828

29-
format:
29+
clang-format format:
3030
git clang-format main
3131

3232
$(BUILDDIR)/tidy/compile_commands.json:

docs/P3796-task-issues.md

Lines changed: 517 additions & 84 deletions
Large diffs are not rendered by default.

examples/CMakeLists.txt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,11 @@
11
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
22

33
set(ALL_EXAMPLES
4+
odd-return
5+
bulk
6+
dangling-references
7+
rvalue-task
8+
aggregate-return
49
tls-scheduler
510
customize
611
issue-symmetric-transfer

examples/aggregate-return.cpp

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
// examples/aggregate-return.cpp -*-C++-*-
2+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
3+
4+
#include <beman/execution/execution.hpp>
5+
#include <beman/task/task.hpp>
6+
7+
namespace ex = beman::execution;
8+
9+
// ----------------------------------------------------------------------------
10+
11+
int main() {
12+
struct aggregate {
13+
int value = 0;
14+
};
15+
16+
ex::sync_wait([]() -> ex::task<aggregate> { co_return aggregate{42}; }());
17+
ex::sync_wait([]() -> ex::task<aggregate> { co_return aggregate{}; }());
18+
ex::sync_wait([]() -> ex::task<aggregate> { co_return {42}; }());
19+
ex::sync_wait([]() -> ex::task<aggregate> { co_return {}; }());
20+
}

examples/bulk.cpp

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
// examples/bulk.cpp -*-C++-*-
2+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
3+
4+
#include <beman/execution/execution.hpp>
5+
#include <beman/execution/task.hpp>
6+
#include <execution>
7+
8+
namespace ex = beman::execution;
9+
namespace beman::execution {
10+
inline constexpr struct par_t {
11+
} par{};
12+
using parallel_scheduler = inline_scheduler;
13+
} // namespace beman::execution
14+
15+
// ----------------------------------------------------------------------------
16+
17+
int main() {
18+
struct env {
19+
auto query(ex::get_scheduler_t) const noexcept { return ex::parallel_scheduler(); }
20+
};
21+
struct work {
22+
auto operator()(std::size_t) { /*...*/ };
23+
};
24+
25+
ex::sync_wait(ex::write_env(ex::bulk(ex::just(), 16u, work{}), env{}));
26+
27+
ex::sync_wait(
28+
ex::write_env([]() -> ex::task<void, ex::empty_env> { co_await ex::bulk(ex::just(), 16u, work{}); }(), env{}));
29+
}

examples/c++now-with_error.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,10 +26,10 @@ struct context {
2626
ex::task<int, context> error_return(int arg) noexcept {
2727
try {
2828
if (arg == 1)
29-
co_yield ex::with_error(E{arg});
29+
co_yield ex::with_error{E{arg}};
3030
co_return arg * 17;
3131
} catch (...) {
32-
unreachable("no error should escape co_yield with_error(E{0})");
32+
unreachable("no error should escape co_yield with_error{E{0}}");
3333
std::terminate();
3434
}
3535
}
@@ -40,7 +40,7 @@ struct ctxt {
4040

4141
ex::task<int, ctxt> call(int v) {
4242
if (v == 1)
43-
co_yield ex::with_error(-1);
43+
co_yield ex::with_error{-1};
4444
co_return 2 * v;
4545
}
4646
} // namespace

examples/dangling-references.cpp

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
// examples/dangling-references.cpp -*-C++-*-
2+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
3+
4+
#include <beman/execution/execution.hpp>
5+
#include <beman/task/task.hpp>
6+
#include <utility>
7+
#include <functional>
8+
#include <string>
9+
10+
namespace ex = beman::execution;
11+
12+
// ----------------------------------------------------------------------------
13+
14+
namespace {
15+
ex::task<int, ex::empty_env> do_work(std::string) { /* work */ co_return 0; };
16+
ex::task<void, ex::empty_env> execute_all() {
17+
co_await ex::when_all(do_work("arguments 1"), do_work("arguments 2"));
18+
co_return;
19+
}
20+
21+
struct error_env {
22+
using error_types = ex::completion_signatures<ex::set_error_t(int)>;
23+
};
24+
} // namespace
25+
26+
int main() {
27+
ex::sync_wait([]() -> ex::task<ex::with_error<int>, error_env> { co_return ex::with_error<int>{42}; }());
28+
29+
ex::sync_wait(execute_all());
30+
ex::sync_wait([]() -> ex::task<void, ex::empty_env> {
31+
auto t = [](const int /* this would be added: &*/ v) -> ex::task<int, ex::empty_env> { co_return v; }(42);
32+
[[maybe_unused]] auto v = co_await std::move(t);
33+
}());
34+
}

examples/error.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ ex::task<int, error_context> fun(int i) {
3838
// successful return of a value
3939
co_return 17;
4040
case 4:
41-
co_yield ex::with_error(std::make_error_code(std::errc::io_error));
41+
co_yield ex::with_error{std::make_error_code(std::errc::io_error)};
4242
break;
4343
}
4444

examples/loop.cpp

Lines changed: 78 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,21 +5,93 @@
55
#include <string>
66
#include <beman/execution/execution.hpp>
77
#include <beman/task/task.hpp>
8+
#include <iostream>
89

910
namespace ex = beman::execution;
1011

12+
namespace {
13+
struct run_loop_env {
14+
using scheduler_type = decltype(std::declval<ex::run_loop>().get_scheduler());
15+
};
16+
17+
template <ex::scheduler Scheduler>
18+
struct log_scheduler {
19+
using scheduler_concept = ex::scheduler_t;
20+
21+
std::remove_cvref_t<Scheduler> scheduler;
22+
23+
log_scheduler(auto&& sched) : scheduler(std::forward<decltype(sched)>(sched)) {}
24+
25+
struct sender {
26+
using sender_concept = ex::sender_t;
27+
using completion_signatures = ex::completion_signatures<ex::set_value_t()>;
28+
using up_sender = decltype(ex::schedule(std::declval<Scheduler>()));
29+
30+
up_sender _sender;
31+
32+
template <ex::receiver Receiver>
33+
struct state {
34+
using operation_state_concept = ex::operation_state_t;
35+
using up_state_t = decltype(ex::connect(std::declval<up_sender>(), std::declval<Receiver>()));
36+
37+
up_state_t _state;
38+
39+
template <ex::sender S, ex::receiver R>
40+
state(S&& sender, R&& receiver)
41+
: _state(ex::connect(std::forward<S>(sender), std::forward<R>(receiver))) {}
42+
43+
auto start() & noexcept -> void {
44+
std::cout << "start scheduler: " << &this->_state << "\n";
45+
ex::start(this->_state);
46+
}
47+
};
48+
49+
struct env {
50+
log_scheduler _sched;
51+
auto query(const ex::get_completion_scheduler_t<ex::set_value_t>&) const noexcept -> log_scheduler {
52+
return this->_sched;
53+
}
54+
};
55+
auto get_env() const noexcept -> env {
56+
return {ex::get_completion_scheduler<ex::set_value_t>(ex::get_env(this->_sender))};
57+
}
58+
template <ex::receiver Receiver>
59+
auto connect(Receiver&& receiver) noexcept -> state<std::remove_cvref_t<Receiver>> {
60+
return {this->_sender, std::forward<Receiver>(receiver)};
61+
}
62+
};
63+
64+
auto schedule() noexcept { return sender{ex::schedule(this->scheduler)}; }
65+
auto operator==(const log_scheduler&) const noexcept -> bool = default;
66+
};
67+
template <ex::scheduler Scheduler>
68+
log_scheduler(Scheduler&&) -> log_scheduler<std::remove_cvref_t<Scheduler>>;
69+
70+
static_assert(ex::scheduler<log_scheduler<ex::inline_scheduler>>);
71+
static_assert(ex::scheduler<log_scheduler<ex::task_scheduler>>);
72+
} // namespace
73+
1174
namespace {
1275
[[maybe_unused]] ex::task<void> loop(auto count) {
13-
for (int i{}; i < count; ++i)
14-
co_await ex::just(i);
76+
for (decltype(count) i{}; i < count; ++i)
77+
// co_await ex::just(i);
78+
co_await [](int x) -> ex::task<> {
79+
std::cout << "before co_await: " << &x << ": " << x << "\n";
80+
co_await (ex::just(x) | ex::then([](int v) { std::cout << &v << ": " << v << "\n"; }));
81+
std::cout << "after co_await: " << &x << ": " << x << "\n";
82+
}(i);
1583
}
1684
} // namespace
1785

1886
int main(int ac, char* av[]) {
19-
auto count = 1 < ac && av[1] == std::string_view("run-it") ? 1000000 : 10000;
20-
#if 1
87+
auto count = 1 < ac && av[1] == std::string_view("run-it") ? 1000000 : 1000;
2188
ex::sync_wait(loop(count));
22-
#else
23-
ex::sync_wait(ex::detail::write_env(loop(count), ex::detail::make_env(ex::get_scheduler, ex::inline_scheduler{})));
89+
ex::sync_wait([](std::size_t count) -> ex::task<void, run_loop_env> {
90+
co_await ex::write_env(
91+
loop(count),
92+
ex::detail::make_env(ex::get_scheduler, log_scheduler(co_await ex::read_env(ex::get_scheduler))));
93+
}(count));
94+
#if 0
95+
ex::sync_wait(ex::detail::write_env(loop(count), ex::detail::make_env(ex::get_scheduler, ex::inline_scheduler{})));
2496
#endif
2597
}

0 commit comments

Comments
 (0)