File size: 2,798 Bytes
985c397 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 | #pragma once
#include <functional>
#include <memory>
#include <type_traits>
namespace fastsignals
{
namespace detail
{
template <class ReturnType, class ClassType, bool AddConst, class... Args>
struct weak_binder
{
using ConstMethodType = ReturnType (ClassType::*)(Args... args) const;
using NonConstMethodType = ReturnType (ClassType::*)(Args... args);
using MethodType = std::conditional_t<AddConst, ConstMethodType, NonConstMethodType>;
using WeakPtrType = std::weak_ptr<ClassType>;
weak_binder(MethodType pMethod, WeakPtrType&& pObject)
: m_pMethod(pMethod)
, m_pObject(std::move(pObject))
{
}
ReturnType operator()(Args... args) const
{
if (auto pThis = m_pObject.lock())
{
return (pThis.get()->*m_pMethod)(std::forward<Args>(args)...);
}
return ReturnType();
}
MethodType m_pMethod;
WeakPtrType m_pObject;
};
} // namespace detail
/// Weak this binding of non-const methods.
template <typename ReturnType, typename ClassType, typename... Params, typename... Args>
decltype(auto) bind_weak(ReturnType (ClassType::*memberFn)(Params... args), std::shared_ptr<ClassType> const& pThis, Args... args)
{
using weak_binder_alias = detail::weak_binder<ReturnType, ClassType, false, Params...>;
weak_binder_alias invoker(memberFn, std::weak_ptr<ClassType>(pThis));
return std::bind(invoker, args...);
}
/// Weak this binding of const methods.
template <typename ReturnType, typename ClassType, typename... Params, typename... Args>
decltype(auto) bind_weak(ReturnType (ClassType::*memberFn)(Params... args) const, std::shared_ptr<ClassType> const& pThis, Args... args)
{
using weak_binder_alias = detail::weak_binder<ReturnType, ClassType, true, Params...>;
weak_binder_alias invoker(memberFn, std::weak_ptr<ClassType>(pThis));
return std::bind(invoker, args...);
}
/// Weak this binding of non-const methods.
template <typename ReturnType, typename ClassType, typename... Params, typename... Args>
decltype(auto) bind_weak(ReturnType (ClassType::*memberFn)(Params... args), std::weak_ptr<ClassType> pThis, Args... args)
{
using weak_binder_alias = detail::weak_binder<ReturnType, ClassType, false, Params...>;
weak_binder_alias invoker(memberFn, std::move(pThis));
return std::bind(invoker, args...);
}
/// Weak this binding of const methods.
template <typename ReturnType, typename ClassType, typename... Params, typename... Args>
decltype(auto) bind_weak(ReturnType (ClassType::*memberFn)(Params... args) const, std::weak_ptr<ClassType> pThis, Args... args)
{
using weak_binder_alias = detail::weak_binder<ReturnType, ClassType, true, Params...>;
weak_binder_alias invoker(memberFn, std::move(pThis));
return std::bind(invoker, args...);
}
} // namespace fastsignals
|