#ifndef SPROUT_INDEX_TUPLE_HPP #define SPROUT_INDEX_TUPLE_HPP #include #include #include namespace sprout { // // index_t // typedef std::ptrdiff_t index_t; // // index_tuple // template struct index_tuple { public: typedef index_tuple type; }; // // make_indexes // template inline SPROUT_CONSTEXPR typename IndexTupleType::type make_indexes() { return typename IndexTupleType::type(); } namespace detail { template struct make_index_tuple_helper { public: typedef typename IndexTupleType::type type; public: static SPROUT_CONSTEXPR type make() { return type(); } }; } // namespace detail // // index_range // namespace detail { template struct index_range_next; template struct index_range_next, Next> { public: typedef sprout::index_tuple type; }; template struct index_range_next2; template struct index_range_next2, Next, Tail> { public: typedef sprout::index_tuple type; }; template struct index_range_impl; template struct index_range_impl< First, Step, N, typename std::enable_if<(N == 0)>::type > { public: typedef sprout::index_tuple<> type; }; template struct index_range_impl< First, Step, N, typename std::enable_if<(N == 1)>::type > { public: typedef sprout::index_tuple type; }; template struct index_range_impl< First, Step, N, typename std::enable_if<(N > 1 && N % 2 == 0)>::type > : public sprout::detail::index_range_next< typename sprout::detail::index_range_impl::type, First + N / 2 * Step > {}; template struct index_range_impl< First, Step, N, typename std::enable_if<(N > 1 && N % 2 == 1)>::type > : public sprout::detail::index_range_next2< typename sprout::detail::index_range_impl::type, First + N / 2 * Step, First + (N - 1) * Step > {}; } // namespace detail template struct index_range : public sprout::detail::make_index_tuple_helper< sprout::detail::index_range_impl< First, Step, ((Last - First) + (Step - 1)) / Step > > {}; // // index_n // namespace detail { template struct index_n_next; template struct index_n_next> { public: typedef sprout::index_tuple type; }; template struct index_n_next2; template struct index_n_next2, Tail> { public: typedef sprout::index_tuple type; }; template struct index_n_impl; template struct index_n_impl< I, N, typename std::enable_if<(N == 0)>::type > { public: typedef sprout::index_tuple<> type; }; template struct index_n_impl< I, N, typename std::enable_if<(N == 1)>::type > { public: typedef sprout::index_tuple type; }; template struct index_n_impl< I, N, typename std::enable_if<(N > 1 && N % 2 == 0)>::type > : public sprout::detail::index_n_next< typename sprout::detail::index_n_impl::type > {}; template struct index_n_impl< I, N, typename std::enable_if<(N > 1 && N % 2 == 1)>::type > : public sprout::detail::index_n_next2< typename sprout::detail::index_n_impl::type, I > {}; } // namespace detail template struct index_n : public sprout::detail::make_index_tuple_helper< sprout::detail::index_n_impl > {}; // // pack_indexes // template struct pack_indexes : public sprout::detail::make_index_tuple_helper< sprout::index_range<0, sizeof...(Args)> > {}; } // namespace sprout #endif // #ifndef SPROUT_INDEX_TUPLE_HPP