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