15 -> std::array<
decltype(g(
std::size_t{},
sizeof...(Is))),
sizeof...(Is)>
17 return {{g(Is,
sizeof...(Is))...}};
20 template<std::
size_t N,
typename Generator>
25 template<
typename T, T Base, u
int8_t Exponent, u
int64_t Value,
bool Overflow = (Value * Base < Value)>
26 struct largest_power_helper {
28 static_assert( std::is_
integral_v<T> && std::is_
unsigned_v<T> &&!std::is_same_v<T,
bool> );
29 static_assert( Base > 1 );
30 constexpr static T next_value = Value * Base;
33 constexpr static T value = next::value;
34 constexpr static uint8_t exponent = next::exponent;
37 template<
typename T, T Base, u
int8_t Exponent, u
int64_t Value>
40 static_assert( std::is_integral_v<T> && std::is_unsigned_v<T> &&!std::is_same_v<T, bool> );
41 static_assert( Base > 1 );
42 static_assert( Exponent < 255 );
44 constexpr static T value = Value;
45 constexpr static uint8_t exponent = Exponent;
48 template<
typename T, T Base>
53 constexpr static T value = helper::value;
54 constexpr static uint8_t exponent = helper::exponent;
58 constexpr T
pow( T base, uint8_t exponent ) {
59 if( base <= 1 )
check(
false,
"base must be at least 2" );
62 for( uint8_t i = 0; i < exponent; ++i, prior =
result ) {
69 template<
typename T, T Base>
71 return pow( Base,
static_cast<uint8_t
>(i) );
76 template<u
int8_t Base,
typename T = u
int64_t>
77 inline constexpr auto powers_of_base = detail::generate_array<detail::largest_power<T, Base>::exponent + 1>( detail::pow_generator<T, Base> );
80 template<u
int8_t Base,
typename T = u
int64_t>
81 constexpr T
pow( uint8_t exponent ) {
82 const auto& lookup_table = powers_of_base<Base, T>;
83 if( exponent >= lookup_table.size() )
check(
false,
"overflow" );
85 return lookup_table[exponent];