1*134723edSLouis Dionne //===----------------------------------------------------------------------===//
2*134723edSLouis Dionne //
3*134723edSLouis Dionne // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4*134723edSLouis Dionne // See https://llvm.org/LICENSE.txt for license information.
5*134723edSLouis Dionne // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6*134723edSLouis Dionne //
7*134723edSLouis Dionne //===----------------------------------------------------------------------===//
8*134723edSLouis Dionne 
9*134723edSLouis Dionne #ifndef _LIBCPP___ALGORITHM_PREV_PERMUTATION_H
10*134723edSLouis Dionne #define _LIBCPP___ALGORITHM_PREV_PERMUTATION_H
11*134723edSLouis Dionne 
12*134723edSLouis Dionne #include <__config>
13*134723edSLouis Dionne #include <__algorithm/comp.h>
14*134723edSLouis Dionne #include <__algorithm/comp_ref_type.h>
15*134723edSLouis Dionne #include <__algorithm/reverse.h>
16*134723edSLouis Dionne #include <__iterator/iterator_traits.h>
17*134723edSLouis Dionne #include <type_traits> // swap
18*134723edSLouis Dionne 
19*134723edSLouis Dionne #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
20*134723edSLouis Dionne #pragma GCC system_header
21*134723edSLouis Dionne #endif
22*134723edSLouis Dionne 
23*134723edSLouis Dionne _LIBCPP_PUSH_MACROS
24*134723edSLouis Dionne #include <__undef_macros>
25*134723edSLouis Dionne 
26*134723edSLouis Dionne _LIBCPP_BEGIN_NAMESPACE_STD
27*134723edSLouis Dionne 
28*134723edSLouis Dionne template <class _Compare, class _BidirectionalIterator>
29*134723edSLouis Dionne _LIBCPP_CONSTEXPR_AFTER_CXX17 bool
30*134723edSLouis Dionne __prev_permutation(_BidirectionalIterator __first, _BidirectionalIterator __last, _Compare __comp)
31*134723edSLouis Dionne {
32*134723edSLouis Dionne     _BidirectionalIterator __i = __last;
33*134723edSLouis Dionne     if (__first == __last || __first == --__i)
34*134723edSLouis Dionne         return false;
35*134723edSLouis Dionne     while (true)
36*134723edSLouis Dionne     {
37*134723edSLouis Dionne         _BidirectionalIterator __ip1 = __i;
38*134723edSLouis Dionne         if (__comp(*__ip1, *--__i))
39*134723edSLouis Dionne         {
40*134723edSLouis Dionne             _BidirectionalIterator __j = __last;
41*134723edSLouis Dionne             while (!__comp(*--__j, *__i))
42*134723edSLouis Dionne                 ;
43*134723edSLouis Dionne             swap(*__i, *__j);
44*134723edSLouis Dionne             _VSTD::reverse(__ip1, __last);
45*134723edSLouis Dionne             return true;
46*134723edSLouis Dionne         }
47*134723edSLouis Dionne         if (__i == __first)
48*134723edSLouis Dionne         {
49*134723edSLouis Dionne             _VSTD::reverse(__first, __last);
50*134723edSLouis Dionne             return false;
51*134723edSLouis Dionne         }
52*134723edSLouis Dionne     }
53*134723edSLouis Dionne }
54*134723edSLouis Dionne 
55*134723edSLouis Dionne template <class _BidirectionalIterator, class _Compare>
56*134723edSLouis Dionne inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
57*134723edSLouis Dionne bool
58*134723edSLouis Dionne prev_permutation(_BidirectionalIterator __first, _BidirectionalIterator __last, _Compare __comp)
59*134723edSLouis Dionne {
60*134723edSLouis Dionne     typedef typename __comp_ref_type<_Compare>::type _Comp_ref;
61*134723edSLouis Dionne     return _VSTD::__prev_permutation<_Comp_ref>(__first, __last, __comp);
62*134723edSLouis Dionne }
63*134723edSLouis Dionne 
64*134723edSLouis Dionne template <class _BidirectionalIterator>
65*134723edSLouis Dionne inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
66*134723edSLouis Dionne bool
67*134723edSLouis Dionne prev_permutation(_BidirectionalIterator __first, _BidirectionalIterator __last)
68*134723edSLouis Dionne {
69*134723edSLouis Dionne     return _VSTD::prev_permutation(__first, __last,
70*134723edSLouis Dionne                                   __less<typename iterator_traits<_BidirectionalIterator>::value_type>());
71*134723edSLouis Dionne }
72*134723edSLouis Dionne 
73*134723edSLouis Dionne _LIBCPP_END_NAMESPACE_STD
74*134723edSLouis Dionne 
75*134723edSLouis Dionne _LIBCPP_POP_MACROS
76*134723edSLouis Dionne 
77*134723edSLouis Dionne #endif // _LIBCPP___ALGORITHM_PREV_PERMUTATION_H
78