diff --git a/libs/datastructures/CMakeLists.txt b/libs/datastructures/CMakeLists.txt index f68621e81d10..b95ed852e91d 100644 --- a/libs/datastructures/CMakeLists.txt +++ b/libs/datastructures/CMakeLists.txt @@ -6,12 +6,24 @@ cmake_minimum_required(VERSION 3.3.2 FATAL_ERROR) +# Compatibility with using Boost.FileSystem, introduced in V1.4.0 +hpx_option(HPX_DATASTRUCTURES_WITH_ADAPT_STD_TUPLE + BOOL "Enable compatibility of hpx::util::tuple with std::tuple. (default: ON)" + ON ADVANCED CATEGORY "Modules") + +if(HPX_DATASTRUCTURES_WITH_ADAPT_STD_TUPLE) + hpx_add_config_define_namespace( + DEFINE HPX_DATASTRUCTURES_HAVE_ADAPT_STD_TUPLE + NAMESPACE DATASTRUCTURES) +endif() + set(datastructures_headers hpx/datastructures/any.hpp hpx/datastructures/tuple.hpp 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 @@ -41,3 +53,7 @@ add_hpx_module(datastructures hpx_type_support CMAKE_SUBDIRS examples tests ) + +if(HPX_DATASTRUCTURES_WITH_ADAPT_STD_TUPLE) + hpx_info(" Adapted hpx::util::tuple to be usable with std::tuple") +endif() diff --git a/libs/datastructures/include/hpx/datastructures/tuple.hpp b/libs/datastructures/include/hpx/datastructures/tuple.hpp index d2e5b0d45013..a32dc44687aa 100644 --- a/libs/datastructures/include/hpx/datastructures/tuple.hpp +++ b/libs/datastructures/include/hpx/datastructures/tuple.hpp @@ -10,6 +10,7 @@ #define HPX_UTIL_TUPLE_HPP #include +#include #include #include @@ -18,6 +19,7 @@ #include #include #include // for size_t +#include #include #include @@ -26,7 +28,13 @@ #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 class tuple; @@ -36,27 +44,59 @@ namespace hpx { namespace util { template struct tuple_element; // undefined - template - HPX_CONSTEXPR HPX_HOST_DEVICE HPX_FORCEINLINE - typename tuple_element::type& - get(Tuple& t) noexcept; + // Hide implementations of get<> inside an internal namespace to be able to + // import those into the namespace std below without pulling in all of + // hpx::util. + namespace adl_barrier { + + template + HPX_CONSTEXPR HPX_HOST_DEVICE HPX_FORCEINLINE + typename tuple_element::type& + get(Tuple& t) noexcept; + + template + HPX_CONSTEXPR HPX_HOST_DEVICE HPX_FORCEINLINE + typename tuple_element::type const& + get(Tuple const& t) noexcept; + + template + HPX_CONSTEXPR HPX_HOST_DEVICE HPX_FORCEINLINE + typename tuple_element::type&& + get(Tuple&& t) noexcept; + + template + HPX_CONSTEXPR HPX_HOST_DEVICE HPX_FORCEINLINE + typename tuple_element::type const&& + get(Tuple const&& t) noexcept; + } // namespace adl_barrier + + using hpx::util::adl_barrier::get; +}} // namespace hpx::util - template - HPX_CONSTEXPR HPX_HOST_DEVICE HPX_FORCEINLINE - typename tuple_element::type const& - get(Tuple const& t) noexcept; +#if defined(HPX_DATASTRUCTURES_HAVE_ADAPT_STD_TUPLE) +// Adapt hpx::util::tuple to be useable with std::tuple +namespace std { - template - HPX_CONSTEXPR HPX_HOST_DEVICE HPX_FORCEINLINE - typename tuple_element::type&& - get(Tuple&& t) noexcept; + template + struct tuple_size> + : public hpx::util::tuple_size> + { + }; - template - HPX_CONSTEXPR HPX_HOST_DEVICE HPX_FORCEINLINE - typename tuple_element::type const&& - get(Tuple const&& t) noexcept; + template + struct tuple_element> + : public hpx::util::tuple_element> + { + }; + + using hpx::util::adl_barrier::get; +} // namespace std +#endif + +namespace hpx { namespace util { namespace detail { + /////////////////////////////////////////////////////////////////////// template struct tuple_member //-V690 @@ -163,8 +203,8 @@ namespace hpx { namespace util { struct are_tuples_compatible_impl, tuple, UTuple> { - typedef char (&no_type)[1]; - typedef char (&yes_type)[2]; + using no_type = char (&)[1]; + using yes_type = char (&)[2]; static no_type call(...); static yes_type call(Ts...); @@ -173,7 +213,7 @@ namespace hpx { namespace util { sizeof(call(util::get(std::declval())...) //-V510 ) == sizeof(yes_type); - typedef std::integral_constant type; + using type = std::integral_constant; }; template @@ -307,6 +347,32 @@ namespace hpx { namespace util { typename detail::at_index::type> const&>(*this) .value(); } + +#if defined(HPX_DATASTRUCTURES_HAVE_ADAPT_STD_TUPLE) + HPX_HOST_DEVICE + operator std::tuple() const& + { + return std::make_tuple(get()...); + } + + HPX_HOST_DEVICE + operator std::tuple() && + { + return std::make_tuple(std::move(get())...); + } + + HPX_HOST_DEVICE + operator std::tuple() & + { + return std::make_tuple(get()...); + } + + HPX_HOST_DEVICE + operator std::tuple() const&& + { + return std::make_tuple(std::move(get())...); + } +#endif }; /////////////////////////////////////////////////////////////////////// @@ -333,12 +399,12 @@ namespace hpx { namespace util { // tuple(const tuple& u) = default; // Initializes each element of *this with the corresponding element // of u. - HPX_CONSTEXPR HPX_HOST_DEVICE tuple(tuple const& /*other*/) {} + HPX_CONSTEXPR HPX_HOST_DEVICE tuple(tuple const& /*other*/) = default; // tuple(tuple&& u) = default; // For all i, initializes the ith element of *this with // std::forward(get(u)). - HPX_CONSTEXPR HPX_HOST_DEVICE tuple(tuple&& /*other*/) {} + HPX_CONSTEXPR HPX_HOST_DEVICE tuple(tuple&& /*other*/) = default; // 20.4.2.2, tuple assignment @@ -362,6 +428,13 @@ 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 {} + +#if defined(HPX_DATASTRUCTURES_HAVE_ADAPT_STD_TUPLE) + operator std::tuple<>() const + { + return std::tuple<>(); + } +#endif }; template @@ -503,6 +576,28 @@ namespace hpx { namespace util { { _impl.swap(other._impl); } + +#if defined(HPX_DATASTRUCTURES_HAVE_ADAPT_STD_TUPLE) + operator std::tuple() const& + { + return _impl; + } + + operator std::tuple() & + { + return _impl; + } + + operator std::tuple() && + { + return _impl; + } + + operator std::tuple() const&& + { + return _impl; + } +#endif }; // 20.4.2.5, tuple helper classes @@ -553,6 +648,13 @@ namespace hpx { namespace util { { }; +#if defined(HPX_DATASTRUCTURES_HAVE_ADAPT_STD_TUPLE) + template + struct tuple_size> : std::tuple_size> + { + }; +#endif + // template // class tuple_element template @@ -581,7 +683,7 @@ namespace hpx { namespace util { template struct tuple_element> { - typedef typename detail::at_index::type type; + using type = typename detail::at_index::type; static HPX_CONSTEXPR HPX_HOST_DEVICE HPX_FORCEINLINE type& get( tuple& tuple) noexcept @@ -599,7 +701,7 @@ namespace hpx { namespace util { template struct tuple_element<0, std::pair> { - typedef T0 type; + using type = T0; static HPX_CONSTEXPR HPX_HOST_DEVICE HPX_FORCEINLINE type& get( std::pair& tuple) noexcept @@ -617,7 +719,7 @@ namespace hpx { namespace util { template struct tuple_element<1, std::pair> { - typedef T1 type; + using type = T1; static HPX_CONSTEXPR HPX_HOST_DEVICE HPX_FORCEINLINE type& get( std::pair& tuple) noexcept @@ -635,7 +737,7 @@ namespace hpx { namespace util { template struct tuple_element> { - typedef Type type; + using type = Type; static HPX_CONSTEXPR HPX_HOST_DEVICE HPX_FORCEINLINE type& get( boost::array& tuple) noexcept @@ -653,7 +755,7 @@ namespace hpx { namespace util { template struct tuple_element> { - typedef Type type; + using type = Type; static HPX_CONSTEXPR HPX_HOST_DEVICE HPX_FORCEINLINE type& get( std::array& tuple) noexcept @@ -668,53 +770,87 @@ namespace hpx { namespace util { } }; - // 20.4.2.6, element access - - // template - // constexpr typename tuple_element >::type& - // get(tuple& t) noexcept; - template - HPX_CONSTEXPR HPX_HOST_DEVICE HPX_FORCEINLINE - typename tuple_element::type& - get(Tuple& t) noexcept +#if defined(HPX_DATASTRUCTURES_HAVE_ADAPT_STD_TUPLE) + template + struct tuple_element> { - return tuple_element::get(t); - } + using type = typename std::tuple_element>::type; - // template - // constexpr typename tuple_element >::type const& - // get(const tuple& t) noexcept; - template - HPX_CONSTEXPR HPX_HOST_DEVICE HPX_FORCEINLINE - typename tuple_element::type const& - get(Tuple const& t) noexcept - { - return tuple_element::get(t); - } + static HPX_CONSTEXPR HPX_HOST_DEVICE HPX_FORCEINLINE type& get( + std::tuple& tuple) noexcept + { + return std::get(tuple); + } - // template - // constexpr typename tuple_element >::type&& - // get(tuple&& t) noexcept; - template - HPX_CONSTEXPR HPX_HOST_DEVICE HPX_FORCEINLINE - typename tuple_element::type&& - get(Tuple&& t) noexcept - { - return std::forward::type>( - util::get(t)); - } + static HPX_CONSTEXPR HPX_HOST_DEVICE HPX_FORCEINLINE type const& get( + std::tuple const& tuple) noexcept + { + return std::get(tuple); + } - // template - // constexpr typename tuple_element >::type const&& - // get(const tuple&& t) noexcept; - template - HPX_CONSTEXPR HPX_HOST_DEVICE HPX_FORCEINLINE - typename tuple_element::type const&& - get(Tuple const&& t) noexcept - { - return std::forward::type const>( - util::get(t)); - } + static HPX_CONSTEXPR HPX_HOST_DEVICE HPX_FORCEINLINE type&& get( + std::tuple&& tuple) noexcept + { + return std::get(std::move(tuple)); + } + + static HPX_CONSTEXPR HPX_HOST_DEVICE HPX_FORCEINLINE type const&& get( + std::tuple const&& tuple) noexcept + { + return std::get(std::move(tuple)); + } + }; +#endif + + // 20.4.2.6, element access + namespace adl_barrier { + + // template + // constexpr typename tuple_element >::type& + // get(tuple& t) noexcept; + template + HPX_CONSTEXPR HPX_HOST_DEVICE HPX_FORCEINLINE + typename tuple_element::type& + get(Tuple& t) noexcept + { + return tuple_element::get(t); + } + + // template + // constexpr typename tuple_element >::type const& + // get(const tuple& t) noexcept; + template + HPX_CONSTEXPR HPX_HOST_DEVICE HPX_FORCEINLINE + typename tuple_element::type const& + get(Tuple const& t) noexcept + { + return tuple_element::get(t); + } + + // template + // constexpr typename tuple_element >::type&& + // get(tuple&& t) noexcept; + template + HPX_CONSTEXPR HPX_HOST_DEVICE HPX_FORCEINLINE + typename tuple_element::type&& + get(Tuple&& t) noexcept + { + return std::forward::type>( + util::get(t)); + } + + // template + // constexpr typename tuple_element >::type const&& + // get(const tuple&& t) noexcept; + template + HPX_CONSTEXPR HPX_HOST_DEVICE HPX_FORCEINLINE + typename tuple_element::type const&& + get(Tuple const&& t) noexcept + { + return std::forward::type const>( + util::get(t)); + } + } // namespace adl_barrier // 20.4.2.4, tuple creation functions detail::ignore_type const ignore = {}; @@ -754,6 +890,7 @@ namespace hpx { namespace util { //template //constexpr tuple tuple_cat(Tuples&&...); namespace detail { + /// Deduces to the overall size of all given tuples template struct tuple_cat_size_impl; @@ -800,9 +937,8 @@ namespace hpx { namespace util { : tuple_cat_element::value, detail::pack> { - typedef tuple_cat_element::value, - detail::pack> - base_type; + using base_type = tuple_cat_element::value, + detail::pack>; template static HPX_CONSTEXPR HPX_HOST_DEVICE HPX_FORCEINLINE auto get( @@ -1018,4 +1154,8 @@ namespace hpx { namespace util { #pragma warning(pop) #endif +#if defined(__clang__) +#pragma clang diagnostic pop +#endif + #endif diff --git a/hpx/traits/is_tuple_like.hpp b/libs/datastructures/include/hpx/traits/is_tuple_like.hpp similarity index 67% rename from hpx/traits/is_tuple_like.hpp rename to libs/datastructures/include/hpx/traits/is_tuple_like.hpp index 77a12cdb8236..75a8af15ee9a 100644 --- a/hpx/traits/is_tuple_like.hpp +++ b/libs/datastructures/include/hpx/traits/is_tuple_like.hpp @@ -9,31 +9,31 @@ #include -#include #include +#include -namespace hpx { namespace traits -{ - namespace detail - { +namespace hpx { namespace traits { + namespace detail { template - struct is_tuple_like_impl - : std::false_type - {}; + struct is_tuple_like_impl : std::false_type + { + }; template - struct is_tuple_like_impl::value)>::type - > : std::true_type - {}; - } + struct is_tuple_like_impl::value)>::type> : std::true_type + { + }; + } // namespace detail /// Deduces to a true type if the given parameter T /// has a specific tuple like size. template struct is_tuple_like : detail::is_tuple_like_impl::type> - {}; -}} + { + }; +}} // namespace hpx::traits #endif /*HPX_TRAITS_IS_TUPLE_LIKE_HPP*/ diff --git a/libs/datastructures/tests/unit/any.cpp b/libs/datastructures/tests/unit/any.cpp index b578f1cc5c4b..34a3625de9c5 100644 --- a/libs/datastructures/tests/unit/any.cpp +++ b/libs/datastructures/tests/unit/any.cpp @@ -7,11 +7,8 @@ //////////////////////////////////////////////////////////////////////////////// #include -#include #include -#include - #include #include #include @@ -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)); @@ -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); -} diff --git a/libs/datastructures/tests/unit/small_big_object.hpp b/libs/datastructures/tests/unit/small_big_object.hpp index 93555b4ad1aa..13c425b46a30 100644 --- a/libs/datastructures/tests/unit/small_big_object.hpp +++ b/libs/datastructures/tests/unit/small_big_object.hpp @@ -9,8 +9,6 @@ #ifndef HPX_SMALL_BIG_OBJECT_HPP #define HPX_SMALL_BIG_OBJECT_HPP -#include - #include #include @@ -22,8 +20,7 @@ struct small_object private: std::uint64_t x_; - friend class hpx::serialization::access; - +public: template void serialize(Archive& ar, unsigned const) { @@ -130,8 +127,7 @@ struct big_object std::uint64_t x_; std::uint64_t y_; - friend class hpx::serialization::access; - +public: template void serialize(Archive& ar, unsigned const) { diff --git a/libs/datastructures/tests/unit/tuple.cpp b/libs/datastructures/tests/unit/tuple.cpp index bed34963a507..9875bcfb53ba 100644 --- a/libs/datastructures/tests/unit/tuple.cpp +++ b/libs/datastructures/tests/unit/tuple.cpp @@ -21,7 +21,6 @@ // clang-format on #include -#include #include #include @@ -537,6 +536,48 @@ void tuple_swap_test() HPX_TEST(j == 1); } +void tuple_std_test() +{ +#if defined(HPX_DATASTRUCTURES_HAVE_ADAPT_STD_TUPLE) + hpx::util::tuple t1(1, 2.0f, 3.0); + std::tuple t2 = t1; + hpx::util::tuple 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); +#endif +} + +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[]) { @@ -553,6 +594,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(); diff --git a/libs/filesystem/CMakeLists.txt b/libs/filesystem/CMakeLists.txt index bafc00f330e2..60ed0b5cb732 100644 --- a/libs/filesystem/CMakeLists.txt +++ b/libs/filesystem/CMakeLists.txt @@ -14,7 +14,7 @@ endif() # Compatibility with using Boost.FileSystem, introduced in V1.4.0 hpx_option(HPX_FILESYSTEM_WITH_BOOST_FILESYSTEM_COMPATIBILITY BOOL "Enable Boost.FileSystem compatibility. (default: ${__filesystem_compatibility_default})" - ON ADVANCED CATEGORY "Modules") + ${__filesystem_compatibility_default} ADVANCED CATEGORY "Modules") set(__boost_filesystem) if(HPX_FILESYSTEM_WITH_BOOST_FILESYSTEM_COMPATIBILITY)