From 7daf437a7bc8fc43e38509ee2fa1840c31d6ef8e Mon Sep 17 00:00:00 2001 From: Dan Hoeflinger Date: Thu, 28 Mar 2024 15:04:55 -0400 Subject: [PATCH 01/33] Enable binary operators for tuple Signed-off-by: Dan Hoeflinger --- include/oneapi/dpl/pstl/tuple_impl.h | 45 ++++++++++++++++++---------- 1 file changed, 30 insertions(+), 15 deletions(-) diff --git a/include/oneapi/dpl/pstl/tuple_impl.h b/include/oneapi/dpl/pstl/tuple_impl.h index 09ac587759b..45066214549 100644 --- a/include/oneapi/dpl/pstl/tuple_impl.h +++ b/include/oneapi/dpl/pstl/tuple_impl.h @@ -424,16 +424,36 @@ struct tuple return *this; } - friend bool - operator==(const tuple& __lhs, const tuple& __rhs) - { - return __lhs.holder.value == __rhs.holder.value && __lhs.next == __rhs.next; - } - friend bool - operator!=(const tuple& __lhs, const tuple& __rhs) - { - return !(__lhs == __rhs); - } +// This macro is used to define binary operators for comparison between oneAPI::dpl::__internal::tuple and +// std::tuple when they have the same number of template arguments and the individual elements which are invdividually +// comparable. These overloads are required because for overload resolution of template arguments, exact match is +// required and the compiler does not consider implicit conversions. We also allow std::tuple implementation to +// implement the operators themselves, which guarantees a match with oneAPI::dpl::__internal::tuple +#define _TUPLE_BINARY_OPERATOR_OVERLOAD(__OPERATOR) \ + template > \ + friend bool operator __OPERATOR(const tuple& __lhs, const oneapi::dpl::__internal::tuple<_U1, _U...>& __rhs) \ + { \ + return static_cast>(__lhs) __OPERATOR static_cast>(__rhs); \ + } \ + template > \ + friend bool operator __OPERATOR(const tuple& __lhs, const std::tuple<_U1, _U...>& __rhs) \ + { \ + return static_cast>(__lhs) __OPERATOR __rhs; \ + } \ + template > \ + friend bool operator __OPERATOR(const std::tuple<_U1, _U...>& __lhs, const tuple& __rhs) \ + { \ + return __lhs __OPERATOR static_cast>(__rhs); \ + } + + _TUPLE_BINARY_OPERATOR_OVERLOAD(==) + _TUPLE_BINARY_OPERATOR_OVERLOAD(!=) + _TUPLE_BINARY_OPERATOR_OVERLOAD(<) + _TUPLE_BINARY_OPERATOR_OVERLOAD(<=) + _TUPLE_BINARY_OPERATOR_OVERLOAD(>) + _TUPLE_BINARY_OPERATOR_OVERLOAD(>=) + +#undef _TUPLE_BINARY_OPERATOR_OVERLOAD template static ::std::tuple @@ -463,11 +483,6 @@ struct tuple<> { return *this; } - friend bool - operator==(const tuple& /*__lhs*/, const tuple& /*__rhs*/) - { - return true; - } }; inline void From 82acba34242e072faf08c44e29ff42aece86674e Mon Sep 17 00:00:00 2001 From: Dan Hoeflinger Date: Fri, 29 Mar 2024 12:49:58 -0400 Subject: [PATCH 02/33] Adding tuple unit tests Signed-off-by: Dan Hoeflinger Signed-off-by: Dan Hoeflinger --- .../parallel_api/iterator/tuple_unit.pass.cpp | 100 ++++++++++++++++++ 1 file changed, 100 insertions(+) create mode 100644 test/parallel_api/iterator/tuple_unit.pass.cpp diff --git a/test/parallel_api/iterator/tuple_unit.pass.cpp b/test/parallel_api/iterator/tuple_unit.pass.cpp new file mode 100644 index 00000000000..20218c80b54 --- /dev/null +++ b/test/parallel_api/iterator/tuple_unit.pass.cpp @@ -0,0 +1,100 @@ +// -*- C++ -*- +//===-- tuple_unit.pass.cpp -----------------------------------------------===// +// +// Copyright (C) Intel Corporation +// +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +// This file incorporates work covered by the following copyright and permission +// notice: +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// +//===----------------------------------------------------------------------===// + +#include "support/test_config.h" + +#include _PSTL_TEST_HEADER(tuple) + +#include "support/utils.h" + +template +using tuplewrapper = oneapi::dpl::__internal::tuple::__type...>; + +template +static oneapi::dpl::__internal::tuple<_T...> +to_onedpl_tuple(const std::tuple<_T...>& __t) +{ + return oneapi::dpl::__internal::tuple<_T...>(__t); +} + +template +void +test_tuple(Tuple1 t1, Tuple2 t2) +{ + + auto onedpl_t1 = to_onedpl_tuple(t1); + auto onedpl_t2 = to_onedpl_tuple(t2); + + static_assert(std::is_trivially_copyable_v, "oneDPL tuple is not trivially copyable"); + + // Test binary comparison operators for std::tuple and oneAPI::dpl::__internal::tuple + EXPECT_EQ((t1 == t2), (onedpl_t1 == onedpl_t2), "equality comparison does not match std::tuple"); + EXPECT_EQ((t1 != t2), (onedpl_t1 != onedpl_t2), "inquality comparison does not match std::tuple"); + EXPECT_EQ((t1 < t2), (onedpl_t1 < onedpl_t2), "less than comparison does not match std::tuple"); + EXPECT_EQ((t1 <= t2), (onedpl_t1 <= onedpl_t2), "less than or equal to comparison does not match std::tuple"); + EXPECT_EQ((t1 > t2), (onedpl_t1 > onedpl_t2), "greater than comparison does not match std::tuple"); + EXPECT_EQ((t1 >= t2), (onedpl_t1 >= onedpl_t2), "greater than or equal to comparison does not match std::tuple"); + + EXPECT_EQ((t1 == t2), (t1 == onedpl_t2), "equality comparison does not match std::tuple"); + EXPECT_EQ((t1 != t2), (t1 != onedpl_t2), "inquality comparison does not match std::tuple"); + EXPECT_EQ((t1 < t2), (t1 < onedpl_t2), "less than comparison does not match std::tuple"); + EXPECT_EQ((t1 <= t2), (t1 <= onedpl_t2), "less than or equal to comparison does not match std::tuple"); + EXPECT_EQ((t1 > t2), (t1 > onedpl_t2), "greater than comparison does not match std::tuple"); + EXPECT_EQ((t1 >= t2), (t1 >= onedpl_t2), "greater than or equal to comparison does not match std::tuple"); + + EXPECT_EQ((t1 == t2), (onedpl_t1 == t2), "equality comparison does not match std::tuple"); + EXPECT_EQ((t1 != t2), (onedpl_t1 != t2), "inquality comparison does not match std::tuple"); + EXPECT_EQ((t1 < t2), (onedpl_t1 < t2), "less than comparison does not match std::tuple"); + EXPECT_EQ((t1 <= t2), (onedpl_t1 <= t2), "less than or equal to comparison does not match std::tuple"); + EXPECT_EQ((t1 > t2), (onedpl_t1 > t2), "greater than comparison does not match std::tuple"); + EXPECT_EQ((t1 >= t2), (onedpl_t1 >= t2), "greater than or equal to comparison does not match std::tuple"); + + auto onedpl_t3 = to_onedpl_tuple(t1); + auto onedpl_t4 = to_onedpl_tuple(t2); + auto t3 = t1; + auto t4 = t2; + + t4 = onedpl_t1; + EXPECT_TRUE(t1 == t4, "assignment of oneDPL tuple to std::tuple provides incorrect results"); + + t3 = onedpl_t2; + EXPECT_TRUE(t2 == t3, "assignment of oneDPL tuple to std::tuple provides incorrect results"); + + onedpl_t3 = t1; + EXPECT_TRUE(onedpl_t1 == onedpl_t3, "assignment of oneDPL tuple from std::tuple provides incorrect results"); + + onedpl_t4 = t2; + EXPECT_TRUE(onedpl_t2 == onedpl_t4, "assignment of oneDPL tuple from std::tuple provides incorrect results"); + + decltype(onedpl_t1) onedpl_t5 = onedpl_t2; + decltype(onedpl_t1) onedpl_t6 = onedpl_t1; + + swap(onedpl_t5, onedpl_t6); + EXPECT_TRUE(((onedpl_t1 == onedpl_t5) && (onedpl_t6 == onedpl_t2)), + "swap of oneDPL tuple provides incorrect results"); +} + +int +main() +{ + + test_tuple(std::tuple{1, 2, 3}, std::tuple{1, 2, 3}); + test_tuple(std::tuple{1, 2, 3}, std::tuple{1, 2, 4}); + test_tuple(std::tuple{1, 2, 3}, std::tuple{0, 2, 4}); + test_tuple(std::tuple{1, 2, 3}, std::tuple{1, 2, 3}); + test_tuple(std::tuple{1, 2, 3}, std::tuple{0, 2, 4}); + + return TestUtils::done(); +} From 186e45a601ad194040d43af27981086201e0891e Mon Sep 17 00:00:00 2001 From: Dan Hoeflinger Date: Fri, 5 Apr 2024 08:31:03 -0400 Subject: [PATCH 03/33] cleanup of unnecessary args, formatting Signed-off-by: Dan Hoeflinger --- include/oneapi/dpl/pstl/tuple_impl.h | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/include/oneapi/dpl/pstl/tuple_impl.h b/include/oneapi/dpl/pstl/tuple_impl.h index 45066214549..51a20d266bb 100644 --- a/include/oneapi/dpl/pstl/tuple_impl.h +++ b/include/oneapi/dpl/pstl/tuple_impl.h @@ -430,18 +430,18 @@ struct tuple // required and the compiler does not consider implicit conversions. We also allow std::tuple implementation to // implement the operators themselves, which guarantees a match with oneAPI::dpl::__internal::tuple #define _TUPLE_BINARY_OPERATOR_OVERLOAD(__OPERATOR) \ - template > \ - friend bool operator __OPERATOR(const tuple& __lhs, const oneapi::dpl::__internal::tuple<_U1, _U...>& __rhs) \ + template > \ + friend bool operator __OPERATOR(const tuple& __lhs, const oneapi::dpl::__internal::tuple<_U...>& __rhs) \ { \ - return static_cast>(__lhs) __OPERATOR static_cast>(__rhs); \ + return static_cast>(__lhs) __OPERATOR static_cast>(__rhs); \ } \ - template > \ - friend bool operator __OPERATOR(const tuple& __lhs, const std::tuple<_U1, _U...>& __rhs) \ + template > \ + friend bool operator __OPERATOR(const tuple& __lhs, const std::tuple<_U...>& __rhs) \ { \ return static_cast>(__lhs) __OPERATOR __rhs; \ } \ - template > \ - friend bool operator __OPERATOR(const std::tuple<_U1, _U...>& __lhs, const tuple& __rhs) \ + template > \ + friend bool operator __OPERATOR(const std::tuple<_U...>& __lhs, const tuple& __rhs) \ { \ return __lhs __OPERATOR static_cast>(__rhs); \ } From 8a87f850c14c2ade1e9ceffc19a712111c1eff37 Mon Sep 17 00:00:00 2001 From: Dan Hoeflinger Date: Fri, 5 Apr 2024 08:36:37 -0400 Subject: [PATCH 04/33] add constexpr Signed-off-by: Dan Hoeflinger --- include/oneapi/dpl/pstl/tuple_impl.h | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/include/oneapi/dpl/pstl/tuple_impl.h b/include/oneapi/dpl/pstl/tuple_impl.h index 51a20d266bb..0a85ae3ce03 100644 --- a/include/oneapi/dpl/pstl/tuple_impl.h +++ b/include/oneapi/dpl/pstl/tuple_impl.h @@ -431,17 +431,17 @@ struct tuple // implement the operators themselves, which guarantees a match with oneAPI::dpl::__internal::tuple #define _TUPLE_BINARY_OPERATOR_OVERLOAD(__OPERATOR) \ template > \ - friend bool operator __OPERATOR(const tuple& __lhs, const oneapi::dpl::__internal::tuple<_U...>& __rhs) \ + friend constexpr bool operator __OPERATOR(const tuple& __lhs, const oneapi::dpl::__internal::tuple<_U...>& __rhs) \ { \ return static_cast>(__lhs) __OPERATOR static_cast>(__rhs); \ } \ template > \ - friend bool operator __OPERATOR(const tuple& __lhs, const std::tuple<_U...>& __rhs) \ + friend constexpr bool operator __OPERATOR(const tuple& __lhs, const std::tuple<_U...>& __rhs) \ { \ return static_cast>(__lhs) __OPERATOR __rhs; \ } \ template > \ - friend bool operator __OPERATOR(const std::tuple<_U...>& __lhs, const tuple& __rhs) \ + friend constexpr bool operator __OPERATOR(const std::tuple<_U...>& __lhs, const tuple& __rhs) \ { \ return __lhs __OPERATOR static_cast>(__rhs); \ } @@ -483,6 +483,11 @@ struct tuple<> { return *this; } + friend bool + operator==(const tuple& /*__lhs*/, const tuple& /*__rhs*/) + { + return true; + } }; inline void From bac8c1f769018dee34493c292dae2a9d18404ab2 Mon Sep 17 00:00:00 2001 From: Dan Hoeflinger Date: Fri, 5 Apr 2024 09:45:24 -0400 Subject: [PATCH 05/33] adding operators for empty tuples Signed-off-by: Dan Hoeflinger --- include/oneapi/dpl/pstl/tuple_impl.h | 29 +++++++++++++++++++++++++--- 1 file changed, 26 insertions(+), 3 deletions(-) diff --git a/include/oneapi/dpl/pstl/tuple_impl.h b/include/oneapi/dpl/pstl/tuple_impl.h index 0a85ae3ce03..b39042652c1 100644 --- a/include/oneapi/dpl/pstl/tuple_impl.h +++ b/include/oneapi/dpl/pstl/tuple_impl.h @@ -476,6 +476,10 @@ struct tuple<> tuple operator[](tuple) { return {}; } tuple operator[](const tuple&) const { return {}; } + operator tuple_type() const + { + return tuple_type{}; + } tuple& operator=(const tuple&) = default; tuple& @@ -483,10 +487,29 @@ struct tuple<> { return *this; } - friend bool - operator==(const tuple& /*__lhs*/, const tuple& /*__rhs*/) + friend constexpr bool operator==(const tuple& __lhs, const tuple& __rhs) + { + return tuple_type{} == tuple_type{}; + } + friend constexpr bool operator!=(const tuple& __lhs, const tuple& __rhs) + { + return tuple_type{} != tuple_type{}; + } + friend constexpr bool operator<(const tuple& __lhs, const tuple& __rhs) + { + return tuple_type{} < tuple_type{}; + } + friend constexpr bool operator<=(const tuple& __lhs, const tuple& __rhs) + { + return tuple_type{} <= tuple_type{}; + } + friend constexpr bool operator>(const tuple& __lhs, const tuple& __rhs) + { + return tuple_type{} > tuple_type{}; + } + friend constexpr bool operator>=(const tuple& __lhs, const tuple& __rhs) { - return true; + return tuple_type{} >= tuple_type{}; } }; From eb4127309ac741c4d83cfb4111c17d6e51e7bcbe Mon Sep 17 00:00:00 2001 From: Dan Hoeflinger Date: Fri, 5 Apr 2024 09:45:38 -0400 Subject: [PATCH 06/33] adding tests for compile time and empty tuples Signed-off-by: Dan Hoeflinger --- .../parallel_api/iterator/tuple_unit.pass.cpp | 61 +++++++++++++++++++ 1 file changed, 61 insertions(+) diff --git a/test/parallel_api/iterator/tuple_unit.pass.cpp b/test/parallel_api/iterator/tuple_unit.pass.cpp index 20218c80b54..b7c17347261 100644 --- a/test/parallel_api/iterator/tuple_unit.pass.cpp +++ b/test/parallel_api/iterator/tuple_unit.pass.cpp @@ -86,15 +86,76 @@ test_tuple(Tuple1 t1, Tuple2 t2) "swap of oneDPL tuple provides incorrect results"); } + +constexpr +void test_compile_time() +{ + constexpr std::tuple std_tup1{1, 2, 3}; + constexpr std::tuple std_tup2{99, 2, 3}; + constexpr oneapi::dpl::tuple dpl_tup1{1, 2, 3}; + constexpr oneapi::dpl::tuple dpl_tup2{99, 2, 3}; + + static_assert((std_tup1 == std_tup2) == (dpl_tup1 == dpl_tup2), "compile time equality comparison does not match std::tuple"); + static_assert((std_tup1 < std_tup2) == (dpl_tup1 < dpl_tup2), "compile time less than comparison does not match std::tuple"); + static_assert((std_tup1 <= std_tup2) == (dpl_tup1 <= dpl_tup2), "compile time lt-equal comparison does not match std::tuple"); + static_assert((std_tup1 > std_tup2) == (dpl_tup1 > dpl_tup2), "compile time greater comparison does not match std::tuple"); + static_assert((std_tup1 >= std_tup2) == (dpl_tup1 >= dpl_tup2), "compile time gt-equal comparison does not match std::tuple"); + static_assert((std_tup1 != std_tup2) == (dpl_tup1 != dpl_tup2), "compile time non-equality comparison does not match std::tuple"); + + static_assert((std_tup1 == std_tup2) == (std_tup1 == dpl_tup2), "compile time equality comparison does not match std::tuple with std::tuple as lhs"); + static_assert((std_tup1 < std_tup2) == (std_tup1 < dpl_tup2), "compile time less than comparison does not match std::tuple with std::tuple as lhs"); + static_assert((std_tup1 <= std_tup2) == (std_tup1 <= dpl_tup2), "compile time lt-equal comparison does not match std::tuple with std::tuple as lhs"); + static_assert((std_tup1 > std_tup2) == (std_tup1 > dpl_tup2), "compile time greater comparison does not match std::tuple with std::tuple as lhs"); + static_assert((std_tup1 >= std_tup2) == (std_tup1 >= dpl_tup2), "compile time gt-equal comparison does not match std::tuple with std::tuple as lhs"); + static_assert((std_tup1 != std_tup2) == (std_tup1 != dpl_tup2), "compile time non-equality comparison does not match std::tuple with std::tuple as lhs"); + + static_assert((std_tup1 == std_tup2) == (dpl_tup1 == std_tup2), "compile time equality comparison does not match std::tuple with std::tuple as rhs"); + static_assert((std_tup1 < std_tup2) == (dpl_tup1 < std_tup2), "compile time less than comparison does not match std::tuple with std::tuple as rhs"); + static_assert((std_tup1 <= std_tup2) == (dpl_tup1 <= std_tup2), "compile time lt-equal comparison does not match std::tuple with std::tuple as rhs"); + static_assert((std_tup1 > std_tup2) == (dpl_tup1 > std_tup2), "compile time greater comparison does not match std::tuple with std::tuple as rhs"); + static_assert((std_tup1 >= std_tup2) == (dpl_tup1 >= std_tup2), "compile time gt-equal comparison does not match std::tuple with std::tuple as rhs"); + static_assert((std_tup1 != std_tup2) == (dpl_tup1 != std_tup2), "compile time non-equality comparison does not match std::tuple with std::tuple as rhs"); + + constexpr std::tuple<> std_empty1{}; + constexpr std::tuple<> std_empty2{}; + constexpr oneapi::dpl::tuple<> dpl_empty1{}; + constexpr oneapi::dpl::tuple<> dpl_empty2{}; + + static_assert((std_empty1 == std_empty2) == (dpl_empty1 == dpl_empty2), "empty compile time equality comparison does not match std::tuple"); + static_assert((std_empty1 < std_empty2) == (dpl_empty1 < dpl_empty2), "empty compile time less than comparison does not match std::tuple"); + static_assert((std_empty1 <= std_empty2) == (dpl_empty1 <= dpl_empty2), "empty compile time lt-equal comparison does not match std::tuple"); + static_assert((std_empty1 > std_empty2) == (dpl_empty1 > dpl_empty2), "empty compile time greater comparison does not match std::tuple"); + static_assert((std_empty1 >= std_empty2) == (dpl_empty1 >= dpl_empty2), "empty compile time gt-equal comparison does not match std::tuple"); + static_assert((std_empty1 != std_empty2) == (dpl_empty1 != dpl_empty2), "empty compile time non-equality comparison does not match std::tuple"); + + static_assert((std_empty1 == std_empty2) == (std_empty1 == dpl_empty2), "empty compile time equality comparison does not match std::tuple with std::tuple as lhs"); + static_assert((std_empty1 < std_empty2) == (std_empty1 < dpl_empty2), "empty compile time less than comparison does not match std::tuple with std::tuple as lhs"); + static_assert((std_empty1 <= std_empty2) == (std_empty1 <= dpl_empty2), "empty compile time lt-equal comparison does not match std::tuple with std::tuple as lhs"); + static_assert((std_empty1 > std_empty2) == (std_empty1 > dpl_empty2), "empty compile time greater comparison does not match std::tuple with std::tuple as lhs"); + static_assert((std_empty1 >= std_empty2) == (std_empty1 >= dpl_empty2), "empty compile time gt-equal comparison does not match std::tuple with std::tuple as lhs"); + static_assert((std_empty1 != std_empty2) == (std_empty1 != dpl_empty2), "empty compile time non-equality comparison does not match std::tuple with std::tuple as lhs"); + + static_assert((std_empty1 == std_empty2) == (dpl_empty1 == std_empty2), "empty compile time equality comparison does not match std::tuple with std::tuple as rhs"); + static_assert((std_empty1 < std_empty2) == (dpl_empty1 < std_empty2), "empty compile time less than comparison does not match std::tuple with std::tuple as rhs"); + static_assert((std_empty1 <= std_empty2) == (dpl_empty1 <= std_empty2), "empty compile time lt-equal comparison does not match std::tuple with std::tuple as rhs"); + static_assert((std_empty1 > std_empty2) == (dpl_empty1 > std_empty2), "empty compile time greater comparison does not match std::tuple with std::tuple as rhs"); + static_assert((std_empty1 >= std_empty2) == (dpl_empty1 >= std_empty2), "empty compile time gt-equal comparison does not match std::tuple with std::tuple as rhs"); + static_assert((std_empty1 != std_empty2) == (dpl_empty1 != std_empty2), "empty compile time non-equality comparison does not match std::tuple with std::tuple as rhs"); +} + + + int main() { + test_compile_time(); test_tuple(std::tuple{1, 2, 3}, std::tuple{1, 2, 3}); test_tuple(std::tuple{1, 2, 3}, std::tuple{1, 2, 4}); test_tuple(std::tuple{1, 2, 3}, std::tuple{0, 2, 4}); test_tuple(std::tuple{1, 2, 3}, std::tuple{1, 2, 3}); test_tuple(std::tuple{1, 2, 3}, std::tuple{0, 2, 4}); + test_tuple(std::tuple<>{}, std::tuple<>{}); return TestUtils::done(); } From 4d6dbb19810a18c48d7b0518ae7b8a0d9bfca5f7 Mon Sep 17 00:00:00 2001 From: Dan Hoeflinger Date: Fri, 5 Apr 2024 09:47:00 -0400 Subject: [PATCH 07/33] formatting Signed-off-by: Dan Hoeflinger --- include/oneapi/dpl/pstl/tuple_impl.h | 18 ++- .../parallel_api/iterator/tuple_unit.pass.cpp | 123 +++++++++++------- 2 files changed, 90 insertions(+), 51 deletions(-) diff --git a/include/oneapi/dpl/pstl/tuple_impl.h b/include/oneapi/dpl/pstl/tuple_impl.h index b39042652c1..b1006870889 100644 --- a/include/oneapi/dpl/pstl/tuple_impl.h +++ b/include/oneapi/dpl/pstl/tuple_impl.h @@ -487,27 +487,33 @@ struct tuple<> { return *this; } - friend constexpr bool operator==(const tuple& __lhs, const tuple& __rhs) + friend constexpr bool + operator==(const tuple& __lhs, const tuple& __rhs) { return tuple_type{} == tuple_type{}; } - friend constexpr bool operator!=(const tuple& __lhs, const tuple& __rhs) + friend constexpr bool + operator!=(const tuple& __lhs, const tuple& __rhs) { return tuple_type{} != tuple_type{}; } - friend constexpr bool operator<(const tuple& __lhs, const tuple& __rhs) + friend constexpr bool + operator<(const tuple& __lhs, const tuple& __rhs) { return tuple_type{} < tuple_type{}; } - friend constexpr bool operator<=(const tuple& __lhs, const tuple& __rhs) + friend constexpr bool + operator<=(const tuple& __lhs, const tuple& __rhs) { return tuple_type{} <= tuple_type{}; } - friend constexpr bool operator>(const tuple& __lhs, const tuple& __rhs) + friend constexpr bool + operator>(const tuple& __lhs, const tuple& __rhs) { return tuple_type{} > tuple_type{}; } - friend constexpr bool operator>=(const tuple& __lhs, const tuple& __rhs) + friend constexpr bool + operator>=(const tuple& __lhs, const tuple& __rhs) { return tuple_type{} >= tuple_type{}; } diff --git a/test/parallel_api/iterator/tuple_unit.pass.cpp b/test/parallel_api/iterator/tuple_unit.pass.cpp index b7c17347261..a938b2d439b 100644 --- a/test/parallel_api/iterator/tuple_unit.pass.cpp +++ b/test/parallel_api/iterator/tuple_unit.pass.cpp @@ -86,65 +86,98 @@ test_tuple(Tuple1 t1, Tuple2 t2) "swap of oneDPL tuple provides incorrect results"); } - -constexpr -void test_compile_time() +constexpr void +test_compile_time() { constexpr std::tuple std_tup1{1, 2, 3}; constexpr std::tuple std_tup2{99, 2, 3}; constexpr oneapi::dpl::tuple dpl_tup1{1, 2, 3}; constexpr oneapi::dpl::tuple dpl_tup2{99, 2, 3}; - static_assert((std_tup1 == std_tup2) == (dpl_tup1 == dpl_tup2), "compile time equality comparison does not match std::tuple"); - static_assert((std_tup1 < std_tup2) == (dpl_tup1 < dpl_tup2), "compile time less than comparison does not match std::tuple"); - static_assert((std_tup1 <= std_tup2) == (dpl_tup1 <= dpl_tup2), "compile time lt-equal comparison does not match std::tuple"); - static_assert((std_tup1 > std_tup2) == (dpl_tup1 > dpl_tup2), "compile time greater comparison does not match std::tuple"); - static_assert((std_tup1 >= std_tup2) == (dpl_tup1 >= dpl_tup2), "compile time gt-equal comparison does not match std::tuple"); - static_assert((std_tup1 != std_tup2) == (dpl_tup1 != dpl_tup2), "compile time non-equality comparison does not match std::tuple"); - - static_assert((std_tup1 == std_tup2) == (std_tup1 == dpl_tup2), "compile time equality comparison does not match std::tuple with std::tuple as lhs"); - static_assert((std_tup1 < std_tup2) == (std_tup1 < dpl_tup2), "compile time less than comparison does not match std::tuple with std::tuple as lhs"); - static_assert((std_tup1 <= std_tup2) == (std_tup1 <= dpl_tup2), "compile time lt-equal comparison does not match std::tuple with std::tuple as lhs"); - static_assert((std_tup1 > std_tup2) == (std_tup1 > dpl_tup2), "compile time greater comparison does not match std::tuple with std::tuple as lhs"); - static_assert((std_tup1 >= std_tup2) == (std_tup1 >= dpl_tup2), "compile time gt-equal comparison does not match std::tuple with std::tuple as lhs"); - static_assert((std_tup1 != std_tup2) == (std_tup1 != dpl_tup2), "compile time non-equality comparison does not match std::tuple with std::tuple as lhs"); - - static_assert((std_tup1 == std_tup2) == (dpl_tup1 == std_tup2), "compile time equality comparison does not match std::tuple with std::tuple as rhs"); - static_assert((std_tup1 < std_tup2) == (dpl_tup1 < std_tup2), "compile time less than comparison does not match std::tuple with std::tuple as rhs"); - static_assert((std_tup1 <= std_tup2) == (dpl_tup1 <= std_tup2), "compile time lt-equal comparison does not match std::tuple with std::tuple as rhs"); - static_assert((std_tup1 > std_tup2) == (dpl_tup1 > std_tup2), "compile time greater comparison does not match std::tuple with std::tuple as rhs"); - static_assert((std_tup1 >= std_tup2) == (dpl_tup1 >= std_tup2), "compile time gt-equal comparison does not match std::tuple with std::tuple as rhs"); - static_assert((std_tup1 != std_tup2) == (dpl_tup1 != std_tup2), "compile time non-equality comparison does not match std::tuple with std::tuple as rhs"); + static_assert((std_tup1 == std_tup2) == (dpl_tup1 == dpl_tup2), + "compile time equality comparison does not match std::tuple"); + static_assert((std_tup1 < std_tup2) == (dpl_tup1 < dpl_tup2), + "compile time less than comparison does not match std::tuple"); + static_assert((std_tup1 <= std_tup2) == (dpl_tup1 <= dpl_tup2), + "compile time lt-equal comparison does not match std::tuple"); + static_assert((std_tup1 > std_tup2) == (dpl_tup1 > dpl_tup2), + "compile time greater comparison does not match std::tuple"); + static_assert((std_tup1 >= std_tup2) == (dpl_tup1 >= dpl_tup2), + "compile time gt-equal comparison does not match std::tuple"); + static_assert((std_tup1 != std_tup2) == (dpl_tup1 != dpl_tup2), + "compile time non-equality comparison does not match std::tuple"); + + static_assert((std_tup1 == std_tup2) == (std_tup1 == dpl_tup2), + "compile time equality comparison does not match std::tuple with std::tuple as lhs"); + static_assert((std_tup1 < std_tup2) == (std_tup1 < dpl_tup2), + "compile time less than comparison does not match std::tuple with std::tuple as lhs"); + static_assert((std_tup1 <= std_tup2) == (std_tup1 <= dpl_tup2), + "compile time lt-equal comparison does not match std::tuple with std::tuple as lhs"); + static_assert((std_tup1 > std_tup2) == (std_tup1 > dpl_tup2), + "compile time greater comparison does not match std::tuple with std::tuple as lhs"); + static_assert((std_tup1 >= std_tup2) == (std_tup1 >= dpl_tup2), + "compile time gt-equal comparison does not match std::tuple with std::tuple as lhs"); + static_assert((std_tup1 != std_tup2) == (std_tup1 != dpl_tup2), + "compile time non-equality comparison does not match std::tuple with std::tuple as lhs"); + + static_assert((std_tup1 == std_tup2) == (dpl_tup1 == std_tup2), + "compile time equality comparison does not match std::tuple with std::tuple as rhs"); + static_assert((std_tup1 < std_tup2) == (dpl_tup1 < std_tup2), + "compile time less than comparison does not match std::tuple with std::tuple as rhs"); + static_assert((std_tup1 <= std_tup2) == (dpl_tup1 <= std_tup2), + "compile time lt-equal comparison does not match std::tuple with std::tuple as rhs"); + static_assert((std_tup1 > std_tup2) == (dpl_tup1 > std_tup2), + "compile time greater comparison does not match std::tuple with std::tuple as rhs"); + static_assert((std_tup1 >= std_tup2) == (dpl_tup1 >= std_tup2), + "compile time gt-equal comparison does not match std::tuple with std::tuple as rhs"); + static_assert((std_tup1 != std_tup2) == (dpl_tup1 != std_tup2), + "compile time non-equality comparison does not match std::tuple with std::tuple as rhs"); constexpr std::tuple<> std_empty1{}; constexpr std::tuple<> std_empty2{}; constexpr oneapi::dpl::tuple<> dpl_empty1{}; constexpr oneapi::dpl::tuple<> dpl_empty2{}; - static_assert((std_empty1 == std_empty2) == (dpl_empty1 == dpl_empty2), "empty compile time equality comparison does not match std::tuple"); - static_assert((std_empty1 < std_empty2) == (dpl_empty1 < dpl_empty2), "empty compile time less than comparison does not match std::tuple"); - static_assert((std_empty1 <= std_empty2) == (dpl_empty1 <= dpl_empty2), "empty compile time lt-equal comparison does not match std::tuple"); - static_assert((std_empty1 > std_empty2) == (dpl_empty1 > dpl_empty2), "empty compile time greater comparison does not match std::tuple"); - static_assert((std_empty1 >= std_empty2) == (dpl_empty1 >= dpl_empty2), "empty compile time gt-equal comparison does not match std::tuple"); - static_assert((std_empty1 != std_empty2) == (dpl_empty1 != dpl_empty2), "empty compile time non-equality comparison does not match std::tuple"); - - static_assert((std_empty1 == std_empty2) == (std_empty1 == dpl_empty2), "empty compile time equality comparison does not match std::tuple with std::tuple as lhs"); - static_assert((std_empty1 < std_empty2) == (std_empty1 < dpl_empty2), "empty compile time less than comparison does not match std::tuple with std::tuple as lhs"); - static_assert((std_empty1 <= std_empty2) == (std_empty1 <= dpl_empty2), "empty compile time lt-equal comparison does not match std::tuple with std::tuple as lhs"); - static_assert((std_empty1 > std_empty2) == (std_empty1 > dpl_empty2), "empty compile time greater comparison does not match std::tuple with std::tuple as lhs"); - static_assert((std_empty1 >= std_empty2) == (std_empty1 >= dpl_empty2), "empty compile time gt-equal comparison does not match std::tuple with std::tuple as lhs"); - static_assert((std_empty1 != std_empty2) == (std_empty1 != dpl_empty2), "empty compile time non-equality comparison does not match std::tuple with std::tuple as lhs"); - - static_assert((std_empty1 == std_empty2) == (dpl_empty1 == std_empty2), "empty compile time equality comparison does not match std::tuple with std::tuple as rhs"); - static_assert((std_empty1 < std_empty2) == (dpl_empty1 < std_empty2), "empty compile time less than comparison does not match std::tuple with std::tuple as rhs"); - static_assert((std_empty1 <= std_empty2) == (dpl_empty1 <= std_empty2), "empty compile time lt-equal comparison does not match std::tuple with std::tuple as rhs"); - static_assert((std_empty1 > std_empty2) == (dpl_empty1 > std_empty2), "empty compile time greater comparison does not match std::tuple with std::tuple as rhs"); - static_assert((std_empty1 >= std_empty2) == (dpl_empty1 >= std_empty2), "empty compile time gt-equal comparison does not match std::tuple with std::tuple as rhs"); - static_assert((std_empty1 != std_empty2) == (dpl_empty1 != std_empty2), "empty compile time non-equality comparison does not match std::tuple with std::tuple as rhs"); + static_assert((std_empty1 == std_empty2) == (dpl_empty1 == dpl_empty2), + "empty compile time equality comparison does not match std::tuple"); + static_assert((std_empty1 < std_empty2) == (dpl_empty1 < dpl_empty2), + "empty compile time less than comparison does not match std::tuple"); + static_assert((std_empty1 <= std_empty2) == (dpl_empty1 <= dpl_empty2), + "empty compile time lt-equal comparison does not match std::tuple"); + static_assert((std_empty1 > std_empty2) == (dpl_empty1 > dpl_empty2), + "empty compile time greater comparison does not match std::tuple"); + static_assert((std_empty1 >= std_empty2) == (dpl_empty1 >= dpl_empty2), + "empty compile time gt-equal comparison does not match std::tuple"); + static_assert((std_empty1 != std_empty2) == (dpl_empty1 != dpl_empty2), + "empty compile time non-equality comparison does not match std::tuple"); + + static_assert((std_empty1 == std_empty2) == (std_empty1 == dpl_empty2), + "empty compile time equality comparison does not match std::tuple with std::tuple as lhs"); + static_assert((std_empty1 < std_empty2) == (std_empty1 < dpl_empty2), + "empty compile time less than comparison does not match std::tuple with std::tuple as lhs"); + static_assert((std_empty1 <= std_empty2) == (std_empty1 <= dpl_empty2), + "empty compile time lt-equal comparison does not match std::tuple with std::tuple as lhs"); + static_assert((std_empty1 > std_empty2) == (std_empty1 > dpl_empty2), + "empty compile time greater comparison does not match std::tuple with std::tuple as lhs"); + static_assert((std_empty1 >= std_empty2) == (std_empty1 >= dpl_empty2), + "empty compile time gt-equal comparison does not match std::tuple with std::tuple as lhs"); + static_assert((std_empty1 != std_empty2) == (std_empty1 != dpl_empty2), + "empty compile time non-equality comparison does not match std::tuple with std::tuple as lhs"); + + static_assert((std_empty1 == std_empty2) == (dpl_empty1 == std_empty2), + "empty compile time equality comparison does not match std::tuple with std::tuple as rhs"); + static_assert((std_empty1 < std_empty2) == (dpl_empty1 < std_empty2), + "empty compile time less than comparison does not match std::tuple with std::tuple as rhs"); + static_assert((std_empty1 <= std_empty2) == (dpl_empty1 <= std_empty2), + "empty compile time lt-equal comparison does not match std::tuple with std::tuple as rhs"); + static_assert((std_empty1 > std_empty2) == (dpl_empty1 > std_empty2), + "empty compile time greater comparison does not match std::tuple with std::tuple as rhs"); + static_assert((std_empty1 >= std_empty2) == (dpl_empty1 >= std_empty2), + "empty compile time gt-equal comparison does not match std::tuple with std::tuple as rhs"); + static_assert((std_empty1 != std_empty2) == (dpl_empty1 != std_empty2), + "empty compile time non-equality comparison does not match std::tuple with std::tuple as rhs"); } - - int main() { From c2e94df5f3fe5873ccd056940387841f60cf6e3c Mon Sep 17 00:00:00 2001 From: Dan Hoeflinger Date: Mon, 8 Apr 2024 09:23:47 -0400 Subject: [PATCH 08/33] implement operators to avoid copies in conversion Signed-off-by: Dan Hoeflinger --- include/oneapi/dpl/pstl/tuple_impl.h | 138 ++++++++++++++++++++------- 1 file changed, 102 insertions(+), 36 deletions(-) diff --git a/include/oneapi/dpl/pstl/tuple_impl.h b/include/oneapi/dpl/pstl/tuple_impl.h index b1006870889..38d8789a6d1 100644 --- a/include/oneapi/dpl/pstl/tuple_impl.h +++ b/include/oneapi/dpl/pstl/tuple_impl.h @@ -424,36 +424,102 @@ struct tuple return *this; } -// This macro is used to define binary operators for comparison between oneAPI::dpl::__internal::tuple and -// std::tuple when they have the same number of template arguments and the individual elements which are invdividually -// comparable. These overloads are required because for overload resolution of template arguments, exact match is -// required and the compiler does not consider implicit conversions. We also allow std::tuple implementation to -// implement the operators themselves, which guarantees a match with oneAPI::dpl::__internal::tuple -#define _TUPLE_BINARY_OPERATOR_OVERLOAD(__OPERATOR) \ - template > \ - friend constexpr bool operator __OPERATOR(const tuple& __lhs, const oneapi::dpl::__internal::tuple<_U...>& __rhs) \ - { \ - return static_cast>(__lhs) __OPERATOR static_cast>(__rhs); \ - } \ - template > \ - friend constexpr bool operator __OPERATOR(const tuple& __lhs, const std::tuple<_U...>& __rhs) \ - { \ - return static_cast>(__lhs) __OPERATOR __rhs; \ - } \ - template > \ - friend constexpr bool operator __OPERATOR(const std::tuple<_U...>& __lhs, const tuple& __rhs) \ - { \ - return __lhs __OPERATOR static_cast>(__rhs); \ - } - - _TUPLE_BINARY_OPERATOR_OVERLOAD(==) - _TUPLE_BINARY_OPERATOR_OVERLOAD(!=) - _TUPLE_BINARY_OPERATOR_OVERLOAD(<) - _TUPLE_BINARY_OPERATOR_OVERLOAD(<=) - _TUPLE_BINARY_OPERATOR_OVERLOAD(>) - _TUPLE_BINARY_OPERATOR_OVERLOAD(>=) - -#undef _TUPLE_BINARY_OPERATOR_OVERLOAD +// The following operators are used to define binary operators for comparison between oneAPI::dpl::__internal::tuple and +// std::tuple when they have the same number of template arguments and the individual elements which are invdividually +// omparable. These overloads are required because for overload resolution of template arguments, exact match is +// required and the compiler does not consider implicit conversions. We also allow std::tuple implementation to +// implement the operators themselves, which guarantees a match with oneAPI::dpl::__internal::tuple + + template > + friend constexpr bool operator==(const tuple& __lhs, const oneapi::dpl::__internal::tuple<_U...>& __rhs) + { + return __lhs.holder.value == __rhs.holder.value && __lhs.next == __rhs.next; + } + template > + friend constexpr bool operator==(const tuple& __lhs, const std::tuple<_U...>& __rhs) + { + return __lhs.holder.value == std::get<0>(__rhs) && __lhs.next == oneapi::dpl::__internal::get_tuple_tail(__rhs); + } + template > + friend constexpr bool operator==(const std::tuple<_U...>& __lhs, const tuple& __rhs) + { + return std::get<0>(__lhs) == __rhs.holder.value && oneapi::dpl::__internal::get_tuple_tail(__lhs) == __rhs.next; + } + template > + friend constexpr bool operator!=(const tuple& __lhs, const oneapi::dpl::__internal::tuple<_U...>& __rhs) + { + return !(__lhs == __rhs); + } + template > + friend constexpr bool operator!=(const tuple& __lhs, const std::tuple<_U...>& __rhs) + { + return !(__lhs == __rhs); + } + template > + friend constexpr bool operator!=(const std::tuple<_U...>& __lhs, const tuple& __rhs) + { + return !(__lhs == __rhs); + } + template > + friend constexpr bool operator<(const tuple& __lhs, const oneapi::dpl::__internal::tuple<_U...>& __rhs) + { + return __lhs.holder.value < __rhs.holder.value || (!(__rhs.holder.value < __lhs.holder.value) && __lhs.next < __rhs.next); + } + template > + friend constexpr bool operator<(const tuple& __lhs, const std::tuple<_U...>& __rhs) + { + return __lhs.holder.value < std::get<0>(__rhs) || (!(std::get<0>(__rhs) < __lhs.holder.value) && __lhs.next < oneapi::dpl::__internal::get_tuple_tail(__rhs)); + } + template > + friend constexpr bool operator<(const std::tuple<_U...>& __lhs, const tuple& __rhs) + { + return std::get<0>(__lhs) < __rhs.holder.value || (!(__rhs.holder.value < std::get<0>(__lhs)) && oneapi::dpl::__internal::get_tuple_tail(__lhs) < __rhs.next); + } + template > + friend constexpr bool operator<=(const tuple& __lhs, const oneapi::dpl::__internal::tuple<_U...>& __rhs) + { + return !(__rhs < __lhs); + } + template > + friend constexpr bool operator<=(const tuple& __lhs, const std::tuple<_U...>& __rhs) + { + return !(__rhs < __lhs); + } + template > + friend constexpr bool operator<=(const std::tuple<_U...>& __lhs, const tuple& __rhs) + { + return !(__rhs < __lhs); + } + template > + friend constexpr bool operator>(const tuple& __lhs, const oneapi::dpl::__internal::tuple<_U...>& __rhs) + { + return __rhs < __lhs; + } + template > + friend constexpr bool operator>(const tuple& __lhs, const std::tuple<_U...>& __rhs) + { + return __rhs < __lhs; + } + template > + friend constexpr bool operator>(const std::tuple<_U...>& __lhs, const tuple& __rhs) + { + return __rhs < __lhs; + } + template > + friend constexpr bool operator>=(const tuple& __lhs, const oneapi::dpl::__internal::tuple<_U...>& __rhs) + { + return !(__lhs < __rhs); + } + template > + friend constexpr bool operator>=(const tuple& __lhs, const std::tuple<_U...>& __rhs) + { + return !(__lhs < __rhs); + } + template > + friend constexpr bool operator>=(const std::tuple<_U...>& __lhs, const tuple& __rhs) + { + return !(__lhs < __rhs); + } template static ::std::tuple @@ -490,32 +556,32 @@ struct tuple<> friend constexpr bool operator==(const tuple& __lhs, const tuple& __rhs) { - return tuple_type{} == tuple_type{}; + return true; } friend constexpr bool operator!=(const tuple& __lhs, const tuple& __rhs) { - return tuple_type{} != tuple_type{}; + return false; } friend constexpr bool operator<(const tuple& __lhs, const tuple& __rhs) { - return tuple_type{} < tuple_type{}; + return false; } friend constexpr bool operator<=(const tuple& __lhs, const tuple& __rhs) { - return tuple_type{} <= tuple_type{}; + return true; } friend constexpr bool operator>(const tuple& __lhs, const tuple& __rhs) { - return tuple_type{} > tuple_type{}; + return false; } friend constexpr bool operator>=(const tuple& __lhs, const tuple& __rhs) { - return tuple_type{} >= tuple_type{}; + return true; } }; From 496ad9c349f167c2a185d15f9cc8216d0834eeb2 Mon Sep 17 00:00:00 2001 From: Dan Hoeflinger Date: Mon, 8 Apr 2024 10:06:32 -0400 Subject: [PATCH 09/33] move code and formatting Signed-off-by: Dan Hoeflinger --- include/oneapi/dpl/pstl/tuple_impl.h | 109 ++++++++++++++++----------- 1 file changed, 66 insertions(+), 43 deletions(-) diff --git a/include/oneapi/dpl/pstl/tuple_impl.h b/include/oneapi/dpl/pstl/tuple_impl.h index 38d8789a6d1..ffb1d87f52b 100644 --- a/include/oneapi/dpl/pstl/tuple_impl.h +++ b/include/oneapi/dpl/pstl/tuple_impl.h @@ -424,99 +424,125 @@ struct tuple return *this; } -// The following operators are used to define binary operators for comparison between oneAPI::dpl::__internal::tuple and -// std::tuple when they have the same number of template arguments and the individual elements which are invdividually -// omparable. These overloads are required because for overload resolution of template arguments, exact match is -// required and the compiler does not consider implicit conversions. We also allow std::tuple implementation to -// implement the operators themselves, which guarantees a match with oneAPI::dpl::__internal::tuple - + // The following operators enable support of binary comparison of oneDPL internal tuples with other oneDPL internal + // tuples with the same number of types where individual elements are binary comparable template > - friend constexpr bool operator==(const tuple& __lhs, const oneapi::dpl::__internal::tuple<_U...>& __rhs) + friend constexpr bool + operator==(const tuple& __lhs, const oneapi::dpl::__internal::tuple<_U...>& __rhs) { return __lhs.holder.value == __rhs.holder.value && __lhs.next == __rhs.next; } template > - friend constexpr bool operator==(const tuple& __lhs, const std::tuple<_U...>& __rhs) + friend constexpr bool + operator!=(const tuple& __lhs, const oneapi::dpl::__internal::tuple<_U...>& __rhs) { - return __lhs.holder.value == std::get<0>(__rhs) && __lhs.next == oneapi::dpl::__internal::get_tuple_tail(__rhs); + return !(__lhs == __rhs); } template > - friend constexpr bool operator==(const std::tuple<_U...>& __lhs, const tuple& __rhs) + friend constexpr bool + operator<(const tuple& __lhs, const oneapi::dpl::__internal::tuple<_U...>& __rhs) { - return std::get<0>(__lhs) == __rhs.holder.value && oneapi::dpl::__internal::get_tuple_tail(__lhs) == __rhs.next; + return __lhs.holder.value < __rhs.holder.value || + (!(__rhs.holder.value < __lhs.holder.value) && __lhs.next < __rhs.next); } + template > - friend constexpr bool operator!=(const tuple& __lhs, const oneapi::dpl::__internal::tuple<_U...>& __rhs) + friend constexpr bool + operator<=(const tuple& __lhs, const oneapi::dpl::__internal::tuple<_U...>& __rhs) { - return !(__lhs == __rhs); + return !(__rhs < __lhs); } + template > - friend constexpr bool operator!=(const tuple& __lhs, const std::tuple<_U...>& __rhs) + friend constexpr bool + operator>(const tuple& __lhs, const oneapi::dpl::__internal::tuple<_U...>& __rhs) { - return !(__lhs == __rhs); + return __rhs < __lhs; } + template > - friend constexpr bool operator!=(const std::tuple<_U...>& __lhs, const tuple& __rhs) + friend constexpr bool + operator>=(const tuple& __lhs, const oneapi::dpl::__internal::tuple<_U...>& __rhs) { - return !(__lhs == __rhs); + return !(__lhs < __rhs); } + + // The following operators enable support of binary comparison of oneDPL internal tuples with std::tuple as rhs + // with the same number of types where individual elements are binary comparable template > - friend constexpr bool operator<(const tuple& __lhs, const oneapi::dpl::__internal::tuple<_U...>& __rhs) + friend constexpr bool + operator==(const tuple& __lhs, const std::tuple<_U...>& __rhs) { - return __lhs.holder.value < __rhs.holder.value || (!(__rhs.holder.value < __lhs.holder.value) && __lhs.next < __rhs.next); + return __lhs.holder.value == std::get<0>(__rhs) && __lhs.next == oneapi::dpl::__internal::get_tuple_tail(__rhs); } template > - friend constexpr bool operator<(const tuple& __lhs, const std::tuple<_U...>& __rhs) + friend constexpr bool + operator!=(const tuple& __lhs, const std::tuple<_U...>& __rhs) { - return __lhs.holder.value < std::get<0>(__rhs) || (!(std::get<0>(__rhs) < __lhs.holder.value) && __lhs.next < oneapi::dpl::__internal::get_tuple_tail(__rhs)); + return !(__lhs == __rhs); } template > - friend constexpr bool operator<(const std::tuple<_U...>& __lhs, const tuple& __rhs) + friend constexpr bool + operator<(const tuple& __lhs, const std::tuple<_U...>& __rhs) { - return std::get<0>(__lhs) < __rhs.holder.value || (!(__rhs.holder.value < std::get<0>(__lhs)) && oneapi::dpl::__internal::get_tuple_tail(__lhs) < __rhs.next); + return __lhs.holder.value < std::get<0>(__rhs) || (!(std::get<0>(__rhs) < __lhs.holder.value) && + __lhs.next < oneapi::dpl::__internal::get_tuple_tail(__rhs)); } template > - friend constexpr bool operator<=(const tuple& __lhs, const oneapi::dpl::__internal::tuple<_U...>& __rhs) + friend constexpr bool + operator<=(const tuple& __lhs, const std::tuple<_U...>& __rhs) { return !(__rhs < __lhs); } template > - friend constexpr bool operator<=(const tuple& __lhs, const std::tuple<_U...>& __rhs) + friend constexpr bool + operator>(const tuple& __lhs, const std::tuple<_U...>& __rhs) { - return !(__rhs < __lhs); + return __rhs < __lhs; } template > - friend constexpr bool operator<=(const std::tuple<_U...>& __lhs, const tuple& __rhs) + friend constexpr bool + operator>=(const tuple& __lhs, const std::tuple<_U...>& __rhs) { - return !(__rhs < __lhs); + return !(__lhs < __rhs); } + + // The following operators enable support of binary comparison of oneDPL internal tuples with std::tuple as lhs + // with the same number of types where individual elements are binary comparable template > - friend constexpr bool operator>(const tuple& __lhs, const oneapi::dpl::__internal::tuple<_U...>& __rhs) + friend constexpr bool + operator==(const std::tuple<_U...>& __lhs, const tuple& __rhs) { - return __rhs < __lhs; + return std::get<0>(__lhs) == __rhs.holder.value && oneapi::dpl::__internal::get_tuple_tail(__lhs) == __rhs.next; } template > - friend constexpr bool operator>(const tuple& __lhs, const std::tuple<_U...>& __rhs) + friend constexpr bool + operator!=(const std::tuple<_U...>& __lhs, const tuple& __rhs) { - return __rhs < __lhs; + return !(__lhs == __rhs); } template > - friend constexpr bool operator>(const std::tuple<_U...>& __lhs, const tuple& __rhs) + friend constexpr bool + operator<(const std::tuple<_U...>& __lhs, const tuple& __rhs) { - return __rhs < __lhs; + return std::get<0>(__lhs) < __rhs.holder.value || (!(__rhs.holder.value < std::get<0>(__lhs)) && + oneapi::dpl::__internal::get_tuple_tail(__lhs) < __rhs.next); } template > - friend constexpr bool operator>=(const tuple& __lhs, const oneapi::dpl::__internal::tuple<_U...>& __rhs) + friend constexpr bool + operator<=(const std::tuple<_U...>& __lhs, const tuple& __rhs) { - return !(__lhs < __rhs); + return !(__rhs < __lhs); } template > - friend constexpr bool operator>=(const tuple& __lhs, const std::tuple<_U...>& __rhs) + friend constexpr bool + operator>(const std::tuple<_U...>& __lhs, const tuple& __rhs) { - return !(__lhs < __rhs); + return __rhs < __lhs; } template > - friend constexpr bool operator>=(const std::tuple<_U...>& __lhs, const tuple& __rhs) + friend constexpr bool + operator>=(const std::tuple<_U...>& __lhs, const tuple& __rhs) { return !(__lhs < __rhs); } @@ -542,10 +568,7 @@ struct tuple<> tuple operator[](tuple) { return {}; } tuple operator[](const tuple&) const { return {}; } - operator tuple_type() const - { - return tuple_type{}; - } + operator tuple_type() const { return tuple_type{}; } tuple& operator=(const tuple&) = default; tuple& From f03cc8a784faaf1806d7f3d5185f9083448ef53c Mon Sep 17 00:00:00 2001 From: Dan Hoeflinger Date: Mon, 8 Apr 2024 11:59:16 -0400 Subject: [PATCH 10/33] updated impl with no copies, conservative enable_if Signed-off-by: Dan Hoeflinger --- include/oneapi/dpl/pstl/tuple_impl.h | 118 ++++++++++++++++++++++----- 1 file changed, 97 insertions(+), 21 deletions(-) diff --git a/include/oneapi/dpl/pstl/tuple_impl.h b/include/oneapi/dpl/pstl/tuple_impl.h index ffb1d87f52b..8253931e79a 100644 --- a/include/oneapi/dpl/pstl/tuple_impl.h +++ b/include/oneapi/dpl/pstl/tuple_impl.h @@ -37,6 +37,22 @@ struct tuple; namespace std { +//forward declare new std::get() functions so they can be used in impl +template +constexpr ::std::tuple_element_t<_Idx, oneapi::dpl::__internal::tuple<_Tp...>>& +get(oneapi::dpl::__internal::tuple<_Tp...>&); + +template +constexpr ::std::tuple_element_t<_Idx, oneapi::dpl::__internal::tuple<_Tp...>> const& +get(const oneapi::dpl::__internal::tuple<_Tp...>&); + +template +constexpr ::std::tuple_element_t<_Idx, oneapi::dpl::__internal::tuple<_Tp...>>&& +get(oneapi::dpl::__internal::tuple<_Tp...>&&); + +template +constexpr ::std::tuple_element_t<_Idx, oneapi::dpl::__internal::tuple<_Tp...>> const&& +get(const oneapi::dpl::__internal::tuple<_Tp...>&& __a); template <::std::size_t N, typename T, typename... Rest> struct tuple_element> : tuple_element> @@ -289,6 +305,69 @@ struct __copy_assignable_holder<_Tp, false> : oneapi::dpl::__internal::__value_h operator=(__copy_assignable_holder&& other) = default; }; +template +struct __get_std_tuple_t_impl +{ + using type = void; +}; + +template +struct __get_std_tuple_t_impl> +{ + using type = std::tuple; +}; + +template +struct __get_std_tuple_t_impl> +{ + using type = std::tuple; +}; + +template +using __get_std_tuple_t = typename __get_std_tuple_t_impl>::type; + +template +using __is_tuple_type = std::negation>>; + +template +using __is_std_tuple_type = std::is_same<__get_std_tuple_t, std::decay_t>; + +// Require that both are tuple types, but at least one type is a oneDPL internal tuple, and that the number of tuple +// elements are the same +template +using __comparable_tuple_types = std::conjunction< + oneapi::dpl::__internal::__is_tuple_type, oneapi::dpl::__internal::__is_tuple_type, + std::negation, oneapi::dpl::__internal::__is_std_tuple_type>>, + std::bool_constant>::value == std::tuple_size>::value>>; + +template ::value, int> = 0> +constexpr bool +__equal(const _Tuple1& __lhs, const _Tuple2& __rhs) +{ + if constexpr(I < std::tuple_size_v<_Tuple1>) + { + return std::get(__lhs) == std::get(__rhs) && oneapi::dpl::__internal::__equal<_Tuple1, _Tuple2, I+1>(__lhs, __rhs); + } + else + { + return true; + } +} +template ::value, int> = 0> +constexpr bool +__less(const _Tuple1& __lhs, const _Tuple2& __rhs) +{ + if constexpr(I < std::tuple_size_v<_Tuple1>) + { + return std::get(__lhs) < std::get(__rhs) || + (!(std::get(__rhs) < std::get(__lhs)) && oneapi::dpl::__internal::__less<_Tuple1, _Tuple2, I+1>(__lhs, __rhs)); + } + else + { + return false; + } +} + template struct tuple { @@ -430,41 +509,40 @@ struct tuple friend constexpr bool operator==(const tuple& __lhs, const oneapi::dpl::__internal::tuple<_U...>& __rhs) { - return __lhs.holder.value == __rhs.holder.value && __lhs.next == __rhs.next; + return oneapi::dpl::__internal::__equal(__lhs, __rhs); } template > friend constexpr bool operator!=(const tuple& __lhs, const oneapi::dpl::__internal::tuple<_U...>& __rhs) { - return !(__lhs == __rhs); + return !(oneapi::dpl::__internal::__equal(__lhs, __rhs)); } template > friend constexpr bool operator<(const tuple& __lhs, const oneapi::dpl::__internal::tuple<_U...>& __rhs) { - return __lhs.holder.value < __rhs.holder.value || - (!(__rhs.holder.value < __lhs.holder.value) && __lhs.next < __rhs.next); + return oneapi::dpl::__internal::__less(__lhs, __rhs); } template > friend constexpr bool operator<=(const tuple& __lhs, const oneapi::dpl::__internal::tuple<_U...>& __rhs) { - return !(__rhs < __lhs); + return !(oneapi::dpl::__internal::__less(__rhs, __lhs)); } template > friend constexpr bool operator>(const tuple& __lhs, const oneapi::dpl::__internal::tuple<_U...>& __rhs) { - return __rhs < __lhs; + return oneapi::dpl::__internal::__less(__rhs, __lhs); } template > friend constexpr bool operator>=(const tuple& __lhs, const oneapi::dpl::__internal::tuple<_U...>& __rhs) { - return !(__lhs < __rhs); + return !(oneapi::dpl::__internal::__less(__lhs, __rhs)); } // The following operators enable support of binary comparison of oneDPL internal tuples with std::tuple as rhs @@ -473,38 +551,37 @@ struct tuple friend constexpr bool operator==(const tuple& __lhs, const std::tuple<_U...>& __rhs) { - return __lhs.holder.value == std::get<0>(__rhs) && __lhs.next == oneapi::dpl::__internal::get_tuple_tail(__rhs); + return oneapi::dpl::__internal::__equal(__lhs, __rhs); } template > friend constexpr bool operator!=(const tuple& __lhs, const std::tuple<_U...>& __rhs) { - return !(__lhs == __rhs); + return !(oneapi::dpl::__internal::__equal(__lhs, __rhs)); } template > friend constexpr bool operator<(const tuple& __lhs, const std::tuple<_U...>& __rhs) { - return __lhs.holder.value < std::get<0>(__rhs) || (!(std::get<0>(__rhs) < __lhs.holder.value) && - __lhs.next < oneapi::dpl::__internal::get_tuple_tail(__rhs)); + return oneapi::dpl::__internal::__less(__lhs, __rhs); } template > friend constexpr bool operator<=(const tuple& __lhs, const std::tuple<_U...>& __rhs) { - return !(__rhs < __lhs); + return !(oneapi::dpl::__internal::__less(__rhs, __lhs)); } template > friend constexpr bool operator>(const tuple& __lhs, const std::tuple<_U...>& __rhs) { - return __rhs < __lhs; + return oneapi::dpl::__internal::__less(__rhs, __lhs); } template > friend constexpr bool operator>=(const tuple& __lhs, const std::tuple<_U...>& __rhs) { - return !(__lhs < __rhs); + return !(oneapi::dpl::__internal::__less(__lhs, __rhs)); } // The following operators enable support of binary comparison of oneDPL internal tuples with std::tuple as lhs @@ -513,38 +590,37 @@ struct tuple friend constexpr bool operator==(const std::tuple<_U...>& __lhs, const tuple& __rhs) { - return std::get<0>(__lhs) == __rhs.holder.value && oneapi::dpl::__internal::get_tuple_tail(__lhs) == __rhs.next; + return oneapi::dpl::__internal::__equal(__lhs, __rhs); } template > friend constexpr bool operator!=(const std::tuple<_U...>& __lhs, const tuple& __rhs) { - return !(__lhs == __rhs); + return !(oneapi::dpl::__internal::__equal(__lhs, __rhs)); } template > friend constexpr bool operator<(const std::tuple<_U...>& __lhs, const tuple& __rhs) { - return std::get<0>(__lhs) < __rhs.holder.value || (!(__rhs.holder.value < std::get<0>(__lhs)) && - oneapi::dpl::__internal::get_tuple_tail(__lhs) < __rhs.next); + return oneapi::dpl::__internal::__less(__lhs, __rhs); } template > friend constexpr bool operator<=(const std::tuple<_U...>& __lhs, const tuple& __rhs) { - return !(__rhs < __lhs); + return !(oneapi::dpl::__internal::__less(__rhs, __lhs)); } template > friend constexpr bool operator>(const std::tuple<_U...>& __lhs, const tuple& __rhs) { - return __rhs < __lhs; + return oneapi::dpl::__internal::__less(__rhs, __lhs); } template > friend constexpr bool operator>=(const std::tuple<_U...>& __lhs, const tuple& __rhs) { - return !(__lhs < __rhs); + return !(oneapi::dpl::__internal::__less(__lhs, __rhs)); } template From c5a5c56a6d5ba8ba2670f77fd9acefba133c8ea4 Mon Sep 17 00:00:00 2001 From: Dan Hoeflinger Date: Mon, 8 Apr 2024 12:48:06 -0400 Subject: [PATCH 11/33] removing unnecessary complexity Signed-off-by: Dan Hoeflinger --- include/oneapi/dpl/pstl/tuple_impl.h | 39 ++-------------------------- 1 file changed, 2 insertions(+), 37 deletions(-) diff --git a/include/oneapi/dpl/pstl/tuple_impl.h b/include/oneapi/dpl/pstl/tuple_impl.h index 8253931e79a..5f7a3e2a686 100644 --- a/include/oneapi/dpl/pstl/tuple_impl.h +++ b/include/oneapi/dpl/pstl/tuple_impl.h @@ -305,42 +305,7 @@ struct __copy_assignable_holder<_Tp, false> : oneapi::dpl::__internal::__value_h operator=(__copy_assignable_holder&& other) = default; }; -template -struct __get_std_tuple_t_impl -{ - using type = void; -}; - -template -struct __get_std_tuple_t_impl> -{ - using type = std::tuple; -}; - -template -struct __get_std_tuple_t_impl> -{ - using type = std::tuple; -}; - -template -using __get_std_tuple_t = typename __get_std_tuple_t_impl>::type; - -template -using __is_tuple_type = std::negation>>; - -template -using __is_std_tuple_type = std::is_same<__get_std_tuple_t, std::decay_t>; - -// Require that both are tuple types, but at least one type is a oneDPL internal tuple, and that the number of tuple -// elements are the same -template -using __comparable_tuple_types = std::conjunction< - oneapi::dpl::__internal::__is_tuple_type, oneapi::dpl::__internal::__is_tuple_type, - std::negation, oneapi::dpl::__internal::__is_std_tuple_type>>, - std::bool_constant>::value == std::tuple_size>::value>>; - -template ::value, int> = 0> +template constexpr bool __equal(const _Tuple1& __lhs, const _Tuple2& __rhs) { @@ -353,7 +318,7 @@ __equal(const _Tuple1& __lhs, const _Tuple2& __rhs) return true; } } -template ::value, int> = 0> +template constexpr bool __less(const _Tuple1& __lhs, const _Tuple2& __rhs) { From 2e7ba03e39befe69250fa9824b1e669852d4f4dd Mon Sep 17 00:00:00 2001 From: Dan Hoeflinger Date: Mon, 8 Apr 2024 12:49:41 -0400 Subject: [PATCH 12/33] formatting Signed-off-by: Dan Hoeflinger --- include/oneapi/dpl/pstl/tuple_impl.h | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/include/oneapi/dpl/pstl/tuple_impl.h b/include/oneapi/dpl/pstl/tuple_impl.h index 5f7a3e2a686..286960a1469 100644 --- a/include/oneapi/dpl/pstl/tuple_impl.h +++ b/include/oneapi/dpl/pstl/tuple_impl.h @@ -309,9 +309,10 @@ template constexpr bool __equal(const _Tuple1& __lhs, const _Tuple2& __rhs) { - if constexpr(I < std::tuple_size_v<_Tuple1>) + if constexpr (I < std::tuple_size_v<_Tuple1>) { - return std::get(__lhs) == std::get(__rhs) && oneapi::dpl::__internal::__equal<_Tuple1, _Tuple2, I+1>(__lhs, __rhs); + return std::get(__lhs) == std::get(__rhs) && + oneapi::dpl::__internal::__equal<_Tuple1, _Tuple2, I + 1>(__lhs, __rhs); } else { @@ -322,10 +323,11 @@ template constexpr bool __less(const _Tuple1& __lhs, const _Tuple2& __rhs) { - if constexpr(I < std::tuple_size_v<_Tuple1>) + if constexpr (I < std::tuple_size_v<_Tuple1>) { return std::get(__lhs) < std::get(__rhs) || - (!(std::get(__rhs) < std::get(__lhs)) && oneapi::dpl::__internal::__less<_Tuple1, _Tuple2, I+1>(__lhs, __rhs)); + (!(std::get(__rhs) < std::get(__lhs)) && + oneapi::dpl::__internal::__less<_Tuple1, _Tuple2, I + 1>(__lhs, __rhs)); } else { From 209460a3c02b7f59b49c91049d2690b986e738d5 Mon Sep 17 00:00:00 2001 From: Dan Hoeflinger Date: Mon, 8 Apr 2024 12:51:32 -0400 Subject: [PATCH 13/33] remove variable name from fwd decl Signed-off-by: Dan Hoeflinger --- include/oneapi/dpl/pstl/tuple_impl.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/include/oneapi/dpl/pstl/tuple_impl.h b/include/oneapi/dpl/pstl/tuple_impl.h index 286960a1469..e8e993195e7 100644 --- a/include/oneapi/dpl/pstl/tuple_impl.h +++ b/include/oneapi/dpl/pstl/tuple_impl.h @@ -52,7 +52,8 @@ get(oneapi::dpl::__internal::tuple<_Tp...>&&); template constexpr ::std::tuple_element_t<_Idx, oneapi::dpl::__internal::tuple<_Tp...>> const&& -get(const oneapi::dpl::__internal::tuple<_Tp...>&& __a); +get(const oneapi::dpl::__internal::tuple<_Tp...>&&); + template <::std::size_t N, typename T, typename... Rest> struct tuple_element> : tuple_element> From de3ae6e57bad041540eb97ab8f4cd47869dba3ae Mon Sep 17 00:00:00 2001 From: Dan Hoeflinger Date: Mon, 8 Apr 2024 13:09:03 -0400 Subject: [PATCH 14/33] improved enable_if Signed-off-by: Dan Hoeflinger --- include/oneapi/dpl/pstl/tuple_impl.h | 36 ++++++++++++++-------------- 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/include/oneapi/dpl/pstl/tuple_impl.h b/include/oneapi/dpl/pstl/tuple_impl.h index e8e993195e7..ead792948dd 100644 --- a/include/oneapi/dpl/pstl/tuple_impl.h +++ b/include/oneapi/dpl/pstl/tuple_impl.h @@ -473,40 +473,40 @@ struct tuple // The following operators enable support of binary comparison of oneDPL internal tuples with other oneDPL internal // tuples with the same number of types where individual elements are binary comparable - template > + template = 0> friend constexpr bool operator==(const tuple& __lhs, const oneapi::dpl::__internal::tuple<_U...>& __rhs) { return oneapi::dpl::__internal::__equal(__lhs, __rhs); } - template > + template = 0> friend constexpr bool operator!=(const tuple& __lhs, const oneapi::dpl::__internal::tuple<_U...>& __rhs) { return !(oneapi::dpl::__internal::__equal(__lhs, __rhs)); } - template > + template = 0> friend constexpr bool operator<(const tuple& __lhs, const oneapi::dpl::__internal::tuple<_U...>& __rhs) { return oneapi::dpl::__internal::__less(__lhs, __rhs); } - template > + template = 0> friend constexpr bool operator<=(const tuple& __lhs, const oneapi::dpl::__internal::tuple<_U...>& __rhs) { return !(oneapi::dpl::__internal::__less(__rhs, __lhs)); } - template > + template = 0> friend constexpr bool operator>(const tuple& __lhs, const oneapi::dpl::__internal::tuple<_U...>& __rhs) { return oneapi::dpl::__internal::__less(__rhs, __lhs); } - template > + template = 0> friend constexpr bool operator>=(const tuple& __lhs, const oneapi::dpl::__internal::tuple<_U...>& __rhs) { @@ -515,37 +515,37 @@ struct tuple // The following operators enable support of binary comparison of oneDPL internal tuples with std::tuple as rhs // with the same number of types where individual elements are binary comparable - template > + template = 0> friend constexpr bool operator==(const tuple& __lhs, const std::tuple<_U...>& __rhs) { return oneapi::dpl::__internal::__equal(__lhs, __rhs); } - template > + template = 0> friend constexpr bool operator!=(const tuple& __lhs, const std::tuple<_U...>& __rhs) { return !(oneapi::dpl::__internal::__equal(__lhs, __rhs)); } - template > + template = 0> friend constexpr bool operator<(const tuple& __lhs, const std::tuple<_U...>& __rhs) { return oneapi::dpl::__internal::__less(__lhs, __rhs); } - template > + template = 0> friend constexpr bool operator<=(const tuple& __lhs, const std::tuple<_U...>& __rhs) { return !(oneapi::dpl::__internal::__less(__rhs, __lhs)); } - template > + template = 0> friend constexpr bool operator>(const tuple& __lhs, const std::tuple<_U...>& __rhs) { return oneapi::dpl::__internal::__less(__rhs, __lhs); } - template > + template = 0> friend constexpr bool operator>=(const tuple& __lhs, const std::tuple<_U...>& __rhs) { @@ -554,37 +554,37 @@ struct tuple // The following operators enable support of binary comparison of oneDPL internal tuples with std::tuple as lhs // with the same number of types where individual elements are binary comparable - template > + template = 0> friend constexpr bool operator==(const std::tuple<_U...>& __lhs, const tuple& __rhs) { return oneapi::dpl::__internal::__equal(__lhs, __rhs); } - template > + template = 0> friend constexpr bool operator!=(const std::tuple<_U...>& __lhs, const tuple& __rhs) { return !(oneapi::dpl::__internal::__equal(__lhs, __rhs)); } - template > + template = 0> friend constexpr bool operator<(const std::tuple<_U...>& __lhs, const tuple& __rhs) { return oneapi::dpl::__internal::__less(__lhs, __rhs); } - template > + template = 0> friend constexpr bool operator<=(const std::tuple<_U...>& __lhs, const tuple& __rhs) { return !(oneapi::dpl::__internal::__less(__rhs, __lhs)); } - template > + template = 0> friend constexpr bool operator>(const std::tuple<_U...>& __lhs, const tuple& __rhs) { return oneapi::dpl::__internal::__less(__rhs, __lhs); } - template > + template = 0> friend constexpr bool operator>=(const std::tuple<_U...>& __lhs, const tuple& __rhs) { From b5cfd21afbe55092a0cb7d576bac19191e4d835a Mon Sep 17 00:00:00 2001 From: Dan Hoeflinger Date: Mon, 8 Apr 2024 16:30:40 -0400 Subject: [PATCH 15/33] int for index Signed-off-by: Dan Hoeflinger --- include/oneapi/dpl/pstl/tuple_impl.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/oneapi/dpl/pstl/tuple_impl.h b/include/oneapi/dpl/pstl/tuple_impl.h index ead792948dd..6f3d0307d94 100644 --- a/include/oneapi/dpl/pstl/tuple_impl.h +++ b/include/oneapi/dpl/pstl/tuple_impl.h @@ -306,7 +306,7 @@ struct __copy_assignable_holder<_Tp, false> : oneapi::dpl::__internal::__value_h operator=(__copy_assignable_holder&& other) = default; }; -template +template constexpr bool __equal(const _Tuple1& __lhs, const _Tuple2& __rhs) { @@ -320,7 +320,7 @@ __equal(const _Tuple1& __lhs, const _Tuple2& __rhs) return true; } } -template +template constexpr bool __less(const _Tuple1& __lhs, const _Tuple2& __rhs) { From be4a7374ec64ef0b8d567ffa19a95007479887bf Mon Sep 17 00:00:00 2001 From: Dan Hoeflinger Date: Mon, 8 Apr 2024 16:35:09 -0400 Subject: [PATCH 16/33] removing unused definition Signed-off-by: Dan Hoeflinger --- test/parallel_api/iterator/tuple_unit.pass.cpp | 3 --- 1 file changed, 3 deletions(-) diff --git a/test/parallel_api/iterator/tuple_unit.pass.cpp b/test/parallel_api/iterator/tuple_unit.pass.cpp index a938b2d439b..d1be1fcc78b 100644 --- a/test/parallel_api/iterator/tuple_unit.pass.cpp +++ b/test/parallel_api/iterator/tuple_unit.pass.cpp @@ -19,9 +19,6 @@ #include "support/utils.h" -template -using tuplewrapper = oneapi::dpl::__internal::tuple::__type...>; - template static oneapi::dpl::__internal::tuple<_T...> to_onedpl_tuple(const std::tuple<_T...>& __t) From 291d6b81a5452f1811f69f5fe400aa5c9ca7ab2f Mon Sep 17 00:00:00 2001 From: Dan Hoeflinger Date: Mon, 12 Aug 2024 11:25:18 -0400 Subject: [PATCH 17/33] removing unused parameter names Signed-off-by: Dan Hoeflinger --- include/oneapi/dpl/pstl/tuple_impl.h | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/include/oneapi/dpl/pstl/tuple_impl.h b/include/oneapi/dpl/pstl/tuple_impl.h index 6f3d0307d94..8bfa8e34047 100644 --- a/include/oneapi/dpl/pstl/tuple_impl.h +++ b/include/oneapi/dpl/pstl/tuple_impl.h @@ -621,32 +621,32 @@ struct tuple<> return *this; } friend constexpr bool - operator==(const tuple& __lhs, const tuple& __rhs) + operator==(const tuple&, const tuple&) { return true; } friend constexpr bool - operator!=(const tuple& __lhs, const tuple& __rhs) + operator!=(const tuple&, const tuple&) { return false; } friend constexpr bool - operator<(const tuple& __lhs, const tuple& __rhs) + operator<(const tuple&, const tuple&) { return false; } friend constexpr bool - operator<=(const tuple& __lhs, const tuple& __rhs) + operator<=(const tuple&, const tuple&) { return true; } friend constexpr bool - operator>(const tuple& __lhs, const tuple& __rhs) + operator>(const tuple&, const tuple&) { return false; } friend constexpr bool - operator>=(const tuple& __lhs, const tuple& __rhs) + operator>=(const tuple&, const tuple&) { return true; } From 2a167c26554d0eeeee03ef0644af4c21d21777c5 Mon Sep 17 00:00:00 2001 From: Dan Hoeflinger Date: Mon, 12 Aug 2024 12:33:49 -0400 Subject: [PATCH 18/33] consolidating redundant instances, using forwarding types in helpers. Signed-off-by: Dan Hoeflinger --- include/oneapi/dpl/pstl/tuple_impl.h | 191 +++++++++++++-------------- 1 file changed, 89 insertions(+), 102 deletions(-) diff --git a/include/oneapi/dpl/pstl/tuple_impl.h b/include/oneapi/dpl/pstl/tuple_impl.h index 8bfa8e34047..0baa7e453f8 100644 --- a/include/oneapi/dpl/pstl/tuple_impl.h +++ b/include/oneapi/dpl/pstl/tuple_impl.h @@ -308,12 +308,15 @@ struct __copy_assignable_holder<_Tp, false> : oneapi::dpl::__internal::__value_h template constexpr bool -__equal(const _Tuple1& __lhs, const _Tuple2& __rhs) +__equal(_Tuple1&& __lhs, _Tuple2&& __rhs) { - if constexpr (I < std::tuple_size_v<_Tuple1>) + static_assert(std::tuple_size_v> == std::tuple_size_v>, + "Tuples must have the same size to be equality compared"); + if constexpr (I < std::tuple_size_v>) { return std::get(__lhs) == std::get(__rhs) && - oneapi::dpl::__internal::__equal<_Tuple1, _Tuple2, I + 1>(__lhs, __rhs); + oneapi::dpl::__internal::__equal<_Tuple1, _Tuple2, I + 1>(std::forward<_Tuple1>(__lhs), + std::forward<_Tuple2>(__rhs)); } else { @@ -322,13 +325,16 @@ __equal(const _Tuple1& __lhs, const _Tuple2& __rhs) } template constexpr bool -__less(const _Tuple1& __lhs, const _Tuple2& __rhs) +__less(_Tuple1&& __lhs, _Tuple2&& __rhs) { - if constexpr (I < std::tuple_size_v<_Tuple1>) + static_assert(std::tuple_size_v> == std::tuple_size_v>, + "Tuples must have the same size to be compared"); + if constexpr (I < std::tuple_size_v>) { return std::get(__lhs) < std::get(__rhs) || (!(std::get(__rhs) < std::get(__lhs)) && - oneapi::dpl::__internal::__less<_Tuple1, _Tuple2, I + 1>(__lhs, __rhs)); + oneapi::dpl::__internal::__less<_Tuple1, _Tuple2, I + 1>(std::forward<_Tuple1>(__lhs), + std::forward<_Tuple2>(__rhs))); } else { @@ -336,6 +342,35 @@ __less(const _Tuple1& __lhs, const _Tuple2& __rhs) } } +template +struct __is_internal_tuple : std::false_type +{ +}; + +template +struct __is_internal_tuple> : std::true_type +{ +}; + +template +inline constexpr bool __is_internal_tuple_v = __is_internal_tuple::value; + +template +struct __is_std_tuple : std::false_type +{ +}; + +template +struct __is_std_tuple> : std::true_type +{ +}; + +template +inline constexpr bool __is_std_tuple_v = __is_std_tuple::value; + +template +inline constexpr bool __is_tuple_comparable_v = __is_std_tuple_v || __is_internal_tuple_v; + template struct tuple { @@ -471,124 +506,76 @@ struct tuple return *this; } - // The following operators enable support of binary comparison of oneDPL internal tuples with other oneDPL internal - // tuples with the same number of types where individual elements are binary comparable - template = 0> - friend constexpr bool - operator==(const tuple& __lhs, const oneapi::dpl::__internal::tuple<_U...>& __rhs) - { - return oneapi::dpl::__internal::__equal(__lhs, __rhs); - } - template = 0> + template > && + oneapi::dpl::__internal::__is_tuple_comparable_v>) || + (oneapi::dpl::__internal::__is_std_tuple_v> && + std::is_same_v>), + int> = 0> friend constexpr bool - operator!=(const tuple& __lhs, const oneapi::dpl::__internal::tuple<_U...>& __rhs) + operator==(_U&& __lhs, _V&& __rhs) { - return !(oneapi::dpl::__internal::__equal(__lhs, __rhs)); - } - template = 0> - friend constexpr bool - operator<(const tuple& __lhs, const oneapi::dpl::__internal::tuple<_U...>& __rhs) - { - return oneapi::dpl::__internal::__less(__lhs, __rhs); + return oneapi::dpl::__internal::__equal(std::forward<_U>(__lhs), std::forward<_V>(__rhs)); } - template = 0> + template > && + oneapi::dpl::__internal::__is_tuple_comparable_v>) || + (oneapi::dpl::__internal::__is_std_tuple_v> && + std::is_same_v>), + int> = 0> friend constexpr bool - operator<=(const tuple& __lhs, const oneapi::dpl::__internal::tuple<_U...>& __rhs) + operator!=(_U&& __lhs, _V&& __rhs) { - return !(oneapi::dpl::__internal::__less(__rhs, __lhs)); + return !oneapi::dpl::__internal::__equal(std::forward<_U>(__lhs), std::forward<_V>(__rhs)); } - template = 0> + template > && + oneapi::dpl::__internal::__is_tuple_comparable_v>) || + (oneapi::dpl::__internal::__is_std_tuple_v> && + std::is_same_v>), + int> = 0> friend constexpr bool - operator>(const tuple& __lhs, const oneapi::dpl::__internal::tuple<_U...>& __rhs) + operator<(_U&& __lhs, _V&& __rhs) { - return oneapi::dpl::__internal::__less(__rhs, __lhs); + return oneapi::dpl::__internal::__less(std::forward<_U>(__lhs), std::forward<_V>(__rhs)); } - template = 0> + template > && + oneapi::dpl::__internal::__is_tuple_comparable_v>) || + (oneapi::dpl::__internal::__is_std_tuple_v> && + std::is_same_v>), + int> = 0> friend constexpr bool - operator>=(const tuple& __lhs, const oneapi::dpl::__internal::tuple<_U...>& __rhs) + operator<=(_U&& __lhs, _V&& __rhs) { - return !(oneapi::dpl::__internal::__less(__lhs, __rhs)); + return !oneapi::dpl::__internal::__less(std::forward<_V>(__rhs), std::forward<_U>(__lhs)); } - // The following operators enable support of binary comparison of oneDPL internal tuples with std::tuple as rhs - // with the same number of types where individual elements are binary comparable - template = 0> - friend constexpr bool - operator==(const tuple& __lhs, const std::tuple<_U...>& __rhs) - { - return oneapi::dpl::__internal::__equal(__lhs, __rhs); - } - template = 0> - friend constexpr bool - operator!=(const tuple& __lhs, const std::tuple<_U...>& __rhs) - { - return !(oneapi::dpl::__internal::__equal(__lhs, __rhs)); - } - template = 0> - friend constexpr bool - operator<(const tuple& __lhs, const std::tuple<_U...>& __rhs) - { - return oneapi::dpl::__internal::__less(__lhs, __rhs); - } - template = 0> + template > && + oneapi::dpl::__internal::__is_tuple_comparable_v>) || + (oneapi::dpl::__internal::__is_std_tuple_v> && + std::is_same_v>), + int> = 0> friend constexpr bool - operator<=(const tuple& __lhs, const std::tuple<_U...>& __rhs) + operator>(_U&& __lhs, _V&& __rhs) { - return !(oneapi::dpl::__internal::__less(__rhs, __lhs)); - } - template = 0> - friend constexpr bool - operator>(const tuple& __lhs, const std::tuple<_U...>& __rhs) - { - return oneapi::dpl::__internal::__less(__rhs, __lhs); - } - template = 0> - friend constexpr bool - operator>=(const tuple& __lhs, const std::tuple<_U...>& __rhs) - { - return !(oneapi::dpl::__internal::__less(__lhs, __rhs)); + return oneapi::dpl::__internal::__less(std::forward<_V>(__rhs), std::forward<_U>(__lhs)); } - // The following operators enable support of binary comparison of oneDPL internal tuples with std::tuple as lhs - // with the same number of types where individual elements are binary comparable - template = 0> - friend constexpr bool - operator==(const std::tuple<_U...>& __lhs, const tuple& __rhs) - { - return oneapi::dpl::__internal::__equal(__lhs, __rhs); - } - template = 0> - friend constexpr bool - operator!=(const std::tuple<_U...>& __lhs, const tuple& __rhs) - { - return !(oneapi::dpl::__internal::__equal(__lhs, __rhs)); - } - template = 0> - friend constexpr bool - operator<(const std::tuple<_U...>& __lhs, const tuple& __rhs) - { - return oneapi::dpl::__internal::__less(__lhs, __rhs); - } - template = 0> - friend constexpr bool - operator<=(const std::tuple<_U...>& __lhs, const tuple& __rhs) - { - return !(oneapi::dpl::__internal::__less(__rhs, __lhs)); - } - template = 0> - friend constexpr bool - operator>(const std::tuple<_U...>& __lhs, const tuple& __rhs) - { - return oneapi::dpl::__internal::__less(__rhs, __lhs); - } - template = 0> + template > && + oneapi::dpl::__internal::__is_tuple_comparable_v>) || + (oneapi::dpl::__internal::__is_std_tuple_v> && + std::is_same_v>), + int> = 0> friend constexpr bool - operator>=(const std::tuple<_U...>& __lhs, const tuple& __rhs) + operator>=(_U&& __lhs, _V&& __rhs) { - return !(oneapi::dpl::__internal::__less(__lhs, __rhs)); + return !oneapi::dpl::__internal::__less(std::forward<_U>(__lhs), std::forward<_V>(__rhs)); } template From fc660802ecb95b96efb61064dbac528de7d32d01 Mon Sep 17 00:00:00 2001 From: Dan Hoeflinger Date: Mon, 12 Aug 2024 12:35:44 -0400 Subject: [PATCH 19/33] moving forward declaring of get functions Signed-off-by: Dan Hoeflinger --- include/oneapi/dpl/pstl/tuple_impl.h | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/include/oneapi/dpl/pstl/tuple_impl.h b/include/oneapi/dpl/pstl/tuple_impl.h index 0baa7e453f8..81677a71c21 100644 --- a/include/oneapi/dpl/pstl/tuple_impl.h +++ b/include/oneapi/dpl/pstl/tuple_impl.h @@ -37,6 +37,18 @@ struct tuple; namespace std { +template <::std::size_t N, typename T, typename... Rest> +struct tuple_element> + : tuple_element> +{ +}; + +template +struct tuple_element<0, oneapi::dpl::__internal::tuple> +{ + using type = T; +}; + //forward declare new std::get() functions so they can be used in impl template constexpr ::std::tuple_element_t<_Idx, oneapi::dpl::__internal::tuple<_Tp...>>& @@ -54,18 +66,6 @@ template constexpr ::std::tuple_element_t<_Idx, oneapi::dpl::__internal::tuple<_Tp...>> const&& get(const oneapi::dpl::__internal::tuple<_Tp...>&&); -template <::std::size_t N, typename T, typename... Rest> -struct tuple_element> - : tuple_element> -{ -}; - -template -struct tuple_element<0, oneapi::dpl::__internal::tuple> -{ - using type = T; -}; - template struct tuple_size> : ::std::integral_constant<::std::size_t, sizeof...(Args)> { From 3c91a36abcc215bba82abdab16b4e60a3e93d6f9 Mon Sep 17 00:00:00 2001 From: Dan Hoeflinger Date: Mon, 12 Aug 2024 15:12:06 -0400 Subject: [PATCH 20/33] consolidate logic for enabling op Signed-off-by: Dan Hoeflinger --- include/oneapi/dpl/pstl/tuple_impl.h | 51 +++++++++++----------------- 1 file changed, 19 insertions(+), 32 deletions(-) diff --git a/include/oneapi/dpl/pstl/tuple_impl.h b/include/oneapi/dpl/pstl/tuple_impl.h index 81677a71c21..6d63f7b82a8 100644 --- a/include/oneapi/dpl/pstl/tuple_impl.h +++ b/include/oneapi/dpl/pstl/tuple_impl.h @@ -368,8 +368,19 @@ struct __is_std_tuple> : std::true_type template inline constexpr bool __is_std_tuple_v = __is_std_tuple::value; -template -inline constexpr bool __is_tuple_comparable_v = __is_std_tuple_v || __is_internal_tuple_v; +// Either LHS = this internal tuple type + RHS = any compatible tuple type +// or LHS = std::tuple + RHS = this internal tuple type +// Note: We do not allow LHS to be "any compatible type" with a RHS as this internal tuple type because then we would +// have ambiguity comaparing two different compatible internal tuple types, because both instantiations would +// create the necessary comparison. As written, the type instatation of the type in the LHS is always +// responsible for creating this comparison operator. +template +inline constexpr bool __enable_comparison_op_v = + (std::is_same_v, std::decay_t<_U>> && //LHS + + (oneapi::dpl::__internal::__is_std_tuple_v> || //RHS option 1 + oneapi::dpl::__internal::__is_internal_tuple_v>)) || //RHS option 2 - OR - + (oneapi::dpl::__internal::__is_std_tuple_v> && //LHS + + std::is_same_v, std::decay_t<_V>>); //RHS template struct tuple @@ -507,11 +518,7 @@ struct tuple } template > && - oneapi::dpl::__internal::__is_tuple_comparable_v>) || - (oneapi::dpl::__internal::__is_std_tuple_v> && - std::is_same_v>), - int> = 0> + std::enable_if_t, int> = 0> friend constexpr bool operator==(_U&& __lhs, _V&& __rhs) { @@ -519,11 +526,7 @@ struct tuple } template > && - oneapi::dpl::__internal::__is_tuple_comparable_v>) || - (oneapi::dpl::__internal::__is_std_tuple_v> && - std::is_same_v>), - int> = 0> + std::enable_if_t, int> = 0> friend constexpr bool operator!=(_U&& __lhs, _V&& __rhs) { @@ -531,11 +534,7 @@ struct tuple } template > && - oneapi::dpl::__internal::__is_tuple_comparable_v>) || - (oneapi::dpl::__internal::__is_std_tuple_v> && - std::is_same_v>), - int> = 0> + std::enable_if_t, int> = 0> friend constexpr bool operator<(_U&& __lhs, _V&& __rhs) { @@ -543,11 +542,7 @@ struct tuple } template > && - oneapi::dpl::__internal::__is_tuple_comparable_v>) || - (oneapi::dpl::__internal::__is_std_tuple_v> && - std::is_same_v>), - int> = 0> + std::enable_if_t, int> = 0> friend constexpr bool operator<=(_U&& __lhs, _V&& __rhs) { @@ -555,11 +550,7 @@ struct tuple } template > && - oneapi::dpl::__internal::__is_tuple_comparable_v>) || - (oneapi::dpl::__internal::__is_std_tuple_v> && - std::is_same_v>), - int> = 0> + std::enable_if_t, int> = 0> friend constexpr bool operator>(_U&& __lhs, _V&& __rhs) { @@ -567,11 +558,7 @@ struct tuple } template > && - oneapi::dpl::__internal::__is_tuple_comparable_v>) || - (oneapi::dpl::__internal::__is_std_tuple_v> && - std::is_same_v>), - int> = 0> + std::enable_if_t, int> = 0> friend constexpr bool operator>=(_U&& __lhs, _V&& __rhs) { From 2e8b5e30b3ae4acbb1c9e672681b288341303f12 Mon Sep 17 00:00:00 2001 From: Dan Hoeflinger Date: Tue, 13 Aug 2024 11:44:03 -0400 Subject: [PATCH 21/33] ::std:: -> std:: Signed-off-by: Dan Hoeflinger --- include/oneapi/dpl/pstl/tuple_impl.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/include/oneapi/dpl/pstl/tuple_impl.h b/include/oneapi/dpl/pstl/tuple_impl.h index 6d63f7b82a8..0eb7f5a3801 100644 --- a/include/oneapi/dpl/pstl/tuple_impl.h +++ b/include/oneapi/dpl/pstl/tuple_impl.h @@ -51,19 +51,19 @@ struct tuple_element<0, oneapi::dpl::__internal::tuple> //forward declare new std::get() functions so they can be used in impl template -constexpr ::std::tuple_element_t<_Idx, oneapi::dpl::__internal::tuple<_Tp...>>& +constexpr std::tuple_element_t<_Idx, oneapi::dpl::__internal::tuple<_Tp...>>& get(oneapi::dpl::__internal::tuple<_Tp...>&); template -constexpr ::std::tuple_element_t<_Idx, oneapi::dpl::__internal::tuple<_Tp...>> const& +constexpr std::tuple_element_t<_Idx, oneapi::dpl::__internal::tuple<_Tp...>> const& get(const oneapi::dpl::__internal::tuple<_Tp...>&); template -constexpr ::std::tuple_element_t<_Idx, oneapi::dpl::__internal::tuple<_Tp...>>&& +constexpr std::tuple_element_t<_Idx, oneapi::dpl::__internal::tuple<_Tp...>>&& get(oneapi::dpl::__internal::tuple<_Tp...>&&); template -constexpr ::std::tuple_element_t<_Idx, oneapi::dpl::__internal::tuple<_Tp...>> const&& +constexpr std::tuple_element_t<_Idx, oneapi::dpl::__internal::tuple<_Tp...>> const&& get(const oneapi::dpl::__internal::tuple<_Tp...>&&); template From 92e6c2fa65f5fb460c8cda9f1cd7e4f48092fecb Mon Sep 17 00:00:00 2001 From: Dan Hoeflinger Date: Tue, 13 Aug 2024 11:58:16 -0400 Subject: [PATCH 22/33] spelling issues Signed-off-by: Dan Hoeflinger --- include/oneapi/dpl/pstl/tuple_impl.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/oneapi/dpl/pstl/tuple_impl.h b/include/oneapi/dpl/pstl/tuple_impl.h index 0eb7f5a3801..f7aa6c7ae30 100644 --- a/include/oneapi/dpl/pstl/tuple_impl.h +++ b/include/oneapi/dpl/pstl/tuple_impl.h @@ -371,8 +371,8 @@ inline constexpr bool __is_std_tuple_v = __is_std_tuple::value; // Either LHS = this internal tuple type + RHS = any compatible tuple type // or LHS = std::tuple + RHS = this internal tuple type // Note: We do not allow LHS to be "any compatible type" with a RHS as this internal tuple type because then we would -// have ambiguity comaparing two different compatible internal tuple types, because both instantiations would -// create the necessary comparison. As written, the type instatation of the type in the LHS is always +// have ambiguity comparing two different compatible internal tuple types, because both instantiations would +// create the necessary comparison. As written, the type instantation of the type in the LHS is always // responsible for creating this comparison operator. template inline constexpr bool __enable_comparison_op_v = From c03ccd9963b0e56ef3da9a7c8a240b4dc3e31996 Mon Sep 17 00:00:00 2001 From: Dan Hoeflinger Date: Tue, 13 Aug 2024 14:52:10 -0400 Subject: [PATCH 23/33] spelling Signed-off-by: Dan Hoeflinger --- include/oneapi/dpl/pstl/tuple_impl.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/oneapi/dpl/pstl/tuple_impl.h b/include/oneapi/dpl/pstl/tuple_impl.h index f7aa6c7ae30..239734d4861 100644 --- a/include/oneapi/dpl/pstl/tuple_impl.h +++ b/include/oneapi/dpl/pstl/tuple_impl.h @@ -372,7 +372,7 @@ inline constexpr bool __is_std_tuple_v = __is_std_tuple::value; // or LHS = std::tuple + RHS = this internal tuple type // Note: We do not allow LHS to be "any compatible type" with a RHS as this internal tuple type because then we would // have ambiguity comparing two different compatible internal tuple types, because both instantiations would -// create the necessary comparison. As written, the type instantation of the type in the LHS is always +// create the necessary comparison. As written, the type instantiation of the type in the LHS is always // responsible for creating this comparison operator. template inline constexpr bool __enable_comparison_op_v = From 0690030b5c5a196b1d05e422ba7be7563bb83c14 Mon Sep 17 00:00:00 2001 From: Dan Hoeflinger Date: Tue, 13 Aug 2024 17:11:04 -0400 Subject: [PATCH 24/33] adding constexpr for ctors and some operations of internal tuple Signed-off-by: Dan Hoeflinger --- include/oneapi/dpl/pstl/tuple_impl.h | 52 ++++++++++++++-------------- 1 file changed, 26 insertions(+), 26 deletions(-) diff --git a/include/oneapi/dpl/pstl/tuple_impl.h b/include/oneapi/dpl/pstl/tuple_impl.h index 239734d4861..61e878c65c8 100644 --- a/include/oneapi/dpl/pstl/tuple_impl.h +++ b/include/oneapi/dpl/pstl/tuple_impl.h @@ -83,14 +83,14 @@ template struct get_value_by_idx; template -::std::tuple +constexpr std::tuple get_tuple_tail_impl(const ::std::tuple& t, const ::std::index_sequence&) { return ::std::tuple(::std::get(t)...); } template -::std::tuple +constexpr std::tuple get_tuple_tail(const ::std::tuple& other) { return oneapi::dpl::__internal::get_tuple_tail_impl(other, ::std::make_index_sequence()); @@ -273,9 +273,9 @@ map_tuplewrapper(F f, TBig in, RestTuples... rest) template struct __value_holder { - __value_holder() = default; + constexpr __value_holder() = default; template - __value_holder(_Up&& t) : value(::std::forward<_Up>(t)) + constexpr __value_holder(_Up&& t) : value(::std::forward<_Up>(t)) { } _Tp value; @@ -293,16 +293,16 @@ template struct __copy_assignable_holder<_Tp, false> : oneapi::dpl::__internal::__value_holder<_Tp> { using oneapi::dpl::__internal::__value_holder<_Tp>::__value_holder; - __copy_assignable_holder() = default; - __copy_assignable_holder(const __copy_assignable_holder&) = default; - __copy_assignable_holder(__copy_assignable_holder&&) = default; - __copy_assignable_holder& + constexpr __copy_assignable_holder() = default; + constexpr __copy_assignable_holder(const __copy_assignable_holder&) = default; + constexpr __copy_assignable_holder(__copy_assignable_holder&&) = default; + constexpr __copy_assignable_holder& operator=(const __copy_assignable_holder& other) { this->value = other.value; return *this; } - __copy_assignable_holder& + constexpr __copy_assignable_holder& operator=(__copy_assignable_holder&& other) = default; }; @@ -418,16 +418,16 @@ struct tuple return get_impl()(::std::move(*this)); } - tuple() = default; - tuple(const tuple& other) = default; - tuple(tuple&& other) = default; + constexpr tuple() = default; + constexpr tuple(const tuple& other) = default; + constexpr tuple(tuple&& other) = default; template > - tuple(const tuple<_U1, _U...>& other) : holder(other.template get<0>()), next(other.next) + constexpr tuple(const tuple<_U1, _U...>& other) : holder(other.template get<0>()), next(other.next) { } template > - tuple(tuple<_U1, _U...>&& other) : holder(std::move(other).template get<0>()), next(std::move(other.next)) + constexpr tuple(tuple<_U1, _U...>&& other) : holder(std::move(other).template get<0>()), next(std::move(other.next)) { } @@ -435,18 +435,18 @@ struct tuple typename = ::std::enable_if_t< (sizeof...(_U) == sizeof...(T) && ::std::conjunction_v<::std::is_constructible, ::std::is_constructible...>)>> - tuple(_U1&& _value, _U&&... _next) : holder(::std::forward<_U1>(_value)), next(::std::forward<_U>(_next)...) + constexpr tuple(_U1&& _value, _U&&... _next) : holder(::std::forward<_U1>(_value)), next(::std::forward<_U>(_next)...) { } // required to convert ::std::tuple to inner tuple in user-provided functor - tuple(const ::std::tuple& other) + constexpr tuple(const ::std::tuple& other) : holder(::std::get<0>(other)), next(oneapi::dpl::__internal::get_tuple_tail(other)) { } // conversion to ::std::tuple with the same template arguments - operator ::std::tuple() const + constexpr operator ::std::tuple() const { static constexpr ::std::size_t __tuple_size = sizeof...(T) + 1; return to_std_tuple(*this, ::std::make_index_sequence<__tuple_size>()); @@ -454,7 +454,7 @@ struct tuple // conversion to ::std::tuple with the different template arguments template - operator ::std::tuple() const + constexpr operator ::std::tuple() const { constexpr ::std::size_t __tuple_size = sizeof...(T) + 1; return to_std_tuple(static_cast>(*this), ::std::make_index_sequence<__tuple_size>()); @@ -509,7 +509,7 @@ struct tuple // for cases when we assign ::std::tuple to __internal::tuple template - tuple& + constexpr tuple& operator=(const ::std::tuple& other) { holder.value = ::std::get<0>(other); @@ -566,7 +566,7 @@ struct tuple } template - static ::std::tuple + constexpr static ::std::tuple to_std_tuple(const oneapi::dpl::__internal::tuple& __t, ::std::index_sequence<_Ip...>) { return ::std::tuple(oneapi::dpl::__internal::get_impl<_Ip>()(__t)...); @@ -579,17 +579,17 @@ struct tuple<> using tuple_type = ::std::tuple<>; // since compiler does not autogenerate ctors // if user defines its own, we have to define them too - tuple() = default; - tuple(const tuple& other) = default; + constexpr tuple() = default; + constexpr tuple(const tuple& other) = default; - tuple(const ::std::tuple<>&) {} + constexpr tuple(const ::std::tuple<>&) {} tuple operator[](tuple) { return {}; } tuple operator[](const tuple&) const { return {}; } - operator tuple_type() const { return tuple_type{}; } - tuple& + constexpr operator tuple_type() const { return tuple_type{}; } + constexpr tuple& operator=(const tuple&) = default; - tuple& + constexpr tuple& operator=(const ::std::tuple<>& /*other*/) { return *this; From 8922b8c1d985feda8d9e41031c70dc4d7563a9b1 Mon Sep 17 00:00:00 2001 From: Dan Hoeflinger Date: Tue, 13 Aug 2024 17:11:27 -0400 Subject: [PATCH 25/33] adress reviewer test feedback Signed-off-by: Dan Hoeflinger --- .../parallel_api/iterator/tuple_unit.pass.cpp | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/test/parallel_api/iterator/tuple_unit.pass.cpp b/test/parallel_api/iterator/tuple_unit.pass.cpp index d1be1fcc78b..98d12093abb 100644 --- a/test/parallel_api/iterator/tuple_unit.pass.cpp +++ b/test/parallel_api/iterator/tuple_unit.pass.cpp @@ -86,10 +86,10 @@ test_tuple(Tuple1 t1, Tuple2 t2) constexpr void test_compile_time() { - constexpr std::tuple std_tup1{1, 2, 3}; - constexpr std::tuple std_tup2{99, 2, 3}; - constexpr oneapi::dpl::tuple dpl_tup1{1, 2, 3}; - constexpr oneapi::dpl::tuple dpl_tup2{99, 2, 3}; + constexpr std::tuple std_tup1{1, 2, 3}; + constexpr std::tuple std_tup2{99, 2, 3}; + constexpr oneapi::dpl::__internal::tuple dpl_tup1{1, 2, 3}; + constexpr oneapi::dpl::__internal::tuple dpl_tup2{99, 2, 3}; static_assert((std_tup1 == std_tup2) == (dpl_tup1 == dpl_tup2), "compile time equality comparison does not match std::tuple"); @@ -130,10 +130,10 @@ test_compile_time() static_assert((std_tup1 != std_tup2) == (dpl_tup1 != std_tup2), "compile time non-equality comparison does not match std::tuple with std::tuple as rhs"); - constexpr std::tuple<> std_empty1{}; - constexpr std::tuple<> std_empty2{}; - constexpr oneapi::dpl::tuple<> dpl_empty1{}; - constexpr oneapi::dpl::tuple<> dpl_empty2{}; + constexpr std::tuple<> std_empty1; + constexpr std::tuple<> std_empty2; + constexpr oneapi::dpl::__internal::tuple<> dpl_empty1{}; + constexpr oneapi::dpl::__internal::tuple<> dpl_empty2{}; static_assert((std_empty1 == std_empty2) == (dpl_empty1 == dpl_empty2), "empty compile time equality comparison does not match std::tuple"); @@ -183,8 +183,8 @@ main() test_tuple(std::tuple{1, 2, 3}, std::tuple{1, 2, 3}); test_tuple(std::tuple{1, 2, 3}, std::tuple{1, 2, 4}); test_tuple(std::tuple{1, 2, 3}, std::tuple{0, 2, 4}); - test_tuple(std::tuple{1, 2, 3}, std::tuple{1, 2, 3}); - test_tuple(std::tuple{1, 2, 3}, std::tuple{0, 2, 4}); + test_tuple(std::tuple{1, 2, 3}, std::tuple{1, 2, 3}); + test_tuple(std::tuple{1, 2, 3}, std::tuple{0, 2, 4}); test_tuple(std::tuple<>{}, std::tuple<>{}); return TestUtils::done(); From f23ca20bc793f45c1afaf6e689e697ce1673456c Mon Sep 17 00:00:00 2001 From: Dan Hoeflinger Date: Tue, 13 Aug 2024 17:14:25 -0400 Subject: [PATCH 26/33] moving tuple_unit.pass Signed-off-by: Dan Hoeflinger --- .../implementation_details}/tuple_unit.pass.cpp | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename test/{parallel_api/iterator => general/implementation_details}/tuple_unit.pass.cpp (100%) diff --git a/test/parallel_api/iterator/tuple_unit.pass.cpp b/test/general/implementation_details/tuple_unit.pass.cpp similarity index 100% rename from test/parallel_api/iterator/tuple_unit.pass.cpp rename to test/general/implementation_details/tuple_unit.pass.cpp From ac84e976b8367184c2297d26ba56b0320d7b2568 Mon Sep 17 00:00:00 2001 From: Dan Hoeflinger Date: Tue, 13 Aug 2024 17:24:02 -0400 Subject: [PATCH 27/33] renaming tuple unit tests Signed-off-by: Dan Hoeflinger --- .../{tuple_unit.pass.cpp => internal_tuple.pass.cpp} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename test/general/implementation_details/{tuple_unit.pass.cpp => internal_tuple.pass.cpp} (100%) diff --git a/test/general/implementation_details/tuple_unit.pass.cpp b/test/general/implementation_details/internal_tuple.pass.cpp similarity index 100% rename from test/general/implementation_details/tuple_unit.pass.cpp rename to test/general/implementation_details/internal_tuple.pass.cpp From d5b00e4876c643a43b139f9a265e5076fdf8bda4 Mon Sep 17 00:00:00 2001 From: Dan Hoeflinger Date: Tue, 13 Aug 2024 17:27:33 -0400 Subject: [PATCH 28/33] adding missing include Signed-off-by: Dan Hoeflinger --- test/general/implementation_details/internal_tuple.pass.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/general/implementation_details/internal_tuple.pass.cpp b/test/general/implementation_details/internal_tuple.pass.cpp index 98d12093abb..121db560e98 100644 --- a/test/general/implementation_details/internal_tuple.pass.cpp +++ b/test/general/implementation_details/internal_tuple.pass.cpp @@ -12,7 +12,7 @@ // See https://llvm.org/LICENSE.txt for license information. // //===----------------------------------------------------------------------===// - +#include #include "support/test_config.h" #include _PSTL_TEST_HEADER(tuple) From 91fdc3057d4747f4f368b5bd52f10d279c83d5ef Mon Sep 17 00:00:00 2001 From: Dan Hoeflinger Date: Tue, 13 Aug 2024 17:30:28 -0400 Subject: [PATCH 29/33] removing warning-causing constexpr conversion operator Signed-off-by: Dan Hoeflinger --- include/oneapi/dpl/pstl/tuple_impl.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/oneapi/dpl/pstl/tuple_impl.h b/include/oneapi/dpl/pstl/tuple_impl.h index 61e878c65c8..b7857260306 100644 --- a/include/oneapi/dpl/pstl/tuple_impl.h +++ b/include/oneapi/dpl/pstl/tuple_impl.h @@ -446,7 +446,7 @@ struct tuple } // conversion to ::std::tuple with the same template arguments - constexpr operator ::std::tuple() const + operator ::std::tuple() const { static constexpr ::std::size_t __tuple_size = sizeof...(T) + 1; return to_std_tuple(*this, ::std::make_index_sequence<__tuple_size>()); From dbd63aead00fe16dae372c6b5b958a8381493e54 Mon Sep 17 00:00:00 2001 From: Dan Hoeflinger Date: Tue, 13 Aug 2024 20:40:30 -0400 Subject: [PATCH 30/33] ::std:: -> std:: Signed-off-by: Dan Hoeflinger --- include/oneapi/dpl/pstl/tuple_impl.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/include/oneapi/dpl/pstl/tuple_impl.h b/include/oneapi/dpl/pstl/tuple_impl.h index b7857260306..874c60e8f60 100644 --- a/include/oneapi/dpl/pstl/tuple_impl.h +++ b/include/oneapi/dpl/pstl/tuple_impl.h @@ -275,7 +275,7 @@ struct __value_holder { constexpr __value_holder() = default; template - constexpr __value_holder(_Up&& t) : value(::std::forward<_Up>(t)) + constexpr __value_holder(_Up&& t) : value(std::forward<_Up>(t)) { } _Tp value; @@ -435,12 +435,12 @@ struct tuple typename = ::std::enable_if_t< (sizeof...(_U) == sizeof...(T) && ::std::conjunction_v<::std::is_constructible, ::std::is_constructible...>)>> - constexpr tuple(_U1&& _value, _U&&... _next) : holder(::std::forward<_U1>(_value)), next(::std::forward<_U>(_next)...) + constexpr tuple(_U1&& _value, _U&&... _next) : holder(std::forward<_U1>(_value)), next(std::forward<_U>(_next)...) { } // required to convert ::std::tuple to inner tuple in user-provided functor - constexpr tuple(const ::std::tuple& other) + constexpr tuple(const std::tuple& other) : holder(::std::get<0>(other)), next(oneapi::dpl::__internal::get_tuple_tail(other)) { } @@ -566,7 +566,7 @@ struct tuple } template - constexpr static ::std::tuple + constexpr static std::tuple to_std_tuple(const oneapi::dpl::__internal::tuple& __t, ::std::index_sequence<_Ip...>) { return ::std::tuple(oneapi::dpl::__internal::get_impl<_Ip>()(__t)...); From 8e98b0f27cfc1438e8f0674d498fdfc202e6f623 Mon Sep 17 00:00:00 2001 From: Dan Hoeflinger Date: Wed, 14 Aug 2024 08:11:40 -0400 Subject: [PATCH 31/33] fix assignment checks Signed-off-by: Dan Hoeflinger --- .../internal_tuple.pass.cpp | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/test/general/implementation_details/internal_tuple.pass.cpp b/test/general/implementation_details/internal_tuple.pass.cpp index 121db560e98..ef31d401f2f 100644 --- a/test/general/implementation_details/internal_tuple.pass.cpp +++ b/test/general/implementation_details/internal_tuple.pass.cpp @@ -58,10 +58,11 @@ test_tuple(Tuple1 t1, Tuple2 t2) EXPECT_EQ((t1 > t2), (onedpl_t1 > t2), "greater than comparison does not match std::tuple"); EXPECT_EQ((t1 >= t2), (onedpl_t1 >= t2), "greater than or equal to comparison does not match std::tuple"); - auto onedpl_t3 = to_onedpl_tuple(t1); - auto onedpl_t4 = to_onedpl_tuple(t2); - auto t3 = t1; - auto t4 = t2; + //checking default construction (assumes elements are default constructible) + decltype(onedpl_t1) onedpl_t3{}; + decltype(onedpl_t2) onedpl_t4{}; + decltype(t1) t3{}; + decltype(t2) t4{}; t4 = onedpl_t1; EXPECT_TRUE(t1 == t4, "assignment of oneDPL tuple to std::tuple provides incorrect results"); @@ -69,11 +70,11 @@ test_tuple(Tuple1 t1, Tuple2 t2) t3 = onedpl_t2; EXPECT_TRUE(t2 == t3, "assignment of oneDPL tuple to std::tuple provides incorrect results"); - onedpl_t3 = t1; - EXPECT_TRUE(onedpl_t1 == onedpl_t3, "assignment of oneDPL tuple from std::tuple provides incorrect results"); + onedpl_t3 = t2; + EXPECT_TRUE(onedpl_t2 == onedpl_t3, "assignment of oneDPL tuple from std::tuple provides incorrect results"); - onedpl_t4 = t2; - EXPECT_TRUE(onedpl_t2 == onedpl_t4, "assignment of oneDPL tuple from std::tuple provides incorrect results"); + onedpl_t4 = t1; + EXPECT_TRUE(onedpl_t1 == onedpl_t4, "assignment of oneDPL tuple from std::tuple provides incorrect results"); decltype(onedpl_t1) onedpl_t5 = onedpl_t2; decltype(onedpl_t1) onedpl_t6 = onedpl_t1; From 3c7d49c4210a3c552a5dfe0360c590ce52779dc2 Mon Sep 17 00:00:00 2001 From: Dan Hoeflinger Date: Wed, 14 Aug 2024 08:12:06 -0400 Subject: [PATCH 32/33] remove constexpr checks from tests Signed-off-by: Dan Hoeflinger --- .../internal_tuple.pass.cpp | 94 ------------------- 1 file changed, 94 deletions(-) diff --git a/test/general/implementation_details/internal_tuple.pass.cpp b/test/general/implementation_details/internal_tuple.pass.cpp index ef31d401f2f..01616deb450 100644 --- a/test/general/implementation_details/internal_tuple.pass.cpp +++ b/test/general/implementation_details/internal_tuple.pass.cpp @@ -84,103 +84,9 @@ test_tuple(Tuple1 t1, Tuple2 t2) "swap of oneDPL tuple provides incorrect results"); } -constexpr void -test_compile_time() -{ - constexpr std::tuple std_tup1{1, 2, 3}; - constexpr std::tuple std_tup2{99, 2, 3}; - constexpr oneapi::dpl::__internal::tuple dpl_tup1{1, 2, 3}; - constexpr oneapi::dpl::__internal::tuple dpl_tup2{99, 2, 3}; - - static_assert((std_tup1 == std_tup2) == (dpl_tup1 == dpl_tup2), - "compile time equality comparison does not match std::tuple"); - static_assert((std_tup1 < std_tup2) == (dpl_tup1 < dpl_tup2), - "compile time less than comparison does not match std::tuple"); - static_assert((std_tup1 <= std_tup2) == (dpl_tup1 <= dpl_tup2), - "compile time lt-equal comparison does not match std::tuple"); - static_assert((std_tup1 > std_tup2) == (dpl_tup1 > dpl_tup2), - "compile time greater comparison does not match std::tuple"); - static_assert((std_tup1 >= std_tup2) == (dpl_tup1 >= dpl_tup2), - "compile time gt-equal comparison does not match std::tuple"); - static_assert((std_tup1 != std_tup2) == (dpl_tup1 != dpl_tup2), - "compile time non-equality comparison does not match std::tuple"); - - static_assert((std_tup1 == std_tup2) == (std_tup1 == dpl_tup2), - "compile time equality comparison does not match std::tuple with std::tuple as lhs"); - static_assert((std_tup1 < std_tup2) == (std_tup1 < dpl_tup2), - "compile time less than comparison does not match std::tuple with std::tuple as lhs"); - static_assert((std_tup1 <= std_tup2) == (std_tup1 <= dpl_tup2), - "compile time lt-equal comparison does not match std::tuple with std::tuple as lhs"); - static_assert((std_tup1 > std_tup2) == (std_tup1 > dpl_tup2), - "compile time greater comparison does not match std::tuple with std::tuple as lhs"); - static_assert((std_tup1 >= std_tup2) == (std_tup1 >= dpl_tup2), - "compile time gt-equal comparison does not match std::tuple with std::tuple as lhs"); - static_assert((std_tup1 != std_tup2) == (std_tup1 != dpl_tup2), - "compile time non-equality comparison does not match std::tuple with std::tuple as lhs"); - - static_assert((std_tup1 == std_tup2) == (dpl_tup1 == std_tup2), - "compile time equality comparison does not match std::tuple with std::tuple as rhs"); - static_assert((std_tup1 < std_tup2) == (dpl_tup1 < std_tup2), - "compile time less than comparison does not match std::tuple with std::tuple as rhs"); - static_assert((std_tup1 <= std_tup2) == (dpl_tup1 <= std_tup2), - "compile time lt-equal comparison does not match std::tuple with std::tuple as rhs"); - static_assert((std_tup1 > std_tup2) == (dpl_tup1 > std_tup2), - "compile time greater comparison does not match std::tuple with std::tuple as rhs"); - static_assert((std_tup1 >= std_tup2) == (dpl_tup1 >= std_tup2), - "compile time gt-equal comparison does not match std::tuple with std::tuple as rhs"); - static_assert((std_tup1 != std_tup2) == (dpl_tup1 != std_tup2), - "compile time non-equality comparison does not match std::tuple with std::tuple as rhs"); - - constexpr std::tuple<> std_empty1; - constexpr std::tuple<> std_empty2; - constexpr oneapi::dpl::__internal::tuple<> dpl_empty1{}; - constexpr oneapi::dpl::__internal::tuple<> dpl_empty2{}; - - static_assert((std_empty1 == std_empty2) == (dpl_empty1 == dpl_empty2), - "empty compile time equality comparison does not match std::tuple"); - static_assert((std_empty1 < std_empty2) == (dpl_empty1 < dpl_empty2), - "empty compile time less than comparison does not match std::tuple"); - static_assert((std_empty1 <= std_empty2) == (dpl_empty1 <= dpl_empty2), - "empty compile time lt-equal comparison does not match std::tuple"); - static_assert((std_empty1 > std_empty2) == (dpl_empty1 > dpl_empty2), - "empty compile time greater comparison does not match std::tuple"); - static_assert((std_empty1 >= std_empty2) == (dpl_empty1 >= dpl_empty2), - "empty compile time gt-equal comparison does not match std::tuple"); - static_assert((std_empty1 != std_empty2) == (dpl_empty1 != dpl_empty2), - "empty compile time non-equality comparison does not match std::tuple"); - - static_assert((std_empty1 == std_empty2) == (std_empty1 == dpl_empty2), - "empty compile time equality comparison does not match std::tuple with std::tuple as lhs"); - static_assert((std_empty1 < std_empty2) == (std_empty1 < dpl_empty2), - "empty compile time less than comparison does not match std::tuple with std::tuple as lhs"); - static_assert((std_empty1 <= std_empty2) == (std_empty1 <= dpl_empty2), - "empty compile time lt-equal comparison does not match std::tuple with std::tuple as lhs"); - static_assert((std_empty1 > std_empty2) == (std_empty1 > dpl_empty2), - "empty compile time greater comparison does not match std::tuple with std::tuple as lhs"); - static_assert((std_empty1 >= std_empty2) == (std_empty1 >= dpl_empty2), - "empty compile time gt-equal comparison does not match std::tuple with std::tuple as lhs"); - static_assert((std_empty1 != std_empty2) == (std_empty1 != dpl_empty2), - "empty compile time non-equality comparison does not match std::tuple with std::tuple as lhs"); - - static_assert((std_empty1 == std_empty2) == (dpl_empty1 == std_empty2), - "empty compile time equality comparison does not match std::tuple with std::tuple as rhs"); - static_assert((std_empty1 < std_empty2) == (dpl_empty1 < std_empty2), - "empty compile time less than comparison does not match std::tuple with std::tuple as rhs"); - static_assert((std_empty1 <= std_empty2) == (dpl_empty1 <= std_empty2), - "empty compile time lt-equal comparison does not match std::tuple with std::tuple as rhs"); - static_assert((std_empty1 > std_empty2) == (dpl_empty1 > std_empty2), - "empty compile time greater comparison does not match std::tuple with std::tuple as rhs"); - static_assert((std_empty1 >= std_empty2) == (dpl_empty1 >= std_empty2), - "empty compile time gt-equal comparison does not match std::tuple with std::tuple as rhs"); - static_assert((std_empty1 != std_empty2) == (dpl_empty1 != std_empty2), - "empty compile time non-equality comparison does not match std::tuple with std::tuple as rhs"); -} - int main() { - test_compile_time(); - test_tuple(std::tuple{1, 2, 3}, std::tuple{1, 2, 3}); test_tuple(std::tuple{1, 2, 3}, std::tuple{1, 2, 4}); test_tuple(std::tuple{1, 2, 3}, std::tuple{0, 2, 4}); From ef73c4f194b0511f05a1bde4b41d2e3639b976b1 Mon Sep 17 00:00:00 2001 From: Dan Hoeflinger Date: Wed, 14 Aug 2024 08:13:38 -0400 Subject: [PATCH 33/33] Revert "adding constexpr for ctors and some operations of internal tuple" This reverts commit 0690030b5c5a196b1d05e422ba7be7563bb83c14. --- include/oneapi/dpl/pstl/tuple_impl.h | 50 ++++++++++++++-------------- 1 file changed, 25 insertions(+), 25 deletions(-) diff --git a/include/oneapi/dpl/pstl/tuple_impl.h b/include/oneapi/dpl/pstl/tuple_impl.h index 874c60e8f60..239734d4861 100644 --- a/include/oneapi/dpl/pstl/tuple_impl.h +++ b/include/oneapi/dpl/pstl/tuple_impl.h @@ -83,14 +83,14 @@ template struct get_value_by_idx; template -constexpr std::tuple +::std::tuple get_tuple_tail_impl(const ::std::tuple& t, const ::std::index_sequence&) { return ::std::tuple(::std::get(t)...); } template -constexpr std::tuple +::std::tuple get_tuple_tail(const ::std::tuple& other) { return oneapi::dpl::__internal::get_tuple_tail_impl(other, ::std::make_index_sequence()); @@ -273,9 +273,9 @@ map_tuplewrapper(F f, TBig in, RestTuples... rest) template struct __value_holder { - constexpr __value_holder() = default; + __value_holder() = default; template - constexpr __value_holder(_Up&& t) : value(std::forward<_Up>(t)) + __value_holder(_Up&& t) : value(::std::forward<_Up>(t)) { } _Tp value; @@ -293,16 +293,16 @@ template struct __copy_assignable_holder<_Tp, false> : oneapi::dpl::__internal::__value_holder<_Tp> { using oneapi::dpl::__internal::__value_holder<_Tp>::__value_holder; - constexpr __copy_assignable_holder() = default; - constexpr __copy_assignable_holder(const __copy_assignable_holder&) = default; - constexpr __copy_assignable_holder(__copy_assignable_holder&&) = default; - constexpr __copy_assignable_holder& + __copy_assignable_holder() = default; + __copy_assignable_holder(const __copy_assignable_holder&) = default; + __copy_assignable_holder(__copy_assignable_holder&&) = default; + __copy_assignable_holder& operator=(const __copy_assignable_holder& other) { this->value = other.value; return *this; } - constexpr __copy_assignable_holder& + __copy_assignable_holder& operator=(__copy_assignable_holder&& other) = default; }; @@ -418,16 +418,16 @@ struct tuple return get_impl()(::std::move(*this)); } - constexpr tuple() = default; - constexpr tuple(const tuple& other) = default; - constexpr tuple(tuple&& other) = default; + tuple() = default; + tuple(const tuple& other) = default; + tuple(tuple&& other) = default; template > - constexpr tuple(const tuple<_U1, _U...>& other) : holder(other.template get<0>()), next(other.next) + tuple(const tuple<_U1, _U...>& other) : holder(other.template get<0>()), next(other.next) { } template > - constexpr tuple(tuple<_U1, _U...>&& other) : holder(std::move(other).template get<0>()), next(std::move(other.next)) + tuple(tuple<_U1, _U...>&& other) : holder(std::move(other).template get<0>()), next(std::move(other.next)) { } @@ -435,12 +435,12 @@ struct tuple typename = ::std::enable_if_t< (sizeof...(_U) == sizeof...(T) && ::std::conjunction_v<::std::is_constructible, ::std::is_constructible...>)>> - constexpr tuple(_U1&& _value, _U&&... _next) : holder(std::forward<_U1>(_value)), next(std::forward<_U>(_next)...) + tuple(_U1&& _value, _U&&... _next) : holder(::std::forward<_U1>(_value)), next(::std::forward<_U>(_next)...) { } // required to convert ::std::tuple to inner tuple in user-provided functor - constexpr tuple(const std::tuple& other) + tuple(const ::std::tuple& other) : holder(::std::get<0>(other)), next(oneapi::dpl::__internal::get_tuple_tail(other)) { } @@ -454,7 +454,7 @@ struct tuple // conversion to ::std::tuple with the different template arguments template - constexpr operator ::std::tuple() const + operator ::std::tuple() const { constexpr ::std::size_t __tuple_size = sizeof...(T) + 1; return to_std_tuple(static_cast>(*this), ::std::make_index_sequence<__tuple_size>()); @@ -509,7 +509,7 @@ struct tuple // for cases when we assign ::std::tuple to __internal::tuple template - constexpr tuple& + tuple& operator=(const ::std::tuple& other) { holder.value = ::std::get<0>(other); @@ -566,7 +566,7 @@ struct tuple } template - constexpr static std::tuple + static ::std::tuple to_std_tuple(const oneapi::dpl::__internal::tuple& __t, ::std::index_sequence<_Ip...>) { return ::std::tuple(oneapi::dpl::__internal::get_impl<_Ip>()(__t)...); @@ -579,17 +579,17 @@ struct tuple<> using tuple_type = ::std::tuple<>; // since compiler does not autogenerate ctors // if user defines its own, we have to define them too - constexpr tuple() = default; - constexpr tuple(const tuple& other) = default; + tuple() = default; + tuple(const tuple& other) = default; - constexpr tuple(const ::std::tuple<>&) {} + tuple(const ::std::tuple<>&) {} tuple operator[](tuple) { return {}; } tuple operator[](const tuple&) const { return {}; } - constexpr operator tuple_type() const { return tuple_type{}; } - constexpr tuple& + operator tuple_type() const { return tuple_type{}; } + tuple& operator=(const tuple&) = default; - constexpr tuple& + tuple& operator=(const ::std::tuple<>& /*other*/) { return *this;