#include <type_traits>

using REAL = double;

template <int P>
constexpr typename std::enable_if<P == 0, REAL>::type
const_pow(REAL ) { return 1.0; }

template <int P>
constexpr typename std::enable_if<P == 1, REAL>::type
const_pow(REAL value) { return value; }

template <int P>
constexpr typename std::enable_if<P == 2, REAL>::type
const_pow( REAL value ) { return value * value; }

template <int P>
constexpr typename std::enable_if<2 < P, REAL>::type
const_pow(REAL value)
{
    return const_pow<2>(const_pow<P / 2>(value)) * const_pow<P % 2>(value);
}

template <int P>
constexpr typename std::enable_if<P < 0, REAL>::type
const_pow(REAL value) { return const_pow<-P>(1.0 / value); }


static_assert(0.5 == const_pow<-1>(2.), "Unepected result");
static_assert(1. == const_pow<0>(2.), "Unepected result");
static_assert(2. == const_pow<1>(2.), "Unepected result");
static_assert(4 == const_pow<2>(2.), "Unepected result");
static_assert(8 == const_pow<3>(2.), "Unepected result");
static_assert(2048 == const_pow<11>(2.), "Unepected result");


int main()
{
    return 0;
}
