From 8ad87d104dd9c79ef268ba7cf708ade2067bc309 Mon Sep 17 00:00:00 2001 From: bolero-MURAKAMI Date: Tue, 28 Feb 2012 14:40:02 +0900 Subject: [PATCH] =?UTF-8?q?index=5Frange=20=E3=81=AE=E3=82=AA=E3=83=BC?= =?UTF-8?q?=E3=83=80=E3=83=BC=E3=82=92=20N(logN)=20=E3=81=AB=E5=86=8D?= =?UTF-8?q?=E5=AE=9F=E8=A3=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sprout/index_tuple.hpp | 128 +++++++++++++++++++++++++++++++---------- 1 file changed, 97 insertions(+), 31 deletions(-) diff --git a/sprout/index_tuple.hpp b/sprout/index_tuple.hpp index ca0a1142..aacc7053 100644 --- a/sprout/index_tuple.hpp +++ b/sprout/index_tuple.hpp @@ -2,6 +2,7 @@ #define SPROUT_INDEX_TUPLE_HPP #include +#include #include namespace sprout { @@ -19,45 +20,110 @@ namespace sprout { // // index_range // - template< - sprout::index_t First, - sprout::index_t Last, - sprout::index_t Step = 1, - typename Acc = sprout::index_tuple<>, - bool Break = (First >= Last) - > - struct index_range { - typedef Acc type; - }; - template< - sprout::index_t First, - sprout::index_t Last, - sprout::index_t Step, - sprout::index_t... Indexes - > - struct index_range, false> - : public sprout::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< + sprout::index_t I, + std::size_t N, + typename Acc, + bool Break = (N == 0) + > + struct index_n_impl { + public: + typedef Acc type; + }; + template< + sprout::index_t I, + std::size_t N, + sprout::index_t... Indexes + > + struct index_n_impl, false> + : public sprout::detail::index_n_impl > + {}; + } // namespace detail template< sprout::index_t I, - sprout::index_t N, - typename Acc = sprout::index_tuple<>, - bool Break = (N == 0) + std::size_t N, + typename Acc = sprout::index_tuple<> > - struct index_n { - typedef Acc type; - }; - template< - sprout::index_t I, - sprout::index_t N, - sprout::index_t... Indexes - > - struct index_n, false> - : public sprout::index_n > + struct index_n + : public sprout::detail::index_n_impl {}; } // namespace sprout