/* * Copyright (C) 2015 Naios * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef _CALLBACK_H_ #define _CALLBACK_H_ #include #include #include #include #include #include "functional_unwrap.hpp" /// A general purpose void returing callback type (`std::function`). template using Callback = std::function; /// A callback wrapped in a std::shared_ptr template using SharedCallback = std::shared_ptr>; /// A callback wrapped in a std::weak_ptr template using WeakCallback = std::weak_ptr>; namespace detail { template struct do_unwrap_callback; template struct do_unwrap_callback> { typedef Callback<_ATy...> CallbackType; typedef SharedCallback<_ATy...> SharedCallbackType; typedef WeakCallback<_ATy...> WeakCallbackType; }; template using unwrap_callback_t = do_unwrap_callback<::fu::function_type_of_t::type>>; template struct WeakProxyFactory; template struct WeakProxyFactory<_CTy, std::weak_ptr>> { static Callback CreateProxy(_CTy&& weak) { return [=](Args&&... args) { if (auto const callback = weak.lock()) (*callback)(std::forward(args)...); }; } }; template struct WeakProxyFactory<_CTy, std::shared_ptr>> { static Callback CreateProxy(_CTy&& shared) { return WeakProxyFactory>&&, std::weak_ptr>>::CreateProxy(std::forward<_CTy>(shared)); } }; } // detail /// Unwraps the callback type of the given functional object. template using callback_of_t = typename detail::unwrap_callback_t<_CTy>::CallbackType; /// Unwraps the shared callback type of the given functional object. template using shared_callback_of_t = typename detail::unwrap_callback_t<_CTy>::SharedCallbackType; /// Unwraps the weak callback type of the given functional object. template using weak_callback_of_t = typename detail::unwrap_callback_t<_CTy>::WeakCallbackType; /// Creates a callback wrapped in a std::shared_ptr. template inline auto make_shared_callback(_CTy&& callback) -> shared_callback_of_t<_CTy> { return std::make_shared> (std::forward>(callback)); } /// Creates a weak callback which wraps the given shared or weak callback. /// If the given managed callback expires the callback is not invoked anymore. template inline auto make_weak_wrapped_callback(_CTy&& callback) -> decltype(detail::WeakProxyFactory<_CTy, typename std::decay<_CTy>::type>:: CreateProxy(std::declval<_CTy>())) { return detail::WeakProxyFactory<_CTy, typename std::decay<_CTy>::type>:: CreateProxy(std::forward<_CTy>(callback)); } #endif // _CALLBACK_H_