Permalink
Browse files

Fix a unit test failure on GCC in tuple_cat

* Add a test which targets the same issue on other toolchains
  • Loading branch information...
Naios committed Aug 2, 2017
1 parent 571f4d2 commit 4ea728d97aea6e3c5d13a879da7fbabae78df5eb
Showing with 42 additions and 20 deletions.
  1. +22 −17 hpx/util/tuple.hpp
  2. +20 −3 tests/unit/util/tuple.cpp
View
@@ -779,7 +779,7 @@ namespace hpx { namespace util
, typename std::enable_if<
(I < tuple_size<Head>::value)
>::type
>
> : tuple_element<I, Head>
{
template <typename THead, typename... TTail>
static HPX_CONSTEXPR HPX_HOST_DEVICE HPX_FORCEINLINE auto get(
@@ -816,26 +816,31 @@ namespace hpx { namespace util
};
///////////////////////////////////////////////////////////////////////
/// A helper function for creating a non owning tuple from the given
/// arguments. Which means that the funcitonality of this function
/// lies between make_tuple and forward_as_tuple.
template <typename... Ts>
tuple<Ts...> create_raw_tuple(Ts&&... args)
template <typename Indices, typename Tuples>
struct tuple_cat_result_impl;
template <std::size_t... Is, typename... Tuples>
struct tuple_cat_result_impl<pack_c<std::size_t, Is...>,
pack<Tuples...>>
{
return tuple<Ts...>{std::forward<Ts>(args)...};
}
using type =
tuple<typename tuple_cat_element<Is, pack<Tuples...>>::type...>;
};
template <typename Indices, typename Tuples>
using tuple_cat_result_of_t =
typename tuple_cat_result_impl<Indices, Tuples>::type;
template <std::size_t... Is, typename... Tuples, typename... Tuples_>
static HPX_CONSTEXPR HPX_HOST_DEVICE HPX_FORCEINLINE auto
tuple_cat_impl(detail::pack_c<std::size_t, Is...>,
detail::pack<Tuples...>, Tuples_&&... tuples)
-> decltype(create_raw_tuple(
tuple_cat_element<Is, detail::pack<Tuples...>>::get(
std::forward<Tuples_>(tuples)...)...))
HPX_CONSTEXPR HPX_HOST_DEVICE HPX_FORCEINLINE auto tuple_cat_impl(
pack_c<std::size_t, Is...> is_pack, pack<Tuples...> tuple_pack,
Tuples_&&... tuples)
-> tuple_cat_result_of_t<decltype(is_pack), decltype(tuple_pack)>
{
return create_raw_tuple(
tuple_cat_element<Is, detail::pack<Tuples...>>::get(
std::forward<Tuples_>(tuples)...)...);
return tuple_cat_result_of_t<decltype(is_pack),
decltype(tuple_pack)>{
tuple_cat_element<Is, pack<Tuples...>>::get(
std::forward<Tuples_>(tuples)...)...};
}
}
View
@@ -372,20 +372,37 @@ void tuple_cat_test()
HPX_TEST_EQ((*hpx::util::get<2>(result)), 2);
}
// Don't move references unconditionally
// Don't move references unconditionally (copyable types)
{
int i1 = 11;
int i2 = 22;
auto f1 = hpx::util::forward_as_tuple(i1);
auto f2 = hpx::util::forward_as_tuple(std::move(i2));
hpx::util::tuple<int&> f1 = hpx::util::forward_as_tuple(i1);
hpx::util::tuple<int&&> f2 = hpx::util::forward_as_tuple(std::move(i2));
hpx::util::tuple<int&, int&&> result =
hpx::util::tuple_cat(std::move(f1), std::move(f2));
HPX_TEST_EQ((hpx::util::get<0>(result)), 11);
HPX_TEST_EQ((hpx::util::get<1>(result)), 22);
}
// Don't move references unconditionally (move only types)
{
std::unique_ptr<int> i1(new int(11));
std::unique_ptr<int> i2(new int(22));
hpx::util::tuple<std::unique_ptr<int>&> f1 =
hpx::util::forward_as_tuple(i1);
hpx::util::tuple<std::unique_ptr<int>&&> f2 =
hpx::util::forward_as_tuple(std::move(i2));
hpx::util::tuple<std::unique_ptr<int>&, std::unique_ptr<int>&&> result =
hpx::util::tuple_cat(std::move(f1), std::move(f2));
HPX_TEST_EQ((*hpx::util::get<0>(result)), 11);
HPX_TEST_EQ((*hpx::util::get<1>(result)), 22);
}
}
// ----------------------------------------------------------------------------

0 comments on commit 4ea728d

Please sign in to comment.