15 #include <boost/asio/bind_executor.hpp>
16 #include <boost/asio/dispatch.hpp>
17 #include <boost/asio/post.hpp>
27 template <
typename TDerived,
typename TClass,
typename TCallable>
28 auto bind_weak(std::weak_ptr<TClass> weak_ptr, TCallable&& callable) {
30 weak_ptr.use_count() > 0,
31 "weakBind requires an initialized weak_ptr. "
32 "(Did you call weak_from_this() in a constructor?)");
34 return [weak = std::move(weak_ptr),
35 cb = std::forward<TCallable>(callable)](
auto&&... args)
mutable {
36 if (
auto base_self = weak.lock()) {
37 auto self = std::static_pointer_cast<TDerived>(std::move(base_self));
38 std::invoke(cb, std::move(
self), std::forward<decltype(args)>(args)...);
43 template <
typename TDerived,
typename TClass,
typename TCallable>
44 auto bind_shared(std::shared_ptr<TClass> shared_ptr, TCallable&& callable) {
46 shared_ptr.use_count() > 0,
47 "bind requires an initialized shared_ptr. "
48 "(Did you call shared_from_this() in a constructor?)");
50 return [
self = std::static_pointer_cast<TDerived>(std::move(shared_ptr)),
51 cb = std::forward<TCallable>(callable)](
auto&&... args)
mutable {
52 std::invoke(cb,
self, std::forward<decltype(args)>(args)...);
58 template <
typename TMemberFn,
typename... TArgs>
60 return [method, args_tuple = std::make_tuple(std::forward<TArgs>(args)...)](
61 auto self,
auto&&... asio_args)
mutable {
63 [&](
auto&&... unpacked_args) {
64 (
self.get()->*method)(
65 std::forward<decltype(unpacked_args)>(unpacked_args)...,
66 std::forward<decltype(asio_args)>(asio_args)...);
68 std::move(args_tuple));
78 template <
typename TClass,
typename TCallable>
80 if constexpr (std::is_member_function_pointer_v<std::decay_t<TCallable>>) {
81 return detail::bind_weak<TClass>(
84 return detail::bind_weak<TClass>(
85 obj->weak_from_this(), std::forward<TCallable>(callable));
89 template <
typename TExecutor,
typename TClass,
typename TFunc>
90 void weakDispatch(TExecutor
const& ex, TClass* obj, TFunc&& func) {
93 detail::bind_weak<TClass>(
94 obj->weak_from_this(), std::forward<TFunc>(func)));
103 TExecutor
const& ex, TClass* obj, TMemberFn method, TArgs&&... args) {
106 detail::bind_weak<TClass>(
107 obj->weak_from_this(),
111 template <
typename TExecutor,
typename TClass,
typename TFunc>
112 void weakPost(TExecutor
const& ex, TClass* obj, TFunc&& func) {
115 detail::bind_weak<TClass>(
116 obj->weak_from_this(), std::forward<TFunc>(func)));
125 TExecutor
const& ex, TClass* obj, TMemberFn method, TArgs&&... args) {
128 detail::bind_weak<TClass>(
129 obj->weak_from_this(),
133 template <
typename TExecutor,
typename TClass,
typename TFunc>
135 TExecutor const& ex, TClass* obj, TFunc&& func) {
136 return boost::asio::bind_executor(
138 detail::bind_weak<TClass>(
139 obj->weak_from_this(), std::forward<TFunc>(func)));
148 TExecutor const& ex, TClass* obj, TMemberFn method, TArgs&&... args) {
149 return boost::asio::bind_executor(
151 detail::bind_weak<TClass>(
152 obj->weak_from_this(),
160 template <
typename TClass,
typename TCallable>
161 auto handler(TClass* obj, TCallable&& callable) {
162 if constexpr (std::is_member_function_pointer_v<std::decay_t<TCallable>>) {
163 return detail::bind_shared<TClass>(
166 return detail::bind_shared<TClass>(
167 obj->shared_from_this(), std::forward<TCallable>(callable));
171 template <
typename TExecutor,
typename TClass,
typename TFunc>
172 void dispatch(TExecutor
const& ex, TClass* obj, TFunc&& func) {
175 detail::bind_shared<TClass>(
176 obj->shared_from_this(), std::forward<TFunc>(func)));
185 TExecutor
const& ex, TClass* obj, TMemberFn method, TArgs&&... args) {
188 detail::bind_shared<TClass>(
189 obj->shared_from_this(),
193 template <
typename TExecutor,
typename TClass,
typename TFunc>
194 void post(TExecutor
const& ex, TClass* obj, TFunc&& func) {
197 detail::bind_shared<TClass>(
198 obj->shared_from_this(), std::forward<TFunc>(func)));
206 void post(TExecutor
const& ex, TClass* obj, TMemberFn method, TArgs&&... args) {
209 detail::bind_shared<TClass>(
210 obj->shared_from_this(),
214 template <
typename TExecutor,
typename TClass,
typename TFunc>
215 decltype(
auto)
bindExecutor(TExecutor const& ex, TClass* obj, TFunc&& func) {
216 return boost::asio::bind_executor(
218 detail::bind_shared<TClass>(
219 obj->shared_from_this(), std::forward<TFunc>(func)));
228 TExecutor const& ex, TClass* obj, TMemberFn method, TArgs&&... args) {
229 return boost::asio::bind_executor(
231 detail::bind_shared<TClass>(
232 obj->shared_from_this(),
#define SOL3_EXPECT(condition,...)
Definition: except.h:222
auto pack_method(TMemberFn method, TArgs &&... args)
Packs a member function and its arguments into a standard callable that perfectly forwards ASIO compl...
Definition: handlers.h:59
auto bind_weak(std::weak_ptr< TClass > weak_ptr, TCallable &&callable)
Definition: handlers.h:28
auto bind_shared(std::shared_ptr< TClass > shared_ptr, TCallable &&callable)
Definition: handlers.h:44
Support safely capturing this in ASIO completion handlers.
Definition: handlers.h:24
void dispatch(TExecutor const &ex, TClass *obj, TFunc &&func)
Definition: handlers.h:172
void post(TExecutor const &ex, TClass *obj, TMemberFn method, TArgs &&... args)
Definition: handlers.h:206
void weakPost(TExecutor const &ex, TClass *obj, TFunc &&func)
Definition: handlers.h:112
decltype(auto) weakBindExecutor(TExecutor const &ex, TClass *obj, TFunc &&func)
Definition: handlers.h:134
void post(TExecutor const &ex, TClass *obj, TFunc &&func)
Definition: handlers.h:194
auto weakHandler(TClass *obj, TCallable &&callable)
Definition: handlers.h:79
decltype(auto) bindExecutor(TExecutor const &ex, TClass *obj, TFunc &&func)
Definition: handlers.h:215
auto handler(TClass *obj, TCallable &&callable)
Definition: handlers.h:161
void weakDispatch(TExecutor const &ex, TClass *obj, TFunc &&func)
Definition: handlers.h:90
void dispatch(TExecutor const &ex, TClass *obj, TMemberFn method, TArgs &&... args)
Definition: handlers.h:184