11#include <boost/asio/any_io_executor.hpp>
12#include <boost/asio/awaitable.hpp>
13#include <boost/asio/co_spawn.hpp>
14#include <boost/asio/post.hpp>
15#include <boost/asio/use_awaitable.hpp>
16#include <boost/asio/use_future.hpp>
17#include <boost/signals2/connection.hpp>
18#include <boost/signals2/signal.hpp>
32 std::promise<std::decay_t<T>> promise{};
33 promise.set_value(std::forward<T>(value));
34 return promise.get_future().share();
38 std::promise<void> promise{};
40 return promise.get_future().share();
47 template<
typename InputIterator>
50 for (; first != last; ++first) {
51 results.push_back((*first).get());
61 template<
typename InputIterator>
62 void operator()(InputIterator first, InputIterator last)
const {
63 for (; first != last; ++first) {
69template<
typename Signature>
72template<
typename R,
typename... Args>
88template<
typename Signature,
92template<
typename R,
typename... Args,
typename Combiner>
95 using slot_t = std::function<R(Args...)>;
99 using result_t =
typename signal_t::result_type;
102 explicit Signal(boost::asio::any_io_executor executor)
111 template<
typename Slot>
113 auto slot_fn =
slot_t{std::forward<Slot>(slot)};
116 .connect([slot_fn = std::move(slot_fn), policy, executor =
executor_](
119 auto args_pack = std::make_shared<std::tuple<std::decay_t<Args>...>>(
120 std::forward<Args>(args)...);
122 if (policy == ExecPolicy::Sync) {
123 if constexpr (std::is_void_v<R>) {
124 std::apply(slot_fn, *args_pack);
125 return detail::make_ready_shared_future();
127 return detail::make_ready_shared_future(
128 std::apply(slot_fn, *args_pack));
132 if constexpr (std::is_void_v<R>) {
135 executor]()
mutable -> boost::asio::awaitable<void>
137 co_await boost::asio::post(executor, boost::asio::use_awaitable);
138 std::apply(slot_fn, *args_pack);
141 auto future = boost::asio::co_spawn(executor, std::move(coroutine),
142 boost::asio::use_future);
143 return future.share();
146 auto coroutine = [slot_fn, args_pack,
147 executor]()
mutable -> boost::asio::awaitable<R>
149 co_await boost::asio::post(executor, boost::asio::use_awaitable);
150 co_return std::apply(slot_fn, *args_pack);
153 auto future = boost::asio::co_spawn(executor, std::move(coroutine),
154 boost::asio::use_future);
155 return future.share();
161 return signal_(std::forward<Args>(args)...);
166 return emit(std::forward<Args>(args)...);
boost::asio::any_io_executor executor_
Definition nl_signal.hxx:170
signal_t signal_
Definition nl_signal.hxx:171
std::shared_future< R > future_t
Definition nl_signal.hxx:96
auto emit(Args... args) -> result_t
Emit the signal and run all connected slots.
Definition nl_signal.hxx:160
boost::signals2::connection connection_t
Definition nl_signal.hxx:98
auto operator()(Args... args) -> result_t
Shortcut to emit the signal.
Definition nl_signal.hxx:165
boost::signals2::signal< future_t(Args...), Combiner > signal_t
Definition nl_signal.hxx:97
typename signal_t::result_type result_t
Definition nl_signal.hxx:99
std::function< R(Args...)> slot_t
Definition nl_signal.hxx:95
Signal(boost::asio::any_io_executor executor)
Construct a Signal that will execute slots on the given executor.
Definition nl_signal.hxx:102
auto connect(Slot &&slot, ExecPolicy policy=ExecPolicy::Sync) -> connection_t
Connect a slot to the signal.
Definition nl_signal.hxx:112
Signal/slot wrapper supporting synchronous and asynchronous execution.
Definition nl_signal.hxx:90
Definition nl_signal.hxx:28
auto make_ready_shared_future(T &&value) -> std::shared_future< std::decay_t< T > >
Definition nl_signal.hxx:31
Definition nl_common.hxx:22
ExecPolicy
Definition nl_signal.hxx:23
@ Async
Definition nl_signal.hxx:25
@ Sync
Definition nl_signal.hxx:24
Definition nl_common.hxx:21
WaitAllCombiner< R > default_combiner
Definition nl_signal.hxx:76
R result_t
Definition nl_signal.hxx:74
std::tuple< Args... > args_tuple
Definition nl_signal.hxx:75
Definition nl_signal.hxx:70
void result_type
Definition nl_signal.hxx:59
void operator()(InputIterator first, InputIterator last) const
Definition nl_signal.hxx:62
Definition nl_signal.hxx:44
auto operator()(InputIterator first, InputIterator last) const -> result_type
Definition nl_signal.hxx:48
std::vector< R > result_type
Definition nl_signal.hxx:45