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 <__algorithm/comp.h>
13134723edSLouis Dionne #include <__algorithm/comp_ref_type.h>
14134723edSLouis Dionne #include <__algorithm/reverse.h>
15*4d81a46fSArthur O'Dwyer #include <__config>
16134723edSLouis Dionne #include <__iterator/iterator_traits.h>
176adbc83eSChristopher 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_BEGIN_NAMESPACE_STD
24134723edSLouis Dionne 
25134723edSLouis Dionne template <class _Compare, class _BidirectionalIterator>
26134723edSLouis Dionne _LIBCPP_CONSTEXPR_AFTER_CXX17 bool
27134723edSLouis Dionne __prev_permutation(_BidirectionalIterator __first, _BidirectionalIterator __last, _Compare __comp)
28134723edSLouis Dionne {
29134723edSLouis Dionne     _BidirectionalIterator __i = __last;
30134723edSLouis Dionne     if (__first == __last || __first == --__i)
31134723edSLouis Dionne         return false;
32134723edSLouis Dionne     while (true)
33134723edSLouis Dionne     {
34134723edSLouis Dionne         _BidirectionalIterator __ip1 = __i;
35134723edSLouis Dionne         if (__comp(*__ip1, *--__i))
36134723edSLouis Dionne         {
37134723edSLouis Dionne             _BidirectionalIterator __j = __last;
38134723edSLouis Dionne             while (!__comp(*--__j, *__i))
39134723edSLouis Dionne                 ;
40134723edSLouis Dionne             swap(*__i, *__j);
41134723edSLouis Dionne             _VSTD::reverse(__ip1, __last);
42134723edSLouis Dionne             return true;
43134723edSLouis Dionne         }
44134723edSLouis Dionne         if (__i == __first)
45134723edSLouis Dionne         {
46134723edSLouis Dionne             _VSTD::reverse(__first, __last);
47134723edSLouis Dionne             return false;
48134723edSLouis Dionne         }
49134723edSLouis Dionne     }
50134723edSLouis Dionne }
51134723edSLouis Dionne 
52134723edSLouis Dionne template <class _BidirectionalIterator, class _Compare>
53134723edSLouis Dionne inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
54134723edSLouis Dionne bool
55134723edSLouis Dionne prev_permutation(_BidirectionalIterator __first, _BidirectionalIterator __last, _Compare __comp)
56134723edSLouis Dionne {
57134723edSLouis Dionne     typedef typename __comp_ref_type<_Compare>::type _Comp_ref;
58134723edSLouis Dionne     return _VSTD::__prev_permutation<_Comp_ref>(__first, __last, __comp);
59134723edSLouis Dionne }
60134723edSLouis Dionne 
61134723edSLouis Dionne template <class _BidirectionalIterator>
62134723edSLouis Dionne inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
63134723edSLouis Dionne bool
64134723edSLouis Dionne prev_permutation(_BidirectionalIterator __first, _BidirectionalIterator __last)
65134723edSLouis Dionne {
66134723edSLouis Dionne     return _VSTD::prev_permutation(__first, __last,
67134723edSLouis Dionne                                   __less<typename iterator_traits<_BidirectionalIterator>::value_type>());
68134723edSLouis Dionne }
69134723edSLouis Dionne 
70134723edSLouis Dionne _LIBCPP_END_NAMESPACE_STD
71134723edSLouis Dionne 
72134723edSLouis Dionne #endif // _LIBCPP___ALGORITHM_PREV_PERMUTATION_H
73