template<unsigned ... args>
struct index_list
{
using type = index_list;
};
template <typename, typename> struct multiply;
template <unsigned... indices, unsigned... tail>
struct multiply<index_list<indices...>,
index_list<tail... >> : index_list<indices..., (sizeof...(indices)+indices)...,
(2*sizeof...(indices)+indices)...> {};
template <unsigned N>
struct make_index_list :
multiply< typename make_index_list<N/2>::type,
typename make_index_list<N%2>::type > {};
template <> struct make_index_list<1> : index_list<0> {};
template <> struct make_index_list<0> : index_list<> {};
#include <limits>
template< typename T,
T base >
static constexpr unsigned highest_exponent( unsigned counter = 0, T current = std::numeric_limits<T>::max() )
{
return current ? highest_exponent<T,base>(counter+1, current/base) : counter ;
}
template< typename T,
T base,
typename = typename make_index_list<highest_exponent<T, base>()>::type >
struct pow_helper;
template< typename T,
T base,
unsigned ... indices >
struct pow_helper<T, base, index_list<indices...>>
{
static_assert( base > 0, "Invalid base!" ); // Kann man erweitern (Edit: >= ist natürlich falsch!)
static constexpr auto number = sizeof...(indices);
static constexpr T pow( unsigned i )
{
return i ? pow(i-1) * base : 1;
}
static constexpr T array[]{ pow(indices)... };
};
template< typename T,
T base,
unsigned ... indices >
constexpr T pow_helper<T, base, index_list<indices...>>::array[];
#include <cassert>
template<typename T, T base>
T pow( unsigned exp )
{
using helper = pow_helper<T, base>;
assert( exp < helper::number );
return helper::array[exp];
}
#include <iostream>
int main()
{
std::cout << pow<int, 10>(3);
}
dGVtcGxhdGU8dW5zaWduZWQgLi4uIGFyZ3M+CnN0cnVjdCBpbmRleF9saXN0CnsKCXVzaW5nIHR5cGUgPSBpbmRleF9saXN0Owp9OwoKdGVtcGxhdGUgPHR5cGVuYW1lLCB0eXBlbmFtZT4gc3RydWN0IG11bHRpcGx5Owp0ZW1wbGF0ZSA8dW5zaWduZWQuLi4gaW5kaWNlcywgdW5zaWduZWQuLi4gdGFpbD4Kc3RydWN0IG11bHRpcGx5PGluZGV4X2xpc3Q8aW5kaWNlcy4uLj4sCgkJICAgIGluZGV4X2xpc3Q8dGFpbC4uLiAgID4+IDogaW5kZXhfbGlzdDxpbmRpY2VzLi4uLCAoc2l6ZW9mLi4uKGluZGljZXMpK2luZGljZXMpLi4uLAoJCQkJCQkJCQkJICAgICAoMipzaXplb2YuLi4oaW5kaWNlcykraW5kaWNlcykuLi4+IHt9Owp0ZW1wbGF0ZSA8dW5zaWduZWQgTj4Kc3RydWN0IG1ha2VfaW5kZXhfbGlzdCA6CgltdWx0aXBseTwgdHlwZW5hbWUgbWFrZV9pbmRleF9saXN0PE4vMj46OnR5cGUsCgkJICAgIHR5cGVuYW1lIG1ha2VfaW5kZXhfbGlzdDxOJTI+Ojp0eXBlID4ge307Cgp0ZW1wbGF0ZSA8PiBzdHJ1Y3QgbWFrZV9pbmRleF9saXN0PDE+IDogaW5kZXhfbGlzdDwwPiB7fTsKdGVtcGxhdGUgPD4gc3RydWN0IG1ha2VfaW5kZXhfbGlzdDwwPiA6IGluZGV4X2xpc3Q8PiB7fTsKCiNpbmNsdWRlIDxsaW1pdHM+CnRlbXBsYXRlPCB0eXBlbmFtZSBULAogICAgICAgICAgVCBiYXNlID4Kc3RhdGljIGNvbnN0ZXhwciB1bnNpZ25lZCBoaWdoZXN0X2V4cG9uZW50KCB1bnNpZ25lZCBjb3VudGVyID0gMCwgVCBjdXJyZW50ID0gc3RkOjpudW1lcmljX2xpbWl0czxUPjo6bWF4KCkgKQp7CglyZXR1cm4gY3VycmVudCA/IGhpZ2hlc3RfZXhwb25lbnQ8VCxiYXNlPihjb3VudGVyKzEsIGN1cnJlbnQvYmFzZSkgOiBjb3VudGVyIDsKfQoKdGVtcGxhdGU8IHR5cGVuYW1lIFQsCiAgICAgICAgICBUIGJhc2UsCiAgICAgICAgICB0eXBlbmFtZSA9IHR5cGVuYW1lIG1ha2VfaW5kZXhfbGlzdDxoaWdoZXN0X2V4cG9uZW50PFQsIGJhc2U+KCk+Ojp0eXBlID4Kc3RydWN0IHBvd19oZWxwZXI7Cgp0ZW1wbGF0ZTwgdHlwZW5hbWUgVCwKICAgICAgICAgIFQgYmFzZSwKICAgICAgICAgIHVuc2lnbmVkIC4uLiBpbmRpY2VzID4Kc3RydWN0IHBvd19oZWxwZXI8VCwgYmFzZSwgaW5kZXhfbGlzdDxpbmRpY2VzLi4uPj4KewoJc3RhdGljX2Fzc2VydCggYmFzZSA+IDAsICJJbnZhbGlkIGJhc2UhIiApOyAvLyBLYW5uIG1hbiBlcndlaXRlcm4gKEVkaXQ6ID49IGlzdCBuYXTDvHJsaWNoIGZhbHNjaCEpCgoJc3RhdGljIGNvbnN0ZXhwciBhdXRvIG51bWJlciA9IHNpemVvZi4uLihpbmRpY2VzKTsKCglzdGF0aWMgY29uc3RleHByIFQgcG93KCB1bnNpZ25lZCBpICkKCXsKCQlyZXR1cm4gaSA/IHBvdyhpLTEpICogYmFzZSA6IDE7Cgl9CgoJc3RhdGljIGNvbnN0ZXhwciBUIGFycmF5W117IHBvdyhpbmRpY2VzKS4uLiB9Owp9OwoKdGVtcGxhdGU8IHR5cGVuYW1lIFQsCiAgICAgICAgICBUIGJhc2UsCiAgICAgICAgICB1bnNpZ25lZCAuLi4gaW5kaWNlcyA+CmNvbnN0ZXhwciBUIHBvd19oZWxwZXI8VCwgYmFzZSwgaW5kZXhfbGlzdDxpbmRpY2VzLi4uPj46OmFycmF5W107CgojaW5jbHVkZSA8Y2Fzc2VydD4KdGVtcGxhdGU8dHlwZW5hbWUgVCwgVCBiYXNlPgpUIHBvdyggdW5zaWduZWQgZXhwICkKewoJdXNpbmcgaGVscGVyID0gcG93X2hlbHBlcjxULCBiYXNlPjsKCWFzc2VydCggZXhwIDwgaGVscGVyOjpudW1iZXIgKTsKCXJldHVybiBoZWxwZXI6OmFycmF5W2V4cF07Cn0KCiNpbmNsdWRlIDxpb3N0cmVhbT4KaW50IG1haW4oKQp7CglzdGQ6OmNvdXQgPDwgcG93PGludCwgMTA+KDMpOwp9