1134723edSLouis Dionne //===----------------------------------------------------------------------===//
2134723edSLouis Dionne //
3134723edSLouis Dionne // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4134723edSLouis Dionne // See https://llvm.org/LICENSE.txt for license information.
5134723edSLouis Dionne // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6134723edSLouis Dionne //
7134723edSLouis Dionne //===----------------------------------------------------------------------===//
8134723edSLouis Dionne 
9134723edSLouis Dionne #ifndef _LIBCPP___ALGORITHM_PREV_PERMUTATION_H
10134723edSLouis Dionne #define _LIBCPP___ALGORITHM_PREV_PERMUTATION_H
11134723edSLouis Dionne 
12134723edSLouis Dionne #include <__config>
13134723edSLouis Dionne #include <__algorithm/comp.h>
14134723edSLouis Dionne #include <__algorithm/comp_ref_type.h>
15134723edSLouis Dionne #include <__algorithm/reverse.h>
16134723edSLouis Dionne #include <__iterator/iterator_traits.h>
17*6adbc83eSChristopher Di Bella #include <__utility/swap.h>
18134723edSLouis Dionne 
19134723edSLouis Dionne #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
20134723edSLouis Dionne #pragma GCC system_header
21134723edSLouis Dionne #endif
22134723edSLouis Dionne 
23134723edSLouis Dionne _LIBCPP_PUSH_MACROS
24134723edSLouis Dionne #include <__undef_macros>
25134723edSLouis Dionne 
26134723edSLouis Dionne _LIBCPP_BEGIN_NAMESPACE_STD
27134723edSLouis Dionne 
28134723edSLouis Dionne template <class _Compare, class _BidirectionalIterator>
29134723edSLouis Dionne _LIBCPP_CONSTEXPR_AFTER_CXX17 bool
30134723edSLouis Dionne __prev_permutation(_BidirectionalIterator __first, _BidirectionalIterator __last, _Compare __comp)
31134723edSLouis Dionne {
32134723edSLouis Dionne     _BidirectionalIterator __i = __last;
33134723edSLouis Dionne     if (__first == __last || __first == --__i)
34134723edSLouis Dionne         return false;
35134723edSLouis Dionne     while (true)
36134723edSLouis Dionne     {
37134723edSLouis Dionne         _BidirectionalIterator __ip1 = __i;
38134723edSLouis Dionne         if (__comp(*__ip1, *--__i))
39134723edSLouis Dionne         {
40134723edSLouis Dionne             _BidirectionalIterator __j = __last;
41134723edSLouis Dionne             while (!__comp(*--__j, *__i))
42134723edSLouis Dionne                 ;
43134723edSLouis Dionne             swap(*__i, *__j);
44134723edSLouis Dionne             _VSTD::reverse(__ip1, __last);
45134723edSLouis Dionne             return true;
46134723edSLouis Dionne         }
47134723edSLouis Dionne         if (__i == __first)
48134723edSLouis Dionne         {
49134723edSLouis Dionne             _VSTD::reverse(__first, __last);
50134723edSLouis Dionne             return false;
51134723edSLouis Dionne         }
52134723edSLouis Dionne     }
53134723edSLouis Dionne }
54134723edSLouis Dionne 
55134723edSLouis Dionne template <class _BidirectionalIterator, class _Compare>
56134723edSLouis Dionne inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
57134723edSLouis Dionne bool
58134723edSLouis Dionne prev_permutation(_BidirectionalIterator __first, _BidirectionalIterator __last, _Compare __comp)
59134723edSLouis Dionne {
60134723edSLouis Dionne     typedef typename __comp_ref_type<_Compare>::type _Comp_ref;
61134723edSLouis Dionne     return _VSTD::__prev_permutation<_Comp_ref>(__first, __last, __comp);
62134723edSLouis Dionne }
63134723edSLouis Dionne 
64134723edSLouis Dionne template <class _BidirectionalIterator>
65134723edSLouis Dionne inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
66134723edSLouis Dionne bool
67134723edSLouis Dionne prev_permutation(_BidirectionalIterator __first, _BidirectionalIterator __last)
68134723edSLouis Dionne {
69134723edSLouis Dionne     return _VSTD::prev_permutation(__first, __last,
70134723edSLouis Dionne                                   __less<typename iterator_traits<_BidirectionalIterator>::value_type>());
71134723edSLouis Dionne }
72134723edSLouis Dionne 
73134723edSLouis Dionne _LIBCPP_END_NAMESPACE_STD
74134723edSLouis Dionne 
75134723edSLouis Dionne _LIBCPP_POP_MACROS
76134723edSLouis Dionne 
77134723edSLouis Dionne #endif // _LIBCPP___ALGORITHM_PREV_PERMUTATION_H
78