From 925d82e6d07be769a9eab7e7aeacc9f9fae9f2d0 Mon Sep 17 00:00:00 2001 From: Priyanshi507 Date: Wed, 20 May 2026 00:22:34 +0000 Subject: [PATCH 1/3] actions_base: integrate reflect_action with basic_action reflect_action now inherits from: basic_action> This provides all typedefs required by transfer_action: component_type, derived_type, result_type, arguments_type, local_result_type, remote_result_type, direct_execution, etc. Uses two-step workaround for GCC/Clang restriction on splice expressions as template arguments: using func_type = [:std::meta::type_of(F):]; // in helper basic_action<..., func_type, ...> // then use alias get_action_name() now returns HPX format 'plain action(app::compute)' matching make_plain_action_name output. invoke() calls func_ptr with forwarded arguments. Signed-off-by: Priyanshi507 --- .../hpx/actions_base/reflect_action.hpp | 66 ++++++++++++------- 1 file changed, 41 insertions(+), 25 deletions(-) diff --git a/libs/full/actions_base/include/hpx/actions_base/reflect_action.hpp b/libs/full/actions_base/include/hpx/actions_base/reflect_action.hpp index 15eb4f2443c..c7a5a941b40 100644 --- a/libs/full/actions_base/include/hpx/actions_base/reflect_action.hpp +++ b/libs/full/actions_base/include/hpx/actions_base/reflect_action.hpp @@ -6,43 +6,52 @@ /// \file reflect_action.hpp /// \brief Reflection-based action definition for HPX remote operations. -/// -/// This header provides reflect_action, a C++26 reflection-based -/// replacement for the HPX_PLAIN_ACTION and HPX_REGISTER_ACTION macros. -/// Instead of verbose boilerplate, users write a single line: -/// -/// using compute_action = HPX_ACTION(app::compute); -/// -/// The action name, function pointer type, arity, and registration are -/// all derived automatically at compile time using C++26 static reflection. - #pragma once #include #if defined(HPX_HAVE_CXX26_REFLECTION) +#include +#include #include #include #include +#include #include namespace hpx::actions { + /// \cond NOINTERNAL + namespace detail { + + /// Helper to extract function type from reflection for use + /// as basic_action template argument (two-step workaround for + /// GCC/Clang restriction on splice expressions as template args). + template + struct reflect_action_base + { + using func_type = [:std::meta::type_of(F):]; + using type = basic_action>; + }; + + } // namespace detail + /// \endcond + /// \brief Reflection-based action template. /// - /// reflect_action provides the same interface as HPX_PLAIN_ACTION - /// but derives all properties automatically from the reflected function F: - /// - Qualified name via scope_builder - /// - Function pointer type via std::meta::type_of(F) - /// - Function pointer via splicing [:F:] - /// - Arity via std::meta::parameters_of(F).size() + /// reflect_action integrates with HPX's action system by inheriting + /// from basic_action>. + /// All properties are derived automatically from the reflected function F. /// /// \tparam F A std::meta::info reflection of a free function. - /// Obtain via the reflection operator: ^^app::my_function template struct reflect_action + : basic_action::func_type, + reflect_action> { /// The function type (e.g. int(double, double)) using func_type = [:std::meta::type_of(F):]; @@ -57,16 +66,23 @@ namespace hpx::actions { static constexpr auto name_storage = hpx::serialization::detail::scope_builder::value; - /// Number of parameters the function takes - static constexpr std::size_t arity = std::meta::parameters_of(F).size(); + /// Returns the action name in HPX format: "plain action(app::compute)" + static std::string get_action_name( + naming::address::address_type /*lva*/) + { + return hpx::actions::detail::make_plain_action_name( + std::string_view(name_storage.data, name_storage.size)); + } - /// Returns the fully qualified name of the action. - /// Called by hpx::actions::detail::register_action during - /// static initialization to register this action with the - /// HPX action registry. - static consteval char const* get_action_name() noexcept + /// Invokes the reflected function with the given arguments. + template + static auto invoke(naming::address::address_type /*lva*/, + naming::address::component_type /*comptype*/, Ts&&... vs) { - return name_storage.data; + using base_t = basic_action>; + base_t::increment_invocation_count(); + return func_ptr(HPX_FORWARD(Ts, vs)...); } }; From 21f61dea398e060df046f50da41984c6ac6b7280 Mon Sep 17 00:00:00 2001 From: Priyanshi507 Date: Wed, 20 May 2026 00:26:47 +0000 Subject: [PATCH 2/3] actions_base: update reflect_action tests for basic_action integration - get_action_name() now takes lva argument (nullptr in tests) - Name format updated to 'plain action(app::compute)' matching make_plain_action_name output Signed-off-by: Priyanshi507 --- .../tests/unit/reflect_action_test.cpp | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/libs/full/actions_base/tests/unit/reflect_action_test.cpp b/libs/full/actions_base/tests/unit/reflect_action_test.cpp index 76168c2b36c..58a2676f75f 100644 --- a/libs/full/actions_base/tests/unit/reflect_action_test.cpp +++ b/libs/full/actions_base/tests/unit/reflect_action_test.cpp @@ -47,29 +47,29 @@ int main() // Test: action name extraction for simple namespace function { HPX_ACTION(app::compute, compute_action); - HPX_TEST_EQ(std::string(compute_action::get_action_name()), - std::string("app::compute")); + HPX_TEST_EQ(std::string(compute_action::get_action_name(nullptr)), + std::string("plain action(app::compute)")); } // Test: action name extraction for void noexcept function { HPX_ACTION(app::broadcast, broadcast_action); - HPX_TEST_EQ(std::string(broadcast_action::get_action_name()), - std::string("app::broadcast")); + HPX_TEST_EQ(std::string(broadcast_action::get_action_name(nullptr)), + std::string("plain action(app::broadcast)")); } // Test: action name extraction for multiple parameters { HPX_ACTION(app::transform, transform_action); - HPX_TEST_EQ(std::string(transform_action::get_action_name()), - std::string("app::transform")); + HPX_TEST_EQ(std::string(transform_action::get_action_name(nullptr)), + std::string("plain action(app::transform)")); } // Test: action name extraction for nested namespace { HPX_ACTION(app::nested::deep_compute, deep_action); - HPX_TEST_EQ(std::string(deep_action::get_action_name()), - std::string("app::nested::deep_compute")); + HPX_TEST_EQ(std::string(deep_action::get_action_name(nullptr)), + std::string("plain action(app::nested::deep_compute)")); } // Test: arity extraction From 92d9971f75399e10465843cc102c766cc0f4e4b5 Mon Sep 17 00:00:00 2001 From: Priyanshi507 Date: Wed, 20 May 2026 14:43:00 +0000 Subject: [PATCH 3/3] actions_base: use hpx/modules/serialization.hpp for C++20 module support Signed-off-by: Priyanshi507 --- .../actions_base/include/hpx/actions_base/reflect_action.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libs/full/actions_base/include/hpx/actions_base/reflect_action.hpp b/libs/full/actions_base/include/hpx/actions_base/reflect_action.hpp index c7a5a941b40..1ac41ed11fb 100644 --- a/libs/full/actions_base/include/hpx/actions_base/reflect_action.hpp +++ b/libs/full/actions_base/include/hpx/actions_base/reflect_action.hpp @@ -14,7 +14,7 @@ #include #include -#include +#include #include #include