Reputation: 281
I am trying to make an optimal function that would accept compile-time constants and runtime constants, and do optimization at compile-time when the compiler knows the value. The problem is when I try to unpack the parameter pack it has to be moved into a runtime variable causing the compiler not to optimize in the same manner as if the constants was properly propagated. Unfortunately I'm not quite sure how to unpack to a single object while maintaining a mixture of compile-time and runtime variables in the same structure.
I have two working test cases: one that does what it suppose to do (assembly-wise), but is not generic with regards to parameter packs. The other does have a parameter packs, but the compiler loses the compile-time constant through the unpacking.
// Example program
#include <iostream>
#include <string>
#include <type_traits>
#include <functional>
#include <tuple>
struct ii{
int value;
};
template<int Val>
using tt = std::conditional_t<Val==0, ii, std::integral_constant<int, Val> >;
template<int... vals>
void foo( tt<vals>... inp)
{
const int arr[sizeof...(inp)] = {inp.value...};
std::cout << "parameter " << (16 / arr[0]) << std::endl; //<-incorrect asm
std::cout << "parameter " << (16/ arr[1] ) << std::endl; //expected asm
}
void check(ii i, std::integral_constant<int, 4> a)
{
std::cout << "i = " << ( 16 / i.value ) << std::endl; //<--expected asm
std::cout << "i = " << (16 / a.value ) << std::endl; //<--this is OK in asm
}
int main()
{
std::integral_constant<int, 4> four;
check(ii{1},four );
foo<four.value,0>(four, ii{1});
}
The expected results for "(16 / arr[0])" should be calculated at compile time, and it should be a constant 4.
Thank you!
Upvotes: 2
Views: 109