| #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;
|
| };
|
| }
|
|
|
|
|
| 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...);
|
| }
|
|
|
|
|
| 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...);
|
| }
|
|
|
|
|
| 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...);
|
| }
|
|
|
|
|
| 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...);
|
| }
|
|
|
| }
|
|
|