#ifndef SPROUT_ALGORITHM_FIXED_NEXT_PERMUTATION_HPP #define SPROUT_ALGORITHM_FIXED_NEXT_PERMUTATION_HPP #include #include #include #include #include #include #include #include #include #include HDR_FUNCTIONAL_SSCRISK_CEL_OR_SPROUT namespace sprout { namespace fixed { namespace detail { template inline SPROUT_CONSTEXPR Result next_permutation_impl_4(Container const& cont, Difference d) { return Result( sprout::get_internal(sprout::fixed::reverse(sprout::sub_array(cont, d, sprout::size(cont)))), true ); } template inline SPROUT_CONSTEXPR Result next_permutation_impl_3( Container const& cont, Compare comp, BidirectionalIterator first, BidirectionalIterator last, BidirectionalIterator i, BidirectionalIterator ii, BidirectionalIterator j ) { return !comp(*i, *sprout::prev(j)) ? sprout::fixed::detail::next_permutation_impl_3( cont, comp, first, last, i, ii, sprout::prev(j) ) : sprout::fixed::detail::next_permutation_impl_4( sprout::fixed::swap_element(cont, i, sprout::prev(j)), sprout::distance(first, ii) ) ; } template inline SPROUT_CONSTEXPR Result next_permutation_impl_2( Container const& cont, Compare comp, BidirectionalIterator first, BidirectionalIterator last, BidirectionalIterator i, BidirectionalIterator ii ) { return comp(*i, *ii) ? sprout::fixed::detail::next_permutation_impl_3( cont, comp, first, last, i, ii, last ) : i == first ? Result(sprout::fixed::reverse_copy(first, last, cont), false) : sprout::fixed::detail::next_permutation_impl_2( cont, comp, first, last, sprout::prev(i), i ) ; } template inline SPROUT_CONSTEXPR Result next_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::next_permutation_impl_2( cont, comp, first, last, sprout::prev(last, 2), sprout::prev(last) ) ; } template inline SPROUT_CONSTEXPR Result next_permutation_impl(Container const& cont, Compare comp, BidirectionalIterator first, BidirectionalIterator last) { return first == last ? Result(sprout::deep_copy(cont), false) : sprout::fixed::detail::next_permutation_impl_1( cont, comp, first, last, sprout::next(first) ); } } // namespace detail // // next_permutation // template inline SPROUT_CONSTEXPR sprout::pair::type, bool> next_permutation(Container const& cont, Compare comp) { typedef sprout::pair::type, bool> type; return sprout::fixed::detail::next_permutation_impl( cont, comp, sprout::begin(cont), sprout::end(cont) ); } template inline SPROUT_CONSTEXPR sprout::pair::type, bool> next_permutation(Container const& cont) { typedef sprout::pair::type, bool> type; return sprout::fixed::detail::next_permutation_impl( cont, NS_SSCRISK_CEL_OR_SPROUT::less::value_type>(), sprout::begin(cont), sprout::end(cont) ); } } // namespace fixed using sprout::fixed::next_permutation; } // namespace sprout #endif // #ifndef SPROUT_ALGORITHM_FIXED_NEXT_PERMUTATION_HPP