xref: /llvm-project/libcxx/include/__algorithm/ranges_is_permutation.h (revision d10dc5a06fac4dcabf2264c64c8672c6f6ae36fb)
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