diff --git a/.nojekyll b/.nojekyll new file mode 100644 index 00000000..e69de29b diff --git a/Makefile b/Makefile index 58e00b00..889a87fd 100644 --- a/Makefile +++ b/Makefile @@ -89,8 +89,12 @@ clang-tidy: build/$(SANITIZER)/compile_commands.json codespell: codespell -L statics,snd,copyable,cancelled -format: +format: cmake-format clang-format + +cmake-format: cmake-format -i `git diff --name-only main | egrep '(CMakeLists.txt|\.cmake)'` + +clang-format: git clang-format main todo: diff --git a/include/beman/execution26/detail/allocator_aware_move.hpp b/include/beman/execution26/detail/allocator_aware_move.hpp index d333880f..4bd2b94f 100644 --- a/include/beman/execution26/detail/allocator_aware_move.hpp +++ b/include/beman/execution26/detail/allocator_aware_move.hpp @@ -19,7 +19,7 @@ template * \headerfile beman/execution26/execution.hpp * \internal */ -auto allocator_aware_move(T&& obj, Context&& context) -> decltype(auto) { +auto allocator_aware_move(T&& obj, Context&& context) noexcept -> decltype(auto) { if constexpr (requires { ::beman::execution26::get_allocator(::beman::execution26::get_env(context)); }) { if constexpr (decltype(::beman::execution26::detail::is_product_type(obj))()) { return obj.make_from(::beman::execution26::get_allocator(::beman::execution26::get_env(context)), diff --git a/include/beman/execution26/detail/basic_operation.hpp b/include/beman/execution26/detail/basic_operation.hpp index a919ef1f..1921195c 100644 --- a/include/beman/execution26/detail/basic_operation.hpp +++ b/include/beman/execution26/detail/basic_operation.hpp @@ -38,8 +38,11 @@ template basic_operation(Sender&& sender, Receiver&& receiver) noexcept(true /*-dk:TODO*/) : ::beman::execution26::detail::basic_state(::std::forward(sender), ::std::move(receiver)), + // NOLINTBEGIN(bugprone-use-after-move,hicpp-invalid-access-moved) + //-dk:TODO deal with moving the sender twice inner_ops(::beman::execution26::detail::connect_all( this, ::std::forward(sender), ::beman::execution26::detail::indices_for())) {} + // NOLINTEND(bugprone-use-after-move,hicpp-invalid-access-moved) private: auto start() & noexcept -> void { diff --git a/include/beman/execution26/detail/basic_sender.hpp b/include/beman/execution26/detail/basic_sender.hpp index a05a5ce4..71776f3e 100644 --- a/include/beman/execution26/detail/basic_sender.hpp +++ b/include/beman/execution26/detail/basic_sender.hpp @@ -15,6 +15,8 @@ #include #include +#include + // ---------------------------------------------------------------------------- namespace beman::execution26::detail { @@ -37,10 +39,11 @@ struct basic_sender : ::beman::execution26::detail::product_type requires(not::beman::execution26::receiver) auto connect(Receiver receiver) = BEMAN_EXECUTION26_DELETE("the passed receiver doesn't model receiver"); + + private: #if __cpp_explicit_this_parameter < 202110L template <::beman::execution26::receiver Receiver> auto connect(Receiver receiver) & noexcept(true /*-dk:TODO*/) @@ -97,4 +100,6 @@ struct basic_sender : ::beman::execution26::detail::product_type + #endif diff --git a/include/beman/execution26/detail/emplace_from.hpp b/include/beman/execution26/detail/emplace_from.hpp index 006b2ee7..a7555ab1 100644 --- a/include/beman/execution26/detail/emplace_from.hpp +++ b/include/beman/execution26/detail/emplace_from.hpp @@ -17,7 +17,7 @@ struct emplace_from { using type = ::beman::execution26::detail::call_result_t; Fun fun; - constexpr operator type() && noexcept(::beman::execution26::detail::nothrow_callable) { + explicit constexpr operator type() && noexcept(::beman::execution26::detail::nothrow_callable) { return ::std::move(fun)(); } }; diff --git a/include/beman/execution26/detail/forward_like.hpp b/include/beman/execution26/detail/forward_like.hpp index b3297b6b..5b6c5edd 100644 --- a/include/beman/execution26/detail/forward_like.hpp +++ b/include/beman/execution26/detail/forward_like.hpp @@ -19,14 +19,14 @@ template struct forward_like_helper { template static auto forward(U&& u) -> ::std::remove_reference_t&& { - return ::std::move(u); + return ::std::move(u); // NOLINT(bugprone-move-forwarding-reference) } }; template struct forward_like_helper { template static auto forward(U&& u) -> ::std::remove_cvref_t&& { - return ::std::move(u); + return ::std::move(u); // NOLINT(bugprone-move-forwarding-reference) } }; template @@ -40,7 +40,7 @@ template struct forward_like_helper { template static auto forward(U&& u) -> const ::std::remove_cvref_t&& { - return ::std::move(u); + return ::std::move(u); // NOLINT(bugprone-move-forwarding-reference) } }; template diff --git a/include/beman/execution26/detail/fwd_env.hpp b/include/beman/execution26/detail/fwd_env.hpp index 8e324048..446f347e 100644 --- a/include/beman/execution26/detail/fwd_env.hpp +++ b/include/beman/execution26/detail/fwd_env.hpp @@ -9,6 +9,8 @@ #include #include +#include + // ---------------------------------------------------------------------------- namespace beman::execution26::detail { @@ -18,7 +20,7 @@ class fwd_env { Env env; public: - fwd_env(Env&& env) : env(::std::forward(env)) {} + explicit fwd_env(Env&& env) : env(::std::forward(env)) {} template requires(not::beman::execution26::forwarding_query(::std::remove_cvref_t())) @@ -39,4 +41,6 @@ fwd_env(Env&&) -> fwd_env; // ---------------------------------------------------------------------------- +#include + #endif diff --git a/include/beman/execution26/detail/get_allocator.hpp b/include/beman/execution26/detail/get_allocator.hpp index ff8c057e..53dd5114 100644 --- a/include/beman/execution26/detail/get_allocator.hpp +++ b/include/beman/execution26/detail/get_allocator.hpp @@ -10,6 +10,8 @@ #include #include +#include + // ---------------------------------------------------------------------------- namespace beman::execution26 { @@ -54,4 +56,6 @@ inline constexpr get_allocator_t get_allocator{}; // ---------------------------------------------------------------------------- +#include + #endif diff --git a/include/beman/execution26/detail/get_completion_scheduler.hpp b/include/beman/execution26/detail/get_completion_scheduler.hpp index ba44ea13..d1f3a3e4 100644 --- a/include/beman/execution26/detail/get_completion_scheduler.hpp +++ b/include/beman/execution26/detail/get_completion_scheduler.hpp @@ -18,6 +18,8 @@ #include #include +#include + // ---------------------------------------------------------------------------- namespace beman::execution26 { @@ -82,4 +84,6 @@ inline constexpr get_completion_scheduler_t get_completion_scheduler{}; // ---------------------------------------------------------------------------- +#include + #endif diff --git a/include/beman/execution26/detail/get_domain.hpp b/include/beman/execution26/detail/get_domain.hpp index 3e8fd4d0..42676b28 100644 --- a/include/beman/execution26/detail/get_domain.hpp +++ b/include/beman/execution26/detail/get_domain.hpp @@ -8,6 +8,8 @@ #include #include +#include + // ---------------------------------------------------------------------------- namespace beman::execution26 { @@ -40,4 +42,6 @@ inline constexpr get_domain_t get_domain{}; // ---------------------------------------------------------------------------- +#include + #endif diff --git a/include/beman/execution26/detail/immovable.hpp b/include/beman/execution26/detail/immovable.hpp new file mode 100644 index 00000000..3306d998 --- /dev/null +++ b/include/beman/execution26/detail/immovable.hpp @@ -0,0 +1,22 @@ +// include/beman/execution26/detail/immovable.hpp -*-C++-*- +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + +#ifndef INCLUDED_BEMAN_EXECUTION26_DETAIL_IMMOVABLE +#define INCLUDED_BEMAN_EXECUTION26_DETAIL_IMMOVABLE + +// ---------------------------------------------------------------------------- + +namespace beman::execution26::detail { +struct immovable { + constexpr immovable() = default; + immovable(immovable&&) = delete; + immovable(const immovable&) = delete; + ~immovable() = default; + auto operator=(immovable&&) -> immovable& = delete; + auto operator=(const immovable&) -> immovable& = delete; +}; +} // namespace beman::execution26::detail + +// ---------------------------------------------------------------------------- + +#endif diff --git a/include/beman/execution26/detail/inplace_stop_source.hpp b/include/beman/execution26/detail/inplace_stop_source.hpp index 48cf8ed8..6e34912a 100644 --- a/include/beman/execution26/detail/inplace_stop_source.hpp +++ b/include/beman/execution26/detail/inplace_stop_source.hpp @@ -40,7 +40,7 @@ class beman::execution26::inplace_stop_token { friend class ::beman::execution26::inplace_stop_source; template friend class ::beman::execution26::inplace_stop_callback; - inplace_stop_token(::beman::execution26::inplace_stop_source* source) : source(source) {} + explicit inplace_stop_token(::beman::execution26::inplace_stop_source* source) : source(source) {} ::beman::execution26::inplace_stop_source* source{}; }; @@ -83,12 +83,15 @@ class beman::execution26::inplace_stop_callback final template 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() { if (this->source) { this->source->deregister(this); } } + auto operator=(const inplace_stop_callback&) -> inplace_stop_callback& = delete; + auto operator=(inplace_stop_callback&&) -> inplace_stop_callback& = delete; private: auto call() -> void override; diff --git a/include/beman/execution26/detail/notify.hpp b/include/beman/execution26/detail/notify.hpp index 87efd33d..f3f60f67 100644 --- a/include/beman/execution26/detail/notify.hpp +++ b/include/beman/execution26/detail/notify.hpp @@ -5,20 +5,16 @@ #define INCLUDED_BEMAN_EXECUTION26_DETAIL_NOTIFY #include +#include #include #include -#include //-dk:TODO remove -#include //-dk:TODO remove // ---------------------------------------------------------------------------- namespace beman::execution26::detail { struct notify_t; -class notifier { +class notifier : ::beman::execution26::detail::immovable { public: - notifier() = default; - notifier(notifier&&) = delete; - auto complete() -> void { ::std::unique_lock kerberos(this->lock); this->completed = true; diff --git a/include/beman/execution26/detail/operation_state_task.hpp b/include/beman/execution26/detail/operation_state_task.hpp index ca8d58f1..85e115e1 100644 --- a/include/beman/execution26/detail/operation_state_task.hpp +++ b/include/beman/execution26/detail/operation_state_task.hpp @@ -57,11 +57,14 @@ struct beman::execution26::detail::operation_state_task { using promise_type = ::beman::execution26::detail::connect_awaitable_promise; explicit operation_state_task(::std::coroutine_handle<> handle) noexcept : handle(handle) {} + operation_state_task(const operation_state_task&) = delete; operation_state_task(operation_state_task&& other) noexcept : handle(::std::exchange(other.handle, {})) {} ~operation_state_task() { if (this->handle) this->handle.destroy(); } + auto operator=(operation_state_task&&) -> operation_state_task& = delete; + auto operator=(const operation_state_task&) -> operation_state_task& = delete; auto start() & noexcept -> void { this->handle.resume(); } diff --git a/include/beman/execution26/detail/product_type.hpp b/include/beman/execution26/detail/product_type.hpp index b0ff01d6..0a5783f1 100644 --- a/include/beman/execution26/detail/product_type.hpp +++ b/include/beman/execution26/detail/product_type.hpp @@ -75,7 +75,7 @@ struct product_type : ::beman::execution26::detail::product_type_base<::std::ind template static auto make_from(Allocator&& allocator, Product&& product) -> product_type { - return std::forward(product).make_from( + return product_type::make_from( ::std::forward(allocator), ::std::forward(product), ::std::index_sequence_for{}); } diff --git a/include/beman/execution26/detail/run_loop.hpp b/include/beman/execution26/detail/run_loop.hpp index 61da1240..eb9ac049 100644 --- a/include/beman/execution26/detail/run_loop.hpp +++ b/include/beman/execution26/detail/run_loop.hpp @@ -8,6 +8,7 @@ #include #include #include +#include #include #include #include @@ -36,7 +37,7 @@ class run_loop { return {this->loop}; } }; - struct opstate_base { + struct opstate_base : ::beman::execution26::detail::immovable { opstate_base* next{}; virtual auto execute() noexcept -> void = 0; }; @@ -49,7 +50,6 @@ class run_loop { template opstate(run_loop* loop, R&& receiver) : loop(loop), receiver(::std::forward(receiver)) {} - opstate(opstate&&) = delete; auto start() & noexcept -> void { try { this->loop->push_back(this); @@ -88,7 +88,7 @@ class run_loop { auto operator==(const scheduler&) const -> bool = default; }; - enum class state { starting, running, finishing }; + enum class state : unsigned char { starting, running, finishing }; state current_state{state::starting}; ::std::mutex mutex{}; @@ -115,12 +115,15 @@ class run_loop { public: run_loop() noexcept = default; + run_loop(const run_loop&) = delete; run_loop(run_loop&&) = delete; ~run_loop() { ::std::lock_guard guard(this->mutex); if (this->front != nullptr || this->current_state == state::running) ::std::terminate(); } + auto operator=(const run_loop&) -> run_loop& = delete; + auto operator=(run_loop&&) -> run_loop& = delete; auto get_scheduler() -> scheduler { return {this}; } diff --git a/include/beman/execution26/detail/sched_attrs.hpp b/include/beman/execution26/detail/sched_attrs.hpp index 5717deae..ef650152 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 - sched_attrs(S&& sched) : sched(::std::forward(sched)) {} + explicit sched_attrs(S sched) : sched(::std::move(sched)) {} template auto query(const ::beman::execution26::get_completion_scheduler_t&) const noexcept { diff --git a/include/beman/execution26/detail/sched_env.hpp b/include/beman/execution26/detail/sched_env.hpp index 122f1d7e..00594c8d 100644 --- a/include/beman/execution26/detail/sched_env.hpp +++ b/include/beman/execution26/detail/sched_env.hpp @@ -20,7 +20,7 @@ class sched_env { public: template - explicit sched_env(S&& sch) : sched(::std::forward(sch)) {} + explicit sched_env(S sch) : sched(::std::move(sch)) {} auto query(const ::beman::execution26::get_scheduler_t&) const noexcept { return this->sched; } auto query(const ::beman::execution26::get_domain_t& q) const noexcept { diff --git a/include/beman/execution26/detail/schedule.hpp b/include/beman/execution26/detail/schedule.hpp index c45ab307..308c0fbc 100644 --- a/include/beman/execution26/detail/schedule.hpp +++ b/include/beman/execution26/detail/schedule.hpp @@ -8,6 +8,8 @@ #include #include +#include + // ---------------------------------------------------------------------------- namespace beman::execution26 { @@ -33,4 +35,6 @@ inline constexpr ::beman::execution26::schedule_t schedule{}; // ---------------------------------------------------------------------------- +#include + #endif diff --git a/include/beman/execution26/detail/sender_adaptor_closure.hpp b/include/beman/execution26/detail/sender_adaptor_closure.hpp index adfe1579..53945dc2 100644 --- a/include/beman/execution26/detail/sender_adaptor_closure.hpp +++ b/include/beman/execution26/detail/sender_adaptor_closure.hpp @@ -16,8 +16,10 @@ struct sender_adaptor_closure_base {}; } // namespace beman::execution26::detail::pipeable namespace beman::execution26 { +// NOLINTBEGIN(bugprone-crtp-constructor-accessibility) template struct sender_adaptor_closure : ::beman::execution26::detail::pipeable::sender_adaptor_closure_base {}; +// NOLINTEND(bugprone-crtp-constructor-accessibility) } // namespace beman::execution26 namespace beman::execution26::detail::pipeable { diff --git a/include/beman/execution26/detail/sender_decompose.hpp b/include/beman/execution26/detail/sender_decompose.hpp index 2a09fe53..d8915f54 100644 --- a/include/beman/execution26/detail/sender_decompose.hpp +++ b/include/beman/execution26/detail/sender_decompose.hpp @@ -13,7 +13,7 @@ namespace beman::execution26::detail { struct sender_convert_to_any_t { template - constexpr operator T() const; + constexpr operator T() const; // NOLINT(hicpp-explicit-conversions) }; template diff --git a/include/beman/execution26/detail/set_error.hpp b/include/beman/execution26/detail/set_error.hpp index 8e2a023f..22766d2a 100644 --- a/include/beman/execution26/detail/set_error.hpp +++ b/include/beman/execution26/detail/set_error.hpp @@ -7,6 +7,8 @@ #include #include +#include + // ---------------------------------------------------------------------------- namespace beman::execution26 { @@ -47,4 +49,6 @@ inline constexpr set_error_t set_error{}; // ---------------------------------------------------------------------------- +#include + #endif diff --git a/include/beman/execution26/detail/set_stopped.hpp b/include/beman/execution26/detail/set_stopped.hpp index a80ccbe0..bad82b2c 100644 --- a/include/beman/execution26/detail/set_stopped.hpp +++ b/include/beman/execution26/detail/set_stopped.hpp @@ -7,6 +7,8 @@ #include #include +#include + // ---------------------------------------------------------------------------- namespace beman::execution26 { @@ -45,4 +47,6 @@ inline constexpr set_stopped_t set_stopped{}; // ---------------------------------------------------------------------------- +#include + #endif diff --git a/include/beman/execution26/detail/set_value.hpp b/include/beman/execution26/detail/set_value.hpp index a0e1a74a..13e876d1 100644 --- a/include/beman/execution26/detail/set_value.hpp +++ b/include/beman/execution26/detail/set_value.hpp @@ -7,6 +7,8 @@ #include #include +#include + // ---------------------------------------------------------------------------- namespace beman::execution26 { @@ -47,4 +49,6 @@ inline constexpr set_value_t set_value{}; // ---------------------------------------------------------------------------- +#include + #endif diff --git a/include/beman/execution26/detail/simple_counting_scope.hpp b/include/beman/execution26/detail/simple_counting_scope.hpp index e683fad9..4f8e7673 100644 --- a/include/beman/execution26/detail/simple_counting_scope.hpp +++ b/include/beman/execution26/detail/simple_counting_scope.hpp @@ -6,6 +6,7 @@ #include #include +#include #include #include #include @@ -19,15 +20,11 @@ class simple_counting_scope; // ---------------------------------------------------------------------------- -class beman::execution26::simple_counting_scope { +class beman::execution26::simple_counting_scope : ::beman::execution26::detail::immovable { public: class token; class assoc; - simple_counting_scope() = default; - simple_counting_scope(simple_counting_scope&&) = delete; - ~simple_counting_scope() = default; - auto get_token() noexcept -> token; auto close() noexcept -> void { switch (this->state) { @@ -60,7 +57,15 @@ class beman::execution26::simple_counting_scope { } private: - enum class state_t { unused, open, open_and_joining, closed, closed_and_joining, unused_and_closed, joined }; + enum class state_t : unsigned char { + unused, + open, + open_and_joining, + closed, + closed_and_joining, + unused_and_closed, + joined + }; friend class assoc; auto try_associate() noexcept -> simple_counting_scope* { ::std::lock_guard lock(this->mutex); @@ -92,6 +97,7 @@ class beman::execution26::simple_counting_scope { // ---------------------------------------------------------------------------- +// NOLINTBEGIN(misc-unconventional-assign-operator,hicpp-special-member-functions) class beman::execution26::simple_counting_scope::assoc { public: assoc() = default; @@ -102,7 +108,7 @@ class beman::execution26::simple_counting_scope::assoc { this->scope->disassociate(); } - auto operator=(assoc other) noexcept -> assoc { + auto operator=(assoc other) noexcept -> assoc& { ::std::swap(this->scope, other.scope); return *this; } @@ -115,6 +121,7 @@ class beman::execution26::simple_counting_scope::assoc { : scope(scope ? scope->try_associate() : nullptr) {} beman::execution26::simple_counting_scope* scope{}; }; +// NOLINTEND(misc-unconventional-assign-operator,hicpp-special-member-functions) // ---------------------------------------------------------------------------- diff --git a/include/beman/execution26/detail/start.hpp b/include/beman/execution26/detail/start.hpp index 7be626e9..455aff1e 100644 --- a/include/beman/execution26/detail/start.hpp +++ b/include/beman/execution26/detail/start.hpp @@ -6,6 +6,8 @@ #include +#include + // ---------------------------------------------------------------------------- namespace beman::execution26 { @@ -45,4 +47,6 @@ inline constexpr start_t start{}; // ---------------------------------------------------------------------------- +#include + #endif diff --git a/include/beman/execution26/detail/starts_on.hpp b/include/beman/execution26/detail/starts_on.hpp index 4564c83c..7b70fc1e 100644 --- a/include/beman/execution26/detail/starts_on.hpp +++ b/include/beman/execution26/detail/starts_on.hpp @@ -43,9 +43,8 @@ struct starts_on_t { template <::beman::execution26::scheduler Scheduler, ::beman::execution26::sender Sender> auto operator()(Scheduler&& scheduler, Sender&& sender) const { - auto domain{::beman::execution26::detail::query_with_default(::beman::execution26::get_domain, - ::std::forward(scheduler), - ::beman::execution26::default_domain{})}; + auto domain{::beman::execution26::detail::query_with_default( + ::beman::execution26::get_domain, scheduler, ::beman::execution26::default_domain{})}; return ::beman::execution26::transform_sender( domain, ::beman::execution26::detail::make_sender( diff --git a/include/beman/execution26/detail/stop_source.hpp b/include/beman/execution26/detail/stop_source.hpp index 99a2ae62..0e98a252 100644 --- a/include/beman/execution26/detail/stop_source.hpp +++ b/include/beman/execution26/detail/stop_source.hpp @@ -49,10 +49,14 @@ struct beman::execution26::detail::stop_callback_base { virtual auto do_call() -> void = 0; protected: - stop_callback_base(const ::beman::execution26::stop_token&); + explicit stop_callback_base(const ::beman::execution26::stop_token&); ~stop_callback_base(); public: + stop_callback_base(stop_callback_base&&) = delete; + stop_callback_base(const stop_callback_base&) = delete; + auto operator=(stop_callback_base&&) -> stop_callback_base& = delete; + auto operator=(const stop_callback_base&) -> stop_callback_base& = delete; auto call() -> void; auto setup() -> void; auto deregister() -> void; @@ -75,7 +79,9 @@ class beman::execution26::stop_source { stop_source(); explicit stop_source(::beman::execution26::nostopstate_t) noexcept; stop_source(const stop_source&); + stop_source(stop_source&&) = default; auto operator=(const stop_source&) -> stop_source&; + auto operator=(stop_source&&) -> stop_source& = default; ~stop_source(); auto swap(stop_source&) noexcept -> void; @@ -93,7 +99,7 @@ class beman::execution26::stop_token { friend ::beman::execution26::detail::stop_callback_base; ::std::shared_ptr<::beman::execution26::detail::stop_state> state; - stop_token(::std::shared_ptr<::beman::execution26::detail::stop_state>); + explicit stop_token(::std::shared_ptr<::beman::execution26::detail::stop_state>); public: template @@ -137,8 +143,11 @@ class beman::execution26::stop_callback final : private CallbackFun, beman::exec : CallbackFun(::std::forward(init)), stop_callback_base(::std::move(token)) { this->setup(); } - ~stop_callback() { this->deregister(); } + stop_callback(const stop_callback&) = delete; stop_callback(stop_callback&&) = delete; + ~stop_callback() { this->deregister(); } + auto operator=(stop_callback&&) -> stop_callback& = delete; + auto operator=(const stop_callback&) -> stop_callback& = delete; }; // ---------------------------------------------------------------------------- @@ -207,9 +216,7 @@ inline beman::execution26::stop_source::stop_source(const stop_source& other) : } inline auto beman::execution26::stop_source::operator=(const stop_source& other) -> stop_source& { - --this->state->sources; - this->state = other.state; - ++this->state->sources; + stop_source(other).swap(*this); return *this; } diff --git a/include/beman/execution26/detail/suppress_push.hpp b/include/beman/execution26/detail/suppress_push.hpp index a5e1c656..834ea078 100644 --- a/include/beman/execution26/detail/suppress_push.hpp +++ b/include/beman/execution26/detail/suppress_push.hpp @@ -14,4 +14,5 @@ #define BEMAN_EXECUTION26_DIAGNOSTIC_PUSHED #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wmissing-braces" +#pragma clang diagnostic ignored "-Wc++26-extensions" #endif \ No newline at end of file diff --git a/include/beman/execution26/detail/when_all.hpp b/include/beman/execution26/detail/when_all.hpp index c35d0a70..2e072265 100644 --- a/include/beman/execution26/detail/when_all.hpp +++ b/include/beman/execution26/detail/when_all.hpp @@ -91,7 +91,7 @@ struct impls_for<::beman::execution26::detail::when_all_t> : ::beman::execution2 ::beman::execution26::get_env(receiver)); }}; - enum class disposition { started, error, stopped }; + enum class disposition : unsigned char { started, error, stopped }; template struct state_type { diff --git a/src/beman/execution26/CMakeLists.txt b/src/beman/execution26/CMakeLists.txt index 79d6960c..bcc11722 100644 --- a/src/beman/execution26/CMakeLists.txt +++ b/src/beman/execution26/CMakeLists.txt @@ -86,6 +86,7 @@ target_sources( ${PROJECT_SOURCE_DIR}/include/beman/execution26/detail/get_stop_token.hpp ${PROJECT_SOURCE_DIR}/include/beman/execution26/detail/has_as_awaitable.hpp ${PROJECT_SOURCE_DIR}/include/beman/execution26/detail/has_completions.hpp + ${PROJECT_SOURCE_DIR}/include/beman/execution26/detail/immovable.hpp ${PROJECT_SOURCE_DIR}/include/beman/execution26/detail/impls_for.hpp ${PROJECT_SOURCE_DIR}/include/beman/execution26/detail/indices_for.hpp ${PROJECT_SOURCE_DIR}/include/beman/execution26/detail/indirect_meta_apply.hpp @@ -128,6 +129,7 @@ target_sources( ${PROJECT_SOURCE_DIR}/include/beman/execution26/detail/schedule_from.hpp ${PROJECT_SOURCE_DIR}/include/beman/execution26/detail/schedule_result_t.hpp ${PROJECT_SOURCE_DIR}/include/beman/execution26/detail/scheduler.hpp + ${PROJECT_SOURCE_DIR}/include/beman/execution26/detail/scheduler_t.hpp ${PROJECT_SOURCE_DIR}/include/beman/execution26/detail/sender.hpp ${PROJECT_SOURCE_DIR}/include/beman/execution26/detail/sender_adaptor.hpp ${PROJECT_SOURCE_DIR}/include/beman/execution26/detail/sender_adaptor_closure.hpp diff --git a/tests/beman/execution26/allocator-requirements-general.test.cpp b/tests/beman/execution26/allocator-requirements-general.test.cpp index 6443099a..9a7a026a 100644 --- a/tests/beman/execution26/allocator-requirements-general.test.cpp +++ b/tests/beman/execution26/allocator-requirements-general.test.cpp @@ -65,7 +65,12 @@ struct deallocate_size_type_mismatch { struct not_copy_constructible { using value_type = int; - not_copy_constructible(const not_copy_constructible&) = delete; + not_copy_constructible() = default; + not_copy_constructible(not_copy_constructible&&) = delete; + not_copy_constructible(const not_copy_constructible&) = delete; + ~not_copy_constructible() = default; + auto operator=(not_copy_constructible&&) -> not_copy_constructible = delete; + auto operator=(const not_copy_constructible&) -> not_copy_constructible = delete; auto allocate(::std::size_t n) -> int* { return new int[n]; } auto deallocate(/*long*/ int*, ::std::size_t) -> void {} diff --git a/tests/beman/execution26/exec-awaitable.test.cpp b/tests/beman/execution26/exec-awaitable.test.cpp index 4fb28a6a..17692050 100644 --- a/tests/beman/execution26/exec-awaitable.test.cpp +++ b/tests/beman/execution26/exec-awaitable.test.cpp @@ -147,6 +147,7 @@ auto test_with_await_transform() -> void { static_assert(noexcept(promise.await_transform(with_as_awaitable, true>{}))); static_assert(not noexcept(promise.await_transform(with_as_awaitable, false>{}))); auto a2{promise.await_transform(with_as_awaitable>{})}; + test::use(a2); static_assert(std::same_as, decltype(a2)>); } diff --git a/tests/beman/execution26/exec-connect.test.cpp b/tests/beman/execution26/exec-connect.test.cpp index a936d2e0..4b23ec1b 100644 --- a/tests/beman/execution26/exec-connect.test.cpp +++ b/tests/beman/execution26/exec-connect.test.cpp @@ -14,7 +14,7 @@ // ---------------------------------------------------------------------------- namespace { -enum class kind { plain, domain }; +enum class kind : unsigned char { plain, domain }; template struct state { using operation_state_concept = test_std::operation_state_t; @@ -23,7 +23,11 @@ struct state { template state(int value, R&& r) : value(value), receiver(std::forward(r)) {} + state(const state&) = delete; state(state&&) = delete; + ~state() = default; + auto operator=(const state&) -> state& = delete; + auto operator=(state&&) -> state& = delete; auto start() noexcept -> void {} }; @@ -41,8 +45,12 @@ struct rvalue_sender { using sender_concept = test_std::sender_t; int value{}; - rvalue_sender(int value) : value(value) {} + explicit rvalue_sender(int value) : value(value) {} + rvalue_sender(const rvalue_sender&) = delete; rvalue_sender(rvalue_sender&&) = default; + auto operator=(const rvalue_sender&) -> rvalue_sender& = delete; + auto operator=(rvalue_sender&&) -> rvalue_sender& = default; + ~rvalue_sender() = default; template auto connect(Receiver&& receiver) && -> state { @@ -59,8 +67,13 @@ struct receiver { int value{}; bool* set_stopped_called{}; - receiver(int value, bool* set_stopped_called = {}) : value(value), set_stopped_called(set_stopped_called) {} + explicit receiver(int value, bool* set_stopped_called = {}) + : value(value), set_stopped_called(set_stopped_called) {} receiver(receiver&&) = default; + receiver(const receiver&) = delete; + ~receiver() = default; + auto operator=(receiver&&) -> receiver& = default; + auto operator=(const receiver&) -> receiver& = delete; auto operator==(const receiver&) const -> bool = default; auto get_env() const noexcept -> env { return {this->value + 2}; } @@ -91,8 +104,13 @@ struct domain_receiver { using receiver_concept = test_std::receiver_t; int value{}; - domain_receiver(int value) : value(value) {} + explicit domain_receiver(int value) : value(value) {} domain_receiver(domain_receiver&&) = default; + domain_receiver(const domain_receiver&) = delete; + ~domain_receiver() = default; + auto operator=(domain_receiver&&) -> domain_receiver& = default; + auto operator=(const domain_receiver&) -> domain_receiver& = delete; + auto operator==(const domain_receiver&) const -> bool = default; auto get_env() const noexcept -> domain_env { return {}; } @@ -217,12 +235,13 @@ auto test_connect_awaitable() -> void { this->iv = value; this->bv = true; } - auto set_error(::std::exception_ptr error) && noexcept -> void { + auto set_error(const ::std::exception_ptr& error) && noexcept -> void { try { std::rethrow_exception(error); } catch (const std::runtime_error&) { this->bv = true; } catch (...) { + this->bv = false; } } auto set_stopped() && noexcept -> void {} @@ -240,6 +259,7 @@ auto test_connect_awaitable() -> void { ASSERT(handle != std::coroutine_handle<>()); ASSERT(iv == 0 && bv == false); result = 42; + test::use(result); handle.resume(); ASSERT(iv == 42 && bv == true); } @@ -255,6 +275,7 @@ auto test_connect_awaitable() -> void { ASSERT(handle != std::coroutine_handle<>()); ASSERT(iv == 0 && bv == false); result = 0; + test::use(result); handle.resume(); ASSERT(iv == 0 && bv == true); } @@ -285,7 +306,7 @@ auto test_connect_with_awaiter() -> void { using receiver_concept = test_std::receiver_t; bool& result; auto set_value(int i) && noexcept -> void { this->result = i == 17; } - auto set_error(std::exception_ptr) && noexcept -> void {} + auto set_error(const std::exception_ptr&) && noexcept -> void {} auto set_stopped() && noexcept -> void {} }; diff --git a/tests/beman/execution26/exec-general.test.cpp b/tests/beman/execution26/exec-general.test.cpp index 277f9da3..891f652f 100644 --- a/tests/beman/execution26/exec-general.test.cpp +++ b/tests/beman/execution26/exec-general.test.cpp @@ -29,8 +29,8 @@ auto test_movable_value() -> void { static_assert(not test_detail::movable_value); static_assert(not test_detail::movable_value); - static_assert(not test_detail::movable_value); - static_assert(not test_detail::movable_value); + static_assert(not test_detail::movable_value); // NOLINT(hicpp-avoid-c-arrays) + static_assert(not test_detail::movable_value); // NOLINT(hicpp-avoid-c-arrays) } auto test_matching_sig() -> void { diff --git a/tests/beman/execution26/exec-get-domain.test.cpp b/tests/beman/execution26/exec-get-domain.test.cpp index 26b7fa9f..f9c2738a 100644 --- a/tests/beman/execution26/exec-get-domain.test.cpp +++ b/tests/beman/execution26/exec-get-domain.test.cpp @@ -51,6 +51,5 @@ TEST(exec_get_domain) { test_get_domain(has_get_domain{42}); test_get_domain(overloaded_get_domain{}); - ASSERT(42 == test_std::get_domain(has_get_domain{42}).value); static_assert(42 == test_std::get_domain(has_get_domain{42}).value); } diff --git a/tests/beman/execution26/exec-get-env.test.cpp b/tests/beman/execution26/exec-get-env.test.cpp index a32400a6..f6093249 100644 --- a/tests/beman/execution26/exec-get-env.test.cpp +++ b/tests/beman/execution26/exec-get-env.test.cpp @@ -13,6 +13,8 @@ struct with_non_env; struct non_env { private: friend struct with_non_env; + non_env() = default; + non_env(non_env&&) = delete; ~non_env() = default; }; struct with_non_env { @@ -42,10 +44,13 @@ TEST(exec_get_env) { static_assert(std::same_as); auto e0 = test_std::get_env(0); + test::use(e0); static_assert(std::same_as); auto e1 = test_std::get_env(non_const{}); + test::use(e1); static_assert(std::same_as); auto e2 = test_std::get_env(normal{}); + test::use(e2); static_assert(std::same_as); //-dk:TODO add negative compilation test: auto e3 = test_std::get_env(normal{}); //-dk:TODO add negative compilation test: auto e4 = test_std::get_env(with_non_env{}); diff --git a/tests/beman/execution26/exec-into-variant.test.cpp b/tests/beman/execution26/exec-into-variant.test.cpp index 4a1bd542..c62ffd6d 100644 --- a/tests/beman/execution26/exec-into-variant.test.cpp +++ b/tests/beman/execution26/exec-into-variant.test.cpp @@ -79,7 +79,7 @@ struct error_receiver { bool* called{}; auto set_error(int e) && noexcept -> void { *this->called = e == 17; } - auto set_error(std::exception_ptr) && noexcept -> void {} + auto set_error(const std::exception_ptr&) && noexcept -> void {} auto set_stopped() && noexcept -> void {} auto set_value(auto&&...) && noexcept -> void {} }; @@ -97,7 +97,7 @@ struct stopped_receiver { bool* called{}; - auto set_error(std::exception_ptr) && noexcept -> void {} + auto set_error(const std::exception_ptr&) && noexcept -> void {} auto set_stopped() && noexcept -> void { *this->called = true; } auto set_value(auto&&...) && noexcept -> void {} }; diff --git a/tests/beman/execution26/exec-just.test.cpp b/tests/beman/execution26/exec-just.test.cpp index 3a76d202..e7d635c4 100644 --- a/tests/beman/execution26/exec-just.test.cpp +++ b/tests/beman/execution26/exec-just.test.cpp @@ -196,11 +196,17 @@ auto test_just_allocator() -> void { } // namespace TEST(exec_just) { - test_just_constraints(); - test_just(); - test_just_allocator(); + using type = test_detail:: call_result_t; static_assert(std::same_as, type>); + try { + test_just_constraints(); + test_just(); + test_just_allocator(); + } catch (...) { + ASSERT(nullptr == + "the just tests shouldn't throw"); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) + } } diff --git a/tests/beman/execution26/exec-let.test.cpp b/tests/beman/execution26/exec-let.test.cpp index f789932c..6d890357 100644 --- a/tests/beman/execution26/exec-let.test.cpp +++ b/tests/beman/execution26/exec-let.test.cpp @@ -6,6 +6,7 @@ #include #include #include +#include #include #include #include @@ -70,7 +71,7 @@ auto test_let_value() { template struct inline_resource : std::pmr::memory_resource { - std::byte buffer[Size]; + std::array buffer; std::byte* next{+this->buffer}; void* do_allocate(std::size_t size, std::size_t) override { @@ -90,7 +91,7 @@ namespace ex = test_std; struct fun { std::pmr::polymorphic_allocator<> allocator{}; fun() {} - fun(std::pmr::polymorphic_allocator<> allocator) : allocator(allocator) {} + explicit fun(std::pmr::polymorphic_allocator<> allocator) : allocator(allocator) {} auto operator()(std::span s) noexcept { return ex::just(std::pmr::vector(s.begin(), s.end(), this->allocator)); } @@ -102,7 +103,7 @@ auto test_let_value_allocator() -> void { static_assert(test_std::sender); static_assert(test_std::sender_in); // static_assert(std::same_as); - ex::sync_wait(std::move(s)); + ex::sync_wait(s); } } // namespace @@ -113,8 +114,14 @@ TEST(exec_let) { static_assert(std::same_as); static_assert(std::same_as); - test_let_value(); - test_let_value_allocator(); + try { + test_let_value(); + test_let_value_allocator(); + } catch (...) { + // NOLINTBEGIN(cert-dcl03-c,hicpp-static-assert,misc-static-assert) + ASSERT(nullptr == "let tests are not expected to throw"); + // NOLINTEND(cert-dcl03-c,hicpp-static-assert,misc-static-assert) + } return EXIT_SUCCESS; } diff --git a/tests/beman/execution26/exec-opstate-start.test.cpp b/tests/beman/execution26/exec-opstate-start.test.cpp index 74599bac..84d6211e 100644 --- a/tests/beman/execution26/exec-opstate-start.test.cpp +++ b/tests/beman/execution26/exec-opstate-start.test.cpp @@ -11,7 +11,7 @@ namespace { struct receiver { int value{}; - auto set_value(int value) noexcept -> void { this->value = value; } + auto set_value(int value) && noexcept -> void { this->value = value; } }; struct non_opstate {}; @@ -19,7 +19,7 @@ struct non_opstate {}; template struct opstate { receiver* rcvr; - auto start() const noexcept(Noexcept) -> void { test_std::set_value(std::move(*rcvr), 42); } + auto start() const noexcept(Noexcept) -> void { test_std::set_value(::std::move(*rcvr), 42); } }; template @@ -39,18 +39,18 @@ auto test_start_argument_type() { template auto test_start_member() { - State state; + State state{}; static_assert(not requires { test_std::start(state); }); - State cstate; + State cstate{}; static_assert(not requires { test_std::start(cstate); }); } template auto test_start_noexcept() { - State state; - static_assert(not requires { test_std::start(state); }); - State cstate; - static_assert(not requires { test_std::start(cstate); }); + State state{}; + static_assert(noexcept(state)); + State cstate{}; + static_assert(noexcept(cstate)); } template diff --git a/tests/beman/execution26/exec-read-env.test.cpp b/tests/beman/execution26/exec-read-env.test.cpp index 56f76718..d4476657 100644 --- a/tests/beman/execution26/exec-read-env.test.cpp +++ b/tests/beman/execution26/exec-read-env.test.cpp @@ -36,7 +36,11 @@ struct receiver { ASSERT(d == domain{this->value}); *this->called = true; } - auto set_error(auto&&) && noexcept -> void { ASSERT(nullptr == "error function was incorrectly called"); } + auto set_error(auto&&) && noexcept -> void { + // NOLINTBEGIN(cert-dcl03-c,hicpp-static-assert,misc-static-assert) + ASSERT(nullptr == "error function was incorrectly called"); + // NOLINTEND(cert-dcl03-c,hicpp-static-assert,misc-static-assert) + } auto get_env() const noexcept -> env { return {this->value}; } }; @@ -45,6 +49,7 @@ auto test_read_env() -> void { ASSERT(domain{17} == test_std::get_domain(env{17})); ASSERT(domain{17} == test_std::get_domain(test_std::get_env(receiver{17}))); auto sender{test_std::read_env(test_std::get_domain)}; + test::use(sender); static_assert(test_std::sender); static_assert(test_std::sender_in); static_assert( diff --git a/tests/beman/execution26/exec-recv.test.cpp b/tests/beman/execution26/exec-recv.test.cpp index 951c900e..b64c28ff 100644 --- a/tests/beman/execution26/exec-recv.test.cpp +++ b/tests/beman/execution26/exec-recv.test.cpp @@ -19,6 +19,12 @@ struct no_get_env; struct non_env { friend struct no_get_env; + non_env() = default; + non_env(non_env&&) = default; + non_env(const non_env&) = default; + auto operator=(non_env&&) -> non_env& = default; + auto operator=(const non_env&) -> non_env& = default; + private: ~non_env() {} }; @@ -35,12 +41,18 @@ struct not_move_constructible { not_move_constructible() = default; not_move_constructible(const not_move_constructible&) = default; not_move_constructible(not_move_constructible&&) = delete; + ~not_move_constructible() = default; + auto operator=(const not_move_constructible&) -> not_move_constructible& = default; + auto operator=(not_move_constructible&&) -> not_move_constructible& = delete; }; struct not_copy_constructible { using receiver_concept = test_std::receiver_t; not_copy_constructible() = default; not_copy_constructible(const not_copy_constructible&) = delete; not_copy_constructible(not_copy_constructible&&) = default; + ~not_copy_constructible() = default; + auto operator=(const not_copy_constructible&) -> not_copy_constructible& = delete; + auto operator=(not_copy_constructible&&) -> not_copy_constructible& = default; }; struct receiver_final final { @@ -52,7 +64,6 @@ struct receiver_base { struct receiver_derived { using receiver_concept = derived; }; -} // namespace auto test_receiver_concept() -> void { static_assert(not test_std::receiver); @@ -67,7 +78,6 @@ auto test_receiver_concept() -> void { static_assert(test_std::receiver); } -namespace { template struct arg_t {}; @@ -78,7 +88,6 @@ struct receiver1 { auto set_error(int) -> void {} auto set_stopped() noexcept -> void {} }; -} // namespace auto test_valid_completions_for_concept() -> void { test_std::set_value(receiver1{}, arg_t<0>()); @@ -94,6 +103,7 @@ auto test_valid_completions_for_concept() -> void { static_assert(test_std::detail::valid_completion_fortest_std::set_stopped_t, receiver1>); } +} // namespace TEST(exec_recv) { test_receiver_concept(); diff --git a/tests/beman/execution26/exec-run-loop-types.test.cpp b/tests/beman/execution26/exec-run-loop-types.test.cpp index d977b2d4..8b6094c6 100644 --- a/tests/beman/execution26/exec-run-loop-types.test.cpp +++ b/tests/beman/execution26/exec-run-loop-types.test.cpp @@ -23,7 +23,7 @@ namespace { auto use(auto&&...) -> void {} -enum class signal_type { none, error, stopped, value }; +enum class signal_type : unsigned char { none, error, stopped, value }; struct token_env { test_std::inplace_stop_token token; @@ -37,7 +37,7 @@ struct receiver { test_std::inplace_stop_token token; auto set_value() && noexcept { *result = signal_type::value; } - auto set_error(std::exception_ptr) && noexcept { *result = signal_type::error; } + auto set_error(const std::exception_ptr&) && noexcept { *result = signal_type::error; } auto set_stopped() && noexcept { *result = signal_type::stopped; } auto get_env() const noexcept -> token_env { return {this->token}; } @@ -48,7 +48,7 @@ struct finish_receiver { using receiver_concept = test_std::receiver_t; auto set_value() && noexcept { this->loop->finish(); } - auto set_error(std::exception_ptr) && noexcept { this->loop->finish(); } + auto set_error(const std::exception_ptr&) && noexcept { this->loop->finish(); } auto set_stopped() && noexcept { this->loop->finish(); } }; diff --git a/tests/beman/execution26/exec-sched.test.cpp b/tests/beman/execution26/exec-sched.test.cpp index df743f51..07ddcaff 100644 --- a/tests/beman/execution26/exec-sched.test.cpp +++ b/tests/beman/execution26/exec-sched.test.cpp @@ -31,7 +31,12 @@ struct no_scheduler_concept { struct not_queryable { using scheduler_concept = test_std::scheduler_t; + not_queryable() = default; + not_queryable(const not_queryable&) = default; + not_queryable(not_queryable&&) = default; ~not_queryable() = delete; + auto operator=(const not_queryable&) -> not_queryable& = default; + auto operator=(not_queryable&&) -> not_queryable& = default; auto schedule() -> sender> { return {}; } auto operator==(const not_queryable&) const -> bool = default; }; @@ -49,6 +54,10 @@ struct not_equality_comparable { struct not_copy_constructible { using scheduler_concept = test_std::scheduler_t; not_copy_constructible(const not_copy_constructible&) = delete; + not_copy_constructible(not_copy_constructible&&) = default; + ~not_copy_constructible() = default; + auto operator=(const not_copy_constructible&) -> not_copy_constructible& = delete; + auto operator=(not_copy_constructible&&) -> not_copy_constructible& = default; auto schedule() -> sender> { return {}; } auto operator==(const not_copy_constructible&) const -> bool = default; }; diff --git a/tests/beman/execution26/exec-schedule.test.cpp b/tests/beman/execution26/exec-schedule.test.cpp index 0dd04a8e..e4e8e468 100644 --- a/tests/beman/execution26/exec-schedule.test.cpp +++ b/tests/beman/execution26/exec-schedule.test.cpp @@ -34,8 +34,9 @@ auto test_schedule(Scheduler&& sched) { if constexpr (Expect) { static_assert(noexcept(test_std::schedule(std::forward(sched))) == noexcept(std::forward(sched).schedule())); + auto value{sched.value}; auto s = test_std::schedule(std::forward(sched)); - ASSERT(s.value == sched.value); + ASSERT(s.value == value); } } } // namespace diff --git a/tests/beman/execution26/exec-scounting.test.cpp b/tests/beman/execution26/exec-scounting.test.cpp index 8a27cab0..e21a446f 100644 --- a/tests/beman/execution26/exec-scounting.test.cpp +++ b/tests/beman/execution26/exec-scounting.test.cpp @@ -26,7 +26,10 @@ auto test_scounting_ctor() -> void { static_assert(not std::assignable_from); // a scope is created unused and can be destroyed: - test_std::simple_counting_scope{}; + { + test_std::simple_counting_scope scope{}; + test::use(scope); + } // a scope can be used and closed and can be destroyed: { test_std::simple_counting_scope scope{}; diff --git a/tests/beman/execution26/exec-set-value.test.cpp b/tests/beman/execution26/exec-set-value.test.cpp index a49a29b6..838ca2c8 100644 --- a/tests/beman/execution26/exec-set-value.test.cpp +++ b/tests/beman/execution26/exec-set-value.test.cpp @@ -12,12 +12,16 @@ template struct arg {}; struct throws { throws() = default; - throws(const throws&) {} + throws(throws&&) noexcept(false) {} + throws(const throws&) noexcept(false) {} + ~throws() = default; + auto operator=(throws&&) noexcept(false) -> throws& { return *this; } + auto operator=(const throws&) noexcept(false) -> throws& { return *this; } // NOLINT(cert-oop54-cpp) }; struct receiver { template auto set_value(T&&...) noexcept -> void {} - auto set_value(throws) noexcept -> void {} + auto set_value(throws) noexcept -> void {} // NOLINT(performance-unnecessary-value-param) auto set_value(int i, bool b, double d) noexcept { ASSERT(i == 42); ASSERT(b == true); diff --git a/tests/beman/execution26/exec-snd-concepts.test.cpp b/tests/beman/execution26/exec-snd-concepts.test.cpp index 9c3b0123..7f6473a1 100644 --- a/tests/beman/execution26/exec-snd-concepts.test.cpp +++ b/tests/beman/execution26/exec-snd-concepts.test.cpp @@ -118,7 +118,12 @@ auto test_sender() -> void { auto test_sender_in() -> void { struct non_queryable { + non_queryable() = default; + non_queryable(non_queryable&&) = default; + non_queryable(const non_queryable&) = default; ~non_queryable() = delete; + auto operator=(non_queryable&&) -> non_queryable& = default; + auto operator=(const non_queryable&) -> non_queryable& = default; }; struct queryable {}; struct non_sender_in {}; diff --git a/tests/beman/execution26/exec-snd-expos.test.cpp b/tests/beman/execution26/exec-snd-expos.test.cpp index fefda204..028e5ca2 100644 --- a/tests/beman/execution26/exec-snd-expos.test.cpp +++ b/tests/beman/execution26/exec-snd-expos.test.cpp @@ -935,7 +935,8 @@ auto test_connect_all() -> void { static_assert(requires { s.connect(receiver{}); }); static_assert(requires { test_std::connect(s, receiver{}); }); test_detail::basic_state state{std::move(s), receiver{}}; - auto product{test_detail::connect_all(&state, std::move(s), std::index_sequence<0, 1, 2, 3>{})}; + const sender4 s1{}; + auto product{test_detail::connect_all(&state, std::move(s1), std::index_sequence<0, 1, 2, 3>{})}; ASSERT(product.size() == 4); test::use(product); } diff --git a/tests/beman/execution26/exec-snd-transform.test.cpp b/tests/beman/execution26/exec-snd-transform.test.cpp index 262eeddd..dcf7e418 100644 --- a/tests/beman/execution26/exec-snd-transform.test.cpp +++ b/tests/beman/execution26/exec-snd-transform.test.cpp @@ -12,7 +12,7 @@ // ---------------------------------------------------------------------------- namespace { -enum class kind { dom, tag }; +enum class kind : unsigned char { dom, tag }; struct env {}; struct empty_domain {}; @@ -68,12 +68,13 @@ struct special_domain { template auto test_transform_sender(Dom&& dom, Sender&& sndr) { + auto value{sndr.value}; static_assert(test_std::sender>); static_assert(requires { test_std::transform_sender(dom, std::forward(sndr)); }); if constexpr (requires { test_std::transform_sender(dom, std::forward(sndr)); }) { static_assert(std::same_as(sndr)))>); static_assert(Noexcept == noexcept(test_std::transform_sender(dom, std::forward(sndr)))); - ASSERT(sndr.value == test_std::transform_sender(dom, std::forward(sndr)).value); + ASSERT(value == test_std::transform_sender(dom, std::forward(sndr)).value); } static_assert(requires { test_std::transform_sender(dom, std::forward(sndr), env{}); }); @@ -81,7 +82,7 @@ auto test_transform_sender(Dom&& dom, Sender&& sndr) { static_assert( std::same_as(sndr), env{}))>); static_assert(Noexcept == noexcept(test_std::transform_sender(dom, std::forward(sndr), env{}))); - ASSERT(sndr.value == test_std::transform_sender(dom, std::forward(sndr), env{}).value); + ASSERT(value == test_std::transform_sender(dom, std::forward(sndr), env{}).value); } static_assert(not requires { test_std::transform_sender(dom, std::forward(sndr), env{}, env{}); }); diff --git a/tests/beman/execution26/exec-sync-wait.test.cpp b/tests/beman/execution26/exec-sync-wait.test.cpp index bedf5f05..2ec92a35 100644 --- a/tests/beman/execution26/exec-sync-wait.test.cpp +++ b/tests/beman/execution26/exec-sync-wait.test.cpp @@ -137,22 +137,20 @@ 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{}; - test_detail::sync_wait_receiver receiver{&state}; + test_detail::sync_wait_state state{}; ASSERT(not state.result); ASSERT(not state.error); - test_std::set_value(std::move(receiver), 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{}; - test_detail::sync_wait_receiver receiver{&state}; + test_detail::sync_wait_state state{}; ASSERT(not state.result); ASSERT(not state.error); - test_std::set_error(std::move(receiver), error{17}); + test_std::set_error(test_detail::sync_wait_receiver{&state}, error{17}); ASSERT(not state.result); ASSERT(state.error); try { @@ -160,16 +158,16 @@ auto test_sync_wait_receiver() -> void { } catch (const error& e) { ASSERT(e.value == 17); } catch (...) { + // NOLINTNEXTLINE(cert-dcl03-c,hicpp-static-assert,misc-static-assert) ASSERT(nullptr == "unexpected exception type"); } } { using sender = decltype(test_std::just(arg<0>{}, arg<1>{}, arg<2>{})); - test_detail::sync_wait_state state{}; - test_detail::sync_wait_receiver receiver{&state}; + test_detail::sync_wait_state state{}; ASSERT(not state.result); ASSERT(not state.error); - test_std::set_error(std::move(receiver), 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 { @@ -177,16 +175,16 @@ auto test_sync_wait_receiver() -> void { } catch (const error& e) { ASSERT(e.value == 17); } catch (...) { + // NOLINTNEXTLINE(cert-dcl03-c,hicpp-static-assert,misc-static-assert) ASSERT(nullptr == "unexpected exception type"); } } { using sender = decltype(test_std::just(arg<0>{}, arg<1>{}, arg<2>{})); - test_detail::sync_wait_state state{}; - test_detail::sync_wait_receiver receiver{&state}; + test_detail::sync_wait_state state{}; ASSERT(not state.result); ASSERT(not state.error); - test_std::set_stopped(std::move(receiver)); + test_std::set_stopped(test_detail::sync_wait_receiver{&state}); ASSERT(not state.result); ASSERT(not state.error); } @@ -198,24 +196,31 @@ auto test_sync_wait() -> void { ASSERT(value); ASSERT(*value == (std::tuple{arg<0>{7}, arg<1>{11}})); } catch (...) { - ASSERT(nullptr == "no exception expected from sync_wait(just(...)"); + ASSERT( + nullptr == + "no exception expected from sync_wait(just(...)"); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) } try { auto value{test_std::sync_wait(send_error{17})}; use(value); - ASSERT(nullptr == "this line should never be reached"); + ASSERT(nullptr == + "this line should never be reached"); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) } catch (const error& e) { ASSERT(e.value == 17); } catch (...) { + // NOLINTBEGIN(cert-dcl03-c,hicpp-static-assert,misc-static-assert) ASSERT(nullptr == "no exception expected from sync_wait(just(...)"); + // NOLINTEND(cert-dcl03-c,hicpp-static-assert,misc-static-assert) } try { auto value{test_std::sync_wait(send_stopped())}; ASSERT(not value); } catch (...) { + // NOLINTBEGIN(cert-dcl03-c,hicpp-static-assert,misc-static-assert) ASSERT(nullptr == "no exception expected from sync_wait(just(...)"); + // NOLINTEND(cert-dcl03-c,hicpp-static-assert,misc-static-assert) } } } // namespace diff --git a/tests/beman/execution26/exec-then.test.cpp b/tests/beman/execution26/exec-then.test.cpp index abb3a7e4..3f2a12b0 100644 --- a/tests/beman/execution26/exec-then.test.cpp +++ b/tests/beman/execution26/exec-then.test.cpp @@ -146,8 +146,9 @@ auto test_then_multi_type() -> void { } auto test_then_value() -> void { - ASSERT(std::tuple{17} == - *test_std::sync_wait(test_std::just(5, 12) | test_std::then([](int a, int b) { return a + b; }))); + ASSERT( + std::tuple{17} == + test_std::sync_wait(test_std::just(5, 12) | test_std::then([](int a, int b) { return a + b; })).value_or(0)); ASSERT(std::tuple{17} == test_std::sync_wait(test_std::just_error(17) | test_std::upon_error([](int a) { return a; }))); ASSERT(std::tuple{17} == @@ -183,15 +184,18 @@ struct allocator_fun { std::pmr::polymorphic_allocator<> alloc; std::byte* data{nullptr}; - allocator_fun(std::pmr::polymorphic_allocator<> alloc) : alloc(alloc), data(alloc.allocate(1)) {} + explicit allocator_fun(std::pmr::polymorphic_allocator<> alloc) : alloc(alloc), data(alloc.allocate(1)) {} allocator_fun(const allocator_fun&, std::pmr::polymorphic_allocator<> = {}) {} - allocator_fun(allocator_fun&& other) : alloc(other.alloc), data(std::exchange(other.data, nullptr)) {} + 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() { if (this->data) this->alloc.deallocate(this->data, 1u); } + auto operator=(const allocator_fun&) -> allocator_fun = delete; + auto operator=(allocator_fun&&) -> allocator_fun = delete; + auto operator()(auto&&...) const {} }; diff --git a/tests/beman/execution26/exec-when-all.test.cpp b/tests/beman/execution26/exec-when-all.test.cpp index a82d2183..971a54db 100644 --- a/tests/beman/execution26/exec-when-all.test.cpp +++ b/tests/beman/execution26/exec-when-all.test.cpp @@ -44,7 +44,7 @@ auto test_when_all_breathing() -> void { static_assert(test_std::sender); test::check_type>( test_std::get_completion_signatures(s, test_std::empty_env{})); - auto res{test_std::sync_wait(std::move(s))}; + auto res{test_std::sync_wait(s)}; ASSERT(res.has_value()); ASSERT((*res == std::tuple{3, true, 1.5})); } @@ -58,7 +58,7 @@ struct await_cancel { using operation_state_concept = test_std::operation_state_t; struct callback { Receiver* receiver; - callback(Receiver* receiver) : receiver(receiver) {} + explicit callback(Receiver* receiver) : receiver(receiver) {} auto operator()() const noexcept -> void { test_std::set_stopped(std::move(*this->receiver)); } }; @@ -115,12 +115,12 @@ struct test_sender { Result expect; std::remove_cvref_t receiver; decltype(test_std::connect(std::declval(), std::declval>())) inner_state; - template - state(auto&& sender, auto&& expect, R&& receiver) + template + state(S&& sender, auto&& expect, R&& receiver) : expect(expect), receiver(std::forward(receiver)), - inner_state( - test_std::connect(std::move(sender), upstream{this->expect, this->receiver})) {} + inner_state(test_std::connect(std::forward(sender), + upstream{this->expect, this->receiver})) {} auto start() & noexcept -> void { test_std::start(this->inner_state); } }; @@ -216,7 +216,7 @@ auto test_when_all() -> void { auto test_when_all_with_variant() -> void { auto s{test_std::when_all_with_variant(test_std::just(17), test_std::just('a', true))}; - auto res{test_std::sync_wait(std::move(s))}; + auto res{test_std::sync_wait(s)}; ASSERT(res); auto&& [v0, v1]{*res}; test::use(v0, v1); diff --git a/tests/beman/execution26/execution-queryable-concept.test.cpp b/tests/beman/execution26/execution-queryable-concept.test.cpp index 2c6020cd..a6722a2d 100644 --- a/tests/beman/execution26/execution-queryable-concept.test.cpp +++ b/tests/beman/execution26/execution-queryable-concept.test.cpp @@ -10,8 +10,13 @@ namespace { template concept has_foo = test_std::detail::queryable && requires(T t) { t.foo; }; -class non_destructible { - ~non_destructible() = default; +struct non_destructible { + non_destructible() = default; + non_destructible(non_destructible&&) = default; + non_destructible(const non_destructible&) = default; + ~non_destructible() = delete; + auto operator=(non_destructible&&) -> non_destructible& = default; + auto operator=(const non_destructible&) -> non_destructible& = default; }; template diff --git a/tests/beman/execution26/execution-syn.test.cpp b/tests/beman/execution26/execution-syn.test.cpp index 509e961c..98dd91b3 100644 --- a/tests/beman/execution26/execution-syn.test.cpp +++ b/tests/beman/execution26/execution-syn.test.cpp @@ -121,9 +121,11 @@ auto test_decayed_tuple() -> void { static_assert(std::same_as, test_detail::decayed_tuple>); static_assert(std::same_as, test_detail::decayed_tuple>); - static_assert(std::same_as, test_detail::decayed_tuple>); - static_assert( - std::same_as, test_detail::decayed_tuple>); + static_assert(std::same_as, + test_detail::decayed_tuple>); // NOLINT(hicpp-avoid-c-arrays) + static_assert(std::same_as< + std::tuple, + test_detail::decayed_tuple>); // NOLINT(hicpp-avoid-c-arrays) } auto test_variant_or_empty() -> void { @@ -265,6 +267,7 @@ auto test_conect_result_t() -> void { static_assert(requires { connect_sender{}.connect(receiver{}); }); auto op{test_std::connect(connect_sender{}, receiver{})}; + test::use(op); static_assert(std::same_as>); } auto test_decays_to() -> void { @@ -275,8 +278,8 @@ auto test_decays_to() -> void { static_assert(test_detail::decays_to); static_assert(test_detail::decays_to); static_assert(test_detail::decays_to); - static_assert(test_detail::decays_to); - static_assert(test_detail::decays_to); + static_assert(test_detail::decays_to); // NOLINT(hicpp-avoid-c-arrays) + static_assert(test_detail::decays_to); // NOLINT(hicpp-avoid-c-arrays) static_assert(not test_detail::decays_to); static_assert(not test_detail::decays_to); static_assert(not test_detail::decays_to); @@ -306,8 +309,10 @@ auto test_sender_adaptor_closure() -> void { static_assert(not test_std::sender); auto direct{closure(sender{})}; + test::use(direct); static_assert(std::same_as, decltype(direct)>); auto via_op{sender{} | closure}; + test::use(via_op); static_assert(std::same_as, decltype(via_op)>); } @@ -329,8 +334,10 @@ auto test_sender_adaptor() -> void { auto closure{arg_closure(17)}; static_assert(std::same_as, decltype(closure)>); auto direct{closure(sender{})}; + test::use(direct); static_assert(std::same_as, decltype(direct)>); auto via_op{sender{} | closure}; + test::use(via_op); static_assert(std::same_as, decltype(via_op)>); } diff --git a/tests/beman/execution26/forward-like.test.cpp b/tests/beman/execution26/forward-like.test.cpp index b71f8e7a..cf133da1 100644 --- a/tests/beman/execution26/forward-like.test.cpp +++ b/tests/beman/execution26/forward-like.test.cpp @@ -24,7 +24,7 @@ TEST(forward_like) { object o{}; const object co{}; test_forward_like(o); - test_forward_like(std::move(o)); + test_forward_like(std::move(o)); // NOLINT(hicpp-move-const-arg,performance-move-const-arg) test_forward_like(co); - test_forward_like(std::move(co)); + test_forward_like(std::move(co)); // NOLINT(hicpp-move-const-arg,performance-move-const-arg) } diff --git a/tests/beman/execution26/functional-syn.test.cpp b/tests/beman/execution26/functional-syn.test.cpp index ab3b49ad..ad557c59 100644 --- a/tests/beman/execution26/functional-syn.test.cpp +++ b/tests/beman/execution26/functional-syn.test.cpp @@ -8,15 +8,30 @@ // ---------------------------------------------------------------------------- namespace { -class non_destructible { - ~non_destructible(); +struct non_destructible { + non_destructible() = default; + non_destructible(non_destructible&&) = default; + non_destructible(const non_destructible&) = default; + ~non_destructible() = delete; + auto operator=(non_destructible&&) -> non_destructible& = default; + auto operator=(const non_destructible&) -> non_destructible& = default; }; struct non_copyable { + non_copyable() = default; + non_copyable(const non_copyable&) = delete; non_copyable(non_copyable&&) = delete; + ~non_copyable() = default; + auto operator=(const non_copyable&) -> non_copyable& = delete; + auto operator=(non_copyable&&) -> non_copyable& = delete; }; struct arg {}; struct throws { - throws(const throws&) {} + throws() noexcept(false) {} + throws(throws&&) noexcept(false) {} + throws(const throws&) noexcept(false) {} + ~throws() {} + auto operator=(throws&&) noexcept(false) -> throws& { return *this; } + auto operator=(const throws&) noexcept(false) -> throws& { return *this; } }; template diff --git a/tests/beman/execution26/include/test/stop_token.hpp b/tests/beman/execution26/include/test/stop_token.hpp index d2275bd7..5d124211 100644 --- a/tests/beman/execution26/include/test/stop_token.hpp +++ b/tests/beman/execution26/include/test/stop_token.hpp @@ -6,9 +6,11 @@ #define INCLUDED_TEST_STOP_TOKEN #include +#include #include #include +#include #include #include #include @@ -50,7 +52,7 @@ inline auto test::stop_visible(Token token, Stop stop) -> void { // was requested. // Reference: [thread.stoptoken.intro] p3 - Token tokens[] = {token, token, token, token}; + std::array tokens{token, token, token, token}; auto predicate = [](auto&& t) { return t.stop_requested(); }; ASSERT((::std::ranges::none_of(tokens, predicate))); @@ -82,7 +84,7 @@ inline auto test::stop_callback(Token token, Stop stop) -> void { struct Callback { Data* data; - Callback(Data* data) : data(data) {} + explicit Callback(Data* data) : data(data) {} auto operator()() { ++this->data->count; this->data->stop_requested = this->data->token.stop_requested(); @@ -91,7 +93,7 @@ inline auto test::stop_callback(Token token, Stop stop) -> void { Data data{token}; - ::test_std::stop_callback_for_t cb0(token, &data); + ::test_std::stop_callback_for_t cb0(token, Callback{&data}); ASSERT(data.count == 0); ASSERT(data.stop_requested == false); stop(); @@ -102,7 +104,7 @@ inline auto test::stop_callback(Token token, Stop stop) -> void { stop(); ASSERT(data.count == 1); - ::test_std::stop_callback_for_t cb1(token, &data); + ::test_std::stop_callback_for_t cb1(token, Callback{&data}); ASSERT(data.count == 2); stop(); ASSERT(data.count == 2); @@ -122,13 +124,13 @@ auto test::stop_callback_dtor_deregisters(Token token, Stop stop) -> void { struct Callback { bool* ptr; - Callback(bool* ptr) : ptr(ptr) {} + explicit Callback(bool* ptr) : ptr(ptr) {} auto operator()() { *this->ptr = true; } }; bool flag{}; ::std::invoke([token, &flag] { - ::test_std::stop_callback_for_t cb(token, &flag); + ::test_std::stop_callback_for_t cb(token, Callback{&flag}); ASSERT(flag == false); }); @@ -164,7 +166,7 @@ inline auto test::stop_callback_dtor_other_thread(Token token, Stop stop) -> voi }; struct Callback { Data* data; - Callback(Data* data) : data(data) {} + explicit Callback(Data* data) : data(data) {} auto operator()() -> void { using namespace ::std::chrono_literals; { @@ -181,7 +183,7 @@ inline auto test::stop_callback_dtor_other_thread(Token token, Stop stop) -> voi Data data; using CB = ::test_std::stop_callback_for_t; - ::std::unique_ptr ptr(new CB(token, &data)); + ::std::unique_ptr ptr(new CB(token, Callback{&data})); ::std::thread thread([&ptr, &data] { { @@ -210,19 +212,24 @@ inline auto test::stop_callback_dtor_same_thread(Token token, Stop stop) -> void // - Then the deregistration does not block. // Reference: [stoptoken.concepts] p4 struct Base { + Base() = default; + Base(Base&&) = default; + Base(const Base&) = default; virtual ~Base() = default; + auto operator=(Base&&) -> Base& = default; + auto operator=(const Base&) -> Base& = default; }; struct Callback { ::std::unique_ptr* self; - Callback(::std::unique_ptr* self) : self(self) {} + explicit Callback(::std::unique_ptr* self) : self(self) {} auto operator()() { this->self->reset(); } }; struct Object : Base { ::test_std::stop_callback_for_t cb; - Object(Token token, ::std::unique_ptr* self) : cb(token, self) {} + Object(Token token, ::std::unique_ptr* self) : cb(std::move(token), Callback{self}) {} }; ::std::unique_ptr ptr; - ptr.reset(new Object(token, &ptr)); + ptr.reset(new Object(std::move(token), &ptr)); ::std::atomic done{}; ::std::thread thread([&done] { diff --git a/tests/beman/execution26/notify.test.cpp b/tests/beman/execution26/notify.test.cpp index 68090672..3b875e6c 100644 --- a/tests/beman/execution26/notify.test.cpp +++ b/tests/beman/execution26/notify.test.cpp @@ -17,7 +17,7 @@ TEST(notify) { static_assert(test_std::sender); static_assert(test_std::sender_in); n.complete(); - test_std::sync_wait(::std::move(s)); + test_std::sync_wait(s); } { struct receiver { diff --git a/tests/beman/execution26/stopcallback-cons.test.cpp b/tests/beman/execution26/stopcallback-cons.test.cpp index b95108ba..4b16dd95 100644 --- a/tests/beman/execution26/stopcallback-cons.test.cpp +++ b/tests/beman/execution26/stopcallback-cons.test.cpp @@ -16,7 +16,7 @@ TEST(stopcallback_cons) { // - Then the response is true when an int* is passed as // initializer argument but false otherwise. struct Callback { - Callback(int*) {} + explicit Callback(int*) {} auto operator()() -> void {} }; static_assert(::std::is_constructible_v<::test_std::stop_callback, const ::test_std::stop_token&, int*>); diff --git a/tests/beman/execution26/stopcallback-general.test.cpp b/tests/beman/execution26/stopcallback-general.test.cpp index 4580fa7b..85153578 100644 --- a/tests/beman/execution26/stopcallback-general.test.cpp +++ b/tests/beman/execution26/stopcallback-general.test.cpp @@ -6,6 +6,7 @@ #include #include +namespace { auto test_stop_callback_interface() -> void { // Reference: [stopcallback.general] p1 struct ThrowInit {}; @@ -35,5 +36,6 @@ auto test_stop_callback_interface() -> void { ::test_std::stop_callback cb(ctoken, Callback(ThrowInit())); } +} // namespace TEST(stopcallback_general) { test_stop_callback_interface(); } diff --git a/tests/beman/execution26/stopcallback-inplace-cons.test.cpp b/tests/beman/execution26/stopcallback-inplace-cons.test.cpp index 24f3debf..8188e510 100644 --- a/tests/beman/execution26/stopcallback-inplace-cons.test.cpp +++ b/tests/beman/execution26/stopcallback-inplace-cons.test.cpp @@ -4,6 +4,7 @@ #include #include "test/execution.hpp" +namespace { auto test_inplace_stopcallback_ctor() -> void { // Plan: // - Given an inplace_stop_source. @@ -59,6 +60,7 @@ auto test_inplace_stopcallback_dtor() -> void { ASSERT(flag1 == true); ASSERT(flag2 == false); } +} // namespace TEST(stopcallback_inplace_cons) { test_inplace_stopcallback_ctor(); diff --git a/tests/beman/execution26/stopsource-cons.test.cpp b/tests/beman/execution26/stopsource-cons.test.cpp index 82c6d20d..0d95564b 100644 --- a/tests/beman/execution26/stopsource-cons.test.cpp +++ b/tests/beman/execution26/stopsource-cons.test.cpp @@ -8,25 +8,36 @@ #include #include +namespace { bool fail{}; +} + +// NOLINTNEXTLINE(hicpp-no-malloc) auto operator new(::std::size_t size) -> void* { return fail ? throw ::std::bad_alloc() : ::std::malloc(size); } -auto operator delete(void* ptr) noexcept -> void { ::std::free(ptr); } -auto operator delete(void* ptr, ::std::size_t) noexcept -> void { ::std::free(ptr); } +auto operator delete(void* ptr) noexcept -> void { ::std::free(ptr); } // NOLINT(hicpp-no-malloc) +auto operator delete(void* ptr, ::std::size_t) noexcept -> void { ::std::free(ptr); } // NOLINT(hicpp-no-malloc) TEST(stopsource_cons) { // Reference: [stopsource.cons] p1 ::test_std::stop_source source; - ASSERT(source.stop_possible()); - ASSERT((not source.stop_requested())); + try { + ASSERT(source.stop_possible()); + ASSERT((not source.stop_requested())); + } catch (...) { + ASSERT(nullptr == "can't be reached"); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) + } // Reference: [stopsource.cons] p3 fail = true; try { - ::test_std::stop_source(); - ASSERT(nullptr == "can't be reached"); + ::test_std::stop_source source{}; + test::use(source); + ASSERT(nullptr == "can't be reached"); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) } catch (const ::std::bad_alloc&) { - ASSERT(nullptr != "bad_alloc was thrown"); + ASSERT(nullptr != "bad_alloc was thrown"); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) + } catch (...) { + ASSERT(nullptr == "can't be reached"); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) } } diff --git a/tests/beman/execution26/stopsource-general.test.cpp b/tests/beman/execution26/stopsource-general.test.cpp index dea31480..26dd25e9 100644 --- a/tests/beman/execution26/stopsource-general.test.cpp +++ b/tests/beman/execution26/stopsource-general.test.cpp @@ -12,8 +12,13 @@ TEST(stopsource_general) { ::test_std::stop_source source1; ::test_std::stop_source source2{::test_std::nostopstate}; static_assert(noexcept(::test_std::stop_source(::test_std::nostopstate_t()))); - ASSERT(not source2.stop_possible()); - ASSERT(not source2.stop_requested()); + try { + ASSERT(not source2.stop_possible()); + ASSERT(not source2.stop_requested()); + } catch (...) { + // NOLINTNEXTLINE(cert-dcl03-c,hicpp-static-assert,misc-static-assert) + ASSERT(nullptr == "the stop source should not throw"); + } static_assert(noexcept(source1.swap(source2))); static_assert(noexcept(source1.stop_requested())); diff --git a/tests/beman/execution26/stopsource-inplace-mem.test.cpp b/tests/beman/execution26/stopsource-inplace-mem.test.cpp index e3277a3e..49885f84 100644 --- a/tests/beman/execution26/stopsource-inplace-mem.test.cpp +++ b/tests/beman/execution26/stopsource-inplace-mem.test.cpp @@ -4,6 +4,7 @@ #include #include "test/execution.hpp" +namespace { auto test_inplace_stop_source_get_token() -> void { // Plan: // - Given two inplace_stop_sources. @@ -68,6 +69,7 @@ auto test_inplace_stop_source_request_stop() -> void { ASSERT(flag1 == true); ASSERT(flag2 == true); } +} // namespace TEST(stopsource_inplace_mem) { test_inplace_stop_source_get_token(); diff --git a/tests/beman/execution26/stopsource-mem.test.cpp b/tests/beman/execution26/stopsource-mem.test.cpp index 2ef94641..6f04b261 100644 --- a/tests/beman/execution26/stopsource-mem.test.cpp +++ b/tests/beman/execution26/stopsource-mem.test.cpp @@ -4,6 +4,7 @@ #include #include "test/execution.hpp" +namespace { auto test_stopsource_swap() -> void { // Plan: // - Given two engaged stop sources. @@ -119,6 +120,7 @@ auto test_stopsource_request_stop() -> void { ASSERT(res4 == false); ASSERT(not disengaged.stop_requested()); } +} // namespace TEST(stopsource_mem) { test_stopsource_swap(); diff --git a/tests/beman/execution26/stoptoken-mem.test.cpp b/tests/beman/execution26/stoptoken-mem.test.cpp index ca1c4bdf..1c733b98 100644 --- a/tests/beman/execution26/stoptoken-mem.test.cpp +++ b/tests/beman/execution26/stoptoken-mem.test.cpp @@ -2,10 +2,12 @@ // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception #include +#include #include #include "test/execution.hpp" #include "test/stop_token.hpp" +namespace { auto test_stop_token_swap() -> void { // Plan: // - Given two pairs of stop_tokens compare equal within the pair @@ -15,8 +17,8 @@ auto test_stop_token_swap() -> void { // Reference: [stoptoken.mem] p1 ::test_std::stop_source s0, s1; - ::test_std::stop_token pair0[] = {s0.get_token(), s0.get_token()}; - ::test_std::stop_token pair1[] = {s1.get_token(), s1.get_token()}; + ::std::array<::test_std::stop_token, 2> pair0 = {s0.get_token(), s0.get_token()}; + ::std::array<::test_std::stop_token, 2> pair1 = {s1.get_token(), s1.get_token()}; ASSERT(pair0[0] == pair0[1]); ASSERT(pair1[0] == pair1[1]); @@ -85,11 +87,18 @@ auto test_stop_token_stop_possible() -> void { ASSERT(unstopped_token.stop_possible() == false); ASSERT(stopped_token.stop_possible() == true); } +} // namespace TEST(stoptoken_mem) { static_assert(::test_std::stoppable_token<::test_std::stop_token>); - test_stop_token_swap(); - test_stop_token_stop_requested(); - test_stop_token_stop_possible(); + try { + test_stop_token_swap(); + test_stop_token_stop_requested(); + test_stop_token_stop_possible(); + } catch (...) { + // NOLINTBEGIN(cert-dcl03-c,hicpp-static-assert,misc-static-assert) + ASSERT(nullptr == "the stop token tests are not expected to throw"); + // NOLINTEND(cert-dcl03-c,hicpp-static-assert,misc-static-assert) + } } diff --git a/tests/beman/execution26/stoptoken-never-general.test.cpp b/tests/beman/execution26/stoptoken-never-general.test.cpp index 695c22b0..01fde390 100644 --- a/tests/beman/execution26/stoptoken-never-general.test.cpp +++ b/tests/beman/execution26/stoptoken-never-general.test.cpp @@ -9,9 +9,10 @@ TEST(stoptoken_never_general) { static_assert(::test_std::unstoppable_token<::test_std::never_stop_token>); ::test_std::never_stop_token token; + const ::test_std::never_stop_token other(token); static_assert(false == token.stop_requested()); static_assert(false == token.stop_possible()); - static_assert(token == token); + static_assert(token == other); struct Callback { explicit Callback(int*) {} diff --git a/tests/beman/execution26/thread-stoptoken-intro.test.cpp b/tests/beman/execution26/thread-stoptoken-intro.test.cpp index 73c5f131..6e176872 100644 --- a/tests/beman/execution26/thread-stoptoken-intro.test.cpp +++ b/tests/beman/execution26/thread-stoptoken-intro.test.cpp @@ -2,14 +2,20 @@ // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception #include +#include #include "test/execution.hpp" #include "test/stop_token.hpp" #include namespace { -struct test_source { +struct test_source : test_detail::immovable { struct callback_base { + callback_base() = default; + callback_base(callback_base&&) = default; + callback_base(const callback_base&) = default; virtual ~callback_base() = default; + auto operator=(callback_base&&) -> callback_base& = default; + auto operator=(const callback_base&) -> callback_base& = default; virtual auto call() -> void = 0; }; struct token { @@ -18,7 +24,11 @@ struct test_source { Fun d_fun; test_source* d_source{}; callback_type(token t, Fun fun) : d_fun(fun), d_source(t.d_source) { this->d_source->add(this); } - ~callback_type() { this->d_source->remove(this); } + callback_type(callback_type&&) = delete; + callback_type(const callback_type&) = delete; + ~callback_type() override { this->d_source->remove(this); } + auto operator=(callback_type&&) -> callback_type& = delete; + auto operator=(const callback_type&) -> callback_type& = delete; auto call() -> void override { this->d_fun(); } }; @@ -39,9 +49,6 @@ struct test_source { no_call d_no_call; callback_base* d_callback{&this->d_no_call}; - test_source() = default; - test_source(test_source&&) = delete; - auto get_token() const -> token { return {const_cast(this)}; } auto stop_possible() const noexcept -> bool { return true; } auto stop_requested() const noexcept -> bool { return this->d_value; }