161cfbce3SDimitry Andric //===----------------------------------------------------------------------===// 261cfbce3SDimitry Andric // 361cfbce3SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 461cfbce3SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 561cfbce3SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 661cfbce3SDimitry Andric // 761cfbce3SDimitry Andric //===----------------------------------------------------------------------===// 861cfbce3SDimitry Andric 961cfbce3SDimitry Andric #ifndef _LIBCPP___ALGORITHM_RANGES_IS_PERMUTATION_H 1061cfbce3SDimitry Andric #define _LIBCPP___ALGORITHM_RANGES_IS_PERMUTATION_H 1161cfbce3SDimitry Andric 1261cfbce3SDimitry Andric #include <__algorithm/is_permutation.h> 1361cfbce3SDimitry Andric #include <__algorithm/iterator_operations.h> 1461cfbce3SDimitry Andric #include <__config> 1561cfbce3SDimitry Andric #include <__functional/identity.h> 1661cfbce3SDimitry Andric #include <__functional/ranges_operations.h> 1761cfbce3SDimitry Andric #include <__iterator/concepts.h> 1861cfbce3SDimitry Andric #include <__iterator/distance.h> 1961cfbce3SDimitry Andric #include <__iterator/projected.h> 2061cfbce3SDimitry Andric #include <__ranges/access.h> 2161cfbce3SDimitry Andric #include <__ranges/concepts.h> 2261cfbce3SDimitry Andric #include <__utility/move.h> 2361cfbce3SDimitry Andric 2461cfbce3SDimitry Andric #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) 2561cfbce3SDimitry Andric # pragma GCC system_header 2661cfbce3SDimitry Andric #endif 2761cfbce3SDimitry Andric 28b3edf446SDimitry Andric _LIBCPP_PUSH_MACROS 29b3edf446SDimitry Andric #include <__undef_macros> 30b3edf446SDimitry Andric 3106c3fb27SDimitry Andric #if _LIBCPP_STD_VER >= 20 3261cfbce3SDimitry Andric 3361cfbce3SDimitry Andric _LIBCPP_BEGIN_NAMESPACE_STD 3461cfbce3SDimitry Andric 3561cfbce3SDimitry Andric namespace ranges { 3661cfbce3SDimitry Andric namespace __is_permutation { 3761cfbce3SDimitry Andric struct __fn { 3806c3fb27SDimitry Andric template <class _Iter1, class _Sent1, class _Iter2, class _Sent2, class _Proj1, class _Proj2, class _Pred> 3906c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr static bool __is_permutation_func_impl( 4006c3fb27SDimitry Andric _Iter1 __first1, 4106c3fb27SDimitry Andric _Sent1 __last1, 4206c3fb27SDimitry Andric _Iter2 __first2, 4306c3fb27SDimitry Andric _Sent2 __last2, 4406c3fb27SDimitry Andric _Pred& __pred, 4506c3fb27SDimitry Andric _Proj1& __proj1, 4606c3fb27SDimitry Andric _Proj2& __proj2) { 4761cfbce3SDimitry Andric return std::__is_permutation<_RangeAlgPolicy>( 4806c3fb27SDimitry Andric std::move(__first1), std::move(__last1), std::move(__first2), std::move(__last2), __pred, __proj1, __proj2); 4961cfbce3SDimitry Andric } 5061cfbce3SDimitry Andric 5106c3fb27SDimitry Andric template < 5206c3fb27SDimitry Andric forward_iterator _Iter1, 5306c3fb27SDimitry Andric sentinel_for<_Iter1> _Sent1, 5406c3fb27SDimitry Andric forward_iterator _Iter2, 5506c3fb27SDimitry Andric sentinel_for<_Iter2> _Sent2, 5661cfbce3SDimitry Andric class _Proj1 = identity, 5761cfbce3SDimitry Andric class _Proj2 = identity, 5806c3fb27SDimitry Andric indirect_equivalence_relation<projected<_Iter1, _Proj1>, projected<_Iter2, _Proj2>> _Pred = ranges::equal_to> 59*0fca6ea1SDimitry Andric [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool operator()( 6006c3fb27SDimitry Andric _Iter1 __first1, 6106c3fb27SDimitry Andric _Sent1 __last1, 6206c3fb27SDimitry Andric _Iter2 __first2, 6306c3fb27SDimitry Andric _Sent2 __last2, 6406c3fb27SDimitry Andric _Pred __pred = {}, 6506c3fb27SDimitry Andric _Proj1 __proj1 = {}, 6606c3fb27SDimitry Andric _Proj2 __proj2 = {}) const { 6761cfbce3SDimitry Andric return __is_permutation_func_impl( 6806c3fb27SDimitry Andric std::move(__first1), std::move(__last1), std::move(__first2), std::move(__last2), __pred, __proj1, __proj2); 6961cfbce3SDimitry Andric } 7061cfbce3SDimitry Andric 7161cfbce3SDimitry Andric template <forward_range _Range1, 7261cfbce3SDimitry Andric forward_range _Range2, 7361cfbce3SDimitry Andric class _Proj1 = identity, 7461cfbce3SDimitry Andric class _Proj2 = identity, 7506c3fb27SDimitry Andric indirect_equivalence_relation<projected<iterator_t<_Range1>, _Proj1>, 7606c3fb27SDimitry Andric projected<iterator_t<_Range2>, _Proj2>> _Pred = ranges::equal_to> 77*0fca6ea1SDimitry Andric [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool operator()( 7806c3fb27SDimitry Andric _Range1&& __range1, _Range2&& __range2, _Pred __pred = {}, _Proj1 __proj1 = {}, _Proj2 __proj2 = {}) const { 7961cfbce3SDimitry Andric if constexpr (sized_range<_Range1> && sized_range<_Range2>) { 8061cfbce3SDimitry Andric if (ranges::distance(__range1) != ranges::distance(__range2)) 8161cfbce3SDimitry Andric return false; 8261cfbce3SDimitry Andric } 8361cfbce3SDimitry Andric 8461cfbce3SDimitry Andric return __is_permutation_func_impl( 8506c3fb27SDimitry Andric ranges::begin(__range1), 8606c3fb27SDimitry Andric ranges::end(__range1), 8706c3fb27SDimitry Andric ranges::begin(__range2), 8806c3fb27SDimitry Andric ranges::end(__range2), 8906c3fb27SDimitry Andric __pred, 9006c3fb27SDimitry Andric __proj1, 9106c3fb27SDimitry Andric __proj2); 9261cfbce3SDimitry Andric } 9361cfbce3SDimitry Andric }; 9461cfbce3SDimitry Andric } // namespace __is_permutation 9561cfbce3SDimitry Andric 9661cfbce3SDimitry Andric inline namespace __cpo { 9761cfbce3SDimitry Andric inline constexpr auto is_permutation = __is_permutation::__fn{}; 9861cfbce3SDimitry Andric } // namespace __cpo 9961cfbce3SDimitry Andric } // namespace ranges 10061cfbce3SDimitry Andric 10161cfbce3SDimitry Andric _LIBCPP_END_NAMESPACE_STD 10261cfbce3SDimitry Andric 10306c3fb27SDimitry Andric #endif // _LIBCPP_STD_VER >= 20 10461cfbce3SDimitry Andric 105b3edf446SDimitry Andric _LIBCPP_POP_MACROS 106b3edf446SDimitry Andric 10761cfbce3SDimitry Andric #endif // _LIBCPP___ALGORITHM_RANGES_IS_PERMUTATION_H 108