static inline T op2_impl(Op op, T x, T y) { switch (op) { case OP_ADD: return add_impl(x, y); case OP_SUB: return sub_impl(x, y); case OP_MUL: return mul_impl(x, y); case OP_DIV: return div_impl(x, y); case OP_POW: return pow_impl(x, y); default: throw std::invalid_argument("Wrong number of arguments for operator"); } }
constexpr T pow_impl(T base, T exp, T result = 1) { return exp == 1 ? base*result : pow_impl(base*base, exp/2, exp%2 ? result*base : result); }