| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970 | /*!@fileDefines `boost::hana::detail::unpack_flatten`.@copyright Louis Dionne 2013-2017Distributed 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_DETAIL_UNPACK_FLATTEN_HPP#define BOOST_HANA_DETAIL_UNPACK_FLATTEN_HPP#include <boost/hana/at.hpp>#include <boost/hana/config.hpp>#include <boost/hana/detail/algorithm.hpp>#include <boost/hana/detail/array.hpp>#include <boost/hana/length.hpp>#include <boost/hana/unpack.hpp>#include <cstddef>#include <utility>BOOST_HANA_NAMESPACE_BEGIN namespace detail {    template <std::size_t ...Lengths>    struct flatten_indices {        // avoid empty arrays by appending 0 to `lengths`        static constexpr std::size_t lengths[sizeof...(Lengths) + 1] = {Lengths..., 0};        static constexpr auto flat_length =            detail::accumulate(lengths, lengths + sizeof...(Lengths), 0);        template <bool Inner>        static constexpr auto compute() {            detail::array<std::size_t, flat_length> indices{};            for (std::size_t index = 0, i = 0; i < sizeof...(Lengths); ++i)                for (std::size_t j = 0; j < lengths[i]; ++j, ++index)                    indices[index] = (Inner ? i : j);            return indices;        }        static constexpr auto inner = compute<true>();        static constexpr auto outer = compute<false>();        template <typename Xs, typename F, std::size_t ...i>        static constexpr decltype(auto)        apply(Xs&& xs, F&& f, std::index_sequence<i...>) {            return static_cast<F&&>(f)(                hana::at_c<outer[i]>(hana::at_c<inner[i]>(                    static_cast<Xs&&>(xs)                ))...            );        }    };    struct make_flatten_indices {        template <typename ...Xs>        auto operator()(Xs const& ...xs) const -> detail::flatten_indices<            decltype(hana::length(xs))::value...        >;    };    template <typename Xs, typename F>    constexpr decltype(auto) unpack_flatten(Xs&& xs, F&& f) {        using Indices = decltype(hana::unpack(xs, make_flatten_indices{}));        return Indices::apply(static_cast<Xs&&>(xs), static_cast<F&&>(f),                        std::make_index_sequence<Indices::flat_length>{});    }} BOOST_HANA_NAMESPACE_END#endif // !BOOST_HANA_DETAIL_UNPACK_FLATTEN_HPP
 |