Skip to content

Commit db85e60

Browse files
committed
async: add hpx::async<^^func>(target, ...) reflection overload
Adds a new hpx::async overload that accepts a std::meta::info reflection of a free function as a non-type template parameter, eliminating the need to define an explicit action type: // Before: explicit action type required using my_action = hpx::actions::reflect_action<^^app::compute>; hpx::async<my_action>(target, args...); // After: direct reflection syntax hpx::async<^^app::compute>(target, args...); The overload is constrained to accept only viable distributed targets (hpx::id_type, client types, distribution policies), matching the existing async_action_dispatch specializations. Internally it constructs reflect_action<F>{} and delegates to the existing hpx::async(action, target, ...) machinery — no changes to dispatch internals required. Guarded by HPX_HAVE_CXX26_REFLECTION. Suggested by hkaiser as a natural extension of the reflection-based action work from PRs TheHPXProject#7298, TheHPXProject#7311, TheHPXProject#7342, TheHPXProject#7349. Signed-off-by: Priyanshi507 <hiiuiuiabi@gmail.com>
1 parent 71a7cca commit db85e60

4 files changed

Lines changed: 98 additions & 0 deletions

File tree

libs/full/actions_base/tests/unit/reflect_action_test.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,16 @@ int main()
141141
hpx::naming::component_type comptype{};
142142
direct_broadcast::invoke(lva, comptype, 42);
143143
}
144+
// Test: hpx::async<^^func> overload exists and is well-formed
145+
// (compile-time check only -- full dispatch requires a live HPX locality)
146+
{
147+
// Verify the overload is accessible and reflect_action<F> is
148+
// constructible from std::meta::info, which is the foundation
149+
// of the hpx::async<^^func>(target, ...) syntax.
150+
using action_type = hpx::actions::reflect_action<^^app::compute>;
151+
static_assert(std::is_default_constructible_v<action_type>,
152+
"reflect_action must be default constructible for async overload");
153+
}
144154
return hpx::util::report_errors();
145155
}
146156

libs/full/async_distributed/include/hpx/async_distributed/async.hpp

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -218,6 +218,27 @@ namespace hpx {
218218
return detail::async_action_dispatch<Action, std::decay_t<F>>::call(
219219
HPX_FORWARD(F, f), HPX_FORWARD(Ts, ts)...);
220220
}
221+
222+
#if defined(HPX_HAVE_CXX26_REFLECTION)
223+
/// \brief Reflection-based async overload.
224+
///
225+
/// Allows calling hpx::async<^^func>(target, ...) directly without
226+
/// defining an explicit action type. Internally constructs
227+
/// reflect_action<F> and delegates to the existing async machinery.
228+
///
229+
/// \tparam F A std::meta::info reflection of a free function.
230+
/// \tparam Target id_type, client, or distribution policy.
231+
/// \tparam Ts Additional arguments to pass to the function.
232+
template <std::meta::info F, typename Target, typename... Ts>
233+
requires(std::is_same_v<std::decay_t<Target>, hpx::id_type> ||
234+
hpx::traits::is_client_v<std::decay_t<Target>> ||
235+
hpx::traits::is_distribution_policy_v<std::decay_t<Target>>)
236+
HPX_CXX_EXPORT HPX_FORCEINLINE auto async(Target&& target, Ts&&... ts)
237+
{
238+
return hpx::async(hpx::actions::reflect_action<F>{},
239+
HPX_FORWARD(Target, target), HPX_FORWARD(Ts, ts)...);
240+
}
241+
#endif // HPX_HAVE_CXX26_REFLECTION
221242
} // namespace hpx
222243

223244
///////////////////////////////////////////////////////////////////////////////

libs/full/async_distributed/tests/unit/CMakeLists.txt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,11 @@ set(tests
3434
set(async_continue_PARAMETERS LOCALITIES 2)
3535
set(async_continue_cb_PARAMETERS LOCALITIES 2)
3636
set(async_remote_PARAMETERS LOCALITIES 2)
37+
38+
if(HPX_WITH_CXX26_REFLECTION)
39+
set(tests ${tests} async_remote_reflect)
40+
set(async_remote_reflect_PARAMETERS LOCALITIES 2)
41+
endif()
3742
set(async_remote_client_PARAMETERS LOCALITIES 2)
3843
set(async_cb_remote_PARAMETERS LOCALITIES 2)
3944
set(async_cb_remote_client_PARAMETERS LOCALITIES 2)
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
// Copyright (c) 2026 Priyanshi Sharma
2+
//
3+
// SPDX-License-Identifier: BSL-1.0
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+
#include <hpx/config.hpp>
8+
#if !defined(HPX_COMPUTE_DEVICE_CODE)
9+
#if defined(HPX_HAVE_CXX26_REFLECTION)
10+
11+
#include <hpx/hpx_init.hpp>
12+
#include <hpx/include/actions.hpp>
13+
#include <hpx/include/async.hpp>
14+
#include <hpx/include/runtime.hpp>
15+
#include <hpx/modules/testing.hpp>
16+
17+
#include <cstdint>
18+
#include <vector>
19+
20+
///////////////////////////////////////////////////////////////////////////////
21+
std::int32_t reflect_increment(std::int32_t i)
22+
{
23+
return i + 1;
24+
}
25+
HPX_PLAIN_ACTION(reflect_increment)
26+
27+
///////////////////////////////////////////////////////////////////////////////
28+
void test_async_reflect(hpx::id_type const& target)
29+
{
30+
// Test: hpx::async<^^func>(target, ...) -- reflection-based syntax
31+
// No explicit action type needed
32+
{
33+
hpx::future<std::int32_t> f1 =
34+
hpx::async<^^reflect_increment>(target, 42);
35+
HPX_TEST_EQ(f1.get(), 43);
36+
}
37+
{
38+
hpx::future<std::int32_t> f1 =
39+
hpx::async<^^reflect_increment>(hpx::launch::async, target, 42);
40+
HPX_TEST_EQ(f1.get(), 43);
41+
}
42+
}
43+
44+
int hpx_main()
45+
{
46+
std::vector<hpx::id_type> localities = hpx::find_all_localities();
47+
for (hpx::id_type const& id : localities)
48+
{
49+
test_async_reflect(id);
50+
}
51+
return hpx::finalize();
52+
}
53+
54+
int main(int argc, char* argv[])
55+
{
56+
HPX_TEST_EQ_MSG(
57+
hpx::init(argc, argv), 0, "HPX main exited with non-zero status");
58+
return hpx::util::report_errors();
59+
}
60+
61+
#endif // HPX_HAVE_CXX26_REFLECTION
62+
#endif // HPX_COMPUTE_DEVICE_CODE

0 commit comments

Comments
 (0)