1569d6630SNikolas Klauser //===----------------------------------------------------------------------===// 2569d6630SNikolas Klauser // 3569d6630SNikolas Klauser // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4569d6630SNikolas Klauser // See https://llvm.org/LICENSE.txt for license information. 5569d6630SNikolas Klauser // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6569d6630SNikolas Klauser // 7569d6630SNikolas Klauser //===----------------------------------------------------------------------===// 8569d6630SNikolas Klauser 9569d6630SNikolas Klauser #ifndef _LIBCPP___ALGORITHM_RANGES_EQUAL_H 10569d6630SNikolas Klauser #define _LIBCPP___ALGORITHM_RANGES_EQUAL_H 11569d6630SNikolas Klauser 12b4ecfd3cSNikolas Klauser #include <__algorithm/equal.h> 13b4ecfd3cSNikolas Klauser #include <__algorithm/unwrap_range.h> 14569d6630SNikolas Klauser #include <__config> 15569d6630SNikolas Klauser #include <__functional/identity.h> 16569d6630SNikolas Klauser #include <__functional/invoke.h> 17569d6630SNikolas Klauser #include <__functional/ranges_operations.h> 18569d6630SNikolas Klauser #include <__iterator/concepts.h> 19569d6630SNikolas Klauser #include <__iterator/distance.h> 20569d6630SNikolas Klauser #include <__iterator/indirectly_comparable.h> 21569d6630SNikolas Klauser #include <__ranges/access.h> 22569d6630SNikolas Klauser #include <__ranges/concepts.h> 23569d6630SNikolas Klauser #include <__utility/move.h> 24569d6630SNikolas Klauser 25569d6630SNikolas Klauser #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) 26569d6630SNikolas Klauser # pragma GCC system_header 27569d6630SNikolas Klauser #endif 28569d6630SNikolas Klauser 297b462251SLouis Dionne _LIBCPP_PUSH_MACROS 307b462251SLouis Dionne #include <__undef_macros> 317b462251SLouis Dionne 324f15267dSNikolas Klauser #if _LIBCPP_STD_VER >= 20 33569d6630SNikolas Klauser 34569d6630SNikolas Klauser _LIBCPP_BEGIN_NAMESPACE_STD 35569d6630SNikolas Klauser 36569d6630SNikolas Klauser namespace ranges { 37*d10dc5a0SChristopher Di Bella struct __equal { 385aa03b64SLouis Dionne template <input_iterator _Iter1, 395aa03b64SLouis Dionne sentinel_for<_Iter1> _Sent1, 405aa03b64SLouis Dionne input_iterator _Iter2, 415aa03b64SLouis Dionne sentinel_for<_Iter2> _Sent2, 42569d6630SNikolas Klauser class _Pred = ranges::equal_to, 43569d6630SNikolas Klauser class _Proj1 = identity, 44569d6630SNikolas Klauser class _Proj2 = identity> 45569d6630SNikolas Klauser requires indirectly_comparable<_Iter1, _Iter2, _Pred, _Proj1, _Proj2> 4683bc7b57SNikolas Klauser [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool operator()( 475aa03b64SLouis Dionne _Iter1 __first1, 485aa03b64SLouis Dionne _Sent1 __last1, 495aa03b64SLouis Dionne _Iter2 __first2, 505aa03b64SLouis Dionne _Sent2 __last2, 51569d6630SNikolas Klauser _Pred __pred = {}, 52569d6630SNikolas Klauser _Proj1 __proj1 = {}, 53569d6630SNikolas Klauser _Proj2 __proj2 = {}) const { 54569d6630SNikolas Klauser if constexpr (sized_sentinel_for<_Sent1, _Iter1> && sized_sentinel_for<_Sent2, _Iter2>) { 55569d6630SNikolas Klauser if (__last1 - __first1 != __last2 - __first2) 56569d6630SNikolas Klauser return false; 57569d6630SNikolas Klauser } 58b4ecfd3cSNikolas Klauser auto __unwrapped1 = std::__unwrap_range(std::move(__first1), std::move(__last1)); 59b4ecfd3cSNikolas Klauser auto __unwrapped2 = std::__unwrap_range(std::move(__first2), std::move(__last2)); 605aa03b64SLouis Dionne return std::__equal_impl( 615aa03b64SLouis Dionne std::move(__unwrapped1.first), 625aa03b64SLouis Dionne std::move(__unwrapped1.second), 635aa03b64SLouis Dionne std::move(__unwrapped2.first), 645aa03b64SLouis Dionne std::move(__unwrapped2.second), 65569d6630SNikolas Klauser __pred, 66569d6630SNikolas Klauser __proj1, 67569d6630SNikolas Klauser __proj2); 68569d6630SNikolas Klauser } 69569d6630SNikolas Klauser 70569d6630SNikolas Klauser template <input_range _Range1, 71569d6630SNikolas Klauser input_range _Range2, 72569d6630SNikolas Klauser class _Pred = ranges::equal_to, 73569d6630SNikolas Klauser class _Proj1 = identity, 74569d6630SNikolas Klauser class _Proj2 = identity> 75569d6630SNikolas Klauser requires indirectly_comparable<iterator_t<_Range1>, iterator_t<_Range2>, _Pred, _Proj1, _Proj2> 7683bc7b57SNikolas Klauser [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool operator()( 775aa03b64SLouis Dionne _Range1&& __range1, _Range2&& __range2, _Pred __pred = {}, _Proj1 __proj1 = {}, _Proj2 __proj2 = {}) const { 78569d6630SNikolas Klauser if constexpr (sized_range<_Range1> && sized_range<_Range2>) { 79569d6630SNikolas Klauser if (ranges::distance(__range1) != ranges::distance(__range2)) 80569d6630SNikolas Klauser return false; 81569d6630SNikolas Klauser } 82b4ecfd3cSNikolas Klauser auto __unwrapped1 = std::__unwrap_range(ranges::begin(__range1), ranges::end(__range1)); 83b4ecfd3cSNikolas Klauser auto __unwrapped2 = std::__unwrap_range(ranges::begin(__range2), ranges::end(__range2)); 845aa03b64SLouis Dionne return std::__equal_impl( 855aa03b64SLouis Dionne std::move(__unwrapped1.first), 865aa03b64SLouis Dionne std::move(__unwrapped1.second), 875aa03b64SLouis Dionne std::move(__unwrapped2.first), 885aa03b64SLouis Dionne std::move(__unwrapped2.second), 89569d6630SNikolas Klauser __pred, 90569d6630SNikolas Klauser __proj1, 91569d6630SNikolas Klauser __proj2); 92569d6630SNikolas Klauser return false; 93569d6630SNikolas Klauser } 94569d6630SNikolas Klauser }; 95569d6630SNikolas Klauser 96569d6630SNikolas Klauser inline namespace __cpo { 97*d10dc5a0SChristopher Di Bella inline constexpr auto equal = __equal{}; 98569d6630SNikolas Klauser } // namespace __cpo 99569d6630SNikolas Klauser } // namespace ranges 100569d6630SNikolas Klauser 101569d6630SNikolas Klauser _LIBCPP_END_NAMESPACE_STD 102569d6630SNikolas Klauser 1034f15267dSNikolas Klauser #endif // _LIBCPP_STD_VER >= 20 104569d6630SNikolas Klauser 1057b462251SLouis Dionne _LIBCPP_POP_MACROS 1067b462251SLouis Dionne 107569d6630SNikolas Klauser #endif // _LIBCPP___ALGORITHM_RANGES_EQUAL_H 108