1 #pragma once 2 #include <c10/macros/Macros.h> 3 #include <type_traits> 4 5 // Utility to guarantee complete unrolling of a loop where the bounds are known 6 // at compile time. Various pragmas achieve similar effects, but are not as 7 // portable across compilers. 8 9 // Example: c10::ForcedUnroll<4>{}(f); is equivalent to f(0); f(1); f(2); f(3); 10 11 namespace c10 { 12 13 template <int n> 14 struct ForcedUnroll { 15 template <typename Func, typename... Args> operatorForcedUnroll16 C10_ALWAYS_INLINE void operator()(const Func& f, Args... args) const { 17 ForcedUnroll<n - 1>{}(f, args...); 18 f(std::integral_constant<int, n - 1>{}, args...); 19 } 20 }; 21 22 template <> 23 struct ForcedUnroll<1> { 24 template <typename Func, typename... Args> 25 C10_ALWAYS_INLINE void operator()(const Func& f, Args... args) const { 26 f(std::integral_constant<int, 0>{}, args...); 27 } 28 }; 29 30 } // namespace c10 31