From 5b44c98edc299a02f6dc74378d6de02ee15adad4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dietmar=20K=C3=BChl?= Date: Sun, 22 Dec 2024 02:09:52 +0100 Subject: [PATCH] Fix clang tidy warnings (#105) - fixed various clang-tidy warnings - fixed various gcc warnings - implemented missing noexcept specifications in some places to fix clang-tidy warnings --- Makefile | 10 +- examples/allocator.cpp | 12 +- examples/doc-just_error.cpp | 7 + examples/doc-just_stopped.cpp | 6 + examples/sender-demo.cpp | 36 +-- examples/stop_token.cpp | 24 +- examples/stopping.cpp | 4 +- examples/when_all-cancel.cpp | 13 +- .../beman/execution26/detail/as_awaitable.hpp | 8 +- .../execution26/detail/basic_operation.hpp | 7 +- .../beman/execution26/detail/basic_sender.hpp | 17 +- .../beman/execution26/detail/basic_state.hpp | 4 +- include/beman/execution26/detail/connect.hpp | 37 ++- .../beman/execution26/detail/connect_all.hpp | 58 ++++- include/beman/execution26/detail/fwd_env.hpp | 2 +- .../detail/get_completion_signatures.hpp | 8 +- .../detail/inplace_stop_source.hpp | 4 +- include/beman/execution26/detail/join_env.hpp | 2 +- include/beman/execution26/detail/make_env.hpp | 2 +- include/beman/execution26/detail/notify.hpp | 4 +- .../detail/operation_state_task.hpp | 4 +- include/beman/execution26/detail/run_loop.hpp | 3 +- .../beman/execution26/detail/sched_attrs.hpp | 2 +- .../execution26/detail/sender_awaitable.hpp | 1 - .../detail/simple_counting_scope.hpp | 5 +- .../beman/execution26/detail/stop_source.hpp | 4 +- include/beman/execution26/detail/then.hpp | 5 + .../detail/with_awaitable_senders.hpp | 3 + tests/beman/execution26/exec-connect.test.cpp | 26 +- tests/beman/execution26/exec-general.test.cpp | 3 +- tests/beman/execution26/exec-let.test.cpp | 2 +- .../beman/execution26/exec-snd-expos.test.cpp | 224 +++++++++--------- tests/beman/execution26/exec-split.test.cpp | 11 +- .../beman/execution26/exec-sync-wait.test.cpp | 27 ++- tests/beman/execution26/exec-then.test.cpp | 6 +- .../beman/execution26/exec-when-all.test.cpp | 8 +- .../exec-with-awaitable-senders.test.cpp | 9 +- .../execution26/include/test/execution.hpp | 3 + .../execution26/include/test/stop_token.hpp | 8 +- 39 files changed, 367 insertions(+), 252 deletions(-) diff --git a/Makefile b/Makefile index 02a714fa..df8947b4 100644 --- a/Makefile +++ b/Makefile @@ -14,7 +14,7 @@ SANITIZERS := run # SANITIZERS += asan # TODO: tsan msan # endif -.PHONY: default release debug doc run update check ce todo distclean clean codespell clang-tidy build test install all format $(SANITIZERS) +.PHONY: default release debug doc run update check ce todo distclean clean codespell clang-tidy build test install all format unstage $(SANITIZERS) SYSROOT ?= TOOLCHAIN ?= @@ -79,6 +79,7 @@ doc: build: CC=$(CXX) cmake --fresh -G Ninja -S $(SOURCEDIR) -B $(BUILD) $(TOOLCHAIN) $(SYSROOT) \ + -DCMAKE_EXPORT_COMPILE_COMMANDS=1 \ -DCMAKE_CXX_COMPILER=$(CXX) # XXX -DCMAKE_CXX_FLAGS="$(CXX_FLAGS) $(SAN_FLAGS)" cmake --build $(BUILD) @@ -111,8 +112,8 @@ check: done | tsort > /dev/null build/$(SANITIZER)/compile_commands.json: $(SANITIZER) -clang-tidy: build/$(SANITIZER)/compile_commands.json - run-clang-tidy -p build/$(SANITIZER) tests examples +clang-tidy: $(BUILD)/compile_commands.json + run-clang-tidy -p $(BUILD) tests examples codespell: codespell -L statics,snd,copyable,cancelled @@ -128,6 +129,9 @@ clang-format: todo: bin/mk-todo.py +unstage: + git restore --staged tests/beman/execution26/CMakeLists.txt + .PHONY: clean-doc clean-doc: $(RM) -r docs/html docs/latex diff --git a/examples/allocator.cpp b/examples/allocator.cpp index 483521c9..cd4655e7 100644 --- a/examples/allocator.cpp +++ b/examples/allocator.cpp @@ -12,7 +12,7 @@ namespace { template struct inline_resource : std::pmr::memory_resource { const char* name; - explicit inline_resource(const char* name) : name(name) {} + explicit inline_resource(const char* n) : name(n) {} std::byte buffer[Size]{}; // NOLINT(hicpp-avoid-c-arrays) std::byte* next{+this->buffer}; // NOLINT(hicpp-no-array-decay) @@ -39,13 +39,13 @@ struct allocator_aware_fun { template requires std::same_as, std::remove_cvref_t> - explicit allocator_aware_fun(F&& fun) : fun(std::forward(fun)) {} - allocator_aware_fun(const allocator_aware_fun& other, allocator_type allocator = {}) - : fun(other.fun), allocator(allocator) {} + explicit allocator_aware_fun(F&& f) : fun(std::forward(f)) {} + allocator_aware_fun(const allocator_aware_fun& other, allocator_type alloc = {}) + : fun(other.fun), allocator(alloc) {} allocator_aware_fun(allocator_aware_fun&& other) noexcept : fun(std::move(other.fun)), allocator(other.allocator) {} - allocator_aware_fun(allocator_aware_fun&& other, allocator_type allocator) - : fun(std::move(other.fun)), allocator(allocator) {} + allocator_aware_fun(allocator_aware_fun&& other, allocator_type alloc) + : fun(std::move(other.fun)), allocator(alloc) {} template auto operator()(Args&&... args) noexcept { diff --git a/examples/doc-just_error.cpp b/examples/doc-just_error.cpp index 3a790e52..24e75b6c 100644 --- a/examples/doc-just_error.cpp +++ b/examples/doc-just_error.cpp @@ -6,12 +6,19 @@ #include namespace ex = beman::execution26; +namespace { +void use(auto&&...) {} +} // namespace + int main() { bool had_error{false}; auto result = ex::sync_wait(ex::just_error(std::error_code(17, std::system_category())) | ex::upon_error([&](std::error_code ec) { + use(ec); assert(ec.value() == 17); had_error = true; })); + use(result, had_error); + assert(result); assert(had_error); } diff --git a/examples/doc-just_stopped.cpp b/examples/doc-just_stopped.cpp index cd7fdd72..5f48cb2d 100644 --- a/examples/doc-just_stopped.cpp +++ b/examples/doc-just_stopped.cpp @@ -7,9 +7,15 @@ #include //-dk:TODO remove namespace ex = beman::execution26; +namespace { +void use(auto&&...) {} +} // namespace + int main() { bool stopped{false}; auto result = ex::sync_wait(ex::just_stopped() | ex::upon_stopped([&] { stopped = true; })); + use(result, stopped); + assert(result); assert(stopped); } diff --git a/examples/sender-demo.cpp b/examples/sender-demo.cpp index a2894aa0..384c71aa 100644 --- a/examples/sender-demo.cpp +++ b/examples/sender-demo.cpp @@ -14,8 +14,8 @@ struct just_op_state { std::pmr::string value; template - just_op_state(R&& r, std::pmr::string&& value) - : rec(std::forward(r)), value(std::move(value), ex::get_allocator(ex::get_env(rec))) {} + just_op_state(R&& r, std::pmr::string&& val) + : rec(std::forward(r)), value(std::move(val), ex::get_allocator(ex::get_env(rec))) {} void start() & noexcept { ex::set_value(std::move(rec), std::move(value)); } }; @@ -46,18 +46,22 @@ static_assert(ex::sender>); static_assert(ex::sender_in>); int main() { - auto j = just_sender{std::pmr::string("value")}; - auto t = std::move(j) | ex::then([](const std::pmr::string& v) { return v + " then"; }); - auto w = ex::when_all(std::move(t)); - auto e = ex::detail::write_env(std::move(w), - ex::detail::make_env(ex::get_allocator, std::pmr::polymorphic_allocator<>())); - - std::cout << "before start\n"; - auto r = ex::sync_wait(std::move(e)); - if (r) { - auto [v] = *r; - std::cout << "produced='" << v << "'\n"; - } else - std::cout << "operation was cancelled\n"; - std::cout << "after start\n"; + try { + auto j = just_sender{std::pmr::string("value")}; + auto t = std::move(j) | ex::then([](const std::pmr::string& v) { return v + " then"; }); + auto w = ex::when_all(std::move(t)); + auto e = ex::detail::write_env(std::move(w), + ex::detail::make_env(ex::get_allocator, std::pmr::polymorphic_allocator<>())); + + std::cout << "before start\n"; + auto r = ex::sync_wait(std::move(e)); + if (r) { + auto [v] = *r; + std::cout << "produced='" << v << "'\n"; + } else + std::cout << "operation was cancelled\n"; + std::cout << "after start\n"; + } catch (const std::exception& ex) { + std::cout << "ERROR: " << ex.what() << "\n"; + } } diff --git a/examples/stop_token.cpp b/examples/stop_token.cpp index 33f36639..9100e284 100644 --- a/examples/stop_token.cpp +++ b/examples/stop_token.cpp @@ -4,6 +4,7 @@ #include #include #include +#include #include #include #include @@ -92,15 +93,20 @@ auto inactive(Token token) -> void { } // namespace auto main() -> int { - exec::stop_source source; - ::std::thread act([token = source.get_token()] { active(token); }); - ::std::thread inact([token = source.get_token()] { inactive(token); }); + try { - print("threads started\n"); - source.request_stop(); - print("threads cancelled\n"); + exec::stop_source source; + ::std::thread act([token = source.get_token()] { active(token); }); + ::std::thread inact([token = source.get_token()] { inactive(token); }); - act.join(); - inact.join(); - print("done\n"); + print("threads started\n"); + source.request_stop(); + print("threads cancelled\n"); + + act.join(); + inact.join(); + print("done\n"); + } catch (const std::exception& ex) { + std::cout << "ERROR: " << ex.what() << "\n"; + } } diff --git a/examples/stopping.cpp b/examples/stopping.cpp index d82151f5..4b43c3a2 100644 --- a/examples/stopping.cpp +++ b/examples/stopping.cpp @@ -22,7 +22,7 @@ namespace { struct env { ex::inplace_stop_token token; - env(ex::inplace_stop_token token) : token(token) {} // NOLINT(hicpp-explicit-conversions) + explicit env(ex::inplace_stop_token t) : token(t) {} // NOLINT(hicpp-explicit-conversions) auto query(const ex::get_stop_token_t&) const noexcept { return this->token; } }; @@ -38,7 +38,7 @@ struct inject_cancel_sender { std::remove_cvref_t inner_receiver; ex::inplace_stop_token token{}; - auto get_env() const noexcept -> env { return {this->token}; } + auto get_env() const noexcept -> env { return env(this->token); } template auto set_value(T&&... t) noexcept -> void { diff --git a/examples/when_all-cancel.cpp b/examples/when_all-cancel.cpp index 0fcb1105..f7daca8d 100644 --- a/examples/when_all-cancel.cpp +++ b/examples/when_all-cancel.cpp @@ -7,6 +7,7 @@ #include #include #include +#include namespace ex = beman::execution26; @@ -106,11 +107,15 @@ struct eager { std::optional inner_state; template - state(R&& r, S&& s) : outer_receiver(std::forward(r)), inner_state() { - inner_state.emplace(std::forward(s), receiver{this}); + state(R&& r, S&& s) + : outer_receiver(std::forward(r)), inner_state(std::in_place, std::forward(s), receiver{this}) {} + auto start() & noexcept -> void { + if (this->inner_state) { + ex::start((*this->inner_state).st); + } else { + assert(this->inner_state); + } } - // TODO on next line: bugprone-unchecked-optional-access - auto start() & noexcept -> void { ex::start((*this->inner_state).st); } }; template auto connect(Receiver&& receiver) { diff --git a/include/beman/execution26/detail/as_awaitable.hpp b/include/beman/execution26/detail/as_awaitable.hpp index 0366b386..5da05f5e 100644 --- a/include/beman/execution26/detail/as_awaitable.hpp +++ b/include/beman/execution26/detail/as_awaitable.hpp @@ -4,7 +4,6 @@ #ifndef INCLUDED_BEMAN_EXECUTION26_DETAIL_AS_AWAITABLE #define INCLUDED_BEMAN_EXECUTION26_DETAIL_AS_AWAITABLE -#include #include #include #include @@ -31,12 +30,11 @@ struct as_awaitable_t { "as_awaitable must return an awaitable"); return ::std::forward(expr).as_awaitable(promise); } else if constexpr (::beman::execution26::detail:: - is_awaitable) { + is_awaitable || + not::beman::execution26::detail::awaitable_sender) { return ::std::forward(expr); - } else if constexpr (::beman::execution26::detail::awaitable_sender) { - return ::beman::execution26::detail::sender_awaitable{::std::forward(expr), promise}; } else { - return ::std::forward(expr); + return ::beman::execution26::detail::sender_awaitable{::std::forward(expr), promise}; } } }; diff --git a/include/beman/execution26/detail/basic_operation.hpp b/include/beman/execution26/detail/basic_operation.hpp index 1921195c..27f045a9 100644 --- a/include/beman/execution26/detail/basic_operation.hpp +++ b/include/beman/execution26/detail/basic_operation.hpp @@ -35,7 +35,12 @@ template using inner_ops_t = ::beman::execution26::detail::connect_all_result; inner_ops_t inner_ops; - basic_operation(Sender&& sender, Receiver&& receiver) noexcept(true /*-dk:TODO*/) + basic_operation(Sender&& sender, Receiver&& receiver) noexcept( + noexcept(::beman::execution26::detail::basic_state(::std::forward(sender), + ::std::move(receiver))) && + noexcept(::beman::execution26::detail::connect_all(this, + ::std::forward(sender), + ::beman::execution26::detail::indices_for()))) : ::beman::execution26::detail::basic_state(::std::forward(sender), ::std::move(receiver)), // NOLINTBEGIN(bugprone-use-after-move,hicpp-invalid-access-moved) diff --git a/include/beman/execution26/detail/basic_sender.hpp b/include/beman/execution26/detail/basic_sender.hpp index 71776f3e..af0d0272 100644 --- a/include/beman/execution26/detail/basic_sender.hpp +++ b/include/beman/execution26/detail/basic_sender.hpp @@ -44,25 +44,32 @@ struct basic_sender : ::beman::execution26::detail::product_type - auto connect(Receiver receiver) & noexcept(true /*-dk:TODO*/) + auto connect(Receiver receiver) & noexcept( + noexcept(::beman::execution26::detail::basic_operation{*this, ::std::move(receiver)})) -> ::beman::execution26::detail::basic_operation { return {*this, ::std::move(receiver)}; } template <::beman::execution26::receiver Receiver> - auto connect(Receiver receiver) const& noexcept(true /*-dk:TODO*/) + auto connect(Receiver receiver) const& noexcept(noexcept( + ::beman::execution26::detail::basic_operation{*this, ::std::move(receiver)})) -> ::beman::execution26::detail::basic_operation { return {*this, ::std::move(receiver)}; } template <::beman::execution26::receiver Receiver> - auto connect(Receiver receiver) && noexcept(true /*-dk:TODO*/) + auto connect(Receiver receiver) && noexcept( + noexcept(::beman::execution26::detail::basic_operation{::std::move(*this), + ::std::move(receiver)})) -> ::beman::execution26::detail::basic_operation { return {::std::move(*this), ::std::move(receiver)}; } #else template <::beman::execution26::detail::decays_to Self, ::beman::execution26::receiver Receiver> - auto connect(this Self&& self, Receiver receiver) noexcept(true /*-dk:TODO*/) + auto + connect(this Self&& self, + Receiver receiver) noexcept(noexcept(::beman::execution26::detail::basic_operation{ + ::std::forward(self), ::std::move(receiver)})) -> ::beman::execution26::detail::basic_operation { return {::std::forward(self), ::std::move(receiver)}; } diff --git a/include/beman/execution26/detail/basic_state.hpp b/include/beman/execution26/detail/basic_state.hpp index 292f3090..83850a44 100644 --- a/include/beman/execution26/detail/basic_state.hpp +++ b/include/beman/execution26/detail/basic_state.hpp @@ -20,8 +20,8 @@ namespace beman::execution26::detail { */ template struct basic_state { - basic_state(Sender&& sender, Receiver&& receiver) noexcept(true) - : receiver(::std::move(receiver)), + basic_state(Sender&& sender, Receiver&& rcvr) noexcept(true) + : receiver(::std::move(rcvr)), state(::beman::execution26::detail::impls_for< ::beman::execution26::tag_of_t >::get_state( ::std::forward(sender), this->receiver)) {} diff --git a/include/beman/execution26/detail/connect.hpp b/include/beman/execution26/detail/connect.hpp index a7b33300..0ec5a2c8 100644 --- a/include/beman/execution26/detail/connect.hpp +++ b/include/beman/execution26/detail/connect.hpp @@ -21,14 +21,39 @@ namespace beman::execution26::detail { * \internal */ struct connect_t { + private: template - auto operator()(Sender&& sender, Receiver&& receiver) const noexcept(true /*-dk:TODO*/) { + static auto make_new_sender(Sender&& sender, Receiver&& receiver) noexcept(true) -> decltype(auto) { + return ::beman::execution26::transform_sender( + decltype(::beman::execution26::detail::get_domain_late(::std::forward(sender), + ::beman::execution26::get_env(receiver))){}, + ::std::forward(sender), + ::beman::execution26::get_env(receiver)); + } + template + static constexpr auto connect_noexcept() -> bool { + if constexpr (requires { + make_new_sender(::std::declval(), ::std::declval()) + .connect(::std::declval()); + }) { + return noexcept(make_new_sender(::std::declval(), ::std::declval()) + .connect(::std::declval())); + } else if constexpr (requires { + ::beman::execution26::detail::connect_awaitable( + make_new_sender(::std::declval(), ::std::declval()), + ::std::declval()); + }) { + return noexcept(::beman::execution26::detail::connect_awaitable( + make_new_sender(::std::declval(), ::std::declval()), ::std::declval())); + } + return true; + } + + public: + template + auto operator()(Sender&& sender, Receiver&& receiver) const noexcept(connect_noexcept()) { auto new_sender = [&sender, &receiver]() -> decltype(auto) { - return ::beman::execution26::transform_sender( - decltype(::beman::execution26::detail::get_domain_late(::std::forward(sender), - ::beman::execution26::get_env(receiver))){}, - ::std::forward(sender), - ::beman::execution26::get_env(receiver)); + return make_new_sender(::std::forward(sender), ::std::forward(receiver)); }; if constexpr (requires { new_sender().connect(::std::forward(receiver)); }) { diff --git a/include/beman/execution26/detail/connect_all.hpp b/include/beman/execution26/detail/connect_all.hpp index 5598ab72..057bb6c7 100644 --- a/include/beman/execution26/detail/connect_all.hpp +++ b/include/beman/execution26/detail/connect_all.hpp @@ -10,6 +10,7 @@ #include #include #include +#include #include #include #include @@ -25,24 +26,55 @@ namespace beman::execution26::detail { * \internal */ struct connect_all_t { + private: + template + static auto apply_with_index_helper(::std::index_sequence seq, Fun&& fun, Tuple&& tuple) noexcept(noexcept( + ::std::forward(fun)(seq, ::beman::execution26::detail::forward_like(::std::get(tuple))...))) + -> decltype(auto) { + return ::std::forward(fun)(seq, + ::beman::execution26::detail::forward_like(::std::get(tuple))...); + } + template + static auto apply_with_index(Fun&& fun, Tuple&& tuple) noexcept( + noexcept(apply_with_index_helper(::std::make_index_sequence<::std::tuple_size_v<::std::decay_t>>{}, + ::std::forward(fun), + ::std::forward(tuple)))) -> decltype(auto) { + return apply_with_index_helper(::std::make_index_sequence<::std::tuple_size_v<::std::decay_t>>{}, + ::std::forward(fun), + ::std::forward(tuple)); + } + + template + struct connect_helper { + ::beman::execution26::detail::basic_state* op; + + template <::std::size_t... J, typename... C> + auto operator()(::std::index_sequence, C&&... c) noexcept( + (noexcept(::beman::execution26::connect( + ::beman::execution26::detail::forward_like(c), + ::beman::execution26::detail::basic_receiver>{ + this->op})) && + ... && true)) -> decltype(auto) { + return ::beman::execution26::detail::product_type{::beman::execution26::connect( + ::beman::execution26::detail::forward_like(c), + ::beman::execution26::detail::basic_receiver>{ + this->op})...}; + } + }; + static auto use(auto&&...) {} + + public: //-dk:TODO is the S parameter deviating from the spec? template auto operator()(::beman::execution26::detail::basic_state* op, S&& sender, - ::std::index_sequence) const noexcept(true /*-dk:TODO*/) { - auto data{::beman::execution26::detail::get_sender_data(::std::forward(sender))}; - return ::std::apply( - [&op](auto&&... c) { - return [&op]<::std::size_t... J>(::std::index_sequence, auto&&... c) { - use(op); - return ::beman::execution26::detail::product_type{::beman::execution26::connect( - ::beman::execution26::detail::forward_like(c), - ::beman::execution26::detail:: - basic_receiver>{op})...}; - }(::std::make_index_sequence<::std::tuple_size_v<::std::decay_t>>{}, c...); - }, - data.children); + ::std::index_sequence) const + noexcept(noexcept(apply_with_index( + connect_helper{op}, + ::beman::execution26::detail::get_sender_data(::std::forward(sender)).children))) -> decltype(auto) { + return apply_with_index(connect_helper{op}, + ::beman::execution26::detail::get_sender_data(::std::forward(sender)).children); } }; diff --git a/include/beman/execution26/detail/fwd_env.hpp b/include/beman/execution26/detail/fwd_env.hpp index 0cf15759..b3288deb 100644 --- a/include/beman/execution26/detail/fwd_env.hpp +++ b/include/beman/execution26/detail/fwd_env.hpp @@ -25,7 +25,7 @@ class fwd_env { Env env; public: - explicit fwd_env(Env&& env) : env(::std::forward(env)) {} + explicit fwd_env(Env&& e) : env(::std::forward(e)) {} template requires(not::beman::execution26::forwarding_query(::std::remove_cvref_t())) diff --git a/include/beman/execution26/detail/get_completion_signatures.hpp b/include/beman/execution26/detail/get_completion_signatures.hpp index 8cf764fe..4ab5aa44 100644 --- a/include/beman/execution26/detail/get_completion_signatures.hpp +++ b/include/beman/execution26/detail/get_completion_signatures.hpp @@ -23,10 +23,10 @@ struct get_completion_signatures_t { private: template static auto get(Sender&& sender, Env&& env) noexcept { - auto new_sender{[](auto&& sender, auto&& env) -> decltype(auto) { - return ::beman::execution26::transform_sender(::beman::execution26::detail::get_domain_late(sender, env), - ::std::forward(sender), - ::std::forward(env)); + auto new_sender{[](auto&& sndr, auto&& e) -> decltype(auto) { + auto domain{::beman::execution26::detail::get_domain_late(sndr, e)}; + return ::beman::execution26::transform_sender( + domain, ::std::forward(sndr), ::std::forward(e)); }}; using sender_type = ::std::remove_cvref_t; diff --git a/include/beman/execution26/detail/inplace_stop_source.hpp b/include/beman/execution26/detail/inplace_stop_source.hpp index 970c70e1..615cf155 100644 --- a/include/beman/execution26/detail/inplace_stop_source.hpp +++ b/include/beman/execution26/detail/inplace_stop_source.hpp @@ -41,7 +41,7 @@ class beman::execution26::inplace_stop_token { friend class ::beman::execution26::inplace_stop_source; template friend class ::beman::execution26::inplace_stop_callback; - explicit inplace_stop_token(::beman::execution26::inplace_stop_source* source) : source(source) {} + explicit inplace_stop_token(::beman::execution26::inplace_stop_source* src) : source(src) {} ::beman::execution26::inplace_stop_source* source{}; }; @@ -86,7 +86,7 @@ class beman::execution26::inplace_stop_callback final inplace_stop_callback(::beman::execution26::inplace_stop_token, Init&&); inplace_stop_callback(const inplace_stop_callback&) = delete; inplace_stop_callback(inplace_stop_callback&&) = delete; - ~inplace_stop_callback() { + ~inplace_stop_callback() override { if (this->source) { this->source->deregister(this); } diff --git a/include/beman/execution26/detail/join_env.hpp b/include/beman/execution26/detail/join_env.hpp index 6bd6a0de..1cc32dcc 100644 --- a/include/beman/execution26/detail/join_env.hpp +++ b/include/beman/execution26/detail/join_env.hpp @@ -18,7 +18,7 @@ class join_env { public: template - join_env(E1&& env1, E2&& env2) : env1(::std::forward(env1)), env2(::std::forward(env2)) {} + join_env(E1&& e1, E2&& e2) : env1(::std::forward(e1)), env2(::std::forward(e2)) {} template requires( diff --git a/include/beman/execution26/detail/make_env.hpp b/include/beman/execution26/detail/make_env.hpp index 5b7c9860..1b8cb020 100644 --- a/include/beman/execution26/detail/make_env.hpp +++ b/include/beman/execution26/detail/make_env.hpp @@ -17,7 +17,7 @@ class make_env { public: template - make_env(const Query&, V&& value) : value(::std::forward(value)) {} + make_env(const Query&, V&& v) : value(::std::forward(v)) {} constexpr auto query(const Query&) const noexcept -> const Value& { return this->value; } constexpr auto query(const Query&) noexcept -> Value& { return this->value; } }; diff --git a/include/beman/execution26/detail/notify.hpp b/include/beman/execution26/detail/notify.hpp index afa4ecda..1a09c6a9 100644 --- a/include/beman/execution26/detail/notify.hpp +++ b/include/beman/execution26/detail/notify.hpp @@ -58,8 +58,8 @@ struct impls_for<::beman::execution26::detail::notify_t> : ::beman::execution26: struct state : ::beman::execution26::detail::notifier::base { ::beman::execution26::detail::notifier* n; ::std::remove_cvref_t& receiver{}; - state(::beman::execution26::detail::notifier* n, ::std::remove_cvref_t& receiver) - : n(n), receiver(receiver) {} + state(::beman::execution26::detail::notifier* nn, ::std::remove_cvref_t& rcvr) + : n(nn), receiver(rcvr) {} auto complete() -> void override { ::beman::execution26::set_value(::std::move(this->receiver)); } }; static constexpr auto get_state{[](Sender&& sender, Receiver&& receiver) { diff --git a/include/beman/execution26/detail/operation_state_task.hpp b/include/beman/execution26/detail/operation_state_task.hpp index 85e115e1..6818d178 100644 --- a/include/beman/execution26/detail/operation_state_task.hpp +++ b/include/beman/execution26/detail/operation_state_task.hpp @@ -28,7 +28,7 @@ struct connect_awaitable_promise; template struct beman::execution26::detail::connect_awaitable_promise : ::beman::execution26::detail::with_await_transform> { - connect_awaitable_promise(auto&&, Receiver& receiver) noexcept : receiver(receiver) {} + connect_awaitable_promise(auto&&, Receiver& rcvr) noexcept : receiver(rcvr) {} auto initial_suspend() noexcept -> ::std::suspend_always { return {}; } [[noreturn]] auto final_suspend() noexcept -> ::std::suspend_always { ::std::terminate(); } [[noreturn]] auto unhandled_exception() noexcept -> void { ::std::terminate(); } @@ -56,7 +56,7 @@ struct beman::execution26::detail::operation_state_task { using operation_state_concept = ::beman::execution26::operation_state_t; using promise_type = ::beman::execution26::detail::connect_awaitable_promise; - explicit operation_state_task(::std::coroutine_handle<> handle) noexcept : handle(handle) {} + explicit operation_state_task(::std::coroutine_handle<> hndl) noexcept : handle(hndl) {} operation_state_task(const operation_state_task&) = delete; operation_state_task(operation_state_task&& other) noexcept : handle(::std::exchange(other.handle, {})) {} ~operation_state_task() { diff --git a/include/beman/execution26/detail/run_loop.hpp b/include/beman/execution26/detail/run_loop.hpp index 560a2024..b7913f2e 100644 --- a/include/beman/execution26/detail/run_loop.hpp +++ b/include/beman/execution26/detail/run_loop.hpp @@ -39,7 +39,6 @@ class run_loop { }; struct opstate_base : ::beman::execution26::detail::virtual_immovable { - virtual ~opstate_base() = default; opstate_base* next{}; virtual auto execute() noexcept -> void = 0; }; @@ -52,7 +51,7 @@ class run_loop { Receiver receiver; template - opstate(run_loop* loop, R&& receiver) : loop(loop), receiver(::std::forward(receiver)) {} + opstate(run_loop* l, R&& rcvr) : loop(l), receiver(::std::forward(rcvr)) {} auto start() & noexcept -> void { try { this->loop->push_back(this); diff --git a/include/beman/execution26/detail/sched_attrs.hpp b/include/beman/execution26/detail/sched_attrs.hpp index ef650152..55f7a709 100644 --- a/include/beman/execution26/detail/sched_attrs.hpp +++ b/include/beman/execution26/detail/sched_attrs.hpp @@ -24,7 +24,7 @@ class sched_attrs { public: template - explicit sched_attrs(S sched) : sched(::std::move(sched)) {} + explicit sched_attrs(S s) : sched(::std::move(s)) {} template auto query(const ::beman::execution26::get_completion_scheduler_t&) const noexcept { diff --git a/include/beman/execution26/detail/sender_awaitable.hpp b/include/beman/execution26/detail/sender_awaitable.hpp index cfaa013a..f414a57c 100644 --- a/include/beman/execution26/detail/sender_awaitable.hpp +++ b/include/beman/execution26/detail/sender_awaitable.hpp @@ -4,7 +4,6 @@ #ifndef INCLUDED_BEMAN_EXECUTION26_DETAIL_SENDER_AWAITABLE #define INCLUDED_BEMAN_EXECUTION26_DETAIL_SENDER_AWAITABLE -#include #include #include #include diff --git a/include/beman/execution26/detail/simple_counting_scope.hpp b/include/beman/execution26/detail/simple_counting_scope.hpp index 09206613..ae9730a8 100644 --- a/include/beman/execution26/detail/simple_counting_scope.hpp +++ b/include/beman/execution26/detail/simple_counting_scope.hpp @@ -118,8 +118,7 @@ class beman::execution26::simple_counting_scope::assoc { private: friend class beman::execution26::simple_counting_scope::token; - explicit assoc(beman::execution26::simple_counting_scope* scope) - : scope(scope ? scope->try_associate() : nullptr) {} + explicit assoc(beman::execution26::simple_counting_scope* scp) : scope(scp ? scp->try_associate() : nullptr) {} beman::execution26::simple_counting_scope* scope{}; }; // NOLINTEND(misc-unconventional-assign-operator,hicpp-special-member-functions) @@ -139,7 +138,7 @@ class beman::execution26::simple_counting_scope::token { private: friend class beman::execution26::simple_counting_scope; - explicit token(beman::execution26::simple_counting_scope* scope) noexcept : scope(scope) {} + explicit token(beman::execution26::simple_counting_scope* scp) noexcept : scope(scp) {} beman::execution26::simple_counting_scope* scope; }; diff --git a/include/beman/execution26/detail/stop_source.hpp b/include/beman/execution26/detail/stop_source.hpp index acaa579c..2ef2c52c 100644 --- a/include/beman/execution26/detail/stop_source.hpp +++ b/include/beman/execution26/detail/stop_source.hpp @@ -192,8 +192,8 @@ inline auto beman::execution26::detail::stop_callback_base::deregister() -> void inline auto beman::execution26::detail::stop_callback_base::call() -> void { this->do_call(); } -inline beman::execution26::stop_token::stop_token(::std::shared_ptr<::beman::execution26::detail::stop_state> state) - : state(::std::move(state)) {} +inline beman::execution26::stop_token::stop_token(::std::shared_ptr<::beman::execution26::detail::stop_state> st) + : state(::std::move(st)) {} inline auto beman::execution26::stop_token::swap(stop_token& other) noexcept -> void { this->state.swap(other.state); } diff --git a/include/beman/execution26/detail/then.hpp b/include/beman/execution26/detail/then.hpp index 973f65f5..43788605 100644 --- a/include/beman/execution26/detail/then.hpp +++ b/include/beman/execution26/detail/then.hpp @@ -51,6 +51,7 @@ struct then_t : ::beman::execution26::sender_adaptor_closure> template struct impls_for> : ::beman::execution26::detail::default_impls { + // NOLINTBEGIN(bugprone-exception-escape) static constexpr auto complete = [](auto, auto& fun, auto& receiver, Tag, Args&&... args) noexcept -> void { if constexpr (::std::same_as) { @@ -66,13 +67,17 @@ struct impls_for> : ::beman::execution26::detail::default_imp if constexpr (not noexcept(::std::invoke(::std::move(fun), ::std::forward(args)...) )) { + static_assert( + noexcept(::beman::execution26::set_error(::std::move(receiver), ::std::current_exception()))); ::beman::execution26::set_error(::std::move(receiver), ::std::current_exception()); } } } else { + static_assert(noexcept(Tag()(::std::move(receiver), ::std::forward(args)...))); Tag()(::std::move(receiver), ::std::forward(args)...); } }; + // NOLINTEND(bugprone-exception-escape) }; template diff --git a/include/beman/execution26/detail/with_awaitable_senders.hpp b/include/beman/execution26/detail/with_awaitable_senders.hpp index 790457c0..eb2d63b9 100644 --- a/include/beman/execution26/detail/with_awaitable_senders.hpp +++ b/include/beman/execution26/detail/with_awaitable_senders.hpp @@ -37,6 +37,9 @@ struct with_awaitable_senders { } private: + friend Promise; + with_awaitable_senders() = default; + [[noreturn]] static auto default_unhandled_stopped(void*) noexcept -> ::std::coroutine_handle<> { ::std::terminate(); } diff --git a/tests/beman/execution26/exec-connect.test.cpp b/tests/beman/execution26/exec-connect.test.cpp index 5c5ef2e6..9a116646 100644 --- a/tests/beman/execution26/exec-connect.test.cpp +++ b/tests/beman/execution26/exec-connect.test.cpp @@ -22,7 +22,7 @@ struct state { std::remove_cvref_t receiver; template - state(int value, R&& r) : value(value), receiver(std::forward(r)) {} + state(int val, R&& r) : value(val), receiver(std::forward(r)) {} state(const state&) = delete; state(state&&) = delete; ~state() = default; @@ -45,7 +45,7 @@ struct rvalue_sender { using sender_concept = test_std::sender_t; int value{}; - explicit rvalue_sender(int value) : value(value) {} + explicit rvalue_sender(int val) : value(val) {} rvalue_sender(const rvalue_sender&) = delete; rvalue_sender(rvalue_sender&&) = default; auto operator=(const rvalue_sender&) -> rvalue_sender& = delete; @@ -67,8 +67,7 @@ struct receiver { int value{}; bool* set_stopped_called{}; - explicit receiver(int value, bool* set_stopped_called = {}) - : value(value), set_stopped_called(set_stopped_called) {} + explicit receiver(int val, bool* called = {}) : value(val), set_stopped_called(called) {} receiver(receiver&&) = default; receiver(const receiver&) = delete; ~receiver() = default; @@ -104,7 +103,7 @@ struct domain_receiver { using receiver_concept = test_std::receiver_t; int value{}; - explicit domain_receiver(int value) : value(value) {} + explicit domain_receiver(int val) : value(val) {} domain_receiver(domain_receiver&&) = default; domain_receiver(const domain_receiver&) = delete; ~domain_receiver() = default; @@ -167,7 +166,6 @@ auto test_operation_state_task() -> void { static_assert( std::same_as<::beman::execution26::detail::connect_awaitable_promise, state_t::promise_type>); static_assert(noexcept(state_t(std::coroutine_handle<>{}))); - static_assert(noexcept(state_t(state_t(std::coroutine_handle<>{})))); state_t state(::std::coroutine_handle<>{}); static_assert(noexcept(state.start())); } @@ -201,7 +199,7 @@ auto test_suspend_complete() -> void { } auto test_connect_awaitable() -> void { - struct awaiter { + struct local_awaiter { ::std::coroutine_handle<>& handle; int& result; @@ -225,7 +223,7 @@ auto test_connect_awaitable() -> void { auto await_resume() -> void {} }; - struct receiver { + struct local_receiver { using receiver_concept = test_std::receiver_t; int& iv; @@ -253,7 +251,7 @@ auto test_connect_awaitable() -> void { int iv{}; bool bv{}; - auto op1{test_detail::connect_awaitable(awaiter{handle, result}, receiver{iv, bv})}; + auto op1{test_detail::connect_awaitable(local_awaiter{handle, result}, local_receiver{iv, bv})}; ASSERT(handle == std::coroutine_handle<>()); op1.start(); ASSERT(handle != std::coroutine_handle<>()); @@ -269,7 +267,7 @@ auto test_connect_awaitable() -> void { int iv{}; bool bv{}; - auto op1{test_detail::connect_awaitable(awaiter{handle, result}, receiver{iv, bv})}; + auto op1{test_detail::connect_awaitable(local_awaiter{handle, result}, local_receiver{iv, bv})}; ASSERT(handle == std::coroutine_handle<>()); op1.start(); ASSERT(handle != std::coroutine_handle<>()); @@ -285,7 +283,7 @@ auto test_connect_awaitable() -> void { int iv{}; bool bv{}; - auto op1{test_detail::connect_awaitable(void_awaiter{handle}, receiver{iv, bv})}; + auto op1{test_detail::connect_awaitable(void_awaiter{handle}, local_receiver{iv, bv})}; ASSERT(handle == std::coroutine_handle<>()); op1.start(); ASSERT(handle != std::coroutine_handle<>()); @@ -296,13 +294,13 @@ auto test_connect_awaitable() -> void { } auto test_connect_with_awaiter() -> void { - struct awaiter { + struct local_awaiter { ::std::coroutine_handle<>& handle; auto await_ready() -> bool { return {}; } auto await_suspend(std::coroutine_handle<> h) -> void { this->handle = h; } auto await_resume() -> int { return 17; } }; - struct receiver { + struct local_receiver { using receiver_concept = test_std::receiver_t; bool& result; auto set_value(int i) && noexcept -> void { this->result = i == 17; } @@ -312,7 +310,7 @@ auto test_connect_with_awaiter() -> void { std::coroutine_handle<> handle{}; bool result{}; - auto op{test_std::connect(awaiter{handle}, receiver{result})}; + auto op{test_std::connect(local_awaiter{handle}, local_receiver{result})}; ASSERT(handle == std::coroutine_handle{}); test_std::start(op); ASSERT(handle != std::coroutine_handle{}); diff --git a/tests/beman/execution26/exec-general.test.cpp b/tests/beman/execution26/exec-general.test.cpp index 5b71ea8b..48dec8a0 100644 --- a/tests/beman/execution26/exec-general.test.cpp +++ b/tests/beman/execution26/exec-general.test.cpp @@ -10,8 +10,9 @@ // ---------------------------------------------------------------------------- namespace { -struct error { +struct error : std::exception { int value; + explicit error(int v) : value(v) {} }; struct non_movable { diff --git a/tests/beman/execution26/exec-let.test.cpp b/tests/beman/execution26/exec-let.test.cpp index beb4efc5..5a2ac0f6 100644 --- a/tests/beman/execution26/exec-let.test.cpp +++ b/tests/beman/execution26/exec-let.test.cpp @@ -91,7 +91,7 @@ namespace ex = test_std; struct fun { std::pmr::polymorphic_allocator<> allocator{}; fun() {} - explicit fun(std::pmr::polymorphic_allocator<> allocator) : allocator(allocator) {} + explicit fun(std::pmr::polymorphic_allocator<> alloc) : allocator(alloc) {} auto operator()(std::span s) noexcept { return ex::just(std::pmr::vector(s.begin(), s.end(), this->allocator)); } diff --git a/tests/beman/execution26/exec-snd-expos.test.cpp b/tests/beman/execution26/exec-snd-expos.test.cpp index da4c7ff7..557d4344 100644 --- a/tests/beman/execution26/exec-snd-expos.test.cpp +++ b/tests/beman/execution26/exec-snd-expos.test.cpp @@ -99,7 +99,7 @@ template struct operation_state : test_detail::immovable { using operation_state_concept = test_std::operation_state_t; int* counter; - explicit operation_state(int* counter) : counter(counter) {} + explicit operation_state(int* cntr) : counter(cntr) {} auto start() & noexcept -> void { ++*counter; } }; @@ -499,39 +499,39 @@ auto test_get_domain_late() -> void { } auto test_default_impls_get_attrs() -> void { - struct env { + struct local_env { int value; }; struct child1 { - auto get_env() const noexcept { return env{1}; } + auto get_env() const noexcept { return local_env{1}; } }; struct child2 { - auto get_env() const noexcept { return env{2}; } + auto get_env() const noexcept { return local_env{2}; } }; static_assert(noexcept(test_detail::default_impls::get_attrs(0, child1{}))); static_assert( - std::same_as, decltype(test_detail::default_impls::get_attrs(0, child1{}))>); + std::same_as, decltype(test_detail::default_impls::get_attrs(0, child1{}))>); // static_assert(std::same_as); } auto test_default_impls_get_env() -> void { - struct env { + struct local_env { int value; }; - struct receiver { - auto get_env() const noexcept { return env{1}; } + struct local_receiver { + auto get_env() const noexcept { return local_env{1}; } }; int arg{}; - static_assert(noexcept(test_detail::default_impls::get_env(0, arg, receiver{}))); - static_assert( - std::same_as, decltype(test_detail::default_impls::get_env(0, arg, receiver{}))>); + static_assert(noexcept(test_detail::default_impls::get_env(0, arg, local_receiver{}))); + static_assert(std::same_as, + decltype(test_detail::default_impls::get_env(0, arg, local_receiver{}))>); } auto test_default_impls_get_state() -> void { - struct tag { + struct local_tag { static auto name() { return "test_default_impls_get_state"; } }; struct data { @@ -539,52 +539,52 @@ auto test_default_impls_get_state() -> void { int v2{}; auto operator==(const data&) const -> bool = default; }; - struct sender0 { - tag t{}; - data d{1, 2}; + struct local_sender0 { + local_tag t{}; + data d{1, 2}; }; - struct sender1 { - tag t{}; - data d{1, 2}; - int i1{}; + struct local_sender1 { + local_tag t{}; + data d{1, 2}; + int i1{}; }; - struct sender2 { - tag t{}; - data d{1, 2}; - int i1{}; - int i2{}; + struct local_sender2 { + local_tag t{}; + data d{1, 2}; + int i1{}; + int i2{}; }; - struct sender3 { - tag t{}; - data d{1, 2}; - int i1{}; - int i2{}; - int i3{}; + struct local_sender3 { + local_tag t{}; + data d{1, 2}; + int i1{}; + int i2{}; + int i3{}; }; - struct sender4 { - tag t{}; - data d{1, 2}; - int i1{}; - int i2{}; - int i3{}; - int i4{}; + struct local_sender4 { + local_tag t{}; + data d{1, 2}; + int i1{}; + int i2{}; + int i3{}; + int i4{}; }; - struct receiver {}; - - sender0 s{}; - const sender0 cs{}; - receiver r{}; - static_assert(noexcept(test_detail::default_impls::get_state(sender0{}, r))); - static_assert(std::same_as); - ASSERT((data{1, 2}) == test_detail::default_impls::get_state(sender0{}, r)); - static_assert(std::same_as); - ASSERT((data{1, 2}) == test_detail::default_impls::get_state(sender1{}, r)); - static_assert(std::same_as); - ASSERT((data{1, 2}) == test_detail::default_impls::get_state(sender2{}, r)); - static_assert(std::same_as); - ASSERT((data{1, 2}) == test_detail::default_impls::get_state(sender3{}, r)); - static_assert(std::same_as); - ASSERT((data{1, 2}) == test_detail::default_impls::get_state(sender4{}, r)); + struct local_receiver {}; + + local_sender0 s{}; + const local_sender0 cs{}; + local_receiver r{}; + static_assert(noexcept(test_detail::default_impls::get_state(local_sender0{}, r))); + static_assert(std::same_as); + ASSERT((data{1, 2}) == test_detail::default_impls::get_state(local_sender0{}, r)); + static_assert(std::same_as); + ASSERT((data{1, 2}) == test_detail::default_impls::get_state(local_sender1{}, r)); + static_assert(std::same_as); + ASSERT((data{1, 2}) == test_detail::default_impls::get_state(local_sender2{}, r)); + static_assert(std::same_as); + ASSERT((data{1, 2}) == test_detail::default_impls::get_state(local_sender3{}, r)); + static_assert(std::same_as); + ASSERT((data{1, 2}) == test_detail::default_impls::get_state(local_sender4{}, r)); static_assert(std::same_as); static_assert(std::same_as); } @@ -616,16 +616,16 @@ auto test_default_impls_start() -> void { template auto test_default_impls_complete(Impls) -> void { struct arg {}; - struct receiver { + struct local_receiver { bool& called; }; struct state {}; - bool called{false}; - auto non_tag = [](receiver&&, int) {}; - auto tag = [](receiver&& r, int, arg) { r.called = true; }; - receiver r{called}; - state s{}; + bool called{false}; + auto non_tag = [](local_receiver&&, int) {}; + auto tag = [](local_receiver&& r, int, arg) { r.called = true; }; + local_receiver r{called}; + state s{}; static_assert(not requires { Impls::complete(::std::integral_constant{}, s, r, non_tag, 0, arg{}); }); static_assert(requires { Impls::complete(::std::integral_constant{}, s, r, tag, 0, arg{}); }); @@ -645,39 +645,39 @@ auto test_default_impls() -> void { } auto test_impls_for() -> void { - struct tag { + struct local_tag { static auto name() { return "test_impls_for"; } }; - static_assert(std::derived_from, test_detail::default_impls>); + static_assert(std::derived_from, test_detail::default_impls>); } auto test_state_type() -> void { - struct tag { + struct local_tag { static auto name() { return "test_state_type"; } }; struct state {}; struct sender { - tag t; - state s; + local_tag t; + state s; }; - struct receiver {}; + struct local_receiver {}; - static_assert(std::same_as>); + static_assert(std::same_as>); } auto test_basic_state() -> void { - struct tag { + struct local_tag { static auto name() { return "test_basic_state"; } }; struct data {}; - struct sender { - tag t; - data d; + struct local_sender { + local_tag t; + data d; }; - struct receiver {}; + struct local_receiver {}; - test_detail::basic_state state(sender{}, receiver{}); + test_detail::basic_state state(local_sender{}, local_receiver{}); } auto test_indices_for() -> void { @@ -704,36 +704,37 @@ auto test_valid_specialization() -> void { auto test_env_type() -> void { using index = std::integral_constant; - struct tag { + struct local_tag { static auto name() { return "test_env_type"; } }; struct data {}; - struct env {}; - struct sender { - tag t; - data d; + struct local_env {}; + struct local_sender { + local_tag t; + data d; }; struct sender_with_env { - tag t; - data d; - auto get_env() const noexcept -> env { return {}; } + local_tag t; + data d; + auto get_env() const noexcept -> local_env { return {}; } }; - struct receiver {}; + struct local_receiver {}; struct receiver_with_env { - auto get_env() const noexcept -> env { return {}; } + auto get_env() const noexcept -> local_env { return {}; } }; - static_assert( - std::same_as, test_detail::env_type>); static_assert(std::same_as, - test_detail::env_type>); - static_assert(std::same_as, test_detail::env_type>); + test_detail::env_type>); + static_assert(std::same_as, + test_detail::env_type>); + static_assert( + std::same_as, test_detail::env_type>); } template auto test_basic_receiver() -> void { using index = std::integral_constant; - struct tag { + struct local_tag { static auto name() { return "test_basic_receiver"; } }; struct data {}; @@ -741,11 +742,11 @@ auto test_basic_receiver() -> void { int value{}; auto operator==(const err&) const -> bool = default; }; - struct sender { - tag t{}; - data d{}; + struct local_sender { + local_tag t{}; + data d{}; }; - struct receiver { + struct local_receiver { T value{}; err error{}; bool stopped{}; @@ -757,15 +758,16 @@ auto test_basic_receiver() -> void { struct unstoppable_receiver { T value; }; - using basic_receiver = test_detail::basic_receiver; + using basic_receiver = test_detail::basic_receiver; static_assert(test_std::receiver); - static_assert(std::same_as); - static_assert(std::same_as, typename basic_receiver::state_t>); + static_assert(std::same_as); + static_assert( + std::same_as, typename basic_receiver::state_t>); ASSERT(&basic_receiver::complete == &test_detail::default_impls::complete); { - test_detail::basic_state op(sender{}, receiver{}); - basic_receiver br{&op}; + test_detail::basic_state op(local_sender{}, local_receiver{}); + basic_receiver br{&op}; static_assert(not requires { test_std::set_value(std::move(br)); }); static_assert(not requires { test_std::set_value(std::move(br), 42, 1); }); static_assert(requires { test_std::set_value(std::move(br), 42); }); @@ -775,8 +777,8 @@ auto test_basic_receiver() -> void { ASSERT(op.receiver.value == 42); } { - test_detail::basic_state op(sender{}, receiver{}); - basic_receiver br{&op}; + test_detail::basic_state op(local_sender{}, local_receiver{}); + basic_receiver br{&op}; static_assert(not requires { test_std::set_error(std::move(br)); }); static_assert(not requires { test_std::set_error(std::move(br), 0); }); static_assert(requires { test_std::set_error(std::move(br), err{42}); }); @@ -786,8 +788,8 @@ auto test_basic_receiver() -> void { ASSERT(op.receiver.error == err{42}); } { - test_detail::basic_state op(sender{}, receiver{}); - basic_receiver br{&op}; + test_detail::basic_state op(local_sender{}, local_receiver{}); + basic_receiver br{&op}; static_assert(requires { test_std::set_stopped(std::move(br)); }); static_assert(noexcept(test_std::set_stopped(std::move(br)))); ASSERT(op.receiver.stopped == false); @@ -795,8 +797,8 @@ auto test_basic_receiver() -> void { ASSERT(op.receiver.stopped == true); } { - test_detail::basic_state op(sender{}, unstoppable_receiver{}); - test_detail::basic_receiver br{&op}; + test_detail::basic_state op(local_sender{}, unstoppable_receiver{}); + test_detail::basic_receiver br{&op}; static_assert(not requires { std::move(br).set_stopped(); }); } //-dk:TODO test basic_receiver::get_env @@ -815,7 +817,7 @@ auto test_completion_tag() -> void { auto test_product_type() -> void { struct nm { int value{}; - explicit nm(int value) : value(value) {} + explicit nm(int val) : value(val) {} nm(nm&&) = delete; nm(const nm&) = delete; ~nm() = default; @@ -995,7 +997,7 @@ auto test_basic_operation() -> void { auto test_completion_signatures_for() -> void { struct arg {}; - struct env {}; + struct local_env {}; struct bad_env {}; struct sender { using sender_concept = test_std::sender_t; @@ -1003,11 +1005,11 @@ auto test_completion_signatures_for() -> void { using env_sigs = test_std::completion_signatures; auto get_completion_signatures(const test_std::empty_env&) -> empty_env_sigs { return {}; } - auto get_completion_signatures(const env&) -> env_sigs { return {}; } + auto get_completion_signatures(const local_env&) -> env_sigs { return {}; } }; static_assert(test_std::sender_in); - static_assert(test_std::sender_in); + static_assert(test_std::sender_in); static_assert(not test_std::sender_in); #if 0 @@ -1017,7 +1019,7 @@ auto test_completion_signatures_for() -> void { sender::empty_env_sigs >); static_assert(std::same_as< - test_detail::completion_signatures_for, + test_detail::completion_signatures_for, sender::env_sigs >); #endif @@ -1059,7 +1061,7 @@ struct tuple_element { } // namespace std namespace { auto test_basic_sender() -> void { - struct env {}; + struct local_env {}; { auto&& [a, b, c] = tagged_sender{basic_sender_tag{}, data{}, sender0{}}; @@ -1071,13 +1073,13 @@ auto test_basic_sender() -> void { static_assert(test_std::sender); static_assert(test_std::sender_in); - static_assert(test_std::sender_in); + static_assert(test_std::sender_in); static_assert(test_std::operation_state>); static_assert(test_std::sender); static_assert(std::same_as>); static_assert( std::same_as); + decltype(test_std::transform_sender(test_std::default_domain{}, tagged_sender{}, local_env{}))>); using basic_sender = test_detail::basic_sender; static_assert(test_std::sender); @@ -1093,7 +1095,7 @@ auto test_basic_sender() -> void { static_assert(std::same_as>); static_assert( std::same_as); + decltype(test_std::transform_sender(test_std::default_domain{}, basic_sender{}, local_env{}))>); static_assert(test_std::sender_in); #if 0 //-dk:TODO restore completion_sigatures_for test diff --git a/tests/beman/execution26/exec-split.test.cpp b/tests/beman/execution26/exec-split.test.cpp index a3f1fdfa..a6a266e9 100644 --- a/tests/beman/execution26/exec-split.test.cpp +++ b/tests/beman/execution26/exec-split.test.cpp @@ -11,6 +11,8 @@ // ---------------------------------------------------------------------------- +namespace { + struct timed_scheduler_t : beman::execution26::scheduler_t {}; class some_thread_pool { @@ -140,10 +142,9 @@ template using to_set_value_t = type_list; void test_completion_sigs_and_sync_wait_on_split() { - auto just = beman::execution26::just(NonCopyable{}); - auto split = beman::execution26::split(std::move(just)); - using split_sender = std::decay_t; - struct empty_env {}; + auto just = beman::execution26::just(NonCopyable{}); + auto split = beman::execution26::split(std::move(just)); + using split_sender = std::decay_t; using expected_value_completions = type_list; using value_completions = beman::execution26::value_types_of_t; static_assert(std::same_as); @@ -171,6 +172,7 @@ void test_completion_from_another_thread() { auto split = beman::execution26::split(scheduler.schedule_after(1ms)); auto return_42 = beman::execution26::then(split, [] { return 42; }); auto result = beman::execution26::sync_wait(return_42); + ASSERT(scheduler == scheduler); // avoid a warning about the required op== being unused ASSERT(result.has_value()); if (result.has_value()) { auto [val] = *result; @@ -198,6 +200,7 @@ void test_multiple_completions_from_other_threads() { ASSERT(val2 == 42); } } +} // namespace TEST(exec_split) { test_destroy_unused_split(); diff --git a/tests/beman/execution26/exec-sync-wait.test.cpp b/tests/beman/execution26/exec-sync-wait.test.cpp index e36f8e6c..5a650b42 100644 --- a/tests/beman/execution26/exec-sync-wait.test.cpp +++ b/tests/beman/execution26/exec-sync-wait.test.cpp @@ -29,8 +29,9 @@ struct arg { int value{}; auto operator==(const arg&) const -> bool = default; }; -struct error { +struct error : std::exception { int value{}; + explicit error(int v) : value(v) {} }; struct sender { using sender_concept = test_std::sender_t; @@ -136,21 +137,21 @@ auto test_sync_wait_state() -> void { auto test_sync_wait_receiver() -> void { { - using sender = decltype(test_std::just(arg<0>{}, arg<1>{}, arg<2>{})); - test_detail::sync_wait_state state{}; + using local_sender = decltype(test_std::just(arg<0>{}, arg<1>{}, arg<2>{})); + test_detail::sync_wait_state state{}; ASSERT(not state.result); ASSERT(not state.error); - test_std::set_value(test_detail::sync_wait_receiver{&state}, arg<0>{2}, arg<1>{3}, arg<2>{5}); + test_std::set_value(test_detail::sync_wait_receiver{&state}, arg<0>{2}, arg<1>{3}, arg<2>{5}); ASSERT(state.result); ASSERT(not state.error); ASSERT(*state.result == (std::tuple{arg<0>{2}, arg<1>{3}, arg<2>{5}})); } { - using sender = decltype(test_std::just(arg<0>{}, arg<1>{}, arg<2>{})); - test_detail::sync_wait_state state{}; + using local_sender = decltype(test_std::just(arg<0>{}, arg<1>{}, arg<2>{})); + test_detail::sync_wait_state state{}; ASSERT(not state.result); ASSERT(not state.error); - test_std::set_error(test_detail::sync_wait_receiver{&state}, error{17}); + test_std::set_error(test_detail::sync_wait_receiver{&state}, error{17}); ASSERT(not state.result); ASSERT(state.error); try { @@ -163,11 +164,11 @@ auto test_sync_wait_receiver() -> void { } } { - using sender = decltype(test_std::just(arg<0>{}, arg<1>{}, arg<2>{})); - test_detail::sync_wait_state state{}; + using local_sender = decltype(test_std::just(arg<0>{}, arg<1>{}, arg<2>{})); + test_detail::sync_wait_state state{}; ASSERT(not state.result); ASSERT(not state.error); - test_std::set_error(test_detail::sync_wait_receiver{&state}, std::make_exception_ptr(error{17})); + test_std::set_error(test_detail::sync_wait_receiver{&state}, std::make_exception_ptr(error{17})); ASSERT(not state.result); ASSERT(state.error); try { @@ -180,11 +181,11 @@ auto test_sync_wait_receiver() -> void { } } { - using sender = decltype(test_std::just(arg<0>{}, arg<1>{}, arg<2>{})); - test_detail::sync_wait_state state{}; + using local_sender = decltype(test_std::just(arg<0>{}, arg<1>{}, arg<2>{})); + test_detail::sync_wait_state state{}; ASSERT(not state.result); ASSERT(not state.error); - test_std::set_stopped(test_detail::sync_wait_receiver{&state}); + test_std::set_stopped(test_detail::sync_wait_receiver{&state}); ASSERT(not state.result); ASSERT(not state.error); } diff --git a/tests/beman/execution26/exec-then.test.cpp b/tests/beman/execution26/exec-then.test.cpp index f088e286..6875fecf 100644 --- a/tests/beman/execution26/exec-then.test.cpp +++ b/tests/beman/execution26/exec-then.test.cpp @@ -187,11 +187,11 @@ struct allocator_fun { std::pmr::polymorphic_allocator<> alloc; std::byte* data{nullptr}; - explicit allocator_fun(std::pmr::polymorphic_allocator<> alloc) : alloc(alloc), data(alloc.allocate(1)) {} + explicit allocator_fun(std::pmr::polymorphic_allocator<> all) : alloc(all), data(alloc.allocate(1)) {} allocator_fun(const allocator_fun&, std::pmr::polymorphic_allocator<> = {}) {} allocator_fun(allocator_fun&& other) noexcept : alloc(other.alloc), data(std::exchange(other.data, nullptr)) {} - allocator_fun(allocator_fun&& other, std::pmr::polymorphic_allocator<> alloc) - : alloc(alloc), data(alloc == other.alloc ? std::exchange(other.data, nullptr) : alloc.allocate(1)) {} + allocator_fun(allocator_fun&& other, std::pmr::polymorphic_allocator<> all) + : alloc(all), data(alloc == other.alloc ? std::exchange(other.data, nullptr) : alloc.allocate(1)) {} ~allocator_fun() { if (this->data) this->alloc.deallocate(this->data, 1u); diff --git a/tests/beman/execution26/exec-when-all.test.cpp b/tests/beman/execution26/exec-when-all.test.cpp index 0bc0d872..d5709fb8 100644 --- a/tests/beman/execution26/exec-when-all.test.cpp +++ b/tests/beman/execution26/exec-when-all.test.cpp @@ -58,7 +58,7 @@ struct await_cancel { using operation_state_concept = test_std::operation_state_t; struct callback { Receiver* receiver; - explicit callback(Receiver* receiver) : receiver(receiver) {} + explicit callback(Receiver* rcvr) : receiver(rcvr) {} auto operator()() const noexcept -> void { test_std::set_stopped(std::move(*this->receiver)); } }; @@ -116,9 +116,9 @@ struct test_sender { std::remove_cvref_t receiver; decltype(test_std::connect(std::declval(), std::declval>())) inner_state; template - state(S&& sender, auto&& expect, R&& receiver) - : expect(expect), - receiver(std::forward(receiver)), + state(S&& sender, auto&& exp, R&& rcvr) + : expect(exp), + receiver(std::forward(rcvr)), inner_state(test_std::connect(std::forward(sender), upstream{this->expect, this->receiver})) {} auto start() & noexcept -> void { test_std::start(this->inner_state); } diff --git a/tests/beman/execution26/exec-with-awaitable-senders.test.cpp b/tests/beman/execution26/exec-with-awaitable-senders.test.cpp index 35438909..f98fa817 100644 --- a/tests/beman/execution26/exec-with-awaitable-senders.test.cpp +++ b/tests/beman/execution26/exec-with-awaitable-senders.test.cpp @@ -14,6 +14,7 @@ namespace exec = beman::execution26; +namespace { struct promise; struct awaitable { @@ -50,10 +51,10 @@ coroutine test_await_void() { co_await exec::just(); } void test_sync_wait_awaitable() { try { - auto [v] = exec::sync_wait(awaitable{}).value(); + auto [v] = exec::sync_wait(awaitable{}).value_or(std::tuple(0)); ASSERT(v == 1); } catch (...) { - ASSERT(false); + ASSERT_UNREACHABLE(); } } @@ -61,7 +62,7 @@ void test_sync_wait_void_awaitable() { try { ASSERT(exec::sync_wait(void_awaitable{})); } catch (...) { - ASSERT(false); + ASSERT_UNREACHABLE(); } } @@ -71,6 +72,8 @@ coroutine test_mix_awaitable_and_sender() { ASSERT(value == 1); } +} // namespace + TEST(exec_with_awaitable_senders) { test_await_tuple().resume(); test_await_void().resume(); diff --git a/tests/beman/execution26/include/test/execution.hpp b/tests/beman/execution26/include/test/execution.hpp index aa87ee3d..55d0c190 100644 --- a/tests/beman/execution26/include/test/execution.hpp +++ b/tests/beman/execution26/include/test/execution.hpp @@ -12,6 +12,7 @@ #include #define ASSERT(condition) assert(condition) +#define ASSERT_UNREACHABLE() assert(::test::unreachable_helper()) #define TEST(name) auto main() -> int namespace beman::execution26 {} @@ -20,6 +21,8 @@ namespace test_std = ::beman::execution26; namespace test_detail = ::beman::execution26::detail; namespace test { +inline bool unreachable_helper() { return false; } + template auto type_exists() {} template diff --git a/tests/beman/execution26/include/test/stop_token.hpp b/tests/beman/execution26/include/test/stop_token.hpp index 189496a1..6a126e7f 100644 --- a/tests/beman/execution26/include/test/stop_token.hpp +++ b/tests/beman/execution26/include/test/stop_token.hpp @@ -84,7 +84,7 @@ inline auto test::stop_callback(const Token& token, Stop stop) -> void { struct Callback { Data* data; - explicit Callback(Data* data) : data(data) {} + explicit Callback(Data* d) : data(d) {} auto operator()() { ++this->data->count; this->data->stop_requested = this->data->token.stop_requested(); @@ -124,7 +124,7 @@ auto test::stop_callback_dtor_deregisters(const Token& token, Stop stop) -> void struct Callback { bool* ptr; - explicit Callback(bool* ptr) : ptr(ptr) {} + explicit Callback(bool* p) : ptr(p) {} auto operator()() { *this->ptr = true; } }; @@ -166,7 +166,7 @@ inline auto test::stop_callback_dtor_other_thread(const Token& token, Stop stop) }; struct Callback { Data* data; - explicit Callback(Data* data) : data(data) {} + explicit Callback(Data* d) : data(d) {} auto operator()() -> void { using namespace ::std::chrono_literals; { @@ -221,7 +221,7 @@ inline auto test::stop_callback_dtor_same_thread(Token token, Stop stop) -> void }; struct Callback { ::std::unique_ptr* self; - explicit Callback(::std::unique_ptr* self) : self(self) {} + explicit Callback(::std::unique_ptr* s) : self(s) {} auto operator()() { this->self->reset(); } }; struct Object : Base {