1//===----------------------------------------------------------------------===// 2// 3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4// See https://llvm.org/LICENSE.txt for license information. 5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6// 7//===----------------------------------------------------------------------===// 8 9#ifndef _LIBCPP___ALGORITHM_PSTL_EQUAL_H 10#define _LIBCPP___ALGORITHM_PSTL_EQUAL_H 11 12#include <__algorithm/equal.h> 13#include <__algorithm/pstl_frontend_dispatch.h> 14#include <__config> 15#include <__functional/operations.h> 16#include <__iterator/iterator_traits.h> 17#include <__numeric/pstl_transform_reduce.h> 18#include <__utility/move.h> 19 20#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) 21# pragma GCC system_header 22#endif 23 24_LIBCPP_PUSH_MACROS 25#include <__undef_macros> 26 27#if !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17 28 29_LIBCPP_BEGIN_NAMESPACE_STD 30 31template <class> 32void __pstl_equal(); 33 34template <class _ExecutionPolicy, 35 class _ForwardIterator1, 36 class _ForwardIterator2, 37 class _Pred, 38 class _RawPolicy = __remove_cvref_t<_ExecutionPolicy>, 39 enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0> 40[[nodiscard]] _LIBCPP_HIDE_FROM_ABI optional<bool> 41__equal(_ExecutionPolicy&& __policy, 42 _ForwardIterator1&& __first1, 43 _ForwardIterator1&& __last1, 44 _ForwardIterator2&& __first2, 45 _Pred&& __pred) noexcept { 46 return std::__pstl_frontend_dispatch( 47 _LIBCPP_PSTL_CUSTOMIZATION_POINT(__pstl_equal, _RawPolicy), 48 [&__policy]( 49 _ForwardIterator1 __g_first1, _ForwardIterator1 __g_last1, _ForwardIterator2 __g_first2, _Pred __g_pred) { 50 return std::__transform_reduce( 51 __policy, 52 std::move(__g_first1), 53 std::move(__g_last1), 54 std::move(__g_first2), 55 true, 56 std::logical_and{}, 57 std::move(__g_pred)); 58 }, 59 std::move(__first1), 60 std::move(__last1), 61 std::move(__first2), 62 std::move(__pred)); 63} 64 65template <class _ExecutionPolicy, 66 class _ForwardIterator1, 67 class _ForwardIterator2, 68 class _Pred, 69 class _RawPolicy = __remove_cvref_t<_ExecutionPolicy>, 70 enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0> 71_LIBCPP_HIDE_FROM_ABI bool 72equal(_ExecutionPolicy&& __policy, 73 _ForwardIterator1 __first1, 74 _ForwardIterator1 __last1, 75 _ForwardIterator2 __first2, 76 _Pred __pred) { 77 auto __res = std::__equal(__policy, std::move(__first1), std::move(__last1), std::move(__first2), std::move(__pred)); 78 if (!__res) 79 std::__throw_bad_alloc(); 80 return *__res; 81} 82 83template <class _ExecutionPolicy, 84 class _ForwardIterator1, 85 class _ForwardIterator2, 86 enable_if_t<is_execution_policy_v<__remove_cvref_t<_ExecutionPolicy>>, int> = 0> 87_LIBCPP_HIDE_FROM_ABI bool 88equal(_ExecutionPolicy&& __policy, _ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2) { 89 return std::equal(__policy, std::move(__first1), std::move(__last1), std::move(__first2), std::equal_to{}); 90} 91 92template <class _ExecutionPolicy, 93 class _ForwardIterator1, 94 class _ForwardIterator2, 95 class _Pred, 96 class _RawPolicy = __remove_cvref_t<_ExecutionPolicy>, 97 enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0> 98[[nodiscard]] _LIBCPP_HIDE_FROM_ABI optional<bool> 99__equal(_ExecutionPolicy&& __policy, 100 _ForwardIterator1&& __first1, 101 _ForwardIterator1&& __last1, 102 _ForwardIterator2&& __first2, 103 _ForwardIterator2&& __last2, 104 _Pred&& __pred) noexcept { 105 return std::__pstl_frontend_dispatch( 106 _LIBCPP_PSTL_CUSTOMIZATION_POINT(__pstl_equal, _RawPolicy), 107 [&__policy](_ForwardIterator1 __g_first1, 108 _ForwardIterator1 __g_last1, 109 _ForwardIterator2 __g_first2, 110 _ForwardIterator2 __g_last2, 111 _Pred __g_pred) -> optional<bool> { 112 if constexpr (__has_random_access_iterator_category<_ForwardIterator1>::value && 113 __has_random_access_iterator_category<_ForwardIterator2>::value) { 114 if (__g_last1 - __g_first1 != __g_last2 - __g_first2) 115 return false; 116 return std::__equal( 117 __policy, std::move(__g_first1), std::move(__g_last1), std::move(__g_first2), std::move(__g_pred)); 118 } else { 119 (void)__policy; // Avoid unused lambda capture warning 120 return std::equal( 121 std::move(__g_first1), 122 std::move(__g_last1), 123 std::move(__g_first2), 124 std::move(__g_last2), 125 std::move(__g_pred)); 126 } 127 }, 128 std::move(__first1), 129 std::move(__last1), 130 std::move(__first2), 131 std::move(__last2), 132 std::move(__pred)); 133} 134 135template <class _ExecutionPolicy, 136 class _ForwardIterator1, 137 class _ForwardIterator2, 138 class _Pred, 139 class _RawPolicy = __remove_cvref_t<_ExecutionPolicy>, 140 enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0> 141_LIBCPP_HIDE_FROM_ABI bool 142equal(_ExecutionPolicy&& __policy, 143 _ForwardIterator1 __first1, 144 _ForwardIterator1 __last1, 145 _ForwardIterator2 __first2, 146 _ForwardIterator2 __last2, 147 _Pred __pred) { 148 auto __res = std::__equal( 149 __policy, std::move(__first1), std::move(__last1), std::move(__first2), std::move(__last2), std::move(__pred)); 150 if (!__res) 151 std::__throw_bad_alloc(); 152 return *__res; 153} 154 155template <class _ExecutionPolicy, 156 class _ForwardIterator1, 157 class _ForwardIterator2, 158 enable_if_t<is_execution_policy_v<__remove_cvref_t<_ExecutionPolicy>>, int> = 0> 159_LIBCPP_HIDE_FROM_ABI bool 160equal(_ExecutionPolicy&& __policy, 161 _ForwardIterator1 __first1, 162 _ForwardIterator1 __last1, 163 _ForwardIterator2 __first2, 164 _ForwardIterator2 __last2) { 165 return std::equal( 166 __policy, std::move(__first1), std::move(__last1), std::move(__first2), std::move(__last2), std::equal_to{}); 167} 168 169_LIBCPP_END_NAMESPACE_STD 170 171#endif // !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17 172 173_LIBCPP_POP_MACROS 174 175#endif // _LIBCPP___ALGORITHM_PSTL_EQUAL_H 176