/** * Copyright 2015 Denis Blank * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #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_