diff --git a/lib/include/srslte/common/multiqueue.h b/lib/include/srslte/common/multiqueue.h index 2bbc52dc4..fb8db8923 100644 --- a/lib/include/srslte/common/multiqueue.h +++ b/lib/include/srslte/common/multiqueue.h @@ -250,25 +250,26 @@ private: * Specialization for tasks with content that is move-only **********************************************************/ -class move_task_t +template +class move_function { public: - move_task_t() = default; + move_function() = default; template - move_task_t(Func&& f) : task_ptr(new derived_task(std::forward(f))) + move_function(Func&& f) : task_ptr(new derived_task(std::forward(f))) { } - void operator()() { (*task_ptr)(); } + void operator()(Args&&... args) { (*task_ptr)(std::forward(args)...); } private: struct base_task { virtual ~base_task() {} - virtual void operator()() = 0; + virtual void operator()(Args&&...) = 0; }; template struct derived_task : public base_task { derived_task(Func&& f_) : f(std::forward(f_)) {} - void operator()() final { f(); } + void operator()(Args&&... args) final { f(std::forward(args)...); } private: Func f; @@ -277,6 +278,7 @@ private: std::unique_ptr task_ptr; }; +using move_task_t = move_function<>; using task_multiqueue = multiqueue_handler; } // namespace srslte diff --git a/lib/include/srslte/common/stack_procedure.h b/lib/include/srslte/common/stack_procedure.h index 626e29ea2..9f57272da 100644 --- a/lib/include/srslte/common/stack_procedure.h +++ b/lib/include/srslte/common/stack_procedure.h @@ -19,6 +19,7 @@ * */ +#include "srslte/common/multiqueue.h" #include #include #include @@ -73,7 +74,7 @@ class callback_group_t { public: using callback_id_t = uint32_t; - using callback_t = std::function; + using callback_t = srslte::move_function; //! register callback, that gets called once callback_id_t on_next_call(callback_t f_) @@ -93,11 +94,11 @@ public: // call all callbacks template - void operator()(const ArgsRef&... args) + void operator()(ArgsRef&&... args) { for (auto& f : func_list) { if (f.active) { - f.func(args...); + f.func(std::forward(args)...); if (not f.call_always) { f.active = false; } @@ -274,7 +275,7 @@ public: using result_type = ResultType; using proc_result_type = proc_result_t; using proc_future_type = proc_future_t; - using then_callback_list_t = callback_group_t; + using then_callback_list_t = callback_group_t; using callback_t = typename then_callback_list_t::callback_t; using callback_id_t = typename then_callback_list_t::callback_id_t; @@ -312,8 +313,8 @@ public: } //! methods to schedule continuation tasks - callback_id_t then(const callback_t& c) { return complete_callbacks.on_next_call(c); } - callback_id_t then_always(const callback_t& c) { return complete_callbacks.on_every_call(c); } + callback_id_t then(callback_t c) { return complete_callbacks.on_next_call(std::move(c)); } + callback_id_t then_always(callback_t c) { return complete_callbacks.on_every_call(std::move(c)); } //! launch a procedure, returning true if successful or running and false if it error or it failed to launch template @@ -363,7 +364,7 @@ protected: // call T::then() if it exists proc_detail::optional_then(proc_ptr.get(), &result); // signal continuations - complete_callbacks(result); + complete_callbacks(std::move(result)); // back to inactive proc_detail::optional_clear(proc_ptr.get()); proc_state = proc_status_t::idle;