Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[libcxx] Unifying __is_trivial_equality_predicate and __is_trivial_plus_operation into __desugars_to #68642

Merged
merged 14 commits into from
Nov 23, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion libcxx/include/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
6 changes: 3 additions & 3 deletions libcxx/include/__algorithm/comp.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@

#include <__config>
#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
Expand All @@ -26,8 +26,8 @@ struct __equal_to {
}
};

template <class _Lhs, class _Rhs>
struct __is_trivial_equality_predicate<__equal_to, _Lhs, _Rhs> : 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.
Expand Down
21 changes: 10 additions & 11 deletions libcxx/include/__algorithm/equal.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,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)
Expand All @@ -41,13 +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<__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<__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));
Expand Down Expand Up @@ -94,12 +93,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<__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>
_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));
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,12 +29,14 @@

_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,
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)
Expand All @@ -43,12 +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<!(__is_trivial_plus_operation<_BinaryOperation, _Tp, _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> && 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);
Expand Down
20 changes: 10 additions & 10 deletions libcxx/include/__functional/operations.h
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -41,13 +40,13 @@ struct _LIBCPP_TEMPLATE_VIS plus
};
_LIBCPP_CTAD_SUPPORTED_FOR_TYPE(plus);

// 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 __is_trivial_plus_operation<plus<_Tp>, _Tp, _Tp> : true_type {};
struct __desugars_to<__plus_tag, plus<_Tp>, _Tp, _Tp> : true_type {};

#if _LIBCPP_STD_VER >= 14
template <class _Tp, class _Up>
struct __is_trivial_plus_operation<plus<>, _Tp, _Up> : true_type {};
#endif
struct __desugars_to<__plus_tag, plus<void>, _Tp, _Up> : true_type {};

#if _LIBCPP_STD_VER >= 14
template <>
Expand Down Expand Up @@ -352,13 +351,14 @@ struct _LIBCPP_TEMPLATE_VIS equal_to<void>
};
#endif

// 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 __is_trivial_equality_predicate<equal_to<_Tp>, _Tp, _Tp> : true_type {};
struct __desugars_to<__equal_tag, equal_to<_Tp>, _Tp, _Tp> : true_type {};

#if _LIBCPP_STD_VER >= 14
template <class _Tp>
struct __is_trivial_equality_predicate<equal_to<>, _Tp, _Tp> : true_type {};
#endif
// 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 {};

#if _LIBCPP_STD_VER >= 14
template <class _Tp = void>
Expand Down
8 changes: 5 additions & 3 deletions libcxx/include/__functional/ranges_operations.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
#include <__concepts/totally_ordered.h>
#include <__config>
#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)
Expand Down Expand Up @@ -95,8 +95,10 @@ struct greater_equal {

} // namespace ranges

template <class _Lhs, class _Rhs>
struct __is_trivial_equality_predicate<ranges::equal_to, _Lhs, _Rhs> : 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

Expand Down
2 changes: 1 addition & 1 deletion libcxx/include/__numeric/pstl_transform_reduce.h
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
18 changes: 16 additions & 2 deletions libcxx/include/__type_traits/operation_traits.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,22 @@

_LIBCPP_BEGIN_NAMESPACE_STD

template <class _Pred, class _Lhs, class _Rhs>
struct __is_trivial_plus_operation : false_type {};
// Tags to represent the canonical operations
struct __equal_tag {};
struct __plus_tag {};

// 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 {};

_LIBCPP_END_NAMESPACE_STD

Expand Down
26 changes: 0 additions & 26 deletions libcxx/include/__type_traits/predicate_traits.h

This file was deleted.

1 change: 0 additions & 1 deletion libcxx/include/module.modulemap.in
Original file line number Diff line number Diff line change
Expand Up @@ -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" }
Expand Down
Loading