From 905fcd01f634bdbc0b5c2d9658f7fc85b7d84f73 Mon Sep 17 00:00:00 2001 From: Nahuel Espinosa Date: Sat, 13 Jan 2024 12:23:18 -0300 Subject: [PATCH] Add move only range test Signed-off-by: Nahuel Espinosa --- beluga/include/beluga/actions/assign.hpp | 6 ++++++ beluga/test/beluga/actions/test_assign.cpp | 13 +++++++++++++ 2 files changed, 19 insertions(+) diff --git a/beluga/include/beluga/actions/assign.hpp b/beluga/include/beluga/actions/assign.hpp index e4b9dd5b6..dd738e583 100644 --- a/beluga/include/beluga/actions/assign.hpp +++ b/beluga/include/beluga/actions/assign.hpp @@ -84,6 +84,12 @@ struct assign_fn { /** * This can be appended to any view closure to evaluate it eagerly and assign the result * to a given range, effectively converting any view into an action. + * + * The assignment of elements into the container may involve copy which can be less efficient than + * move because lvalue references are produced during the indirection call. Users can opt-in to use + * `ranges::views::move` to adapt the range in order for their elements to always produce an rvalue + * reference during the indirection call which implies move. In this case, make sure that the input + * views don't require accessing the elements in the adapted range more than once. */ inline constexpr detail::assign_fn assign; diff --git a/beluga/test/beluga/actions/test_assign.cpp b/beluga/test/beluga/actions/test_assign.cpp index d96ef6a2d..a2c3157ef 100644 --- a/beluga/test/beluga/actions/test_assign.cpp +++ b/beluga/test/beluga/actions/test_assign.cpp @@ -22,9 +22,12 @@ #include #include #include +#include #include #include +#include + namespace { TEST(AssignAction, ViewToAction) { @@ -33,6 +36,16 @@ TEST(AssignAction, ViewToAction) { ASSERT_TRUE(ranges::equal(input, std::vector{3, 2, 1})); } +TEST(AssignAction, MoveOnlyRange) { + auto input = std::vector>{}; + input.emplace_back(std::make_unique(1)); + input.emplace_back(std::make_unique(2)); + input.emplace_back(std::make_unique(3)); + input |= ranges::views::move | ranges::views::reverse | beluga::actions::assign; + ASSERT_EQ(*input.front(), 3); + ASSERT_EQ(*input.back(), 1); +} + TEST(AssignAction, ViewToActionComposition) { auto reverse_and_assign = ranges::views::reverse | beluga::actions::assign; auto input = std::vector{1, 2, 3};