#include <iostream>
#include <vector>
using namespace std;
#if 1
#ifdef _MSC_VER
#define NO_INLINE __declspec(noinline)
#else
#define NO_INLINE __attribute__((noinline))
#endif
#else
#define NO_INLINE
#endif
void use(void *p)
{
static auto volatile t=p;
};
template<typename T,unsigned N,typename F>
NO_INLINE auto cps_alloca_static(F &&f) -> decltype(f(nullptr))
{
T data[N];
return f(&data[0]);
}
template<typename T,typename F>
NO_INLINE auto cps_alloca_dynamic(unsigned n,F &&f) -> decltype(f(nullptr))
{
vector<T> data(n);
return f(&data[0]);
}
template<typename T,typename F>
auto cps_alloca(unsigned n,F &&f) -> decltype(f(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);
default: return cps_alloca_dynamic<T>(n,f);
}; // mpl::for_each / array / index pack / recursive bsearch / etc variaciĆ³n
}
struct Payload
{
volatile char d[2048];
};
void test(unsigned n)
{
volatile char begin;
cps_alloca<Payload>(n,[&](Payload *p)
{
volatile char end;
const auto overhead = &begin-&end - int(n*sizeof(Payload));
cout << "n=" << n << "\toverhead=" << overhead << endl;
use(p);
});
}
int main()
{
for(auto i=1u;i!=6u;++i)
test(i);
}
I2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8dmVjdG9yPgoKdXNpbmcgbmFtZXNwYWNlIHN0ZDsKCiNpZiAxCiAgICAjaWZkZWYgX01TQ19WRVIKICAgICAgICAjZGVmaW5lIE5PX0lOTElORSBfX2RlY2xzcGVjKG5vaW5saW5lKQogICAgI2Vsc2UKICAgICAgICAjZGVmaW5lIE5PX0lOTElORSBfX2F0dHJpYnV0ZV9fKChub2lubGluZSkpCiAgICAjZW5kaWYKI2Vsc2UKICAgICNkZWZpbmUgTk9fSU5MSU5FCiNlbmRpZgoKdm9pZCB1c2Uodm9pZCAqcCkKewogICAgc3RhdGljIGF1dG8gdm9sYXRpbGUgdD1wOwp9OwoKdGVtcGxhdGU8dHlwZW5hbWUgVCx1bnNpZ25lZCBOLHR5cGVuYW1lIEY+Ck5PX0lOTElORSBhdXRvIGNwc19hbGxvY2Ffc3RhdGljKEYgJiZmKSAtPiBkZWNsdHlwZShmKG51bGxwdHIpKQp7CiAgICBUIGRhdGFbTl07CiAgICByZXR1cm4gZigmZGF0YVswXSk7Cn0KCnRlbXBsYXRlPHR5cGVuYW1lIFQsdHlwZW5hbWUgRj4KTk9fSU5MSU5FIGF1dG8gY3BzX2FsbG9jYV9keW5hbWljKHVuc2lnbmVkIG4sRiAmJmYpIC0+IGRlY2x0eXBlKGYobnVsbHB0cikpCnsKICAgIHZlY3RvcjxUPiBkYXRhKG4pOwogICAgcmV0dXJuIGYoJmRhdGFbMF0pOwp9Cgp0ZW1wbGF0ZTx0eXBlbmFtZSBULHR5cGVuYW1lIEY+CmF1dG8gY3BzX2FsbG9jYSh1bnNpZ25lZCBuLEYgJiZmKSAtPiBkZWNsdHlwZShmKG51bGxwdHIpKQp7CiAgICBzd2l0Y2gobikKICAgIHsKICAgICAgICBjYXNlIDE6IHJldHVybiBjcHNfYWxsb2NhX3N0YXRpYzxULDE+KGYpOwogICAgICAgIGNhc2UgMjogcmV0dXJuIGNwc19hbGxvY2Ffc3RhdGljPFQsMj4oZik7CiAgICAgICAgY2FzZSAzOiByZXR1cm4gY3BzX2FsbG9jYV9zdGF0aWM8VCwzPihmKTsKICAgICAgICBjYXNlIDQ6IHJldHVybiBjcHNfYWxsb2NhX3N0YXRpYzxULDQ+KGYpOwogICAgICAgIGRlZmF1bHQ6IHJldHVybiBjcHNfYWxsb2NhX2R5bmFtaWM8VD4obixmKTsKICAgIH07IC8vIG1wbDo6Zm9yX2VhY2ggLyBhcnJheSAvIGluZGV4IHBhY2sgLyByZWN1cnNpdmUgYnNlYXJjaCAvIGV0YyB2YXJpYWNpw7NuCn0KCnN0cnVjdCBQYXlsb2FkCnsKICAgIHZvbGF0aWxlIGNoYXIgZFsyMDQ4XTsKfTsKCnZvaWQgdGVzdCh1bnNpZ25lZCBuKQp7CiAgICB2b2xhdGlsZSBjaGFyIGJlZ2luOwogICAgY3BzX2FsbG9jYTxQYXlsb2FkPihuLFsmXShQYXlsb2FkICpwKQogICAgewogICAgICAgIHZvbGF0aWxlIGNoYXIgZW5kOwogICAgICAgIGNvbnN0IGF1dG8gb3ZlcmhlYWQgPSAmYmVnaW4tJmVuZCAtIGludChuKnNpemVvZihQYXlsb2FkKSk7CiAgICAgICAgY291dCA8PCAibj0iIDw8IG4gPDwgIlx0b3ZlcmhlYWQ9IiA8PCBvdmVyaGVhZCA8PCBlbmRsOwogICAgICAgIHVzZShwKTsKICAgIH0pOwp9CgppbnQgbWFpbigpCnsKICAgIGZvcihhdXRvIGk9MXU7aSE9NnU7KytpKQogICAgICAgIHRlc3QoaSk7Cn0=