mriera
mriera

Reputation: 281

How can I use C++11 parameter packs to distinguish between compile time constants and runtime vars?

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

Answers (0)

Related Questions