diff options
author | Nikolas Klauser <nikolasklauser@berlin.de> | 2022-08-02 22:40:13 -0700 |
---|---|---|
committer | Tom Stellard <tstellar@redhat.com> | 2022-08-05 01:04:08 -0700 |
commit | 1ee16f1049e2f79f590d6982c6a23bb4cde44a89 (patch) | |
tree | 7e2f4395f3fc754bf1c477d18180c04641764d8e /libcxx/include/__algorithm/ranges_next_permutation.h | |
parent | 24186f723b91c8d05a269c05579aad3753bc0153 (diff) |
[libc++][ranges] Implement `ranges::{prev, next}_permutation`.
Co-authored-by: Konstantin Varlamov <varconst@apple.com>
Differential Revision: https://reviews.llvm.org/D129859
(cherry picked from commit 68264b649461206dc095e672eacf8a003e0b9e49)
Diffstat (limited to 'libcxx/include/__algorithm/ranges_next_permutation.h')
-rw-r--r-- | libcxx/include/__algorithm/ranges_next_permutation.h | 72 |
1 files changed, 72 insertions, 0 deletions
diff --git a/libcxx/include/__algorithm/ranges_next_permutation.h b/libcxx/include/__algorithm/ranges_next_permutation.h new file mode 100644 index 000000000000..34c5fee04050 --- /dev/null +++ b/libcxx/include/__algorithm/ranges_next_permutation.h @@ -0,0 +1,72 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___ALGORITHM_RANGES_NEXT_PERMUTATION_H +#define _LIBCPP___ALGORITHM_RANGES_NEXT_PERMUTATION_H + +#include <__algorithm/in_found_result.h> +#include <__algorithm/iterator_operations.h> +#include <__algorithm/make_projected.h> +#include <__algorithm/next_permutation.h> +#include <__config> +#include <__functional/identity.h> +#include <__functional/ranges_operations.h> +#include <__iterator/concepts.h> +#include <__iterator/sortable.h> +#include <__ranges/access.h> +#include <__ranges/concepts.h> +#include <__ranges/dangling.h> +#include <__utility/move.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +#if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES) + +_LIBCPP_BEGIN_NAMESPACE_STD + +namespace ranges { + +template <class _InIter> +using next_permutation_result = in_found_result<_InIter>; + +namespace __next_permutation { + +struct __fn { + template <bidirectional_iterator _Iter, sentinel_for<_Iter> _Sent, class _Comp = ranges::less, class _Proj = identity> + requires sortable<_Iter, _Comp, _Proj> + _LIBCPP_HIDE_FROM_ABI constexpr next_permutation_result<_Iter> + operator()(_Iter __first, _Sent __last, _Comp __comp = {}, _Proj __proj = {}) const { + auto __result = std::__next_permutation<_RangeAlgPolicy>( + std::move(__first), std::move(__last), std::__make_projected(__comp, __proj)); + return {std::move(__result.first), std::move(__result.second)}; + } + + template <bidirectional_range _Range, class _Comp = ranges::less, class _Proj = identity> + requires sortable<iterator_t<_Range>, _Comp, _Proj> + _LIBCPP_HIDE_FROM_ABI constexpr next_permutation_result<borrowed_iterator_t<_Range>> + operator()(_Range&& __range, _Comp __comp = {}, _Proj __proj = {}) const { + auto __result = std::__next_permutation<_RangeAlgPolicy>( + ranges::begin(__range), ranges::end(__range), std::__make_projected(__comp, __proj)); + return {std::move(__result.first), std::move(__result.second)}; + } +}; + +} // namespace __next_permutation + +inline namespace __cpo { +constexpr inline auto next_permutation = __next_permutation::__fn{}; +} // namespace __cpo +} // namespace ranges + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES) + +#endif // _LIBCPP___ALGORITHM_RANGES_NEXT_PERMUTATION_H |