Suppose I have a configuration function to be defined by the user of the library which may or may not be constexpr.
constexpr int iterations() { return 10; }
// Or maybe:
int iterations() { return std::atoi(std::getenv("ITERATIONS")); }
// I'm okay with requiring the constexpr version to be:
constexpr auto iterations() { return std::integral_constant<int, 10>{}; }
Now I have a function that has different behavior depending on the value of iterations(), but this function should be constexpr if iterations is, because I want the user to be able to use it in constexpr if they configured the library to allow for it:
/*constexpr*/ std::uint32_t algorithm(std::uint32_t x) {
auto const iterations = ::iterations();
// For illustration purposes
for (int i = 0; i < iterations; ++i) {
x *= x;
}
return x;
}
What can I do to algorithm to make the function constexpr if iterations() is? In short, I want something like constexpr(constexpr(::iterations())).
Note that "conditional constexpr" is usually dependent on a template parameter as in Conditionally constexpr member function in which case the constexpr keyword can just be used, but in this case, I want the constexpr to be conditional on something which is not a template parameter, but a statically known function. Marking algorithm as constexpr is a compilation error:
error: call to non-'constexpr' function 'bool iterations()'