#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 {}; // // 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::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< sprout::index_t I, std::size_t N > struct index_n : public sprout::detail::index_n_impl {}; } // namespace sprout #endif // #ifndef SPROUT_INDEX_TUPLE_HPP