1 // Copyright (c) 2007-2017 Hartmut Kaiser 2 // Copyright (c) 2016 Thomas Heller 3 // 4 // Distributed under the Boost Software License, Version 1.0. (See accompanying 5 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 6 7 #ifndef HPX_ACTIONS_TRIGGER_HPP 8 #define HPX_ACTIONS_TRIGGER_HPP 9 10 #include <hpx/exception.hpp> 11 #include <hpx/lcos/future.hpp> 12 #include <hpx/runtime/actions/continuation_fwd.hpp> 13 #include <hpx/traits/is_future.hpp> 14 #include <hpx/util/assert.hpp> 15 #include <hpx/util/bind.hpp> 16 #include <hpx/util/decay.hpp> 17 #include <hpx/util/invoke.hpp> 18 #include <hpx/util/result_of.hpp> 19 #include <hpx/util/unused.hpp> 20 21 #include <utility> 22 #include <type_traits> 23 24 namespace hpx { namespace actions 25 { 26 /////////////////////////////////////////////////////////////////////////// 27 namespace detail 28 { 29 template <typename Result, typename RemoteResult, typename F, 30 typename... Ts> trigger_impl(std::false_type,typed_continuation<Result,RemoteResult> && cont,F && f,Ts &&...vs)31 void trigger_impl(std::false_type, 32 typed_continuation<Result, RemoteResult>&& cont, F&& f, Ts&&... vs) 33 { 34 try { 35 cont.trigger_value( 36 util::invoke(std::forward<F>(f), std::forward<Ts>(vs)...)); 37 } 38 catch (...) { 39 // make sure hpx::exceptions are propagated back to the client 40 cont.trigger_error(std::current_exception()); 41 } 42 } 43 44 // Overload when return type is "void" aka util::unused_type 45 template <typename Result, typename RemoteResult, typename F, 46 typename... Ts> trigger_impl(std::true_type,typed_continuation<Result,RemoteResult> && cont,F && f,Ts &&...vs)47 void trigger_impl(std::true_type, 48 typed_continuation<Result, RemoteResult>&& cont, F&& f, Ts&&... vs) 49 { 50 try { 51 util::invoke(std::forward<F>(f), std::forward<Ts>(vs)...); 52 cont.trigger(); 53 } 54 catch (...) { 55 // make sure hpx::exceptions are propagated back to the client 56 cont.trigger_error(std::current_exception()); 57 } 58 } 59 } 60 61 template <typename Result, typename RemoteResult, typename F, 62 typename... Ts> trigger(typed_continuation<Result,RemoteResult> && cont,F && f,Ts &&...vs)63 void trigger( 64 typed_continuation<Result, RemoteResult>&& cont, F&& f, Ts&&... vs) 65 { 66 typename std::is_same<RemoteResult, util::unused_type>::type is_void; 67 68 detail::trigger_impl(is_void, std::move(cont), std::forward<F>(f), 69 std::forward<Ts>(vs)...); 70 } 71 }} 72 73 #endif 74