I wrote a small wrapper function to choose between runtime (std) sqrt
and a constexpr version, as a continuation of the vector class I published here earlier:
C++ mathematical n-dimensional vector template using fold expressions
It seems to work fine and Compiler Explorer shows that the sqrt function is completely compiled out.
The relevant code (sqrt
coming from the standard library):
constexpr T cx_sqrt(const T& m) const {
int i = 0;
while((i*i) <= m) {
i++;
}
i--;
T d = m - (i * i);
T p = d / (2 * i);
T a = i + p;
return a - (p * p) / (2 * a);
}
constexpr T choose_sqrt(const T& m) const {
return (__builtin_constant_p(m) && __builtin_constant_p(*m)) ? cx_sqrt(m) : sqrt(m);
}
template <size_t... I>
constexpr T magnitude_impl(std::index_sequence<I...>) const {
return choose_sqrt(((values[I] * values[I]) + ...));
}
Any gotchas using a method like this?
__builtin_constant_p()
? Any special flags or#include
headers? \$\endgroup\$values
come from inmagnitude_impl
? \$\endgroup\$const
specifier at the end of declaration. \$\endgroup\$