Loading src/TNL/Algorithms/staticFor.h +30 −29 Original line number Diff line number Diff line Loading @@ -17,6 +17,13 @@ namespace TNL { namespace Algorithms { namespace detail { // special dispatch for `begin >= end` (i.e. empty loop) template< typename Index, Index begin, Index end, typename Func > constexpr std::enable_if_t< (begin >= end) > static_for_dispatch( Func &&f ) {} #if __cplusplus >= 201703L // C++17 version using fold expression Loading @@ -26,49 +33,43 @@ constexpr void static_for_impl( Func &&f, std::integer_sequence< Index, idx... > ( f( std::integral_constant<Index, begin + idx>{} ), ... ); } #else // C++14 version using recursion and variadic pack template< typename Index, Index begin, typename Func, Index idx > constexpr void static_for_impl( Func &&f, std::integer_sequence< Index, idx > ) { f( std::integral_constant<Index, begin + idx>{} ); } template< typename Index, Index begin, typename Func, Index idx, Index... indices > // WTF why, clang, why... //constexpr void constexpr std::enable_if_t< sizeof...(indices) >= 1 > static_for_impl( Func &&f, std::integer_sequence< Index, idx, indices... > ) // general dispatch for `begin < end` template< typename Index, Index begin, Index end, typename Func > constexpr std::enable_if_t< (begin < end) > static_for_dispatch( Func &&f ) { static_for_impl< Index, begin >( std::forward< Func >( f ), std::integer_sequence< Index, idx >{} ); static_for_impl< Index, begin >( std::forward< Func >( f ), std::integer_sequence< Index, indices... >{} std::make_integer_sequence< Index, end - begin >{} ); } #endif #else // general specialization for `begin < end` // C++14 version using recursive folding // (We avoid manual folding with std::integer_sequence, because it cannot be // empty, so it would be rather weird. Folding is done by bisection to limit // the recursion depth.) // special dispatch for 1 iteration template< typename Index, Index begin, Index end, typename Func > constexpr std::enable_if_t< (begin < end) > constexpr std::enable_if_t< (begin < end && end - begin == 1) > static_for_dispatch( Func &&f ) { static_for_impl< Index, begin >( std::forward< Func >( f ), std::make_integer_sequence< Index, end - begin >{} ); f( std::integral_constant< Index, begin >{} ); } // specialization for `begin >= end` (i.e. empty loop) // general dispatch for at least 2 iterations template< typename Index, Index begin, Index end, typename Func > constexpr std::enable_if_t< (begin >= end) > constexpr std::enable_if_t< (begin < end && end - begin >= 2) > static_for_dispatch( Func &&f ) {} { constexpr Index mid = begin + (end - begin) / 2; static_for_dispatch< Index, begin, mid >( std::forward< Func >( f ) ); static_for_dispatch< Index, mid, end >( std::forward< Func >( f ) ); } #endif } // namespace detail Loading src/TNL/Algorithms/unrolledFor.h +17 −27 Original line number Diff line number Diff line Loading @@ -17,49 +17,39 @@ namespace Algorithms { namespace detail { template< typename Index, Index begin, Index end > struct UnrolledFor { static_assert( begin < end, "internal error - wrong iteration index for UnrolledFor" ); // special dispatch for empty loop template< typename Index, Index begin, Index end, Index unrollFactor, typename Func > constexpr std::enable_if_t< (begin >= end) > unrolled_for_dispatch( Func&& f ) {} template< typename Func > static constexpr void exec( Func&& f ) // special dispatch for 1 iteration template< typename Index, Index begin, Index end, Index unrollFactor, typename Func > constexpr std::enable_if_t< (begin < end && end - begin == 1) > unrolled_for_dispatch( Func&& f ) { f( begin ); UnrolledFor< Index, begin + 1, end >::exec( std::forward< Func >( f ) ); } }; template< typename Index, Index end > struct UnrolledFor< Index, end, end > { template< typename Func > static constexpr void exec( Func&& f ) {} }; // specialization for short loops - unrolling // specialization for unrolling short loops (at least 2, but at most unrollFactor iterations) template< typename Index, Index begin, Index end, Index unrollFactor, typename Func > constexpr std::enable_if_t< (begin < end && end - begin <= unrollFactor) > constexpr std::enable_if_t< (begin < end && end - begin >= 2 && end - begin <= unrollFactor) > unrolled_for_dispatch( Func&& f ) { UnrolledFor< Index, begin, end >::exec( std::forward< Func >( f ) ); constexpr Index mid = begin + (end - begin) / 2; unrolled_for_dispatch< Index, begin, mid, unrollFactor >( std::forward< Func >( f ) ); unrolled_for_dispatch< Index, mid, end, unrollFactor >( std::forward< Func >( f ) ); } // specialization for long loops - normal for-loop template< typename Index, Index begin, Index end, Index unrollFactor, typename Func > constexpr std::enable_if_t< (begin < end && end - begin > unrollFactor) > constexpr std::enable_if_t< (begin < end && end - begin > 1 && end - begin > unrollFactor) > unrolled_for_dispatch( Func&& f ) { for( Index i = begin; i < end; i++ ) f( i ); } // specialization for empty loop template< typename Index, Index begin, Index end, Index unrollFactor, typename Func > constexpr std::enable_if_t< (begin >= end) > unrolled_for_dispatch( Func&& f ) {} } // namespace detail /** Loading Loading
src/TNL/Algorithms/staticFor.h +30 −29 Original line number Diff line number Diff line Loading @@ -17,6 +17,13 @@ namespace TNL { namespace Algorithms { namespace detail { // special dispatch for `begin >= end` (i.e. empty loop) template< typename Index, Index begin, Index end, typename Func > constexpr std::enable_if_t< (begin >= end) > static_for_dispatch( Func &&f ) {} #if __cplusplus >= 201703L // C++17 version using fold expression Loading @@ -26,49 +33,43 @@ constexpr void static_for_impl( Func &&f, std::integer_sequence< Index, idx... > ( f( std::integral_constant<Index, begin + idx>{} ), ... ); } #else // C++14 version using recursion and variadic pack template< typename Index, Index begin, typename Func, Index idx > constexpr void static_for_impl( Func &&f, std::integer_sequence< Index, idx > ) { f( std::integral_constant<Index, begin + idx>{} ); } template< typename Index, Index begin, typename Func, Index idx, Index... indices > // WTF why, clang, why... //constexpr void constexpr std::enable_if_t< sizeof...(indices) >= 1 > static_for_impl( Func &&f, std::integer_sequence< Index, idx, indices... > ) // general dispatch for `begin < end` template< typename Index, Index begin, Index end, typename Func > constexpr std::enable_if_t< (begin < end) > static_for_dispatch( Func &&f ) { static_for_impl< Index, begin >( std::forward< Func >( f ), std::integer_sequence< Index, idx >{} ); static_for_impl< Index, begin >( std::forward< Func >( f ), std::integer_sequence< Index, indices... >{} std::make_integer_sequence< Index, end - begin >{} ); } #endif #else // general specialization for `begin < end` // C++14 version using recursive folding // (We avoid manual folding with std::integer_sequence, because it cannot be // empty, so it would be rather weird. Folding is done by bisection to limit // the recursion depth.) // special dispatch for 1 iteration template< typename Index, Index begin, Index end, typename Func > constexpr std::enable_if_t< (begin < end) > constexpr std::enable_if_t< (begin < end && end - begin == 1) > static_for_dispatch( Func &&f ) { static_for_impl< Index, begin >( std::forward< Func >( f ), std::make_integer_sequence< Index, end - begin >{} ); f( std::integral_constant< Index, begin >{} ); } // specialization for `begin >= end` (i.e. empty loop) // general dispatch for at least 2 iterations template< typename Index, Index begin, Index end, typename Func > constexpr std::enable_if_t< (begin >= end) > constexpr std::enable_if_t< (begin < end && end - begin >= 2) > static_for_dispatch( Func &&f ) {} { constexpr Index mid = begin + (end - begin) / 2; static_for_dispatch< Index, begin, mid >( std::forward< Func >( f ) ); static_for_dispatch< Index, mid, end >( std::forward< Func >( f ) ); } #endif } // namespace detail Loading
src/TNL/Algorithms/unrolledFor.h +17 −27 Original line number Diff line number Diff line Loading @@ -17,49 +17,39 @@ namespace Algorithms { namespace detail { template< typename Index, Index begin, Index end > struct UnrolledFor { static_assert( begin < end, "internal error - wrong iteration index for UnrolledFor" ); // special dispatch for empty loop template< typename Index, Index begin, Index end, Index unrollFactor, typename Func > constexpr std::enable_if_t< (begin >= end) > unrolled_for_dispatch( Func&& f ) {} template< typename Func > static constexpr void exec( Func&& f ) // special dispatch for 1 iteration template< typename Index, Index begin, Index end, Index unrollFactor, typename Func > constexpr std::enable_if_t< (begin < end && end - begin == 1) > unrolled_for_dispatch( Func&& f ) { f( begin ); UnrolledFor< Index, begin + 1, end >::exec( std::forward< Func >( f ) ); } }; template< typename Index, Index end > struct UnrolledFor< Index, end, end > { template< typename Func > static constexpr void exec( Func&& f ) {} }; // specialization for short loops - unrolling // specialization for unrolling short loops (at least 2, but at most unrollFactor iterations) template< typename Index, Index begin, Index end, Index unrollFactor, typename Func > constexpr std::enable_if_t< (begin < end && end - begin <= unrollFactor) > constexpr std::enable_if_t< (begin < end && end - begin >= 2 && end - begin <= unrollFactor) > unrolled_for_dispatch( Func&& f ) { UnrolledFor< Index, begin, end >::exec( std::forward< Func >( f ) ); constexpr Index mid = begin + (end - begin) / 2; unrolled_for_dispatch< Index, begin, mid, unrollFactor >( std::forward< Func >( f ) ); unrolled_for_dispatch< Index, mid, end, unrollFactor >( std::forward< Func >( f ) ); } // specialization for long loops - normal for-loop template< typename Index, Index begin, Index end, Index unrollFactor, typename Func > constexpr std::enable_if_t< (begin < end && end - begin > unrollFactor) > constexpr std::enable_if_t< (begin < end && end - begin > 1 && end - begin > unrollFactor) > unrolled_for_dispatch( Func&& f ) { for( Index i = begin; i < end; i++ ) f( i ); } // specialization for empty loop template< typename Index, Index begin, Index end, Index unrollFactor, typename Func > constexpr std::enable_if_t< (begin >= end) > unrolled_for_dispatch( Func&& f ) {} } // namespace detail /** Loading