/*! @file Defines `boost::hana::partition`. @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_PARTITION_HPP #define BOOST_HANA_PARTITION_HPP #include #include #include #include #include #include #include #include #include #include // required by fwd decl #include #include #include #include namespace boost { namespace hana { //! @cond template constexpr auto partition_t::operator()(Xs&& xs, Pred&& pred) const { using S = typename hana::tag_of::type; using Partition = BOOST_HANA_DISPATCH_IF(partition_impl, hana::Sequence::value ); #ifndef BOOST_HANA_CONFIG_DISABLE_CONCEPT_CHECKS static_assert(hana::Sequence::value, "hana::partition(xs, pred) requires 'xs' to be a Sequence"); #endif return Partition::apply(static_cast(xs), static_cast(pred)); } //! @endcond namespace detail { template struct partition_indices { static constexpr detail::array results{{B...}}; static constexpr std::size_t left_size = detail::count(results.begin(), results.end(), true); static constexpr std::size_t right_size = sizeof...(B) - left_size; static constexpr auto compute_left() { detail::array indices{}; std::size_t* left = &indices[0]; for (std::size_t i = 0; i < sizeof...(B); ++i) if (results[i]) *left++ = i; return indices; } static constexpr auto compute_right() { detail::array indices{}; std::size_t* right = &indices[0]; for (std::size_t i = 0; i < sizeof...(B); ++i) if (!results[i]) *right++ = i; return indices; } static constexpr auto left_indices = compute_left(); static constexpr auto right_indices = compute_right(); template static constexpr auto apply(Xs&& xs, std::index_sequence, std::index_sequence) { return hana::make( hana::make(hana::at_c(static_cast(xs))...), hana::make(hana::at_c(static_cast(xs))...) ); } }; template struct deduce_partition_indices { template auto operator()(Xs&& ...xs) const -> detail::partition_indices< static_cast(detail::decay< decltype(std::declval()(static_cast(xs))) >::type::value)... > { return {}; } }; } template struct partition_impl> : default_ { template static constexpr auto apply(Xs&& xs, Pred&&) { using Indices = decltype(hana::unpack( static_cast(xs), detail::deduce_partition_indices{} )); return Indices::template apply( static_cast(xs), std::make_index_sequence{}, std::make_index_sequence{} ); } }; }} // end namespace boost::hana #endif // !BOOST_HANA_PARTITION_HPP