#include <iostream>
#include <vector>
using namespace std;
void use(void *p)
{
static auto volatile t=p;
};
template<typename T,unsigned N,typename F>
auto cps_alloca_static(F &&f) -> decltype(f(nullptr,nullptr))
{
T data[N];
return f(&data[0],&data[0]+N);
}
template<typename T,typename F>
auto cps_alloca_dynamic(unsigned n,F &&f) -> decltype(f(nullptr,nullptr))
{
vector<T> data(n);
return f(&data[0],&data[0]+n);
}
template<typename T,typename F>
auto cps_alloca(unsigned n,F &&f) -> decltype(f(nullptr,nullptr))
{
switch(n)
{
case 1: return cps_alloca_static<T,1>(f);
case 2: return cps_alloca_static<T,2>(f);
case 3: return cps_alloca_static<T,3>(f);
case 4: return cps_alloca_static<T,4>(f);
case 0: return f(nullptr,nullptr);
default: return cps_alloca_dynamic<T>(n,f);
}; // mpl::for_each / array / index pack / recursive bsearch / etc variaciĆ³n
}
struct Payload
{
char d[1 << 14];
};
void test(unsigned n)
{
volatile char begin;
cps_alloca<Payload>(n,[&](Payload *first,Payload *last)
{
volatile char end;
const auto overhead = &begin-&end - int(n*sizeof(Payload));
cout << "n=" << n << "\toverhead=" << overhead << endl;
use(first); use(last);
});
}
int main()
{
for(auto i=1u;i!=6u;++i)
test(i);
}
I2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8dmVjdG9yPgoKdXNpbmcgbmFtZXNwYWNlIHN0ZDsKCnZvaWQgdXNlKHZvaWQgKnApCnsKICAgIHN0YXRpYyBhdXRvIHZvbGF0aWxlIHQ9cDsKfTsKCnRlbXBsYXRlPHR5cGVuYW1lIFQsdW5zaWduZWQgTix0eXBlbmFtZSBGPgphdXRvIGNwc19hbGxvY2Ffc3RhdGljKEYgJiZmKSAtPiBkZWNsdHlwZShmKG51bGxwdHIsbnVsbHB0cikpCnsKICAgIFQgZGF0YVtOXTsKICAgIHJldHVybiBmKCZkYXRhWzBdLCZkYXRhWzBdK04pOwp9Cgp0ZW1wbGF0ZTx0eXBlbmFtZSBULHR5cGVuYW1lIEY+CmF1dG8gY3BzX2FsbG9jYV9keW5hbWljKHVuc2lnbmVkIG4sRiAmJmYpIC0+IGRlY2x0eXBlKGYobnVsbHB0cixudWxscHRyKSkKewogICAgdmVjdG9yPFQ+IGRhdGEobik7CiAgICByZXR1cm4gZigmZGF0YVswXSwmZGF0YVswXStuKTsKfQoKdGVtcGxhdGU8dHlwZW5hbWUgVCx0eXBlbmFtZSBGPgphdXRvIGNwc19hbGxvY2EodW5zaWduZWQgbixGICYmZikgLT4gZGVjbHR5cGUoZihudWxscHRyLG51bGxwdHIpKQp7CiAgICBzd2l0Y2gobikKICAgIHsKICAgICAgICBjYXNlIDE6IHJldHVybiBjcHNfYWxsb2NhX3N0YXRpYzxULDE+KGYpOwogICAgICAgIGNhc2UgMjogcmV0dXJuIGNwc19hbGxvY2Ffc3RhdGljPFQsMj4oZik7CiAgICAgICAgY2FzZSAzOiByZXR1cm4gY3BzX2FsbG9jYV9zdGF0aWM8VCwzPihmKTsKICAgICAgICBjYXNlIDQ6IHJldHVybiBjcHNfYWxsb2NhX3N0YXRpYzxULDQ+KGYpOwogICAgICAgIGNhc2UgMDogcmV0dXJuIGYobnVsbHB0cixudWxscHRyKTsKICAgICAgICBkZWZhdWx0OiByZXR1cm4gY3BzX2FsbG9jYV9keW5hbWljPFQ+KG4sZik7CiAgICB9OyAvLyBtcGw6OmZvcl9lYWNoIC8gYXJyYXkgLyBpbmRleCBwYWNrIC8gcmVjdXJzaXZlIGJzZWFyY2ggLyBldGMgdmFyaWFjacOzbgp9CgpzdHJ1Y3QgUGF5bG9hZAp7CiAgICBjaGFyIGRbMSA8PCAxNF07Cn07Cgp2b2lkIHRlc3QodW5zaWduZWQgbikKewogICAgdm9sYXRpbGUgY2hhciBiZWdpbjsKICAgIGNwc19hbGxvY2E8UGF5bG9hZD4obixbJl0oUGF5bG9hZCAqZmlyc3QsUGF5bG9hZCAqbGFzdCkKICAgIHsKICAgICAgICB2b2xhdGlsZSBjaGFyIGVuZDsKICAgICAgICBjb25zdCBhdXRvIG92ZXJoZWFkID0gJmJlZ2luLSZlbmQgLSBpbnQobipzaXplb2YoUGF5bG9hZCkpOwogICAgICAgIGNvdXQgPDwgIm49IiA8PCBuIDw8ICJcdG92ZXJoZWFkPSIgPDwgb3ZlcmhlYWQgPDwgZW5kbDsKICAgICAgICB1c2UoZmlyc3QpOyB1c2UobGFzdCk7CiAgICB9KTsKfQoKaW50IG1haW4oKQp7CiAgICBmb3IoYXV0byBpPTF1O2khPTZ1OysraSkKICAgICAgICB0ZXN0KGkpOwp9