Permalink
Browse files

Fix the mapping of l-value references (hpx::lcos::shared_future)

* Add some unit tests to ensure the behaviour
  • Loading branch information...
Naios committed Jul 7, 2017
1 parent 2ef735b commit 444b431f8984e87e167a06656e06f565869c9a9b
Showing with 74 additions and 3 deletions.
  1. +9 −3 hpx/util/detail/pack_traversal_impl.hpp
  2. +65 −0 tests/unit/util/pack_traversal.cpp
@@ -658,6 +658,13 @@ namespace util {
std::forward<T>(element));
}
/// Boxes the given values into an according tuple
template <typename... T>
tuple<T...> box(T&&... args)
{
return tuple<T...>{std::forward<T>(args)...};
}
public:
explicit mapping_helper(M mapper)
: mapper_(std::move(mapper))
@@ -678,16 +685,15 @@ namespace util {
template <typename First, typename Second, typename... T>
auto init_traverse(strategy_remap_tag strategy, First&& first,
Second&& second, T&&... rest)
-> decltype(util::make_tuple(
-> decltype(std::declval<mapping_helper>().box(
std::declval<mapping_helper>().try_traverse(
strategy, std::forward<First>(first)),
std::declval<mapping_helper>().try_traverse(
strategy, std::forward<Second>(second)),
std::declval<mapping_helper>().try_traverse(
strategy, std::forward<T>(rest))...))
{
return util::make_tuple(
try_traverse(strategy, std::forward<First>(first)),
return box(try_traverse(strategy, std::forward<First>(first)),
try_traverse(strategy, std::forward<Second>(second)),
try_traverse(strategy, std::forward<T>(rest))...);
}
@@ -489,6 +489,47 @@ static void testStrategicTraverse()
int res = map_pack([](int i) { return i; }, 1);
HPX_TEST_EQ(res, 1);
}
// Make it possible to pass move only objects in as reference,
// while returning those as reference.
{
std::unique_ptr<int> ptr(new int(7));
std::unique_ptr<int> const& ref = map_pack(
[](std::unique_ptr<int> const& ref) -> std::unique_ptr<int> const& {
// ...
return ref;
},
ptr);
HPX_TEST_EQ(*ref, 7);
*ptr = 0;
HPX_TEST_EQ(*ref, 0);
}
// Multiple args: Make it possible to pass move only objects in
// as reference, while returning those as reference.
{
std::unique_ptr<int> ptr1(new int(6));
std::unique_ptr<int> ptr2(new int(7));
hpx::util::tuple<std::unique_ptr<int> const&,
std::unique_ptr<int> const&>
ref = map_pack(
[](std::unique_ptr<int> const& ref)
-> std::unique_ptr<int> const& {
// ...
return ref;
},
ptr1, ptr2);
HPX_TEST_EQ((*get<0>(ref)), 6);
HPX_TEST_EQ((*get<1>(ref)), 7);
*ptr1 = 1;
*ptr2 = 2;
HPX_TEST_EQ((*get<0>(ref)), 1);
HPX_TEST_EQ((*get<1>(ref)), 2);
}
}
static void testStrategicContainerTraverse()
@@ -644,6 +685,30 @@ static void testStrategicTupleLikeTraverse()
HPX_TEST((res == std::array<float, 3>{{1.f, 1.f, 1.f}}));
}
#endif
// Make it possible to pass tuples containing move only objects
// in as reference, while returning those as reference.
{
auto value = hpx::util::make_tuple(
std::unique_ptr<int>(new int(6)), std::unique_ptr<int>(new int(7)));
hpx::util::tuple<std::unique_ptr<int> const&,
std::unique_ptr<int> const&>
ref = map_pack(
[](std::unique_ptr<int> const& ref)
-> std::unique_ptr<int> const& {
// ...
return ref;
},
value);
HPX_TEST_EQ((*get<0>(ref)), 6);
HPX_TEST_EQ((*get<1>(ref)), 7);
(*get<0>(ref)) = 1;
(*get<1>(ref)) = 2;
HPX_TEST_EQ((*get<0>(ref)), 1);
HPX_TEST_EQ((*get<1>(ref)), 2);
}
}
int main(int, char**)

0 comments on commit 444b431

Please sign in to comment.