[libcxx-commits] [libcxx] [libcxx] Unifying __is_trivial_equality_predicate and __is_trivial_plus_operation into __desugars_to (PR #68642)
Louis Dionne via libcxx-commits
libcxx-commits at lists.llvm.org
Wed Nov 22 06:52:09 PST 2023
https://github.com/ldionne updated https://github.com/llvm/llvm-project/pull/68642
>From 118a293fa7220606b75b429b0dcbd5551f7fa24b Mon Sep 17 00:00:00 2001
From: AntonRydahl <rydahl2610 at gmail.com>
Date: Mon, 9 Oct 2023 15:13:22 -0700
Subject: [PATCH 01/14] Merged __is_trivial_equality_predicate and
__is_trivial_plus_operation into __desugars_to
---
libcxx/include/CMakeLists.txt | 1 -
libcxx/include/__algorithm/comp.h | 7 ++---
libcxx/include/__algorithm/equal.h | 22 ++++++++--------
.../cpu_backends/transform_reduce.h | 23 ++++++++--------
libcxx/include/__functional/operations.h | 15 +++++------
.../include/__functional/ranges_operations.h | 7 ++---
.../include/__numeric/pstl_transform_reduce.h | 2 +-
.../include/__type_traits/operation_traits.h | 4 +--
.../include/__type_traits/predicate_traits.h | 26 -------------------
libcxx/include/module.modulemap.in | 1 -
10 files changed, 40 insertions(+), 68 deletions(-)
delete mode 100644 libcxx/include/__type_traits/predicate_traits.h
diff --git a/libcxx/include/CMakeLists.txt b/libcxx/include/CMakeLists.txt
index 889d7fedbf2965f1..aef54ea25fd52f36 100644
--- a/libcxx/include/CMakeLists.txt
+++ b/libcxx/include/CMakeLists.txt
@@ -816,7 +816,6 @@ set(files
__type_traits/negation.h
__type_traits/noexcept_move_assign_container.h
__type_traits/operation_traits.h
- __type_traits/predicate_traits.h
__type_traits/promote.h
__type_traits/rank.h
__type_traits/remove_all_extents.h
diff --git a/libcxx/include/__algorithm/comp.h b/libcxx/include/__algorithm/comp.h
index 9474536615ffb67a..0993c37cce36a6be 100644
--- a/libcxx/include/__algorithm/comp.h
+++ b/libcxx/include/__algorithm/comp.h
@@ -10,8 +10,9 @@
#define _LIBCPP___ALGORITHM_COMP_H
#include <__config>
+#include <__functional/operations.h>
#include <__type_traits/integral_constant.h>
-#include <__type_traits/predicate_traits.h>
+#include <__type_traits/operation_traits.h>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
@@ -26,8 +27,8 @@ struct __equal_to {
}
};
-template <class _Lhs, class _Rhs>
-struct __is_trivial_equality_predicate<__equal_to, _Lhs, _Rhs> : true_type {};
+template <>
+struct __desugars_to<__equal_to, std::equal_to<>> : true_type {};
// The definition is required because __less is part of the ABI, but it's empty
// because all comparisons should be transparent.
diff --git a/libcxx/include/__algorithm/equal.h b/libcxx/include/__algorithm/equal.h
index b69aeff92bb92891..35e82da15e4d0587 100644
--- a/libcxx/include/__algorithm/equal.h
+++ b/libcxx/include/__algorithm/equal.h
@@ -15,6 +15,7 @@
#include <__config>
#include <__functional/identity.h>
#include <__functional/invoke.h>
+#include <__functional/operations.h>
#include <__iterator/distance.h>
#include <__iterator/iterator_traits.h>
#include <__string/constexpr_c_functions.h>
@@ -23,7 +24,7 @@
#include <__type_traits/is_constant_evaluated.h>
#include <__type_traits/is_equality_comparable.h>
#include <__type_traits/is_volatile.h>
-#include <__type_traits/predicate_traits.h>
+#include <__type_traits/operation_traits.h>
#include <__utility/move.h>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
@@ -41,13 +42,12 @@ _LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 boo
return true;
}
-template <
- class _Tp,
- class _Up,
- class _BinaryPredicate,
- __enable_if_t<__is_trivial_equality_predicate<_BinaryPredicate, _Tp, _Up>::value && !is_volatile<_Tp>::value &&
- !is_volatile<_Up>::value && __libcpp_is_trivially_equality_comparable<_Tp, _Up>::value,
- int> = 0>
+template < class _Tp,
+ class _Up,
+ class _BinaryPredicate,
+ __enable_if_t<__desugars_to<_BinaryPredicate, std::equal_to<>>::value && !is_volatile<_Tp>::value &&
+ !is_volatile<_Up>::value && __libcpp_is_trivially_equality_comparable<_Tp, _Up>::value,
+ int> = 0>
_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool
__equal_iter_impl(_Tp* __first1, _Tp* __last1, _Up* __first2, _BinaryPredicate&) {
return std::__constexpr_memcmp_equal(__first1, __first2, __element_count(__last1 - __first1));
@@ -94,12 +94,12 @@ template <class _Tp,
class _Pred,
class _Proj1,
class _Proj2,
- __enable_if_t<__is_trivial_equality_predicate<_Pred, _Tp, _Up>::value && __is_identity<_Proj1>::value &&
+ __enable_if_t<__desugars_to<_Pred, std::equal_to<>>::value && __is_identity<_Proj1>::value &&
__is_identity<_Proj2>::value && !is_volatile<_Tp>::value && !is_volatile<_Up>::value &&
__libcpp_is_trivially_equality_comparable<_Tp, _Up>::value,
int> = 0>
-_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool __equal_impl(
- _Tp* __first1, _Tp* __last1, _Up* __first2, _Up*, _Pred&, _Proj1&, _Proj2&) {
+_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool
+__equal_impl(_Tp* __first1, _Tp* __last1, _Up* __first2, _Up*, _Pred&, _Proj1&, _Proj2&) {
return std::__constexpr_memcmp_equal(__first1, __first2, __element_count(__last1 - __first1));
}
diff --git a/libcxx/include/__algorithm/pstl_backends/cpu_backends/transform_reduce.h b/libcxx/include/__algorithm/pstl_backends/cpu_backends/transform_reduce.h
index a5ca9c89d1ab23b6..3f4bc31632956b3d 100644
--- a/libcxx/include/__algorithm/pstl_backends/cpu_backends/transform_reduce.h
+++ b/libcxx/include/__algorithm/pstl_backends/cpu_backends/transform_reduce.h
@@ -11,6 +11,7 @@
#include <__algorithm/pstl_backends/cpu_backends/backend.h>
#include <__config>
+#include <__functional/operations.h>
#include <__iterator/concepts.h>
#include <__iterator/iterator_traits.h>
#include <__numeric/transform_reduce.h>
@@ -29,12 +30,11 @@
_LIBCPP_BEGIN_NAMESPACE_STD
-template <
- typename _DifferenceType,
- typename _Tp,
- typename _BinaryOperation,
- typename _UnaryOperation,
- __enable_if_t<__is_trivial_plus_operation<_BinaryOperation, _Tp, _Tp>::value && is_arithmetic_v<_Tp>, int> = 0>
+template < typename _DifferenceType,
+ typename _Tp,
+ typename _BinaryOperation,
+ typename _UnaryOperation,
+ __enable_if_t<__desugars_to<_BinaryOperation, std::plus<>>::value && is_arithmetic_v<_Tp>, int> = 0>
_LIBCPP_HIDE_FROM_ABI _Tp
__simd_transform_reduce(_DifferenceType __n, _Tp __init, _BinaryOperation, _UnaryOperation __f) noexcept {
_PSTL_PRAGMA_SIMD_REDUCTION(+ : __init)
@@ -43,12 +43,11 @@ __simd_transform_reduce(_DifferenceType __n, _Tp __init, _BinaryOperation, _Unar
return __init;
}
-template <
- typename _Size,
- typename _Tp,
- typename _BinaryOperation,
- typename _UnaryOperation,
- __enable_if_t<!(__is_trivial_plus_operation<_BinaryOperation, _Tp, _Tp>::value && is_arithmetic_v<_Tp>), int> = 0>
+template < typename _Size,
+ typename _Tp,
+ typename _BinaryOperation,
+ typename _UnaryOperation,
+ __enable_if_t<!(__desugars_to<_BinaryOperation, std::plus<>>::value && is_arithmetic_v<_Tp>), int> = 0>
_LIBCPP_HIDE_FROM_ABI _Tp
__simd_transform_reduce(_Size __n, _Tp __init, _BinaryOperation __binary_op, _UnaryOperation __f) noexcept {
const _Size __block_size = __lane_size / sizeof(_Tp);
diff --git a/libcxx/include/__functional/operations.h b/libcxx/include/__functional/operations.h
index 6cdb89d6b449bcdf..d6c8ff547cfbdcdc 100644
--- a/libcxx/include/__functional/operations.h
+++ b/libcxx/include/__functional/operations.h
@@ -15,7 +15,6 @@
#include <__functional/unary_function.h>
#include <__type_traits/integral_constant.h>
#include <__type_traits/operation_traits.h>
-#include <__type_traits/predicate_traits.h>
#include <__utility/forward.h>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
@@ -41,12 +40,12 @@ struct _LIBCPP_TEMPLATE_VIS plus
};
_LIBCPP_CTAD_SUPPORTED_FOR_TYPE(plus);
-template <class _Tp>
-struct __is_trivial_plus_operation<plus<_Tp>, _Tp, _Tp> : true_type {};
+template <class _Pred>
+struct __desugars_to<plus<_Pred>, plus<_Pred>> : true_type {};
#if _LIBCPP_STD_VER >= 14
-template <class _Tp, class _Up>
-struct __is_trivial_plus_operation<plus<>, _Tp, _Up> : true_type {};
+template <>
+struct __desugars_to<plus<>, plus<>> : true_type {};
#endif
#if _LIBCPP_STD_VER >= 14
@@ -353,11 +352,11 @@ struct _LIBCPP_TEMPLATE_VIS equal_to<void>
#endif
template <class _Tp>
-struct __is_trivial_equality_predicate<equal_to<_Tp>, _Tp, _Tp> : true_type {};
+struct __desugars_to<equal_to<_Tp>, std::equal_to<_Tp>> : true_type {};
#if _LIBCPP_STD_VER >= 14
-template <class _Tp>
-struct __is_trivial_equality_predicate<equal_to<>, _Tp, _Tp> : true_type {};
+template <>
+struct __desugars_to<equal_to<>, std::equal_to<>> : true_type {};
#endif
#if _LIBCPP_STD_VER >= 14
diff --git a/libcxx/include/__functional/ranges_operations.h b/libcxx/include/__functional/ranges_operations.h
index c344fc38f98ddd9b..22d6f7fef3b3da5d 100644
--- a/libcxx/include/__functional/ranges_operations.h
+++ b/libcxx/include/__functional/ranges_operations.h
@@ -13,8 +13,9 @@
#include <__concepts/equality_comparable.h>
#include <__concepts/totally_ordered.h>
#include <__config>
+#include <__functional/operations.h>
#include <__type_traits/integral_constant.h>
-#include <__type_traits/predicate_traits.h>
+#include <__type_traits/operation_traits.h>
#include <__utility/forward.h>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
@@ -95,8 +96,8 @@ struct greater_equal {
} // namespace ranges
-template <class _Lhs, class _Rhs>
-struct __is_trivial_equality_predicate<ranges::equal_to, _Lhs, _Rhs> : true_type {};
+template <>
+struct __desugars_to<ranges::equal_to, std::equal_to<>> : true_type {};
#endif // _LIBCPP_STD_VER >= 20
diff --git a/libcxx/include/__numeric/pstl_transform_reduce.h b/libcxx/include/__numeric/pstl_transform_reduce.h
index 4127ee21e3045c83..1127726046665c0d 100644
--- a/libcxx/include/__numeric/pstl_transform_reduce.h
+++ b/libcxx/include/__numeric/pstl_transform_reduce.h
@@ -84,7 +84,7 @@ _LIBCPP_HIDE_FROM_ABI _Tp transform_reduce(
}
// This overload doesn't get a customization point because it's trivial to detect (through e.g.
-// __is_trivial_plus_operation) when specializing the more general variant, which should always be preferred
+// __desugars_to) when specializing the more general variant, which should always be preferred
template <class _ExecutionPolicy,
class _ForwardIterator1,
class _ForwardIterator2,
diff --git a/libcxx/include/__type_traits/operation_traits.h b/libcxx/include/__type_traits/operation_traits.h
index 7dda93e9083a4042..d03bf6209a6cc778 100644
--- a/libcxx/include/__type_traits/operation_traits.h
+++ b/libcxx/include/__type_traits/operation_traits.h
@@ -18,8 +18,8 @@
_LIBCPP_BEGIN_NAMESPACE_STD
-template <class _Pred, class _Lhs, class _Rhs>
-struct __is_trivial_plus_operation : false_type {};
+template <class _Pred, class _Reference>
+struct __desugars_to : false_type {};
_LIBCPP_END_NAMESPACE_STD
diff --git a/libcxx/include/__type_traits/predicate_traits.h b/libcxx/include/__type_traits/predicate_traits.h
deleted file mode 100644
index 872608e6ac3be3fd..0000000000000000
--- a/libcxx/include/__type_traits/predicate_traits.h
+++ /dev/null
@@ -1,26 +0,0 @@
-//===----------------------------------------------------------------------===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef _LIBCPP___TYPE_TRAITS_PREDICATE_TRAITS
-#define _LIBCPP___TYPE_TRAITS_PREDICATE_TRAITS
-
-#include <__config>
-#include <__type_traits/integral_constant.h>
-
-#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-# pragma GCC system_header
-#endif
-
-_LIBCPP_BEGIN_NAMESPACE_STD
-
-template <class _Pred, class _Lhs, class _Rhs>
-struct __is_trivial_equality_predicate : false_type {};
-
-_LIBCPP_END_NAMESPACE_STD
-
-#endif // _LIBCPP___TYPE_TRAITS_PREDICATE_TRAITS
diff --git a/libcxx/include/module.modulemap.in b/libcxx/include/module.modulemap.in
index 17ebe48f329963d5..b4a68c8ecde0ab1c 100644
--- a/libcxx/include/module.modulemap.in
+++ b/libcxx/include/module.modulemap.in
@@ -2013,7 +2013,6 @@ module std_private_type_traits_nat [system
module std_private_type_traits_negation [system] { header "__type_traits/negation.h" }
module std_private_type_traits_noexcept_move_assign_container [system] { header "__type_traits/noexcept_move_assign_container.h" }
module std_private_type_traits_operation_traits [system] { header "__type_traits/operation_traits.h" }
-module std_private_type_traits_predicate_traits [system] { header "__type_traits/predicate_traits.h" }
module std_private_type_traits_promote [system] { header "__type_traits/promote.h" }
module std_private_type_traits_rank [system] { header "__type_traits/rank.h" }
module std_private_type_traits_remove_all_extents [system] { header "__type_traits/remove_all_extents.h" }
>From 23485d5e7fb93351b464748eee49d616eff30d5b Mon Sep 17 00:00:00 2001
From: AntonRydahl <rydahl2610 at gmail.com>
Date: Fri, 13 Oct 2023 12:05:49 -0700
Subject: [PATCH 02/14] Resolving suggested changes
---
libcxx/include/__algorithm/comp.h | 2 +-
libcxx/include/__algorithm/equal.h | 4 ++--
.../cpu_backends/transform_reduce.h | 4 ++--
libcxx/include/__functional/operations.h | 16 +++-------------
libcxx/include/__type_traits/operation_traits.h | 5 ++++-
5 files changed, 12 insertions(+), 19 deletions(-)
diff --git a/libcxx/include/__algorithm/comp.h b/libcxx/include/__algorithm/comp.h
index 0993c37cce36a6be..3624a26a7d6d771e 100644
--- a/libcxx/include/__algorithm/comp.h
+++ b/libcxx/include/__algorithm/comp.h
@@ -28,7 +28,7 @@ struct __equal_to {
};
template <>
-struct __desugars_to<__equal_to, std::equal_to<>> : true_type {};
+struct __desugars_to<__equal_to, equal_to<void>> : true_type {};
// The definition is required because __less is part of the ABI, but it's empty
// because all comparisons should be transparent.
diff --git a/libcxx/include/__algorithm/equal.h b/libcxx/include/__algorithm/equal.h
index 35e82da15e4d0587..116d1a903e50716f 100644
--- a/libcxx/include/__algorithm/equal.h
+++ b/libcxx/include/__algorithm/equal.h
@@ -45,7 +45,7 @@ _LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 boo
template < class _Tp,
class _Up,
class _BinaryPredicate,
- __enable_if_t<__desugars_to<_BinaryPredicate, std::equal_to<>>::value && !is_volatile<_Tp>::value &&
+ __enable_if_t<__desugars_to<_BinaryPredicate, equal_to<_Tp>>::value && !is_volatile<_Tp>::value &&
!is_volatile<_Up>::value && __libcpp_is_trivially_equality_comparable<_Tp, _Up>::value,
int> = 0>
_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool
@@ -94,7 +94,7 @@ template <class _Tp,
class _Pred,
class _Proj1,
class _Proj2,
- __enable_if_t<__desugars_to<_Pred, std::equal_to<>>::value && __is_identity<_Proj1>::value &&
+ __enable_if_t<__desugars_to<_Pred, equal_to<_Tp>>::value && __is_identity<_Proj1>::value &&
__is_identity<_Proj2>::value && !is_volatile<_Tp>::value && !is_volatile<_Up>::value &&
__libcpp_is_trivially_equality_comparable<_Tp, _Up>::value,
int> = 0>
diff --git a/libcxx/include/__algorithm/pstl_backends/cpu_backends/transform_reduce.h b/libcxx/include/__algorithm/pstl_backends/cpu_backends/transform_reduce.h
index 3f4bc31632956b3d..c238d1475aec9dbb 100644
--- a/libcxx/include/__algorithm/pstl_backends/cpu_backends/transform_reduce.h
+++ b/libcxx/include/__algorithm/pstl_backends/cpu_backends/transform_reduce.h
@@ -34,7 +34,7 @@ template < typename _DifferenceType,
typename _Tp,
typename _BinaryOperation,
typename _UnaryOperation,
- __enable_if_t<__desugars_to<_BinaryOperation, std::plus<>>::value && is_arithmetic_v<_Tp>, int> = 0>
+ __enable_if_t<__desugars_to<_BinaryOperation, plus<_Tp>>::value && is_arithmetic_v<_Tp>, int> = 0>
_LIBCPP_HIDE_FROM_ABI _Tp
__simd_transform_reduce(_DifferenceType __n, _Tp __init, _BinaryOperation, _UnaryOperation __f) noexcept {
_PSTL_PRAGMA_SIMD_REDUCTION(+ : __init)
@@ -47,7 +47,7 @@ template < typename _Size,
typename _Tp,
typename _BinaryOperation,
typename _UnaryOperation,
- __enable_if_t<!(__desugars_to<_BinaryOperation, std::plus<>>::value && is_arithmetic_v<_Tp>), int> = 0>
+ __enable_if_t<!(__desugars_to<_BinaryOperation, plus<_Tp>>::value && is_arithmetic_v<_Tp>), int> = 0>
_LIBCPP_HIDE_FROM_ABI _Tp
__simd_transform_reduce(_Size __n, _Tp __init, _BinaryOperation __binary_op, _UnaryOperation __f) noexcept {
const _Size __block_size = __lane_size / sizeof(_Tp);
diff --git a/libcxx/include/__functional/operations.h b/libcxx/include/__functional/operations.h
index d6c8ff547cfbdcdc..19ea9ab46ff7270a 100644
--- a/libcxx/include/__functional/operations.h
+++ b/libcxx/include/__functional/operations.h
@@ -40,13 +40,8 @@ struct _LIBCPP_TEMPLATE_VIS plus
};
_LIBCPP_CTAD_SUPPORTED_FOR_TYPE(plus);
-template <class _Pred>
-struct __desugars_to<plus<_Pred>, plus<_Pred>> : true_type {};
-
-#if _LIBCPP_STD_VER >= 14
-template <>
-struct __desugars_to<plus<>, plus<>> : true_type {};
-#endif
+template <class _Tp>
+struct __desugars_to<plus<_Tp>, plus<void>> : true_type {};
#if _LIBCPP_STD_VER >= 14
template <>
@@ -352,12 +347,7 @@ struct _LIBCPP_TEMPLATE_VIS equal_to<void>
#endif
template <class _Tp>
-struct __desugars_to<equal_to<_Tp>, std::equal_to<_Tp>> : true_type {};
-
-#if _LIBCPP_STD_VER >= 14
-template <>
-struct __desugars_to<equal_to<>, std::equal_to<>> : true_type {};
-#endif
+struct __desugars_to<equal_to<_Tp>, equal_to<void>> : true_type {};
#if _LIBCPP_STD_VER >= 14
template <class _Tp = void>
diff --git a/libcxx/include/__type_traits/operation_traits.h b/libcxx/include/__type_traits/operation_traits.h
index d03bf6209a6cc778..7dd7ef7c9d23d39e 100644
--- a/libcxx/include/__type_traits/operation_traits.h
+++ b/libcxx/include/__type_traits/operation_traits.h
@@ -18,9 +18,12 @@
_LIBCPP_BEGIN_NAMESPACE_STD
-template <class _Pred, class _Reference>
+template <class _Operation, class _Canonical>
struct __desugars_to : false_type {};
+template <class _Operation>
+struct __desugars_to<_Operation, _Operation> : true_type {};
+
_LIBCPP_END_NAMESPACE_STD
#endif // _LIBCPP___TYPE_TRAITS_OPERATION_TRAITS_H
>From 771977d49ddfd8e2f3e77ae98efecce2c50dd08c Mon Sep 17 00:00:00 2001
From: AntonRydahl <rydahl2610 at gmail.com>
Date: Fri, 13 Oct 2023 15:25:44 -0700
Subject: [PATCH 03/14] Attempt to fix -std=gnu++03 related errors
---
libcxx/include/__algorithm/comp.h | 2 +-
libcxx/include/__algorithm/equal.h | 4 ++--
.../__algorithm/pstl_backends/cpu_backends/transform_reduce.h | 4 ++--
libcxx/include/__functional/operations.h | 4 ++--
4 files changed, 7 insertions(+), 7 deletions(-)
diff --git a/libcxx/include/__algorithm/comp.h b/libcxx/include/__algorithm/comp.h
index 3624a26a7d6d771e..38fd284274300023 100644
--- a/libcxx/include/__algorithm/comp.h
+++ b/libcxx/include/__algorithm/comp.h
@@ -28,7 +28,7 @@ struct __equal_to {
};
template <>
-struct __desugars_to<__equal_to, equal_to<void>> : true_type {};
+struct __desugars_to<__equal_to, equal_to<void> > : true_type {};
// The definition is required because __less is part of the ABI, but it's empty
// because all comparisons should be transparent.
diff --git a/libcxx/include/__algorithm/equal.h b/libcxx/include/__algorithm/equal.h
index 116d1a903e50716f..320c84df3641e3db 100644
--- a/libcxx/include/__algorithm/equal.h
+++ b/libcxx/include/__algorithm/equal.h
@@ -45,7 +45,7 @@ _LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 boo
template < class _Tp,
class _Up,
class _BinaryPredicate,
- __enable_if_t<__desugars_to<_BinaryPredicate, equal_to<_Tp>>::value && !is_volatile<_Tp>::value &&
+ __enable_if_t<__desugars_to<_BinaryPredicate, equal_to<_Tp> >::value && !is_volatile<_Tp>::value &&
!is_volatile<_Up>::value && __libcpp_is_trivially_equality_comparable<_Tp, _Up>::value,
int> = 0>
_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool
@@ -94,7 +94,7 @@ template <class _Tp,
class _Pred,
class _Proj1,
class _Proj2,
- __enable_if_t<__desugars_to<_Pred, equal_to<_Tp>>::value && __is_identity<_Proj1>::value &&
+ __enable_if_t<__desugars_to<_Pred, equal_to<_Tp> >::value && __is_identity<_Proj1>::value &&
__is_identity<_Proj2>::value && !is_volatile<_Tp>::value && !is_volatile<_Up>::value &&
__libcpp_is_trivially_equality_comparable<_Tp, _Up>::value,
int> = 0>
diff --git a/libcxx/include/__algorithm/pstl_backends/cpu_backends/transform_reduce.h b/libcxx/include/__algorithm/pstl_backends/cpu_backends/transform_reduce.h
index c238d1475aec9dbb..245eda5388622d57 100644
--- a/libcxx/include/__algorithm/pstl_backends/cpu_backends/transform_reduce.h
+++ b/libcxx/include/__algorithm/pstl_backends/cpu_backends/transform_reduce.h
@@ -34,7 +34,7 @@ template < typename _DifferenceType,
typename _Tp,
typename _BinaryOperation,
typename _UnaryOperation,
- __enable_if_t<__desugars_to<_BinaryOperation, plus<_Tp>>::value && is_arithmetic_v<_Tp>, int> = 0>
+ __enable_if_t<__desugars_to<_BinaryOperation, plus<_Tp> >::value && is_arithmetic_v<_Tp>, int> = 0>
_LIBCPP_HIDE_FROM_ABI _Tp
__simd_transform_reduce(_DifferenceType __n, _Tp __init, _BinaryOperation, _UnaryOperation __f) noexcept {
_PSTL_PRAGMA_SIMD_REDUCTION(+ : __init)
@@ -47,7 +47,7 @@ template < typename _Size,
typename _Tp,
typename _BinaryOperation,
typename _UnaryOperation,
- __enable_if_t<!(__desugars_to<_BinaryOperation, plus<_Tp>>::value && is_arithmetic_v<_Tp>), int> = 0>
+ __enable_if_t<!(__desugars_to<_BinaryOperation, plus<_Tp> >::value && is_arithmetic_v<_Tp>), int> = 0>
_LIBCPP_HIDE_FROM_ABI _Tp
__simd_transform_reduce(_Size __n, _Tp __init, _BinaryOperation __binary_op, _UnaryOperation __f) noexcept {
const _Size __block_size = __lane_size / sizeof(_Tp);
diff --git a/libcxx/include/__functional/operations.h b/libcxx/include/__functional/operations.h
index 19ea9ab46ff7270a..4f734cac7c6772a2 100644
--- a/libcxx/include/__functional/operations.h
+++ b/libcxx/include/__functional/operations.h
@@ -41,7 +41,7 @@ struct _LIBCPP_TEMPLATE_VIS plus
_LIBCPP_CTAD_SUPPORTED_FOR_TYPE(plus);
template <class _Tp>
-struct __desugars_to<plus<_Tp>, plus<void>> : true_type {};
+struct __desugars_to<plus<_Tp>, plus<void> > : true_type {};
#if _LIBCPP_STD_VER >= 14
template <>
@@ -347,7 +347,7 @@ struct _LIBCPP_TEMPLATE_VIS equal_to<void>
#endif
template <class _Tp>
-struct __desugars_to<equal_to<_Tp>, equal_to<void>> : true_type {};
+struct __desugars_to<equal_to<_Tp>, equal_to<void> > : true_type {};
#if _LIBCPP_STD_VER >= 14
template <class _Tp = void>
>From 5fbb876231e8f9223ac771898019555542de7586 Mon Sep 17 00:00:00 2001
From: AntonRydahl <rydahl2610 at gmail.com>
Date: Sun, 15 Oct 2023 20:45:16 -0700
Subject: [PATCH 04/14] Only optimizing __equal_impl for is_equal<void>
---
libcxx/include/__algorithm/equal.h | 4 ++--
libcxx/include/__functional/operations.h | 6 ------
2 files changed, 2 insertions(+), 8 deletions(-)
diff --git a/libcxx/include/__algorithm/equal.h b/libcxx/include/__algorithm/equal.h
index 320c84df3641e3db..188c40f482c90b11 100644
--- a/libcxx/include/__algorithm/equal.h
+++ b/libcxx/include/__algorithm/equal.h
@@ -45,7 +45,7 @@ _LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 boo
template < class _Tp,
class _Up,
class _BinaryPredicate,
- __enable_if_t<__desugars_to<_BinaryPredicate, equal_to<_Tp> >::value && !is_volatile<_Tp>::value &&
+ __enable_if_t<__desugars_to<_BinaryPredicate, equal_to<void> >::value && !is_volatile<_Tp>::value &&
!is_volatile<_Up>::value && __libcpp_is_trivially_equality_comparable<_Tp, _Up>::value,
int> = 0>
_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool
@@ -94,7 +94,7 @@ template <class _Tp,
class _Pred,
class _Proj1,
class _Proj2,
- __enable_if_t<__desugars_to<_Pred, equal_to<_Tp> >::value && __is_identity<_Proj1>::value &&
+ __enable_if_t<__desugars_to<_Pred, equal_to<void> >::value && __is_identity<_Proj1>::value &&
__is_identity<_Proj2>::value && !is_volatile<_Tp>::value && !is_volatile<_Up>::value &&
__libcpp_is_trivially_equality_comparable<_Tp, _Up>::value,
int> = 0>
diff --git a/libcxx/include/__functional/operations.h b/libcxx/include/__functional/operations.h
index 4f734cac7c6772a2..6b489a0fb439c8a5 100644
--- a/libcxx/include/__functional/operations.h
+++ b/libcxx/include/__functional/operations.h
@@ -40,9 +40,6 @@ struct _LIBCPP_TEMPLATE_VIS plus
};
_LIBCPP_CTAD_SUPPORTED_FOR_TYPE(plus);
-template <class _Tp>
-struct __desugars_to<plus<_Tp>, plus<void> > : true_type {};
-
#if _LIBCPP_STD_VER >= 14
template <>
struct _LIBCPP_TEMPLATE_VIS plus<void>
@@ -346,9 +343,6 @@ struct _LIBCPP_TEMPLATE_VIS equal_to<void>
};
#endif
-template <class _Tp>
-struct __desugars_to<equal_to<_Tp>, equal_to<void> > : true_type {};
-
#if _LIBCPP_STD_VER >= 14
template <class _Tp = void>
#else
>From bf21f4c0754888c552c7bae9db2c8ddc88da028c Mon Sep 17 00:00:00 2001
From: AntonRydahl <rydahl2610 at gmail.com>
Date: Sun, 5 Nov 2023 12:55:06 -0800
Subject: [PATCH 05/14] Update __desugars_to to compare againts tags rather
than transparent predicates
---
libcxx/include/__algorithm/equal.h | 4 +-
.../cpu_backends/transform_reduce.h | 17 ++++++---
libcxx/include/__functional/operations.h | 22 +++++++++++
.../include/__functional/ranges_operations.h | 6 ++-
.../include/__type_traits/operation_traits.h | 11 ++++--
.../pstl.transform_reduce.string.pass.cpp | 38 +++++++++++++++++++
6 files changed, 84 insertions(+), 14 deletions(-)
create mode 100644 libcxx/test/libcxx/algorithms/pstl.transform_reduce.string.pass.cpp
diff --git a/libcxx/include/__algorithm/equal.h b/libcxx/include/__algorithm/equal.h
index 188c40f482c90b11..7979628b7446bf9c 100644
--- a/libcxx/include/__algorithm/equal.h
+++ b/libcxx/include/__algorithm/equal.h
@@ -45,7 +45,7 @@ _LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 boo
template < class _Tp,
class _Up,
class _BinaryPredicate,
- __enable_if_t<__desugars_to<_BinaryPredicate, equal_to<void> >::value && !is_volatile<_Tp>::value &&
+ __enable_if_t<__desugars_to<__equal_tag, _BinaryPredicate, _Tp, _Up>::value && !is_volatile<_Tp>::value &&
!is_volatile<_Up>::value && __libcpp_is_trivially_equality_comparable<_Tp, _Up>::value,
int> = 0>
_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool
@@ -94,7 +94,7 @@ template <class _Tp,
class _Pred,
class _Proj1,
class _Proj2,
- __enable_if_t<__desugars_to<_Pred, equal_to<void> >::value && __is_identity<_Proj1>::value &&
+ __enable_if_t<__desugars_to<__equal_tag, _Pred, _Tp, _Up>::value && __is_identity<_Proj1>::value &&
__is_identity<_Proj2>::value && !is_volatile<_Tp>::value && !is_volatile<_Up>::value &&
__libcpp_is_trivially_equality_comparable<_Tp, _Up>::value,
int> = 0>
diff --git a/libcxx/include/__algorithm/pstl_backends/cpu_backends/transform_reduce.h b/libcxx/include/__algorithm/pstl_backends/cpu_backends/transform_reduce.h
index 245eda5388622d57..0786d3f24cf85abe 100644
--- a/libcxx/include/__algorithm/pstl_backends/cpu_backends/transform_reduce.h
+++ b/libcxx/include/__algorithm/pstl_backends/cpu_backends/transform_reduce.h
@@ -34,7 +34,9 @@ template < typename _DifferenceType,
typename _Tp,
typename _BinaryOperation,
typename _UnaryOperation,
- __enable_if_t<__desugars_to<_BinaryOperation, plus<_Tp> >::value && is_arithmetic_v<_Tp>, int> = 0>
+ typename _UnaryResult = invoke_result_t<_UnaryOperation, _DifferenceType>,
+ __enable_if_t<__desugars_to<__plus_tag, _BinaryOperation, _Tp, _UnaryResult>::value && is_arithmetic_v<_Tp>,
+ int> = 0>
_LIBCPP_HIDE_FROM_ABI _Tp
__simd_transform_reduce(_DifferenceType __n, _Tp __init, _BinaryOperation, _UnaryOperation __f) noexcept {
_PSTL_PRAGMA_SIMD_REDUCTION(+ : __init)
@@ -43,11 +45,14 @@ __simd_transform_reduce(_DifferenceType __n, _Tp __init, _BinaryOperation, _Unar
return __init;
}
-template < typename _Size,
- typename _Tp,
- typename _BinaryOperation,
- typename _UnaryOperation,
- __enable_if_t<!(__desugars_to<_BinaryOperation, plus<_Tp> >::value && is_arithmetic_v<_Tp>), int> = 0>
+template <
+ typename _Size,
+ typename _Tp,
+ typename _BinaryOperation,
+ typename _UnaryOperation,
+ typename _UnaryResult = invoke_result_t<_UnaryOperation, _Size>,
+ __enable_if_t<!(__desugars_to<__plus_tag, _BinaryOperation, _Tp, _UnaryResult>::value && is_arithmetic_v<_Tp>),
+ int> = 0>
_LIBCPP_HIDE_FROM_ABI _Tp
__simd_transform_reduce(_Size __n, _Tp __init, _BinaryOperation __binary_op, _UnaryOperation __f) noexcept {
const _Size __block_size = __lane_size / sizeof(_Tp);
diff --git a/libcxx/include/__functional/operations.h b/libcxx/include/__functional/operations.h
index 6b489a0fb439c8a5..30554d97ab238ffc 100644
--- a/libcxx/include/__functional/operations.h
+++ b/libcxx/include/__functional/operations.h
@@ -40,6 +40,17 @@ struct _LIBCPP_TEMPLATE_VIS plus
};
_LIBCPP_CTAD_SUPPORTED_FOR_TYPE(plus);
+// For the typed version of plus, we require that the left- and right-hand
+// side of the plus operator matches
+template <class _Tp>
+struct __desugars_to<__plus_tag, plus<_Tp>, _Tp, _Tp> : true_type {};
+
+#if _LIBCPP_STD_VER >= 14
+// In the transparent case, we do not enforce that
+template <class _Tp, class _Up>
+struct __desugars_to<__plus_tag, plus<void>, _Tp, _Up> : true_type {};
+#endif
+
#if _LIBCPP_STD_VER >= 14
template <>
struct _LIBCPP_TEMPLATE_VIS plus<void>
@@ -343,6 +354,17 @@ struct _LIBCPP_TEMPLATE_VIS equal_to<void>
};
#endif
+// For the typed version of equal_to, we require that the left- and right-hand
+// side of the equality operator matches
+template <class _Tp>
+struct __desugars_to<__equal_tag, equal_to<_Tp>, _Tp, _Tp> : true_type {};
+
+#if _LIBCPP_STD_VER >= 14
+// In the transparent case, we do not enforce that
+template <class _Tp, class _Up>
+struct __desugars_to<__equal_tag, equal_to<void>, _Tp, _Up> : true_type {};
+#endif
+
#if _LIBCPP_STD_VER >= 14
template <class _Tp = void>
#else
diff --git a/libcxx/include/__functional/ranges_operations.h b/libcxx/include/__functional/ranges_operations.h
index 22d6f7fef3b3da5d..eee3442a3ef0e8f7 100644
--- a/libcxx/include/__functional/ranges_operations.h
+++ b/libcxx/include/__functional/ranges_operations.h
@@ -96,8 +96,10 @@ struct greater_equal {
} // namespace ranges
-template <>
-struct __desugars_to<ranges::equal_to, std::equal_to<>> : true_type {};
+// For ranges we do not require that the types on each side of the equality
+// operator are of the same type
+template <class _Tp, class _Up>
+struct __desugars_to<__equal_tag, ranges::equal_to, _Tp, _Up> : true_type {};
#endif // _LIBCPP_STD_VER >= 20
diff --git a/libcxx/include/__type_traits/operation_traits.h b/libcxx/include/__type_traits/operation_traits.h
index 7dd7ef7c9d23d39e..5774e14ab091200c 100644
--- a/libcxx/include/__type_traits/operation_traits.h
+++ b/libcxx/include/__type_traits/operation_traits.h
@@ -18,11 +18,14 @@
_LIBCPP_BEGIN_NAMESPACE_STD
-template <class _Operation, class _Canonical>
-struct __desugars_to : false_type {};
+// Tags to represent the canonical operations
+struct __equal_tag {};
+struct __plus_tag {};
+
+// In the general case, __desugars_to is false
-template <class _Operation>
-struct __desugars_to<_Operation, _Operation> : true_type {};
+template <class _CanonicalTag, class _Operation, class... _Args>
+struct __desugars_to : false_type {};
_LIBCPP_END_NAMESPACE_STD
diff --git a/libcxx/test/libcxx/algorithms/pstl.transform_reduce.string.pass.cpp b/libcxx/test/libcxx/algorithms/pstl.transform_reduce.string.pass.cpp
new file mode 100644
index 0000000000000000..ced0e6a23da77acc
--- /dev/null
+++ b/libcxx/test/libcxx/algorithms/pstl.transform_reduce.string.pass.cpp
@@ -0,0 +1,38 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// This test verifies that you can make string reductions with parallel
+// algorithms
+
+#include <algorithm>
+#include <cassert>
+#include <execution>
+#include <vector>
+
+int main(int, char**) {
+ int length = 10000;
+ std::vector<std::string> vec(length);
+ for (int i = 0; i < length; i++) {
+ std::string str = "";
+ char a;
+ for (int j = 0; j < 5; j++) {
+ a = 56 + (((int)i * 5 + 3 * j) % 200);
+ str += a;
+ }
+ vec[i] = str;
+ }
+
+ std::string result = std::transform_reduce(
+ std::execution::par_unseq, vec.begin(), vec.end(), (std::string) "", std::plus{}, [](std::string& str) {
+ return str;
+ });
+ for (auto v : vec) {
+ assert(result.find(v) != std::string::npos && "Substring not found in deruced string.");
+ }
+ return 0;
+}
\ No newline at end of file
>From 144578eba8b678ff908a88b77f454c45311bbb65 Mon Sep 17 00:00:00 2001
From: AntonRydahl <rydahl2610 at gmail.com>
Date: Mon, 6 Nov 2023 12:09:16 -0800
Subject: [PATCH 06/14] Update string reduction commit
---
.../pstl.transform_reduce.string.pass.cpp | 31 ++++++++++++++-----
1 file changed, 23 insertions(+), 8 deletions(-)
diff --git a/libcxx/test/libcxx/algorithms/pstl.transform_reduce.string.pass.cpp b/libcxx/test/libcxx/algorithms/pstl.transform_reduce.string.pass.cpp
index ced0e6a23da77acc..10c2db3c7d3ea7be 100644
--- a/libcxx/test/libcxx/algorithms/pstl.transform_reduce.string.pass.cpp
+++ b/libcxx/test/libcxx/algorithms/pstl.transform_reduce.string.pass.cpp
@@ -9,30 +9,45 @@
// This test verifies that you can make string reductions with parallel
// algorithms
+// UNSUPPORTED: c++03, c++11, c++14
+
#include <algorithm>
#include <cassert>
#include <execution>
#include <vector>
+template <class Execution, class Input>
+void test_execution_policy(Execution& execution, Input& input) {
+ std::string result = std::transform_reduce(
+ execution, input.begin(), input.end(), (std::string) "", std::plus{}, [](std::string& str) { return str; });
+ for (auto v : input) {
+ assert(result.find(v) != std::string::npos && "Substring not found in reduuced string.");
+ }
+}
+
int main(int, char**) {
int length = 10000;
std::vector<std::string> vec(length);
+
+ // Generating semi-random strings of length 5
+ unsigned int seed = 17;
for (int i = 0; i < length; i++) {
std::string str = "";
char a;
for (int j = 0; j < 5; j++) {
- a = 56 + (((int)i * 5 + 3 * j) % 200);
+ // Generating random unsigned int with a linear congruential generator
+ seed = (214013*seed + 11) % 4294967295;
+
+ // Generating ASCII character from 33 (!) to 126 (~)
+ a = ((unsigned int) 33 + (seed % 93));
str += a;
}
vec[i] = str;
}
- std::string result = std::transform_reduce(
- std::execution::par_unseq, vec.begin(), vec.end(), (std::string) "", std::plus{}, [](std::string& str) {
- return str;
- });
- for (auto v : vec) {
- assert(result.find(v) != std::string::npos && "Substring not found in deruced string.");
- }
+ test_execution_policy(std::execution::seq, vec);
+ test_execution_policy(std::execution::unseq, vec);
+ test_execution_policy(std::execution::par, vec);
+ test_execution_policy(std::execution::par_unseq, vec);
return 0;
}
\ No newline at end of file
>From 54883a83827c2c3158b4faa5c94f2d37296c0d92 Mon Sep 17 00:00:00 2001
From: AntonRydahl <rydahl2610 at gmail.com>
Date: Mon, 6 Nov 2023 12:10:05 -0800
Subject: [PATCH 07/14] Clang-formatted test
---
.../libcxx/algorithms/pstl.transform_reduce.string.pass.cpp | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/libcxx/test/libcxx/algorithms/pstl.transform_reduce.string.pass.cpp b/libcxx/test/libcxx/algorithms/pstl.transform_reduce.string.pass.cpp
index 10c2db3c7d3ea7be..c56e57bacefdeabb 100644
--- a/libcxx/test/libcxx/algorithms/pstl.transform_reduce.string.pass.cpp
+++ b/libcxx/test/libcxx/algorithms/pstl.transform_reduce.string.pass.cpp
@@ -36,10 +36,10 @@ int main(int, char**) {
char a;
for (int j = 0; j < 5; j++) {
// Generating random unsigned int with a linear congruential generator
- seed = (214013*seed + 11) % 4294967295;
-
+ seed = (214013 * seed + 11) % 4294967295;
+
// Generating ASCII character from 33 (!) to 126 (~)
- a = ((unsigned int) 33 + (seed % 93));
+ a = ((unsigned int)33 + (seed % 93));
str += a;
}
vec[i] = str;
>From e90bb810e6cd8b40ff70ea7d37e989281acd4e54 Mon Sep 17 00:00:00 2001
From: AntonRydahl <rydahl2610 at gmail.com>
Date: Mon, 6 Nov 2023 15:02:27 -0800
Subject: [PATCH 08/14] Added #include<string> in new test
---
.../test/libcxx/algorithms/pstl.transform_reduce.string.pass.cpp | 1 +
1 file changed, 1 insertion(+)
diff --git a/libcxx/test/libcxx/algorithms/pstl.transform_reduce.string.pass.cpp b/libcxx/test/libcxx/algorithms/pstl.transform_reduce.string.pass.cpp
index c56e57bacefdeabb..bede4864538ccc0c 100644
--- a/libcxx/test/libcxx/algorithms/pstl.transform_reduce.string.pass.cpp
+++ b/libcxx/test/libcxx/algorithms/pstl.transform_reduce.string.pass.cpp
@@ -14,6 +14,7 @@
#include <algorithm>
#include <cassert>
#include <execution>
+#include <string>
#include <vector>
template <class Execution, class Input>
>From 22b0e2818e867044bea70b85196817719db081d2 Mon Sep 17 00:00:00 2001
From: AntonRydahl <rydahl2610 at gmail.com>
Date: Thu, 9 Nov 2023 22:30:05 -0800
Subject: [PATCH 09/14] Added libcpp-has-no-incomplete-pstl to test
---
.../libcxx/algorithms/pstl.transform_reduce.string.pass.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/libcxx/test/libcxx/algorithms/pstl.transform_reduce.string.pass.cpp b/libcxx/test/libcxx/algorithms/pstl.transform_reduce.string.pass.cpp
index bede4864538ccc0c..aacaf95450dc4763 100644
--- a/libcxx/test/libcxx/algorithms/pstl.transform_reduce.string.pass.cpp
+++ b/libcxx/test/libcxx/algorithms/pstl.transform_reduce.string.pass.cpp
@@ -9,7 +9,7 @@
// This test verifies that you can make string reductions with parallel
// algorithms
-// UNSUPPORTED: c++03, c++11, c++14
+// UNSUPPORTED: c++03, c++11, c++14, libcpp-has-no-incomplete-pstl
#include <algorithm>
#include <cassert>
>From 51c9fb408705ef877d974985a5e4c32fa0780190 Mon Sep 17 00:00:00 2001
From: AntonRydahl <rydahl2610 at gmail.com>
Date: Thu, 9 Nov 2023 23:10:04 -0800
Subject: [PATCH 10/14] Imported numeric in test
---
.../libcxx/algorithms/pstl.transform_reduce.string.pass.cpp | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/libcxx/test/libcxx/algorithms/pstl.transform_reduce.string.pass.cpp b/libcxx/test/libcxx/algorithms/pstl.transform_reduce.string.pass.cpp
index aacaf95450dc4763..483c51b6034f244d 100644
--- a/libcxx/test/libcxx/algorithms/pstl.transform_reduce.string.pass.cpp
+++ b/libcxx/test/libcxx/algorithms/pstl.transform_reduce.string.pass.cpp
@@ -9,11 +9,12 @@
// This test verifies that you can make string reductions with parallel
// algorithms
-// UNSUPPORTED: c++03, c++11, c++14, libcpp-has-no-incomplete-pstl
+// UNSUPPORTED: c++03, c++11, c++14
#include <algorithm>
#include <cassert>
#include <execution>
+#include <numeric>
#include <string>
#include <vector>
>From 076cac9db7e6d2f99a4ec2ded42a04e7a508bed5 Mon Sep 17 00:00:00 2001
From: AntonRydahl <rydahl2610 at gmail.com>
Date: Thu, 9 Nov 2023 23:49:26 -0800
Subject: [PATCH 11/14] Fixing C++ build bot
---
.../libcxx/algorithms/pstl.transform_reduce.string.pass.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/libcxx/test/libcxx/algorithms/pstl.transform_reduce.string.pass.cpp b/libcxx/test/libcxx/algorithms/pstl.transform_reduce.string.pass.cpp
index 483c51b6034f244d..5ddcba6386fa6867 100644
--- a/libcxx/test/libcxx/algorithms/pstl.transform_reduce.string.pass.cpp
+++ b/libcxx/test/libcxx/algorithms/pstl.transform_reduce.string.pass.cpp
@@ -9,7 +9,7 @@
// This test verifies that you can make string reductions with parallel
// algorithms
-// UNSUPPORTED: c++03, c++11, c++14
+// UNSUPPORTED: c++03, c++11, c++14, libcpp-has-no-incomplete-pstl
#include <algorithm>
#include <cassert>
>From 3ad3b3226a2e3616bb0b6bb6599481eeb4d43d5e Mon Sep 17 00:00:00 2001
From: AntonRydahl <rydahl2610 at gmail.com>
Date: Thu, 9 Nov 2023 23:51:22 -0800
Subject: [PATCH 12/14] Test only supporting C++20 and greater
---
.../libcxx/algorithms/pstl.transform_reduce.string.pass.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/libcxx/test/libcxx/algorithms/pstl.transform_reduce.string.pass.cpp b/libcxx/test/libcxx/algorithms/pstl.transform_reduce.string.pass.cpp
index 5ddcba6386fa6867..e9288e486df478b4 100644
--- a/libcxx/test/libcxx/algorithms/pstl.transform_reduce.string.pass.cpp
+++ b/libcxx/test/libcxx/algorithms/pstl.transform_reduce.string.pass.cpp
@@ -9,7 +9,7 @@
// This test verifies that you can make string reductions with parallel
// algorithms
-// UNSUPPORTED: c++03, c++11, c++14, libcpp-has-no-incomplete-pstl
+// UNSUPPORTED: c++03, c++11, c++14, c++17
#include <algorithm>
#include <cassert>
>From 56dbdd3312f5a20403a59574ac93c8330d9c83ba Mon Sep 17 00:00:00 2001
From: AntonRydahl <rydahl2610 at gmail.com>
Date: Fri, 10 Nov 2023 10:44:15 -0800
Subject: [PATCH 13/14] Adding libcpp-has-no-incomplete-pstl to test
---
.../libcxx/algorithms/pstl.transform_reduce.string.pass.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/libcxx/test/libcxx/algorithms/pstl.transform_reduce.string.pass.cpp b/libcxx/test/libcxx/algorithms/pstl.transform_reduce.string.pass.cpp
index e9288e486df478b4..7d9a10d544c16791 100644
--- a/libcxx/test/libcxx/algorithms/pstl.transform_reduce.string.pass.cpp
+++ b/libcxx/test/libcxx/algorithms/pstl.transform_reduce.string.pass.cpp
@@ -9,7 +9,7 @@
// This test verifies that you can make string reductions with parallel
// algorithms
-// UNSUPPORTED: c++03, c++11, c++14, c++17
+// UNSUPPORTED: c++03, c++11, c++14, c++17, libcpp-has-no-incomplete-pstl
#include <algorithm>
#include <cassert>
>From bd628759c7ed3101f2b8ba6bc3f8ff1203209e23 Mon Sep 17 00:00:00 2001
From: Louis Dionne <ldionne.2 at gmail.com>
Date: Tue, 21 Nov 2023 17:34:42 -0500
Subject: [PATCH 14/14] Fixup a few things. In particular I removed the test
since I don't think it was testing anything new, and in fact I failed to
write a reproducer for the transform_reduce _UnaryResult thing.
---
libcxx/include/__algorithm/comp.h | 5 +-
libcxx/include/__algorithm/equal.h | 13 ++---
.../cpu_backends/transform_reduce.h | 32 +++++------
libcxx/include/__functional/operations.h | 13 ++---
.../include/__functional/ranges_operations.h | 1 -
.../include/__type_traits/operation_traits.h | 12 +++-
.../pstl.transform_reduce.string.pass.cpp | 55 -------------------
7 files changed, 38 insertions(+), 93 deletions(-)
delete mode 100644 libcxx/test/libcxx/algorithms/pstl.transform_reduce.string.pass.cpp
diff --git a/libcxx/include/__algorithm/comp.h b/libcxx/include/__algorithm/comp.h
index 38fd284274300023..3902f7560304a125 100644
--- a/libcxx/include/__algorithm/comp.h
+++ b/libcxx/include/__algorithm/comp.h
@@ -10,7 +10,6 @@
#define _LIBCPP___ALGORITHM_COMP_H
#include <__config>
-#include <__functional/operations.h>
#include <__type_traits/integral_constant.h>
#include <__type_traits/operation_traits.h>
@@ -27,8 +26,8 @@ struct __equal_to {
}
};
-template <>
-struct __desugars_to<__equal_to, equal_to<void> > : true_type {};
+template <class _Tp, class _Up>
+struct __desugars_to<__equal_tag, __equal_to, _Tp, _Up> : true_type {};
// The definition is required because __less is part of the ABI, but it's empty
// because all comparisons should be transparent.
diff --git a/libcxx/include/__algorithm/equal.h b/libcxx/include/__algorithm/equal.h
index 7979628b7446bf9c..ca2e49ca5679a4f3 100644
--- a/libcxx/include/__algorithm/equal.h
+++ b/libcxx/include/__algorithm/equal.h
@@ -15,7 +15,6 @@
#include <__config>
#include <__functional/identity.h>
#include <__functional/invoke.h>
-#include <__functional/operations.h>
#include <__iterator/distance.h>
#include <__iterator/iterator_traits.h>
#include <__string/constexpr_c_functions.h>
@@ -42,12 +41,12 @@ _LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 boo
return true;
}
-template < class _Tp,
- class _Up,
- class _BinaryPredicate,
- __enable_if_t<__desugars_to<__equal_tag, _BinaryPredicate, _Tp, _Up>::value && !is_volatile<_Tp>::value &&
- !is_volatile<_Up>::value && __libcpp_is_trivially_equality_comparable<_Tp, _Up>::value,
- int> = 0>
+template <class _Tp,
+ class _Up,
+ class _BinaryPredicate,
+ __enable_if_t<__desugars_to<__equal_tag, _BinaryPredicate, _Tp, _Up>::value && !is_volatile<_Tp>::value &&
+ !is_volatile<_Up>::value && __libcpp_is_trivially_equality_comparable<_Tp, _Up>::value,
+ int> = 0>
_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool
__equal_iter_impl(_Tp* __first1, _Tp* __last1, _Up* __first2, _BinaryPredicate&) {
return std::__constexpr_memcmp_equal(__first1, __first2, __element_count(__last1 - __first1));
diff --git a/libcxx/include/__algorithm/pstl_backends/cpu_backends/transform_reduce.h b/libcxx/include/__algorithm/pstl_backends/cpu_backends/transform_reduce.h
index 0786d3f24cf85abe..ab2e3172b8b63bd2 100644
--- a/libcxx/include/__algorithm/pstl_backends/cpu_backends/transform_reduce.h
+++ b/libcxx/include/__algorithm/pstl_backends/cpu_backends/transform_reduce.h
@@ -11,7 +11,6 @@
#include <__algorithm/pstl_backends/cpu_backends/backend.h>
#include <__config>
-#include <__functional/operations.h>
#include <__iterator/concepts.h>
#include <__iterator/iterator_traits.h>
#include <__numeric/transform_reduce.h>
@@ -30,13 +29,14 @@
_LIBCPP_BEGIN_NAMESPACE_STD
-template < typename _DifferenceType,
- typename _Tp,
- typename _BinaryOperation,
- typename _UnaryOperation,
- typename _UnaryResult = invoke_result_t<_UnaryOperation, _DifferenceType>,
- __enable_if_t<__desugars_to<__plus_tag, _BinaryOperation, _Tp, _UnaryResult>::value && is_arithmetic_v<_Tp>,
- int> = 0>
+template <typename _DifferenceType,
+ typename _Tp,
+ typename _BinaryOperation,
+ typename _UnaryOperation,
+ typename _UnaryResult = invoke_result_t<_UnaryOperation, _DifferenceType>,
+ __enable_if_t<__desugars_to<__plus_tag, _BinaryOperation, _Tp, _UnaryResult>::value && is_arithmetic_v<_Tp> &&
+ is_arithmetic_v<_UnaryResult>,
+ int> = 0>
_LIBCPP_HIDE_FROM_ABI _Tp
__simd_transform_reduce(_DifferenceType __n, _Tp __init, _BinaryOperation, _UnaryOperation __f) noexcept {
_PSTL_PRAGMA_SIMD_REDUCTION(+ : __init)
@@ -45,14 +45,14 @@ __simd_transform_reduce(_DifferenceType __n, _Tp __init, _BinaryOperation, _Unar
return __init;
}
-template <
- typename _Size,
- typename _Tp,
- typename _BinaryOperation,
- typename _UnaryOperation,
- typename _UnaryResult = invoke_result_t<_UnaryOperation, _Size>,
- __enable_if_t<!(__desugars_to<__plus_tag, _BinaryOperation, _Tp, _UnaryResult>::value && is_arithmetic_v<_Tp>),
- int> = 0>
+template <typename _Size,
+ typename _Tp,
+ typename _BinaryOperation,
+ typename _UnaryOperation,
+ typename _UnaryResult = invoke_result_t<_UnaryOperation, _Size>,
+ __enable_if_t<!(__desugars_to<__plus_tag, _BinaryOperation, _Tp, _UnaryResult>::value &&
+ is_arithmetic_v<_Tp> && is_arithmetic_v<_UnaryResult>),
+ int> = 0>
_LIBCPP_HIDE_FROM_ABI _Tp
__simd_transform_reduce(_Size __n, _Tp __init, _BinaryOperation __binary_op, _UnaryOperation __f) noexcept {
const _Size __block_size = __lane_size / sizeof(_Tp);
diff --git a/libcxx/include/__functional/operations.h b/libcxx/include/__functional/operations.h
index 30554d97ab238ffc..9812ccf8e4136ff6 100644
--- a/libcxx/include/__functional/operations.h
+++ b/libcxx/include/__functional/operations.h
@@ -40,16 +40,13 @@ struct _LIBCPP_TEMPLATE_VIS plus
};
_LIBCPP_CTAD_SUPPORTED_FOR_TYPE(plus);
-// For the typed version of plus, we require that the left- and right-hand
-// side of the plus operator matches
+// The non-transparent std::plus specialization is only equivalent to a raw plus
+// operator when we don't perform an implicit conversion when calling it.
template <class _Tp>
struct __desugars_to<__plus_tag, plus<_Tp>, _Tp, _Tp> : true_type {};
-#if _LIBCPP_STD_VER >= 14
-// In the transparent case, we do not enforce that
template <class _Tp, class _Up>
struct __desugars_to<__plus_tag, plus<void>, _Tp, _Up> : true_type {};
-#endif
#if _LIBCPP_STD_VER >= 14
template <>
@@ -354,16 +351,14 @@ struct _LIBCPP_TEMPLATE_VIS equal_to<void>
};
#endif
-// For the typed version of equal_to, we require that the left- and right-hand
-// side of the equality operator matches
+// The non-transparent std::equal_to specialization is only equivalent to a raw equality
+// comparison when we don't perform an implicit conversion when calling it.
template <class _Tp>
struct __desugars_to<__equal_tag, equal_to<_Tp>, _Tp, _Tp> : true_type {};
-#if _LIBCPP_STD_VER >= 14
// In the transparent case, we do not enforce that
template <class _Tp, class _Up>
struct __desugars_to<__equal_tag, equal_to<void>, _Tp, _Up> : true_type {};
-#endif
#if _LIBCPP_STD_VER >= 14
template <class _Tp = void>
diff --git a/libcxx/include/__functional/ranges_operations.h b/libcxx/include/__functional/ranges_operations.h
index eee3442a3ef0e8f7..b54589f8c0d8792f 100644
--- a/libcxx/include/__functional/ranges_operations.h
+++ b/libcxx/include/__functional/ranges_operations.h
@@ -13,7 +13,6 @@
#include <__concepts/equality_comparable.h>
#include <__concepts/totally_ordered.h>
#include <__config>
-#include <__functional/operations.h>
#include <__type_traits/integral_constant.h>
#include <__type_traits/operation_traits.h>
#include <__utility/forward.h>
diff --git a/libcxx/include/__type_traits/operation_traits.h b/libcxx/include/__type_traits/operation_traits.h
index 5774e14ab091200c..ef6e71693430d01a 100644
--- a/libcxx/include/__type_traits/operation_traits.h
+++ b/libcxx/include/__type_traits/operation_traits.h
@@ -22,8 +22,16 @@ _LIBCPP_BEGIN_NAMESPACE_STD
struct __equal_tag {};
struct __plus_tag {};
-// In the general case, __desugars_to is false
-
+// This class template is used to determine whether an operation "desugars"
+// (or boils down) to a given canonical operation.
+//
+// For example, `std::equal_to<>`, our internal `std::__equal_to` helper and
+// `ranges::equal_to` are all just fancy ways of representing a transparent
+// equality operation, so they all desugar to `__equal_tag`.
+//
+// This is useful to optimize some functions in cases where we know e.g. the
+// predicate being passed is actually going to call a builtin operator, or has
+// some specific semantics.
template <class _CanonicalTag, class _Operation, class... _Args>
struct __desugars_to : false_type {};
diff --git a/libcxx/test/libcxx/algorithms/pstl.transform_reduce.string.pass.cpp b/libcxx/test/libcxx/algorithms/pstl.transform_reduce.string.pass.cpp
deleted file mode 100644
index 7d9a10d544c16791..0000000000000000
--- a/libcxx/test/libcxx/algorithms/pstl.transform_reduce.string.pass.cpp
+++ /dev/null
@@ -1,55 +0,0 @@
-//===----------------------------------------------------------------------===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-// This test verifies that you can make string reductions with parallel
-// algorithms
-
-// UNSUPPORTED: c++03, c++11, c++14, c++17, libcpp-has-no-incomplete-pstl
-
-#include <algorithm>
-#include <cassert>
-#include <execution>
-#include <numeric>
-#include <string>
-#include <vector>
-
-template <class Execution, class Input>
-void test_execution_policy(Execution& execution, Input& input) {
- std::string result = std::transform_reduce(
- execution, input.begin(), input.end(), (std::string) "", std::plus{}, [](std::string& str) { return str; });
- for (auto v : input) {
- assert(result.find(v) != std::string::npos && "Substring not found in reduuced string.");
- }
-}
-
-int main(int, char**) {
- int length = 10000;
- std::vector<std::string> vec(length);
-
- // Generating semi-random strings of length 5
- unsigned int seed = 17;
- for (int i = 0; i < length; i++) {
- std::string str = "";
- char a;
- for (int j = 0; j < 5; j++) {
- // Generating random unsigned int with a linear congruential generator
- seed = (214013 * seed + 11) % 4294967295;
-
- // Generating ASCII character from 33 (!) to 126 (~)
- a = ((unsigned int)33 + (seed % 93));
- str += a;
- }
- vec[i] = str;
- }
-
- test_execution_policy(std::execution::seq, vec);
- test_execution_policy(std::execution::unseq, vec);
- test_execution_policy(std::execution::par, vec);
- test_execution_policy(std::execution::par_unseq, vec);
- return 0;
-}
\ No newline at end of file
More information about the libcxx-commits
mailing list