Permalink
Browse files

Fix the mapping of arrray like heterogeneous containers

  • Loading branch information...
Naios committed Jul 5, 2017
1 parent a0b96c0 commit 2ef735bff61d23858a70aa37e53b100e5c559963
Showing with 34 additions and 6 deletions.
  1. +7 −6 hpx/util/detail/pack_traversal_impl.hpp
  2. +27 −0 tests/unit/util/pack_traversal.cpp
@@ -337,7 +337,7 @@ namespace util {
/// Specialization for std::tuple like types which contain
/// an arbitrary amount of heterogenous arguments.
template <typename M, template <class...> class Base,
template <typename M, template <typename...> class Base,
typename... OldArgs>
struct tuple_like_remapper<strategy_remap_tag, M, Base<OldArgs...>
#ifdef HPX_HAVE_CXX11_SFINAE_EXPRESSION_COMPLETE
@@ -358,7 +358,7 @@ namespace util {
mapper_(std::forward<Args>(args))...};
}
};
template <typename M, template <class...> class Base,
template <typename M, template <typename...> class Base,
typename... OldArgs>
struct tuple_like_remapper<strategy_traverse_tag, M,
Base<OldArgs...>
@@ -384,7 +384,7 @@ namespace util {
/// Specialization for std::array like types, which contains a
/// compile-time known amount of homogeneous types.
template <typename M, template <class, std::size_t> class Base,
template <typename M, template <typename, std::size_t> class Base,
typename OldArg, std::size_t Size>
struct tuple_like_remapper<strategy_remap_tag, M, Base<OldArg, Size>
#ifdef HPX_HAVE_CXX11_SFINAE_EXPRESSION_COMPLETE
@@ -404,7 +404,7 @@ namespace util {
{mapper_(std::forward<Args>(args))...}};
}
};
template <typename M, template <class, std::size_t> class Base,
template <typename M, template <typename, std::size_t> class Base,
typename OldArg, std::size_t Size>
struct tuple_like_remapper<strategy_traverse_tag, M,
Base<OldArg, Size>
@@ -433,12 +433,13 @@ namespace util {
template <typename Strategy, typename T, typename M>
auto remap(Strategy, T&& container, M&& mapper) -> decltype(
invoke_fused(std::declval<tuple_like_remapper<Strategy,
typename std::decay<M>::type, T>>(),
typename std::decay<M>::type,
typename std::decay<T>::type>>(),
std::forward<T>(container)))
{
return invoke_fused(
tuple_like_remapper<Strategy, typename std::decay<M>::type,
T>{std::forward<M>(mapper)},
typename std::decay<T>::type>{std::forward<M>(mapper)},
std::forward<T>(container));
}
} // end namespace tuple_like_remapping
@@ -17,6 +17,10 @@
#include <utility>
#include <vector>
#if defined(HPX_HAVE_CXX11_STD_ARRAY)
#include <array>
#endif
using namespace hpx;
using namespace hpx::util;
using namespace hpx::util::detail;
@@ -467,6 +471,19 @@ static void testStrategicTraverse()
HPX_TEST_EQ((*get<2>(res)), 4U);
}
// Move only types contained in a pack which was passed as l-value
// reference is forwarded to the mapper as reference too.
{
std::vector<std::unique_ptr<int>> container;
container.push_back(std::unique_ptr<int>(new int(3)));
std::vector<int> res =
map_pack([](std::unique_ptr<int>& p) { return *p; }, container);
HPX_TEST_EQ(res.size(), 1U);
HPX_TEST_EQ(res[0], 3);
}
// Single object remapping returns the value itself without any boxing
{
int res = map_pack([](int i) { return i; }, 1);
@@ -617,6 +634,16 @@ static void testStrategicTupleLikeTraverse()
"Type mismatch!");
HPX_TEST((res == expected));
}
#if defined(HPX_HAVE_CXX11_STD_ARRAY)
// Fixed size homogeneous container
{
std::array<int, 3> values{{1, 2, 3}};
std::array<float, 3> res = map_pack([](int) { return 1.f; }, values);
HPX_TEST((res == std::array<float, 3>{{1.f, 1.f, 1.f}}));
}
#endif
}
int main(int, char**)

0 comments on commit 2ef735b

Please sign in to comment.