/*! @file Defines `boost::hana::permutations`. @copyright Louis Dionne 2013-2017 Distributed under the Boost Software License, Version 1.0. (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt) */ #ifndef BOOST_HANA_PERMUTATIONS_HPP #define BOOST_HANA_PERMUTATIONS_HPP #include #include #include #include #include #include #include #include #include #include namespace boost { namespace hana { //! @cond template constexpr auto permutations_t::operator()(Xs&& xs) const { using S = typename hana::tag_of::type; using Permutations = BOOST_HANA_DISPATCH_IF(permutations_impl, hana::Sequence::value ); #ifndef BOOST_HANA_CONFIG_DISABLE_CONCEPT_CHECKS static_assert(hana::Sequence::value, "hana::permutations(xs) requires 'xs' to be a Sequence"); #endif return Permutations::apply(static_cast(xs)); } //! @endcond namespace detail { template struct permutation_indices { static constexpr auto value = detail::array{}.iota(0).permutations(); }; } template struct permutations_impl> : default_ { template static constexpr auto nth_permutation(Xs const& xs, std::index_sequence) { constexpr auto indices = detail::permutation_indices::value; (void)indices; // workaround GCC warning when sizeof...(i) == 0 return hana::make(hana::at_c(xs)...); } template static constexpr auto permutations_helper(Xs const& xs, std::index_sequence) { return hana::make(nth_permutation(xs, std::make_index_sequence{})...); } template static constexpr auto apply(Xs const& xs) { constexpr std::size_t N = decltype(hana::length(xs))::value; constexpr std::size_t total_perms = detail::factorial(N); return permutations_helper(xs, std::make_index_sequence{}); } }; }} // end namespace boost::hana #endif // !BOOST_HANA_PERMUTATIONS_HPP