From dcfb50363a3efd939f1c6eadd97640afbcc120e6 Mon Sep 17 00:00:00 2001 From: Denis Blank Date: Fri, 14 Jul 2017 14:32:49 +0200 Subject: [PATCH] Fix tuple_cat when using l-value references * Add basic unit tests to ensure the correctness of tuple_cat. --- hpx/util/tuple.hpp | 38 ++++++++++++++------------------------ tests/unit/util/tuple.cpp | 29 +++++++++++++++++++++++++++++ 2 files changed, 43 insertions(+), 24 deletions(-) diff --git a/hpx/util/tuple.hpp b/hpx/util/tuple.hpp index a1c1e9b68e93..f632dc732c31 100644 --- a/hpx/util/tuple.hpp +++ b/hpx/util/tuple.hpp @@ -746,6 +746,7 @@ namespace hpx { namespace util //constexpr tuple tuple_cat(Tuples&&...); namespace detail { + /// Deduces to the overall size of all given tuples template struct tuple_cat_size_impl; @@ -782,18 +783,12 @@ namespace hpx { namespace util { typedef tuple_element base_type; + template 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(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(head)); } }; @@ -813,18 +808,12 @@ namespace hpx { namespace util , detail::pack > base_type; + template 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(tail)...)) { - return base_type::get(tail...); + return base_type::get(std::forward(tail)...); } }; @@ -861,11 +850,12 @@ namespace hpx { namespace util template HPX_CONSTEXPR HPX_HOST_DEVICE HPX_FORCEINLINE - typename detail::tuple_cat_result::type - tuple_cat(Tuples&&... tuples) + typename detail::tuple_cat_result< + typename std::decay::type...>::type + tuple_cat(Tuples&&... tuples) { - return detail::tuple_cat_result::make( - std::forward(tuples)...); + return detail::tuple_cat_result::type...>:: + make(std::forward(tuples)...); } // 20.4.2.7, relational operators diff --git a/tests/unit/util/tuple.cpp b/tests/unit/util/tuple.cpp index d83cf799d876..dcf55f92ba1c 100644 --- a/tests/unit/util/tuple.cpp +++ b/tests/unit/util/tuple.cpp @@ -328,6 +328,34 @@ void tie_test() } +// ---------------------------------------------------------------------------- +// - testing cat ----------------------------------------------------------- +// ---------------------------------------------------------------------------- +void tuple_cat_test() +{ + hpx::util::tuple two = hpx::util::make_tuple(1, 2.f); + + // Cat two tuples + { + hpx::util::tuple 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 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 ------------------------------------------------- // ---------------------------------------------------------------------------- @@ -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();