/home/users/khuck/src/hpx-lsu/hpx/runtime/actions/trigger.hpp

Line% of fetchesSource
1  
//  Copyright (c) 2007-2016 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  
    namespace detail
27  
    {
28  
29  
        // special handling of actions returning a future
30  
        template <typename Result, typename RemoteResult, typename Future>
31  
        void deferred_trigger(std::false_type,
32  
            typed_continuation<Result, RemoteResult>&& cont, Future&& result)
33  
        {
34  
            try {
35  
                HPX_ASSERT(result.is_ready());
36  
                cont.trigger_value(hpx::util::detail::decay_copy(result.get()));
37  
            }
38  
            catch (...) {
39  
                // make sure hpx::exceptions are propagated back to the client
40  
                cont.trigger_error(boost::current_exception());
41  
            }
42  
        }
43  
44  
        template <typename Result, typename RemoteResult, typename Future>
45  
        void deferred_trigger(std::true_type,
46  
            typed_continuation<Result, RemoteResult>&& cont, Future&& result)
47  
        {
48  
            try {
49  
                HPX_ASSERT(result.is_ready());
50  
                result.get();                   // rethrow exceptions
51  
                cont.trigger();
52  
            }
53  
            catch (...) {
54  
                // make sure hpx::exceptions are propagated back to the client
55  
                cont.trigger_error(boost::current_exception());
56  
            }
57  
        }
58  
59  
        template <typename Result, typename RemoteResult, typename F, typename ...Ts>
60  
        void trigger_impl_future(std::true_type,
61  
            typed_continuation<Result, RemoteResult>&& cont, F&& f, Ts&&... vs)
62  
        {
63  
            typedef
64  
                typename std::is_same<RemoteResult, util::unused_type>::type
65  
                is_void;
66  
67  
            auto result = util::invoke(std::forward<F>(f),
68  
                std::forward<Ts>(vs)...);
69  
70  
            typedef typename hpx::util::decay<decltype(result)>::type future_type;
71  
72  
            if(result.is_ready())
73  
            {
74  
                detail::deferred_trigger<Result, RemoteResult>(
75  
                    is_void(), std::move(cont), std::move(result));
76  
                return;
77  
            }
78  
79  
            void (*fun)(is_void, typed_continuation<Result, RemoteResult>&&,
80  
                    future_type&&)
81  
                = &detail::deferred_trigger<Result, RemoteResult, future_type>;
82  
83  
            result.then(
84  
                hpx::util::bind(
85  
                    hpx::util::one_shot(fun)
86  
                  , is_void()
87  
                  , std::move(cont) //-V575
88  
                  , util::placeholders::_1
89  
                )
90  
            );
91  
        }
92  
93  
        template <typename Result, typename RemoteResult, typename F, typename ...Ts>
94  
        void trigger_impl(std::false_type,
95  
            typed_continuation<Result, RemoteResult>&& cont, F&& f, Ts&&... vs)
96  
        {
97  
            try {
98  
                cont.trigger_value(
99  
                        util::invoke(std::forward<F>(f), std::forward<Ts>(vs)...));
100  
            }
101  
            catch (...) {
102  
                // make sure hpx::exceptions are propagated back to the client
103  
                cont.trigger_error(boost::current_exception());
104  
            }
105  
        }
106  
107  
        // Overload when return type is "void" aka util::unused_type
108  
        template <typename Result, typename RemoteResult, typename F, typename ...Ts>
109  
        void trigger_impl(std::true_type, typed_continuation<Result, RemoteResult>&& cont,
110  
            F&& f, Ts&&... vs)
111  
        {
112  
            try {
113  
                util::invoke(std::forward<F>(f), std::forward<Ts>(vs)...);
114  
                cont.trigger();
115  
            }
116  
            catch (...) {
117  
                // make sure hpx::exceptions are propagated back to the client
118  
                cont.trigger_error(boost::current_exception());
119  
            }
120  
        }
121  
122  
        template <typename Result, typename RemoteResult, typename F, typename ...Ts>
123  
        void trigger_impl_future(std::false_type,
124  
            typed_continuation<Result, RemoteResult>&& cont, F&& f, Ts&&... vs)
125  
        {
126  
            typename std::is_same<RemoteResult, util::unused_type>::type is_void;
127  
128  
            trigger_impl(is_void, std::move(cont), std::forward<F>(f),
129  
                std::forward<Ts>(vs)...);
130  
        }
131  
    }
132  
133  
    template <typename Result, typename RemoteResult, typename F, typename ...Ts>
134  
    void trigger(typed_continuation<Result, RemoteResult>&& cont,
135  
        F&& f, Ts&&... vs)
136  
    {
137  
        typedef typename util::result_of<F(Ts...)>::type result_type;
138  
        traits::is_future<result_type> is_future;
139  
140  
        detail::trigger_impl_future(is_future, std::move(cont),
141  
            std::forward<F>(f), std::forward<Ts>(vs)...);
142  
    }
143  
}}
144  
145  
#endif
146  

Copyright (c) 2006-2012 Rogue Wave Software, Inc. All Rights Reserved.
Patents pending.