// compile with -O2 flag

// C++11 constexpr functions must be 1 liners, which means no loops
// can be resolved by using recursion
constexpr int fib(int n) {
    return n <= 1 ? 1 : ( fib(n-2) + fib(n - 1) );
}

// C++14 constexpr functions allowed to use local variables and loops
// even be virtual since C++20
constexpr int fib14(int n) {
    int pp = 1; // previous-previous
    int p  = 1; // previous
    for ( int i=0; i<=n; ++i ) {
        int next = pp+p;
        pp=p;
        p=next;
    }
    return p;
}

// constexpr function will compile (silently) into a runtime function
// if non-constexpr features are used 
constexpr int fib14_error(int n) {
    int a[n+1] = {0}; // not constexpr
    a[0] = a[1] = 1;
    for ( int i=0; i<=n; ++i ) {
        a[i] = a[i-2]+a[i-1];
    }
    return a[n];
}

int main() {
    return fib14(7);
}