1 // Copyright (c) 2017 Antoine TRAN TAN 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 /// \file hpx/runtime/actions/make_action.hpp 7 8 #ifndef HPX_RUNTIME_ACTIONS_LAMBDA_TO_ACTION_HPP 9 #define HPX_RUNTIME_ACTIONS_LAMBDA_TO_ACTION_HPP 10 11 #include <hpx/include/plain_actions.hpp> 12 #include <string> 13 #include <type_traits> 14 #include <utility> 15 16 namespace hpx { namespace actions 17 { 18 /// \cond NOINTERNAL 19 20 /////////////////////////////////////////////////////////////////////////// 21 namespace detail 22 { 23 // Helpers to actionize a lambda 24 25 template <typename ... T> 26 struct sequence 27 {}; 28 29 struct addr_add 30 { 31 template<class T> 32 friend typename std::remove_reference<T>::type * operator +(addr_add,T && t)33 operator+(addr_add, T &&t) 34 { 35 return &t; 36 } 37 }; 38 39 40 template<typename F, typename ReturnType, typename... Args> 41 struct lambda_action 42 : basic_action<detail::plain_function, ReturnType(Args...), 43 lambda_action<F, ReturnType, Args...>> 44 { 45 typedef lambda_action derived_type; 46 typedef std::false_type direct_execution; 47 typedef void is_plain_action; 48 get_action_namehpx::actions::detail::lambda_action49 static std::string get_action_name(naming::address::address_type /*lva*/) 50 { 51 return "lambda action()"; 52 } 53 54 template <typename ...Ts> invokehpx::actions::detail::lambda_action55 static ReturnType invoke(naming::address::address_type /*lva*/, 56 naming::address::component_type comptype, Ts&&... vs) 57 { 58 int * dummy = nullptr; 59 return reinterpret_cast<const F&>(*dummy)( std::forward<Ts>(vs)... ); 60 } 61 }; 62 63 template <typename F, typename T> 64 struct extract_lambda_action 65 {}; 66 67 // Specialization for lambdas 68 template <typename F, typename ClassType, typename ReturnType, typename... Args> 69 struct extract_lambda_action<F, ReturnType(ClassType::*)(Args...) const> 70 { 71 using type = lambda_action<F, ReturnType, Args...>; 72 }; 73 74 template <typename F> 75 struct action_from_lambda 76 { 77 using type = 78 typename extract_lambda_action<F, decltype(&F::operator())>::type; 79 }; 80 81 struct action_maker 82 { 83 template<typename F> 84 HPX_CONSTEXPR typename hpx::actions::detail::action_from_lambda<F>::type operator +=hpx::actions::detail::action_maker85 operator += (F*) const 86 { 87 static_assert( 88 //!std::is_assignable<F,F>::value && 89 std::is_empty<F>::value, 90 "lambda_to_action() needs and only needs a lambda with empty " \ 91 "capture list"); 92 93 return typename 94 hpx::actions::detail::action_from_lambda<F>::type(); 95 } 96 }; 97 } 98 99 template<typename F> lambda_to_action(F && f)100 auto lambda_to_action(F&& f) 101 -> decltype( hpx::actions::detail::action_maker() += true 102 ? nullptr 103 : hpx::actions::detail::addr_add() + f) 104 { 105 HPX_CONSTEXPR auto act = 106 hpx::actions::detail::action_maker() += true 107 ? nullptr 108 : hpx::actions::detail::addr_add() + f; 109 110 return act; 111 } 112 }} 113 114 #endif /*HPX_RUNTIME_ACTIONS_LAMBDA_TO_ACTION_HPP*/ 115