14038c859SNikolas Klauser //===----------------------------------------------------------------------===// 24038c859SNikolas Klauser // 34038c859SNikolas Klauser // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 44038c859SNikolas Klauser // See https://llvm.org/LICENSE.txt for license information. 54038c859SNikolas Klauser // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 64038c859SNikolas Klauser // 74038c859SNikolas Klauser //===----------------------------------------------------------------------===// 84038c859SNikolas Klauser 94038c859SNikolas Klauser #ifndef _LIBCPP___ALGORITHM_RANGES_IS_PERMUTATION_H 104038c859SNikolas Klauser #define _LIBCPP___ALGORITHM_RANGES_IS_PERMUTATION_H 114038c859SNikolas Klauser 124038c859SNikolas Klauser #include <__algorithm/is_permutation.h> 134038c859SNikolas Klauser #include <__algorithm/iterator_operations.h> 144038c859SNikolas Klauser #include <__config> 154038c859SNikolas Klauser #include <__functional/identity.h> 164038c859SNikolas Klauser #include <__functional/ranges_operations.h> 174038c859SNikolas Klauser #include <__iterator/concepts.h> 184038c859SNikolas Klauser #include <__iterator/distance.h> 194038c859SNikolas Klauser #include <__iterator/projected.h> 204038c859SNikolas Klauser #include <__ranges/access.h> 214038c859SNikolas Klauser #include <__ranges/concepts.h> 224038c859SNikolas Klauser #include <__utility/move.h> 234038c859SNikolas Klauser 244038c859SNikolas Klauser #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) 254038c859SNikolas Klauser # pragma GCC system_header 264038c859SNikolas Klauser #endif 274038c859SNikolas Klauser 287b462251SLouis Dionne _LIBCPP_PUSH_MACROS 297b462251SLouis Dionne #include <__undef_macros> 307b462251SLouis Dionne 314f15267dSNikolas Klauser #if _LIBCPP_STD_VER >= 20 324038c859SNikolas Klauser 334038c859SNikolas Klauser _LIBCPP_BEGIN_NAMESPACE_STD 344038c859SNikolas Klauser 354038c859SNikolas Klauser namespace ranges { 36*d10dc5a0SChristopher Di Bella struct __is_permutation { 375aa03b64SLouis Dionne template <class _Iter1, class _Sent1, class _Iter2, class _Sent2, class _Proj1, class _Proj2, class _Pred> 385aa03b64SLouis Dionne _LIBCPP_HIDE_FROM_ABI constexpr static bool __is_permutation_func_impl( 395aa03b64SLouis Dionne _Iter1 __first1, 405aa03b64SLouis Dionne _Sent1 __last1, 415aa03b64SLouis Dionne _Iter2 __first2, 425aa03b64SLouis Dionne _Sent2 __last2, 435aa03b64SLouis Dionne _Pred& __pred, 445aa03b64SLouis Dionne _Proj1& __proj1, 455aa03b64SLouis Dionne _Proj2& __proj2) { 464038c859SNikolas Klauser return std::__is_permutation<_RangeAlgPolicy>( 475aa03b64SLouis Dionne std::move(__first1), std::move(__last1), std::move(__first2), std::move(__last2), __pred, __proj1, __proj2); 484038c859SNikolas Klauser } 494038c859SNikolas Klauser 505aa03b64SLouis Dionne template < 515aa03b64SLouis Dionne forward_iterator _Iter1, 525aa03b64SLouis Dionne sentinel_for<_Iter1> _Sent1, 535aa03b64SLouis Dionne forward_iterator _Iter2, 545aa03b64SLouis Dionne sentinel_for<_Iter2> _Sent2, 554038c859SNikolas Klauser class _Proj1 = identity, 564038c859SNikolas Klauser class _Proj2 = identity, 575aa03b64SLouis Dionne indirect_equivalence_relation<projected<_Iter1, _Proj1>, projected<_Iter2, _Proj2>> _Pred = ranges::equal_to> 5883bc7b57SNikolas Klauser [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool operator()( 595aa03b64SLouis Dionne _Iter1 __first1, 605aa03b64SLouis Dionne _Sent1 __last1, 615aa03b64SLouis Dionne _Iter2 __first2, 625aa03b64SLouis Dionne _Sent2 __last2, 635aa03b64SLouis Dionne _Pred __pred = {}, 645aa03b64SLouis Dionne _Proj1 __proj1 = {}, 655aa03b64SLouis Dionne _Proj2 __proj2 = {}) const { 664038c859SNikolas Klauser return __is_permutation_func_impl( 675aa03b64SLouis Dionne std::move(__first1), std::move(__last1), std::move(__first2), std::move(__last2), __pred, __proj1, __proj2); 684038c859SNikolas Klauser } 694038c859SNikolas Klauser 704038c859SNikolas Klauser template <forward_range _Range1, 714038c859SNikolas Klauser forward_range _Range2, 724038c859SNikolas Klauser class _Proj1 = identity, 734038c859SNikolas Klauser class _Proj2 = identity, 745aa03b64SLouis Dionne indirect_equivalence_relation<projected<iterator_t<_Range1>, _Proj1>, 755aa03b64SLouis Dionne projected<iterator_t<_Range2>, _Proj2>> _Pred = ranges::equal_to> 7683bc7b57SNikolas Klauser [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool operator()( 775aa03b64SLouis Dionne _Range1&& __range1, _Range2&& __range2, _Pred __pred = {}, _Proj1 __proj1 = {}, _Proj2 __proj2 = {}) const { 784038c859SNikolas Klauser if constexpr (sized_range<_Range1> && sized_range<_Range2>) { 794038c859SNikolas Klauser if (ranges::distance(__range1) != ranges::distance(__range2)) 804038c859SNikolas Klauser return false; 814038c859SNikolas Klauser } 824038c859SNikolas Klauser 834038c859SNikolas Klauser return __is_permutation_func_impl( 845aa03b64SLouis Dionne ranges::begin(__range1), 855aa03b64SLouis Dionne ranges::end(__range1), 865aa03b64SLouis Dionne ranges::begin(__range2), 875aa03b64SLouis Dionne ranges::end(__range2), 885aa03b64SLouis Dionne __pred, 895aa03b64SLouis Dionne __proj1, 905aa03b64SLouis Dionne __proj2); 914038c859SNikolas Klauser } 924038c859SNikolas Klauser }; 934038c859SNikolas Klauser 944038c859SNikolas Klauser inline namespace __cpo { 95*d10dc5a0SChristopher Di Bella inline constexpr auto is_permutation = __is_permutation{}; 964038c859SNikolas Klauser } // namespace __cpo 974038c859SNikolas Klauser } // namespace ranges 984038c859SNikolas Klauser 994038c859SNikolas Klauser _LIBCPP_END_NAMESPACE_STD 1004038c859SNikolas Klauser 1014f15267dSNikolas Klauser #endif // _LIBCPP_STD_VER >= 20 1024038c859SNikolas Klauser 1037b462251SLouis Dionne _LIBCPP_POP_MACROS 1047b462251SLouis Dionne 1054038c859SNikolas Klauser #endif // _LIBCPP___ALGORITHM_RANGES_IS_PERMUTATION_H 106