1 //  Copyright (c) 2007-2018 Hartmut Kaiser
2 //
3 //  Distributed under the Boost Software License, Version 1.0. (See accompanying
4 //  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
5 
6 #if !defined(HPX_TRAITS_ACTION_DECORATE_FUNCTION_MAR_30_2014_1054AM)
7 #define HPX_TRAITS_ACTION_DECORATE_FUNCTION_MAR_30_2014_1054AM
8 
9 #include <hpx/runtime/naming_fwd.hpp>
10 #include <hpx/runtime/threads/thread_data_fwd.hpp>
11 #include <hpx/traits/detail/wrap_int.hpp>
12 #include <hpx/traits/has_xxx.hpp>
13 #include <hpx/util/unique_function.hpp>
14 
15 #include <type_traits>
16 #include <utility>
17 
18 namespace hpx { namespace traits
19 {
20     ///////////////////////////////////////////////////////////////////////////
21     // Customization point for action capabilities
22     namespace detail
23     {
24         struct decorate_function_helper
25         {
26             // by default we return the unchanged function
27             template <typename Component, typename F>
28             static threads::thread_function_type
callhpx::traits::detail::decorate_function_helper29             call(wrap_int, naming::address_type /*lva*/, F && f)
30             {
31                 return std::forward<F>(f);
32             }
33 
34             // forward the call if the component implements the function
35             template <typename Component, typename F>
36             static auto
callhpx::traits::detail::decorate_function_helper37             call(int, naming::address_type lva, F && f)
38             ->  decltype(Component::decorate_action(lva, std::forward<F>(f)))
39             {
40                 return Component::decorate_action(lva, std::forward<F>(f));
41             }
42         };
43 
44         template <typename Component, typename F>
45         threads::thread_function_type
call_decorate_function(naming::address_type lva,F && f)46         call_decorate_function(naming::address_type lva, F && f)
47         {
48             return decorate_function_helper::template call<Component>(
49                 0, lva, std::forward<F>(f));
50         }
51 
52         HPX_HAS_XXX_TRAIT_DEF(decorates_action);
53     }
54 
55     template <typename Action, typename Enable = void>
56     struct has_decorates_action
57       : detail::has_decorates_action<
58             typename std::decay<Action>::type::component_type>
59     {};
60 
61     template <typename Action, typename Enable = void>
62     struct action_decorate_function
63     {
64         static constexpr bool value = has_decorates_action<Action>::value;
65 
66         template <typename F>
67         static threads::thread_function_type
callhpx::traits::action_decorate_function68         call(naming::address_type lva, F && f)
69         {
70             typedef typename std::decay<Action>::type::component_type
71                 component_type;
72             return detail::call_decorate_function<component_type>(
73                 lva, std::forward<F>(f));
74         }
75     };
76 
77     template <typename Action, typename Enable = void>
78     struct component_decorates_action
79       : detail::has_decorates_action<typename std::decay<Action>::type>
80     {};
81 
82     template <typename Component, typename Enable = void>
83     struct component_decorate_function
84     {
85         template <typename F>
86         static threads::thread_function_type
callhpx::traits::component_decorate_function87         call(naming::address_type lva, F && f)
88         {
89             return detail::call_decorate_function<Component>(
90                 lva, std::forward<F>(f));
91         }
92     };
93 }}
94 
95 #endif
96 
97