Skip to content

Commit

Permalink
Making hpx::util::tuple<Ts...> and std::tuple<Ts...> convertible
Browse files Browse the repository at this point in the history
Fixes #1403 by allowing the use of hpx::util::get with std::tuple and
std::get with hpx::util::tuple::get. Same goes for the utilities
tuple_size and tuple_element.
An additional conversion operator from hpx::util::tuple<Ts..> to
std::tuple<Ts..> has been added to make the two types interchangable.

Flyby: Making the datastructures unit test only depend on itself and
hpx_testing: Adding hpx/traits/is_tuple_like.hpp
  • Loading branch information
sithhell authored and hkaiser committed Sep 25, 2019
1 parent 8f9678c commit 3299d77
Show file tree
Hide file tree
Showing 7 changed files with 126 additions and 23 deletions.
1 change: 1 addition & 0 deletions libs/datastructures/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ set(datastructures_headers
hpx/datastructures/optional.hpp
hpx/datastructures/detail/pack.hpp
hpx/traits/supports_streaming_with_any.hpp
hpx/traits/is_tuple_like.hpp
)

set(datastructures_compat_headers
Expand Down
79 changes: 79 additions & 0 deletions libs/datastructures/include/hpx/datastructures/tuple.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
#include <algorithm>
#include <array>
#include <cstddef> // for size_t
#include <tuple>
#include <type_traits>
#include <utility>

Expand All @@ -26,6 +27,11 @@
#pragma warning(disable : 4520) // multiple default constructors specified
#endif

#if defined(__clang__)
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wmismatched-tags"
#endif

namespace hpx { namespace util {
template <typename... Ts>
class tuple;
Expand Down Expand Up @@ -55,7 +61,26 @@ namespace hpx { namespace util {
HPX_CONSTEXPR HPX_HOST_DEVICE HPX_FORCEINLINE
typename tuple_element<I, Tuple>::type const&&
get(Tuple const&& t) noexcept;
}}

// Adapt hpx::util::tuple to be useable with std::tuple
namespace std
{
template <typename... Ts>
struct tuple_size<hpx::util::tuple<Ts...>>
: public hpx::util::tuple_size<hpx::util::tuple<Ts...>>
{};

template <std::size_t I, typename... Ts>
struct tuple_element<I, hpx::util::tuple<Ts...>>
: public hpx::util::tuple_element<I, hpx::util::tuple<Ts...>>
{};

using hpx::util::get;
}

namespace hpx { namespace util
{
namespace detail {
///////////////////////////////////////////////////////////////////////
template <std::size_t I, typename T, typename Enable = void>
Expand Down Expand Up @@ -307,6 +332,18 @@ namespace hpx { namespace util {
typename detail::at_index<I, Ts...>::type> const&>(*this)
.value();
}

HPX_HOST_DEVICE
operator std::tuple<Ts...>() const &
{
return std::make_tuple(get<Is>()...);
}

HPX_HOST_DEVICE
operator std::tuple<Ts...>() &&
{
return std::make_tuple(std::move(get<Is>())...);
}
};

///////////////////////////////////////////////////////////////////////
Expand Down Expand Up @@ -362,6 +399,11 @@ namespace hpx { namespace util {
// Calls swap for each element in *this and its corresponding element
// in rhs.
HPX_HOST_DEVICE void swap(tuple& /*other*/) noexcept {}

operator std::tuple<>() const
{
return std::tuple<>();
}
};

template <typename... Ts>
Expand Down Expand Up @@ -503,6 +545,16 @@ namespace hpx { namespace util {
{
_impl.swap(other._impl);
}

operator std::tuple<Ts...>() const&
{
return _impl;
}

operator std::tuple<Ts...>() &&
{
return _impl;
}
};

// 20.4.2.5, tuple helper classes
Expand Down Expand Up @@ -553,6 +605,11 @@ namespace hpx { namespace util {
{
};

template <typename ...Ts>
struct tuple_size<std::tuple<Ts...>>
: std::tuple_size<std::tuple<Ts...>>
{};

// template <size_t I, class Tuple>
// class tuple_element
template <std::size_t I, typename T>
Expand Down Expand Up @@ -668,6 +725,24 @@ namespace hpx { namespace util {
}
};

template <std::size_t I, typename ...Ts>
struct tuple_element<I, std::tuple<Ts...>>
{
using type = typename std::tuple_element<I, std::tuple<Ts...>>::type;

static HPX_CONSTEXPR HPX_HOST_DEVICE HPX_FORCEINLINE type&
get(std::tuple<Ts...>& tuple) noexcept
{
return std::get<I>(tuple);
}

static HPX_CONSTEXPR HPX_HOST_DEVICE HPX_FORCEINLINE type const&
get(std::tuple<Ts...> const& tuple) noexcept
{
return std::get<I>(tuple);
}
};

// 20.4.2.6, element access

// template <size_t I, class... Types>
Expand Down Expand Up @@ -1018,4 +1093,8 @@ namespace hpx { namespace util {
#pragma warning(pop)
#endif

#if defined(__clang__)
#pragma clang diagnostic pop
#endif

#endif
File renamed without changes.
3 changes: 2 additions & 1 deletion libs/datastructures/tests/unit/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,8 @@ foreach(test ${tests})
# add example executable
add_hpx_executable(${test}_test
SOURCES ${sources}
${${test}_FLAGS}
NOLIBS
DEPENDENCIES hpx_datastructures hpx_testing
EXCLUDE_FROM_ALL
FOLDER ${folder_name})

Expand Down
16 changes: 1 addition & 15 deletions libs/datastructures/tests/unit/any.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,8 @@
////////////////////////////////////////////////////////////////////////////////

#include <hpx/datastructures/any.hpp>
#include <hpx/hpx_init.hpp>
#include <hpx/testing.hpp>

#include <hpx/util/storage/tuple.hpp>

#include <iostream>
#include <sstream>
#include <string>
Expand All @@ -24,11 +21,8 @@ using hpx::util::any_cast;
using hpx::util::any_nonser;
using hpx::util::streamable_any_nonser;

using hpx::finalize;
using hpx::init;

///////////////////////////////////////////////////////////////////////////////
int hpx_main()
int main()
{
{
streamable_any_nonser any1(big_object(30, 40));
Expand Down Expand Up @@ -134,13 +128,5 @@ int hpx_main()
}
}

finalize();
return hpx::util::report_errors();
}

///////////////////////////////////////////////////////////////////////////////
int main(int argc, char* argv[])
{
// Initialize and run HPX
return init(argc, argv);
}
8 changes: 2 additions & 6 deletions libs/datastructures/tests/unit/small_big_object.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,6 @@
#ifndef HPX_SMALL_BIG_OBJECT_HPP
#define HPX_SMALL_BIG_OBJECT_HPP

#include <hpx/runtime/serialization/serialize.hpp>

#include <cstdint>
#include <iostream>

Expand All @@ -22,8 +20,7 @@ struct small_object
private:
std::uint64_t x_;

friend class hpx::serialization::access;

public:
template <typename Archive>
void serialize(Archive& ar, unsigned const)
{
Expand Down Expand Up @@ -130,8 +127,7 @@ struct big_object
std::uint64_t x_;
std::uint64_t y_;

friend class hpx::serialization::access;

public:
template <typename Archive>
void serialize(Archive& ar, unsigned const)
{
Expand Down
42 changes: 41 additions & 1 deletion libs/datastructures/tests/unit/tuple.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@
// clang-format on

#include <hpx/config.hpp>
#include <hpx/hpx_init.hpp>
#include <hpx/datastructures/tuple.hpp>
#include <hpx/testing.hpp>

Expand Down Expand Up @@ -537,6 +536,46 @@ void tuple_swap_test()
HPX_TEST(j == 1);
}

void tuple_std_test()
{
hpx::util::tuple<int, float, double> t1(1, 2.0f, 3.0);
std::tuple<int, float, double> t2 = t1;
hpx::util::tuple<int, float, double> t3 = t2;
HPX_TEST(std::get<0>(t1) == 1);
HPX_TEST(std::get<0>(t2) == 1);
HPX_TEST(std::get<0>(t3) == 1);

HPX_TEST(hpx::util::get<0>(t1) == 1);
HPX_TEST(hpx::util::get<0>(t2) == 1);
HPX_TEST(hpx::util::get<0>(t3) == 1);

HPX_TEST(std::get<1>(t1) == 2.0f);
HPX_TEST(std::get<1>(t2) == 2.0f);
HPX_TEST(std::get<1>(t3) == 2.0f);

HPX_TEST(hpx::util::get<1>(t1) == 2.0f);
HPX_TEST(hpx::util::get<1>(t2) == 2.0f);
HPX_TEST(hpx::util::get<1>(t3) == 2.0f);

HPX_TEST(std::get<2>(t1) == 3.0);
HPX_TEST(std::get<2>(t2) == 3.0);
HPX_TEST(std::get<2>(t3) == 3.0);

HPX_TEST(hpx::util::get<2>(t1) == 3.0);
HPX_TEST(hpx::util::get<2>(t2) == 3.0);
HPX_TEST(hpx::util::get<2>(t3) == 3.0);
}

void tuple_structured_binding_test()
{
#if defined(HPX_HAVE_CXX17_STRUCTURED_BINDINGS)
auto [a1, a2] = hpx::util::make_tuple(1, '2');

HPX_TEST_EQ(a1, 1);
HPX_TEST_EQ(a2, '2');
#endif
}

///////////////////////////////////////////////////////////////////////////////
int main(int argc, char* argv[])
{
Expand All @@ -553,6 +592,7 @@ int main(int argc, char* argv[])
const_tuple_test();
tuple_length_test();
tuple_swap_test();
tuple_structured_binding_test();
}

return hpx::util::report_errors();
Expand Down

0 comments on commit 3299d77

Please sign in to comment.