Skip to content

Commit

Permalink
Fix tuple_cat when using l-value references
Browse files Browse the repository at this point in the history
* Add basic unit tests to ensure the correctness of tuple_cat.
  • Loading branch information
Naios committed Jul 27, 2017
1 parent 5c208ae commit dcfb503
Show file tree
Hide file tree
Showing 2 changed files with 43 additions and 24 deletions.
38 changes: 14 additions & 24 deletions hpx/util/tuple.hpp
Expand Up @@ -746,6 +746,7 @@ namespace hpx { namespace util
//constexpr tuple<Ctypes ...> tuple_cat(Tuples&&...);
namespace detail
{
/// Deduces to the overall size of all given tuples
template <std::size_t Size, typename Tuples>
struct tuple_cat_size_impl;

Expand Down Expand Up @@ -782,18 +783,12 @@ namespace hpx { namespace util
{
typedef tuple_element<I, Head> base_type;

template <typename THead, typename... TTail>
static HPX_CONSTEXPR HPX_HOST_DEVICE HPX_FORCEINLINE
typename base_type::type&
get(Head& head, Tail& ...tail) noexcept
auto get(THead&& head, TTail&&... /*tail*/) noexcept
-> decltype(base_type::get(std::forward<THead>(head)))
{
return base_type::get(head);
}

static HPX_CONSTEXPR HPX_HOST_DEVICE HPX_FORCEINLINE
typename base_type::type const&
get(Head const& head, Tail& ...tail) noexcept
{
return base_type::get(head);
return base_type::get(std::forward<THead>(head));
}
};

Expand All @@ -813,18 +808,12 @@ namespace hpx { namespace util
, detail::pack<Tail...>
> base_type;

template <typename THead, typename... TTail>
static HPX_CONSTEXPR HPX_HOST_DEVICE HPX_FORCEINLINE
typename base_type::type&
get(Head& head, Tail& ...tail) noexcept
{
return base_type::get(tail...);
}

static HPX_CONSTEXPR HPX_HOST_DEVICE HPX_FORCEINLINE
typename base_type::type const&
get(Head const& head, Tail& ...tail) noexcept
auto get(THead&& /*head*/, TTail&&... tail) noexcept
-> decltype(base_type::get(std::forward<TTail>(tail)...))
{
return base_type::get(tail...);
return base_type::get(std::forward<TTail>(tail)...);
}
};

Expand Down Expand Up @@ -861,11 +850,12 @@ namespace hpx { namespace util

template <typename ...Tuples>
HPX_CONSTEXPR HPX_HOST_DEVICE HPX_FORCEINLINE
typename detail::tuple_cat_result<Tuples...>::type
tuple_cat(Tuples&&... tuples)
typename detail::tuple_cat_result<
typename std::decay<Tuples>::type...>::type
tuple_cat(Tuples&&... tuples)
{
return detail::tuple_cat_result<Tuples...>::make(
std::forward<Tuples>(tuples)...);
return detail::tuple_cat_result<typename std::decay<Tuples>::type...>::
make(std::forward<Tuples>(tuples)...);
}

// 20.4.2.7, relational operators
Expand Down
29 changes: 29 additions & 0 deletions tests/unit/util/tuple.cpp
Expand Up @@ -328,6 +328,34 @@ void tie_test()
}


// ----------------------------------------------------------------------------
// - testing cat -----------------------------------------------------------
// ----------------------------------------------------------------------------
void tuple_cat_test()
{
hpx::util::tuple<int, float> two = hpx::util::make_tuple(1, 2.f);

// Cat two tuples
{
hpx::util::tuple<int, float, int, float> res =
hpx::util::tuple_cat(two, two);

auto expected = hpx::util::make_tuple(1, 2.f, 1, 2.f);

HPX_TEST((res == expected));
}

// Cat multiple tuples
{
hpx::util::tuple<int, float, int, float, int, float> res =
hpx::util::tuple_cat(two, two, two);

auto expected = hpx::util::make_tuple(1, 2.f, 1, 2.f, 1, 2.f);

HPX_TEST((res == expected));
}
}

// ----------------------------------------------------------------------------
// - testing tuple equality -------------------------------------------------
// ----------------------------------------------------------------------------
Expand Down Expand Up @@ -429,6 +457,7 @@ int main(int argc, char* argv[])
mutate_test();
make_tuple_test();
tie_test();
tuple_cat_test();
equality_test();
ordering_test();
const_tuple_test();
Expand Down

0 comments on commit dcfb503

Please sign in to comment.