(Edit: if the input is constexpr itself) Its also quire easy to think about specializing a few templates and doing it that way. If you look up an example of the fib sequence in c++ templates you'll get the general idea.
Won't you just run into a constexpr evaluation depth error with a suggestion to set -fconstexpr-depth? I don't see how this is the gotcha it's made out to be.
If you wanted a c++26 preconditon for collatz tho, here it is. ```cpp bool collatz(unsigned long long n) { while (n != 1) n = n % 2 ? 3 * n + 1 : n / 2; return true; }
void f(unsigned long long n) pre(collatz(n)); ``` That's basically what you'd write if you were doing it with asserts, as the linked article states, just now you add it to the declaration.
cpp bool collatz(unsigned long long n)
{
while (n != 1)
n = n % 2 ? 3 * n + 1 : n / 2;
return true;
}
You’ll need to add code to detect cycles other than 1, 4, 2, 1, 4, 2,… to that. That can be done in constant space (https://en.wikipedia.org/wiki/Cycle_detection#Floyd’s_tortoi...)Ideally, you also need a way to detect runs towards infinity. That is harder.
Otherwise, an optimising compiler can use the forward progress guarantee and optimize that to:
cpp bool collatz(unsigned long long n)
{
return true;
}
and then completely remove the precondition.For future readers his sequel post explains the specific cause.