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