/*============================================================================= Copyright (c) 2011-2015 Bolero MURAKAMI https://github.com/bolero-MURAKAMI/Sprout Distributed under the Boost Software License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) =============================================================================*/ #ifndef SPROUT_ALGORITHM_FIXED_PREV_PERMUTATION_HPP #define SPROUT_ALGORITHM_FIXED_PREV_PERMUTATION_HPP #include #include #include #include #include #include #include #include #if SPROUT_GCC_EARLIER(4, 8, 2) # include # include #else # include # include #endif #include #include HDR_FUNCTIONAL_SSCRISK_CEL_OR_SPROUT namespace sprout { namespace fixed { namespace detail { template inline SPROUT_CONSTEXPR Result prev_permutation_impl_4(Container const& cont, Difference d) { return Result( #if SPROUT_GCC_EARLIER(4, 8, 2) sprout::range::fixed::copy_backward(sprout::fit::reverse_copy(sprout::next(sprout::begin(cont), d), sprout::end(cont), cont), cont), #else sprout::fixed::copy_backward(sprout::make_reverse_iterator(sprout::end(cont)), sprout::make_reverse_iterator(sprout::next(sprout::begin(cont), d)), cont), #endif true ); } template inline SPROUT_CONSTEXPR Result prev_permutation_impl_3( Container const& cont, Compare comp, BidirectionalIterator first, BidirectionalIterator last, BidirectionalIterator i, BidirectionalIterator ii, BidirectionalIterator j ) { return !comp(*sprout::prev(j), *i) ? sprout::fixed::detail::prev_permutation_impl_3( cont, comp, first, last, i, ii, sprout::prev(j) ) : sprout::fixed::detail::prev_permutation_impl_4( sprout::fixed::swap_element(cont, i, sprout::prev(j)), sprout::distance(first, ii) ) ; } template inline SPROUT_CONSTEXPR Result prev_permutation_impl_2( Container const& cont, Compare comp, BidirectionalIterator first, BidirectionalIterator last, BidirectionalIterator i, BidirectionalIterator ii ) { return comp(*ii, *i) ? sprout::fixed::detail::prev_permutation_impl_3( cont, comp, first, last, i, ii, last ) : i == first ? Result(sprout::fixed::reverse_copy(first, last, cont), false) : sprout::fixed::detail::prev_permutation_impl_2( cont, comp, first, last, sprout::prev(i), i ) ; } template inline SPROUT_CONSTEXPR Result prev_permutation_impl_1(Container const& cont, Compare comp, BidirectionalIterator first, BidirectionalIterator last, BidirectionalIterator i) { return i == last ? Result(sprout::deep_copy(cont), false) : sprout::fixed::detail::prev_permutation_impl_2( cont, comp, first, last, sprout::prev(last, 2), sprout::prev(last) ) ; } template inline SPROUT_CONSTEXPR Result prev_permutation_impl(Container const& cont, Compare comp, BidirectionalIterator first, BidirectionalIterator last) { return first == last ? Result(sprout::deep_copy(cont), false) : sprout::fixed::detail::prev_permutation_impl_1( cont, comp, first, last, sprout::next(first) ); } } // namespace detail // // prev_permutation // template inline SPROUT_CONSTEXPR sprout::pair::type, bool> prev_permutation(Container const& cont, Compare comp) { typedef sprout::pair::type, bool> type; return sprout::fixed::detail::prev_permutation_impl( cont, comp, sprout::begin(cont), sprout::end(cont) ); } // // prev_permutation // template inline SPROUT_CONSTEXPR sprout::pair::type, bool> prev_permutation(Container const& cont) { typedef sprout::pair::type, bool> type; return sprout::fixed::detail::prev_permutation_impl( cont, NS_SSCRISK_CEL_OR_SPROUT::less::value_type>(), sprout::begin(cont), sprout::end(cont) ); } } // namespace fixed using sprout::fixed::prev_permutation; } // namespace sprout #endif // #ifndef SPROUT_ALGORITHM_FIXED_PREV_PERMUTATION_HPP