#include <iostream>
template<unsigned> struct size {};
template<unsigned...Is> struct indexes {typedef indexes<Is...> type;};
template<class lhs, class rhs> struct concat_indexes;
template<unsigned...Is, unsigned...Ys> struct concat_indexes<indexes<Is...>, indexes<Ys...>>{
typedef indexes<Is...,Ys...> type;
};
template<class lhs, class rhs>
using ConcatIndexes = typename concat_indexes<lhs, rhs>::type;
template<unsigned min, unsigned count> struct make_indexes:
ConcatIndexes<
typename make_indexes<min, count/2>::type,
typename make_indexes<min+count/2, (count+1)/2>::type
>
{};
template<unsigned min> struct make_indexes<min, 0>:
indexes<>
{};
template<unsigned min> struct make_indexes<min, 1>:
indexes<min>
{};
template<unsigned max, unsigned min=0>
using MakeIndexes = typename make_indexes<min, max-min>::type;
template< typename L, typename R, unsigned I >
struct helper_helper {
static R func( L&& l ) { return std::forward<L>(l)(size<I>()); }
};
template<typename L, unsigned... Is>
auto
dispatch_helper(indexes<Is...>, L&& l, unsigned i)
-> decltype( std::declval<L>()(size<0>()) )
{
typedef decltype( std::declval<L>()(size<0>()) ) R;
// some compilers have problems with this line.
// you can write a helper class replace the lambda below if so:
typedef R(*F)(L&&);
static const F table[] = {
helper_helper<L, R, Is>::func...
};
return table[i]( std::forward<L>(l) );
};
template<unsigned Max, typename L>
auto
dispatch(L&& l, unsigned i)
-> decltype( std::declval<L>()(size<0>()) )
{
return dispatch_helper( MakeIndexes<Max>(), std::forward<L>(l), i );
};
struct test {
template<unsigned I>
int operator()( size<I> ) { std::cout << I << "\n"; return I; }
};
int main() {
int x = dispatch<1<<14>( test{}, 3 );
std::cout << x << "\n";
// your code goes here
return 0;
}
I2luY2x1ZGUgPGlvc3RyZWFtPgoKdGVtcGxhdGU8dW5zaWduZWQ+IHN0cnVjdCBzaXplIHt9OwoKICAgIHRlbXBsYXRlPHVuc2lnbmVkLi4uSXM+IHN0cnVjdCBpbmRleGVzIHt0eXBlZGVmIGluZGV4ZXM8SXMuLi4+IHR5cGU7fTsKICAgIHRlbXBsYXRlPGNsYXNzIGxocywgY2xhc3MgcmhzPiBzdHJ1Y3QgY29uY2F0X2luZGV4ZXM7CiAgICB0ZW1wbGF0ZTx1bnNpZ25lZC4uLklzLCB1bnNpZ25lZC4uLllzPiBzdHJ1Y3QgY29uY2F0X2luZGV4ZXM8aW5kZXhlczxJcy4uLj4sIGluZGV4ZXM8WXMuLi4+PnsKICAgIAl0eXBlZGVmIGluZGV4ZXM8SXMuLi4sWXMuLi4+IHR5cGU7CiAgICB9OwogICAgdGVtcGxhdGU8Y2xhc3MgbGhzLCBjbGFzcyByaHM+CiAgICB1c2luZyBDb25jYXRJbmRleGVzID0gdHlwZW5hbWUgY29uY2F0X2luZGV4ZXM8bGhzLCByaHM+Ojp0eXBlOwogICAgCiAgICB0ZW1wbGF0ZTx1bnNpZ25lZCBtaW4sIHVuc2lnbmVkIGNvdW50PiBzdHJ1Y3QgbWFrZV9pbmRleGVzOgogICAgCUNvbmNhdEluZGV4ZXM8CiAgICAJCXR5cGVuYW1lIG1ha2VfaW5kZXhlczxtaW4sIGNvdW50LzI+Ojp0eXBlLAogICAgCQl0eXBlbmFtZSBtYWtlX2luZGV4ZXM8bWluK2NvdW50LzIsIChjb3VudCsxKS8yPjo6dHlwZQogICAgCT4KICAgIHt9OwogICAgdGVtcGxhdGU8dW5zaWduZWQgbWluPiBzdHJ1Y3QgbWFrZV9pbmRleGVzPG1pbiwgMD46CiAgICAJaW5kZXhlczw+CiAgICB7fTsKICAgIHRlbXBsYXRlPHVuc2lnbmVkIG1pbj4gc3RydWN0IG1ha2VfaW5kZXhlczxtaW4sIDE+OgogICAgCWluZGV4ZXM8bWluPgogICAge307Cgl0ZW1wbGF0ZTx1bnNpZ25lZCBtYXgsIHVuc2lnbmVkIG1pbj0wPgoJdXNpbmcgTWFrZUluZGV4ZXMgPSB0eXBlbmFtZSBtYWtlX2luZGV4ZXM8bWluLCBtYXgtbWluPjo6dHlwZTsKCiAgICB0ZW1wbGF0ZTwgdHlwZW5hbWUgTCwgdHlwZW5hbWUgUiwgdW5zaWduZWQgSSA+CiAgICBzdHJ1Y3QgaGVscGVyX2hlbHBlciB7CiAgICAJc3RhdGljIFIgZnVuYyggTCYmIGwgKSB7IHJldHVybiBzdGQ6OmZvcndhcmQ8TD4obCkoc2l6ZTxJPigpKTsgfQogICAgfTsKICAgIHRlbXBsYXRlPHR5cGVuYW1lIEwsIHVuc2lnbmVkLi4uIElzPgogICAgYXV0bwogICAgZGlzcGF0Y2hfaGVscGVyKGluZGV4ZXM8SXMuLi4+LCBMJiYgbCwgdW5zaWduZWQgaSkKICAgIC0+IGRlY2x0eXBlKCBzdGQ6OmRlY2x2YWw8TD4oKShzaXplPDA+KCkpICkKICAgIHsKICAgICAgdHlwZWRlZiBkZWNsdHlwZSggc3RkOjpkZWNsdmFsPEw+KCkoc2l6ZTwwPigpKSApIFI7CiAgICAgIC8vIHNvbWUgY29tcGlsZXJzIGhhdmUgcHJvYmxlbXMgd2l0aCB0aGlzIGxpbmUuCiAgICAgIC8vIHlvdSBjYW4gd3JpdGUgYSBoZWxwZXIgY2xhc3MgcmVwbGFjZSB0aGUgbGFtYmRhIGJlbG93IGlmIHNvOgogICAgICB0eXBlZGVmIFIoKkYpKEwmJik7CiAgICAgIHN0YXRpYyBjb25zdCBGIHRhYmxlW10gPSB7CiAgICAgICAgaGVscGVyX2hlbHBlcjxMLCBSLCBJcz46OmZ1bmMuLi4KICAgICAgfTsKICAgICAgcmV0dXJuIHRhYmxlW2ldKCBzdGQ6OmZvcndhcmQ8TD4obCkgKTsKICAgIH07CiAgICB0ZW1wbGF0ZTx1bnNpZ25lZCBNYXgsIHR5cGVuYW1lIEw+CiAgICBhdXRvCiAgICBkaXNwYXRjaChMJiYgbCwgdW5zaWduZWQgaSkKICAgIC0+IGRlY2x0eXBlKCBzdGQ6OmRlY2x2YWw8TD4oKShzaXplPDA+KCkpICkKICAgIHsKICAgICAgcmV0dXJuIGRpc3BhdGNoX2hlbHBlciggTWFrZUluZGV4ZXM8TWF4PigpLCBzdGQ6OmZvcndhcmQ8TD4obCksIGkgKTsKICAgIH07CgoKc3RydWN0IHRlc3QgewoJdGVtcGxhdGU8dW5zaWduZWQgST4KCWludCBvcGVyYXRvcigpKCBzaXplPEk+ICkgeyBzdGQ6OmNvdXQgPDwgSSA8PCAiXG4iOyByZXR1cm4gSTsgfQp9OwoKaW50IG1haW4oKSB7CglpbnQgeCA9IGRpc3BhdGNoPDE8PDE0PiggdGVzdHt9LCAzICk7CglzdGQ6OmNvdXQgPDwgeCA8PCAiXG4iOwoJLy8geW91ciBjb2RlIGdvZXMgaGVyZQoJcmV0dXJuIDA7Cn0=