fork download
  1. template<unsigned ... args>
  2. struct index_list
  3. {
  4. using type = index_list;
  5. };
  6.  
  7. template <typename, typename> struct multiply;
  8. template <unsigned... indices, unsigned... tail>
  9. struct multiply<index_list<indices...>,
  10. index_list<tail... >> : index_list<indices..., (sizeof...(indices)+indices)...,
  11. (2*sizeof...(indices)+indices)...> {};
  12. template <unsigned N>
  13. struct make_index_list :
  14. multiply< typename make_index_list<N/2>::type,
  15. typename make_index_list<N%2>::type > {};
  16.  
  17. template <> struct make_index_list<1> : index_list<0> {};
  18. template <> struct make_index_list<0> : index_list<> {};
  19.  
  20. #include <limits>
  21. template< typename T,
  22. T base >
  23. static constexpr unsigned highest_exponent( unsigned counter = 0, T current = std::numeric_limits<T>::max() )
  24. {
  25. return current ? highest_exponent<T,base>(counter+1, current/base) : counter ;
  26. }
  27.  
  28. template< typename T,
  29. T base,
  30. typename = typename make_index_list<highest_exponent<T, base>()>::type >
  31. struct pow_helper;
  32.  
  33. template< typename T,
  34. T base,
  35. unsigned ... indices >
  36. struct pow_helper<T, base, index_list<indices...>>
  37. {
  38. static_assert( base > 0, "Invalid base!" ); // Kann man erweitern (Edit: >= ist natürlich falsch!)
  39.  
  40. static constexpr auto number = sizeof...(indices);
  41.  
  42. static constexpr T pow( unsigned i )
  43. {
  44. return i ? pow(i-1) * base : 1;
  45. }
  46.  
  47. static constexpr T array[]{ pow(indices)... };
  48. };
  49.  
  50. template< typename T,
  51. T base,
  52. unsigned ... indices >
  53. constexpr T pow_helper<T, base, index_list<indices...>>::array[];
  54.  
  55. #include <cassert>
  56. template<typename T, T base>
  57. T pow( unsigned exp )
  58. {
  59. using helper = pow_helper<T, base>;
  60. assert( exp < helper::number );
  61. return helper::array[exp];
  62. }
  63.  
  64. #include <iostream>
  65. int main()
  66. {
  67. std::cout << pow<int, 10>(3);
  68. }
Success #stdin #stdout 0s 3296KB
stdin
Standard input is empty
stdout
1000