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