I have some templated code that compilers can tail call optimize for most data types but not others. The code implements pow()
template<typename T, typename U>
void powRecurse(T& x, U& y, T& acc)
{
if(y == 0) {
acc = Identity<T>;
return;
}
if(y == 1) {
acc = acc * x;
return;
}
if(y % 2 == 1) {
acc = acc * x;
y = y - 1;
}
x = x*x;
y = y/2;
powRecurse<T, U>(x, y, acc);
}
template<typename T, typename U>
T tailPow(T x, U y)
{
T rv = Identity<T>;
powRecurse<T, U>(x, y, rv);
return rv;
}
The type of parameter T seems to have no affect on tail call optimization, any types I've tried can be tail called optimized with the right types for the parameter U. If parameter U is a uint64_t the compiler can tail call optimize. If it's boost::multiprecision::cpp_int then the compiler doesn't tail call optimize.
I've also tried wrapping a uint64_t in a class and a template wrapper on an int type which both tail call optimize.
Is there any reason this shouldn't tail call optimize? Obviously I could loop this but I'm really just trying to understand the language or compiler issues here.