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