diff --git a/sprout/index_tuple/index_range.hpp b/sprout/index_tuple/index_range.hpp index 723bcd5d..21f11640 100644 --- a/sprout/index_tuple/index_range.hpp +++ b/sprout/index_tuple/index_range.hpp @@ -1,7 +1,6 @@ #ifndef SPROUT_INDEX_TUPLE_INDEX_RANGE_HPP #define SPROUT_INDEX_TUPLE_INDEX_RANGE_HPP -#include #include #include #include @@ -11,7 +10,10 @@ namespace sprout { // // index_range // - template + template< + sprout::index_t First, sprout::index_t Last, + typename std::make_signed::type Step = sprout::detail::integer_range_default_step::value + > struct index_range : public sprout::detail::make_indexes_helper< typename sprout::integer_range::type @@ -21,7 +23,10 @@ namespace sprout { // // uindex_range // - template + template< + sprout::uindex_t First, sprout::uindex_t Last, + typename std::make_signed::type Step = sprout::detail::integer_range_default_step::value + > struct uindex_range : public sprout::detail::make_indexes_helper< typename sprout::integer_range::type diff --git a/sprout/index_tuple/integer_range.hpp b/sprout/index_tuple/integer_range.hpp index 35f964f1..7e3238b5 100644 --- a/sprout/index_tuple/integer_range.hpp +++ b/sprout/index_tuple/integer_range.hpp @@ -1,16 +1,19 @@ #ifndef SPROUT_INDEX_TUPLE_INTEGER_RANGE_HPP #define SPROUT_INDEX_TUPLE_INTEGER_RANGE_HPP -#include #include #include #include #include namespace sprout { - // - // integer_range - // + namespace detail { + template + struct integer_range_default_step + : public std::integral_constant::type, (First <= Last ? 1 : -1)> + {}; + } // namespace detail + namespace detail { template struct integer_range_next_even; @@ -26,23 +29,23 @@ namespace sprout { : public sprout::integer_seq {}; - template + template::type Step, typename std::make_unsigned::type N, typename Enable = void> struct integer_range_impl; - template + template::type Step, typename std::make_unsigned::type N> struct integer_range_impl< T, First, Step, N, typename std::enable_if<(N == 0)>::type > : public sprout::integer_seq {}; - template + template::type Step, typename std::make_unsigned::type N> struct integer_range_impl< T, First, Step, N, typename std::enable_if<(N == 1)>::type > : public sprout::integer_seq {}; - template + template::type Step, typename std::make_unsigned::type N> struct integer_range_impl< T, First, Step, N, typename std::enable_if<(N > 1 && N % 2 == 0)>::type @@ -52,7 +55,7 @@ namespace sprout { N / 2 * Step > {}; - template + template::type Step, typename std::make_unsigned::type N> struct integer_range_impl< T, First, Step, N, typename std::enable_if<(N > 1 && N % 2 == 1)>::type @@ -62,15 +65,36 @@ namespace sprout { N / 2 * Step, First + (N - 1) * Step > {}; + template::type Step, typename Enable = void> + struct integer_range {}; + template::type Step> + struct integer_range< + T, First, Last, Step, + typename std::enable_if<((First < Last && Step > 0) || (First > Last && Step < 0) || (First == Last))>::type + > + : public sprout::detail::integer_range_impl< + T, First, Step, + (static_cast::type>(Last - First) + (Step > 0 ? Step - 1 : Step + 1)) / Step + > + {}; } // namespace detail - template + // + // integer_range + // + template< + typename T, T First, T Last, + typename std::make_signed::type Step = sprout::detail::integer_range_default_step::value + > struct integer_range : public sprout::detail::make_indexes_helper< - sprout::detail::integer_range_impl< - T, First, Step, ((Last - First) + (Step - 1)) / Step - > + sprout::detail::integer_range > - {}; + { + static_assert( + (First < Last && Step > 0) || (First > Last && Step < 0) || (First == Last), + "(First < Last && Step > 0) || (First > Last && Step < 0) || (First == Last)" + ); + }; } // namespace sprout #endif // #ifndef SPROUT_INDEX_TUPLE_INTEGER_RANGE_HPP